blob 0e276a8c (1368341B) - 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 "util.hpp" 17 #include "mem_list.hpp" 18 19 #include <errno.h> 20 21 struct IrBuilderSrc { 22 CodeGen *codegen; 23 IrExecutableSrc *exec; 24 IrBasicBlockSrc *current_basic_block; 25 AstNode *main_block_node; 26 }; 27 28 struct IrBuilderGen { 29 CodeGen *codegen; 30 IrExecutableGen *exec; 31 IrBasicBlockGen *current_basic_block; 32 33 // track for immediate post-analysis destruction 34 mem::List<IrInstGenConst *> constants; 35 }; 36 37 struct IrAnalyze { 38 CodeGen *codegen; 39 IrBuilderSrc old_irb; 40 IrBuilderGen new_irb; 41 size_t old_bb_index; 42 size_t instruction_index; 43 ZigType *explicit_return_type; 44 AstNode *explicit_return_type_source_node; 45 ZigList<IrInstGen *> src_implicit_return_type_list; 46 ZigList<IrSuspendPosition> resume_stack; 47 IrBasicBlockSrc *const_predecessor_bb; 48 size_t ref_count; 49 size_t break_debug_id; // for debugging purposes 50 IrInstGen *return_ptr; 51 52 // For the purpose of using in a debugger 53 void dump(); 54 }; 55 56 enum ConstCastResultId { 57 ConstCastResultIdOk, 58 ConstCastResultIdInvalid, 59 ConstCastResultIdErrSet, 60 ConstCastResultIdErrSetGlobal, 61 ConstCastResultIdPointerChild, 62 ConstCastResultIdSliceChild, 63 ConstCastResultIdOptionalChild, 64 ConstCastResultIdErrorUnionPayload, 65 ConstCastResultIdErrorUnionErrorSet, 66 ConstCastResultIdFnAlign, 67 ConstCastResultIdFnCC, 68 ConstCastResultIdFnVarArgs, 69 ConstCastResultIdFnIsGeneric, 70 ConstCastResultIdFnReturnType, 71 ConstCastResultIdFnArgCount, 72 ConstCastResultIdFnGenericArgCount, 73 ConstCastResultIdFnArg, 74 ConstCastResultIdFnArgNoAlias, 75 ConstCastResultIdType, 76 ConstCastResultIdUnresolvedInferredErrSet, 77 ConstCastResultIdAsyncAllocatorType, 78 ConstCastResultIdBadAllowsZero, 79 ConstCastResultIdArrayChild, 80 ConstCastResultIdSentinelArrays, 81 ConstCastResultIdPtrLens, 82 ConstCastResultIdCV, 83 ConstCastResultIdPtrSentinel, 84 ConstCastResultIdIntShorten, 85 }; 86 87 struct ConstCastOnly; 88 struct ConstCastArg { 89 size_t arg_index; 90 ZigType *actual_param_type; 91 ZigType *expected_param_type; 92 ConstCastOnly *child; 93 }; 94 95 struct ConstCastArgNoAlias { 96 size_t arg_index; 97 }; 98 99 struct ConstCastOptionalMismatch; 100 struct ConstCastPointerMismatch; 101 struct ConstCastSliceMismatch; 102 struct ConstCastErrUnionErrSetMismatch; 103 struct ConstCastErrUnionPayloadMismatch; 104 struct ConstCastErrSetMismatch; 105 struct ConstCastTypeMismatch; 106 struct ConstCastArrayMismatch; 107 struct ConstCastBadAllowsZero; 108 struct ConstCastBadNullTermArrays; 109 struct ConstCastBadCV; 110 struct ConstCastPtrSentinel; 111 struct ConstCastIntShorten; 112 113 struct ConstCastOnly { 114 ConstCastResultId id; 115 union { 116 ConstCastErrSetMismatch *error_set_mismatch; 117 ConstCastPointerMismatch *pointer_mismatch; 118 ConstCastSliceMismatch *slice_mismatch; 119 ConstCastOptionalMismatch *optional; 120 ConstCastErrUnionPayloadMismatch *error_union_payload; 121 ConstCastErrUnionErrSetMismatch *error_union_error_set; 122 ConstCastTypeMismatch *type_mismatch; 123 ConstCastArrayMismatch *array_mismatch; 124 ConstCastOnly *return_type; 125 ConstCastOnly *null_wrap_ptr_child; 126 ConstCastArg fn_arg; 127 ConstCastArgNoAlias arg_no_alias; 128 ConstCastBadAllowsZero *bad_allows_zero; 129 ConstCastBadNullTermArrays *sentinel_arrays; 130 ConstCastBadCV *bad_cv; 131 ConstCastPtrSentinel *bad_ptr_sentinel; 132 ConstCastIntShorten *int_shorten; 133 } data; 134 }; 135 136 struct ConstCastTypeMismatch { 137 ZigType *wanted_type; 138 ZigType *actual_type; 139 }; 140 141 struct ConstCastOptionalMismatch { 142 ConstCastOnly child; 143 ZigType *wanted_child; 144 ZigType *actual_child; 145 }; 146 147 struct ConstCastPointerMismatch { 148 ConstCastOnly child; 149 ZigType *wanted_child; 150 ZigType *actual_child; 151 }; 152 153 struct ConstCastSliceMismatch { 154 ConstCastOnly child; 155 ZigType *wanted_child; 156 ZigType *actual_child; 157 }; 158 159 struct ConstCastArrayMismatch { 160 ConstCastOnly child; 161 ZigType *wanted_child; 162 ZigType *actual_child; 163 }; 164 165 struct ConstCastErrUnionErrSetMismatch { 166 ConstCastOnly child; 167 ZigType *wanted_err_set; 168 ZigType *actual_err_set; 169 }; 170 171 struct ConstCastErrUnionPayloadMismatch { 172 ConstCastOnly child; 173 ZigType *wanted_payload; 174 ZigType *actual_payload; 175 }; 176 177 struct ConstCastErrSetMismatch { 178 ZigList<ErrorTableEntry *> missing_errors; 179 }; 180 181 struct ConstCastBadAllowsZero { 182 ZigType *wanted_type; 183 ZigType *actual_type; 184 }; 185 186 struct ConstCastBadNullTermArrays { 187 ConstCastOnly child; 188 ZigType *wanted_type; 189 ZigType *actual_type; 190 }; 191 192 struct ConstCastBadCV { 193 ZigType *wanted_type; 194 ZigType *actual_type; 195 }; 196 197 struct ConstCastPtrSentinel { 198 ZigType *wanted_type; 199 ZigType *actual_type; 200 }; 201 202 struct ConstCastIntShorten { 203 ZigType *wanted_type; 204 ZigType *actual_type; 205 }; 206 207 // for debugging purposes 208 struct DbgIrBreakPoint { 209 const char *src_file; 210 uint32_t line; 211 }; 212 DbgIrBreakPoint dbg_ir_breakpoints_buf[20]; 213 size_t dbg_ir_breakpoints_count = 0; 214 215 static IrInstSrc *ir_gen_node(IrBuilderSrc *irb, AstNode *node, Scope *scope); 216 static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *scope, LVal lval, 217 ResultLoc *result_loc); 218 static IrInstGen *ir_implicit_cast(IrAnalyze *ira, IrInstGen *value, ZigType *expected_type); 219 static IrInstGen *ir_implicit_cast2(IrAnalyze *ira, IrInst *value_source_instr, 220 IrInstGen *value, ZigType *expected_type); 221 static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst *source_instr, IrInstGen *ptr, 222 ResultLoc *result_loc); 223 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutableSrc *exec, AstNode *source_node, Buf *msg); 224 static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 225 IrInst* source_instr, IrInstGen *container_ptr, IrInst *container_ptr_src, 226 ZigType *container_type, bool initializing); 227 static void ir_assert(bool ok, IrInst* source_instruction); 228 static void ir_assert_gen(bool ok, IrInstGen *source_instruction); 229 static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *var); 230 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op); 231 static IrInstSrc *ir_lval_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *value, LVal lval, ResultLoc *result_loc); 232 static IrInstSrc *ir_expr_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *inst, ResultLoc *result_loc); 233 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align); 234 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align); 235 static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ZigValue *val); 236 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val); 237 static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 238 ZigValue *out_val, ZigValue *ptr_val); 239 static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr, 240 IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on); 241 static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed undef_allowed); 242 static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); 243 static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 244 ZigType *ptr_type); 245 static IrInstGen *ir_analyze_bit_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 246 ZigType *dest_type); 247 static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_instr, 248 ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime, bool allow_discard); 249 static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr, 250 ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime, bool allow_discard); 251 static IrInstGen *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInst* source_instr, 252 IrInstGen *base_ptr, bool safety_check_on, bool initializing); 253 static IrInstGen *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInst* source_instr, 254 IrInstGen *base_ptr, bool safety_check_on, bool initializing); 255 static IrInstGen *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInst* source_instr, 256 IrInstGen *base_ptr, bool initializing); 257 static IrInstGen *ir_analyze_store_ptr(IrAnalyze *ira, IrInst* source_instr, 258 IrInstGen *ptr, IrInstGen *uncasted_value, bool allow_write_through_const); 259 static IrInstSrc *ir_gen_union_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 260 IrInstSrc *union_type, IrInstSrc *field_name, AstNode *expr_node, 261 LVal lval, ResultLoc *parent_result_loc); 262 static void ir_reset_result(ResultLoc *result_loc); 263 static Buf *get_anon_type_name(CodeGen *codegen, IrExecutableSrc *exec, const char *kind_name, 264 Scope *scope, AstNode *source_node, Buf *out_bare_name); 265 static ResultLocCast *ir_build_cast_result_loc(IrBuilderSrc *irb, IrInstSrc *dest_type, 266 ResultLoc *parent_result_loc); 267 static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_instr, 268 TypeStructField *field, IrInstGen *struct_ptr, ZigType *struct_type, bool initializing); 269 static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, 270 IrInst* source_instr, IrInstGen *container_ptr, ZigType *container_type); 271 static ResultLoc *no_result_loc(void); 272 static IrInstGen *ir_analyze_test_non_null(IrAnalyze *ira, IrInst *source_inst, IrInstGen *value); 273 static IrInstGen *ir_error_dependency_loop(IrAnalyze *ira, IrInst *source_instr); 274 static IrInstGen *ir_const_undef(IrAnalyze *ira, IrInst *source_instruction, ZigType *ty); 275 276 static void destroy_instruction_src(IrInstSrc *inst) { 277 switch (inst->id) { 278 case IrInstSrcIdInvalid: 279 zig_unreachable(); 280 case IrInstSrcIdReturn: 281 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcReturn *>(inst)); 282 case IrInstSrcIdConst: 283 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcConst *>(inst)); 284 case IrInstSrcIdBinOp: 285 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBinOp *>(inst)); 286 case IrInstSrcIdMergeErrSets: 287 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMergeErrSets *>(inst)); 288 case IrInstSrcIdDeclVar: 289 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcDeclVar *>(inst)); 290 case IrInstSrcIdCall: 291 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCall *>(inst)); 292 case IrInstSrcIdCallExtra: 293 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallExtra *>(inst)); 294 case IrInstSrcIdUnOp: 295 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnOp *>(inst)); 296 case IrInstSrcIdCondBr: 297 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCondBr *>(inst)); 298 case IrInstSrcIdBr: 299 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBr *>(inst)); 300 case IrInstSrcIdPhi: 301 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPhi *>(inst)); 302 case IrInstSrcIdContainerInitList: 303 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcContainerInitList *>(inst)); 304 case IrInstSrcIdContainerInitFields: 305 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcContainerInitFields *>(inst)); 306 case IrInstSrcIdUnreachable: 307 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnreachable *>(inst)); 308 case IrInstSrcIdElemPtr: 309 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcElemPtr *>(inst)); 310 case IrInstSrcIdVarPtr: 311 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVarPtr *>(inst)); 312 case IrInstSrcIdLoadPtr: 313 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcLoadPtr *>(inst)); 314 case IrInstSrcIdStorePtr: 315 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcStorePtr *>(inst)); 316 case IrInstSrcIdTypeOf: 317 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeOf *>(inst)); 318 case IrInstSrcIdFieldPtr: 319 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFieldPtr *>(inst)); 320 case IrInstSrcIdSetCold: 321 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetCold *>(inst)); 322 case IrInstSrcIdSetRuntimeSafety: 323 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetRuntimeSafety *>(inst)); 324 case IrInstSrcIdSetFloatMode: 325 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetFloatMode *>(inst)); 326 case IrInstSrcIdArrayType: 327 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcArrayType *>(inst)); 328 case IrInstSrcIdSliceType: 329 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSliceType *>(inst)); 330 case IrInstSrcIdAnyFrameType: 331 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAnyFrameType *>(inst)); 332 case IrInstSrcIdAsm: 333 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAsm *>(inst)); 334 case IrInstSrcIdSizeOf: 335 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSizeOf *>(inst)); 336 case IrInstSrcIdTestNonNull: 337 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestNonNull *>(inst)); 338 case IrInstSrcIdOptionalUnwrapPtr: 339 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOptionalUnwrapPtr *>(inst)); 340 case IrInstSrcIdPopCount: 341 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPopCount *>(inst)); 342 case IrInstSrcIdClz: 343 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcClz *>(inst)); 344 case IrInstSrcIdCtz: 345 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCtz *>(inst)); 346 case IrInstSrcIdBswap: 347 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBswap *>(inst)); 348 case IrInstSrcIdBitReverse: 349 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitReverse *>(inst)); 350 case IrInstSrcIdSwitchBr: 351 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchBr *>(inst)); 352 case IrInstSrcIdSwitchVar: 353 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchVar *>(inst)); 354 case IrInstSrcIdSwitchElseVar: 355 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchElseVar *>(inst)); 356 case IrInstSrcIdSwitchTarget: 357 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchTarget *>(inst)); 358 case IrInstSrcIdImport: 359 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcImport *>(inst)); 360 case IrInstSrcIdRef: 361 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcRef *>(inst)); 362 case IrInstSrcIdCompileErr: 363 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCompileErr *>(inst)); 364 case IrInstSrcIdCompileLog: 365 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCompileLog *>(inst)); 366 case IrInstSrcIdErrName: 367 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrName *>(inst)); 368 case IrInstSrcIdCImport: 369 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCImport *>(inst)); 370 case IrInstSrcIdCInclude: 371 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCInclude *>(inst)); 372 case IrInstSrcIdCDefine: 373 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCDefine *>(inst)); 374 case IrInstSrcIdCUndef: 375 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCUndef *>(inst)); 376 case IrInstSrcIdEmbedFile: 377 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEmbedFile *>(inst)); 378 case IrInstSrcIdCmpxchg: 379 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCmpxchg *>(inst)); 380 case IrInstSrcIdFence: 381 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFence *>(inst)); 382 case IrInstSrcIdTruncate: 383 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTruncate *>(inst)); 384 case IrInstSrcIdIntCast: 385 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntCast *>(inst)); 386 case IrInstSrcIdFloatCast: 387 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst)); 388 case IrInstSrcIdErrSetCast: 389 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst)); 390 case IrInstSrcIdIntToFloat: 391 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst)); 392 case IrInstSrcIdFloatToInt: 393 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatToInt *>(inst)); 394 case IrInstSrcIdBoolToInt: 395 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolToInt *>(inst)); 396 case IrInstSrcIdVectorType: 397 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVectorType *>(inst)); 398 case IrInstSrcIdShuffleVector: 399 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcShuffleVector *>(inst)); 400 case IrInstSrcIdSplat: 401 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSplat *>(inst)); 402 case IrInstSrcIdBoolNot: 403 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolNot *>(inst)); 404 case IrInstSrcIdMemset: 405 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemset *>(inst)); 406 case IrInstSrcIdMemcpy: 407 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemcpy *>(inst)); 408 case IrInstSrcIdSlice: 409 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSlice *>(inst)); 410 case IrInstSrcIdBreakpoint: 411 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBreakpoint *>(inst)); 412 case IrInstSrcIdReturnAddress: 413 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcReturnAddress *>(inst)); 414 case IrInstSrcIdFrameAddress: 415 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameAddress *>(inst)); 416 case IrInstSrcIdFrameHandle: 417 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameHandle *>(inst)); 418 case IrInstSrcIdFrameType: 419 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameType *>(inst)); 420 case IrInstSrcIdFrameSize: 421 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameSize *>(inst)); 422 case IrInstSrcIdAlignOf: 423 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlignOf *>(inst)); 424 case IrInstSrcIdOverflowOp: 425 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOverflowOp *>(inst)); 426 case IrInstSrcIdTestErr: 427 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestErr *>(inst)); 428 case IrInstSrcIdUnwrapErrCode: 429 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnwrapErrCode *>(inst)); 430 case IrInstSrcIdUnwrapErrPayload: 431 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnwrapErrPayload *>(inst)); 432 case IrInstSrcIdFnProto: 433 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFnProto *>(inst)); 434 case IrInstSrcIdTestComptime: 435 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestComptime *>(inst)); 436 case IrInstSrcIdPtrCast: 437 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrCast *>(inst)); 438 case IrInstSrcIdBitCast: 439 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitCast *>(inst)); 440 case IrInstSrcIdPtrToInt: 441 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrToInt *>(inst)); 442 case IrInstSrcIdIntToPtr: 443 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToPtr *>(inst)); 444 case IrInstSrcIdIntToEnum: 445 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToEnum *>(inst)); 446 case IrInstSrcIdIntToErr: 447 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToErr *>(inst)); 448 case IrInstSrcIdErrToInt: 449 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrToInt *>(inst)); 450 case IrInstSrcIdCheckSwitchProngs: 451 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckSwitchProngs *>(inst)); 452 case IrInstSrcIdCheckStatementIsVoid: 453 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckStatementIsVoid *>(inst)); 454 case IrInstSrcIdTypeName: 455 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeName *>(inst)); 456 case IrInstSrcIdTagName: 457 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTagName *>(inst)); 458 case IrInstSrcIdPtrType: 459 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrType *>(inst)); 460 case IrInstSrcIdDeclRef: 461 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcDeclRef *>(inst)); 462 case IrInstSrcIdPanic: 463 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPanic *>(inst)); 464 case IrInstSrcIdFieldParentPtr: 465 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFieldParentPtr *>(inst)); 466 case IrInstSrcIdByteOffsetOf: 467 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcByteOffsetOf *>(inst)); 468 case IrInstSrcIdBitOffsetOf: 469 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitOffsetOf *>(inst)); 470 case IrInstSrcIdTypeInfo: 471 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeInfo *>(inst)); 472 case IrInstSrcIdType: 473 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcType *>(inst)); 474 case IrInstSrcIdHasField: 475 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasField *>(inst)); 476 case IrInstSrcIdSetEvalBranchQuota: 477 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetEvalBranchQuota *>(inst)); 478 case IrInstSrcIdAlignCast: 479 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlignCast *>(inst)); 480 case IrInstSrcIdImplicitCast: 481 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcImplicitCast *>(inst)); 482 case IrInstSrcIdResolveResult: 483 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResolveResult *>(inst)); 484 case IrInstSrcIdResetResult: 485 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResetResult *>(inst)); 486 case IrInstSrcIdOpaqueType: 487 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOpaqueType *>(inst)); 488 case IrInstSrcIdSetAlignStack: 489 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetAlignStack *>(inst)); 490 case IrInstSrcIdArgType: 491 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcArgType *>(inst)); 492 case IrInstSrcIdTagType: 493 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTagType *>(inst)); 494 case IrInstSrcIdExport: 495 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcExport *>(inst)); 496 case IrInstSrcIdErrorReturnTrace: 497 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrorReturnTrace *>(inst)); 498 case IrInstSrcIdErrorUnion: 499 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrorUnion *>(inst)); 500 case IrInstSrcIdAtomicRmw: 501 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicRmw *>(inst)); 502 case IrInstSrcIdSaveErrRetAddr: 503 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSaveErrRetAddr *>(inst)); 504 case IrInstSrcIdAddImplicitReturnType: 505 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAddImplicitReturnType *>(inst)); 506 case IrInstSrcIdFloatOp: 507 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatOp *>(inst)); 508 case IrInstSrcIdMulAdd: 509 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMulAdd *>(inst)); 510 case IrInstSrcIdAtomicLoad: 511 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicLoad *>(inst)); 512 case IrInstSrcIdAtomicStore: 513 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicStore *>(inst)); 514 case IrInstSrcIdEnumToInt: 515 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEnumToInt *>(inst)); 516 case IrInstSrcIdCheckRuntimeScope: 517 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckRuntimeScope *>(inst)); 518 case IrInstSrcIdHasDecl: 519 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasDecl *>(inst)); 520 case IrInstSrcIdUndeclaredIdent: 521 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUndeclaredIdent *>(inst)); 522 case IrInstSrcIdAlloca: 523 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlloca *>(inst)); 524 case IrInstSrcIdEndExpr: 525 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEndExpr *>(inst)); 526 case IrInstSrcIdUnionInitNamedField: 527 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnionInitNamedField *>(inst)); 528 case IrInstSrcIdSuspendBegin: 529 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSuspendBegin *>(inst)); 530 case IrInstSrcIdSuspendFinish: 531 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSuspendFinish *>(inst)); 532 case IrInstSrcIdResume: 533 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResume *>(inst)); 534 case IrInstSrcIdAwait: 535 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAwait *>(inst)); 536 case IrInstSrcIdSpillBegin: 537 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSpillBegin *>(inst)); 538 case IrInstSrcIdSpillEnd: 539 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSpillEnd *>(inst)); 540 case IrInstSrcIdCallArgs: 541 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallArgs *>(inst)); 542 } 543 zig_unreachable(); 544 } 545 546 void destroy_instruction_gen(IrInstGen *inst) { 547 switch (inst->id) { 548 case IrInstGenIdInvalid: 549 zig_unreachable(); 550 case IrInstGenIdReturn: 551 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenReturn *>(inst)); 552 case IrInstGenIdConst: 553 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenConst *>(inst)); 554 case IrInstGenIdBinOp: 555 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinOp *>(inst)); 556 case IrInstGenIdCast: 557 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCast *>(inst)); 558 case IrInstGenIdCall: 559 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCall *>(inst)); 560 case IrInstGenIdCondBr: 561 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCondBr *>(inst)); 562 case IrInstGenIdBr: 563 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBr *>(inst)); 564 case IrInstGenIdPhi: 565 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPhi *>(inst)); 566 case IrInstGenIdUnreachable: 567 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnreachable *>(inst)); 568 case IrInstGenIdElemPtr: 569 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenElemPtr *>(inst)); 570 case IrInstGenIdVarPtr: 571 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVarPtr *>(inst)); 572 case IrInstGenIdReturnPtr: 573 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenReturnPtr *>(inst)); 574 case IrInstGenIdLoadPtr: 575 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenLoadPtr *>(inst)); 576 case IrInstGenIdStorePtr: 577 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenStorePtr *>(inst)); 578 case IrInstGenIdVectorStoreElem: 579 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVectorStoreElem *>(inst)); 580 case IrInstGenIdStructFieldPtr: 581 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenStructFieldPtr *>(inst)); 582 case IrInstGenIdUnionFieldPtr: 583 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnionFieldPtr *>(inst)); 584 case IrInstGenIdAsm: 585 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAsm *>(inst)); 586 case IrInstGenIdTestNonNull: 587 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTestNonNull *>(inst)); 588 case IrInstGenIdOptionalUnwrapPtr: 589 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenOptionalUnwrapPtr *>(inst)); 590 case IrInstGenIdPopCount: 591 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPopCount *>(inst)); 592 case IrInstGenIdClz: 593 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenClz *>(inst)); 594 case IrInstGenIdCtz: 595 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCtz *>(inst)); 596 case IrInstGenIdBswap: 597 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBswap *>(inst)); 598 case IrInstGenIdBitReverse: 599 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBitReverse *>(inst)); 600 case IrInstGenIdSwitchBr: 601 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSwitchBr *>(inst)); 602 case IrInstGenIdUnionTag: 603 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnionTag *>(inst)); 604 case IrInstGenIdRef: 605 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenRef *>(inst)); 606 case IrInstGenIdErrName: 607 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrName *>(inst)); 608 case IrInstGenIdCmpxchg: 609 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCmpxchg *>(inst)); 610 case IrInstGenIdFence: 611 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFence *>(inst)); 612 case IrInstGenIdTruncate: 613 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTruncate *>(inst)); 614 case IrInstGenIdShuffleVector: 615 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenShuffleVector *>(inst)); 616 case IrInstGenIdSplat: 617 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSplat *>(inst)); 618 case IrInstGenIdBoolNot: 619 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBoolNot *>(inst)); 620 case IrInstGenIdMemset: 621 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenMemset *>(inst)); 622 case IrInstGenIdMemcpy: 623 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenMemcpy *>(inst)); 624 case IrInstGenIdSlice: 625 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSlice *>(inst)); 626 case IrInstGenIdBreakpoint: 627 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBreakpoint *>(inst)); 628 case IrInstGenIdReturnAddress: 629 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenReturnAddress *>(inst)); 630 case IrInstGenIdFrameAddress: 631 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFrameAddress *>(inst)); 632 case IrInstGenIdFrameHandle: 633 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFrameHandle *>(inst)); 634 case IrInstGenIdFrameSize: 635 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFrameSize *>(inst)); 636 case IrInstGenIdOverflowOp: 637 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenOverflowOp *>(inst)); 638 case IrInstGenIdTestErr: 639 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTestErr *>(inst)); 640 case IrInstGenIdUnwrapErrCode: 641 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnwrapErrCode *>(inst)); 642 case IrInstGenIdUnwrapErrPayload: 643 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnwrapErrPayload *>(inst)); 644 case IrInstGenIdOptionalWrap: 645 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenOptionalWrap *>(inst)); 646 case IrInstGenIdErrWrapCode: 647 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrWrapCode *>(inst)); 648 case IrInstGenIdErrWrapPayload: 649 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrWrapPayload *>(inst)); 650 case IrInstGenIdPtrCast: 651 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPtrCast *>(inst)); 652 case IrInstGenIdBitCast: 653 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBitCast *>(inst)); 654 case IrInstGenIdWidenOrShorten: 655 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWidenOrShorten *>(inst)); 656 case IrInstGenIdPtrToInt: 657 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPtrToInt *>(inst)); 658 case IrInstGenIdIntToPtr: 659 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenIntToPtr *>(inst)); 660 case IrInstGenIdIntToEnum: 661 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenIntToEnum *>(inst)); 662 case IrInstGenIdIntToErr: 663 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenIntToErr *>(inst)); 664 case IrInstGenIdErrToInt: 665 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrToInt *>(inst)); 666 case IrInstGenIdTagName: 667 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTagName *>(inst)); 668 case IrInstGenIdPanic: 669 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPanic *>(inst)); 670 case IrInstGenIdFieldParentPtr: 671 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFieldParentPtr *>(inst)); 672 case IrInstGenIdAlignCast: 673 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlignCast *>(inst)); 674 case IrInstGenIdErrorReturnTrace: 675 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrorReturnTrace *>(inst)); 676 case IrInstGenIdAtomicRmw: 677 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAtomicRmw *>(inst)); 678 case IrInstGenIdSaveErrRetAddr: 679 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSaveErrRetAddr *>(inst)); 680 case IrInstGenIdFloatOp: 681 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFloatOp *>(inst)); 682 case IrInstGenIdMulAdd: 683 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenMulAdd *>(inst)); 684 case IrInstGenIdAtomicLoad: 685 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAtomicLoad *>(inst)); 686 case IrInstGenIdAtomicStore: 687 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAtomicStore *>(inst)); 688 case IrInstGenIdDeclVar: 689 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenDeclVar *>(inst)); 690 case IrInstGenIdArrayToVector: 691 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenArrayToVector *>(inst)); 692 case IrInstGenIdVectorToArray: 693 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVectorToArray *>(inst)); 694 case IrInstGenIdPtrOfArrayToSlice: 695 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPtrOfArrayToSlice *>(inst)); 696 case IrInstGenIdAssertZero: 697 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertZero *>(inst)); 698 case IrInstGenIdAssertNonNull: 699 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertNonNull *>(inst)); 700 case IrInstGenIdAlloca: 701 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlloca *>(inst)); 702 case IrInstGenIdSuspendBegin: 703 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSuspendBegin *>(inst)); 704 case IrInstGenIdSuspendFinish: 705 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSuspendFinish *>(inst)); 706 case IrInstGenIdResume: 707 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenResume *>(inst)); 708 case IrInstGenIdAwait: 709 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAwait *>(inst)); 710 case IrInstGenIdSpillBegin: 711 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSpillBegin *>(inst)); 712 case IrInstGenIdSpillEnd: 713 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSpillEnd *>(inst)); 714 case IrInstGenIdVectorExtractElem: 715 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVectorExtractElem *>(inst)); 716 case IrInstGenIdBinaryNot: 717 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinaryNot *>(inst)); 718 case IrInstGenIdNegation: 719 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegation *>(inst)); 720 case IrInstGenIdNegationWrapping: 721 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegationWrapping *>(inst)); 722 } 723 zig_unreachable(); 724 } 725 726 static void ira_ref(IrAnalyze *ira) { 727 ira->ref_count += 1; 728 } 729 static void ira_deref(IrAnalyze *ira) { 730 if (ira->ref_count > 1) { 731 ira->ref_count -= 1; 732 733 // immediate destruction of dangling IrInstGenConst is not possible 734 // free tracking memory because it will never be used 735 ira->new_irb.constants.deinit(&heap::c_allocator); 736 return; 737 } 738 assert(ira->ref_count != 0); 739 740 for (size_t bb_i = 0; bb_i < ira->old_irb.exec->basic_block_list.length; bb_i += 1) { 741 IrBasicBlockSrc *pass1_bb = ira->old_irb.exec->basic_block_list.items[bb_i]; 742 for (size_t inst_i = 0; inst_i < pass1_bb->instruction_list.length; inst_i += 1) { 743 IrInstSrc *pass1_inst = pass1_bb->instruction_list.items[inst_i]; 744 destroy_instruction_src(pass1_inst); 745 } 746 heap::c_allocator.destroy(pass1_bb); 747 } 748 ira->old_irb.exec->basic_block_list.deinit(); 749 ira->old_irb.exec->tld_list.deinit(); 750 heap::c_allocator.destroy(ira->old_irb.exec); 751 ira->src_implicit_return_type_list.deinit(); 752 ira->resume_stack.deinit(); 753 754 // destroy dangling IrInstGenConst 755 for (size_t i = 0; i < ira->new_irb.constants.length; i += 1) { 756 auto constant = ira->new_irb.constants.items[i]; 757 if (constant->base.base.ref_count == 0 && !ir_inst_gen_has_side_effects(&constant->base)) 758 destroy_instruction_gen(&constant->base); 759 } 760 ira->new_irb.constants.deinit(&heap::c_allocator); 761 762 heap::c_allocator.destroy(ira); 763 } 764 765 static ZigValue *const_ptr_pointee_unchecked_no_isf(CodeGen *g, ZigValue *const_val) { 766 assert(get_src_ptr_type(const_val->type) != nullptr); 767 assert(const_val->special == ConstValSpecialStatic); 768 769 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { 770 case OnePossibleValueInvalid: 771 return nullptr; 772 case OnePossibleValueYes: 773 return get_the_one_possible_value(g, const_val->type->data.pointer.child_type); 774 case OnePossibleValueNo: 775 break; 776 } 777 778 ZigValue *result; 779 switch (const_val->data.x_ptr.special) { 780 case ConstPtrSpecialInvalid: 781 zig_unreachable(); 782 case ConstPtrSpecialRef: 783 result = const_val->data.x_ptr.data.ref.pointee; 784 break; 785 case ConstPtrSpecialBaseArray: { 786 ZigValue *array_val = const_val->data.x_ptr.data.base_array.array_val; 787 if (const_val->data.x_ptr.data.base_array.elem_index == array_val->type->data.array.len) { 788 result = array_val->type->data.array.sentinel; 789 } else { 790 expand_undef_array(g, array_val); 791 result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index]; 792 } 793 break; 794 } 795 case ConstPtrSpecialBaseStruct: { 796 ZigValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val; 797 expand_undef_struct(g, struct_val); 798 result = struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index]; 799 break; 800 } 801 case ConstPtrSpecialBaseErrorUnionCode: 802 result = const_val->data.x_ptr.data.base_err_union_code.err_union_val->data.x_err_union.error_set; 803 break; 804 case ConstPtrSpecialBaseErrorUnionPayload: 805 result = const_val->data.x_ptr.data.base_err_union_payload.err_union_val->data.x_err_union.payload; 806 break; 807 case ConstPtrSpecialBaseOptionalPayload: 808 result = const_val->data.x_ptr.data.base_optional_payload.optional_val->data.x_optional; 809 break; 810 case ConstPtrSpecialNull: 811 result = const_val; 812 break; 813 case ConstPtrSpecialHardCodedAddr: 814 zig_unreachable(); 815 case ConstPtrSpecialDiscard: 816 zig_unreachable(); 817 case ConstPtrSpecialFunction: 818 zig_unreachable(); 819 } 820 assert(result != nullptr); 821 return result; 822 } 823 824 static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) { 825 assert(get_src_ptr_type(const_val->type) != nullptr); 826 assert(const_val->special == ConstValSpecialStatic); 827 828 InferredStructField *isf = const_val->type->data.pointer.inferred_struct_field; 829 if (isf != nullptr) { 830 TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); 831 assert(field != nullptr); 832 if (field->is_comptime) { 833 assert(field->init_val != nullptr); 834 return field->init_val; 835 } 836 ZigValue *struct_val = const_ptr_pointee_unchecked_no_isf(g, const_val); 837 assert(struct_val->type->id == ZigTypeIdStruct); 838 return struct_val->data.x_struct.fields[field->src_index]; 839 } 840 841 return const_ptr_pointee_unchecked_no_isf(g, const_val); 842 } 843 844 static bool is_tuple(ZigType *type) { 845 return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialInferredTuple; 846 } 847 848 static bool is_slice(ZigType *type) { 849 return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialSlice; 850 } 851 852 static bool slice_is_const(ZigType *type) { 853 assert(is_slice(type)); 854 return type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const; 855 } 856 857 // This function returns true when you can change the type of a ZigValue and the 858 // value remains meaningful. 859 static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expected, ZigType *actual) { 860 if (expected == actual) 861 return true; 862 863 if (get_codegen_ptr_type(expected) != nullptr && get_codegen_ptr_type(actual) != nullptr) 864 return true; 865 866 if (is_opt_err_set(expected) && is_opt_err_set(actual)) 867 return true; 868 869 if (expected->id != actual->id) 870 return false; 871 872 switch (expected->id) { 873 case ZigTypeIdInvalid: 874 case ZigTypeIdUnreachable: 875 zig_unreachable(); 876 case ZigTypeIdMetaType: 877 case ZigTypeIdVoid: 878 case ZigTypeIdBool: 879 case ZigTypeIdComptimeFloat: 880 case ZigTypeIdComptimeInt: 881 case ZigTypeIdEnumLiteral: 882 case ZigTypeIdUndefined: 883 case ZigTypeIdNull: 884 case ZigTypeIdBoundFn: 885 case ZigTypeIdErrorSet: 886 case ZigTypeIdOpaque: 887 case ZigTypeIdAnyFrame: 888 case ZigTypeIdFn: 889 return true; 890 case ZigTypeIdPointer: 891 return expected->data.pointer.inferred_struct_field == actual->data.pointer.inferred_struct_field; 892 case ZigTypeIdFloat: 893 return expected->data.floating.bit_count == actual->data.floating.bit_count; 894 case ZigTypeIdInt: 895 return expected->data.integral.is_signed == actual->data.integral.is_signed; 896 case ZigTypeIdStruct: 897 return is_slice(expected) && is_slice(actual); 898 case ZigTypeIdOptional: 899 case ZigTypeIdErrorUnion: 900 case ZigTypeIdEnum: 901 case ZigTypeIdUnion: 902 case ZigTypeIdVector: 903 case ZigTypeIdFnFrame: 904 return false; 905 case ZigTypeIdArray: 906 return expected->data.array.len == actual->data.array.len && 907 expected->data.array.child_type == actual->data.array.child_type && 908 (expected->data.array.sentinel == nullptr || (actual->data.array.sentinel != nullptr && 909 const_values_equal(codegen, expected->data.array.sentinel, actual->data.array.sentinel))); 910 } 911 zig_unreachable(); 912 } 913 914 static bool ir_should_inline(IrExecutableSrc *exec, Scope *scope) { 915 if (exec->is_inline) 916 return true; 917 918 while (scope != nullptr) { 919 if (scope->id == ScopeIdCompTime) 920 return true; 921 if (scope->id == ScopeIdTypeOf) 922 return false; 923 if (scope->id == ScopeIdFnDef) 924 break; 925 scope = scope->parent; 926 } 927 return false; 928 } 929 930 static void ir_instruction_append(IrBasicBlockSrc *basic_block, IrInstSrc *instruction) { 931 assert(basic_block); 932 assert(instruction); 933 basic_block->instruction_list.append(instruction); 934 } 935 936 static void ir_inst_gen_append(IrBasicBlockGen *basic_block, IrInstGen *instruction) { 937 assert(basic_block); 938 assert(instruction); 939 basic_block->instruction_list.append(instruction); 940 } 941 942 static size_t exec_next_debug_id(IrExecutableSrc *exec) { 943 size_t result = exec->next_debug_id; 944 exec->next_debug_id += 1; 945 return result; 946 } 947 948 static size_t exec_next_debug_id_gen(IrExecutableGen *exec) { 949 size_t result = exec->next_debug_id; 950 exec->next_debug_id += 1; 951 return result; 952 } 953 954 static ZigFn *exec_fn_entry(IrExecutableSrc *exec) { 955 return exec->fn_entry; 956 } 957 958 static Buf *exec_c_import_buf(IrExecutableSrc *exec) { 959 return exec->c_import_buf; 960 } 961 962 static bool value_is_comptime(ZigValue *const_val) { 963 return const_val->special != ConstValSpecialRuntime; 964 } 965 966 static bool instr_is_comptime(IrInstGen *instruction) { 967 return value_is_comptime(instruction->value); 968 } 969 970 static bool instr_is_unreachable(IrInstSrc *instruction) { 971 return instruction->is_noreturn; 972 } 973 974 static void ir_link_new_bb(IrBasicBlockGen *new_bb, IrBasicBlockSrc *old_bb) { 975 new_bb->parent = old_bb; 976 old_bb->child = new_bb; 977 } 978 979 static void ir_ref_bb(IrBasicBlockSrc *bb) { 980 bb->ref_count += 1; 981 } 982 983 static void ir_ref_bb_gen(IrBasicBlockGen *bb) { 984 bb->ref_count += 1; 985 } 986 987 static void ir_ref_instruction(IrInstSrc *instruction, IrBasicBlockSrc *cur_bb) { 988 assert(instruction->id != IrInstSrcIdInvalid); 989 instruction->base.ref_count += 1; 990 if (instruction->owner_bb != cur_bb && !instr_is_unreachable(instruction) 991 && instruction->id != IrInstSrcIdConst) 992 { 993 ir_ref_bb(instruction->owner_bb); 994 } 995 } 996 997 static void ir_ref_inst_gen(IrInstGen *instruction, IrBasicBlockGen *cur_bb) { 998 assert(instruction->id != IrInstGenIdInvalid); 999 instruction->base.ref_count += 1; 1000 if (instruction->owner_bb != cur_bb && !instr_is_comptime(instruction)) 1001 ir_ref_bb_gen(instruction->owner_bb); 1002 } 1003 1004 static void ir_ref_var(ZigVar *var) { 1005 var->ref_count += 1; 1006 } 1007 1008 static void create_result_ptr(CodeGen *codegen, ZigType *expected_type, 1009 ZigValue **out_result, ZigValue **out_result_ptr) 1010 { 1011 ZigValue *result = codegen->pass1_arena->create<ZigValue>(); 1012 ZigValue *result_ptr = codegen->pass1_arena->create<ZigValue>(); 1013 result->special = ConstValSpecialUndef; 1014 result->type = expected_type; 1015 result_ptr->special = ConstValSpecialStatic; 1016 result_ptr->type = get_pointer_to_type(codegen, result->type, false); 1017 result_ptr->data.x_ptr.mut = ConstPtrMutComptimeVar; 1018 result_ptr->data.x_ptr.special = ConstPtrSpecialRef; 1019 result_ptr->data.x_ptr.data.ref.pointee = result; 1020 1021 *out_result = result; 1022 *out_result_ptr = result_ptr; 1023 } 1024 1025 ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) { 1026 Error err; 1027 1028 ZigValue *result; 1029 ZigValue *result_ptr; 1030 create_result_ptr(ira->codegen, ira->codegen->builtin_types.entry_type, &result, &result_ptr); 1031 1032 if ((err = ir_eval_const_value(ira->codegen, scope, node, result_ptr, 1033 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 1034 nullptr, nullptr, node, nullptr, ira->new_irb.exec, nullptr, UndefBad))) 1035 { 1036 return ira->codegen->builtin_types.entry_invalid; 1037 } 1038 if (type_is_invalid(result->type)) 1039 return ira->codegen->builtin_types.entry_invalid; 1040 1041 assert(result->special != ConstValSpecialRuntime); 1042 ZigType *res_type = result->data.x_type; 1043 1044 return res_type; 1045 } 1046 1047 static IrBasicBlockSrc *ir_create_basic_block(IrBuilderSrc *irb, Scope *scope, const char *name_hint) { 1048 IrBasicBlockSrc *result = heap::c_allocator.create<IrBasicBlockSrc>(); 1049 result->scope = scope; 1050 result->name_hint = name_hint; 1051 result->debug_id = exec_next_debug_id(irb->exec); 1052 result->index = UINT32_MAX; // set later 1053 return result; 1054 } 1055 1056 static IrBasicBlockGen *ir_create_basic_block_gen(IrAnalyze *ira, Scope *scope, const char *name_hint) { 1057 IrBasicBlockGen *result = heap::c_allocator.create<IrBasicBlockGen>(); 1058 result->scope = scope; 1059 result->name_hint = name_hint; 1060 result->debug_id = exec_next_debug_id_gen(ira->new_irb.exec); 1061 result->index = UINT32_MAX; // set later 1062 return result; 1063 } 1064 1065 static IrBasicBlockGen *ir_build_bb_from(IrAnalyze *ira, IrBasicBlockSrc *other_bb) { 1066 IrBasicBlockGen *new_bb = ir_create_basic_block_gen(ira, other_bb->scope, other_bb->name_hint); 1067 ir_link_new_bb(new_bb, other_bb); 1068 return new_bb; 1069 } 1070 1071 static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclVar *) { 1072 return IrInstSrcIdDeclVar; 1073 } 1074 1075 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBr *) { 1076 return IrInstSrcIdBr; 1077 } 1078 1079 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCondBr *) { 1080 return IrInstSrcIdCondBr; 1081 } 1082 1083 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchBr *) { 1084 return IrInstSrcIdSwitchBr; 1085 } 1086 1087 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchVar *) { 1088 return IrInstSrcIdSwitchVar; 1089 } 1090 1091 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchElseVar *) { 1092 return IrInstSrcIdSwitchElseVar; 1093 } 1094 1095 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchTarget *) { 1096 return IrInstSrcIdSwitchTarget; 1097 } 1098 1099 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPhi *) { 1100 return IrInstSrcIdPhi; 1101 } 1102 1103 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnOp *) { 1104 return IrInstSrcIdUnOp; 1105 } 1106 1107 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBinOp *) { 1108 return IrInstSrcIdBinOp; 1109 } 1110 1111 static constexpr IrInstSrcId ir_inst_id(IrInstSrcMergeErrSets *) { 1112 return IrInstSrcIdMergeErrSets; 1113 } 1114 1115 static constexpr IrInstSrcId ir_inst_id(IrInstSrcLoadPtr *) { 1116 return IrInstSrcIdLoadPtr; 1117 } 1118 1119 static constexpr IrInstSrcId ir_inst_id(IrInstSrcStorePtr *) { 1120 return IrInstSrcIdStorePtr; 1121 } 1122 1123 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldPtr *) { 1124 return IrInstSrcIdFieldPtr; 1125 } 1126 1127 static constexpr IrInstSrcId ir_inst_id(IrInstSrcElemPtr *) { 1128 return IrInstSrcIdElemPtr; 1129 } 1130 1131 static constexpr IrInstSrcId ir_inst_id(IrInstSrcVarPtr *) { 1132 return IrInstSrcIdVarPtr; 1133 } 1134 1135 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCall *) { 1136 return IrInstSrcIdCall; 1137 } 1138 1139 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallArgs *) { 1140 return IrInstSrcIdCallArgs; 1141 } 1142 1143 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallExtra *) { 1144 return IrInstSrcIdCallExtra; 1145 } 1146 1147 static constexpr IrInstSrcId ir_inst_id(IrInstSrcConst *) { 1148 return IrInstSrcIdConst; 1149 } 1150 1151 static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturn *) { 1152 return IrInstSrcIdReturn; 1153 } 1154 1155 static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitList *) { 1156 return IrInstSrcIdContainerInitList; 1157 } 1158 1159 static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitFields *) { 1160 return IrInstSrcIdContainerInitFields; 1161 } 1162 1163 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnreachable *) { 1164 return IrInstSrcIdUnreachable; 1165 } 1166 1167 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeOf *) { 1168 return IrInstSrcIdTypeOf; 1169 } 1170 1171 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetCold *) { 1172 return IrInstSrcIdSetCold; 1173 } 1174 1175 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetRuntimeSafety *) { 1176 return IrInstSrcIdSetRuntimeSafety; 1177 } 1178 1179 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetFloatMode *) { 1180 return IrInstSrcIdSetFloatMode; 1181 } 1182 1183 static constexpr IrInstSrcId ir_inst_id(IrInstSrcArrayType *) { 1184 return IrInstSrcIdArrayType; 1185 } 1186 1187 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAnyFrameType *) { 1188 return IrInstSrcIdAnyFrameType; 1189 } 1190 1191 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSliceType *) { 1192 return IrInstSrcIdSliceType; 1193 } 1194 1195 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAsm *) { 1196 return IrInstSrcIdAsm; 1197 } 1198 1199 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSizeOf *) { 1200 return IrInstSrcIdSizeOf; 1201 } 1202 1203 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestNonNull *) { 1204 return IrInstSrcIdTestNonNull; 1205 } 1206 1207 static constexpr IrInstSrcId ir_inst_id(IrInstSrcOptionalUnwrapPtr *) { 1208 return IrInstSrcIdOptionalUnwrapPtr; 1209 } 1210 1211 static constexpr IrInstSrcId ir_inst_id(IrInstSrcClz *) { 1212 return IrInstSrcIdClz; 1213 } 1214 1215 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCtz *) { 1216 return IrInstSrcIdCtz; 1217 } 1218 1219 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPopCount *) { 1220 return IrInstSrcIdPopCount; 1221 } 1222 1223 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBswap *) { 1224 return IrInstSrcIdBswap; 1225 } 1226 1227 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitReverse *) { 1228 return IrInstSrcIdBitReverse; 1229 } 1230 1231 static constexpr IrInstSrcId ir_inst_id(IrInstSrcImport *) { 1232 return IrInstSrcIdImport; 1233 } 1234 1235 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCImport *) { 1236 return IrInstSrcIdCImport; 1237 } 1238 1239 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCInclude *) { 1240 return IrInstSrcIdCInclude; 1241 } 1242 1243 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCDefine *) { 1244 return IrInstSrcIdCDefine; 1245 } 1246 1247 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCUndef *) { 1248 return IrInstSrcIdCUndef; 1249 } 1250 1251 static constexpr IrInstSrcId ir_inst_id(IrInstSrcRef *) { 1252 return IrInstSrcIdRef; 1253 } 1254 1255 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileErr *) { 1256 return IrInstSrcIdCompileErr; 1257 } 1258 1259 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileLog *) { 1260 return IrInstSrcIdCompileLog; 1261 } 1262 1263 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrName *) { 1264 return IrInstSrcIdErrName; 1265 } 1266 1267 static constexpr IrInstSrcId ir_inst_id(IrInstSrcEmbedFile *) { 1268 return IrInstSrcIdEmbedFile; 1269 } 1270 1271 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCmpxchg *) { 1272 return IrInstSrcIdCmpxchg; 1273 } 1274 1275 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFence *) { 1276 return IrInstSrcIdFence; 1277 } 1278 1279 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTruncate *) { 1280 return IrInstSrcIdTruncate; 1281 } 1282 1283 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntCast *) { 1284 return IrInstSrcIdIntCast; 1285 } 1286 1287 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatCast *) { 1288 return IrInstSrcIdFloatCast; 1289 } 1290 1291 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToFloat *) { 1292 return IrInstSrcIdIntToFloat; 1293 } 1294 1295 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatToInt *) { 1296 return IrInstSrcIdFloatToInt; 1297 } 1298 1299 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolToInt *) { 1300 return IrInstSrcIdBoolToInt; 1301 } 1302 1303 static constexpr IrInstSrcId ir_inst_id(IrInstSrcVectorType *) { 1304 return IrInstSrcIdVectorType; 1305 } 1306 1307 static constexpr IrInstSrcId ir_inst_id(IrInstSrcShuffleVector *) { 1308 return IrInstSrcIdShuffleVector; 1309 } 1310 1311 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSplat *) { 1312 return IrInstSrcIdSplat; 1313 } 1314 1315 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolNot *) { 1316 return IrInstSrcIdBoolNot; 1317 } 1318 1319 static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemset *) { 1320 return IrInstSrcIdMemset; 1321 } 1322 1323 static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemcpy *) { 1324 return IrInstSrcIdMemcpy; 1325 } 1326 1327 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSlice *) { 1328 return IrInstSrcIdSlice; 1329 } 1330 1331 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBreakpoint *) { 1332 return IrInstSrcIdBreakpoint; 1333 } 1334 1335 static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturnAddress *) { 1336 return IrInstSrcIdReturnAddress; 1337 } 1338 1339 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameAddress *) { 1340 return IrInstSrcIdFrameAddress; 1341 } 1342 1343 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameHandle *) { 1344 return IrInstSrcIdFrameHandle; 1345 } 1346 1347 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameType *) { 1348 return IrInstSrcIdFrameType; 1349 } 1350 1351 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameSize *) { 1352 return IrInstSrcIdFrameSize; 1353 } 1354 1355 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignOf *) { 1356 return IrInstSrcIdAlignOf; 1357 } 1358 1359 static constexpr IrInstSrcId ir_inst_id(IrInstSrcOverflowOp *) { 1360 return IrInstSrcIdOverflowOp; 1361 } 1362 1363 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestErr *) { 1364 return IrInstSrcIdTestErr; 1365 } 1366 1367 static constexpr IrInstSrcId ir_inst_id(IrInstSrcMulAdd *) { 1368 return IrInstSrcIdMulAdd; 1369 } 1370 1371 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatOp *) { 1372 return IrInstSrcIdFloatOp; 1373 } 1374 1375 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrCode *) { 1376 return IrInstSrcIdUnwrapErrCode; 1377 } 1378 1379 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrPayload *) { 1380 return IrInstSrcIdUnwrapErrPayload; 1381 } 1382 1383 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFnProto *) { 1384 return IrInstSrcIdFnProto; 1385 } 1386 1387 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestComptime *) { 1388 return IrInstSrcIdTestComptime; 1389 } 1390 1391 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrCast *) { 1392 return IrInstSrcIdPtrCast; 1393 } 1394 1395 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitCast *) { 1396 return IrInstSrcIdBitCast; 1397 } 1398 1399 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToPtr *) { 1400 return IrInstSrcIdIntToPtr; 1401 } 1402 1403 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrToInt *) { 1404 return IrInstSrcIdPtrToInt; 1405 } 1406 1407 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToEnum *) { 1408 return IrInstSrcIdIntToEnum; 1409 } 1410 1411 static constexpr IrInstSrcId ir_inst_id(IrInstSrcEnumToInt *) { 1412 return IrInstSrcIdEnumToInt; 1413 } 1414 1415 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToErr *) { 1416 return IrInstSrcIdIntToErr; 1417 } 1418 1419 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrToInt *) { 1420 return IrInstSrcIdErrToInt; 1421 } 1422 1423 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckSwitchProngs *) { 1424 return IrInstSrcIdCheckSwitchProngs; 1425 } 1426 1427 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckStatementIsVoid *) { 1428 return IrInstSrcIdCheckStatementIsVoid; 1429 } 1430 1431 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeName *) { 1432 return IrInstSrcIdTypeName; 1433 } 1434 1435 static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclRef *) { 1436 return IrInstSrcIdDeclRef; 1437 } 1438 1439 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPanic *) { 1440 return IrInstSrcIdPanic; 1441 } 1442 1443 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTagName *) { 1444 return IrInstSrcIdTagName; 1445 } 1446 1447 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTagType *) { 1448 return IrInstSrcIdTagType; 1449 } 1450 1451 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldParentPtr *) { 1452 return IrInstSrcIdFieldParentPtr; 1453 } 1454 1455 static constexpr IrInstSrcId ir_inst_id(IrInstSrcByteOffsetOf *) { 1456 return IrInstSrcIdByteOffsetOf; 1457 } 1458 1459 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitOffsetOf *) { 1460 return IrInstSrcIdBitOffsetOf; 1461 } 1462 1463 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeInfo *) { 1464 return IrInstSrcIdTypeInfo; 1465 } 1466 1467 static constexpr IrInstSrcId ir_inst_id(IrInstSrcType *) { 1468 return IrInstSrcIdType; 1469 } 1470 1471 static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasField *) { 1472 return IrInstSrcIdHasField; 1473 } 1474 1475 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetEvalBranchQuota *) { 1476 return IrInstSrcIdSetEvalBranchQuota; 1477 } 1478 1479 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrType *) { 1480 return IrInstSrcIdPtrType; 1481 } 1482 1483 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignCast *) { 1484 return IrInstSrcIdAlignCast; 1485 } 1486 1487 static constexpr IrInstSrcId ir_inst_id(IrInstSrcImplicitCast *) { 1488 return IrInstSrcIdImplicitCast; 1489 } 1490 1491 static constexpr IrInstSrcId ir_inst_id(IrInstSrcResolveResult *) { 1492 return IrInstSrcIdResolveResult; 1493 } 1494 1495 static constexpr IrInstSrcId ir_inst_id(IrInstSrcResetResult *) { 1496 return IrInstSrcIdResetResult; 1497 } 1498 1499 static constexpr IrInstSrcId ir_inst_id(IrInstSrcOpaqueType *) { 1500 return IrInstSrcIdOpaqueType; 1501 } 1502 1503 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetAlignStack *) { 1504 return IrInstSrcIdSetAlignStack; 1505 } 1506 1507 static constexpr IrInstSrcId ir_inst_id(IrInstSrcArgType *) { 1508 return IrInstSrcIdArgType; 1509 } 1510 1511 static constexpr IrInstSrcId ir_inst_id(IrInstSrcExport *) { 1512 return IrInstSrcIdExport; 1513 } 1514 1515 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorReturnTrace *) { 1516 return IrInstSrcIdErrorReturnTrace; 1517 } 1518 1519 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorUnion *) { 1520 return IrInstSrcIdErrorUnion; 1521 } 1522 1523 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicRmw *) { 1524 return IrInstSrcIdAtomicRmw; 1525 } 1526 1527 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicLoad *) { 1528 return IrInstSrcIdAtomicLoad; 1529 } 1530 1531 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicStore *) { 1532 return IrInstSrcIdAtomicStore; 1533 } 1534 1535 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSaveErrRetAddr *) { 1536 return IrInstSrcIdSaveErrRetAddr; 1537 } 1538 1539 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAddImplicitReturnType *) { 1540 return IrInstSrcIdAddImplicitReturnType; 1541 } 1542 1543 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrSetCast *) { 1544 return IrInstSrcIdErrSetCast; 1545 } 1546 1547 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckRuntimeScope *) { 1548 return IrInstSrcIdCheckRuntimeScope; 1549 } 1550 1551 static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasDecl *) { 1552 return IrInstSrcIdHasDecl; 1553 } 1554 1555 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUndeclaredIdent *) { 1556 return IrInstSrcIdUndeclaredIdent; 1557 } 1558 1559 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlloca *) { 1560 return IrInstSrcIdAlloca; 1561 } 1562 1563 static constexpr IrInstSrcId ir_inst_id(IrInstSrcEndExpr *) { 1564 return IrInstSrcIdEndExpr; 1565 } 1566 1567 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnionInitNamedField *) { 1568 return IrInstSrcIdUnionInitNamedField; 1569 } 1570 1571 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSuspendBegin *) { 1572 return IrInstSrcIdSuspendBegin; 1573 } 1574 1575 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSuspendFinish *) { 1576 return IrInstSrcIdSuspendFinish; 1577 } 1578 1579 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAwait *) { 1580 return IrInstSrcIdAwait; 1581 } 1582 1583 static constexpr IrInstSrcId ir_inst_id(IrInstSrcResume *) { 1584 return IrInstSrcIdResume; 1585 } 1586 1587 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSpillBegin *) { 1588 return IrInstSrcIdSpillBegin; 1589 } 1590 1591 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSpillEnd *) { 1592 return IrInstSrcIdSpillEnd; 1593 } 1594 1595 1596 static constexpr IrInstGenId ir_inst_id(IrInstGenDeclVar *) { 1597 return IrInstGenIdDeclVar; 1598 } 1599 1600 static constexpr IrInstGenId ir_inst_id(IrInstGenBr *) { 1601 return IrInstGenIdBr; 1602 } 1603 1604 static constexpr IrInstGenId ir_inst_id(IrInstGenCondBr *) { 1605 return IrInstGenIdCondBr; 1606 } 1607 1608 static constexpr IrInstGenId ir_inst_id(IrInstGenSwitchBr *) { 1609 return IrInstGenIdSwitchBr; 1610 } 1611 1612 static constexpr IrInstGenId ir_inst_id(IrInstGenPhi *) { 1613 return IrInstGenIdPhi; 1614 } 1615 1616 static constexpr IrInstGenId ir_inst_id(IrInstGenBinaryNot *) { 1617 return IrInstGenIdBinaryNot; 1618 } 1619 1620 static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) { 1621 return IrInstGenIdNegation; 1622 } 1623 1624 static constexpr IrInstGenId ir_inst_id(IrInstGenNegationWrapping *) { 1625 return IrInstGenIdNegationWrapping; 1626 } 1627 1628 static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) { 1629 return IrInstGenIdBinOp; 1630 } 1631 1632 static constexpr IrInstGenId ir_inst_id(IrInstGenLoadPtr *) { 1633 return IrInstGenIdLoadPtr; 1634 } 1635 1636 static constexpr IrInstGenId ir_inst_id(IrInstGenStorePtr *) { 1637 return IrInstGenIdStorePtr; 1638 } 1639 1640 static constexpr IrInstGenId ir_inst_id(IrInstGenVectorStoreElem *) { 1641 return IrInstGenIdVectorStoreElem; 1642 } 1643 1644 static constexpr IrInstGenId ir_inst_id(IrInstGenStructFieldPtr *) { 1645 return IrInstGenIdStructFieldPtr; 1646 } 1647 1648 static constexpr IrInstGenId ir_inst_id(IrInstGenUnionFieldPtr *) { 1649 return IrInstGenIdUnionFieldPtr; 1650 } 1651 1652 static constexpr IrInstGenId ir_inst_id(IrInstGenElemPtr *) { 1653 return IrInstGenIdElemPtr; 1654 } 1655 1656 static constexpr IrInstGenId ir_inst_id(IrInstGenVarPtr *) { 1657 return IrInstGenIdVarPtr; 1658 } 1659 1660 static constexpr IrInstGenId ir_inst_id(IrInstGenReturnPtr *) { 1661 return IrInstGenIdReturnPtr; 1662 } 1663 1664 static constexpr IrInstGenId ir_inst_id(IrInstGenCall *) { 1665 return IrInstGenIdCall; 1666 } 1667 1668 static constexpr IrInstGenId ir_inst_id(IrInstGenReturn *) { 1669 return IrInstGenIdReturn; 1670 } 1671 1672 static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) { 1673 return IrInstGenIdCast; 1674 } 1675 1676 static constexpr IrInstGenId ir_inst_id(IrInstGenUnreachable *) { 1677 return IrInstGenIdUnreachable; 1678 } 1679 1680 static constexpr IrInstGenId ir_inst_id(IrInstGenAsm *) { 1681 return IrInstGenIdAsm; 1682 } 1683 1684 static constexpr IrInstGenId ir_inst_id(IrInstGenTestNonNull *) { 1685 return IrInstGenIdTestNonNull; 1686 } 1687 1688 static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalUnwrapPtr *) { 1689 return IrInstGenIdOptionalUnwrapPtr; 1690 } 1691 1692 static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalWrap *) { 1693 return IrInstGenIdOptionalWrap; 1694 } 1695 1696 static constexpr IrInstGenId ir_inst_id(IrInstGenUnionTag *) { 1697 return IrInstGenIdUnionTag; 1698 } 1699 1700 static constexpr IrInstGenId ir_inst_id(IrInstGenClz *) { 1701 return IrInstGenIdClz; 1702 } 1703 1704 static constexpr IrInstGenId ir_inst_id(IrInstGenCtz *) { 1705 return IrInstGenIdCtz; 1706 } 1707 1708 static constexpr IrInstGenId ir_inst_id(IrInstGenPopCount *) { 1709 return IrInstGenIdPopCount; 1710 } 1711 1712 static constexpr IrInstGenId ir_inst_id(IrInstGenBswap *) { 1713 return IrInstGenIdBswap; 1714 } 1715 1716 static constexpr IrInstGenId ir_inst_id(IrInstGenBitReverse *) { 1717 return IrInstGenIdBitReverse; 1718 } 1719 1720 static constexpr IrInstGenId ir_inst_id(IrInstGenRef *) { 1721 return IrInstGenIdRef; 1722 } 1723 1724 static constexpr IrInstGenId ir_inst_id(IrInstGenErrName *) { 1725 return IrInstGenIdErrName; 1726 } 1727 1728 static constexpr IrInstGenId ir_inst_id(IrInstGenCmpxchg *) { 1729 return IrInstGenIdCmpxchg; 1730 } 1731 1732 static constexpr IrInstGenId ir_inst_id(IrInstGenFence *) { 1733 return IrInstGenIdFence; 1734 } 1735 1736 static constexpr IrInstGenId ir_inst_id(IrInstGenTruncate *) { 1737 return IrInstGenIdTruncate; 1738 } 1739 1740 static constexpr IrInstGenId ir_inst_id(IrInstGenShuffleVector *) { 1741 return IrInstGenIdShuffleVector; 1742 } 1743 1744 static constexpr IrInstGenId ir_inst_id(IrInstGenSplat *) { 1745 return IrInstGenIdSplat; 1746 } 1747 1748 static constexpr IrInstGenId ir_inst_id(IrInstGenBoolNot *) { 1749 return IrInstGenIdBoolNot; 1750 } 1751 1752 static constexpr IrInstGenId ir_inst_id(IrInstGenMemset *) { 1753 return IrInstGenIdMemset; 1754 } 1755 1756 static constexpr IrInstGenId ir_inst_id(IrInstGenMemcpy *) { 1757 return IrInstGenIdMemcpy; 1758 } 1759 1760 static constexpr IrInstGenId ir_inst_id(IrInstGenSlice *) { 1761 return IrInstGenIdSlice; 1762 } 1763 1764 static constexpr IrInstGenId ir_inst_id(IrInstGenBreakpoint *) { 1765 return IrInstGenIdBreakpoint; 1766 } 1767 1768 static constexpr IrInstGenId ir_inst_id(IrInstGenReturnAddress *) { 1769 return IrInstGenIdReturnAddress; 1770 } 1771 1772 static constexpr IrInstGenId ir_inst_id(IrInstGenFrameAddress *) { 1773 return IrInstGenIdFrameAddress; 1774 } 1775 1776 static constexpr IrInstGenId ir_inst_id(IrInstGenFrameHandle *) { 1777 return IrInstGenIdFrameHandle; 1778 } 1779 1780 static constexpr IrInstGenId ir_inst_id(IrInstGenFrameSize *) { 1781 return IrInstGenIdFrameSize; 1782 } 1783 1784 static constexpr IrInstGenId ir_inst_id(IrInstGenOverflowOp *) { 1785 return IrInstGenIdOverflowOp; 1786 } 1787 1788 static constexpr IrInstGenId ir_inst_id(IrInstGenTestErr *) { 1789 return IrInstGenIdTestErr; 1790 } 1791 1792 static constexpr IrInstGenId ir_inst_id(IrInstGenMulAdd *) { 1793 return IrInstGenIdMulAdd; 1794 } 1795 1796 static constexpr IrInstGenId ir_inst_id(IrInstGenFloatOp *) { 1797 return IrInstGenIdFloatOp; 1798 } 1799 1800 static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrCode *) { 1801 return IrInstGenIdUnwrapErrCode; 1802 } 1803 1804 static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrPayload *) { 1805 return IrInstGenIdUnwrapErrPayload; 1806 } 1807 1808 static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapCode *) { 1809 return IrInstGenIdErrWrapCode; 1810 } 1811 1812 static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapPayload *) { 1813 return IrInstGenIdErrWrapPayload; 1814 } 1815 1816 static constexpr IrInstGenId ir_inst_id(IrInstGenPtrCast *) { 1817 return IrInstGenIdPtrCast; 1818 } 1819 1820 static constexpr IrInstGenId ir_inst_id(IrInstGenBitCast *) { 1821 return IrInstGenIdBitCast; 1822 } 1823 1824 static constexpr IrInstGenId ir_inst_id(IrInstGenWidenOrShorten *) { 1825 return IrInstGenIdWidenOrShorten; 1826 } 1827 1828 static constexpr IrInstGenId ir_inst_id(IrInstGenIntToPtr *) { 1829 return IrInstGenIdIntToPtr; 1830 } 1831 1832 static constexpr IrInstGenId ir_inst_id(IrInstGenPtrToInt *) { 1833 return IrInstGenIdPtrToInt; 1834 } 1835 1836 static constexpr IrInstGenId ir_inst_id(IrInstGenIntToEnum *) { 1837 return IrInstGenIdIntToEnum; 1838 } 1839 1840 static constexpr IrInstGenId ir_inst_id(IrInstGenIntToErr *) { 1841 return IrInstGenIdIntToErr; 1842 } 1843 1844 static constexpr IrInstGenId ir_inst_id(IrInstGenErrToInt *) { 1845 return IrInstGenIdErrToInt; 1846 } 1847 1848 static constexpr IrInstGenId ir_inst_id(IrInstGenPanic *) { 1849 return IrInstGenIdPanic; 1850 } 1851 1852 static constexpr IrInstGenId ir_inst_id(IrInstGenTagName *) { 1853 return IrInstGenIdTagName; 1854 } 1855 1856 static constexpr IrInstGenId ir_inst_id(IrInstGenFieldParentPtr *) { 1857 return IrInstGenIdFieldParentPtr; 1858 } 1859 1860 static constexpr IrInstGenId ir_inst_id(IrInstGenAlignCast *) { 1861 return IrInstGenIdAlignCast; 1862 } 1863 1864 static constexpr IrInstGenId ir_inst_id(IrInstGenErrorReturnTrace *) { 1865 return IrInstGenIdErrorReturnTrace; 1866 } 1867 1868 static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicRmw *) { 1869 return IrInstGenIdAtomicRmw; 1870 } 1871 1872 static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicLoad *) { 1873 return IrInstGenIdAtomicLoad; 1874 } 1875 1876 static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicStore *) { 1877 return IrInstGenIdAtomicStore; 1878 } 1879 1880 static constexpr IrInstGenId ir_inst_id(IrInstGenSaveErrRetAddr *) { 1881 return IrInstGenIdSaveErrRetAddr; 1882 } 1883 1884 static constexpr IrInstGenId ir_inst_id(IrInstGenVectorToArray *) { 1885 return IrInstGenIdVectorToArray; 1886 } 1887 1888 static constexpr IrInstGenId ir_inst_id(IrInstGenArrayToVector *) { 1889 return IrInstGenIdArrayToVector; 1890 } 1891 1892 static constexpr IrInstGenId ir_inst_id(IrInstGenAssertZero *) { 1893 return IrInstGenIdAssertZero; 1894 } 1895 1896 static constexpr IrInstGenId ir_inst_id(IrInstGenAssertNonNull *) { 1897 return IrInstGenIdAssertNonNull; 1898 } 1899 1900 static constexpr IrInstGenId ir_inst_id(IrInstGenPtrOfArrayToSlice *) { 1901 return IrInstGenIdPtrOfArrayToSlice; 1902 } 1903 1904 static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendBegin *) { 1905 return IrInstGenIdSuspendBegin; 1906 } 1907 1908 static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendFinish *) { 1909 return IrInstGenIdSuspendFinish; 1910 } 1911 1912 static constexpr IrInstGenId ir_inst_id(IrInstGenAwait *) { 1913 return IrInstGenIdAwait; 1914 } 1915 1916 static constexpr IrInstGenId ir_inst_id(IrInstGenResume *) { 1917 return IrInstGenIdResume; 1918 } 1919 1920 static constexpr IrInstGenId ir_inst_id(IrInstGenSpillBegin *) { 1921 return IrInstGenIdSpillBegin; 1922 } 1923 1924 static constexpr IrInstGenId ir_inst_id(IrInstGenSpillEnd *) { 1925 return IrInstGenIdSpillEnd; 1926 } 1927 1928 static constexpr IrInstGenId ir_inst_id(IrInstGenVectorExtractElem *) { 1929 return IrInstGenIdVectorExtractElem; 1930 } 1931 1932 static constexpr IrInstGenId ir_inst_id(IrInstGenAlloca *) { 1933 return IrInstGenIdAlloca; 1934 } 1935 1936 static constexpr IrInstGenId ir_inst_id(IrInstGenConst *) { 1937 return IrInstGenIdConst; 1938 } 1939 1940 template<typename T> 1941 static T *ir_create_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 1942 T *special_instruction = heap::c_allocator.create<T>(); 1943 special_instruction->base.id = ir_inst_id(special_instruction); 1944 special_instruction->base.base.scope = scope; 1945 special_instruction->base.base.source_node = source_node; 1946 special_instruction->base.base.debug_id = exec_next_debug_id(irb->exec); 1947 special_instruction->base.owner_bb = irb->current_basic_block; 1948 return special_instruction; 1949 } 1950 1951 template<typename T> 1952 static T *ir_create_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 1953 T *special_instruction = heap::c_allocator.create<T>(); 1954 special_instruction->base.id = ir_inst_id(special_instruction); 1955 special_instruction->base.base.scope = scope; 1956 special_instruction->base.base.source_node = source_node; 1957 special_instruction->base.base.debug_id = exec_next_debug_id_gen(irb->exec); 1958 special_instruction->base.owner_bb = irb->current_basic_block; 1959 special_instruction->base.value = irb->codegen->pass1_arena->create<ZigValue>(); 1960 return special_instruction; 1961 } 1962 1963 template<typename T> 1964 static T *ir_create_inst_noval(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 1965 T *special_instruction = heap::c_allocator.create<T>(); 1966 special_instruction->base.id = ir_inst_id(special_instruction); 1967 special_instruction->base.base.scope = scope; 1968 special_instruction->base.base.source_node = source_node; 1969 special_instruction->base.base.debug_id = exec_next_debug_id_gen(irb->exec); 1970 special_instruction->base.owner_bb = irb->current_basic_block; 1971 return special_instruction; 1972 } 1973 1974 template<typename T> 1975 static T *ir_build_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 1976 T *special_instruction = ir_create_instruction<T>(irb, scope, source_node); 1977 ir_instruction_append(irb->current_basic_block, &special_instruction->base); 1978 return special_instruction; 1979 } 1980 1981 template<typename T> 1982 static T *ir_build_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 1983 T *special_instruction = ir_create_inst_gen<T>(irb, scope, source_node); 1984 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base); 1985 return special_instruction; 1986 } 1987 1988 template<typename T> 1989 static T *ir_build_inst_noreturn(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 1990 T *special_instruction = ir_create_inst_noval<T>(irb, scope, source_node); 1991 special_instruction->base.value = irb->codegen->intern.for_unreachable(); 1992 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base); 1993 return special_instruction; 1994 } 1995 1996 template<typename T> 1997 static T *ir_build_inst_void(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 1998 T *special_instruction = ir_create_inst_noval<T>(irb, scope, source_node); 1999 special_instruction->base.value = irb->codegen->intern.for_void(); 2000 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base); 2001 return special_instruction; 2002 } 2003 2004 IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn, 2005 ZigType *var_type, const char *name_hint) 2006 { 2007 IrInstGenAlloca *alloca_gen = heap::c_allocator.create<IrInstGenAlloca>(); 2008 alloca_gen->base.id = IrInstGenIdAlloca; 2009 alloca_gen->base.base.source_node = source_node; 2010 alloca_gen->base.base.scope = scope; 2011 alloca_gen->base.value = g->pass1_arena->create<ZigValue>(); 2012 alloca_gen->base.value->type = get_pointer_to_type(g, var_type, false); 2013 alloca_gen->base.base.ref_count = 1; 2014 alloca_gen->name_hint = name_hint; 2015 fn->alloca_gen_list.append(alloca_gen); 2016 return &alloca_gen->base; 2017 } 2018 2019 static IrInstGen *ir_build_cast(IrAnalyze *ira, IrInst *source_instr,ZigType *dest_type, 2020 IrInstGen *value, CastOp cast_op) 2021 { 2022 IrInstGenCast *inst = ir_build_inst_gen<IrInstGenCast>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2023 inst->base.value->type = dest_type; 2024 inst->value = value; 2025 inst->cast_op = cast_op; 2026 2027 ir_ref_inst_gen(value, ira->new_irb.current_basic_block); 2028 2029 return &inst->base; 2030 } 2031 2032 static IrInstSrc *ir_build_cond_br(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *condition, 2033 IrBasicBlockSrc *then_block, IrBasicBlockSrc *else_block, IrInstSrc *is_comptime) 2034 { 2035 IrInstSrcCondBr *inst = ir_build_instruction<IrInstSrcCondBr>(irb, scope, source_node); 2036 inst->base.is_noreturn = true; 2037 inst->condition = condition; 2038 inst->then_block = then_block; 2039 inst->else_block = else_block; 2040 inst->is_comptime = is_comptime; 2041 2042 ir_ref_instruction(condition, irb->current_basic_block); 2043 ir_ref_bb(then_block); 2044 ir_ref_bb(else_block); 2045 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); 2046 2047 return &inst->base; 2048 } 2049 2050 static IrInstGen *ir_build_cond_br_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *condition, 2051 IrBasicBlockGen *then_block, IrBasicBlockGen *else_block) 2052 { 2053 IrInstGenCondBr *inst = ir_build_inst_noreturn<IrInstGenCondBr>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2054 inst->condition = condition; 2055 inst->then_block = then_block; 2056 inst->else_block = else_block; 2057 2058 ir_ref_inst_gen(condition, ira->new_irb.current_basic_block); 2059 ir_ref_bb_gen(then_block); 2060 ir_ref_bb_gen(else_block); 2061 2062 return &inst->base; 2063 } 2064 2065 static IrInstSrc *ir_build_return_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *operand) { 2066 IrInstSrcReturn *inst = ir_build_instruction<IrInstSrcReturn>(irb, scope, source_node); 2067 inst->base.is_noreturn = true; 2068 inst->operand = operand; 2069 2070 if (operand != nullptr) ir_ref_instruction(operand, irb->current_basic_block); 2071 2072 return &inst->base; 2073 } 2074 2075 static IrInstGen *ir_build_return_gen(IrAnalyze *ira, IrInst *source_inst, IrInstGen *operand) { 2076 IrInstGenReturn *inst = ir_build_inst_noreturn<IrInstGenReturn>(&ira->new_irb, 2077 source_inst->scope, source_inst->source_node); 2078 inst->operand = operand; 2079 2080 if (operand != nullptr) ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); 2081 2082 return &inst->base; 2083 } 2084 2085 static IrInstSrc *ir_build_const_void(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2086 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2087 ir_instruction_append(irb->current_basic_block, &const_instruction->base); 2088 const_instruction->value = irb->codegen->intern.for_void(); 2089 return &const_instruction->base; 2090 } 2091 2092 static IrInstSrc *ir_build_const_undefined(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2093 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2094 ir_instruction_append(irb->current_basic_block, &const_instruction->base); 2095 const_instruction->value = irb->codegen->intern.for_undefined(); 2096 return &const_instruction->base; 2097 } 2098 2099 static IrInstSrc *ir_build_const_uint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, uint64_t value) { 2100 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2101 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2102 const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_int; 2103 const_instruction->value->special = ConstValSpecialStatic; 2104 bigint_init_unsigned(&const_instruction->value->data.x_bigint, value); 2105 return &const_instruction->base; 2106 } 2107 2108 static IrInstSrc *ir_build_const_bigint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigInt *bigint) { 2109 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2110 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2111 const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_int; 2112 const_instruction->value->special = ConstValSpecialStatic; 2113 bigint_init_bigint(&const_instruction->value->data.x_bigint, bigint); 2114 return &const_instruction->base; 2115 } 2116 2117 static IrInstSrc *ir_build_const_bigfloat(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigFloat *bigfloat) { 2118 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2119 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2120 const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_float; 2121 const_instruction->value->special = ConstValSpecialStatic; 2122 bigfloat_init_bigfloat(&const_instruction->value->data.x_bigfloat, bigfloat); 2123 return &const_instruction->base; 2124 } 2125 2126 static IrInstSrc *ir_build_const_null(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2127 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2128 ir_instruction_append(irb->current_basic_block, &const_instruction->base); 2129 const_instruction->value = irb->codegen->intern.for_null(); 2130 return &const_instruction->base; 2131 } 2132 2133 static IrInstSrc *ir_build_const_usize(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, uint64_t value) { 2134 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2135 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2136 const_instruction->value->type = irb->codegen->builtin_types.entry_usize; 2137 const_instruction->value->special = ConstValSpecialStatic; 2138 bigint_init_unsigned(&const_instruction->value->data.x_bigint, value); 2139 return &const_instruction->base; 2140 } 2141 2142 static IrInstSrc *ir_create_const_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2143 ZigType *type_entry) 2144 { 2145 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2146 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2147 const_instruction->value->type = irb->codegen->builtin_types.entry_type; 2148 const_instruction->value->special = ConstValSpecialStatic; 2149 const_instruction->value->data.x_type = type_entry; 2150 return &const_instruction->base; 2151 } 2152 2153 static IrInstSrc *ir_build_const_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2154 ZigType *type_entry) 2155 { 2156 IrInstSrc *instruction = ir_create_const_type(irb, scope, source_node, type_entry); 2157 ir_instruction_append(irb->current_basic_block, instruction); 2158 return instruction; 2159 } 2160 2161 static IrInstSrc *ir_build_const_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigType *import) { 2162 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2163 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2164 const_instruction->value->type = irb->codegen->builtin_types.entry_type; 2165 const_instruction->value->special = ConstValSpecialStatic; 2166 const_instruction->value->data.x_type = import; 2167 return &const_instruction->base; 2168 } 2169 2170 static IrInstSrc *ir_build_const_bool(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, bool value) { 2171 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2172 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2173 const_instruction->value->type = irb->codegen->builtin_types.entry_bool; 2174 const_instruction->value->special = ConstValSpecialStatic; 2175 const_instruction->value->data.x_bool = value; 2176 return &const_instruction->base; 2177 } 2178 2179 static IrInstSrc *ir_build_const_enum_literal(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *name) { 2180 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2181 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2182 const_instruction->value->type = irb->codegen->builtin_types.entry_enum_literal; 2183 const_instruction->value->special = ConstValSpecialStatic; 2184 const_instruction->value->data.x_enum_literal = name; 2185 return &const_instruction->base; 2186 } 2187 2188 static IrInstSrc *ir_create_const_str_lit(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *str) { 2189 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2190 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2191 init_const_str_lit(irb->codegen, const_instruction->value, str); 2192 2193 return &const_instruction->base; 2194 } 2195 2196 static IrInstSrc *ir_build_const_str_lit(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *str) { 2197 IrInstSrc *instruction = ir_create_const_str_lit(irb, scope, source_node, str); 2198 ir_instruction_append(irb->current_basic_block, instruction); 2199 return instruction; 2200 } 2201 2202 static IrInstSrc *ir_build_bin_op(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, 2203 IrInstSrc *op1, IrInstSrc *op2, bool safety_check_on) 2204 { 2205 IrInstSrcBinOp *inst = ir_build_instruction<IrInstSrcBinOp>(irb, scope, source_node); 2206 inst->op_id = op_id; 2207 inst->op1 = op1; 2208 inst->op2 = op2; 2209 inst->safety_check_on = safety_check_on; 2210 2211 ir_ref_instruction(op1, irb->current_basic_block); 2212 ir_ref_instruction(op2, irb->current_basic_block); 2213 2214 return &inst->base; 2215 } 2216 2217 static IrInstGen *ir_build_bin_op_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *res_type, 2218 IrBinOp op_id, IrInstGen *op1, IrInstGen *op2, bool safety_check_on) 2219 { 2220 IrInstGenBinOp *inst = ir_build_inst_gen<IrInstGenBinOp>(&ira->new_irb, 2221 source_instr->scope, source_instr->source_node); 2222 inst->base.value->type = res_type; 2223 inst->op_id = op_id; 2224 inst->op1 = op1; 2225 inst->op2 = op2; 2226 inst->safety_check_on = safety_check_on; 2227 2228 ir_ref_inst_gen(op1, ira->new_irb.current_basic_block); 2229 ir_ref_inst_gen(op2, ira->new_irb.current_basic_block); 2230 2231 return &inst->base; 2232 } 2233 2234 2235 static IrInstSrc *ir_build_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2236 IrInstSrc *op1, IrInstSrc *op2, Buf *type_name) 2237 { 2238 IrInstSrcMergeErrSets *inst = ir_build_instruction<IrInstSrcMergeErrSets>(irb, scope, source_node); 2239 inst->op1 = op1; 2240 inst->op2 = op2; 2241 inst->type_name = type_name; 2242 2243 ir_ref_instruction(op1, irb->current_basic_block); 2244 ir_ref_instruction(op2, irb->current_basic_block); 2245 2246 return &inst->base; 2247 } 2248 2249 static IrInstSrc *ir_build_var_ptr_x(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var, 2250 ScopeFnDef *crossed_fndef_scope) 2251 { 2252 IrInstSrcVarPtr *instruction = ir_build_instruction<IrInstSrcVarPtr>(irb, scope, source_node); 2253 instruction->var = var; 2254 instruction->crossed_fndef_scope = crossed_fndef_scope; 2255 2256 ir_ref_var(var); 2257 2258 return &instruction->base; 2259 } 2260 2261 static IrInstSrc *ir_build_var_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var) { 2262 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr); 2263 } 2264 2265 static IrInstGen *ir_build_var_ptr_gen(IrAnalyze *ira, IrInst *source_instr, ZigVar *var) { 2266 IrInstGenVarPtr *instruction = ir_build_inst_gen<IrInstGenVarPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2267 instruction->var = var; 2268 2269 ir_ref_var(var); 2270 2271 return &instruction->base; 2272 } 2273 2274 static IrInstGen *ir_build_return_ptr(IrAnalyze *ira, Scope *scope, AstNode *source_node, ZigType *ty) { 2275 IrInstGenReturnPtr *instruction = ir_build_inst_gen<IrInstGenReturnPtr>(&ira->new_irb, scope, source_node); 2276 instruction->base.value->type = ty; 2277 return &instruction->base; 2278 } 2279 2280 static IrInstSrc *ir_build_elem_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2281 IrInstSrc *array_ptr, IrInstSrc *elem_index, bool safety_check_on, PtrLen ptr_len, 2282 AstNode *init_array_type_source_node) 2283 { 2284 IrInstSrcElemPtr *instruction = ir_build_instruction<IrInstSrcElemPtr>(irb, scope, source_node); 2285 instruction->array_ptr = array_ptr; 2286 instruction->elem_index = elem_index; 2287 instruction->safety_check_on = safety_check_on; 2288 instruction->ptr_len = ptr_len; 2289 instruction->init_array_type_source_node = init_array_type_source_node; 2290 2291 ir_ref_instruction(array_ptr, irb->current_basic_block); 2292 ir_ref_instruction(elem_index, irb->current_basic_block); 2293 2294 return &instruction->base; 2295 } 2296 2297 static IrInstGen *ir_build_elem_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 2298 IrInstGen *array_ptr, IrInstGen *elem_index, bool safety_check_on, ZigType *return_type) 2299 { 2300 IrInstGenElemPtr *instruction = ir_build_inst_gen<IrInstGenElemPtr>(&ira->new_irb, scope, source_node); 2301 instruction->base.value->type = return_type; 2302 instruction->array_ptr = array_ptr; 2303 instruction->elem_index = elem_index; 2304 instruction->safety_check_on = safety_check_on; 2305 2306 ir_ref_inst_gen(array_ptr, ira->new_irb.current_basic_block); 2307 ir_ref_inst_gen(elem_index, ira->new_irb.current_basic_block); 2308 2309 return &instruction->base; 2310 } 2311 2312 static IrInstSrc *ir_build_field_ptr_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2313 IrInstSrc *container_ptr, IrInstSrc *field_name_expr, bool initializing) 2314 { 2315 IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(irb, scope, source_node); 2316 instruction->container_ptr = container_ptr; 2317 instruction->field_name_buffer = nullptr; 2318 instruction->field_name_expr = field_name_expr; 2319 instruction->initializing = initializing; 2320 2321 ir_ref_instruction(container_ptr, irb->current_basic_block); 2322 ir_ref_instruction(field_name_expr, irb->current_basic_block); 2323 2324 return &instruction->base; 2325 } 2326 2327 static IrInstSrc *ir_build_field_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2328 IrInstSrc *container_ptr, Buf *field_name, bool initializing) 2329 { 2330 IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(irb, scope, source_node); 2331 instruction->container_ptr = container_ptr; 2332 instruction->field_name_buffer = field_name; 2333 instruction->field_name_expr = nullptr; 2334 instruction->initializing = initializing; 2335 2336 ir_ref_instruction(container_ptr, irb->current_basic_block); 2337 2338 return &instruction->base; 2339 } 2340 2341 static IrInstSrc *ir_build_has_field(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2342 IrInstSrc *container_type, IrInstSrc *field_name) 2343 { 2344 IrInstSrcHasField *instruction = ir_build_instruction<IrInstSrcHasField>(irb, scope, source_node); 2345 instruction->container_type = container_type; 2346 instruction->field_name = field_name; 2347 2348 ir_ref_instruction(container_type, irb->current_basic_block); 2349 ir_ref_instruction(field_name, irb->current_basic_block); 2350 2351 return &instruction->base; 2352 } 2353 2354 static IrInstGen *ir_build_struct_field_ptr(IrAnalyze *ira, IrInst *source_instr, 2355 IrInstGen *struct_ptr, TypeStructField *field, ZigType *ptr_type) 2356 { 2357 IrInstGenStructFieldPtr *inst = ir_build_inst_gen<IrInstGenStructFieldPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2358 inst->base.value->type = ptr_type; 2359 inst->struct_ptr = struct_ptr; 2360 inst->field = field; 2361 2362 ir_ref_inst_gen(struct_ptr, ira->new_irb.current_basic_block); 2363 2364 return &inst->base; 2365 } 2366 2367 static IrInstGen *ir_build_union_field_ptr(IrAnalyze *ira, IrInst *source_instr, 2368 IrInstGen *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing, ZigType *ptr_type) 2369 { 2370 IrInstGenUnionFieldPtr *inst = ir_build_inst_gen<IrInstGenUnionFieldPtr>(&ira->new_irb, 2371 source_instr->scope, source_instr->source_node); 2372 inst->base.value->type = ptr_type; 2373 inst->initializing = initializing; 2374 inst->safety_check_on = safety_check_on; 2375 inst->union_ptr = union_ptr; 2376 inst->field = field; 2377 2378 ir_ref_inst_gen(union_ptr, ira->new_irb.current_basic_block); 2379 2380 return &inst->base; 2381 } 2382 2383 static IrInstSrc *ir_build_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2384 IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc *args, ResultLoc *result_loc) 2385 { 2386 IrInstSrcCallExtra *call_instruction = ir_build_instruction<IrInstSrcCallExtra>(irb, scope, source_node); 2387 call_instruction->options = options; 2388 call_instruction->fn_ref = fn_ref; 2389 call_instruction->args = args; 2390 call_instruction->result_loc = result_loc; 2391 2392 ir_ref_instruction(options, irb->current_basic_block); 2393 ir_ref_instruction(fn_ref, irb->current_basic_block); 2394 ir_ref_instruction(args, irb->current_basic_block); 2395 2396 return &call_instruction->base; 2397 } 2398 2399 static IrInstSrc *ir_build_call_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2400 IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc **args_ptr, size_t args_len, 2401 ResultLoc *result_loc) 2402 { 2403 IrInstSrcCallArgs *call_instruction = ir_build_instruction<IrInstSrcCallArgs>(irb, scope, source_node); 2404 call_instruction->options = options; 2405 call_instruction->fn_ref = fn_ref; 2406 call_instruction->args_ptr = args_ptr; 2407 call_instruction->args_len = args_len; 2408 call_instruction->result_loc = result_loc; 2409 2410 ir_ref_instruction(options, irb->current_basic_block); 2411 ir_ref_instruction(fn_ref, irb->current_basic_block); 2412 for (size_t i = 0; i < args_len; i += 1) 2413 ir_ref_instruction(args_ptr[i], irb->current_basic_block); 2414 2415 return &call_instruction->base; 2416 } 2417 2418 static IrInstSrc *ir_build_call_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2419 ZigFn *fn_entry, IrInstSrc *fn_ref, size_t arg_count, IrInstSrc **args, 2420 IrInstSrc *ret_ptr, CallModifier modifier, bool is_async_call_builtin, 2421 IrInstSrc *new_stack, ResultLoc *result_loc) 2422 { 2423 IrInstSrcCall *call_instruction = ir_build_instruction<IrInstSrcCall>(irb, scope, source_node); 2424 call_instruction->fn_entry = fn_entry; 2425 call_instruction->fn_ref = fn_ref; 2426 call_instruction->args = args; 2427 call_instruction->arg_count = arg_count; 2428 call_instruction->modifier = modifier; 2429 call_instruction->is_async_call_builtin = is_async_call_builtin; 2430 call_instruction->new_stack = new_stack; 2431 call_instruction->result_loc = result_loc; 2432 call_instruction->ret_ptr = ret_ptr; 2433 2434 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); 2435 for (size_t i = 0; i < arg_count; i += 1) 2436 ir_ref_instruction(args[i], irb->current_basic_block); 2437 if (ret_ptr != nullptr) ir_ref_instruction(ret_ptr, irb->current_basic_block); 2438 if (new_stack != nullptr) ir_ref_instruction(new_stack, irb->current_basic_block); 2439 2440 return &call_instruction->base; 2441 } 2442 2443 static IrInstGenCall *ir_build_call_gen(IrAnalyze *ira, IrInst *source_instruction, 2444 ZigFn *fn_entry, IrInstGen *fn_ref, size_t arg_count, IrInstGen **args, 2445 CallModifier modifier, IrInstGen *new_stack, bool is_async_call_builtin, 2446 IrInstGen *result_loc, ZigType *return_type) 2447 { 2448 IrInstGenCall *call_instruction = ir_build_inst_gen<IrInstGenCall>(&ira->new_irb, 2449 source_instruction->scope, source_instruction->source_node); 2450 call_instruction->base.value->type = return_type; 2451 call_instruction->fn_entry = fn_entry; 2452 call_instruction->fn_ref = fn_ref; 2453 call_instruction->args = args; 2454 call_instruction->arg_count = arg_count; 2455 call_instruction->modifier = modifier; 2456 call_instruction->is_async_call_builtin = is_async_call_builtin; 2457 call_instruction->new_stack = new_stack; 2458 call_instruction->result_loc = result_loc; 2459 2460 if (fn_ref != nullptr) ir_ref_inst_gen(fn_ref, ira->new_irb.current_basic_block); 2461 for (size_t i = 0; i < arg_count; i += 1) 2462 ir_ref_inst_gen(args[i], ira->new_irb.current_basic_block); 2463 if (new_stack != nullptr) ir_ref_inst_gen(new_stack, ira->new_irb.current_basic_block); 2464 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); 2465 2466 return call_instruction; 2467 } 2468 2469 static IrInstSrc *ir_build_phi(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2470 size_t incoming_count, IrBasicBlockSrc **incoming_blocks, IrInstSrc **incoming_values, 2471 ResultLocPeerParent *peer_parent) 2472 { 2473 assert(incoming_count != 0); 2474 assert(incoming_count != SIZE_MAX); 2475 2476 IrInstSrcPhi *phi_instruction = ir_build_instruction<IrInstSrcPhi>(irb, scope, source_node); 2477 phi_instruction->incoming_count = incoming_count; 2478 phi_instruction->incoming_blocks = incoming_blocks; 2479 phi_instruction->incoming_values = incoming_values; 2480 phi_instruction->peer_parent = peer_parent; 2481 2482 for (size_t i = 0; i < incoming_count; i += 1) { 2483 ir_ref_bb(incoming_blocks[i]); 2484 ir_ref_instruction(incoming_values[i], irb->current_basic_block); 2485 } 2486 2487 return &phi_instruction->base; 2488 } 2489 2490 static IrInstGen *ir_build_phi_gen(IrAnalyze *ira, IrInst *source_instr, size_t incoming_count, 2491 IrBasicBlockGen **incoming_blocks, IrInstGen **incoming_values, ZigType *result_type) 2492 { 2493 assert(incoming_count != 0); 2494 assert(incoming_count != SIZE_MAX); 2495 2496 IrInstGenPhi *phi_instruction = ir_build_inst_gen<IrInstGenPhi>(&ira->new_irb, 2497 source_instr->scope, source_instr->source_node); 2498 phi_instruction->base.value->type = result_type; 2499 phi_instruction->incoming_count = incoming_count; 2500 phi_instruction->incoming_blocks = incoming_blocks; 2501 phi_instruction->incoming_values = incoming_values; 2502 2503 for (size_t i = 0; i < incoming_count; i += 1) { 2504 ir_ref_bb_gen(incoming_blocks[i]); 2505 ir_ref_inst_gen(incoming_values[i], ira->new_irb.current_basic_block); 2506 } 2507 2508 return &phi_instruction->base; 2509 } 2510 2511 static IrInstSrc *ir_build_br(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2512 IrBasicBlockSrc *dest_block, IrInstSrc *is_comptime) 2513 { 2514 IrInstSrcBr *inst = ir_build_instruction<IrInstSrcBr>(irb, scope, source_node); 2515 inst->base.is_noreturn = true; 2516 inst->dest_block = dest_block; 2517 inst->is_comptime = is_comptime; 2518 2519 ir_ref_bb(dest_block); 2520 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 2521 2522 return &inst->base; 2523 } 2524 2525 static IrInstGen *ir_build_br_gen(IrAnalyze *ira, IrInst *source_instr, IrBasicBlockGen *dest_block) { 2526 IrInstGenBr *inst = ir_build_inst_noreturn<IrInstGenBr>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2527 inst->dest_block = dest_block; 2528 2529 ir_ref_bb_gen(dest_block); 2530 2531 return &inst->base; 2532 } 2533 2534 static IrInstSrc *ir_build_ptr_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2535 IrInstSrc *child_type, bool is_const, bool is_volatile, PtrLen ptr_len, 2536 IrInstSrc *sentinel, IrInstSrc *align_value, 2537 uint32_t bit_offset_start, uint32_t host_int_bytes, bool is_allow_zero) 2538 { 2539 IrInstSrcPtrType *inst = ir_build_instruction<IrInstSrcPtrType>(irb, scope, source_node); 2540 inst->sentinel = sentinel; 2541 inst->align_value = align_value; 2542 inst->child_type = child_type; 2543 inst->is_const = is_const; 2544 inst->is_volatile = is_volatile; 2545 inst->ptr_len = ptr_len; 2546 inst->bit_offset_start = bit_offset_start; 2547 inst->host_int_bytes = host_int_bytes; 2548 inst->is_allow_zero = is_allow_zero; 2549 2550 if (sentinel) ir_ref_instruction(sentinel, irb->current_basic_block); 2551 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 2552 ir_ref_instruction(child_type, irb->current_basic_block); 2553 2554 return &inst->base; 2555 } 2556 2557 static IrInstSrc *ir_build_un_op_lval(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, 2558 IrInstSrc *value, LVal lval, ResultLoc *result_loc) 2559 { 2560 IrInstSrcUnOp *instruction = ir_build_instruction<IrInstSrcUnOp>(irb, scope, source_node); 2561 instruction->op_id = op_id; 2562 instruction->value = value; 2563 instruction->lval = lval; 2564 instruction->result_loc = result_loc; 2565 2566 ir_ref_instruction(value, irb->current_basic_block); 2567 2568 return &instruction->base; 2569 } 2570 2571 static IrInstSrc *ir_build_un_op(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, 2572 IrInstSrc *value) 2573 { 2574 return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr); 2575 } 2576 2577 static IrInstGen *ir_build_negation(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, ZigType *expr_type) { 2578 IrInstGenNegation *instruction = ir_build_inst_gen<IrInstGenNegation>(&ira->new_irb, 2579 source_instr->scope, source_instr->source_node); 2580 instruction->base.value->type = expr_type; 2581 instruction->operand = operand; 2582 2583 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); 2584 2585 return &instruction->base; 2586 } 2587 2588 static IrInstGen *ir_build_negation_wrapping(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, 2589 ZigType *expr_type) 2590 { 2591 IrInstGenNegationWrapping *instruction = ir_build_inst_gen<IrInstGenNegationWrapping>(&ira->new_irb, 2592 source_instr->scope, source_instr->source_node); 2593 instruction->base.value->type = expr_type; 2594 instruction->operand = operand; 2595 2596 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); 2597 2598 return &instruction->base; 2599 } 2600 2601 static IrInstGen *ir_build_binary_not(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, 2602 ZigType *expr_type) 2603 { 2604 IrInstGenBinaryNot *instruction = ir_build_inst_gen<IrInstGenBinaryNot>(&ira->new_irb, 2605 source_instr->scope, source_instr->source_node); 2606 instruction->base.value->type = expr_type; 2607 instruction->operand = operand; 2608 2609 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); 2610 2611 return &instruction->base; 2612 } 2613 2614 static IrInstSrc *ir_build_container_init_list(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2615 size_t item_count, IrInstSrc **elem_result_loc_list, IrInstSrc *result_loc, 2616 AstNode *init_array_type_source_node) 2617 { 2618 IrInstSrcContainerInitList *container_init_list_instruction = 2619 ir_build_instruction<IrInstSrcContainerInitList>(irb, scope, source_node); 2620 container_init_list_instruction->item_count = item_count; 2621 container_init_list_instruction->elem_result_loc_list = elem_result_loc_list; 2622 container_init_list_instruction->result_loc = result_loc; 2623 container_init_list_instruction->init_array_type_source_node = init_array_type_source_node; 2624 2625 for (size_t i = 0; i < item_count; i += 1) { 2626 ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block); 2627 } 2628 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 2629 2630 return &container_init_list_instruction->base; 2631 } 2632 2633 static IrInstSrc *ir_build_container_init_fields(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2634 size_t field_count, IrInstSrcContainerInitFieldsField *fields, IrInstSrc *result_loc) 2635 { 2636 IrInstSrcContainerInitFields *container_init_fields_instruction = 2637 ir_build_instruction<IrInstSrcContainerInitFields>(irb, scope, source_node); 2638 container_init_fields_instruction->field_count = field_count; 2639 container_init_fields_instruction->fields = fields; 2640 container_init_fields_instruction->result_loc = result_loc; 2641 2642 for (size_t i = 0; i < field_count; i += 1) { 2643 ir_ref_instruction(fields[i].result_loc, irb->current_basic_block); 2644 } 2645 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 2646 2647 return &container_init_fields_instruction->base; 2648 } 2649 2650 static IrInstSrc *ir_build_unreachable(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2651 IrInstSrcUnreachable *inst = ir_build_instruction<IrInstSrcUnreachable>(irb, scope, source_node); 2652 inst->base.is_noreturn = true; 2653 return &inst->base; 2654 } 2655 2656 static IrInstGen *ir_build_unreachable_gen(IrAnalyze *ira, IrInst *source_instr) { 2657 IrInstGenUnreachable *inst = ir_build_inst_noreturn<IrInstGenUnreachable>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2658 return &inst->base; 2659 } 2660 2661 static IrInstSrcStorePtr *ir_build_store_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2662 IrInstSrc *ptr, IrInstSrc *value) 2663 { 2664 IrInstSrcStorePtr *instruction = ir_build_instruction<IrInstSrcStorePtr>(irb, scope, source_node); 2665 instruction->ptr = ptr; 2666 instruction->value = value; 2667 2668 ir_ref_instruction(ptr, irb->current_basic_block); 2669 ir_ref_instruction(value, irb->current_basic_block); 2670 2671 return instruction; 2672 } 2673 2674 static IrInstGen *ir_build_store_ptr_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *ptr, IrInstGen *value) { 2675 IrInstGenStorePtr *instruction = ir_build_inst_void<IrInstGenStorePtr>(&ira->new_irb, 2676 source_instr->scope, source_instr->source_node); 2677 instruction->ptr = ptr; 2678 instruction->value = value; 2679 2680 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); 2681 ir_ref_inst_gen(value, ira->new_irb.current_basic_block); 2682 2683 return &instruction->base; 2684 } 2685 2686 static IrInstGen *ir_build_vector_store_elem(IrAnalyze *ira, IrInst *src_inst, 2687 IrInstGen *vector_ptr, IrInstGen *index, IrInstGen *value) 2688 { 2689 IrInstGenVectorStoreElem *inst = ir_build_inst_void<IrInstGenVectorStoreElem>( 2690 &ira->new_irb, src_inst->scope, src_inst->source_node); 2691 inst->vector_ptr = vector_ptr; 2692 inst->index = index; 2693 inst->value = value; 2694 2695 ir_ref_inst_gen(vector_ptr, ira->new_irb.current_basic_block); 2696 ir_ref_inst_gen(index, ira->new_irb.current_basic_block); 2697 ir_ref_inst_gen(value, ira->new_irb.current_basic_block); 2698 2699 return &inst->base; 2700 } 2701 2702 static IrInstSrc *ir_build_var_decl_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2703 ZigVar *var, IrInstSrc *align_value, IrInstSrc *ptr) 2704 { 2705 IrInstSrcDeclVar *inst = ir_build_instruction<IrInstSrcDeclVar>(irb, scope, source_node); 2706 inst->var = var; 2707 inst->align_value = align_value; 2708 inst->ptr = ptr; 2709 2710 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 2711 ir_ref_instruction(ptr, irb->current_basic_block); 2712 2713 return &inst->base; 2714 } 2715 2716 static IrInstGen *ir_build_var_decl_gen(IrAnalyze *ira, IrInst *source_instruction, 2717 ZigVar *var, IrInstGen *var_ptr) 2718 { 2719 IrInstGenDeclVar *inst = ir_build_inst_gen<IrInstGenDeclVar>(&ira->new_irb, 2720 source_instruction->scope, source_instruction->source_node); 2721 inst->base.value->special = ConstValSpecialStatic; 2722 inst->base.value->type = ira->codegen->builtin_types.entry_void; 2723 inst->var = var; 2724 inst->var_ptr = var_ptr; 2725 2726 ir_ref_inst_gen(var_ptr, ira->new_irb.current_basic_block); 2727 2728 return &inst->base; 2729 } 2730 2731 static IrInstSrc *ir_build_export(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2732 IrInstSrc *target, IrInstSrc *options) 2733 { 2734 IrInstSrcExport *export_instruction = ir_build_instruction<IrInstSrcExport>( 2735 irb, scope, source_node); 2736 export_instruction->target = target; 2737 export_instruction->options = options; 2738 2739 ir_ref_instruction(target, irb->current_basic_block); 2740 ir_ref_instruction(options, irb->current_basic_block); 2741 2742 return &export_instruction->base; 2743 } 2744 2745 static IrInstSrc *ir_build_load_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *ptr) { 2746 IrInstSrcLoadPtr *instruction = ir_build_instruction<IrInstSrcLoadPtr>(irb, scope, source_node); 2747 instruction->ptr = ptr; 2748 2749 ir_ref_instruction(ptr, irb->current_basic_block); 2750 2751 return &instruction->base; 2752 } 2753 2754 static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instruction, 2755 IrInstGen *ptr, ZigType *ty, IrInstGen *result_loc) 2756 { 2757 IrInstGenLoadPtr *instruction = ir_build_inst_gen<IrInstGenLoadPtr>( 2758 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2759 instruction->base.value->type = ty; 2760 instruction->ptr = ptr; 2761 instruction->result_loc = result_loc; 2762 2763 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); 2764 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); 2765 2766 return &instruction->base; 2767 } 2768 2769 static IrInstSrc *ir_build_typeof(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 2770 IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node); 2771 instruction->value = value; 2772 2773 ir_ref_instruction(value, irb->current_basic_block); 2774 2775 return &instruction->base; 2776 } 2777 2778 static IrInstSrc *ir_build_set_cold(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_cold) { 2779 IrInstSrcSetCold *instruction = ir_build_instruction<IrInstSrcSetCold>(irb, scope, source_node); 2780 instruction->is_cold = is_cold; 2781 2782 ir_ref_instruction(is_cold, irb->current_basic_block); 2783 2784 return &instruction->base; 2785 } 2786 2787 static IrInstSrc *ir_build_set_runtime_safety(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2788 IrInstSrc *safety_on) 2789 { 2790 IrInstSrcSetRuntimeSafety *inst = ir_build_instruction<IrInstSrcSetRuntimeSafety>(irb, scope, source_node); 2791 inst->safety_on = safety_on; 2792 2793 ir_ref_instruction(safety_on, irb->current_basic_block); 2794 2795 return &inst->base; 2796 } 2797 2798 static IrInstSrc *ir_build_set_float_mode(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2799 IrInstSrc *mode_value) 2800 { 2801 IrInstSrcSetFloatMode *instruction = ir_build_instruction<IrInstSrcSetFloatMode>(irb, scope, source_node); 2802 instruction->mode_value = mode_value; 2803 2804 ir_ref_instruction(mode_value, irb->current_basic_block); 2805 2806 return &instruction->base; 2807 } 2808 2809 static IrInstSrc *ir_build_array_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *size, 2810 IrInstSrc *sentinel, IrInstSrc *child_type) 2811 { 2812 IrInstSrcArrayType *instruction = ir_build_instruction<IrInstSrcArrayType>(irb, scope, source_node); 2813 instruction->size = size; 2814 instruction->sentinel = sentinel; 2815 instruction->child_type = child_type; 2816 2817 ir_ref_instruction(size, irb->current_basic_block); 2818 if (sentinel != nullptr) ir_ref_instruction(sentinel, irb->current_basic_block); 2819 ir_ref_instruction(child_type, irb->current_basic_block); 2820 2821 return &instruction->base; 2822 } 2823 2824 static IrInstSrc *ir_build_anyframe_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2825 IrInstSrc *payload_type) 2826 { 2827 IrInstSrcAnyFrameType *instruction = ir_build_instruction<IrInstSrcAnyFrameType>(irb, scope, source_node); 2828 instruction->payload_type = payload_type; 2829 2830 if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block); 2831 2832 return &instruction->base; 2833 } 2834 2835 static IrInstSrc *ir_build_slice_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2836 IrInstSrc *child_type, bool is_const, bool is_volatile, 2837 IrInstSrc *sentinel, IrInstSrc *align_value, bool is_allow_zero) 2838 { 2839 IrInstSrcSliceType *instruction = ir_build_instruction<IrInstSrcSliceType>(irb, scope, source_node); 2840 instruction->is_const = is_const; 2841 instruction->is_volatile = is_volatile; 2842 instruction->child_type = child_type; 2843 instruction->sentinel = sentinel; 2844 instruction->align_value = align_value; 2845 instruction->is_allow_zero = is_allow_zero; 2846 2847 if (sentinel != nullptr) ir_ref_instruction(sentinel, irb->current_basic_block); 2848 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 2849 ir_ref_instruction(child_type, irb->current_basic_block); 2850 2851 return &instruction->base; 2852 } 2853 2854 static IrInstSrc *ir_build_asm_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2855 IrInstSrc *asm_template, IrInstSrc **input_list, IrInstSrc **output_types, 2856 ZigVar **output_vars, size_t return_count, bool has_side_effects, bool is_global) 2857 { 2858 IrInstSrcAsm *instruction = ir_build_instruction<IrInstSrcAsm>(irb, scope, source_node); 2859 instruction->asm_template = asm_template; 2860 instruction->input_list = input_list; 2861 instruction->output_types = output_types; 2862 instruction->output_vars = output_vars; 2863 instruction->return_count = return_count; 2864 instruction->has_side_effects = has_side_effects; 2865 instruction->is_global = is_global; 2866 2867 assert(source_node->type == NodeTypeAsmExpr); 2868 for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) { 2869 IrInstSrc *output_type = output_types[i]; 2870 if (output_type) ir_ref_instruction(output_type, irb->current_basic_block); 2871 } 2872 2873 for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) { 2874 IrInstSrc *input_value = input_list[i]; 2875 ir_ref_instruction(input_value, irb->current_basic_block); 2876 } 2877 2878 return &instruction->base; 2879 } 2880 2881 static IrInstGen *ir_build_asm_gen(IrAnalyze *ira, IrInst *source_instr, 2882 Buf *asm_template, AsmToken *token_list, size_t token_list_len, 2883 IrInstGen **input_list, IrInstGen **output_types, ZigVar **output_vars, size_t return_count, 2884 bool has_side_effects, ZigType *return_type) 2885 { 2886 IrInstGenAsm *instruction = ir_build_inst_gen<IrInstGenAsm>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2887 instruction->base.value->type = return_type; 2888 instruction->asm_template = asm_template; 2889 instruction->token_list = token_list; 2890 instruction->token_list_len = token_list_len; 2891 instruction->input_list = input_list; 2892 instruction->output_types = output_types; 2893 instruction->output_vars = output_vars; 2894 instruction->return_count = return_count; 2895 instruction->has_side_effects = has_side_effects; 2896 2897 assert(source_instr->source_node->type == NodeTypeAsmExpr); 2898 for (size_t i = 0; i < source_instr->source_node->data.asm_expr.output_list.length; i += 1) { 2899 IrInstGen *output_type = output_types[i]; 2900 if (output_type) ir_ref_inst_gen(output_type, ira->new_irb.current_basic_block); 2901 } 2902 2903 for (size_t i = 0; i < source_instr->source_node->data.asm_expr.input_list.length; i += 1) { 2904 IrInstGen *input_value = input_list[i]; 2905 ir_ref_inst_gen(input_value, ira->new_irb.current_basic_block); 2906 } 2907 2908 return &instruction->base; 2909 } 2910 2911 static IrInstSrc *ir_build_size_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value, 2912 bool bit_size) 2913 { 2914 IrInstSrcSizeOf *instruction = ir_build_instruction<IrInstSrcSizeOf>(irb, scope, source_node); 2915 instruction->type_value = type_value; 2916 instruction->bit_size = bit_size; 2917 2918 ir_ref_instruction(type_value, irb->current_basic_block); 2919 2920 return &instruction->base; 2921 } 2922 2923 static IrInstSrc *ir_build_test_non_null_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2924 IrInstSrc *value) 2925 { 2926 IrInstSrcTestNonNull *instruction = ir_build_instruction<IrInstSrcTestNonNull>(irb, scope, source_node); 2927 instruction->value = value; 2928 2929 ir_ref_instruction(value, irb->current_basic_block); 2930 2931 return &instruction->base; 2932 } 2933 2934 static IrInstGen *ir_build_test_non_null_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) { 2935 IrInstGenTestNonNull *inst = ir_build_inst_gen<IrInstGenTestNonNull>(&ira->new_irb, 2936 source_instr->scope, source_instr->source_node); 2937 inst->base.value->type = ira->codegen->builtin_types.entry_bool; 2938 inst->value = value; 2939 2940 ir_ref_inst_gen(value, ira->new_irb.current_basic_block); 2941 2942 return &inst->base; 2943 } 2944 2945 static IrInstSrc *ir_build_optional_unwrap_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2946 IrInstSrc *base_ptr, bool safety_check_on, bool initializing) 2947 { 2948 IrInstSrcOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstSrcOptionalUnwrapPtr>(irb, scope, source_node); 2949 instruction->base_ptr = base_ptr; 2950 instruction->safety_check_on = safety_check_on; 2951 instruction->initializing = initializing; 2952 2953 ir_ref_instruction(base_ptr, irb->current_basic_block); 2954 2955 return &instruction->base; 2956 } 2957 2958 static IrInstGen *ir_build_optional_unwrap_ptr_gen(IrAnalyze *ira, IrInst *source_instr, 2959 IrInstGen *base_ptr, bool safety_check_on, bool initializing, ZigType *result_type) 2960 { 2961 IrInstGenOptionalUnwrapPtr *inst = ir_build_inst_gen<IrInstGenOptionalUnwrapPtr>(&ira->new_irb, 2962 source_instr->scope, source_instr->source_node); 2963 inst->base.value->type = result_type; 2964 inst->base_ptr = base_ptr; 2965 inst->safety_check_on = safety_check_on; 2966 inst->initializing = initializing; 2967 2968 ir_ref_inst_gen(base_ptr, ira->new_irb.current_basic_block); 2969 2970 return &inst->base; 2971 } 2972 2973 static IrInstGen *ir_build_optional_wrap(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_ty, 2974 IrInstGen *operand, IrInstGen *result_loc) 2975 { 2976 IrInstGenOptionalWrap *instruction = ir_build_inst_gen<IrInstGenOptionalWrap>( 2977 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2978 instruction->base.value->type = result_ty; 2979 instruction->operand = operand; 2980 instruction->result_loc = result_loc; 2981 2982 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); 2983 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); 2984 2985 return &instruction->base; 2986 } 2987 2988 static IrInstGen *ir_build_err_wrap_payload(IrAnalyze *ira, IrInst *source_instruction, 2989 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc) 2990 { 2991 IrInstGenErrWrapPayload *instruction = ir_build_inst_gen<IrInstGenErrWrapPayload>( 2992 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2993 instruction->base.value->type = result_type; 2994 instruction->operand = operand; 2995 instruction->result_loc = result_loc; 2996 2997 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); 2998 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); 2999 3000 return &instruction->base; 3001 } 3002 3003 static IrInstGen *ir_build_err_wrap_code(IrAnalyze *ira, IrInst *source_instruction, 3004 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc) 3005 { 3006 IrInstGenErrWrapCode *instruction = ir_build_inst_gen<IrInstGenErrWrapCode>( 3007 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3008 instruction->base.value->type = result_type; 3009 instruction->operand = operand; 3010 instruction->result_loc = result_loc; 3011 3012 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); 3013 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); 3014 3015 return &instruction->base; 3016 } 3017 3018 static IrInstSrc *ir_build_clz(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3019 IrInstSrc *op) 3020 { 3021 IrInstSrcClz *instruction = ir_build_instruction<IrInstSrcClz>(irb, scope, source_node); 3022 instruction->type = type; 3023 instruction->op = op; 3024 3025 ir_ref_instruction(type, irb->current_basic_block); 3026 ir_ref_instruction(op, irb->current_basic_block); 3027 3028 return &instruction->base; 3029 } 3030 3031 static IrInstGen *ir_build_clz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) { 3032 IrInstGenClz *instruction = ir_build_inst_gen<IrInstGenClz>(&ira->new_irb, 3033 source_instr->scope, source_instr->source_node); 3034 instruction->base.value->type = result_type; 3035 instruction->op = op; 3036 3037 ir_ref_inst_gen(op, ira->new_irb.current_basic_block); 3038 3039 return &instruction->base; 3040 } 3041 3042 static IrInstSrc *ir_build_ctz(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3043 IrInstSrc *op) 3044 { 3045 IrInstSrcCtz *instruction = ir_build_instruction<IrInstSrcCtz>(irb, scope, source_node); 3046 instruction->type = type; 3047 instruction->op = op; 3048 3049 ir_ref_instruction(type, irb->current_basic_block); 3050 ir_ref_instruction(op, irb->current_basic_block); 3051 3052 return &instruction->base; 3053 } 3054 3055 static IrInstGen *ir_build_ctz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) { 3056 IrInstGenCtz *instruction = ir_build_inst_gen<IrInstGenCtz>(&ira->new_irb, 3057 source_instr->scope, source_instr->source_node); 3058 instruction->base.value->type = result_type; 3059 instruction->op = op; 3060 3061 ir_ref_inst_gen(op, ira->new_irb.current_basic_block); 3062 3063 return &instruction->base; 3064 } 3065 3066 static IrInstSrc *ir_build_pop_count(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3067 IrInstSrc *op) 3068 { 3069 IrInstSrcPopCount *instruction = ir_build_instruction<IrInstSrcPopCount>(irb, scope, source_node); 3070 instruction->type = type; 3071 instruction->op = op; 3072 3073 ir_ref_instruction(type, irb->current_basic_block); 3074 ir_ref_instruction(op, irb->current_basic_block); 3075 3076 return &instruction->base; 3077 } 3078 3079 static IrInstGen *ir_build_pop_count_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, 3080 IrInstGen *op) 3081 { 3082 IrInstGenPopCount *instruction = ir_build_inst_gen<IrInstGenPopCount>(&ira->new_irb, 3083 source_instr->scope, source_instr->source_node); 3084 instruction->base.value->type = result_type; 3085 instruction->op = op; 3086 3087 ir_ref_inst_gen(op, ira->new_irb.current_basic_block); 3088 3089 return &instruction->base; 3090 } 3091 3092 static IrInstSrc *ir_build_bswap(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3093 IrInstSrc *op) 3094 { 3095 IrInstSrcBswap *instruction = ir_build_instruction<IrInstSrcBswap>(irb, scope, source_node); 3096 instruction->type = type; 3097 instruction->op = op; 3098 3099 ir_ref_instruction(type, irb->current_basic_block); 3100 ir_ref_instruction(op, irb->current_basic_block); 3101 3102 return &instruction->base; 3103 } 3104 3105 static IrInstGen *ir_build_bswap_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *op_type, 3106 IrInstGen *op) 3107 { 3108 IrInstGenBswap *instruction = ir_build_inst_gen<IrInstGenBswap>(&ira->new_irb, 3109 source_instr->scope, source_instr->source_node); 3110 instruction->base.value->type = op_type; 3111 instruction->op = op; 3112 3113 ir_ref_inst_gen(op, ira->new_irb.current_basic_block); 3114 3115 return &instruction->base; 3116 } 3117 3118 static IrInstSrc *ir_build_bit_reverse(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3119 IrInstSrc *op) 3120 { 3121 IrInstSrcBitReverse *instruction = ir_build_instruction<IrInstSrcBitReverse>(irb, scope, source_node); 3122 instruction->type = type; 3123 instruction->op = op; 3124 3125 ir_ref_instruction(type, irb->current_basic_block); 3126 ir_ref_instruction(op, irb->current_basic_block); 3127 3128 return &instruction->base; 3129 } 3130 3131 static IrInstGen *ir_build_bit_reverse_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *int_type, 3132 IrInstGen *op) 3133 { 3134 IrInstGenBitReverse *instruction = ir_build_inst_gen<IrInstGenBitReverse>(&ira->new_irb, 3135 source_instr->scope, source_instr->source_node); 3136 instruction->base.value->type = int_type; 3137 instruction->op = op; 3138 3139 ir_ref_inst_gen(op, ira->new_irb.current_basic_block); 3140 3141 return &instruction->base; 3142 } 3143 3144 static IrInstSrcSwitchBr *ir_build_switch_br_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3145 IrInstSrc *target_value, IrBasicBlockSrc *else_block, size_t case_count, IrInstSrcSwitchBrCase *cases, 3146 IrInstSrc *is_comptime, IrInstSrc *switch_prongs_void) 3147 { 3148 IrInstSrcSwitchBr *instruction = ir_build_instruction<IrInstSrcSwitchBr>(irb, scope, source_node); 3149 instruction->base.is_noreturn = true; 3150 instruction->target_value = target_value; 3151 instruction->else_block = else_block; 3152 instruction->case_count = case_count; 3153 instruction->cases = cases; 3154 instruction->is_comptime = is_comptime; 3155 instruction->switch_prongs_void = switch_prongs_void; 3156 3157 ir_ref_instruction(target_value, irb->current_basic_block); 3158 ir_ref_instruction(is_comptime, irb->current_basic_block); 3159 ir_ref_bb(else_block); 3160 ir_ref_instruction(switch_prongs_void, irb->current_basic_block); 3161 3162 for (size_t i = 0; i < case_count; i += 1) { 3163 ir_ref_instruction(cases[i].value, irb->current_basic_block); 3164 ir_ref_bb(cases[i].block); 3165 } 3166 3167 return instruction; 3168 } 3169 3170 static IrInstGenSwitchBr *ir_build_switch_br_gen(IrAnalyze *ira, IrInst *source_instr, 3171 IrInstGen *target_value, IrBasicBlockGen *else_block, size_t case_count, IrInstGenSwitchBrCase *cases) 3172 { 3173 IrInstGenSwitchBr *instruction = ir_build_inst_noreturn<IrInstGenSwitchBr>(&ira->new_irb, 3174 source_instr->scope, source_instr->source_node); 3175 instruction->target_value = target_value; 3176 instruction->else_block = else_block; 3177 instruction->case_count = case_count; 3178 instruction->cases = cases; 3179 3180 ir_ref_inst_gen(target_value, ira->new_irb.current_basic_block); 3181 ir_ref_bb_gen(else_block); 3182 3183 for (size_t i = 0; i < case_count; i += 1) { 3184 ir_ref_inst_gen(cases[i].value, ira->new_irb.current_basic_block); 3185 ir_ref_bb_gen(cases[i].block); 3186 } 3187 3188 return instruction; 3189 } 3190 3191 static IrInstSrc *ir_build_switch_target(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3192 IrInstSrc *target_value_ptr) 3193 { 3194 IrInstSrcSwitchTarget *instruction = ir_build_instruction<IrInstSrcSwitchTarget>(irb, scope, source_node); 3195 instruction->target_value_ptr = target_value_ptr; 3196 3197 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 3198 3199 return &instruction->base; 3200 } 3201 3202 static IrInstSrc *ir_build_switch_var(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3203 IrInstSrc *target_value_ptr, IrInstSrc **prongs_ptr, size_t prongs_len) 3204 { 3205 IrInstSrcSwitchVar *instruction = ir_build_instruction<IrInstSrcSwitchVar>(irb, scope, source_node); 3206 instruction->target_value_ptr = target_value_ptr; 3207 instruction->prongs_ptr = prongs_ptr; 3208 instruction->prongs_len = prongs_len; 3209 3210 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 3211 for (size_t i = 0; i < prongs_len; i += 1) { 3212 ir_ref_instruction(prongs_ptr[i], irb->current_basic_block); 3213 } 3214 3215 return &instruction->base; 3216 } 3217 3218 // For this instruction the switch_br must be set later. 3219 static IrInstSrcSwitchElseVar *ir_build_switch_else_var(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3220 IrInstSrc *target_value_ptr) 3221 { 3222 IrInstSrcSwitchElseVar *instruction = ir_build_instruction<IrInstSrcSwitchElseVar>(irb, scope, source_node); 3223 instruction->target_value_ptr = target_value_ptr; 3224 3225 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 3226 3227 return instruction; 3228 } 3229 3230 static IrInstGen *ir_build_union_tag(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, 3231 ZigType *tag_type) 3232 { 3233 IrInstGenUnionTag *instruction = ir_build_inst_gen<IrInstGenUnionTag>(&ira->new_irb, 3234 source_instr->scope, source_instr->source_node); 3235 instruction->value = value; 3236 instruction->base.value->type = tag_type; 3237 3238 ir_ref_inst_gen(value, ira->new_irb.current_basic_block); 3239 3240 return &instruction->base; 3241 } 3242 3243 static IrInstSrc *ir_build_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { 3244 IrInstSrcImport *instruction = ir_build_instruction<IrInstSrcImport>(irb, scope, source_node); 3245 instruction->name = name; 3246 3247 ir_ref_instruction(name, irb->current_basic_block); 3248 3249 return &instruction->base; 3250 } 3251 3252 static IrInstSrc *ir_build_ref_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value, 3253 bool is_const, bool is_volatile) 3254 { 3255 IrInstSrcRef *instruction = ir_build_instruction<IrInstSrcRef>(irb, scope, source_node); 3256 instruction->value = value; 3257 instruction->is_const = is_const; 3258 instruction->is_volatile = is_volatile; 3259 3260 ir_ref_instruction(value, irb->current_basic_block); 3261 3262 return &instruction->base; 3263 } 3264 3265 static IrInstGen *ir_build_ref_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type, 3266 IrInstGen *operand, IrInstGen *result_loc) 3267 { 3268 IrInstGenRef *instruction = ir_build_inst_gen<IrInstGenRef>(&ira->new_irb, 3269 source_instruction->scope, source_instruction->source_node); 3270 instruction->base.value->type = result_type; 3271 instruction->operand = operand; 3272 instruction->result_loc = result_loc; 3273 3274 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); 3275 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); 3276 3277 return &instruction->base; 3278 } 3279 3280 static IrInstSrc *ir_build_compile_err(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *msg) { 3281 IrInstSrcCompileErr *instruction = ir_build_instruction<IrInstSrcCompileErr>(irb, scope, source_node); 3282 instruction->msg = msg; 3283 3284 ir_ref_instruction(msg, irb->current_basic_block); 3285 3286 return &instruction->base; 3287 } 3288 3289 static IrInstSrc *ir_build_compile_log(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3290 size_t msg_count, IrInstSrc **msg_list) 3291 { 3292 IrInstSrcCompileLog *instruction = ir_build_instruction<IrInstSrcCompileLog>(irb, scope, source_node); 3293 instruction->msg_count = msg_count; 3294 instruction->msg_list = msg_list; 3295 3296 for (size_t i = 0; i < msg_count; i += 1) { 3297 ir_ref_instruction(msg_list[i], irb->current_basic_block); 3298 } 3299 3300 return &instruction->base; 3301 } 3302 3303 static IrInstSrc *ir_build_err_name(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 3304 IrInstSrcErrName *instruction = ir_build_instruction<IrInstSrcErrName>(irb, scope, source_node); 3305 instruction->value = value; 3306 3307 ir_ref_instruction(value, irb->current_basic_block); 3308 3309 return &instruction->base; 3310 } 3311 3312 static IrInstGen *ir_build_err_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, 3313 ZigType *str_type) 3314 { 3315 IrInstGenErrName *instruction = ir_build_inst_gen<IrInstGenErrName>(&ira->new_irb, 3316 source_instr->scope, source_instr->source_node); 3317 instruction->base.value->type = str_type; 3318 instruction->value = value; 3319 3320 ir_ref_inst_gen(value, ira->new_irb.current_basic_block); 3321 3322 return &instruction->base; 3323 } 3324 3325 static IrInstSrc *ir_build_c_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3326 IrInstSrcCImport *instruction = ir_build_instruction<IrInstSrcCImport>(irb, scope, source_node); 3327 return &instruction->base; 3328 } 3329 3330 static IrInstSrc *ir_build_c_include(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { 3331 IrInstSrcCInclude *instruction = ir_build_instruction<IrInstSrcCInclude>(irb, scope, source_node); 3332 instruction->name = name; 3333 3334 ir_ref_instruction(name, irb->current_basic_block); 3335 3336 return &instruction->base; 3337 } 3338 3339 static IrInstSrc *ir_build_c_define(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name, IrInstSrc *value) { 3340 IrInstSrcCDefine *instruction = ir_build_instruction<IrInstSrcCDefine>(irb, scope, source_node); 3341 instruction->name = name; 3342 instruction->value = value; 3343 3344 ir_ref_instruction(name, irb->current_basic_block); 3345 ir_ref_instruction(value, irb->current_basic_block); 3346 3347 return &instruction->base; 3348 } 3349 3350 static IrInstSrc *ir_build_c_undef(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { 3351 IrInstSrcCUndef *instruction = ir_build_instruction<IrInstSrcCUndef>(irb, scope, source_node); 3352 instruction->name = name; 3353 3354 ir_ref_instruction(name, irb->current_basic_block); 3355 3356 return &instruction->base; 3357 } 3358 3359 static IrInstSrc *ir_build_embed_file(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { 3360 IrInstSrcEmbedFile *instruction = ir_build_instruction<IrInstSrcEmbedFile>(irb, scope, source_node); 3361 instruction->name = name; 3362 3363 ir_ref_instruction(name, irb->current_basic_block); 3364 3365 return &instruction->base; 3366 } 3367 3368 static IrInstSrc *ir_build_cmpxchg_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3369 IrInstSrc *type_value, IrInstSrc *ptr, IrInstSrc *cmp_value, IrInstSrc *new_value, 3370 IrInstSrc *success_order_value, IrInstSrc *failure_order_value, bool is_weak, ResultLoc *result_loc) 3371 { 3372 IrInstSrcCmpxchg *instruction = ir_build_instruction<IrInstSrcCmpxchg>(irb, scope, source_node); 3373 instruction->type_value = type_value; 3374 instruction->ptr = ptr; 3375 instruction->cmp_value = cmp_value; 3376 instruction->new_value = new_value; 3377 instruction->success_order_value = success_order_value; 3378 instruction->failure_order_value = failure_order_value; 3379 instruction->is_weak = is_weak; 3380 instruction->result_loc = result_loc; 3381 3382 ir_ref_instruction(type_value, irb->current_basic_block); 3383 ir_ref_instruction(ptr, irb->current_basic_block); 3384 ir_ref_instruction(cmp_value, irb->current_basic_block); 3385 ir_ref_instruction(new_value, irb->current_basic_block); 3386 ir_ref_instruction(success_order_value, irb->current_basic_block); 3387 ir_ref_instruction(failure_order_value, irb->current_basic_block); 3388 3389 return &instruction->base; 3390 } 3391 3392 static IrInstGen *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type, 3393 IrInstGen *ptr, IrInstGen *cmp_value, IrInstGen *new_value, 3394 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstGen *result_loc) 3395 { 3396 IrInstGenCmpxchg *instruction = ir_build_inst_gen<IrInstGenCmpxchg>(&ira->new_irb, 3397 source_instruction->scope, source_instruction->source_node); 3398 instruction->base.value->type = result_type; 3399 instruction->ptr = ptr; 3400 instruction->cmp_value = cmp_value; 3401 instruction->new_value = new_value; 3402 instruction->success_order = success_order; 3403 instruction->failure_order = failure_order; 3404 instruction->is_weak = is_weak; 3405 instruction->result_loc = result_loc; 3406 3407 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); 3408 ir_ref_inst_gen(cmp_value, ira->new_irb.current_basic_block); 3409 ir_ref_inst_gen(new_value, ira->new_irb.current_basic_block); 3410 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); 3411 3412 return &instruction->base; 3413 } 3414 3415 static IrInstSrc *ir_build_fence(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *order) { 3416 IrInstSrcFence *instruction = ir_build_instruction<IrInstSrcFence>(irb, scope, source_node); 3417 instruction->order = order; 3418 3419 ir_ref_instruction(order, irb->current_basic_block); 3420 3421 return &instruction->base; 3422 } 3423 3424 static IrInstGen *ir_build_fence_gen(IrAnalyze *ira, IrInst *source_instr, AtomicOrder order) { 3425 IrInstGenFence *instruction = ir_build_inst_void<IrInstGenFence>(&ira->new_irb, 3426 source_instr->scope, source_instr->source_node); 3427 instruction->order = order; 3428 3429 return &instruction->base; 3430 } 3431 3432 static IrInstSrc *ir_build_truncate(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3433 IrInstSrc *dest_type, IrInstSrc *target) 3434 { 3435 IrInstSrcTruncate *instruction = ir_build_instruction<IrInstSrcTruncate>(irb, scope, source_node); 3436 instruction->dest_type = dest_type; 3437 instruction->target = target; 3438 3439 ir_ref_instruction(dest_type, irb->current_basic_block); 3440 ir_ref_instruction(target, irb->current_basic_block); 3441 3442 return &instruction->base; 3443 } 3444 3445 static IrInstGen *ir_build_truncate_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *dest_type, 3446 IrInstGen *target) 3447 { 3448 IrInstGenTruncate *instruction = ir_build_inst_gen<IrInstGenTruncate>(&ira->new_irb, 3449 source_instr->scope, source_instr->source_node); 3450 instruction->base.value->type = dest_type; 3451 instruction->target = target; 3452 3453 ir_ref_inst_gen(target, ira->new_irb.current_basic_block); 3454 3455 return &instruction->base; 3456 } 3457 3458 static IrInstSrc *ir_build_int_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *dest_type, 3459 IrInstSrc *target) 3460 { 3461 IrInstSrcIntCast *instruction = ir_build_instruction<IrInstSrcIntCast>(irb, scope, source_node); 3462 instruction->dest_type = dest_type; 3463 instruction->target = target; 3464 3465 ir_ref_instruction(dest_type, irb->current_basic_block); 3466 ir_ref_instruction(target, irb->current_basic_block); 3467 3468 return &instruction->base; 3469 } 3470 3471 static IrInstSrc *ir_build_float_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *dest_type, 3472 IrInstSrc *target) 3473 { 3474 IrInstSrcFloatCast *instruction = ir_build_instruction<IrInstSrcFloatCast>(irb, scope, source_node); 3475 instruction->dest_type = dest_type; 3476 instruction->target = target; 3477 3478 ir_ref_instruction(dest_type, irb->current_basic_block); 3479 ir_ref_instruction(target, irb->current_basic_block); 3480 3481 return &instruction->base; 3482 } 3483 3484 static IrInstSrc *ir_build_err_set_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3485 IrInstSrc *dest_type, IrInstSrc *target) 3486 { 3487 IrInstSrcErrSetCast *instruction = ir_build_instruction<IrInstSrcErrSetCast>(irb, scope, source_node); 3488 instruction->dest_type = dest_type; 3489 instruction->target = target; 3490 3491 ir_ref_instruction(dest_type, irb->current_basic_block); 3492 ir_ref_instruction(target, irb->current_basic_block); 3493 3494 return &instruction->base; 3495 } 3496 3497 static IrInstSrc *ir_build_int_to_float(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3498 IrInstSrc *dest_type, IrInstSrc *target) 3499 { 3500 IrInstSrcIntToFloat *instruction = ir_build_instruction<IrInstSrcIntToFloat>(irb, scope, source_node); 3501 instruction->dest_type = dest_type; 3502 instruction->target = target; 3503 3504 ir_ref_instruction(dest_type, irb->current_basic_block); 3505 ir_ref_instruction(target, irb->current_basic_block); 3506 3507 return &instruction->base; 3508 } 3509 3510 static IrInstSrc *ir_build_float_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3511 IrInstSrc *dest_type, IrInstSrc *target) 3512 { 3513 IrInstSrcFloatToInt *instruction = ir_build_instruction<IrInstSrcFloatToInt>(irb, scope, source_node); 3514 instruction->dest_type = dest_type; 3515 instruction->target = target; 3516 3517 ir_ref_instruction(dest_type, irb->current_basic_block); 3518 ir_ref_instruction(target, irb->current_basic_block); 3519 3520 return &instruction->base; 3521 } 3522 3523 static IrInstSrc *ir_build_bool_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target) { 3524 IrInstSrcBoolToInt *instruction = ir_build_instruction<IrInstSrcBoolToInt>(irb, scope, source_node); 3525 instruction->target = target; 3526 3527 ir_ref_instruction(target, irb->current_basic_block); 3528 3529 return &instruction->base; 3530 } 3531 3532 static IrInstSrc *ir_build_vector_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *len, 3533 IrInstSrc *elem_type) 3534 { 3535 IrInstSrcVectorType *instruction = ir_build_instruction<IrInstSrcVectorType>(irb, scope, source_node); 3536 instruction->len = len; 3537 instruction->elem_type = elem_type; 3538 3539 ir_ref_instruction(len, irb->current_basic_block); 3540 ir_ref_instruction(elem_type, irb->current_basic_block); 3541 3542 return &instruction->base; 3543 } 3544 3545 static IrInstSrc *ir_build_shuffle_vector(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3546 IrInstSrc *scalar_type, IrInstSrc *a, IrInstSrc *b, IrInstSrc *mask) 3547 { 3548 IrInstSrcShuffleVector *instruction = ir_build_instruction<IrInstSrcShuffleVector>(irb, scope, source_node); 3549 instruction->scalar_type = scalar_type; 3550 instruction->a = a; 3551 instruction->b = b; 3552 instruction->mask = mask; 3553 3554 if (scalar_type != nullptr) ir_ref_instruction(scalar_type, irb->current_basic_block); 3555 ir_ref_instruction(a, irb->current_basic_block); 3556 ir_ref_instruction(b, irb->current_basic_block); 3557 ir_ref_instruction(mask, irb->current_basic_block); 3558 3559 return &instruction->base; 3560 } 3561 3562 static IrInstGen *ir_build_shuffle_vector_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 3563 ZigType *result_type, IrInstGen *a, IrInstGen *b, IrInstGen *mask) 3564 { 3565 IrInstGenShuffleVector *inst = ir_build_inst_gen<IrInstGenShuffleVector>(&ira->new_irb, scope, source_node); 3566 inst->base.value->type = result_type; 3567 inst->a = a; 3568 inst->b = b; 3569 inst->mask = mask; 3570 3571 ir_ref_inst_gen(a, ira->new_irb.current_basic_block); 3572 ir_ref_inst_gen(b, ira->new_irb.current_basic_block); 3573 ir_ref_inst_gen(mask, ira->new_irb.current_basic_block); 3574 3575 return &inst->base; 3576 } 3577 3578 static IrInstSrc *ir_build_splat_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3579 IrInstSrc *len, IrInstSrc *scalar) 3580 { 3581 IrInstSrcSplat *instruction = ir_build_instruction<IrInstSrcSplat>(irb, scope, source_node); 3582 instruction->len = len; 3583 instruction->scalar = scalar; 3584 3585 ir_ref_instruction(len, irb->current_basic_block); 3586 ir_ref_instruction(scalar, irb->current_basic_block); 3587 3588 return &instruction->base; 3589 } 3590 3591 static IrInstGen *ir_build_splat_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type, 3592 IrInstGen *scalar) 3593 { 3594 IrInstGenSplat *instruction = ir_build_inst_gen<IrInstGenSplat>( 3595 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3596 instruction->base.value->type = result_type; 3597 instruction->scalar = scalar; 3598 3599 ir_ref_inst_gen(scalar, ira->new_irb.current_basic_block); 3600 3601 return &instruction->base; 3602 } 3603 3604 static IrInstSrc *ir_build_bool_not(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 3605 IrInstSrcBoolNot *instruction = ir_build_instruction<IrInstSrcBoolNot>(irb, scope, source_node); 3606 instruction->value = value; 3607 3608 ir_ref_instruction(value, irb->current_basic_block); 3609 3610 return &instruction->base; 3611 } 3612 3613 static IrInstGen *ir_build_bool_not_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) { 3614 IrInstGenBoolNot *instruction = ir_build_inst_gen<IrInstGenBoolNot>(&ira->new_irb, 3615 source_instr->scope, source_instr->source_node); 3616 instruction->base.value->type = ira->codegen->builtin_types.entry_bool; 3617 instruction->value = value; 3618 3619 ir_ref_inst_gen(value, ira->new_irb.current_basic_block); 3620 3621 return &instruction->base; 3622 } 3623 3624 static IrInstSrc *ir_build_memset_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3625 IrInstSrc *dest_ptr, IrInstSrc *byte, IrInstSrc *count) 3626 { 3627 IrInstSrcMemset *instruction = ir_build_instruction<IrInstSrcMemset>(irb, scope, source_node); 3628 instruction->dest_ptr = dest_ptr; 3629 instruction->byte = byte; 3630 instruction->count = count; 3631 3632 ir_ref_instruction(dest_ptr, irb->current_basic_block); 3633 ir_ref_instruction(byte, irb->current_basic_block); 3634 ir_ref_instruction(count, irb->current_basic_block); 3635 3636 return &instruction->base; 3637 } 3638 3639 static IrInstGen *ir_build_memset_gen(IrAnalyze *ira, IrInst *source_instr, 3640 IrInstGen *dest_ptr, IrInstGen *byte, IrInstGen *count) 3641 { 3642 IrInstGenMemset *instruction = ir_build_inst_void<IrInstGenMemset>(&ira->new_irb, 3643 source_instr->scope, source_instr->source_node); 3644 instruction->dest_ptr = dest_ptr; 3645 instruction->byte = byte; 3646 instruction->count = count; 3647 3648 ir_ref_inst_gen(dest_ptr, ira->new_irb.current_basic_block); 3649 ir_ref_inst_gen(byte, ira->new_irb.current_basic_block); 3650 ir_ref_inst_gen(count, ira->new_irb.current_basic_block); 3651 3652 return &instruction->base; 3653 } 3654 3655 static IrInstSrc *ir_build_memcpy_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3656 IrInstSrc *dest_ptr, IrInstSrc *src_ptr, IrInstSrc *count) 3657 { 3658 IrInstSrcMemcpy *instruction = ir_build_instruction<IrInstSrcMemcpy>(irb, scope, source_node); 3659 instruction->dest_ptr = dest_ptr; 3660 instruction->src_ptr = src_ptr; 3661 instruction->count = count; 3662 3663 ir_ref_instruction(dest_ptr, irb->current_basic_block); 3664 ir_ref_instruction(src_ptr, irb->current_basic_block); 3665 ir_ref_instruction(count, irb->current_basic_block); 3666 3667 return &instruction->base; 3668 } 3669 3670 static IrInstGen *ir_build_memcpy_gen(IrAnalyze *ira, IrInst *source_instr, 3671 IrInstGen *dest_ptr, IrInstGen *src_ptr, IrInstGen *count) 3672 { 3673 IrInstGenMemcpy *instruction = ir_build_inst_void<IrInstGenMemcpy>(&ira->new_irb, 3674 source_instr->scope, source_instr->source_node); 3675 instruction->dest_ptr = dest_ptr; 3676 instruction->src_ptr = src_ptr; 3677 instruction->count = count; 3678 3679 ir_ref_inst_gen(dest_ptr, ira->new_irb.current_basic_block); 3680 ir_ref_inst_gen(src_ptr, ira->new_irb.current_basic_block); 3681 ir_ref_inst_gen(count, ira->new_irb.current_basic_block); 3682 3683 return &instruction->base; 3684 } 3685 3686 static IrInstSrc *ir_build_slice_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3687 IrInstSrc *ptr, IrInstSrc *start, IrInstSrc *end, IrInstSrc *sentinel, 3688 bool safety_check_on, ResultLoc *result_loc) 3689 { 3690 IrInstSrcSlice *instruction = ir_build_instruction<IrInstSrcSlice>(irb, scope, source_node); 3691 instruction->ptr = ptr; 3692 instruction->start = start; 3693 instruction->end = end; 3694 instruction->sentinel = sentinel; 3695 instruction->safety_check_on = safety_check_on; 3696 instruction->result_loc = result_loc; 3697 3698 ir_ref_instruction(ptr, irb->current_basic_block); 3699 ir_ref_instruction(start, irb->current_basic_block); 3700 if (end) ir_ref_instruction(end, irb->current_basic_block); 3701 if (sentinel) ir_ref_instruction(sentinel, irb->current_basic_block); 3702 3703 return &instruction->base; 3704 } 3705 3706 static IrInstGen *ir_build_slice_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *slice_type, 3707 IrInstGen *ptr, IrInstGen *start, IrInstGen *end, bool safety_check_on, IrInstGen *result_loc) 3708 { 3709 IrInstGenSlice *instruction = ir_build_inst_gen<IrInstGenSlice>( 3710 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3711 instruction->base.value->type = slice_type; 3712 instruction->ptr = ptr; 3713 instruction->start = start; 3714 instruction->end = end; 3715 instruction->safety_check_on = safety_check_on; 3716 instruction->result_loc = result_loc; 3717 3718 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); 3719 ir_ref_inst_gen(start, ira->new_irb.current_basic_block); 3720 if (end) ir_ref_inst_gen(end, ira->new_irb.current_basic_block); 3721 ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); 3722 3723 return &instruction->base; 3724 } 3725 3726 static IrInstSrc *ir_build_breakpoint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3727 IrInstSrcBreakpoint *instruction = ir_build_instruction<IrInstSrcBreakpoint>(irb, scope, source_node); 3728 return &instruction->base; 3729 } 3730 3731 static IrInstGen *ir_build_breakpoint_gen(IrAnalyze *ira, IrInst *source_instr) { 3732 IrInstGenBreakpoint *instruction = ir_build_inst_void<IrInstGenBreakpoint>(&ira->new_irb, 3733 source_instr->scope, source_instr->source_node); 3734 return &instruction->base; 3735 } 3736 3737 static IrInstSrc *ir_build_return_address_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3738 IrInstSrcReturnAddress *instruction = ir_build_instruction<IrInstSrcReturnAddress>(irb, scope, source_node); 3739 return &instruction->base; 3740 } 3741 3742 static IrInstGen *ir_build_return_address_gen(IrAnalyze *ira, IrInst *source_instr) { 3743 IrInstGenReturnAddress *inst = ir_build_inst_gen<IrInstGenReturnAddress>(&ira->new_irb, source_instr->scope, source_instr->source_node); 3744 inst->base.value->type = ira->codegen->builtin_types.entry_usize; 3745 return &inst->base; 3746 } 3747 3748 static IrInstSrc *ir_build_frame_address_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3749 IrInstSrcFrameAddress *inst = ir_build_instruction<IrInstSrcFrameAddress>(irb, scope, source_node); 3750 return &inst->base; 3751 } 3752 3753 static IrInstGen *ir_build_frame_address_gen(IrAnalyze *ira, IrInst *source_instr) { 3754 IrInstGenFrameAddress *inst = ir_build_inst_gen<IrInstGenFrameAddress>(&ira->new_irb, source_instr->scope, source_instr->source_node); 3755 inst->base.value->type = ira->codegen->builtin_types.entry_usize; 3756 return &inst->base; 3757 } 3758 3759 static IrInstSrc *ir_build_handle_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3760 IrInstSrcFrameHandle *inst = ir_build_instruction<IrInstSrcFrameHandle>(irb, scope, source_node); 3761 return &inst->base; 3762 } 3763 3764 static IrInstGen *ir_build_handle_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *ty) { 3765 IrInstGenFrameHandle *inst = ir_build_inst_gen<IrInstGenFrameHandle>(&ira->new_irb, source_instr->scope, source_instr->source_node); 3766 inst->base.value->type = ty; 3767 return &inst->base; 3768 } 3769 3770 static IrInstSrc *ir_build_frame_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *fn) { 3771 IrInstSrcFrameType *inst = ir_build_instruction<IrInstSrcFrameType>(irb, scope, source_node); 3772 inst->fn = fn; 3773 3774 ir_ref_instruction(fn, irb->current_basic_block); 3775 3776 return &inst->base; 3777 } 3778 3779 static IrInstSrc *ir_build_frame_size_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *fn) { 3780 IrInstSrcFrameSize *inst = ir_build_instruction<IrInstSrcFrameSize>(irb, scope, source_node); 3781 inst->fn = fn; 3782 3783 ir_ref_instruction(fn, irb->current_basic_block); 3784 3785 return &inst->base; 3786 } 3787 3788 static IrInstGen *ir_build_frame_size_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *fn) 3789 { 3790 IrInstGenFrameSize *inst = ir_build_inst_gen<IrInstGenFrameSize>(&ira->new_irb, source_instr->scope, source_instr->source_node); 3791 inst->base.value->type = ira->codegen->builtin_types.entry_usize; 3792 inst->fn = fn; 3793 3794 ir_ref_inst_gen(fn, ira->new_irb.current_basic_block); 3795 3796 return &inst->base; 3797 } 3798 3799 static IrInstSrc *ir_build_overflow_op_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3800 IrOverflowOp op, IrInstSrc *type_value, IrInstSrc *op1, IrInstSrc *op2, IrInstSrc *result_ptr) 3801 { 3802 IrInstSrcOverflowOp *instruction = ir_build_instruction<IrInstSrcOverflowOp>(irb, scope, source_node); 3803 instruction->op = op; 3804 instruction->type_value = type_value; 3805 instruction->op1 = op1; 3806 instruction->op2 = op2; 3807 instruction->result_ptr = result_ptr; 3808 3809 ir_ref_instruction(type_value, irb->current_basic_block); 3810 ir_ref_instruction(op1, irb->current_basic_block); 3811 ir_ref_instruction(op2, irb->current_basic_block); 3812 ir_ref_instruction(result_ptr, irb->current_basic_block); 3813 3814 return &instruction->base; 3815 } 3816 3817 static IrInstGen *ir_build_overflow_op_gen(IrAnalyze *ira, IrInst *source_instr, 3818 IrOverflowOp op, IrInstGen *op1, IrInstGen *op2, IrInstGen *result_ptr, 3819 ZigType *result_ptr_type) 3820 { 3821 IrInstGenOverflowOp *instruction = ir_build_inst_gen<IrInstGenOverflowOp>(&ira->new_irb, 3822 source_instr->scope, source_instr->source_node); 3823 instruction->base.value->type = ira->codegen->builtin_types.entry_bool; 3824 instruction->op = op; 3825 instruction->op1 = op1; 3826 instruction->op2 = op2; 3827 instruction->result_ptr = result_ptr; 3828 instruction->result_ptr_type = result_ptr_type; 3829 3830 ir_ref_inst_gen(op1, ira->new_irb.current_basic_block); 3831 ir_ref_inst_gen(op2, ira->new_irb.current_basic_block); 3832 ir_ref_inst_gen(result_ptr, ira->new_irb.current_basic_block); 3833 3834 return &instruction->base; 3835 } 3836 3837 static IrInstSrc *ir_build_float_op_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *operand, 3838 BuiltinFnId fn_id) 3839 { 3840 IrInstSrcFloatOp *instruction = ir_build_instruction<IrInstSrcFloatOp>(irb, scope, source_node); 3841 instruction->operand = operand; 3842 instruction->fn_id = fn_id; 3843 3844 ir_ref_instruction(operand, irb->current_basic_block); 3845 3846 return &instruction->base; 3847 } 3848 3849 static IrInstGen *ir_build_float_op_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, 3850 BuiltinFnId fn_id, ZigType *operand_type) 3851 { 3852 IrInstGenFloatOp *instruction = ir_build_inst_gen<IrInstGenFloatOp>(&ira->new_irb, 3853 source_instr->scope, source_instr->source_node); 3854 instruction->base.value->type = operand_type; 3855 instruction->operand = operand; 3856 instruction->fn_id = fn_id; 3857 3858 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); 3859 3860 return &instruction->base; 3861 } 3862 3863 static IrInstSrc *ir_build_mul_add_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3864 IrInstSrc *type_value, IrInstSrc *op1, IrInstSrc *op2, IrInstSrc *op3) 3865 { 3866 IrInstSrcMulAdd *instruction = ir_build_instruction<IrInstSrcMulAdd>(irb, scope, source_node); 3867 instruction->type_value = type_value; 3868 instruction->op1 = op1; 3869 instruction->op2 = op2; 3870 instruction->op3 = op3; 3871 3872 ir_ref_instruction(type_value, irb->current_basic_block); 3873 ir_ref_instruction(op1, irb->current_basic_block); 3874 ir_ref_instruction(op2, irb->current_basic_block); 3875 ir_ref_instruction(op3, irb->current_basic_block); 3876 3877 return &instruction->base; 3878 } 3879 3880 static IrInstGen *ir_build_mul_add_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *op1, IrInstGen *op2, 3881 IrInstGen *op3, ZigType *expr_type) 3882 { 3883 IrInstGenMulAdd *instruction = ir_build_inst_gen<IrInstGenMulAdd>(&ira->new_irb, 3884 source_instr->scope, source_instr->source_node); 3885 instruction->base.value->type = expr_type; 3886 instruction->op1 = op1; 3887 instruction->op2 = op2; 3888 instruction->op3 = op3; 3889 3890 ir_ref_inst_gen(op1, ira->new_irb.current_basic_block); 3891 ir_ref_inst_gen(op2, ira->new_irb.current_basic_block); 3892 ir_ref_inst_gen(op3, ira->new_irb.current_basic_block); 3893 3894 return &instruction->base; 3895 } 3896 3897 static IrInstSrc *ir_build_align_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value) { 3898 IrInstSrcAlignOf *instruction = ir_build_instruction<IrInstSrcAlignOf>(irb, scope, source_node); 3899 instruction->type_value = type_value; 3900 3901 ir_ref_instruction(type_value, irb->current_basic_block); 3902 3903 return &instruction->base; 3904 } 3905 3906 static IrInstSrc *ir_build_test_err_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3907 IrInstSrc *base_ptr, bool resolve_err_set, bool base_ptr_is_payload) 3908 { 3909 IrInstSrcTestErr *instruction = ir_build_instruction<IrInstSrcTestErr>(irb, scope, source_node); 3910 instruction->base_ptr = base_ptr; 3911 instruction->resolve_err_set = resolve_err_set; 3912 instruction->base_ptr_is_payload = base_ptr_is_payload; 3913 3914 ir_ref_instruction(base_ptr, irb->current_basic_block); 3915 3916 return &instruction->base; 3917 } 3918 3919 static IrInstGen *ir_build_test_err_gen(IrAnalyze *ira, IrInst *source_instruction, IrInstGen *err_union) { 3920 IrInstGenTestErr *instruction = ir_build_inst_gen<IrInstGenTestErr>( 3921 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3922 instruction->base.value->type = ira->codegen->builtin_types.entry_bool; 3923 instruction->err_union = err_union; 3924 3925 ir_ref_inst_gen(err_union, ira->new_irb.current_basic_block); 3926 3927 return &instruction->base; 3928 } 3929 3930 static IrInstSrc *ir_build_unwrap_err_code_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3931 IrInstSrc *err_union_ptr) 3932 { 3933 IrInstSrcUnwrapErrCode *inst = ir_build_instruction<IrInstSrcUnwrapErrCode>(irb, scope, source_node); 3934 inst->err_union_ptr = err_union_ptr; 3935 3936 ir_ref_instruction(err_union_ptr, irb->current_basic_block); 3937 3938 return &inst->base; 3939 } 3940 3941 static IrInstGen *ir_build_unwrap_err_code_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 3942 IrInstGen *err_union_ptr, ZigType *result_type) 3943 { 3944 IrInstGenUnwrapErrCode *inst = ir_build_inst_gen<IrInstGenUnwrapErrCode>(&ira->new_irb, scope, source_node); 3945 inst->base.value->type = result_type; 3946 inst->err_union_ptr = err_union_ptr; 3947 3948 ir_ref_inst_gen(err_union_ptr, ira->new_irb.current_basic_block); 3949 3950 return &inst->base; 3951 } 3952 3953 static IrInstSrc *ir_build_unwrap_err_payload_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3954 IrInstSrc *value, bool safety_check_on, bool initializing) 3955 { 3956 IrInstSrcUnwrapErrPayload *inst = ir_build_instruction<IrInstSrcUnwrapErrPayload>(irb, scope, source_node); 3957 inst->value = value; 3958 inst->safety_check_on = safety_check_on; 3959 inst->initializing = initializing; 3960 3961 ir_ref_instruction(value, irb->current_basic_block); 3962 3963 return &inst->base; 3964 } 3965 3966 static IrInstGen *ir_build_unwrap_err_payload_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 3967 IrInstGen *value, bool safety_check_on, bool initializing, ZigType *result_type) 3968 { 3969 IrInstGenUnwrapErrPayload *inst = ir_build_inst_gen<IrInstGenUnwrapErrPayload>(&ira->new_irb, scope, source_node); 3970 inst->base.value->type = result_type; 3971 inst->value = value; 3972 inst->safety_check_on = safety_check_on; 3973 inst->initializing = initializing; 3974 3975 ir_ref_inst_gen(value, ira->new_irb.current_basic_block); 3976 3977 return &inst->base; 3978 } 3979 3980 static IrInstSrc *ir_build_fn_proto(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3981 IrInstSrc **param_types, IrInstSrc *align_value, IrInstSrc *callconv_value, 3982 IrInstSrc *return_type, bool is_var_args) 3983 { 3984 IrInstSrcFnProto *instruction = ir_build_instruction<IrInstSrcFnProto>(irb, scope, source_node); 3985 instruction->param_types = param_types; 3986 instruction->align_value = align_value; 3987 instruction->callconv_value = callconv_value; 3988 instruction->return_type = return_type; 3989 instruction->is_var_args = is_var_args; 3990 3991 assert(source_node->type == NodeTypeFnProto); 3992 size_t param_count = source_node->data.fn_proto.params.length; 3993 if (is_var_args) param_count -= 1; 3994 for (size_t i = 0; i < param_count; i += 1) { 3995 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block); 3996 } 3997 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 3998 if (callconv_value != nullptr) ir_ref_instruction(callconv_value, irb->current_basic_block); 3999 ir_ref_instruction(return_type, irb->current_basic_block); 4000 4001 return &instruction->base; 4002 } 4003 4004 static IrInstSrc *ir_build_test_comptime(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 4005 IrInstSrcTestComptime *instruction = ir_build_instruction<IrInstSrcTestComptime>(irb, scope, source_node); 4006 instruction->value = value; 4007 4008 ir_ref_instruction(value, irb->current_basic_block); 4009 4010 return &instruction->base; 4011 } 4012 4013 static IrInstSrc *ir_build_ptr_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4014 IrInstSrc *dest_type, IrInstSrc *ptr, bool safety_check_on) 4015 { 4016 IrInstSrcPtrCast *instruction = ir_build_instruction<IrInstSrcPtrCast>( 4017 irb, scope, source_node); 4018 instruction->dest_type = dest_type; 4019 instruction->ptr = ptr; 4020 instruction->safety_check_on = safety_check_on; 4021 4022 ir_ref_instruction(dest_type, irb->current_basic_block); 4023 ir_ref_instruction(ptr, irb->current_basic_block); 4024 4025 return &instruction->base; 4026 } 4027 4028 static IrInstGen *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInst *source_instruction, 4029 ZigType *ptr_type, IrInstGen *ptr, bool safety_check_on) 4030 { 4031 IrInstGenPtrCast *instruction = ir_build_inst_gen<IrInstGenPtrCast>( 4032 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 4033 instruction->base.value->type = ptr_type; 4034 instruction->ptr = ptr; 4035 instruction->safety_check_on = safety_check_on; 4036 4037 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); 4038 4039 return &instruction->base; 4040 } 4041 4042 static IrInstSrc *ir_build_implicit_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4043 IrInstSrc *operand, ResultLocCast *result_loc_cast) 4044 { 4045 IrInstSrcImplicitCast *instruction = ir_build_instruction<IrInstSrcImplicitCast>(irb, scope, source_node); 4046 instruction->operand = operand; 4047 instruction->result_loc_cast = result_loc_cast; 4048 4049 ir_ref_instruction(operand, irb->current_basic_block); 4050 4051 return &instruction->base; 4052 } 4053 4054 static IrInstSrc *ir_build_bit_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4055 IrInstSrc *operand, ResultLocBitCast *result_loc_bit_cast) 4056 { 4057 IrInstSrcBitCast *instruction = ir_build_instruction<IrInstSrcBitCast>(irb, scope, source_node); 4058 instruction->operand = operand; 4059 instruction->result_loc_bit_cast = result_loc_bit_cast; 4060 4061 ir_ref_instruction(operand, irb->current_basic_block); 4062 4063 return &instruction->base; 4064 } 4065 4066 static IrInstGen *ir_build_bit_cast_gen(IrAnalyze *ira, IrInst *source_instruction, 4067 IrInstGen *operand, ZigType *ty) 4068 { 4069 IrInstGenBitCast *instruction = ir_build_inst_gen<IrInstGenBitCast>( 4070 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 4071 instruction->base.value->type = ty; 4072 instruction->operand = operand; 4073 4074 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); 4075 4076 return &instruction->base; 4077 } 4078 4079 static IrInstGen *ir_build_widen_or_shorten(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, 4080 ZigType *result_type) 4081 { 4082 IrInstGenWidenOrShorten *inst = ir_build_inst_gen<IrInstGenWidenOrShorten>(&ira->new_irb, scope, source_node); 4083 inst->base.value->type = result_type; 4084 inst->target = target; 4085 4086 ir_ref_inst_gen(target, ira->new_irb.current_basic_block); 4087 4088 return &inst->base; 4089 } 4090 4091 static IrInstSrc *ir_build_int_to_ptr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4092 IrInstSrc *dest_type, IrInstSrc *target) 4093 { 4094 IrInstSrcIntToPtr *instruction = ir_build_instruction<IrInstSrcIntToPtr>(irb, scope, source_node); 4095 instruction->dest_type = dest_type; 4096 instruction->target = target; 4097 4098 ir_ref_instruction(dest_type, irb->current_basic_block); 4099 ir_ref_instruction(target, irb->current_basic_block); 4100 4101 return &instruction->base; 4102 } 4103 4104 static IrInstGen *ir_build_int_to_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 4105 IrInstGen *target, ZigType *ptr_type) 4106 { 4107 IrInstGenIntToPtr *instruction = ir_build_inst_gen<IrInstGenIntToPtr>(&ira->new_irb, scope, source_node); 4108 instruction->base.value->type = ptr_type; 4109 instruction->target = target; 4110 4111 ir_ref_inst_gen(target, ira->new_irb.current_basic_block); 4112 4113 return &instruction->base; 4114 } 4115 4116 static IrInstSrc *ir_build_ptr_to_int_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4117 IrInstSrc *target) 4118 { 4119 IrInstSrcPtrToInt *inst = ir_build_instruction<IrInstSrcPtrToInt>(irb, scope, source_node); 4120 inst->target = target; 4121 4122 ir_ref_instruction(target, irb->current_basic_block); 4123 4124 return &inst->base; 4125 } 4126 4127 static IrInstGen *ir_build_ptr_to_int_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target) { 4128 IrInstGenPtrToInt *inst = ir_build_inst_gen<IrInstGenPtrToInt>(&ira->new_irb, source_instr->scope, source_instr->source_node); 4129 inst->base.value->type = ira->codegen->builtin_types.entry_usize; 4130 inst->target = target; 4131 4132 ir_ref_inst_gen(target, ira->new_irb.current_basic_block); 4133 4134 return &inst->base; 4135 } 4136 4137 static IrInstSrc *ir_build_int_to_enum_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4138 IrInstSrc *dest_type, IrInstSrc *target) 4139 { 4140 IrInstSrcIntToEnum *instruction = ir_build_instruction<IrInstSrcIntToEnum>(irb, scope, source_node); 4141 instruction->dest_type = dest_type; 4142 instruction->target = target; 4143 4144 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 4145 ir_ref_instruction(target, irb->current_basic_block); 4146 4147 return &instruction->base; 4148 } 4149 4150 static IrInstGen *ir_build_int_to_enum_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 4151 ZigType *dest_type, IrInstGen *target) 4152 { 4153 IrInstGenIntToEnum *instruction = ir_build_inst_gen<IrInstGenIntToEnum>(&ira->new_irb, scope, source_node); 4154 instruction->base.value->type = dest_type; 4155 instruction->target = target; 4156 4157 ir_ref_inst_gen(target, ira->new_irb.current_basic_block); 4158 4159 return &instruction->base; 4160 } 4161 4162 static IrInstSrc *ir_build_enum_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4163 IrInstSrc *target) 4164 { 4165 IrInstSrcEnumToInt *instruction = ir_build_instruction<IrInstSrcEnumToInt>( 4166 irb, scope, source_node); 4167 instruction->target = target; 4168 4169 ir_ref_instruction(target, irb->current_basic_block); 4170 4171 return &instruction->base; 4172 } 4173 4174 static IrInstSrc *ir_build_int_to_err_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4175 IrInstSrc *target) 4176 { 4177 IrInstSrcIntToErr *instruction = ir_build_instruction<IrInstSrcIntToErr>(irb, scope, source_node); 4178 instruction->target = target; 4179 4180 ir_ref_instruction(target, irb->current_basic_block); 4181 4182 return &instruction->base; 4183 } 4184 4185 static IrInstGen *ir_build_int_to_err_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, 4186 ZigType *wanted_type) 4187 { 4188 IrInstGenIntToErr *instruction = ir_build_inst_gen<IrInstGenIntToErr>(&ira->new_irb, scope, source_node); 4189 instruction->base.value->type = wanted_type; 4190 instruction->target = target; 4191 4192 ir_ref_inst_gen(target, ira->new_irb.current_basic_block); 4193 4194 return &instruction->base; 4195 } 4196 4197 static IrInstSrc *ir_build_err_to_int_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4198 IrInstSrc *target) 4199 { 4200 IrInstSrcErrToInt *instruction = ir_build_instruction<IrInstSrcErrToInt>( 4201 irb, scope, source_node); 4202 instruction->target = target; 4203 4204 ir_ref_instruction(target, irb->current_basic_block); 4205 4206 return &instruction->base; 4207 } 4208 4209 static IrInstGen *ir_build_err_to_int_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, 4210 ZigType *wanted_type) 4211 { 4212 IrInstGenErrToInt *instruction = ir_build_inst_gen<IrInstGenErrToInt>(&ira->new_irb, scope, source_node); 4213 instruction->base.value->type = wanted_type; 4214 instruction->target = target; 4215 4216 ir_ref_inst_gen(target, ira->new_irb.current_basic_block); 4217 4218 return &instruction->base; 4219 } 4220 4221 static IrInstSrc *ir_build_check_switch_prongs(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4222 IrInstSrc *target_value, IrInstSrcCheckSwitchProngsRange *ranges, size_t range_count, 4223 bool have_else_prong, bool have_underscore_prong) 4224 { 4225 IrInstSrcCheckSwitchProngs *instruction = ir_build_instruction<IrInstSrcCheckSwitchProngs>( 4226 irb, scope, source_node); 4227 instruction->target_value = target_value; 4228 instruction->ranges = ranges; 4229 instruction->range_count = range_count; 4230 instruction->have_else_prong = have_else_prong; 4231 instruction->have_underscore_prong = have_underscore_prong; 4232 4233 ir_ref_instruction(target_value, irb->current_basic_block); 4234 for (size_t i = 0; i < range_count; i += 1) { 4235 ir_ref_instruction(ranges[i].start, irb->current_basic_block); 4236 ir_ref_instruction(ranges[i].end, irb->current_basic_block); 4237 } 4238 4239 return &instruction->base; 4240 } 4241 4242 static IrInstSrc *ir_build_check_statement_is_void(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4243 IrInstSrc* statement_value) 4244 { 4245 IrInstSrcCheckStatementIsVoid *instruction = ir_build_instruction<IrInstSrcCheckStatementIsVoid>( 4246 irb, scope, source_node); 4247 instruction->statement_value = statement_value; 4248 4249 ir_ref_instruction(statement_value, irb->current_basic_block); 4250 4251 return &instruction->base; 4252 } 4253 4254 static IrInstSrc *ir_build_type_name(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4255 IrInstSrc *type_value) 4256 { 4257 IrInstSrcTypeName *instruction = ir_build_instruction<IrInstSrcTypeName>(irb, scope, source_node); 4258 instruction->type_value = type_value; 4259 4260 ir_ref_instruction(type_value, irb->current_basic_block); 4261 4262 return &instruction->base; 4263 } 4264 4265 static IrInstSrc *ir_build_decl_ref(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) { 4266 IrInstSrcDeclRef *instruction = ir_build_instruction<IrInstSrcDeclRef>(irb, scope, source_node); 4267 instruction->tld = tld; 4268 instruction->lval = lval; 4269 4270 return &instruction->base; 4271 } 4272 4273 static IrInstSrc *ir_build_panic_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *msg) { 4274 IrInstSrcPanic *instruction = ir_build_instruction<IrInstSrcPanic>(irb, scope, source_node); 4275 instruction->base.is_noreturn = true; 4276 instruction->msg = msg; 4277 4278 ir_ref_instruction(msg, irb->current_basic_block); 4279 4280 return &instruction->base; 4281 } 4282 4283 static IrInstGen *ir_build_panic_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *msg) { 4284 IrInstGenPanic *instruction = ir_build_inst_noreturn<IrInstGenPanic>(&ira->new_irb, 4285 source_instr->scope, source_instr->source_node); 4286 instruction->msg = msg; 4287 4288 ir_ref_inst_gen(msg, ira->new_irb.current_basic_block); 4289 4290 return &instruction->base; 4291 } 4292 4293 static IrInstSrc *ir_build_tag_name_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target) { 4294 IrInstSrcTagName *instruction = ir_build_instruction<IrInstSrcTagName>(irb, scope, source_node); 4295 instruction->target = target; 4296 4297 ir_ref_instruction(target, irb->current_basic_block); 4298 4299 return &instruction->base; 4300 } 4301 4302 static IrInstGen *ir_build_tag_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target, 4303 ZigType *result_type) 4304 { 4305 IrInstGenTagName *instruction = ir_build_inst_gen<IrInstGenTagName>(&ira->new_irb, 4306 source_instr->scope, source_instr->source_node); 4307 instruction->base.value->type = result_type; 4308 instruction->target = target; 4309 4310 ir_ref_inst_gen(target, ira->new_irb.current_basic_block); 4311 4312 return &instruction->base; 4313 } 4314 4315 static IrInstSrc *ir_build_tag_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4316 IrInstSrc *target) 4317 { 4318 IrInstSrcTagType *instruction = ir_build_instruction<IrInstSrcTagType>(irb, scope, source_node); 4319 instruction->target = target; 4320 4321 ir_ref_instruction(target, irb->current_basic_block); 4322 4323 return &instruction->base; 4324 } 4325 4326 static IrInstSrc *ir_build_field_parent_ptr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4327 IrInstSrc *type_value, IrInstSrc *field_name, IrInstSrc *field_ptr) 4328 { 4329 IrInstSrcFieldParentPtr *inst = ir_build_instruction<IrInstSrcFieldParentPtr>( 4330 irb, scope, source_node); 4331 inst->type_value = type_value; 4332 inst->field_name = field_name; 4333 inst->field_ptr = field_ptr; 4334 4335 ir_ref_instruction(type_value, irb->current_basic_block); 4336 ir_ref_instruction(field_name, irb->current_basic_block); 4337 ir_ref_instruction(field_ptr, irb->current_basic_block); 4338 4339 return &inst->base; 4340 } 4341 4342 static IrInstGen *ir_build_field_parent_ptr_gen(IrAnalyze *ira, IrInst *source_instr, 4343 IrInstGen *field_ptr, TypeStructField *field, ZigType *result_type) 4344 { 4345 IrInstGenFieldParentPtr *inst = ir_build_inst_gen<IrInstGenFieldParentPtr>(&ira->new_irb, 4346 source_instr->scope, source_instr->source_node); 4347 inst->base.value->type = result_type; 4348 inst->field_ptr = field_ptr; 4349 inst->field = field; 4350 4351 ir_ref_inst_gen(field_ptr, ira->new_irb.current_basic_block); 4352 4353 return &inst->base; 4354 } 4355 4356 static IrInstSrc *ir_build_byte_offset_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4357 IrInstSrc *type_value, IrInstSrc *field_name) 4358 { 4359 IrInstSrcByteOffsetOf *instruction = ir_build_instruction<IrInstSrcByteOffsetOf>(irb, scope, source_node); 4360 instruction->type_value = type_value; 4361 instruction->field_name = field_name; 4362 4363 ir_ref_instruction(type_value, irb->current_basic_block); 4364 ir_ref_instruction(field_name, irb->current_basic_block); 4365 4366 return &instruction->base; 4367 } 4368 4369 static IrInstSrc *ir_build_bit_offset_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4370 IrInstSrc *type_value, IrInstSrc *field_name) 4371 { 4372 IrInstSrcBitOffsetOf *instruction = ir_build_instruction<IrInstSrcBitOffsetOf>(irb, scope, source_node); 4373 instruction->type_value = type_value; 4374 instruction->field_name = field_name; 4375 4376 ir_ref_instruction(type_value, irb->current_basic_block); 4377 ir_ref_instruction(field_name, irb->current_basic_block); 4378 4379 return &instruction->base; 4380 } 4381 4382 static IrInstSrc *ir_build_type_info(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value) { 4383 IrInstSrcTypeInfo *instruction = ir_build_instruction<IrInstSrcTypeInfo>(irb, scope, source_node); 4384 instruction->type_value = type_value; 4385 4386 ir_ref_instruction(type_value, irb->current_basic_block); 4387 4388 return &instruction->base; 4389 } 4390 4391 static IrInstSrc *ir_build_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_info) { 4392 IrInstSrcType *instruction = ir_build_instruction<IrInstSrcType>(irb, scope, source_node); 4393 instruction->type_info = type_info; 4394 4395 ir_ref_instruction(type_info, irb->current_basic_block); 4396 4397 return &instruction->base; 4398 } 4399 4400 static IrInstSrc *ir_build_set_eval_branch_quota(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4401 IrInstSrc *new_quota) 4402 { 4403 IrInstSrcSetEvalBranchQuota *instruction = ir_build_instruction<IrInstSrcSetEvalBranchQuota>(irb, scope, source_node); 4404 instruction->new_quota = new_quota; 4405 4406 ir_ref_instruction(new_quota, irb->current_basic_block); 4407 4408 return &instruction->base; 4409 } 4410 4411 static IrInstSrc *ir_build_align_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4412 IrInstSrc *align_bytes, IrInstSrc *target) 4413 { 4414 IrInstSrcAlignCast *instruction = ir_build_instruction<IrInstSrcAlignCast>(irb, scope, source_node); 4415 instruction->align_bytes = align_bytes; 4416 instruction->target = target; 4417 4418 ir_ref_instruction(align_bytes, irb->current_basic_block); 4419 ir_ref_instruction(target, irb->current_basic_block); 4420 4421 return &instruction->base; 4422 } 4423 4424 static IrInstGen *ir_build_align_cast_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, 4425 ZigType *result_type) 4426 { 4427 IrInstGenAlignCast *instruction = ir_build_inst_gen<IrInstGenAlignCast>(&ira->new_irb, scope, source_node); 4428 instruction->base.value->type = result_type; 4429 instruction->target = target; 4430 4431 ir_ref_inst_gen(target, ira->new_irb.current_basic_block); 4432 4433 return &instruction->base; 4434 } 4435 4436 static IrInstSrc *ir_build_resolve_result(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4437 ResultLoc *result_loc, IrInstSrc *ty) 4438 { 4439 IrInstSrcResolveResult *instruction = ir_build_instruction<IrInstSrcResolveResult>(irb, scope, source_node); 4440 instruction->result_loc = result_loc; 4441 instruction->ty = ty; 4442 4443 if (ty != nullptr) ir_ref_instruction(ty, irb->current_basic_block); 4444 4445 return &instruction->base; 4446 } 4447 4448 static IrInstSrc *ir_build_reset_result(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4449 ResultLoc *result_loc) 4450 { 4451 IrInstSrcResetResult *instruction = ir_build_instruction<IrInstSrcResetResult>(irb, scope, source_node); 4452 instruction->result_loc = result_loc; 4453 instruction->base.is_gen = true; 4454 4455 return &instruction->base; 4456 } 4457 4458 static IrInstSrc *ir_build_opaque_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 4459 IrInstSrcOpaqueType *instruction = ir_build_instruction<IrInstSrcOpaqueType>(irb, scope, source_node); 4460 4461 return &instruction->base; 4462 } 4463 4464 static IrInstSrc *ir_build_set_align_stack(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4465 IrInstSrc *align_bytes) 4466 { 4467 IrInstSrcSetAlignStack *instruction = ir_build_instruction<IrInstSrcSetAlignStack>(irb, scope, source_node); 4468 instruction->align_bytes = align_bytes; 4469 4470 ir_ref_instruction(align_bytes, irb->current_basic_block); 4471 4472 return &instruction->base; 4473 } 4474 4475 static IrInstSrc *ir_build_arg_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4476 IrInstSrc *fn_type, IrInstSrc *arg_index, bool allow_var) 4477 { 4478 IrInstSrcArgType *instruction = ir_build_instruction<IrInstSrcArgType>(irb, scope, source_node); 4479 instruction->fn_type = fn_type; 4480 instruction->arg_index = arg_index; 4481 instruction->allow_var = allow_var; 4482 4483 ir_ref_instruction(fn_type, irb->current_basic_block); 4484 ir_ref_instruction(arg_index, irb->current_basic_block); 4485 4486 return &instruction->base; 4487 } 4488 4489 static IrInstSrc *ir_build_error_return_trace_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4490 IrInstErrorReturnTraceOptional optional) 4491 { 4492 IrInstSrcErrorReturnTrace *inst = ir_build_instruction<IrInstSrcErrorReturnTrace>(irb, scope, source_node); 4493 inst->optional = optional; 4494 4495 return &inst->base; 4496 } 4497 4498 static IrInstGen *ir_build_error_return_trace_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 4499 IrInstErrorReturnTraceOptional optional, ZigType *result_type) 4500 { 4501 IrInstGenErrorReturnTrace *inst = ir_build_inst_gen<IrInstGenErrorReturnTrace>(&ira->new_irb, scope, source_node); 4502 inst->base.value->type = result_type; 4503 inst->optional = optional; 4504 4505 return &inst->base; 4506 } 4507 4508 static IrInstSrc *ir_build_error_union(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4509 IrInstSrc *err_set, IrInstSrc *payload) 4510 { 4511 IrInstSrcErrorUnion *instruction = ir_build_instruction<IrInstSrcErrorUnion>(irb, scope, source_node); 4512 instruction->err_set = err_set; 4513 instruction->payload = payload; 4514 4515 ir_ref_instruction(err_set, irb->current_basic_block); 4516 ir_ref_instruction(payload, irb->current_basic_block); 4517 4518 return &instruction->base; 4519 } 4520 4521 static IrInstSrc *ir_build_atomic_rmw_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4522 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *op, IrInstSrc *operand, 4523 IrInstSrc *ordering) 4524 { 4525 IrInstSrcAtomicRmw *instruction = ir_build_instruction<IrInstSrcAtomicRmw>(irb, scope, source_node); 4526 instruction->operand_type = operand_type; 4527 instruction->ptr = ptr; 4528 instruction->op = op; 4529 instruction->operand = operand; 4530 instruction->ordering = ordering; 4531 4532 ir_ref_instruction(operand_type, irb->current_basic_block); 4533 ir_ref_instruction(ptr, irb->current_basic_block); 4534 ir_ref_instruction(op, irb->current_basic_block); 4535 ir_ref_instruction(operand, irb->current_basic_block); 4536 ir_ref_instruction(ordering, irb->current_basic_block); 4537 4538 return &instruction->base; 4539 } 4540 4541 static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr, 4542 IrInstGen *ptr, IrInstGen *operand, AtomicRmwOp op, AtomicOrder ordering, ZigType *operand_type) 4543 { 4544 IrInstGenAtomicRmw *instruction = ir_build_inst_gen<IrInstGenAtomicRmw>(&ira->new_irb, source_instr->scope, source_instr->source_node); 4545 instruction->base.value->type = operand_type; 4546 instruction->ptr = ptr; 4547 instruction->op = op; 4548 instruction->operand = operand; 4549 instruction->ordering = ordering; 4550 4551 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); 4552 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); 4553 4554 return &instruction->base; 4555 } 4556 4557 static IrInstSrc *ir_build_atomic_load_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4558 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *ordering) 4559 { 4560 IrInstSrcAtomicLoad *instruction = ir_build_instruction<IrInstSrcAtomicLoad>(irb, scope, source_node); 4561 instruction->operand_type = operand_type; 4562 instruction->ptr = ptr; 4563 instruction->ordering = ordering; 4564 4565 ir_ref_instruction(operand_type, irb->current_basic_block); 4566 ir_ref_instruction(ptr, irb->current_basic_block); 4567 ir_ref_instruction(ordering, irb->current_basic_block); 4568 4569 return &instruction->base; 4570 } 4571 4572 static IrInstGen *ir_build_atomic_load_gen(IrAnalyze *ira, IrInst *source_instr, 4573 IrInstGen *ptr, AtomicOrder ordering, ZigType *operand_type) 4574 { 4575 IrInstGenAtomicLoad *instruction = ir_build_inst_gen<IrInstGenAtomicLoad>(&ira->new_irb, 4576 source_instr->scope, source_instr->source_node); 4577 instruction->base.value->type = operand_type; 4578 instruction->ptr = ptr; 4579 instruction->ordering = ordering; 4580 4581 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); 4582 4583 return &instruction->base; 4584 } 4585 4586 static IrInstSrc *ir_build_atomic_store_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4587 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *value, IrInstSrc *ordering) 4588 { 4589 IrInstSrcAtomicStore *instruction = ir_build_instruction<IrInstSrcAtomicStore>(irb, scope, source_node); 4590 instruction->operand_type = operand_type; 4591 instruction->ptr = ptr; 4592 instruction->value = value; 4593 instruction->ordering = ordering; 4594 4595 ir_ref_instruction(operand_type, irb->current_basic_block); 4596 ir_ref_instruction(ptr, irb->current_basic_block); 4597 ir_ref_instruction(value, irb->current_basic_block); 4598 ir_ref_instruction(ordering, irb->current_basic_block); 4599 4600 return &instruction->base; 4601 } 4602 4603 static IrInstGen *ir_build_atomic_store_gen(IrAnalyze *ira, IrInst *source_instr, 4604 IrInstGen *ptr, IrInstGen *value, AtomicOrder ordering) 4605 { 4606 IrInstGenAtomicStore *instruction = ir_build_inst_void<IrInstGenAtomicStore>(&ira->new_irb, 4607 source_instr->scope, source_instr->source_node); 4608 instruction->ptr = ptr; 4609 instruction->value = value; 4610 instruction->ordering = ordering; 4611 4612 ir_ref_inst_gen(ptr, ira->new_irb.current_basic_block); 4613 ir_ref_inst_gen(value, ira->new_irb.current_basic_block); 4614 4615 return &instruction->base; 4616 } 4617 4618 static IrInstSrc *ir_build_save_err_ret_addr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 4619 IrInstSrcSaveErrRetAddr *inst = ir_build_instruction<IrInstSrcSaveErrRetAddr>(irb, scope, source_node); 4620 return &inst->base; 4621 } 4622 4623 static IrInstGen *ir_build_save_err_ret_addr_gen(IrAnalyze *ira, IrInst *source_instr) { 4624 IrInstGenSaveErrRetAddr *inst = ir_build_inst_void<IrInstGenSaveErrRetAddr>(&ira->new_irb, 4625 source_instr->scope, source_instr->source_node); 4626 return &inst->base; 4627 } 4628 4629 static IrInstSrc *ir_build_add_implicit_return_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4630 IrInstSrc *value, ResultLocReturn *result_loc_ret) 4631 { 4632 IrInstSrcAddImplicitReturnType *inst = ir_build_instruction<IrInstSrcAddImplicitReturnType>(irb, scope, source_node); 4633 inst->value = value; 4634 inst->result_loc_ret = result_loc_ret; 4635 4636 ir_ref_instruction(value, irb->current_basic_block); 4637 4638 return &inst->base; 4639 } 4640 4641 static IrInstSrc *ir_build_has_decl(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4642 IrInstSrc *container, IrInstSrc *name) 4643 { 4644 IrInstSrcHasDecl *instruction = ir_build_instruction<IrInstSrcHasDecl>(irb, scope, source_node); 4645 instruction->container = container; 4646 instruction->name = name; 4647 4648 ir_ref_instruction(container, irb->current_basic_block); 4649 ir_ref_instruction(name, irb->current_basic_block); 4650 4651 return &instruction->base; 4652 } 4653 4654 static IrInstSrc *ir_build_undeclared_identifier(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *name) { 4655 IrInstSrcUndeclaredIdent *instruction = ir_build_instruction<IrInstSrcUndeclaredIdent>(irb, scope, source_node); 4656 instruction->name = name; 4657 4658 return &instruction->base; 4659 } 4660 4661 static IrInstSrc *ir_build_check_runtime_scope(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *scope_is_comptime, IrInstSrc *is_comptime) { 4662 IrInstSrcCheckRuntimeScope *instruction = ir_build_instruction<IrInstSrcCheckRuntimeScope>(irb, scope, source_node); 4663 instruction->scope_is_comptime = scope_is_comptime; 4664 instruction->is_comptime = is_comptime; 4665 4666 ir_ref_instruction(scope_is_comptime, irb->current_basic_block); 4667 ir_ref_instruction(is_comptime, irb->current_basic_block); 4668 4669 return &instruction->base; 4670 } 4671 4672 static IrInstSrc *ir_build_union_init_named_field(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4673 IrInstSrc *union_type, IrInstSrc *field_name, IrInstSrc *field_result_loc, IrInstSrc *result_loc) 4674 { 4675 IrInstSrcUnionInitNamedField *instruction = ir_build_instruction<IrInstSrcUnionInitNamedField>(irb, scope, source_node); 4676 instruction->union_type = union_type; 4677 instruction->field_name = field_name; 4678 instruction->field_result_loc = field_result_loc; 4679 instruction->result_loc = result_loc; 4680 4681 ir_ref_instruction(union_type, irb->current_basic_block); 4682 ir_ref_instruction(field_name, irb->current_basic_block); 4683 ir_ref_instruction(field_result_loc, irb->current_basic_block); 4684 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 4685 4686 return &instruction->base; 4687 } 4688 4689 4690 static IrInstGen *ir_build_vector_to_array(IrAnalyze *ira, IrInst *source_instruction, 4691 ZigType *result_type, IrInstGen *vector, IrInstGen *result_loc) 4692 { 4693 IrInstGenVectorToArray *instruction = ir_build_inst_gen<IrInstGenVectorToArray>(&ira->new_irb, 4694 source_instruction->scope, source_instruction->source_node); 4695 instruction->base.value->type = result_type; 4696 instruction->vector = vector; 4697 instruction->result_loc = result_loc; 4698 4699 ir_ref_inst_gen(vector, ira->new_irb.current_basic_block); 4700 ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); 4701 4702 return &instruction->base; 4703 } 4704 4705 static IrInstGen *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInst *source_instruction, 4706 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc) 4707 { 4708 IrInstGenPtrOfArrayToSlice *instruction = ir_build_inst_gen<IrInstGenPtrOfArrayToSlice>(&ira->new_irb, 4709 source_instruction->scope, source_instruction->source_node); 4710 instruction->base.value->type = result_type; 4711 instruction->operand = operand; 4712 instruction->result_loc = result_loc; 4713 4714 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); 4715 ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); 4716 4717 return &instruction->base; 4718 } 4719 4720 static IrInstGen *ir_build_array_to_vector(IrAnalyze *ira, IrInst *source_instruction, 4721 IrInstGen *array, ZigType *result_type) 4722 { 4723 IrInstGenArrayToVector *instruction = ir_build_inst_gen<IrInstGenArrayToVector>(&ira->new_irb, 4724 source_instruction->scope, source_instruction->source_node); 4725 instruction->base.value->type = result_type; 4726 instruction->array = array; 4727 4728 ir_ref_inst_gen(array, ira->new_irb.current_basic_block); 4729 4730 return &instruction->base; 4731 } 4732 4733 static IrInstGen *ir_build_assert_zero(IrAnalyze *ira, IrInst *source_instruction, 4734 IrInstGen *target) 4735 { 4736 IrInstGenAssertZero *instruction = ir_build_inst_gen<IrInstGenAssertZero>(&ira->new_irb, 4737 source_instruction->scope, source_instruction->source_node); 4738 instruction->base.value->type = ira->codegen->builtin_types.entry_void; 4739 instruction->target = target; 4740 4741 ir_ref_inst_gen(target, ira->new_irb.current_basic_block); 4742 4743 return &instruction->base; 4744 } 4745 4746 static IrInstGen *ir_build_assert_non_null(IrAnalyze *ira, IrInst *source_instruction, 4747 IrInstGen *target) 4748 { 4749 IrInstGenAssertNonNull *instruction = ir_build_inst_gen<IrInstGenAssertNonNull>(&ira->new_irb, 4750 source_instruction->scope, source_instruction->source_node); 4751 instruction->base.value->type = ira->codegen->builtin_types.entry_void; 4752 instruction->target = target; 4753 4754 ir_ref_inst_gen(target, ira->new_irb.current_basic_block); 4755 4756 return &instruction->base; 4757 } 4758 4759 static IrInstSrc *ir_build_alloca_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4760 IrInstSrc *align, const char *name_hint, IrInstSrc *is_comptime) 4761 { 4762 IrInstSrcAlloca *instruction = ir_build_instruction<IrInstSrcAlloca>(irb, scope, source_node); 4763 instruction->base.is_gen = true; 4764 instruction->align = align; 4765 instruction->name_hint = name_hint; 4766 instruction->is_comptime = is_comptime; 4767 4768 if (align != nullptr) ir_ref_instruction(align, irb->current_basic_block); 4769 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); 4770 4771 return &instruction->base; 4772 } 4773 4774 static IrInstGenAlloca *ir_build_alloca_gen(IrAnalyze *ira, IrInst *source_instruction, 4775 uint32_t align, const char *name_hint) 4776 { 4777 IrInstGenAlloca *instruction = ir_create_inst_gen<IrInstGenAlloca>(&ira->new_irb, 4778 source_instruction->scope, source_instruction->source_node); 4779 instruction->align = align; 4780 instruction->name_hint = name_hint; 4781 4782 return instruction; 4783 } 4784 4785 static IrInstSrc *ir_build_end_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4786 IrInstSrc *value, ResultLoc *result_loc) 4787 { 4788 IrInstSrcEndExpr *instruction = ir_build_instruction<IrInstSrcEndExpr>(irb, scope, source_node); 4789 instruction->base.is_gen = true; 4790 instruction->value = value; 4791 instruction->result_loc = result_loc; 4792 4793 ir_ref_instruction(value, irb->current_basic_block); 4794 4795 return &instruction->base; 4796 } 4797 4798 static IrInstSrcSuspendBegin *ir_build_suspend_begin_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 4799 return ir_build_instruction<IrInstSrcSuspendBegin>(irb, scope, source_node); 4800 } 4801 4802 static IrInstGen *ir_build_suspend_begin_gen(IrAnalyze *ira, IrInst *source_instr) { 4803 IrInstGenSuspendBegin *inst = ir_build_inst_void<IrInstGenSuspendBegin>(&ira->new_irb, 4804 source_instr->scope, source_instr->source_node); 4805 return &inst->base; 4806 } 4807 4808 static IrInstSrc *ir_build_suspend_finish_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4809 IrInstSrcSuspendBegin *begin) 4810 { 4811 IrInstSrcSuspendFinish *inst = ir_build_instruction<IrInstSrcSuspendFinish>(irb, scope, source_node); 4812 inst->begin = begin; 4813 4814 ir_ref_instruction(&begin->base, irb->current_basic_block); 4815 4816 return &inst->base; 4817 } 4818 4819 static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSuspendBegin *begin) { 4820 IrInstGenSuspendFinish *inst = ir_build_inst_void<IrInstGenSuspendFinish>(&ira->new_irb, 4821 source_instr->scope, source_instr->source_node); 4822 inst->begin = begin; 4823 4824 ir_ref_inst_gen(&begin->base, ira->new_irb.current_basic_block); 4825 4826 return &inst->base; 4827 } 4828 4829 static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4830 IrInstSrc *frame, ResultLoc *result_loc, bool is_noasync) 4831 { 4832 IrInstSrcAwait *instruction = ir_build_instruction<IrInstSrcAwait>(irb, scope, source_node); 4833 instruction->frame = frame; 4834 instruction->result_loc = result_loc; 4835 instruction->is_noasync = is_noasync; 4836 4837 ir_ref_instruction(frame, irb->current_basic_block); 4838 4839 return &instruction->base; 4840 } 4841 4842 static IrInstGenAwait *ir_build_await_gen(IrAnalyze *ira, IrInst *source_instruction, 4843 IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc, bool is_noasync) 4844 { 4845 IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb, 4846 source_instruction->scope, source_instruction->source_node); 4847 instruction->base.value->type = result_type; 4848 instruction->frame = frame; 4849 instruction->result_loc = result_loc; 4850 instruction->is_noasync = is_noasync; 4851 4852 ir_ref_inst_gen(frame, ira->new_irb.current_basic_block); 4853 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block); 4854 4855 return instruction; 4856 } 4857 4858 static IrInstSrc *ir_build_resume_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *frame) { 4859 IrInstSrcResume *instruction = ir_build_instruction<IrInstSrcResume>(irb, scope, source_node); 4860 instruction->frame = frame; 4861 4862 ir_ref_instruction(frame, irb->current_basic_block); 4863 4864 return &instruction->base; 4865 } 4866 4867 static IrInstGen *ir_build_resume_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *frame) { 4868 IrInstGenResume *instruction = ir_build_inst_void<IrInstGenResume>(&ira->new_irb, 4869 source_instr->scope, source_instr->source_node); 4870 instruction->frame = frame; 4871 4872 ir_ref_inst_gen(frame, ira->new_irb.current_basic_block); 4873 4874 return &instruction->base; 4875 } 4876 4877 static IrInstSrcSpillBegin *ir_build_spill_begin_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4878 IrInstSrc *operand, SpillId spill_id) 4879 { 4880 IrInstSrcSpillBegin *instruction = ir_build_instruction<IrInstSrcSpillBegin>(irb, scope, source_node); 4881 instruction->operand = operand; 4882 instruction->spill_id = spill_id; 4883 4884 ir_ref_instruction(operand, irb->current_basic_block); 4885 4886 return instruction; 4887 } 4888 4889 static IrInstGen *ir_build_spill_begin_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, 4890 SpillId spill_id) 4891 { 4892 IrInstGenSpillBegin *instruction = ir_build_inst_void<IrInstGenSpillBegin>(&ira->new_irb, 4893 source_instr->scope, source_instr->source_node); 4894 instruction->operand = operand; 4895 instruction->spill_id = spill_id; 4896 4897 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block); 4898 4899 return &instruction->base; 4900 } 4901 4902 static IrInstSrc *ir_build_spill_end_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4903 IrInstSrcSpillBegin *begin) 4904 { 4905 IrInstSrcSpillEnd *instruction = ir_build_instruction<IrInstSrcSpillEnd>(irb, scope, source_node); 4906 instruction->begin = begin; 4907 4908 ir_ref_instruction(&begin->base, irb->current_basic_block); 4909 4910 return &instruction->base; 4911 } 4912 4913 static IrInstGen *ir_build_spill_end_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSpillBegin *begin, 4914 ZigType *result_type) 4915 { 4916 IrInstGenSpillEnd *instruction = ir_build_inst_gen<IrInstGenSpillEnd>(&ira->new_irb, 4917 source_instr->scope, source_instr->source_node); 4918 instruction->base.value->type = result_type; 4919 instruction->begin = begin; 4920 4921 ir_ref_inst_gen(&begin->base, ira->new_irb.current_basic_block); 4922 4923 return &instruction->base; 4924 } 4925 4926 static IrInstGen *ir_build_vector_extract_elem(IrAnalyze *ira, IrInst *source_instruction, 4927 IrInstGen *vector, IrInstGen *index) 4928 { 4929 IrInstGenVectorExtractElem *instruction = ir_build_inst_gen<IrInstGenVectorExtractElem>( 4930 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 4931 instruction->base.value->type = vector->value->type->data.vector.elem_type; 4932 instruction->vector = vector; 4933 instruction->index = index; 4934 4935 ir_ref_inst_gen(vector, ira->new_irb.current_basic_block); 4936 ir_ref_inst_gen(index, ira->new_irb.current_basic_block); 4937 4938 return &instruction->base; 4939 } 4940 4941 static void ir_count_defers(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { 4942 results[ReturnKindUnconditional] = 0; 4943 results[ReturnKindError] = 0; 4944 4945 Scope *scope = inner_scope; 4946 4947 while (scope != outer_scope) { 4948 assert(scope); 4949 switch (scope->id) { 4950 case ScopeIdDefer: { 4951 AstNode *defer_node = scope->source_node; 4952 assert(defer_node->type == NodeTypeDefer); 4953 ReturnKind defer_kind = defer_node->data.defer.kind; 4954 results[defer_kind] += 1; 4955 scope = scope->parent; 4956 continue; 4957 } 4958 case ScopeIdDecls: 4959 case ScopeIdFnDef: 4960 return; 4961 case ScopeIdBlock: 4962 case ScopeIdVarDecl: 4963 case ScopeIdLoop: 4964 case ScopeIdSuspend: 4965 case ScopeIdCompTime: 4966 case ScopeIdRuntime: 4967 case ScopeIdTypeOf: 4968 case ScopeIdExpr: 4969 scope = scope->parent; 4970 continue; 4971 case ScopeIdDeferExpr: 4972 case ScopeIdCImport: 4973 zig_unreachable(); 4974 } 4975 } 4976 } 4977 4978 static IrInstSrc *ir_mark_gen(IrInstSrc *instruction) { 4979 instruction->is_gen = true; 4980 return instruction; 4981 } 4982 4983 static bool ir_gen_defers_for_block(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_scope, bool gen_error_defers) { 4984 Scope *scope = inner_scope; 4985 bool is_noreturn = false; 4986 while (scope != outer_scope) { 4987 if (!scope) 4988 return is_noreturn; 4989 4990 switch (scope->id) { 4991 case ScopeIdDefer: { 4992 AstNode *defer_node = scope->source_node; 4993 assert(defer_node->type == NodeTypeDefer); 4994 ReturnKind defer_kind = defer_node->data.defer.kind; 4995 if (defer_kind == ReturnKindUnconditional || 4996 (gen_error_defers && defer_kind == ReturnKindError)) 4997 { 4998 AstNode *defer_expr_node = defer_node->data.defer.expr; 4999 Scope *defer_expr_scope = defer_node->data.defer.expr_scope; 5000 IrInstSrc *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope); 5001 if (defer_expr_value != irb->codegen->invalid_inst_src) { 5002 if (defer_expr_value->is_noreturn) { 5003 is_noreturn = true; 5004 } else { 5005 ir_mark_gen(ir_build_check_statement_is_void(irb, defer_expr_scope, defer_expr_node, 5006 defer_expr_value)); 5007 } 5008 } 5009 } 5010 scope = scope->parent; 5011 continue; 5012 } 5013 case ScopeIdDecls: 5014 case ScopeIdFnDef: 5015 return is_noreturn; 5016 case ScopeIdBlock: 5017 case ScopeIdVarDecl: 5018 case ScopeIdLoop: 5019 case ScopeIdSuspend: 5020 case ScopeIdCompTime: 5021 case ScopeIdRuntime: 5022 case ScopeIdTypeOf: 5023 case ScopeIdExpr: 5024 scope = scope->parent; 5025 continue; 5026 case ScopeIdDeferExpr: 5027 case ScopeIdCImport: 5028 zig_unreachable(); 5029 } 5030 } 5031 return is_noreturn; 5032 } 5033 5034 static void ir_set_cursor_at_end_gen(IrBuilderGen *irb, IrBasicBlockGen *basic_block) { 5035 assert(basic_block); 5036 irb->current_basic_block = basic_block; 5037 } 5038 5039 static void ir_set_cursor_at_end(IrBuilderSrc *irb, IrBasicBlockSrc *basic_block) { 5040 assert(basic_block); 5041 irb->current_basic_block = basic_block; 5042 } 5043 5044 static void ir_set_cursor_at_end_and_append_block(IrBuilderSrc *irb, IrBasicBlockSrc *basic_block) { 5045 basic_block->index = irb->exec->basic_block_list.length; 5046 irb->exec->basic_block_list.append(basic_block); 5047 ir_set_cursor_at_end(irb, basic_block); 5048 } 5049 5050 static ScopeSuspend *get_scope_suspend(Scope *scope) { 5051 while (scope) { 5052 if (scope->id == ScopeIdSuspend) 5053 return (ScopeSuspend *)scope; 5054 if (scope->id == ScopeIdFnDef) 5055 return nullptr; 5056 5057 scope = scope->parent; 5058 } 5059 return nullptr; 5060 } 5061 5062 static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { 5063 while (scope) { 5064 if (scope->id == ScopeIdDeferExpr) 5065 return (ScopeDeferExpr *)scope; 5066 if (scope->id == ScopeIdFnDef) 5067 return nullptr; 5068 5069 scope = scope->parent; 5070 } 5071 return nullptr; 5072 } 5073 5074 static IrInstSrc *ir_gen_return(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 5075 assert(node->type == NodeTypeReturnExpr); 5076 5077 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); 5078 if (scope_defer_expr) { 5079 if (!scope_defer_expr->reported_err) { 5080 add_node_error(irb->codegen, node, buf_sprintf("cannot return from defer expression")); 5081 scope_defer_expr->reported_err = true; 5082 } 5083 return irb->codegen->invalid_inst_src; 5084 } 5085 5086 Scope *outer_scope = irb->exec->begin_scope; 5087 5088 AstNode *expr_node = node->data.return_expr.expr; 5089 switch (node->data.return_expr.kind) { 5090 case ReturnKindUnconditional: 5091 { 5092 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>(); 5093 result_loc_ret->base.id = ResultLocIdReturn; 5094 ir_build_reset_result(irb, scope, node, &result_loc_ret->base); 5095 5096 IrInstSrc *return_value; 5097 if (expr_node) { 5098 // Temporarily set this so that if we return a type it gets the name of the function 5099 ZigFn *prev_name_fn = irb->exec->name_fn; 5100 irb->exec->name_fn = exec_fn_entry(irb->exec); 5101 return_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_ret->base); 5102 irb->exec->name_fn = prev_name_fn; 5103 if (return_value == irb->codegen->invalid_inst_src) 5104 return irb->codegen->invalid_inst_src; 5105 } else { 5106 return_value = ir_build_const_void(irb, scope, node); 5107 ir_build_end_expr(irb, scope, node, return_value, &result_loc_ret->base); 5108 } 5109 5110 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value, result_loc_ret)); 5111 5112 size_t defer_counts[2]; 5113 ir_count_defers(irb, scope, outer_scope, defer_counts); 5114 bool have_err_defers = defer_counts[ReturnKindError] > 0; 5115 if (!have_err_defers && !irb->codegen->have_err_ret_tracing) { 5116 // only generate unconditional defers 5117 ir_gen_defers_for_block(irb, scope, outer_scope, false); 5118 IrInstSrc *result = ir_build_return_src(irb, scope, node, nullptr); 5119 result_loc_ret->base.source_instruction = result; 5120 return result; 5121 } 5122 bool should_inline = ir_should_inline(irb->exec, scope); 5123 5124 IrBasicBlockSrc *err_block = ir_create_basic_block(irb, scope, "ErrRetErr"); 5125 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk"); 5126 5127 IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node, return_value, false, true); 5128 5129 IrInstSrc *is_comptime; 5130 if (should_inline) { 5131 is_comptime = ir_build_const_bool(irb, scope, node, should_inline); 5132 } else { 5133 is_comptime = ir_build_test_comptime(irb, scope, node, is_err); 5134 } 5135 5136 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime)); 5137 IrBasicBlockSrc *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt"); 5138 5139 ir_set_cursor_at_end_and_append_block(irb, err_block); 5140 ir_gen_defers_for_block(irb, scope, outer_scope, true); 5141 if (irb->codegen->have_err_ret_tracing && !should_inline) { 5142 ir_build_save_err_ret_addr_src(irb, scope, node); 5143 } 5144 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 5145 5146 ir_set_cursor_at_end_and_append_block(irb, ok_block); 5147 ir_gen_defers_for_block(irb, scope, outer_scope, false); 5148 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 5149 5150 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); 5151 IrInstSrc *result = ir_build_return_src(irb, scope, node, nullptr); 5152 result_loc_ret->base.source_instruction = result; 5153 return result; 5154 } 5155 case ReturnKindError: 5156 { 5157 assert(expr_node); 5158 IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 5159 if (err_union_ptr == irb->codegen->invalid_inst_src) 5160 return irb->codegen->invalid_inst_src; 5161 IrInstSrc *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr, true, false); 5162 5163 IrBasicBlockSrc *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); 5164 IrBasicBlockSrc *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); 5165 IrInstSrc *is_comptime; 5166 bool should_inline = ir_should_inline(irb->exec, scope); 5167 if (should_inline) { 5168 is_comptime = ir_build_const_bool(irb, scope, node, true); 5169 } else { 5170 is_comptime = ir_build_test_comptime(irb, scope, node, is_err_val); 5171 } 5172 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime)); 5173 5174 ir_set_cursor_at_end_and_append_block(irb, return_block); 5175 IrInstSrc *err_val_ptr = ir_build_unwrap_err_code_src(irb, scope, node, err_union_ptr); 5176 IrInstSrc *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); 5177 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val, nullptr)); 5178 IrInstSrcSpillBegin *spill_begin = ir_build_spill_begin_src(irb, scope, node, err_val, 5179 SpillIdRetErrCode); 5180 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>(); 5181 result_loc_ret->base.id = ResultLocIdReturn; 5182 ir_build_reset_result(irb, scope, node, &result_loc_ret->base); 5183 ir_build_end_expr(irb, scope, node, err_val, &result_loc_ret->base); 5184 if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) { 5185 if (irb->codegen->have_err_ret_tracing && !should_inline) { 5186 ir_build_save_err_ret_addr_src(irb, scope, node); 5187 } 5188 err_val = ir_build_spill_end_src(irb, scope, node, spill_begin); 5189 IrInstSrc *ret_inst = ir_build_return_src(irb, scope, node, err_val); 5190 result_loc_ret->base.source_instruction = ret_inst; 5191 } 5192 5193 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5194 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(irb, scope, node, err_union_ptr, false, false); 5195 if (lval == LValPtr) 5196 return unwrapped_ptr; 5197 else 5198 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, unwrapped_ptr), result_loc); 5199 } 5200 } 5201 zig_unreachable(); 5202 } 5203 5204 static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope, 5205 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime, 5206 bool skip_name_check) 5207 { 5208 ZigVar *variable_entry = heap::c_allocator.create<ZigVar>(); 5209 variable_entry->parent_scope = parent_scope; 5210 variable_entry->shadowable = is_shadowable; 5211 variable_entry->is_comptime = is_comptime; 5212 variable_entry->src_arg_index = SIZE_MAX; 5213 variable_entry->const_value = codegen->pass1_arena->create<ZigValue>(); 5214 5215 if (is_comptime != nullptr) { 5216 is_comptime->base.ref_count += 1; 5217 } 5218 5219 if (name) { 5220 variable_entry->name = strdup(buf_ptr(name)); 5221 5222 if (!skip_name_check) { 5223 ZigVar *existing_var = find_variable(codegen, parent_scope, name, nullptr); 5224 if (existing_var && !existing_var->shadowable) { 5225 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) { 5226 ErrorMsg *msg = add_node_error(codegen, node, 5227 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); 5228 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); 5229 } 5230 variable_entry->var_type = codegen->builtin_types.entry_invalid; 5231 } else { 5232 ZigType *type; 5233 if (get_primitive_type(codegen, name, &type) != ErrorPrimitiveTypeNotFound) { 5234 add_node_error(codegen, node, 5235 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name))); 5236 variable_entry->var_type = codegen->builtin_types.entry_invalid; 5237 } else { 5238 Tld *tld = find_decl(codegen, parent_scope, name); 5239 if (tld != nullptr) { 5240 ErrorMsg *msg = add_node_error(codegen, node, 5241 buf_sprintf("redefinition of '%s'", buf_ptr(name))); 5242 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here")); 5243 variable_entry->var_type = codegen->builtin_types.entry_invalid; 5244 } 5245 } 5246 } 5247 } 5248 } else { 5249 assert(is_shadowable); 5250 // TODO make this name not actually be in scope. user should be able to make a variable called "_anon" 5251 // might already be solved, let's just make sure it has test coverage 5252 // maybe we put a prefix on this so the debug info doesn't clobber user debug info for same named variables 5253 variable_entry->name = "_anon"; 5254 } 5255 5256 variable_entry->src_is_const = src_is_const; 5257 variable_entry->gen_is_const = gen_is_const; 5258 variable_entry->decl_node = node; 5259 variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry); 5260 5261 return variable_entry; 5262 } 5263 5264 // Set name to nullptr to make the variable anonymous (not visible to programmer). 5265 // After you call this function var->child_scope has the variable in scope 5266 static ZigVar *ir_create_var(IrBuilderSrc *irb, AstNode *node, Scope *scope, Buf *name, 5267 bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime) 5268 { 5269 bool is_underscored = name ? buf_eql_str(name, "_") : false; 5270 ZigVar *var = create_local_var(irb->codegen, node, scope, 5271 (is_underscored ? nullptr : name), src_is_const, gen_is_const, 5272 (is_underscored ? true : is_shadowable), is_comptime, false); 5273 assert(var->child_scope); 5274 return var; 5275 } 5276 5277 static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) { 5278 ResultLocPeer *result = heap::c_allocator.create<ResultLocPeer>(); 5279 result->base.id = ResultLocIdPeer; 5280 result->base.source_instruction = peer_parent->base.source_instruction; 5281 result->parent = peer_parent; 5282 result->base.allow_write_through_const = peer_parent->parent->allow_write_through_const; 5283 return result; 5284 } 5285 5286 static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *block_node, LVal lval, 5287 ResultLoc *result_loc) 5288 { 5289 assert(block_node->type == NodeTypeBlock); 5290 5291 ZigList<IrInstSrc *> incoming_values = {0}; 5292 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 5293 5294 ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope); 5295 5296 Scope *outer_block_scope = &scope_block->base; 5297 Scope *child_scope = outer_block_scope; 5298 5299 ZigFn *fn_entry = scope_fn_entry(parent_scope); 5300 if (fn_entry && fn_entry->child_scope == parent_scope) { 5301 fn_entry->def_scope = scope_block; 5302 } 5303 5304 if (block_node->data.block.statements.length == 0) { 5305 // {} 5306 return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc); 5307 } 5308 5309 if (block_node->data.block.name != nullptr) { 5310 scope_block->lval = lval; 5311 scope_block->incoming_blocks = &incoming_blocks; 5312 scope_block->incoming_values = &incoming_values; 5313 scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd"); 5314 scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, 5315 ir_should_inline(irb->exec, parent_scope)); 5316 5317 scope_block->peer_parent = heap::c_allocator.create<ResultLocPeerParent>(); 5318 scope_block->peer_parent->base.id = ResultLocIdPeerParent; 5319 scope_block->peer_parent->base.source_instruction = scope_block->is_comptime; 5320 scope_block->peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; 5321 scope_block->peer_parent->end_bb = scope_block->end_block; 5322 scope_block->peer_parent->is_comptime = scope_block->is_comptime; 5323 scope_block->peer_parent->parent = result_loc; 5324 ir_build_reset_result(irb, parent_scope, block_node, &scope_block->peer_parent->base); 5325 } 5326 5327 bool is_continuation_unreachable = false; 5328 IrInstSrc *noreturn_return_value = nullptr; 5329 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { 5330 AstNode *statement_node = block_node->data.block.statements.at(i); 5331 5332 IrInstSrc *statement_value = ir_gen_node(irb, statement_node, child_scope); 5333 is_continuation_unreachable = instr_is_unreachable(statement_value); 5334 if (is_continuation_unreachable) { 5335 // keep the last noreturn statement value around in case we need to return it 5336 noreturn_return_value = statement_value; 5337 } 5338 // This logic must be kept in sync with 5339 // [STMT_EXPR_TEST_THING] <--- (search this token) 5340 if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_inst_src) { 5341 // defer starts a new scope 5342 child_scope = statement_node->data.defer.child_scope; 5343 assert(child_scope); 5344 } else if (statement_value->id == IrInstSrcIdDeclVar) { 5345 // variable declarations start a new scope 5346 IrInstSrcDeclVar *decl_var_instruction = (IrInstSrcDeclVar *)statement_value; 5347 child_scope = decl_var_instruction->var->child_scope; 5348 } else if (statement_value != irb->codegen->invalid_inst_src && !is_continuation_unreachable) { 5349 // this statement's value must be void 5350 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value)); 5351 } 5352 } 5353 5354 if (is_continuation_unreachable) { 5355 assert(noreturn_return_value != nullptr); 5356 if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) { 5357 return noreturn_return_value; 5358 } 5359 5360 if (scope_block->peer_parent != nullptr && scope_block->peer_parent->peers.length != 0) { 5361 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; 5362 } 5363 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 5364 IrInstSrc *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, 5365 incoming_blocks.items, incoming_values.items, scope_block->peer_parent); 5366 return ir_expr_wrap(irb, parent_scope, phi, result_loc); 5367 } else { 5368 incoming_blocks.append(irb->current_basic_block); 5369 IrInstSrc *else_expr_result = ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node)); 5370 5371 if (scope_block->peer_parent != nullptr) { 5372 ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent); 5373 scope_block->peer_parent->peers.append(peer_result); 5374 ir_build_end_expr(irb, parent_scope, block_node, else_expr_result, &peer_result->base); 5375 5376 if (scope_block->peer_parent->peers.length != 0) { 5377 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; 5378 } 5379 } 5380 5381 incoming_values.append(else_expr_result); 5382 } 5383 5384 bool is_return_from_fn = block_node == irb->main_block_node; 5385 if (!is_return_from_fn) { 5386 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); 5387 } 5388 5389 IrInstSrc *result; 5390 if (block_node->data.block.name != nullptr) { 5391 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); 5392 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 5393 IrInstSrc *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, 5394 incoming_blocks.items, incoming_values.items, scope_block->peer_parent); 5395 result = ir_expr_wrap(irb, parent_scope, phi, result_loc); 5396 } else { 5397 IrInstSrc *void_inst = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)); 5398 result = ir_lval_wrap(irb, parent_scope, void_inst, lval, result_loc); 5399 } 5400 if (!is_return_from_fn) 5401 return result; 5402 5403 // no need for save_err_ret_addr because this cannot return error 5404 // only generate unconditional defers 5405 5406 ir_mark_gen(ir_build_add_implicit_return_type(irb, child_scope, block_node, result, nullptr)); 5407 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>(); 5408 result_loc_ret->base.id = ResultLocIdReturn; 5409 ir_build_reset_result(irb, parent_scope, block_node, &result_loc_ret->base); 5410 ir_mark_gen(ir_build_end_expr(irb, parent_scope, block_node, result, &result_loc_ret->base)); 5411 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); 5412 return ir_mark_gen(ir_build_return_src(irb, child_scope, result->base.source_node, result)); 5413 } 5414 5415 static IrInstSrc *ir_gen_bin_op_id(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 5416 Scope *inner_scope = scope; 5417 if (op_id == IrBinOpArrayCat || op_id == IrBinOpArrayMult) { 5418 inner_scope = create_comptime_scope(irb->codegen, node, scope); 5419 } 5420 5421 IrInstSrc *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, inner_scope); 5422 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, inner_scope); 5423 5424 if (op1 == irb->codegen->invalid_inst_src || op2 == irb->codegen->invalid_inst_src) 5425 return irb->codegen->invalid_inst_src; 5426 5427 return ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 5428 } 5429 5430 static IrInstSrc *ir_gen_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5431 IrInstSrc *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 5432 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5433 5434 if (op1 == irb->codegen->invalid_inst_src || op2 == irb->codegen->invalid_inst_src) 5435 return irb->codegen->invalid_inst_src; 5436 5437 // TODO only pass type_name when the || operator is the top level AST node in the var decl expr 5438 Buf bare_name = BUF_INIT; 5439 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error", scope, node, &bare_name); 5440 5441 return ir_build_merge_err_sets(irb, scope, node, op1, op2, type_name); 5442 } 5443 5444 static IrInstSrc *ir_gen_assign(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5445 IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); 5446 if (lvalue == irb->codegen->invalid_inst_src) 5447 return irb->codegen->invalid_inst_src; 5448 5449 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>(); 5450 result_loc_inst->base.id = ResultLocIdInstruction; 5451 result_loc_inst->base.source_instruction = lvalue; 5452 ir_ref_instruction(lvalue, irb->current_basic_block); 5453 ir_build_reset_result(irb, scope, node, &result_loc_inst->base); 5454 5455 IrInstSrc *rvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op2, scope, LValNone, 5456 &result_loc_inst->base); 5457 if (rvalue == irb->codegen->invalid_inst_src) 5458 return irb->codegen->invalid_inst_src; 5459 5460 return ir_build_const_void(irb, scope, node); 5461 } 5462 5463 static IrInstSrc *ir_gen_assign_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5464 IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); 5465 if (lvalue == irb->codegen->invalid_inst_src) 5466 return lvalue; 5467 IrInstSrc *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); 5468 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5469 if (op2 == irb->codegen->invalid_inst_src) 5470 return op2; 5471 IrInstSrc *result = ir_build_merge_err_sets(irb, scope, node, op1, op2, nullptr); 5472 ir_build_store_ptr(irb, scope, node, lvalue, result); 5473 return ir_build_const_void(irb, scope, node); 5474 } 5475 5476 static IrInstSrc *ir_gen_assign_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 5477 IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); 5478 if (lvalue == irb->codegen->invalid_inst_src) 5479 return lvalue; 5480 IrInstSrc *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); 5481 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5482 if (op2 == irb->codegen->invalid_inst_src) 5483 return op2; 5484 IrInstSrc *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 5485 ir_build_store_ptr(irb, scope, node, lvalue, result); 5486 return ir_build_const_void(irb, scope, node); 5487 } 5488 5489 static IrInstSrc *ir_gen_bool_or(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5490 assert(node->type == NodeTypeBinOpExpr); 5491 5492 IrInstSrc *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 5493 if (val1 == irb->codegen->invalid_inst_src) 5494 return irb->codegen->invalid_inst_src; 5495 IrBasicBlockSrc *post_val1_block = irb->current_basic_block; 5496 5497 IrInstSrc *is_comptime; 5498 if (ir_should_inline(irb->exec, scope)) { 5499 is_comptime = ir_build_const_bool(irb, scope, node, true); 5500 } else { 5501 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 5502 } 5503 5504 // block for when val1 == false 5505 IrBasicBlockSrc *false_block = ir_create_basic_block(irb, scope, "BoolOrFalse"); 5506 // block for when val1 == true (don't even evaluate the second part) 5507 IrBasicBlockSrc *true_block = ir_create_basic_block(irb, scope, "BoolOrTrue"); 5508 5509 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 5510 5511 ir_set_cursor_at_end_and_append_block(irb, false_block); 5512 IrInstSrc *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5513 if (val2 == irb->codegen->invalid_inst_src) 5514 return irb->codegen->invalid_inst_src; 5515 IrBasicBlockSrc *post_val2_block = irb->current_basic_block; 5516 5517 ir_build_br(irb, scope, node, true_block, is_comptime); 5518 5519 ir_set_cursor_at_end_and_append_block(irb, true_block); 5520 5521 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 5522 incoming_values[0] = val1; 5523 incoming_values[1] = val2; 5524 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 5525 incoming_blocks[0] = post_val1_block; 5526 incoming_blocks[1] = post_val2_block; 5527 5528 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); 5529 } 5530 5531 static IrInstSrc *ir_gen_bool_and(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5532 assert(node->type == NodeTypeBinOpExpr); 5533 5534 IrInstSrc *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 5535 if (val1 == irb->codegen->invalid_inst_src) 5536 return irb->codegen->invalid_inst_src; 5537 IrBasicBlockSrc *post_val1_block = irb->current_basic_block; 5538 5539 IrInstSrc *is_comptime; 5540 if (ir_should_inline(irb->exec, scope)) { 5541 is_comptime = ir_build_const_bool(irb, scope, node, true); 5542 } else { 5543 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 5544 } 5545 5546 // block for when val1 == true 5547 IrBasicBlockSrc *true_block = ir_create_basic_block(irb, scope, "BoolAndTrue"); 5548 // block for when val1 == false (don't even evaluate the second part) 5549 IrBasicBlockSrc *false_block = ir_create_basic_block(irb, scope, "BoolAndFalse"); 5550 5551 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 5552 5553 ir_set_cursor_at_end_and_append_block(irb, true_block); 5554 IrInstSrc *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5555 if (val2 == irb->codegen->invalid_inst_src) 5556 return irb->codegen->invalid_inst_src; 5557 IrBasicBlockSrc *post_val2_block = irb->current_basic_block; 5558 5559 ir_build_br(irb, scope, node, false_block, is_comptime); 5560 5561 ir_set_cursor_at_end_and_append_block(irb, false_block); 5562 5563 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 5564 incoming_values[0] = val1; 5565 incoming_values[1] = val2; 5566 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 5567 incoming_blocks[0] = post_val1_block; 5568 incoming_blocks[1] = post_val2_block; 5569 5570 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); 5571 } 5572 5573 static ResultLocPeerParent *ir_build_result_peers(IrBuilderSrc *irb, IrInstSrc *cond_br_inst, 5574 IrBasicBlockSrc *end_block, ResultLoc *parent, IrInstSrc *is_comptime) 5575 { 5576 ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>(); 5577 peer_parent->base.id = ResultLocIdPeerParent; 5578 peer_parent->base.source_instruction = cond_br_inst; 5579 peer_parent->base.allow_write_through_const = parent->allow_write_through_const; 5580 peer_parent->end_bb = end_block; 5581 peer_parent->is_comptime = is_comptime; 5582 peer_parent->parent = parent; 5583 5584 IrInstSrc *popped_inst = irb->current_basic_block->instruction_list.pop(); 5585 ir_assert(popped_inst == cond_br_inst, &cond_br_inst->base); 5586 5587 ir_build_reset_result(irb, cond_br_inst->base.scope, cond_br_inst->base.source_node, &peer_parent->base); 5588 irb->current_basic_block->instruction_list.append(popped_inst); 5589 5590 return peer_parent; 5591 } 5592 5593 static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilderSrc *irb, IrInstSrc *cond_br_inst, 5594 IrBasicBlockSrc *else_block, IrBasicBlockSrc *end_block, ResultLoc *parent, IrInstSrc *is_comptime) 5595 { 5596 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, parent, is_comptime); 5597 5598 peer_parent->peers.append(create_peer_result(peer_parent)); 5599 peer_parent->peers.last()->next_bb = else_block; 5600 5601 peer_parent->peers.append(create_peer_result(peer_parent)); 5602 peer_parent->peers.last()->next_bb = end_block; 5603 5604 return peer_parent; 5605 } 5606 5607 static IrInstSrc *ir_gen_orelse(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval, 5608 ResultLoc *result_loc) 5609 { 5610 assert(node->type == NodeTypeBinOpExpr); 5611 5612 AstNode *op1_node = node->data.bin_op_expr.op1; 5613 AstNode *op2_node = node->data.bin_op_expr.op2; 5614 5615 IrInstSrc *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); 5616 if (maybe_ptr == irb->codegen->invalid_inst_src) 5617 return irb->codegen->invalid_inst_src; 5618 5619 IrInstSrc *maybe_val = ir_build_load_ptr(irb, parent_scope, node, maybe_ptr); 5620 IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, parent_scope, node, maybe_val); 5621 5622 IrInstSrc *is_comptime; 5623 if (ir_should_inline(irb->exec, parent_scope)) { 5624 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 5625 } else { 5626 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_non_null); 5627 } 5628 5629 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); 5630 IrBasicBlockSrc *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); 5631 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); 5632 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); 5633 5634 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, 5635 result_loc, is_comptime); 5636 5637 ir_set_cursor_at_end_and_append_block(irb, null_block); 5638 IrInstSrc *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, LValNone, 5639 &peer_parent->peers.at(0)->base); 5640 if (null_result == irb->codegen->invalid_inst_src) 5641 return irb->codegen->invalid_inst_src; 5642 IrBasicBlockSrc *after_null_block = irb->current_basic_block; 5643 if (!instr_is_unreachable(null_result)) 5644 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 5645 5646 ir_set_cursor_at_end_and_append_block(irb, ok_block); 5647 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false, false); 5648 IrInstSrc *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 5649 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); 5650 IrBasicBlockSrc *after_ok_block = irb->current_basic_block; 5651 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 5652 5653 ir_set_cursor_at_end_and_append_block(irb, end_block); 5654 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 5655 incoming_values[0] = null_result; 5656 incoming_values[1] = unwrapped_payload; 5657 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 5658 incoming_blocks[0] = after_null_block; 5659 incoming_blocks[1] = after_ok_block; 5660 IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); 5661 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 5662 } 5663 5664 static IrInstSrc *ir_gen_error_union(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 5665 assert(node->type == NodeTypeBinOpExpr); 5666 5667 AstNode *op1_node = node->data.bin_op_expr.op1; 5668 AstNode *op2_node = node->data.bin_op_expr.op2; 5669 5670 IrInstSrc *err_set = ir_gen_node(irb, op1_node, parent_scope); 5671 if (err_set == irb->codegen->invalid_inst_src) 5672 return irb->codegen->invalid_inst_src; 5673 5674 IrInstSrc *payload = ir_gen_node(irb, op2_node, parent_scope); 5675 if (payload == irb->codegen->invalid_inst_src) 5676 return irb->codegen->invalid_inst_src; 5677 5678 return ir_build_error_union(irb, parent_scope, node, err_set, payload); 5679 } 5680 5681 static IrInstSrc *ir_gen_bin_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 5682 assert(node->type == NodeTypeBinOpExpr); 5683 5684 BinOpType bin_op_type = node->data.bin_op_expr.bin_op; 5685 switch (bin_op_type) { 5686 case BinOpTypeInvalid: 5687 zig_unreachable(); 5688 case BinOpTypeAssign: 5689 return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc); 5690 case BinOpTypeAssignTimes: 5691 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMult), lval, result_loc); 5692 case BinOpTypeAssignTimesWrap: 5693 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap), lval, result_loc); 5694 case BinOpTypeAssignDiv: 5695 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); 5696 case BinOpTypeAssignMod: 5697 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); 5698 case BinOpTypeAssignPlus: 5699 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAdd), lval, result_loc); 5700 case BinOpTypeAssignPlusWrap: 5701 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap), lval, result_loc); 5702 case BinOpTypeAssignMinus: 5703 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSub), lval, result_loc); 5704 case BinOpTypeAssignMinusWrap: 5705 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap), lval, result_loc); 5706 case BinOpTypeAssignBitShiftLeft: 5707 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); 5708 case BinOpTypeAssignBitShiftRight: 5709 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); 5710 case BinOpTypeAssignBitAnd: 5711 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd), lval, result_loc); 5712 case BinOpTypeAssignBitXor: 5713 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinXor), lval, result_loc); 5714 case BinOpTypeAssignBitOr: 5715 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinOr), lval, result_loc); 5716 case BinOpTypeAssignMergeErrorSets: 5717 return ir_lval_wrap(irb, scope, ir_gen_assign_merge_err_sets(irb, scope, node), lval, result_loc); 5718 case BinOpTypeBoolOr: 5719 return ir_lval_wrap(irb, scope, ir_gen_bool_or(irb, scope, node), lval, result_loc); 5720 case BinOpTypeBoolAnd: 5721 return ir_lval_wrap(irb, scope, ir_gen_bool_and(irb, scope, node), lval, result_loc); 5722 case BinOpTypeCmpEq: 5723 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq), lval, result_loc); 5724 case BinOpTypeCmpNotEq: 5725 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq), lval, result_loc); 5726 case BinOpTypeCmpLessThan: 5727 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan), lval, result_loc); 5728 case BinOpTypeCmpGreaterThan: 5729 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan), lval, result_loc); 5730 case BinOpTypeCmpLessOrEq: 5731 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq), lval, result_loc); 5732 case BinOpTypeCmpGreaterOrEq: 5733 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc); 5734 case BinOpTypeBinOr: 5735 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr), lval, result_loc); 5736 case BinOpTypeBinXor: 5737 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor), lval, result_loc); 5738 case BinOpTypeBinAnd: 5739 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd), lval, result_loc); 5740 case BinOpTypeBitShiftLeft: 5741 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); 5742 case BinOpTypeBitShiftRight: 5743 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); 5744 case BinOpTypeAdd: 5745 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd), lval, result_loc); 5746 case BinOpTypeAddWrap: 5747 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap), lval, result_loc); 5748 case BinOpTypeSub: 5749 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSub), lval, result_loc); 5750 case BinOpTypeSubWrap: 5751 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap), lval, result_loc); 5752 case BinOpTypeMult: 5753 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMult), lval, result_loc); 5754 case BinOpTypeMultWrap: 5755 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap), lval, result_loc); 5756 case BinOpTypeDiv: 5757 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); 5758 case BinOpTypeMod: 5759 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); 5760 case BinOpTypeArrayCat: 5761 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat), lval, result_loc); 5762 case BinOpTypeArrayMult: 5763 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult), lval, result_loc); 5764 case BinOpTypeMergeErrorSets: 5765 return ir_lval_wrap(irb, scope, ir_gen_merge_err_sets(irb, scope, node), lval, result_loc); 5766 case BinOpTypeUnwrapOptional: 5767 return ir_gen_orelse(irb, scope, node, lval, result_loc); 5768 case BinOpTypeErrorUnion: 5769 return ir_lval_wrap(irb, scope, ir_gen_error_union(irb, scope, node), lval, result_loc); 5770 } 5771 zig_unreachable(); 5772 } 5773 5774 static IrInstSrc *ir_gen_int_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5775 assert(node->type == NodeTypeIntLiteral); 5776 5777 return ir_build_const_bigint(irb, scope, node, node->data.int_literal.bigint); 5778 } 5779 5780 static IrInstSrc *ir_gen_float_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5781 assert(node->type == NodeTypeFloatLiteral); 5782 5783 if (node->data.float_literal.overflow) { 5784 add_node_error(irb->codegen, node, buf_sprintf("float literal out of range of any type")); 5785 return irb->codegen->invalid_inst_src; 5786 } 5787 5788 return ir_build_const_bigfloat(irb, scope, node, node->data.float_literal.bigfloat); 5789 } 5790 5791 static IrInstSrc *ir_gen_char_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5792 assert(node->type == NodeTypeCharLiteral); 5793 5794 return ir_build_const_uint(irb, scope, node, node->data.char_literal.value); 5795 } 5796 5797 static IrInstSrc *ir_gen_null_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5798 assert(node->type == NodeTypeNullLiteral); 5799 5800 return ir_build_const_null(irb, scope, node); 5801 } 5802 5803 static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode *node, Buf *var_name) { 5804 ScopeDecls *scope_decls = nullptr; 5805 while (scope != nullptr) { 5806 if (scope->id == ScopeIdDecls) { 5807 scope_decls = reinterpret_cast<ScopeDecls *>(scope); 5808 } 5809 scope = scope->parent; 5810 } 5811 TldVar *tld_var = heap::c_allocator.create<TldVar>(); 5812 init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); 5813 tld_var->base.resolution = TldResolutionInvalid; 5814 tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, 5815 g->invalid_inst_gen->value, &tld_var->base, g->builtin_types.entry_invalid); 5816 scope_decls->decl_table.put(var_name, &tld_var->base); 5817 } 5818 5819 static IrInstSrc *ir_gen_symbol(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 5820 Error err; 5821 assert(node->type == NodeTypeSymbol); 5822 5823 Buf *variable_name = node->data.symbol_expr.symbol; 5824 5825 if (buf_eql_str(variable_name, "_")) { 5826 if (lval == LValPtr) { 5827 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, node); 5828 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 5829 const_instruction->value->type = get_pointer_to_type(irb->codegen, 5830 irb->codegen->builtin_types.entry_void, false); 5831 const_instruction->value->special = ConstValSpecialStatic; 5832 const_instruction->value->data.x_ptr.special = ConstPtrSpecialDiscard; 5833 return &const_instruction->base; 5834 } else { 5835 add_node_error(irb->codegen, node, buf_sprintf("`_` may only be used to assign things to")); 5836 return irb->codegen->invalid_inst_src; 5837 } 5838 } 5839 5840 ZigType *primitive_type; 5841 if ((err = get_primitive_type(irb->codegen, variable_name, &primitive_type))) { 5842 if (err == ErrorOverflow) { 5843 add_node_error(irb->codegen, node, 5844 buf_sprintf("primitive integer type '%s' exceeds maximum bit width of 65535", 5845 buf_ptr(variable_name))); 5846 return irb->codegen->invalid_inst_src; 5847 } 5848 assert(err == ErrorPrimitiveTypeNotFound); 5849 } else { 5850 IrInstSrc *value = ir_build_const_type(irb, scope, node, primitive_type); 5851 if (lval == LValPtr) { 5852 return ir_build_ref_src(irb, scope, node, value, false, false); 5853 } else { 5854 return ir_expr_wrap(irb, scope, value, result_loc); 5855 } 5856 } 5857 5858 ScopeFnDef *crossed_fndef_scope; 5859 ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope); 5860 if (var) { 5861 IrInstSrc *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); 5862 if (lval == LValPtr) { 5863 return var_ptr; 5864 } else { 5865 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, var_ptr), result_loc); 5866 } 5867 } 5868 5869 Tld *tld = find_decl(irb->codegen, scope, variable_name); 5870 if (tld) { 5871 IrInstSrc *decl_ref = ir_build_decl_ref(irb, scope, node, tld, lval); 5872 if (lval == LValPtr) { 5873 return decl_ref; 5874 } else { 5875 return ir_expr_wrap(irb, scope, decl_ref, result_loc); 5876 } 5877 } 5878 5879 if (get_container_scope(node->owner)->any_imports_failed) { 5880 // skip the error message since we had a failing import in this file 5881 // if an import breaks we don't need redundant undeclared identifier errors 5882 return irb->codegen->invalid_inst_src; 5883 } 5884 5885 return ir_build_undeclared_identifier(irb, scope, node, variable_name); 5886 } 5887 5888 static IrInstSrc *ir_gen_array_access(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 5889 ResultLoc *result_loc) 5890 { 5891 assert(node->type == NodeTypeArrayAccessExpr); 5892 5893 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; 5894 IrInstSrc *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr); 5895 if (array_ref_instruction == irb->codegen->invalid_inst_src) 5896 return array_ref_instruction; 5897 5898 AstNode *subscript_node = node->data.array_access_expr.subscript; 5899 IrInstSrc *subscript_instruction = ir_gen_node(irb, subscript_node, scope); 5900 if (subscript_instruction == irb->codegen->invalid_inst_src) 5901 return subscript_instruction; 5902 5903 IrInstSrc *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, 5904 subscript_instruction, true, PtrLenSingle, nullptr); 5905 if (lval == LValPtr) 5906 return ptr_instruction; 5907 5908 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 5909 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 5910 } 5911 5912 static IrInstSrc *ir_gen_field_access(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5913 assert(node->type == NodeTypeFieldAccessExpr); 5914 5915 AstNode *container_ref_node = node->data.field_access_expr.struct_expr; 5916 Buf *field_name = node->data.field_access_expr.field_name; 5917 5918 IrInstSrc *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr); 5919 if (container_ref_instruction == irb->codegen->invalid_inst_src) 5920 return container_ref_instruction; 5921 5922 return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name, false); 5923 } 5924 5925 static IrInstSrc *ir_gen_overflow_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrOverflowOp op) { 5926 assert(node->type == NodeTypeFnCallExpr); 5927 5928 AstNode *type_node = node->data.fn_call_expr.params.at(0); 5929 AstNode *op1_node = node->data.fn_call_expr.params.at(1); 5930 AstNode *op2_node = node->data.fn_call_expr.params.at(2); 5931 AstNode *result_ptr_node = node->data.fn_call_expr.params.at(3); 5932 5933 5934 IrInstSrc *type_value = ir_gen_node(irb, type_node, scope); 5935 if (type_value == irb->codegen->invalid_inst_src) 5936 return irb->codegen->invalid_inst_src; 5937 5938 IrInstSrc *op1 = ir_gen_node(irb, op1_node, scope); 5939 if (op1 == irb->codegen->invalid_inst_src) 5940 return irb->codegen->invalid_inst_src; 5941 5942 IrInstSrc *op2 = ir_gen_node(irb, op2_node, scope); 5943 if (op2 == irb->codegen->invalid_inst_src) 5944 return irb->codegen->invalid_inst_src; 5945 5946 IrInstSrc *result_ptr = ir_gen_node(irb, result_ptr_node, scope); 5947 if (result_ptr == irb->codegen->invalid_inst_src) 5948 return irb->codegen->invalid_inst_src; 5949 5950 return ir_build_overflow_op_src(irb, scope, node, op, type_value, op1, op2, result_ptr); 5951 } 5952 5953 static IrInstSrc *ir_gen_mul_add(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5954 assert(node->type == NodeTypeFnCallExpr); 5955 5956 AstNode *type_node = node->data.fn_call_expr.params.at(0); 5957 AstNode *op1_node = node->data.fn_call_expr.params.at(1); 5958 AstNode *op2_node = node->data.fn_call_expr.params.at(2); 5959 AstNode *op3_node = node->data.fn_call_expr.params.at(3); 5960 5961 IrInstSrc *type_value = ir_gen_node(irb, type_node, scope); 5962 if (type_value == irb->codegen->invalid_inst_src) 5963 return irb->codegen->invalid_inst_src; 5964 5965 IrInstSrc *op1 = ir_gen_node(irb, op1_node, scope); 5966 if (op1 == irb->codegen->invalid_inst_src) 5967 return irb->codegen->invalid_inst_src; 5968 5969 IrInstSrc *op2 = ir_gen_node(irb, op2_node, scope); 5970 if (op2 == irb->codegen->invalid_inst_src) 5971 return irb->codegen->invalid_inst_src; 5972 5973 IrInstSrc *op3 = ir_gen_node(irb, op3_node, scope); 5974 if (op3 == irb->codegen->invalid_inst_src) 5975 return irb->codegen->invalid_inst_src; 5976 5977 return ir_build_mul_add_src(irb, scope, node, type_value, op1, op2, op3); 5978 } 5979 5980 static IrInstSrc *ir_gen_this(IrBuilderSrc *irb, Scope *orig_scope, AstNode *node) { 5981 for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) { 5982 if (it_scope->id == ScopeIdDecls) { 5983 ScopeDecls *decls_scope = (ScopeDecls *)it_scope; 5984 ZigType *container_type = decls_scope->container_type; 5985 if (container_type != nullptr) { 5986 return ir_build_const_type(irb, orig_scope, node, container_type); 5987 } else { 5988 return ir_build_const_import(irb, orig_scope, node, decls_scope->import); 5989 } 5990 } 5991 } 5992 zig_unreachable(); 5993 } 5994 5995 static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *await_node, AstNode *call_node, 5996 LVal lval, ResultLoc *result_loc) 5997 { 5998 size_t arg_offset = 3; 5999 if (call_node->data.fn_call_expr.params.length < arg_offset) { 6000 add_node_error(irb->codegen, call_node, 6001 buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, 6002 arg_offset, call_node->data.fn_call_expr.params.length)); 6003 return irb->codegen->invalid_inst_src; 6004 } 6005 6006 AstNode *bytes_node = call_node->data.fn_call_expr.params.at(0); 6007 IrInstSrc *bytes = ir_gen_node(irb, bytes_node, scope); 6008 if (bytes == irb->codegen->invalid_inst_src) 6009 return bytes; 6010 6011 AstNode *ret_ptr_node = call_node->data.fn_call_expr.params.at(1); 6012 IrInstSrc *ret_ptr = ir_gen_node(irb, ret_ptr_node, scope); 6013 if (ret_ptr == irb->codegen->invalid_inst_src) 6014 return ret_ptr; 6015 6016 AstNode *fn_ref_node = call_node->data.fn_call_expr.params.at(2); 6017 IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 6018 if (fn_ref == irb->codegen->invalid_inst_src) 6019 return fn_ref; 6020 6021 size_t arg_count = call_node->data.fn_call_expr.params.length - arg_offset; 6022 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count); 6023 for (size_t i = 0; i < arg_count; i += 1) { 6024 AstNode *arg_node = call_node->data.fn_call_expr.params.at(i + arg_offset); 6025 IrInstSrc *arg = ir_gen_node(irb, arg_node, scope); 6026 if (arg == irb->codegen->invalid_inst_src) 6027 return arg; 6028 args[i] = arg; 6029 } 6030 6031 CallModifier modifier = (await_node == nullptr) ? CallModifierAsync : CallModifierNone; 6032 bool is_async_call_builtin = true; 6033 IrInstSrc *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args, 6034 ret_ptr, modifier, is_async_call_builtin, bytes, result_loc); 6035 return ir_lval_wrap(irb, scope, call, lval, result_loc); 6036 } 6037 6038 static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 6039 AstNode *fn_ref_node, CallModifier modifier, IrInstSrc *options, 6040 AstNode **args_ptr, size_t args_len, LVal lval, ResultLoc *result_loc) 6041 { 6042 IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 6043 if (fn_ref == irb->codegen->invalid_inst_src) 6044 return fn_ref; 6045 6046 IrInstSrc *fn_type = ir_build_typeof(irb, scope, source_node, fn_ref); 6047 6048 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len); 6049 for (size_t i = 0; i < args_len; i += 1) { 6050 AstNode *arg_node = args_ptr[i]; 6051 6052 IrInstSrc *arg_index = ir_build_const_usize(irb, scope, arg_node, i); 6053 IrInstSrc *arg_type = ir_build_arg_type(irb, scope, source_node, fn_type, arg_index, true); 6054 ResultLoc *no_result = no_result_loc(); 6055 ir_build_reset_result(irb, scope, source_node, no_result); 6056 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result); 6057 6058 IrInstSrc *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base); 6059 if (arg == irb->codegen->invalid_inst_src) 6060 return arg; 6061 6062 args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast); 6063 } 6064 6065 IrInstSrc *fn_call; 6066 if (options != nullptr) { 6067 fn_call = ir_build_call_args(irb, scope, source_node, options, fn_ref, args, args_len, result_loc); 6068 } else { 6069 fn_call = ir_build_call_src(irb, scope, source_node, nullptr, fn_ref, args_len, args, nullptr, 6070 modifier, false, nullptr, result_loc); 6071 } 6072 return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); 6073 } 6074 6075 static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 6076 ResultLoc *result_loc) 6077 { 6078 assert(node->type == NodeTypeFnCallExpr); 6079 6080 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; 6081 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 6082 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 6083 6084 if (!entry) { 6085 add_node_error(irb->codegen, node, 6086 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name))); 6087 return irb->codegen->invalid_inst_src; 6088 } 6089 6090 BuiltinFnEntry *builtin_fn = entry->value; 6091 size_t actual_param_count = node->data.fn_call_expr.params.length; 6092 6093 if (builtin_fn->param_count != SIZE_MAX && builtin_fn->param_count != actual_param_count) { 6094 add_node_error(irb->codegen, node, 6095 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, 6096 builtin_fn->param_count, actual_param_count)); 6097 return irb->codegen->invalid_inst_src; 6098 } 6099 6100 switch (builtin_fn->id) { 6101 case BuiltinFnIdInvalid: 6102 zig_unreachable(); 6103 case BuiltinFnIdTypeof: 6104 { 6105 Scope *sub_scope = create_typeof_scope(irb->codegen, node, scope); 6106 6107 AstNode *arg_node = node->data.fn_call_expr.params.at(0); 6108 IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope); 6109 if (arg == irb->codegen->invalid_inst_src) 6110 return arg; 6111 6112 IrInstSrc *type_of = ir_build_typeof(irb, scope, node, arg); 6113 return ir_lval_wrap(irb, scope, type_of, lval, result_loc); 6114 } 6115 case BuiltinFnIdSetCold: 6116 { 6117 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6118 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6119 if (arg0_value == irb->codegen->invalid_inst_src) 6120 return arg0_value; 6121 6122 IrInstSrc *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); 6123 return ir_lval_wrap(irb, scope, set_cold, lval, result_loc); 6124 } 6125 case BuiltinFnIdSetRuntimeSafety: 6126 { 6127 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6128 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6129 if (arg0_value == irb->codegen->invalid_inst_src) 6130 return arg0_value; 6131 6132 IrInstSrc *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); 6133 return ir_lval_wrap(irb, scope, set_safety, lval, result_loc); 6134 } 6135 case BuiltinFnIdSetFloatMode: 6136 { 6137 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6138 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6139 if (arg0_value == irb->codegen->invalid_inst_src) 6140 return arg0_value; 6141 6142 IrInstSrc *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value); 6143 return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc); 6144 } 6145 case BuiltinFnIdSizeof: 6146 case BuiltinFnIdBitSizeof: 6147 { 6148 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6149 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6150 if (arg0_value == irb->codegen->invalid_inst_src) 6151 return arg0_value; 6152 6153 IrInstSrc *size_of = ir_build_size_of(irb, scope, node, arg0_value, builtin_fn->id == BuiltinFnIdBitSizeof); 6154 return ir_lval_wrap(irb, scope, size_of, lval, result_loc); 6155 } 6156 case BuiltinFnIdImport: 6157 { 6158 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6159 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6160 if (arg0_value == irb->codegen->invalid_inst_src) 6161 return arg0_value; 6162 6163 IrInstSrc *import = ir_build_import(irb, scope, node, arg0_value); 6164 return ir_lval_wrap(irb, scope, import, lval, result_loc); 6165 } 6166 case BuiltinFnIdCImport: 6167 { 6168 IrInstSrc *c_import = ir_build_c_import(irb, scope, node); 6169 return ir_lval_wrap(irb, scope, c_import, lval, result_loc); 6170 } 6171 case BuiltinFnIdCInclude: 6172 { 6173 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6174 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6175 if (arg0_value == irb->codegen->invalid_inst_src) 6176 return arg0_value; 6177 6178 if (!exec_c_import_buf(irb->exec)) { 6179 add_node_error(irb->codegen, node, buf_sprintf("C include valid only inside C import block")); 6180 return irb->codegen->invalid_inst_src; 6181 } 6182 6183 IrInstSrc *c_include = ir_build_c_include(irb, scope, node, arg0_value); 6184 return ir_lval_wrap(irb, scope, c_include, lval, result_loc); 6185 } 6186 case BuiltinFnIdCDefine: 6187 { 6188 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6189 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6190 if (arg0_value == irb->codegen->invalid_inst_src) 6191 return arg0_value; 6192 6193 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6194 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6195 if (arg1_value == irb->codegen->invalid_inst_src) 6196 return arg1_value; 6197 6198 if (!exec_c_import_buf(irb->exec)) { 6199 add_node_error(irb->codegen, node, buf_sprintf("C define valid only inside C import block")); 6200 return irb->codegen->invalid_inst_src; 6201 } 6202 6203 IrInstSrc *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); 6204 return ir_lval_wrap(irb, scope, c_define, lval, result_loc); 6205 } 6206 case BuiltinFnIdCUndef: 6207 { 6208 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6209 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6210 if (arg0_value == irb->codegen->invalid_inst_src) 6211 return arg0_value; 6212 6213 if (!exec_c_import_buf(irb->exec)) { 6214 add_node_error(irb->codegen, node, buf_sprintf("C undef valid only inside C import block")); 6215 return irb->codegen->invalid_inst_src; 6216 } 6217 6218 IrInstSrc *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); 6219 return ir_lval_wrap(irb, scope, c_undef, lval, result_loc); 6220 } 6221 case BuiltinFnIdCompileErr: 6222 { 6223 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6224 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6225 if (arg0_value == irb->codegen->invalid_inst_src) 6226 return arg0_value; 6227 6228 IrInstSrc *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); 6229 return ir_lval_wrap(irb, scope, compile_err, lval, result_loc); 6230 } 6231 case BuiltinFnIdCompileLog: 6232 { 6233 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(actual_param_count); 6234 6235 for (size_t i = 0; i < actual_param_count; i += 1) { 6236 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 6237 args[i] = ir_gen_node(irb, arg_node, scope); 6238 if (args[i] == irb->codegen->invalid_inst_src) 6239 return irb->codegen->invalid_inst_src; 6240 } 6241 6242 IrInstSrc *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); 6243 return ir_lval_wrap(irb, scope, compile_log, lval, result_loc); 6244 } 6245 case BuiltinFnIdErrName: 6246 { 6247 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6248 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6249 if (arg0_value == irb->codegen->invalid_inst_src) 6250 return arg0_value; 6251 6252 IrInstSrc *err_name = ir_build_err_name(irb, scope, node, arg0_value); 6253 return ir_lval_wrap(irb, scope, err_name, lval, result_loc); 6254 } 6255 case BuiltinFnIdEmbedFile: 6256 { 6257 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6258 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6259 if (arg0_value == irb->codegen->invalid_inst_src) 6260 return arg0_value; 6261 6262 IrInstSrc *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); 6263 return ir_lval_wrap(irb, scope, embed_file, lval, result_loc); 6264 } 6265 case BuiltinFnIdCmpxchgWeak: 6266 case BuiltinFnIdCmpxchgStrong: 6267 { 6268 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6269 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6270 if (arg0_value == irb->codegen->invalid_inst_src) 6271 return arg0_value; 6272 6273 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6274 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6275 if (arg1_value == irb->codegen->invalid_inst_src) 6276 return arg1_value; 6277 6278 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 6279 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 6280 if (arg2_value == irb->codegen->invalid_inst_src) 6281 return arg2_value; 6282 6283 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 6284 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); 6285 if (arg3_value == irb->codegen->invalid_inst_src) 6286 return arg3_value; 6287 6288 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 6289 IrInstSrc *arg4_value = ir_gen_node(irb, arg4_node, scope); 6290 if (arg4_value == irb->codegen->invalid_inst_src) 6291 return arg4_value; 6292 6293 AstNode *arg5_node = node->data.fn_call_expr.params.at(5); 6294 IrInstSrc *arg5_value = ir_gen_node(irb, arg5_node, scope); 6295 if (arg5_value == irb->codegen->invalid_inst_src) 6296 return arg5_value; 6297 6298 IrInstSrc *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value, 6299 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak), 6300 result_loc); 6301 return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc); 6302 } 6303 case BuiltinFnIdFence: 6304 { 6305 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6306 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6307 if (arg0_value == irb->codegen->invalid_inst_src) 6308 return arg0_value; 6309 6310 IrInstSrc *fence = ir_build_fence(irb, scope, node, arg0_value); 6311 return ir_lval_wrap(irb, scope, fence, lval, result_loc); 6312 } 6313 case BuiltinFnIdDivExact: 6314 { 6315 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6316 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6317 if (arg0_value == irb->codegen->invalid_inst_src) 6318 return arg0_value; 6319 6320 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6321 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6322 if (arg1_value == irb->codegen->invalid_inst_src) 6323 return arg1_value; 6324 6325 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); 6326 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6327 } 6328 case BuiltinFnIdDivTrunc: 6329 { 6330 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6331 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6332 if (arg0_value == irb->codegen->invalid_inst_src) 6333 return arg0_value; 6334 6335 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6336 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6337 if (arg1_value == irb->codegen->invalid_inst_src) 6338 return arg1_value; 6339 6340 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); 6341 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6342 } 6343 case BuiltinFnIdDivFloor: 6344 { 6345 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6346 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6347 if (arg0_value == irb->codegen->invalid_inst_src) 6348 return arg0_value; 6349 6350 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6351 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6352 if (arg1_value == irb->codegen->invalid_inst_src) 6353 return arg1_value; 6354 6355 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); 6356 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6357 } 6358 case BuiltinFnIdRem: 6359 { 6360 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6361 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6362 if (arg0_value == irb->codegen->invalid_inst_src) 6363 return arg0_value; 6364 6365 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6366 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6367 if (arg1_value == irb->codegen->invalid_inst_src) 6368 return arg1_value; 6369 6370 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); 6371 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6372 } 6373 case BuiltinFnIdMod: 6374 { 6375 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6376 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6377 if (arg0_value == irb->codegen->invalid_inst_src) 6378 return arg0_value; 6379 6380 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6381 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6382 if (arg1_value == irb->codegen->invalid_inst_src) 6383 return arg1_value; 6384 6385 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); 6386 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6387 } 6388 case BuiltinFnIdSqrt: 6389 case BuiltinFnIdSin: 6390 case BuiltinFnIdCos: 6391 case BuiltinFnIdExp: 6392 case BuiltinFnIdExp2: 6393 case BuiltinFnIdLog: 6394 case BuiltinFnIdLog2: 6395 case BuiltinFnIdLog10: 6396 case BuiltinFnIdFabs: 6397 case BuiltinFnIdFloor: 6398 case BuiltinFnIdCeil: 6399 case BuiltinFnIdTrunc: 6400 case BuiltinFnIdNearbyInt: 6401 case BuiltinFnIdRound: 6402 { 6403 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6404 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6405 if (arg0_value == irb->codegen->invalid_inst_src) 6406 return arg0_value; 6407 6408 IrInstSrc *inst = ir_build_float_op_src(irb, scope, node, arg0_value, builtin_fn->id); 6409 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 6410 } 6411 case BuiltinFnIdTruncate: 6412 { 6413 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6414 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6415 if (arg0_value == irb->codegen->invalid_inst_src) 6416 return arg0_value; 6417 6418 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6419 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6420 if (arg1_value == irb->codegen->invalid_inst_src) 6421 return arg1_value; 6422 6423 IrInstSrc *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); 6424 return ir_lval_wrap(irb, scope, truncate, lval, result_loc); 6425 } 6426 case BuiltinFnIdIntCast: 6427 { 6428 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6429 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6430 if (arg0_value == irb->codegen->invalid_inst_src) 6431 return arg0_value; 6432 6433 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6434 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6435 if (arg1_value == irb->codegen->invalid_inst_src) 6436 return arg1_value; 6437 6438 IrInstSrc *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); 6439 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6440 } 6441 case BuiltinFnIdFloatCast: 6442 { 6443 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6444 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6445 if (arg0_value == irb->codegen->invalid_inst_src) 6446 return arg0_value; 6447 6448 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6449 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6450 if (arg1_value == irb->codegen->invalid_inst_src) 6451 return arg1_value; 6452 6453 IrInstSrc *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); 6454 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6455 } 6456 case BuiltinFnIdErrSetCast: 6457 { 6458 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6459 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6460 if (arg0_value == irb->codegen->invalid_inst_src) 6461 return arg0_value; 6462 6463 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6464 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6465 if (arg1_value == irb->codegen->invalid_inst_src) 6466 return arg1_value; 6467 6468 IrInstSrc *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); 6469 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6470 } 6471 case BuiltinFnIdIntToFloat: 6472 { 6473 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6474 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6475 if (arg0_value == irb->codegen->invalid_inst_src) 6476 return arg0_value; 6477 6478 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6479 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6480 if (arg1_value == irb->codegen->invalid_inst_src) 6481 return arg1_value; 6482 6483 IrInstSrc *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); 6484 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6485 } 6486 case BuiltinFnIdFloatToInt: 6487 { 6488 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6489 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6490 if (arg0_value == irb->codegen->invalid_inst_src) 6491 return arg0_value; 6492 6493 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6494 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6495 if (arg1_value == irb->codegen->invalid_inst_src) 6496 return arg1_value; 6497 6498 IrInstSrc *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); 6499 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6500 } 6501 case BuiltinFnIdErrToInt: 6502 { 6503 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6504 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6505 if (arg0_value == irb->codegen->invalid_inst_src) 6506 return arg0_value; 6507 6508 IrInstSrc *result = ir_build_err_to_int_src(irb, scope, node, arg0_value); 6509 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6510 } 6511 case BuiltinFnIdIntToErr: 6512 { 6513 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6514 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6515 if (arg0_value == irb->codegen->invalid_inst_src) 6516 return arg0_value; 6517 6518 IrInstSrc *result = ir_build_int_to_err_src(irb, scope, node, arg0_value); 6519 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6520 } 6521 case BuiltinFnIdBoolToInt: 6522 { 6523 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6524 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6525 if (arg0_value == irb->codegen->invalid_inst_src) 6526 return arg0_value; 6527 6528 IrInstSrc *result = ir_build_bool_to_int(irb, scope, node, arg0_value); 6529 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6530 } 6531 case BuiltinFnIdVectorType: 6532 { 6533 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6534 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6535 if (arg0_value == irb->codegen->invalid_inst_src) 6536 return arg0_value; 6537 6538 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6539 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6540 if (arg1_value == irb->codegen->invalid_inst_src) 6541 return arg1_value; 6542 6543 IrInstSrc *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value); 6544 return ir_lval_wrap(irb, scope, vector_type, lval, result_loc); 6545 } 6546 case BuiltinFnIdShuffle: 6547 { 6548 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6549 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6550 if (arg0_value == irb->codegen->invalid_inst_src) 6551 return arg0_value; 6552 6553 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6554 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6555 if (arg1_value == irb->codegen->invalid_inst_src) 6556 return arg1_value; 6557 6558 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 6559 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 6560 if (arg2_value == irb->codegen->invalid_inst_src) 6561 return arg2_value; 6562 6563 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 6564 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); 6565 if (arg3_value == irb->codegen->invalid_inst_src) 6566 return arg3_value; 6567 6568 IrInstSrc *shuffle_vector = ir_build_shuffle_vector(irb, scope, node, 6569 arg0_value, arg1_value, arg2_value, arg3_value); 6570 return ir_lval_wrap(irb, scope, shuffle_vector, lval, result_loc); 6571 } 6572 case BuiltinFnIdSplat: 6573 { 6574 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6575 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6576 if (arg0_value == irb->codegen->invalid_inst_src) 6577 return arg0_value; 6578 6579 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6580 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6581 if (arg1_value == irb->codegen->invalid_inst_src) 6582 return arg1_value; 6583 6584 IrInstSrc *splat = ir_build_splat_src(irb, scope, node, 6585 arg0_value, arg1_value); 6586 return ir_lval_wrap(irb, scope, splat, lval, result_loc); 6587 } 6588 case BuiltinFnIdMemcpy: 6589 { 6590 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6591 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6592 if (arg0_value == irb->codegen->invalid_inst_src) 6593 return arg0_value; 6594 6595 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6596 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6597 if (arg1_value == irb->codegen->invalid_inst_src) 6598 return arg1_value; 6599 6600 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 6601 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 6602 if (arg2_value == irb->codegen->invalid_inst_src) 6603 return arg2_value; 6604 6605 IrInstSrc *ir_memcpy = ir_build_memcpy_src(irb, scope, node, arg0_value, arg1_value, arg2_value); 6606 return ir_lval_wrap(irb, scope, ir_memcpy, lval, result_loc); 6607 } 6608 case BuiltinFnIdMemset: 6609 { 6610 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6611 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6612 if (arg0_value == irb->codegen->invalid_inst_src) 6613 return arg0_value; 6614 6615 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6616 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6617 if (arg1_value == irb->codegen->invalid_inst_src) 6618 return arg1_value; 6619 6620 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 6621 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 6622 if (arg2_value == irb->codegen->invalid_inst_src) 6623 return arg2_value; 6624 6625 IrInstSrc *ir_memset = ir_build_memset_src(irb, scope, node, arg0_value, arg1_value, arg2_value); 6626 return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc); 6627 } 6628 case BuiltinFnIdField: 6629 { 6630 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6631 IrInstSrc *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr); 6632 if (arg0_value == irb->codegen->invalid_inst_src) 6633 return arg0_value; 6634 6635 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6636 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6637 if (arg1_value == irb->codegen->invalid_inst_src) 6638 return arg1_value; 6639 6640 IrInstSrc *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, 6641 arg0_value, arg1_value, false); 6642 6643 if (lval == LValPtr) 6644 return ptr_instruction; 6645 6646 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 6647 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 6648 } 6649 case BuiltinFnIdHasField: 6650 { 6651 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6652 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6653 if (arg0_value == irb->codegen->invalid_inst_src) 6654 return arg0_value; 6655 6656 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6657 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6658 if (arg1_value == irb->codegen->invalid_inst_src) 6659 return arg1_value; 6660 6661 IrInstSrc *type_info = ir_build_has_field(irb, scope, node, arg0_value, arg1_value); 6662 return ir_lval_wrap(irb, scope, type_info, lval, result_loc); 6663 } 6664 case BuiltinFnIdTypeInfo: 6665 { 6666 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6667 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6668 if (arg0_value == irb->codegen->invalid_inst_src) 6669 return arg0_value; 6670 6671 IrInstSrc *type_info = ir_build_type_info(irb, scope, node, arg0_value); 6672 return ir_lval_wrap(irb, scope, type_info, lval, result_loc); 6673 } 6674 case BuiltinFnIdType: 6675 { 6676 AstNode *arg_node = node->data.fn_call_expr.params.at(0); 6677 IrInstSrc *arg = ir_gen_node(irb, arg_node, scope); 6678 if (arg == irb->codegen->invalid_inst_src) 6679 return arg; 6680 6681 IrInstSrc *type = ir_build_type(irb, scope, node, arg); 6682 return ir_lval_wrap(irb, scope, type, lval, result_loc); 6683 } 6684 case BuiltinFnIdBreakpoint: 6685 return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval, result_loc); 6686 case BuiltinFnIdReturnAddress: 6687 return ir_lval_wrap(irb, scope, ir_build_return_address_src(irb, scope, node), lval, result_loc); 6688 case BuiltinFnIdFrameAddress: 6689 return ir_lval_wrap(irb, scope, ir_build_frame_address_src(irb, scope, node), lval, result_loc); 6690 case BuiltinFnIdFrameHandle: 6691 if (!irb->exec->fn_entry) { 6692 add_node_error(irb->codegen, node, buf_sprintf("@frame() called outside of function definition")); 6693 return irb->codegen->invalid_inst_src; 6694 } 6695 return ir_lval_wrap(irb, scope, ir_build_handle_src(irb, scope, node), lval, result_loc); 6696 case BuiltinFnIdFrameType: { 6697 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6698 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6699 if (arg0_value == irb->codegen->invalid_inst_src) 6700 return arg0_value; 6701 6702 IrInstSrc *frame_type = ir_build_frame_type(irb, scope, node, arg0_value); 6703 return ir_lval_wrap(irb, scope, frame_type, lval, result_loc); 6704 } 6705 case BuiltinFnIdFrameSize: { 6706 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6707 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6708 if (arg0_value == irb->codegen->invalid_inst_src) 6709 return arg0_value; 6710 6711 IrInstSrc *frame_size = ir_build_frame_size_src(irb, scope, node, arg0_value); 6712 return ir_lval_wrap(irb, scope, frame_size, lval, result_loc); 6713 } 6714 case BuiltinFnIdAlignOf: 6715 { 6716 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6717 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6718 if (arg0_value == irb->codegen->invalid_inst_src) 6719 return arg0_value; 6720 6721 IrInstSrc *align_of = ir_build_align_of(irb, scope, node, arg0_value); 6722 return ir_lval_wrap(irb, scope, align_of, lval, result_loc); 6723 } 6724 case BuiltinFnIdAddWithOverflow: 6725 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval, result_loc); 6726 case BuiltinFnIdSubWithOverflow: 6727 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval, result_loc); 6728 case BuiltinFnIdMulWithOverflow: 6729 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval, result_loc); 6730 case BuiltinFnIdShlWithOverflow: 6731 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval, result_loc); 6732 case BuiltinFnIdMulAdd: 6733 return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval, result_loc); 6734 case BuiltinFnIdTypeName: 6735 { 6736 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6737 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6738 if (arg0_value == irb->codegen->invalid_inst_src) 6739 return arg0_value; 6740 6741 IrInstSrc *type_name = ir_build_type_name(irb, scope, node, arg0_value); 6742 return ir_lval_wrap(irb, scope, type_name, lval, result_loc); 6743 } 6744 case BuiltinFnIdPanic: 6745 { 6746 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6747 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6748 if (arg0_value == irb->codegen->invalid_inst_src) 6749 return arg0_value; 6750 6751 IrInstSrc *panic = ir_build_panic_src(irb, scope, node, arg0_value); 6752 return ir_lval_wrap(irb, scope, panic, lval, result_loc); 6753 } 6754 case BuiltinFnIdPtrCast: 6755 { 6756 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6757 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6758 if (arg0_value == irb->codegen->invalid_inst_src) 6759 return arg0_value; 6760 6761 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6762 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6763 if (arg1_value == irb->codegen->invalid_inst_src) 6764 return arg1_value; 6765 6766 IrInstSrc *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true); 6767 return ir_lval_wrap(irb, scope, ptr_cast, lval, result_loc); 6768 } 6769 case BuiltinFnIdBitCast: 6770 { 6771 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); 6772 IrInstSrc *dest_type = ir_gen_node(irb, dest_type_node, scope); 6773 if (dest_type == irb->codegen->invalid_inst_src) 6774 return dest_type; 6775 6776 ResultLocBitCast *result_loc_bit_cast = heap::c_allocator.create<ResultLocBitCast>(); 6777 result_loc_bit_cast->base.id = ResultLocIdBitCast; 6778 result_loc_bit_cast->base.source_instruction = dest_type; 6779 result_loc_bit_cast->base.allow_write_through_const = result_loc->allow_write_through_const; 6780 ir_ref_instruction(dest_type, irb->current_basic_block); 6781 result_loc_bit_cast->parent = result_loc; 6782 6783 ir_build_reset_result(irb, scope, node, &result_loc_bit_cast->base); 6784 6785 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6786 IrInstSrc *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, 6787 &result_loc_bit_cast->base); 6788 if (arg1_value == irb->codegen->invalid_inst_src) 6789 return arg1_value; 6790 6791 IrInstSrc *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast); 6792 return ir_lval_wrap(irb, scope, bitcast, lval, result_loc); 6793 } 6794 case BuiltinFnIdAs: 6795 { 6796 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); 6797 IrInstSrc *dest_type = ir_gen_node(irb, dest_type_node, scope); 6798 if (dest_type == irb->codegen->invalid_inst_src) 6799 return dest_type; 6800 6801 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, dest_type, result_loc); 6802 6803 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6804 IrInstSrc *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, 6805 &result_loc_cast->base); 6806 if (arg1_value == irb->codegen->invalid_inst_src) 6807 return arg1_value; 6808 6809 IrInstSrc *result = ir_build_implicit_cast(irb, scope, node, arg1_value, result_loc_cast); 6810 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6811 } 6812 case BuiltinFnIdIntToPtr: 6813 { 6814 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6815 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6816 if (arg0_value == irb->codegen->invalid_inst_src) 6817 return arg0_value; 6818 6819 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6820 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6821 if (arg1_value == irb->codegen->invalid_inst_src) 6822 return arg1_value; 6823 6824 IrInstSrc *int_to_ptr = ir_build_int_to_ptr_src(irb, scope, node, arg0_value, arg1_value); 6825 return ir_lval_wrap(irb, scope, int_to_ptr, lval, result_loc); 6826 } 6827 case BuiltinFnIdPtrToInt: 6828 { 6829 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6830 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6831 if (arg0_value == irb->codegen->invalid_inst_src) 6832 return arg0_value; 6833 6834 IrInstSrc *ptr_to_int = ir_build_ptr_to_int_src(irb, scope, node, arg0_value); 6835 return ir_lval_wrap(irb, scope, ptr_to_int, lval, result_loc); 6836 } 6837 case BuiltinFnIdTagName: 6838 { 6839 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6840 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6841 if (arg0_value == irb->codegen->invalid_inst_src) 6842 return arg0_value; 6843 6844 IrInstSrc *tag_name = ir_build_tag_name_src(irb, scope, node, arg0_value); 6845 return ir_lval_wrap(irb, scope, tag_name, lval, result_loc); 6846 } 6847 case BuiltinFnIdTagType: 6848 { 6849 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6850 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6851 if (arg0_value == irb->codegen->invalid_inst_src) 6852 return arg0_value; 6853 6854 IrInstSrc *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); 6855 return ir_lval_wrap(irb, scope, tag_type, lval, result_loc); 6856 } 6857 case BuiltinFnIdFieldParentPtr: 6858 { 6859 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6860 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6861 if (arg0_value == irb->codegen->invalid_inst_src) 6862 return arg0_value; 6863 6864 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6865 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6866 if (arg1_value == irb->codegen->invalid_inst_src) 6867 return arg1_value; 6868 6869 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 6870 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 6871 if (arg2_value == irb->codegen->invalid_inst_src) 6872 return arg2_value; 6873 6874 IrInstSrc *field_parent_ptr = ir_build_field_parent_ptr_src(irb, scope, node, 6875 arg0_value, arg1_value, arg2_value); 6876 return ir_lval_wrap(irb, scope, field_parent_ptr, lval, result_loc); 6877 } 6878 case BuiltinFnIdByteOffsetOf: 6879 { 6880 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6881 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6882 if (arg0_value == irb->codegen->invalid_inst_src) 6883 return arg0_value; 6884 6885 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6886 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6887 if (arg1_value == irb->codegen->invalid_inst_src) 6888 return arg1_value; 6889 6890 IrInstSrc *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value); 6891 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); 6892 } 6893 case BuiltinFnIdBitOffsetOf: 6894 { 6895 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6896 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6897 if (arg0_value == irb->codegen->invalid_inst_src) 6898 return arg0_value; 6899 6900 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6901 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6902 if (arg1_value == irb->codegen->invalid_inst_src) 6903 return arg1_value; 6904 6905 IrInstSrc *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); 6906 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); 6907 } 6908 case BuiltinFnIdCall: { 6909 // Cast the options parameter to the options type 6910 ZigType *options_type = get_builtin_type(irb->codegen, "CallOptions"); 6911 IrInstSrc *options_type_inst = ir_build_const_type(irb, scope, node, options_type); 6912 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, options_type_inst, no_result_loc()); 6913 6914 AstNode *options_node = node->data.fn_call_expr.params.at(0); 6915 IrInstSrc *options_inner = ir_gen_node_extra(irb, options_node, scope, 6916 LValNone, &result_loc_cast->base); 6917 if (options_inner == irb->codegen->invalid_inst_src) 6918 return options_inner; 6919 IrInstSrc *options = ir_build_implicit_cast(irb, scope, options_node, options_inner, result_loc_cast); 6920 6921 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); 6922 AstNode *args_node = node->data.fn_call_expr.params.at(2); 6923 if (args_node->type == NodeTypeContainerInitExpr) { 6924 if (args_node->data.container_init_expr.kind == ContainerInitKindArray || 6925 args_node->data.container_init_expr.entries.length == 0) 6926 { 6927 return ir_gen_fn_call_with_args(irb, scope, node, 6928 fn_ref_node, CallModifierNone, options, 6929 args_node->data.container_init_expr.entries.items, 6930 args_node->data.container_init_expr.entries.length, 6931 lval, result_loc); 6932 } else { 6933 exec_add_error_node(irb->codegen, irb->exec, args_node, 6934 buf_sprintf("TODO: @call with anon struct literal")); 6935 return irb->codegen->invalid_inst_src; 6936 } 6937 } else { 6938 IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 6939 if (fn_ref == irb->codegen->invalid_inst_src) 6940 return fn_ref; 6941 6942 IrInstSrc *args = ir_gen_node(irb, args_node, scope); 6943 if (args == irb->codegen->invalid_inst_src) 6944 return args; 6945 6946 IrInstSrc *call = ir_build_call_extra(irb, scope, node, options, fn_ref, args, result_loc); 6947 return ir_lval_wrap(irb, scope, call, lval, result_loc); 6948 } 6949 } 6950 case BuiltinFnIdAsyncCall: 6951 return ir_gen_async_call(irb, scope, nullptr, node, lval, result_loc); 6952 case BuiltinFnIdShlExact: 6953 { 6954 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6955 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6956 if (arg0_value == irb->codegen->invalid_inst_src) 6957 return arg0_value; 6958 6959 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6960 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6961 if (arg1_value == irb->codegen->invalid_inst_src) 6962 return arg1_value; 6963 6964 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); 6965 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6966 } 6967 case BuiltinFnIdShrExact: 6968 { 6969 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6970 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6971 if (arg0_value == irb->codegen->invalid_inst_src) 6972 return arg0_value; 6973 6974 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6975 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6976 if (arg1_value == irb->codegen->invalid_inst_src) 6977 return arg1_value; 6978 6979 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); 6980 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6981 } 6982 case BuiltinFnIdSetEvalBranchQuota: 6983 { 6984 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6985 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6986 if (arg0_value == irb->codegen->invalid_inst_src) 6987 return arg0_value; 6988 6989 IrInstSrc *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); 6990 return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval, result_loc); 6991 } 6992 case BuiltinFnIdAlignCast: 6993 { 6994 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6995 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6996 if (arg0_value == irb->codegen->invalid_inst_src) 6997 return arg0_value; 6998 6999 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7000 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7001 if (arg1_value == irb->codegen->invalid_inst_src) 7002 return arg1_value; 7003 7004 IrInstSrc *align_cast = ir_build_align_cast_src(irb, scope, node, arg0_value, arg1_value); 7005 return ir_lval_wrap(irb, scope, align_cast, lval, result_loc); 7006 } 7007 case BuiltinFnIdOpaqueType: 7008 { 7009 IrInstSrc *opaque_type = ir_build_opaque_type(irb, scope, node); 7010 return ir_lval_wrap(irb, scope, opaque_type, lval, result_loc); 7011 } 7012 case BuiltinFnIdThis: 7013 { 7014 IrInstSrc *this_inst = ir_gen_this(irb, scope, node); 7015 return ir_lval_wrap(irb, scope, this_inst, lval, result_loc); 7016 } 7017 case BuiltinFnIdSetAlignStack: 7018 { 7019 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7020 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7021 if (arg0_value == irb->codegen->invalid_inst_src) 7022 return arg0_value; 7023 7024 IrInstSrc *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); 7025 return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc); 7026 } 7027 case BuiltinFnIdExport: 7028 { 7029 // Cast the options parameter to the options type 7030 ZigType *options_type = get_builtin_type(irb->codegen, "ExportOptions"); 7031 IrInstSrc *options_type_inst = ir_build_const_type(irb, scope, node, options_type); 7032 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, options_type_inst, no_result_loc()); 7033 7034 AstNode *target_node = node->data.fn_call_expr.params.at(0); 7035 IrInstSrc *target_value = ir_gen_node(irb, target_node, scope); 7036 if (target_value == irb->codegen->invalid_inst_src) 7037 return target_value; 7038 7039 AstNode *options_node = node->data.fn_call_expr.params.at(1); 7040 IrInstSrc *options_value = ir_gen_node_extra(irb, options_node, 7041 scope, LValNone, &result_loc_cast->base); 7042 if (options_value == irb->codegen->invalid_inst_src) 7043 return options_value; 7044 7045 IrInstSrc *casted_options_value = ir_build_implicit_cast( 7046 irb, scope, options_node, options_value, result_loc_cast); 7047 7048 IrInstSrc *ir_export = ir_build_export(irb, scope, node, target_value, casted_options_value); 7049 return ir_lval_wrap(irb, scope, ir_export, lval, result_loc); 7050 } 7051 case BuiltinFnIdErrorReturnTrace: 7052 { 7053 IrInstSrc *error_return_trace = ir_build_error_return_trace_src(irb, scope, node, 7054 IrInstErrorReturnTraceNull); 7055 return ir_lval_wrap(irb, scope, error_return_trace, lval, result_loc); 7056 } 7057 case BuiltinFnIdAtomicRmw: 7058 { 7059 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7060 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7061 if (arg0_value == irb->codegen->invalid_inst_src) 7062 return arg0_value; 7063 7064 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7065 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7066 if (arg1_value == irb->codegen->invalid_inst_src) 7067 return arg1_value; 7068 7069 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 7070 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 7071 if (arg2_value == irb->codegen->invalid_inst_src) 7072 return arg2_value; 7073 7074 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 7075 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); 7076 if (arg3_value == irb->codegen->invalid_inst_src) 7077 return arg3_value; 7078 7079 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 7080 IrInstSrc *arg4_value = ir_gen_node(irb, arg4_node, scope); 7081 if (arg4_value == irb->codegen->invalid_inst_src) 7082 return arg4_value; 7083 7084 IrInstSrc *inst = ir_build_atomic_rmw_src(irb, scope, node, 7085 arg0_value, arg1_value, arg2_value, arg3_value, arg4_value); 7086 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 7087 } 7088 case BuiltinFnIdAtomicLoad: 7089 { 7090 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7091 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7092 if (arg0_value == irb->codegen->invalid_inst_src) 7093 return arg0_value; 7094 7095 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7096 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7097 if (arg1_value == irb->codegen->invalid_inst_src) 7098 return arg1_value; 7099 7100 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 7101 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 7102 if (arg2_value == irb->codegen->invalid_inst_src) 7103 return arg2_value; 7104 7105 IrInstSrc *inst = ir_build_atomic_load_src(irb, scope, node, arg0_value, arg1_value, arg2_value); 7106 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 7107 } 7108 case BuiltinFnIdAtomicStore: 7109 { 7110 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7111 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7112 if (arg0_value == irb->codegen->invalid_inst_src) 7113 return arg0_value; 7114 7115 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7116 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7117 if (arg1_value == irb->codegen->invalid_inst_src) 7118 return arg1_value; 7119 7120 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 7121 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 7122 if (arg2_value == irb->codegen->invalid_inst_src) 7123 return arg2_value; 7124 7125 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 7126 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); 7127 if (arg3_value == irb->codegen->invalid_inst_src) 7128 return arg3_value; 7129 7130 IrInstSrc *inst = ir_build_atomic_store_src(irb, scope, node, arg0_value, arg1_value, 7131 arg2_value, arg3_value); 7132 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 7133 } 7134 case BuiltinFnIdIntToEnum: 7135 { 7136 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7137 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7138 if (arg0_value == irb->codegen->invalid_inst_src) 7139 return arg0_value; 7140 7141 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7142 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7143 if (arg1_value == irb->codegen->invalid_inst_src) 7144 return arg1_value; 7145 7146 IrInstSrc *result = ir_build_int_to_enum_src(irb, scope, node, arg0_value, arg1_value); 7147 return ir_lval_wrap(irb, scope, result, lval, result_loc); 7148 } 7149 case BuiltinFnIdEnumToInt: 7150 { 7151 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7152 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7153 if (arg0_value == irb->codegen->invalid_inst_src) 7154 return arg0_value; 7155 7156 IrInstSrc *result = ir_build_enum_to_int(irb, scope, node, arg0_value); 7157 return ir_lval_wrap(irb, scope, result, lval, result_loc); 7158 } 7159 case BuiltinFnIdCtz: 7160 case BuiltinFnIdPopCount: 7161 case BuiltinFnIdClz: 7162 case BuiltinFnIdBswap: 7163 case BuiltinFnIdBitReverse: 7164 { 7165 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7166 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7167 if (arg0_value == irb->codegen->invalid_inst_src) 7168 return arg0_value; 7169 7170 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7171 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7172 if (arg1_value == irb->codegen->invalid_inst_src) 7173 return arg1_value; 7174 7175 IrInstSrc *result; 7176 switch (builtin_fn->id) { 7177 case BuiltinFnIdCtz: 7178 result = ir_build_ctz(irb, scope, node, arg0_value, arg1_value); 7179 break; 7180 case BuiltinFnIdPopCount: 7181 result = ir_build_pop_count(irb, scope, node, arg0_value, arg1_value); 7182 break; 7183 case BuiltinFnIdClz: 7184 result = ir_build_clz(irb, scope, node, arg0_value, arg1_value); 7185 break; 7186 case BuiltinFnIdBswap: 7187 result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value); 7188 break; 7189 case BuiltinFnIdBitReverse: 7190 result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value); 7191 break; 7192 default: 7193 zig_unreachable(); 7194 } 7195 return ir_lval_wrap(irb, scope, result, lval, result_loc); 7196 } 7197 case BuiltinFnIdHasDecl: 7198 { 7199 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7200 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7201 if (arg0_value == irb->codegen->invalid_inst_src) 7202 return arg0_value; 7203 7204 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7205 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7206 if (arg1_value == irb->codegen->invalid_inst_src) 7207 return arg1_value; 7208 7209 IrInstSrc *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value); 7210 return ir_lval_wrap(irb, scope, has_decl, lval, result_loc); 7211 } 7212 case BuiltinFnIdUnionInit: 7213 { 7214 AstNode *union_type_node = node->data.fn_call_expr.params.at(0); 7215 IrInstSrc *union_type_inst = ir_gen_node(irb, union_type_node, scope); 7216 if (union_type_inst == irb->codegen->invalid_inst_src) 7217 return union_type_inst; 7218 7219 AstNode *name_node = node->data.fn_call_expr.params.at(1); 7220 IrInstSrc *name_inst = ir_gen_node(irb, name_node, scope); 7221 if (name_inst == irb->codegen->invalid_inst_src) 7222 return name_inst; 7223 7224 AstNode *init_node = node->data.fn_call_expr.params.at(2); 7225 7226 return ir_gen_union_init_expr(irb, scope, node, union_type_inst, name_inst, init_node, 7227 lval, result_loc); 7228 } 7229 } 7230 zig_unreachable(); 7231 } 7232 7233 static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 7234 ResultLoc *result_loc) 7235 { 7236 assert(node->type == NodeTypeFnCallExpr); 7237 7238 if (node->data.fn_call_expr.modifier == CallModifierBuiltin) 7239 return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); 7240 7241 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; 7242 return ir_gen_fn_call_with_args(irb, scope, node, fn_ref_node, node->data.fn_call_expr.modifier, 7243 nullptr, node->data.fn_call_expr.params.items, node->data.fn_call_expr.params.length, lval, result_loc); 7244 } 7245 7246 static IrInstSrc *ir_gen_if_bool_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 7247 ResultLoc *result_loc) 7248 { 7249 assert(node->type == NodeTypeIfBoolExpr); 7250 7251 IrInstSrc *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); 7252 if (condition == irb->codegen->invalid_inst_src) 7253 return irb->codegen->invalid_inst_src; 7254 7255 IrInstSrc *is_comptime; 7256 if (ir_should_inline(irb->exec, scope)) { 7257 is_comptime = ir_build_const_bool(irb, scope, node, true); 7258 } else { 7259 is_comptime = ir_build_test_comptime(irb, scope, node, condition); 7260 } 7261 7262 AstNode *then_node = node->data.if_bool_expr.then_block; 7263 AstNode *else_node = node->data.if_bool_expr.else_node; 7264 7265 IrBasicBlockSrc *then_block = ir_create_basic_block(irb, scope, "Then"); 7266 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "Else"); 7267 IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "EndIf"); 7268 7269 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, condition, 7270 then_block, else_block, is_comptime); 7271 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 7272 result_loc, is_comptime); 7273 7274 ir_set_cursor_at_end_and_append_block(irb, then_block); 7275 7276 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 7277 IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval, 7278 &peer_parent->peers.at(0)->base); 7279 if (then_expr_result == irb->codegen->invalid_inst_src) 7280 return irb->codegen->invalid_inst_src; 7281 IrBasicBlockSrc *after_then_block = irb->current_basic_block; 7282 if (!instr_is_unreachable(then_expr_result)) 7283 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 7284 7285 ir_set_cursor_at_end_and_append_block(irb, else_block); 7286 IrInstSrc *else_expr_result; 7287 if (else_node) { 7288 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); 7289 if (else_expr_result == irb->codegen->invalid_inst_src) 7290 return irb->codegen->invalid_inst_src; 7291 } else { 7292 else_expr_result = ir_build_const_void(irb, scope, node); 7293 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 7294 } 7295 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 7296 if (!instr_is_unreachable(else_expr_result)) 7297 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 7298 7299 ir_set_cursor_at_end_and_append_block(irb, endif_block); 7300 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 7301 incoming_values[0] = then_expr_result; 7302 incoming_values[1] = else_expr_result; 7303 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 7304 incoming_blocks[0] = after_then_block; 7305 incoming_blocks[1] = after_else_block; 7306 7307 IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 7308 return ir_expr_wrap(irb, scope, phi, result_loc); 7309 } 7310 7311 static IrInstSrc *ir_gen_prefix_op_id_lval(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { 7312 assert(node->type == NodeTypePrefixOpExpr); 7313 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 7314 7315 IrInstSrc *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); 7316 if (value == irb->codegen->invalid_inst_src) 7317 return value; 7318 7319 return ir_build_un_op(irb, scope, node, op_id, value); 7320 } 7321 7322 static IrInstSrc *ir_gen_prefix_op_id(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrUnOp op_id) { 7323 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone); 7324 } 7325 7326 static IrInstSrc *ir_expr_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *inst, ResultLoc *result_loc) { 7327 if (inst == irb->codegen->invalid_inst_src) return inst; 7328 ir_build_end_expr(irb, scope, inst->base.source_node, inst, result_loc); 7329 return inst; 7330 } 7331 7332 static IrInstSrc *ir_lval_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *value, LVal lval, 7333 ResultLoc *result_loc) 7334 { 7335 // This logic must be kept in sync with 7336 // [STMT_EXPR_TEST_THING] <--- (search this token) 7337 if (value == irb->codegen->invalid_inst_src || 7338 instr_is_unreachable(value) || 7339 value->base.source_node->type == NodeTypeDefer || 7340 value->id == IrInstSrcIdDeclVar) 7341 { 7342 return value; 7343 } 7344 7345 if (lval == LValPtr) { 7346 // We needed a pointer to a value, but we got a value. So we create 7347 // an instruction which just makes a pointer of it. 7348 return ir_build_ref_src(irb, scope, value->base.source_node, value, false, false); 7349 } else if (result_loc != nullptr) { 7350 return ir_expr_wrap(irb, scope, value, result_loc); 7351 } else { 7352 return value; 7353 } 7354 7355 } 7356 7357 static PtrLen star_token_to_ptr_len(TokenId token_id) { 7358 switch (token_id) { 7359 case TokenIdStar: 7360 case TokenIdStarStar: 7361 return PtrLenSingle; 7362 case TokenIdLBracket: 7363 return PtrLenUnknown; 7364 case TokenIdSymbol: 7365 return PtrLenC; 7366 default: 7367 zig_unreachable(); 7368 } 7369 } 7370 7371 static IrInstSrc *ir_gen_pointer_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 7372 assert(node->type == NodeTypePointerType); 7373 7374 PtrLen ptr_len = star_token_to_ptr_len(node->data.pointer_type.star_token->id); 7375 7376 bool is_const = node->data.pointer_type.is_const; 7377 bool is_volatile = node->data.pointer_type.is_volatile; 7378 bool is_allow_zero = node->data.pointer_type.allow_zero_token != nullptr; 7379 AstNode *sentinel_expr = node->data.pointer_type.sentinel; 7380 AstNode *expr_node = node->data.pointer_type.op_expr; 7381 AstNode *align_expr = node->data.pointer_type.align_expr; 7382 7383 IrInstSrc *sentinel; 7384 if (sentinel_expr != nullptr) { 7385 sentinel = ir_gen_node(irb, sentinel_expr, scope); 7386 if (sentinel == irb->codegen->invalid_inst_src) 7387 return sentinel; 7388 } else { 7389 sentinel = nullptr; 7390 } 7391 7392 IrInstSrc *align_value; 7393 if (align_expr != nullptr) { 7394 align_value = ir_gen_node(irb, align_expr, scope); 7395 if (align_value == irb->codegen->invalid_inst_src) 7396 return align_value; 7397 } else { 7398 align_value = nullptr; 7399 } 7400 7401 IrInstSrc *child_type = ir_gen_node(irb, expr_node, scope); 7402 if (child_type == irb->codegen->invalid_inst_src) 7403 return child_type; 7404 7405 uint32_t bit_offset_start = 0; 7406 if (node->data.pointer_type.bit_offset_start != nullptr) { 7407 if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_start, 32, false)) { 7408 Buf *val_buf = buf_alloc(); 7409 bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_start, 10); 7410 exec_add_error_node(irb->codegen, irb->exec, node, 7411 buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf))); 7412 return irb->codegen->invalid_inst_src; 7413 } 7414 bit_offset_start = bigint_as_u32(node->data.pointer_type.bit_offset_start); 7415 } 7416 7417 uint32_t host_int_bytes = 0; 7418 if (node->data.pointer_type.host_int_bytes != nullptr) { 7419 if (!bigint_fits_in_bits(node->data.pointer_type.host_int_bytes, 32, false)) { 7420 Buf *val_buf = buf_alloc(); 7421 bigint_append_buf(val_buf, node->data.pointer_type.host_int_bytes, 10); 7422 exec_add_error_node(irb->codegen, irb->exec, node, 7423 buf_sprintf("value %s too large for u32 byte count", buf_ptr(val_buf))); 7424 return irb->codegen->invalid_inst_src; 7425 } 7426 host_int_bytes = bigint_as_u32(node->data.pointer_type.host_int_bytes); 7427 } 7428 7429 if (host_int_bytes != 0 && bit_offset_start >= host_int_bytes * 8) { 7430 exec_add_error_node(irb->codegen, irb->exec, node, 7431 buf_sprintf("bit offset starts after end of host integer")); 7432 return irb->codegen->invalid_inst_src; 7433 } 7434 7435 return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile, 7436 ptr_len, sentinel, align_value, bit_offset_start, host_int_bytes, is_allow_zero); 7437 } 7438 7439 static IrInstSrc *ir_gen_catch_unreachable(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 7440 AstNode *expr_node, LVal lval, ResultLoc *result_loc) 7441 { 7442 IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 7443 if (err_union_ptr == irb->codegen->invalid_inst_src) 7444 return irb->codegen->invalid_inst_src; 7445 7446 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, scope, source_node, err_union_ptr, true, false); 7447 if (payload_ptr == irb->codegen->invalid_inst_src) 7448 return irb->codegen->invalid_inst_src; 7449 7450 if (lval == LValPtr) 7451 return payload_ptr; 7452 7453 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, source_node, payload_ptr); 7454 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 7455 } 7456 7457 static IrInstSrc *ir_gen_bool_not(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 7458 assert(node->type == NodeTypePrefixOpExpr); 7459 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 7460 7461 IrInstSrc *value = ir_gen_node(irb, expr_node, scope); 7462 if (value == irb->codegen->invalid_inst_src) 7463 return irb->codegen->invalid_inst_src; 7464 7465 return ir_build_bool_not(irb, scope, node, value); 7466 } 7467 7468 static IrInstSrc *ir_gen_prefix_op_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 7469 ResultLoc *result_loc) 7470 { 7471 assert(node->type == NodeTypePrefixOpExpr); 7472 7473 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; 7474 7475 switch (prefix_op) { 7476 case PrefixOpInvalid: 7477 zig_unreachable(); 7478 case PrefixOpBoolNot: 7479 return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval, result_loc); 7480 case PrefixOpBinNot: 7481 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval, result_loc); 7482 case PrefixOpNegation: 7483 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval, result_loc); 7484 case PrefixOpNegationWrap: 7485 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval, result_loc); 7486 case PrefixOpOptional: 7487 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval, result_loc); 7488 case PrefixOpAddrOf: { 7489 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 7490 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr), lval, result_loc); 7491 } 7492 } 7493 zig_unreachable(); 7494 } 7495 7496 static IrInstSrc *ir_gen_union_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 7497 IrInstSrc *union_type, IrInstSrc *field_name, AstNode *expr_node, 7498 LVal lval, ResultLoc *parent_result_loc) 7499 { 7500 IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, source_node, parent_result_loc, union_type); 7501 IrInstSrc *field_ptr = ir_build_field_ptr_instruction(irb, scope, source_node, container_ptr, 7502 field_name, true); 7503 7504 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>(); 7505 result_loc_inst->base.id = ResultLocIdInstruction; 7506 result_loc_inst->base.source_instruction = field_ptr; 7507 ir_ref_instruction(field_ptr, irb->current_basic_block); 7508 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 7509 7510 IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 7511 &result_loc_inst->base); 7512 if (expr_value == irb->codegen->invalid_inst_src) 7513 return expr_value; 7514 7515 IrInstSrc *init_union = ir_build_union_init_named_field(irb, scope, source_node, union_type, 7516 field_name, field_ptr, container_ptr); 7517 7518 return ir_lval_wrap(irb, scope, init_union, lval, parent_result_loc); 7519 } 7520 7521 static IrInstSrc *ir_gen_container_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 7522 ResultLoc *parent_result_loc) 7523 { 7524 assert(node->type == NodeTypeContainerInitExpr); 7525 7526 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; 7527 ContainerInitKind kind = container_init_expr->kind; 7528 7529 ResultLocCast *result_loc_cast = nullptr; 7530 ResultLoc *child_result_loc; 7531 AstNode *init_array_type_source_node; 7532 if (container_init_expr->type != nullptr) { 7533 IrInstSrc *container_type; 7534 if (container_init_expr->type->type == NodeTypeInferredArrayType) { 7535 if (kind == ContainerInitKindStruct) { 7536 add_node_error(irb->codegen, container_init_expr->type, 7537 buf_sprintf("initializing array with struct syntax")); 7538 return irb->codegen->invalid_inst_src; 7539 } 7540 IrInstSrc *sentinel; 7541 if (container_init_expr->type->data.inferred_array_type.sentinel != nullptr) { 7542 sentinel = ir_gen_node(irb, container_init_expr->type->data.inferred_array_type.sentinel, scope); 7543 if (sentinel == irb->codegen->invalid_inst_src) 7544 return sentinel; 7545 } else { 7546 sentinel = nullptr; 7547 } 7548 7549 IrInstSrc *elem_type = ir_gen_node(irb, 7550 container_init_expr->type->data.inferred_array_type.child_type, scope); 7551 if (elem_type == irb->codegen->invalid_inst_src) 7552 return elem_type; 7553 size_t item_count = container_init_expr->entries.length; 7554 IrInstSrc *item_count_inst = ir_build_const_usize(irb, scope, node, item_count); 7555 container_type = ir_build_array_type(irb, scope, node, item_count_inst, sentinel, elem_type); 7556 } else { 7557 container_type = ir_gen_node(irb, container_init_expr->type, scope); 7558 if (container_type == irb->codegen->invalid_inst_src) 7559 return container_type; 7560 } 7561 7562 result_loc_cast = ir_build_cast_result_loc(irb, container_type, parent_result_loc); 7563 child_result_loc = &result_loc_cast->base; 7564 init_array_type_source_node = container_type->base.source_node; 7565 } else { 7566 child_result_loc = parent_result_loc; 7567 if (parent_result_loc->source_instruction != nullptr) { 7568 init_array_type_source_node = parent_result_loc->source_instruction->base.source_node; 7569 } else { 7570 init_array_type_source_node = node; 7571 } 7572 } 7573 7574 switch (kind) { 7575 case ContainerInitKindStruct: { 7576 IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc, 7577 nullptr); 7578 7579 size_t field_count = container_init_expr->entries.length; 7580 IrInstSrcContainerInitFieldsField *fields = heap::c_allocator.allocate<IrInstSrcContainerInitFieldsField>(field_count); 7581 for (size_t i = 0; i < field_count; i += 1) { 7582 AstNode *entry_node = container_init_expr->entries.at(i); 7583 assert(entry_node->type == NodeTypeStructValueField); 7584 7585 Buf *name = entry_node->data.struct_val_field.name; 7586 AstNode *expr_node = entry_node->data.struct_val_field.expr; 7587 7588 IrInstSrc *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true); 7589 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>(); 7590 result_loc_inst->base.id = ResultLocIdInstruction; 7591 result_loc_inst->base.source_instruction = field_ptr; 7592 result_loc_inst->base.allow_write_through_const = true; 7593 ir_ref_instruction(field_ptr, irb->current_basic_block); 7594 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 7595 7596 IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 7597 &result_loc_inst->base); 7598 if (expr_value == irb->codegen->invalid_inst_src) 7599 return expr_value; 7600 7601 fields[i].name = name; 7602 fields[i].source_node = entry_node; 7603 fields[i].result_loc = field_ptr; 7604 } 7605 IrInstSrc *result = ir_build_container_init_fields(irb, scope, node, field_count, 7606 fields, container_ptr); 7607 7608 if (result_loc_cast != nullptr) { 7609 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast); 7610 } 7611 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc); 7612 } 7613 case ContainerInitKindArray: { 7614 size_t item_count = container_init_expr->entries.length; 7615 7616 IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc, 7617 nullptr); 7618 7619 IrInstSrc **result_locs = heap::c_allocator.allocate<IrInstSrc *>(item_count); 7620 for (size_t i = 0; i < item_count; i += 1) { 7621 AstNode *expr_node = container_init_expr->entries.at(i); 7622 7623 IrInstSrc *elem_index = ir_build_const_usize(irb, scope, expr_node, i); 7624 IrInstSrc *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, 7625 elem_index, false, PtrLenSingle, init_array_type_source_node); 7626 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>(); 7627 result_loc_inst->base.id = ResultLocIdInstruction; 7628 result_loc_inst->base.source_instruction = elem_ptr; 7629 result_loc_inst->base.allow_write_through_const = true; 7630 ir_ref_instruction(elem_ptr, irb->current_basic_block); 7631 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 7632 7633 IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 7634 &result_loc_inst->base); 7635 if (expr_value == irb->codegen->invalid_inst_src) 7636 return expr_value; 7637 7638 result_locs[i] = elem_ptr; 7639 } 7640 IrInstSrc *result = ir_build_container_init_list(irb, scope, node, item_count, 7641 result_locs, container_ptr, init_array_type_source_node); 7642 if (result_loc_cast != nullptr) { 7643 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast); 7644 } 7645 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc); 7646 } 7647 } 7648 zig_unreachable(); 7649 } 7650 7651 static ResultLocVar *ir_build_var_result_loc(IrBuilderSrc *irb, IrInstSrc *alloca, ZigVar *var) { 7652 ResultLocVar *result_loc_var = heap::c_allocator.create<ResultLocVar>(); 7653 result_loc_var->base.id = ResultLocIdVar; 7654 result_loc_var->base.source_instruction = alloca; 7655 result_loc_var->base.allow_write_through_const = true; 7656 result_loc_var->var = var; 7657 7658 ir_build_reset_result(irb, alloca->base.scope, alloca->base.source_node, &result_loc_var->base); 7659 7660 return result_loc_var; 7661 } 7662 7663 static ResultLocCast *ir_build_cast_result_loc(IrBuilderSrc *irb, IrInstSrc *dest_type, 7664 ResultLoc *parent_result_loc) 7665 { 7666 ResultLocCast *result_loc_cast = heap::c_allocator.create<ResultLocCast>(); 7667 result_loc_cast->base.id = ResultLocIdCast; 7668 result_loc_cast->base.source_instruction = dest_type; 7669 result_loc_cast->base.allow_write_through_const = parent_result_loc->allow_write_through_const; 7670 ir_ref_instruction(dest_type, irb->current_basic_block); 7671 result_loc_cast->parent = parent_result_loc; 7672 7673 ir_build_reset_result(irb, dest_type->base.scope, dest_type->base.source_node, &result_loc_cast->base); 7674 7675 return result_loc_cast; 7676 } 7677 7678 static void build_decl_var_and_init(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var, 7679 IrInstSrc *init, const char *name_hint, IrInstSrc *is_comptime) 7680 { 7681 IrInstSrc *alloca = ir_build_alloca_src(irb, scope, source_node, nullptr, name_hint, is_comptime); 7682 ResultLocVar *var_result_loc = ir_build_var_result_loc(irb, alloca, var); 7683 ir_build_end_expr(irb, scope, source_node, init, &var_result_loc->base); 7684 ir_build_var_decl_src(irb, scope, source_node, var, nullptr, alloca); 7685 } 7686 7687 static IrInstSrc *ir_gen_var_decl(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 7688 assert(node->type == NodeTypeVariableDeclaration); 7689 7690 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; 7691 7692 if (buf_eql_str(variable_declaration->symbol, "_")) { 7693 add_node_error(irb->codegen, node, buf_sprintf("`_` is not a declarable symbol")); 7694 return irb->codegen->invalid_inst_src; 7695 } 7696 7697 // Used for the type expr and the align expr 7698 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 7699 7700 IrInstSrc *type_instruction; 7701 if (variable_declaration->type != nullptr) { 7702 type_instruction = ir_gen_node(irb, variable_declaration->type, comptime_scope); 7703 if (type_instruction == irb->codegen->invalid_inst_src) 7704 return type_instruction; 7705 } else { 7706 type_instruction = nullptr; 7707 } 7708 7709 bool is_shadowable = false; 7710 bool is_const = variable_declaration->is_const; 7711 bool is_extern = variable_declaration->is_extern; 7712 7713 bool is_comptime_scalar = ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime; 7714 IrInstSrc *is_comptime = ir_build_const_bool(irb, scope, node, is_comptime_scalar); 7715 ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, 7716 is_const, is_const, is_shadowable, is_comptime); 7717 // we detect IrInstSrcDeclVar in gen_block to make sure the next node 7718 // is inside var->child_scope 7719 7720 if (!is_extern && !variable_declaration->expr) { 7721 var->var_type = irb->codegen->builtin_types.entry_invalid; 7722 add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); 7723 return irb->codegen->invalid_inst_src; 7724 } 7725 7726 IrInstSrc *align_value = nullptr; 7727 if (variable_declaration->align_expr != nullptr) { 7728 align_value = ir_gen_node(irb, variable_declaration->align_expr, comptime_scope); 7729 if (align_value == irb->codegen->invalid_inst_src) 7730 return align_value; 7731 } 7732 7733 if (variable_declaration->section_expr != nullptr) { 7734 add_node_error(irb->codegen, variable_declaration->section_expr, 7735 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol))); 7736 } 7737 7738 // Parser should ensure that this never happens 7739 assert(variable_declaration->threadlocal_tok == nullptr); 7740 7741 IrInstSrc *alloca = ir_build_alloca_src(irb, scope, node, align_value, 7742 buf_ptr(variable_declaration->symbol), is_comptime); 7743 7744 // Create a result location for the initialization expression. 7745 ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var); 7746 ResultLoc *init_result_loc; 7747 ResultLocCast *result_loc_cast; 7748 if (type_instruction != nullptr) { 7749 result_loc_cast = ir_build_cast_result_loc(irb, type_instruction, &result_loc_var->base); 7750 init_result_loc = &result_loc_cast->base; 7751 } else { 7752 result_loc_cast = nullptr; 7753 init_result_loc = &result_loc_var->base; 7754 } 7755 7756 Scope *init_scope = is_comptime_scalar ? 7757 create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope; 7758 7759 // Temporarily set the name of the IrExecutableSrc to the VariableDeclaration 7760 // so that the struct or enum from the init expression inherits the name. 7761 Buf *old_exec_name = irb->exec->name; 7762 irb->exec->name = variable_declaration->symbol; 7763 IrInstSrc *init_value = ir_gen_node_extra(irb, variable_declaration->expr, init_scope, 7764 LValNone, init_result_loc); 7765 irb->exec->name = old_exec_name; 7766 7767 if (init_value == irb->codegen->invalid_inst_src) 7768 return irb->codegen->invalid_inst_src; 7769 7770 if (result_loc_cast != nullptr) { 7771 IrInstSrc *implicit_cast = ir_build_implicit_cast(irb, scope, init_value->base.source_node, 7772 init_value, result_loc_cast); 7773 ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base); 7774 } 7775 7776 return ir_build_var_decl_src(irb, scope, node, var, align_value, alloca); 7777 } 7778 7779 static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 7780 ResultLoc *result_loc) 7781 { 7782 assert(node->type == NodeTypeWhileExpr); 7783 7784 AstNode *continue_expr_node = node->data.while_expr.continue_expr; 7785 AstNode *else_node = node->data.while_expr.else_node; 7786 7787 IrBasicBlockSrc *cond_block = ir_create_basic_block(irb, scope, "WhileCond"); 7788 IrBasicBlockSrc *body_block = ir_create_basic_block(irb, scope, "WhileBody"); 7789 IrBasicBlockSrc *continue_block = continue_expr_node ? 7790 ir_create_basic_block(irb, scope, "WhileContinue") : cond_block; 7791 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, scope, "WhileEnd"); 7792 IrBasicBlockSrc *else_block = else_node ? 7793 ir_create_basic_block(irb, scope, "WhileElse") : end_block; 7794 7795 IrInstSrc *is_comptime = ir_build_const_bool(irb, scope, node, 7796 ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline); 7797 ir_build_br(irb, scope, node, cond_block, is_comptime); 7798 7799 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 7800 Buf *var_symbol = node->data.while_expr.var_symbol; 7801 Buf *err_symbol = node->data.while_expr.err_symbol; 7802 if (err_symbol != nullptr) { 7803 ir_set_cursor_at_end_and_append_block(irb, cond_block); 7804 7805 Scope *payload_scope; 7806 AstNode *symbol_node = node; // TODO make more accurate 7807 ZigVar *payload_var; 7808 if (var_symbol) { 7809 // TODO make it an error to write to payload variable 7810 payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 7811 true, false, false, is_comptime); 7812 payload_scope = payload_var->child_scope; 7813 } else { 7814 payload_scope = subexpr_scope; 7815 } 7816 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, payload_scope); 7817 IrInstSrc *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, 7818 LValPtr, nullptr); 7819 if (err_val_ptr == irb->codegen->invalid_inst_src) 7820 return err_val_ptr; 7821 IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr, 7822 true, false); 7823 IrBasicBlockSrc *after_cond_block = irb->current_basic_block; 7824 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 7825 IrInstSrc *cond_br_inst; 7826 if (!instr_is_unreachable(is_err)) { 7827 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, 7828 else_block, body_block, is_comptime); 7829 cond_br_inst->is_gen = true; 7830 } else { 7831 // for the purposes of the source instruction to ir_build_result_peers 7832 cond_br_inst = irb->current_basic_block->instruction_list.last(); 7833 } 7834 7835 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 7836 is_comptime); 7837 7838 ir_set_cursor_at_end_and_append_block(irb, body_block); 7839 if (var_symbol) { 7840 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, &spill_scope->base, symbol_node, 7841 err_val_ptr, false, false); 7842 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ? 7843 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, symbol_node, payload_ptr); 7844 build_decl_var_and_init(irb, payload_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime); 7845 } 7846 7847 ZigList<IrInstSrc *> incoming_values = {0}; 7848 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 7849 7850 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope); 7851 loop_scope->break_block = end_block; 7852 loop_scope->continue_block = continue_block; 7853 loop_scope->is_comptime = is_comptime; 7854 loop_scope->incoming_blocks = &incoming_blocks; 7855 loop_scope->incoming_values = &incoming_values; 7856 loop_scope->lval = lval; 7857 loop_scope->peer_parent = peer_parent; 7858 loop_scope->spill_scope = spill_scope; 7859 7860 // Note the body block of the loop is not the place that lval and result_loc are used - 7861 // it's actually in break statements, handled similarly to return statements. 7862 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 7863 IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 7864 if (body_result == irb->codegen->invalid_inst_src) 7865 return body_result; 7866 7867 if (!instr_is_unreachable(body_result)) { 7868 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result)); 7869 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime)); 7870 } 7871 7872 if (continue_expr_node) { 7873 ir_set_cursor_at_end_and_append_block(irb, continue_block); 7874 IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, payload_scope); 7875 if (expr_result == irb->codegen->invalid_inst_src) 7876 return expr_result; 7877 if (!instr_is_unreachable(expr_result)) { 7878 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, continue_expr_node, expr_result)); 7879 ir_mark_gen(ir_build_br(irb, payload_scope, node, cond_block, is_comptime)); 7880 } 7881 } 7882 7883 ir_set_cursor_at_end_and_append_block(irb, else_block); 7884 assert(else_node != nullptr); 7885 7886 // TODO make it an error to write to error variable 7887 AstNode *err_symbol_node = else_node; // TODO make more accurate 7888 ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol, 7889 true, false, false, is_comptime); 7890 Scope *err_scope = err_var->child_scope; 7891 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, err_symbol_node, err_val_ptr); 7892 IrInstSrc *err_value = ir_build_load_ptr(irb, err_scope, err_symbol_node, err_ptr); 7893 build_decl_var_and_init(irb, err_scope, err_symbol_node, err_var, err_value, buf_ptr(err_symbol), is_comptime); 7894 7895 if (peer_parent->peers.length != 0) { 7896 peer_parent->peers.last()->next_bb = else_block; 7897 } 7898 ResultLocPeer *peer_result = create_peer_result(peer_parent); 7899 peer_parent->peers.append(peer_result); 7900 IrInstSrc *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_result->base); 7901 if (else_result == irb->codegen->invalid_inst_src) 7902 return else_result; 7903 if (!instr_is_unreachable(else_result)) 7904 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 7905 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 7906 ir_set_cursor_at_end_and_append_block(irb, end_block); 7907 if (else_result) { 7908 incoming_blocks.append(after_else_block); 7909 incoming_values.append(else_result); 7910 } else { 7911 incoming_blocks.append(after_cond_block); 7912 incoming_values.append(void_else_result); 7913 } 7914 if (peer_parent->peers.length != 0) { 7915 peer_parent->peers.last()->next_bb = end_block; 7916 } 7917 7918 IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 7919 incoming_blocks.items, incoming_values.items, peer_parent); 7920 return ir_expr_wrap(irb, scope, phi, result_loc); 7921 } else if (var_symbol != nullptr) { 7922 ir_set_cursor_at_end_and_append_block(irb, cond_block); 7923 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 7924 // TODO make it an error to write to payload variable 7925 AstNode *symbol_node = node; // TODO make more accurate 7926 7927 ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 7928 true, false, false, is_comptime); 7929 Scope *child_scope = payload_var->child_scope; 7930 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, child_scope); 7931 IrInstSrc *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, 7932 LValPtr, nullptr); 7933 if (maybe_val_ptr == irb->codegen->invalid_inst_src) 7934 return maybe_val_ptr; 7935 IrInstSrc *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); 7936 IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, scope, node->data.while_expr.condition, maybe_val); 7937 IrBasicBlockSrc *after_cond_block = irb->current_basic_block; 7938 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 7939 IrInstSrc *cond_br_inst; 7940 if (!instr_is_unreachable(is_non_null)) { 7941 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, 7942 body_block, else_block, is_comptime); 7943 cond_br_inst->is_gen = true; 7944 } else { 7945 // for the purposes of the source instruction to ir_build_result_peers 7946 cond_br_inst = irb->current_basic_block->instruction_list.last(); 7947 } 7948 7949 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 7950 is_comptime); 7951 7952 ir_set_cursor_at_end_and_append_block(irb, body_block); 7953 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, &spill_scope->base, symbol_node, maybe_val_ptr, false, false); 7954 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ? 7955 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, symbol_node, payload_ptr); 7956 build_decl_var_and_init(irb, child_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime); 7957 7958 ZigList<IrInstSrc *> incoming_values = {0}; 7959 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 7960 7961 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 7962 loop_scope->break_block = end_block; 7963 loop_scope->continue_block = continue_block; 7964 loop_scope->is_comptime = is_comptime; 7965 loop_scope->incoming_blocks = &incoming_blocks; 7966 loop_scope->incoming_values = &incoming_values; 7967 loop_scope->lval = lval; 7968 loop_scope->peer_parent = peer_parent; 7969 loop_scope->spill_scope = spill_scope; 7970 7971 // Note the body block of the loop is not the place that lval and result_loc are used - 7972 // it's actually in break statements, handled similarly to return statements. 7973 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 7974 IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 7975 if (body_result == irb->codegen->invalid_inst_src) 7976 return body_result; 7977 7978 if (!instr_is_unreachable(body_result)) { 7979 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result)); 7980 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 7981 } 7982 7983 if (continue_expr_node) { 7984 ir_set_cursor_at_end_and_append_block(irb, continue_block); 7985 IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, child_scope); 7986 if (expr_result == irb->codegen->invalid_inst_src) 7987 return expr_result; 7988 if (!instr_is_unreachable(expr_result)) { 7989 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, continue_expr_node, expr_result)); 7990 ir_mark_gen(ir_build_br(irb, child_scope, node, cond_block, is_comptime)); 7991 } 7992 } 7993 7994 IrInstSrc *else_result = nullptr; 7995 if (else_node) { 7996 ir_set_cursor_at_end_and_append_block(irb, else_block); 7997 7998 if (peer_parent->peers.length != 0) { 7999 peer_parent->peers.last()->next_bb = else_block; 8000 } 8001 ResultLocPeer *peer_result = create_peer_result(peer_parent); 8002 peer_parent->peers.append(peer_result); 8003 else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_result->base); 8004 if (else_result == irb->codegen->invalid_inst_src) 8005 return else_result; 8006 if (!instr_is_unreachable(else_result)) 8007 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 8008 } 8009 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8010 ir_set_cursor_at_end_and_append_block(irb, end_block); 8011 if (else_result) { 8012 incoming_blocks.append(after_else_block); 8013 incoming_values.append(else_result); 8014 } else { 8015 incoming_blocks.append(after_cond_block); 8016 incoming_values.append(void_else_result); 8017 } 8018 if (peer_parent->peers.length != 0) { 8019 peer_parent->peers.last()->next_bb = end_block; 8020 } 8021 8022 IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 8023 incoming_blocks.items, incoming_values.items, peer_parent); 8024 return ir_expr_wrap(irb, scope, phi, result_loc); 8025 } else { 8026 ir_set_cursor_at_end_and_append_block(irb, cond_block); 8027 IrInstSrc *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); 8028 if (cond_val == irb->codegen->invalid_inst_src) 8029 return cond_val; 8030 IrBasicBlockSrc *after_cond_block = irb->current_basic_block; 8031 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 8032 IrInstSrc *cond_br_inst; 8033 if (!instr_is_unreachable(cond_val)) { 8034 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, 8035 body_block, else_block, is_comptime); 8036 cond_br_inst->is_gen = true; 8037 } else { 8038 // for the purposes of the source instruction to ir_build_result_peers 8039 cond_br_inst = irb->current_basic_block->instruction_list.last(); 8040 } 8041 8042 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 8043 is_comptime); 8044 ir_set_cursor_at_end_and_append_block(irb, body_block); 8045 8046 ZigList<IrInstSrc *> incoming_values = {0}; 8047 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 8048 8049 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 8050 8051 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope); 8052 loop_scope->break_block = end_block; 8053 loop_scope->continue_block = continue_block; 8054 loop_scope->is_comptime = is_comptime; 8055 loop_scope->incoming_blocks = &incoming_blocks; 8056 loop_scope->incoming_values = &incoming_values; 8057 loop_scope->lval = lval; 8058 loop_scope->peer_parent = peer_parent; 8059 8060 // Note the body block of the loop is not the place that lval and result_loc are used - 8061 // it's actually in break statements, handled similarly to return statements. 8062 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 8063 IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 8064 if (body_result == irb->codegen->invalid_inst_src) 8065 return body_result; 8066 8067 if (!instr_is_unreachable(body_result)) { 8068 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result)); 8069 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime)); 8070 } 8071 8072 if (continue_expr_node) { 8073 ir_set_cursor_at_end_and_append_block(irb, continue_block); 8074 IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, subexpr_scope); 8075 if (expr_result == irb->codegen->invalid_inst_src) 8076 return expr_result; 8077 if (!instr_is_unreachable(expr_result)) { 8078 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, continue_expr_node, expr_result)); 8079 ir_mark_gen(ir_build_br(irb, scope, node, cond_block, is_comptime)); 8080 } 8081 } 8082 8083 IrInstSrc *else_result = nullptr; 8084 if (else_node) { 8085 ir_set_cursor_at_end_and_append_block(irb, else_block); 8086 8087 if (peer_parent->peers.length != 0) { 8088 peer_parent->peers.last()->next_bb = else_block; 8089 } 8090 ResultLocPeer *peer_result = create_peer_result(peer_parent); 8091 peer_parent->peers.append(peer_result); 8092 8093 else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_result->base); 8094 if (else_result == irb->codegen->invalid_inst_src) 8095 return else_result; 8096 if (!instr_is_unreachable(else_result)) 8097 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 8098 } 8099 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8100 ir_set_cursor_at_end_and_append_block(irb, end_block); 8101 if (else_result) { 8102 incoming_blocks.append(after_else_block); 8103 incoming_values.append(else_result); 8104 } else { 8105 incoming_blocks.append(after_cond_block); 8106 incoming_values.append(void_else_result); 8107 } 8108 if (peer_parent->peers.length != 0) { 8109 peer_parent->peers.last()->next_bb = end_block; 8110 } 8111 8112 IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 8113 incoming_blocks.items, incoming_values.items, peer_parent); 8114 return ir_expr_wrap(irb, scope, phi, result_loc); 8115 } 8116 } 8117 8118 static IrInstSrc *ir_gen_for_expr(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval, 8119 ResultLoc *result_loc) 8120 { 8121 assert(node->type == NodeTypeForExpr); 8122 8123 AstNode *array_node = node->data.for_expr.array_expr; 8124 AstNode *elem_node = node->data.for_expr.elem_node; 8125 AstNode *index_node = node->data.for_expr.index_node; 8126 AstNode *body_node = node->data.for_expr.body; 8127 AstNode *else_node = node->data.for_expr.else_node; 8128 8129 if (!elem_node) { 8130 add_node_error(irb->codegen, node, buf_sprintf("for loop expression missing element parameter")); 8131 return irb->codegen->invalid_inst_src; 8132 } 8133 assert(elem_node->type == NodeTypeSymbol); 8134 8135 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, parent_scope); 8136 8137 IrInstSrc *array_val_ptr = ir_gen_node_extra(irb, array_node, &spill_scope->base, LValPtr, nullptr); 8138 if (array_val_ptr == irb->codegen->invalid_inst_src) 8139 return array_val_ptr; 8140 8141 IrInstSrc *is_comptime = ir_build_const_bool(irb, parent_scope, node, 8142 ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); 8143 8144 AstNode *index_var_source_node; 8145 ZigVar *index_var; 8146 const char *index_var_name; 8147 if (index_node) { 8148 index_var_source_node = index_node; 8149 Buf *index_var_name_buf = index_node->data.symbol_expr.symbol; 8150 index_var = ir_create_var(irb, index_node, parent_scope, index_var_name_buf, true, false, false, is_comptime); 8151 index_var_name = buf_ptr(index_var_name_buf); 8152 } else { 8153 index_var_source_node = node; 8154 index_var = ir_create_var(irb, node, parent_scope, nullptr, true, false, true, is_comptime); 8155 index_var_name = "i"; 8156 } 8157 8158 IrInstSrc *zero = ir_build_const_usize(irb, parent_scope, node, 0); 8159 build_decl_var_and_init(irb, parent_scope, index_var_source_node, index_var, zero, index_var_name, is_comptime); 8160 parent_scope = index_var->child_scope; 8161 8162 IrInstSrc *one = ir_build_const_usize(irb, parent_scope, node, 1); 8163 IrInstSrc *index_ptr = ir_build_var_ptr(irb, parent_scope, node, index_var); 8164 8165 8166 IrBasicBlockSrc *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond"); 8167 IrBasicBlockSrc *body_block = ir_create_basic_block(irb, parent_scope, "ForBody"); 8168 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd"); 8169 IrBasicBlockSrc *else_block = else_node ? ir_create_basic_block(irb, parent_scope, "ForElse") : end_block; 8170 IrBasicBlockSrc *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue"); 8171 8172 Buf *len_field_name = buf_create_from_str("len"); 8173 IrInstSrc *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name, false); 8174 IrInstSrc *len_val = ir_build_load_ptr(irb, &spill_scope->base, node, len_ref); 8175 ir_build_br(irb, parent_scope, node, cond_block, is_comptime); 8176 8177 ir_set_cursor_at_end_and_append_block(irb, cond_block); 8178 IrInstSrc *index_val = ir_build_load_ptr(irb, &spill_scope->base, node, index_ptr); 8179 IrInstSrc *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); 8180 IrBasicBlockSrc *after_cond_block = irb->current_basic_block; 8181 IrInstSrc *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); 8182 IrInstSrc *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, 8183 body_block, else_block, is_comptime)); 8184 8185 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, is_comptime); 8186 8187 ir_set_cursor_at_end_and_append_block(irb, body_block); 8188 IrInstSrc *elem_ptr = ir_build_elem_ptr(irb, &spill_scope->base, node, array_val_ptr, index_val, 8189 false, PtrLenSingle, nullptr); 8190 // TODO make it an error to write to element variable or i variable. 8191 Buf *elem_var_name = elem_node->data.symbol_expr.symbol; 8192 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); 8193 Scope *child_scope = elem_var->child_scope; 8194 8195 IrInstSrc *elem_value = node->data.for_expr.elem_is_ptr ? 8196 elem_ptr : ir_build_load_ptr(irb, &spill_scope->base, elem_node, elem_ptr); 8197 build_decl_var_and_init(irb, parent_scope, elem_node, elem_var, elem_value, buf_ptr(elem_var_name), is_comptime); 8198 8199 ZigList<IrInstSrc *> incoming_values = {0}; 8200 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 8201 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 8202 loop_scope->break_block = end_block; 8203 loop_scope->continue_block = continue_block; 8204 loop_scope->is_comptime = is_comptime; 8205 loop_scope->incoming_blocks = &incoming_blocks; 8206 loop_scope->incoming_values = &incoming_values; 8207 loop_scope->lval = LValNone; 8208 loop_scope->peer_parent = peer_parent; 8209 loop_scope->spill_scope = spill_scope; 8210 8211 // Note the body block of the loop is not the place that lval and result_loc are used - 8212 // it's actually in break statements, handled similarly to return statements. 8213 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 8214 IrInstSrc *body_result = ir_gen_node(irb, body_node, &loop_scope->base); 8215 if (body_result == irb->codegen->invalid_inst_src) 8216 return irb->codegen->invalid_inst_src; 8217 8218 if (!instr_is_unreachable(body_result)) { 8219 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result)); 8220 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 8221 } 8222 8223 ir_set_cursor_at_end_and_append_block(irb, continue_block); 8224 IrInstSrc *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false); 8225 ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)->allow_write_through_const = true; 8226 ir_build_br(irb, child_scope, node, cond_block, is_comptime); 8227 8228 IrInstSrc *else_result = nullptr; 8229 if (else_node) { 8230 ir_set_cursor_at_end_and_append_block(irb, else_block); 8231 8232 if (peer_parent->peers.length != 0) { 8233 peer_parent->peers.last()->next_bb = else_block; 8234 } 8235 ResultLocPeer *peer_result = create_peer_result(peer_parent); 8236 peer_parent->peers.append(peer_result); 8237 else_result = ir_gen_node_extra(irb, else_node, parent_scope, LValNone, &peer_result->base); 8238 if (else_result == irb->codegen->invalid_inst_src) 8239 return else_result; 8240 if (!instr_is_unreachable(else_result)) 8241 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 8242 } 8243 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8244 ir_set_cursor_at_end_and_append_block(irb, end_block); 8245 8246 if (else_result) { 8247 incoming_blocks.append(after_else_block); 8248 incoming_values.append(else_result); 8249 } else { 8250 incoming_blocks.append(after_cond_block); 8251 incoming_values.append(void_else_value); 8252 } 8253 if (peer_parent->peers.length != 0) { 8254 peer_parent->peers.last()->next_bb = end_block; 8255 } 8256 8257 IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, 8258 incoming_blocks.items, incoming_values.items, peer_parent); 8259 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 8260 } 8261 8262 static IrInstSrc *ir_gen_bool_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8263 assert(node->type == NodeTypeBoolLiteral); 8264 return ir_build_const_bool(irb, scope, node, node->data.bool_literal.value); 8265 } 8266 8267 static IrInstSrc *ir_gen_enum_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8268 assert(node->type == NodeTypeEnumLiteral); 8269 Buf *name = &node->data.enum_literal.identifier->data.str_lit.str; 8270 return ir_build_const_enum_literal(irb, scope, node, name); 8271 } 8272 8273 static IrInstSrc *ir_gen_string_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8274 assert(node->type == NodeTypeStringLiteral); 8275 8276 return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf); 8277 } 8278 8279 static IrInstSrc *ir_gen_array_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8280 assert(node->type == NodeTypeArrayType); 8281 8282 AstNode *size_node = node->data.array_type.size; 8283 AstNode *child_type_node = node->data.array_type.child_type; 8284 bool is_const = node->data.array_type.is_const; 8285 bool is_volatile = node->data.array_type.is_volatile; 8286 bool is_allow_zero = node->data.array_type.allow_zero_token != nullptr; 8287 AstNode *sentinel_expr = node->data.array_type.sentinel; 8288 AstNode *align_expr = node->data.array_type.align_expr; 8289 8290 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 8291 8292 IrInstSrc *sentinel; 8293 if (sentinel_expr != nullptr) { 8294 sentinel = ir_gen_node(irb, sentinel_expr, comptime_scope); 8295 if (sentinel == irb->codegen->invalid_inst_src) 8296 return sentinel; 8297 } else { 8298 sentinel = nullptr; 8299 } 8300 8301 if (size_node) { 8302 if (is_const) { 8303 add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type")); 8304 return irb->codegen->invalid_inst_src; 8305 } 8306 if (is_volatile) { 8307 add_node_error(irb->codegen, node, buf_create_from_str("volatile qualifier invalid on array type")); 8308 return irb->codegen->invalid_inst_src; 8309 } 8310 if (is_allow_zero) { 8311 add_node_error(irb->codegen, node, buf_create_from_str("allowzero qualifier invalid on array type")); 8312 return irb->codegen->invalid_inst_src; 8313 } 8314 if (align_expr != nullptr) { 8315 add_node_error(irb->codegen, node, buf_create_from_str("align qualifier invalid on array type")); 8316 return irb->codegen->invalid_inst_src; 8317 } 8318 8319 IrInstSrc *size_value = ir_gen_node(irb, size_node, comptime_scope); 8320 if (size_value == irb->codegen->invalid_inst_src) 8321 return size_value; 8322 8323 IrInstSrc *child_type = ir_gen_node(irb, child_type_node, comptime_scope); 8324 if (child_type == irb->codegen->invalid_inst_src) 8325 return child_type; 8326 8327 return ir_build_array_type(irb, scope, node, size_value, sentinel, child_type); 8328 } else { 8329 IrInstSrc *align_value; 8330 if (align_expr != nullptr) { 8331 align_value = ir_gen_node(irb, align_expr, comptime_scope); 8332 if (align_value == irb->codegen->invalid_inst_src) 8333 return align_value; 8334 } else { 8335 align_value = nullptr; 8336 } 8337 8338 IrInstSrc *child_type = ir_gen_node(irb, child_type_node, comptime_scope); 8339 if (child_type == irb->codegen->invalid_inst_src) 8340 return child_type; 8341 8342 return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, sentinel, 8343 align_value, is_allow_zero); 8344 } 8345 } 8346 8347 static IrInstSrc *ir_gen_anyframe_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8348 assert(node->type == NodeTypeAnyFrameType); 8349 8350 AstNode *payload_type_node = node->data.anyframe_type.payload_type; 8351 IrInstSrc *payload_type_value = nullptr; 8352 8353 if (payload_type_node != nullptr) { 8354 payload_type_value = ir_gen_node(irb, payload_type_node, scope); 8355 if (payload_type_value == irb->codegen->invalid_inst_src) 8356 return payload_type_value; 8357 8358 } 8359 8360 return ir_build_anyframe_type(irb, scope, node, payload_type_value); 8361 } 8362 8363 static IrInstSrc *ir_gen_undefined_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8364 assert(node->type == NodeTypeUndefinedLiteral); 8365 return ir_build_const_undefined(irb, scope, node); 8366 } 8367 8368 static Error parse_asm_template(IrAnalyze *ira, AstNode *source_node, Buf *asm_template, 8369 ZigList<AsmToken> *tok_list) 8370 { 8371 // TODO Connect the errors in this function back up to the actual source location 8372 // rather than just the token. https://github.com/ziglang/zig/issues/2080 8373 enum State { 8374 StateStart, 8375 StatePercent, 8376 StateTemplate, 8377 StateVar, 8378 }; 8379 8380 assert(tok_list->length == 0); 8381 8382 AsmToken *cur_tok = nullptr; 8383 8384 enum State state = StateStart; 8385 8386 for (size_t i = 0; i < buf_len(asm_template); i += 1) { 8387 uint8_t c = *((uint8_t*)buf_ptr(asm_template) + i); 8388 switch (state) { 8389 case StateStart: 8390 if (c == '%') { 8391 tok_list->add_one(); 8392 cur_tok = &tok_list->last(); 8393 cur_tok->id = AsmTokenIdPercent; 8394 cur_tok->start = i; 8395 state = StatePercent; 8396 } else { 8397 tok_list->add_one(); 8398 cur_tok = &tok_list->last(); 8399 cur_tok->id = AsmTokenIdTemplate; 8400 cur_tok->start = i; 8401 state = StateTemplate; 8402 } 8403 break; 8404 case StatePercent: 8405 if (c == '%') { 8406 cur_tok->end = i; 8407 state = StateStart; 8408 } else if (c == '[') { 8409 cur_tok->id = AsmTokenIdVar; 8410 state = StateVar; 8411 } else if (c == '=') { 8412 cur_tok->id = AsmTokenIdUniqueId; 8413 cur_tok->end = i; 8414 state = StateStart; 8415 } else { 8416 add_node_error(ira->codegen, source_node, 8417 buf_create_from_str("expected a '%' or '['")); 8418 return ErrorSemanticAnalyzeFail; 8419 } 8420 break; 8421 case StateTemplate: 8422 if (c == '%') { 8423 cur_tok->end = i; 8424 i -= 1; 8425 cur_tok = nullptr; 8426 state = StateStart; 8427 } 8428 break; 8429 case StateVar: 8430 if (c == ']') { 8431 cur_tok->end = i; 8432 state = StateStart; 8433 } else if ((c >= 'a' && c <= 'z') || 8434 (c >= '0' && c <= '9') || 8435 (c == '_')) 8436 { 8437 // do nothing 8438 } else { 8439 add_node_error(ira->codegen, source_node, 8440 buf_sprintf("invalid substitution character: '%c'", c)); 8441 return ErrorSemanticAnalyzeFail; 8442 } 8443 break; 8444 } 8445 } 8446 8447 switch (state) { 8448 case StateStart: 8449 break; 8450 case StatePercent: 8451 case StateVar: 8452 add_node_error(ira->codegen, source_node, buf_sprintf("unexpected end of assembly template")); 8453 return ErrorSemanticAnalyzeFail; 8454 case StateTemplate: 8455 cur_tok->end = buf_len(asm_template); 8456 break; 8457 } 8458 return ErrorNone; 8459 } 8460 8461 static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_template) { 8462 const char *ptr = buf_ptr(src_template) + tok->start + 2; 8463 size_t len = tok->end - tok->start - 2; 8464 size_t result = 0; 8465 for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1, result += 1) { 8466 AsmOutput *asm_output = node->data.asm_expr.output_list.at(i); 8467 if (buf_eql_mem(asm_output->asm_symbolic_name, ptr, len)) { 8468 return result; 8469 } 8470 } 8471 for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1, result += 1) { 8472 AsmInput *asm_input = node->data.asm_expr.input_list.at(i); 8473 if (buf_eql_mem(asm_input->asm_symbolic_name, ptr, len)) { 8474 return result; 8475 } 8476 } 8477 return SIZE_MAX; 8478 } 8479 8480 static IrInstSrc *ir_gen_asm_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8481 assert(node->type == NodeTypeAsmExpr); 8482 AstNodeAsmExpr *asm_expr = &node->data.asm_expr; 8483 8484 IrInstSrc *asm_template = ir_gen_node(irb, asm_expr->asm_template, scope); 8485 if (asm_template == irb->codegen->invalid_inst_src) 8486 return irb->codegen->invalid_inst_src; 8487 8488 bool is_volatile = asm_expr->volatile_token != nullptr; 8489 bool in_fn_scope = (scope_fn_entry(scope) != nullptr); 8490 8491 if (!in_fn_scope) { 8492 if (is_volatile) { 8493 add_token_error(irb->codegen, node->owner, asm_expr->volatile_token, 8494 buf_sprintf("volatile is meaningless on global assembly")); 8495 return irb->codegen->invalid_inst_src; 8496 } 8497 8498 if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 || 8499 asm_expr->clobber_list.length != 0) 8500 { 8501 add_node_error(irb->codegen, node, 8502 buf_sprintf("global assembly cannot have inputs, outputs, or clobbers")); 8503 return irb->codegen->invalid_inst_src; 8504 } 8505 8506 return ir_build_asm_src(irb, scope, node, asm_template, nullptr, nullptr, 8507 nullptr, 0, is_volatile, true); 8508 } 8509 8510 IrInstSrc **input_list = heap::c_allocator.allocate<IrInstSrc *>(asm_expr->input_list.length); 8511 IrInstSrc **output_types = heap::c_allocator.allocate<IrInstSrc *>(asm_expr->output_list.length); 8512 ZigVar **output_vars = heap::c_allocator.allocate<ZigVar *>(asm_expr->output_list.length); 8513 size_t return_count = 0; 8514 if (!is_volatile && asm_expr->output_list.length == 0) { 8515 add_node_error(irb->codegen, node, 8516 buf_sprintf("assembly expression with no output must be marked volatile")); 8517 return irb->codegen->invalid_inst_src; 8518 } 8519 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 8520 AsmOutput *asm_output = asm_expr->output_list.at(i); 8521 if (asm_output->return_type) { 8522 return_count += 1; 8523 8524 IrInstSrc *return_type = ir_gen_node(irb, asm_output->return_type, scope); 8525 if (return_type == irb->codegen->invalid_inst_src) 8526 return irb->codegen->invalid_inst_src; 8527 if (return_count > 1) { 8528 add_node_error(irb->codegen, node, 8529 buf_sprintf("inline assembly allows up to one output value")); 8530 return irb->codegen->invalid_inst_src; 8531 } 8532 output_types[i] = return_type; 8533 } else { 8534 Buf *variable_name = asm_output->variable_name; 8535 // TODO there is some duplication here with ir_gen_symbol. I need to do a full audit of how 8536 // inline assembly works. https://github.com/ziglang/zig/issues/215 8537 ZigVar *var = find_variable(irb->codegen, scope, variable_name, nullptr); 8538 if (var) { 8539 output_vars[i] = var; 8540 } else { 8541 add_node_error(irb->codegen, node, 8542 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); 8543 return irb->codegen->invalid_inst_src; 8544 } 8545 } 8546 8547 const char modifier = *buf_ptr(asm_output->constraint); 8548 if (modifier != '=') { 8549 add_node_error(irb->codegen, node, 8550 buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported." 8551 " Compiler TODO: see https://github.com/ziglang/zig/issues/215", 8552 buf_ptr(asm_output->asm_symbolic_name), modifier)); 8553 return irb->codegen->invalid_inst_src; 8554 } 8555 } 8556 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 8557 AsmInput *asm_input = asm_expr->input_list.at(i); 8558 IrInstSrc *input_value = ir_gen_node(irb, asm_input->expr, scope); 8559 if (input_value == irb->codegen->invalid_inst_src) 8560 return irb->codegen->invalid_inst_src; 8561 8562 input_list[i] = input_value; 8563 } 8564 8565 return ir_build_asm_src(irb, scope, node, asm_template, input_list, output_types, 8566 output_vars, return_count, is_volatile, false); 8567 } 8568 8569 static IrInstSrc *ir_gen_if_optional_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 8570 ResultLoc *result_loc) 8571 { 8572 assert(node->type == NodeTypeIfOptional); 8573 8574 Buf *var_symbol = node->data.test_expr.var_symbol; 8575 AstNode *expr_node = node->data.test_expr.target_node; 8576 AstNode *then_node = node->data.test_expr.then_node; 8577 AstNode *else_node = node->data.test_expr.else_node; 8578 bool var_is_ptr = node->data.test_expr.var_is_ptr; 8579 8580 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, expr_node, scope); 8581 spill_scope->spill_harder = true; 8582 8583 IrInstSrc *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, &spill_scope->base, LValPtr, nullptr); 8584 if (maybe_val_ptr == irb->codegen->invalid_inst_src) 8585 return maybe_val_ptr; 8586 8587 IrInstSrc *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr); 8588 IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, scope, node, maybe_val); 8589 8590 IrBasicBlockSrc *then_block = ir_create_basic_block(irb, scope, "OptionalThen"); 8591 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "OptionalElse"); 8592 IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "OptionalEndIf"); 8593 8594 IrInstSrc *is_comptime; 8595 if (ir_should_inline(irb->exec, scope)) { 8596 is_comptime = ir_build_const_bool(irb, scope, node, true); 8597 } else { 8598 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); 8599 } 8600 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null, 8601 then_block, else_block, is_comptime); 8602 8603 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 8604 result_loc, is_comptime); 8605 8606 ir_set_cursor_at_end_and_append_block(irb, then_block); 8607 8608 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, &spill_scope->base, is_comptime); 8609 Scope *var_scope; 8610 if (var_symbol) { 8611 bool is_shadowable = false; 8612 bool is_const = true; 8613 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 8614 var_symbol, is_const, is_const, is_shadowable, is_comptime); 8615 8616 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false); 8617 IrInstSrc *var_value = var_is_ptr ? 8618 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, node, payload_ptr); 8619 build_decl_var_and_init(irb, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), is_comptime); 8620 var_scope = var->child_scope; 8621 } else { 8622 var_scope = subexpr_scope; 8623 } 8624 IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, 8625 &peer_parent->peers.at(0)->base); 8626 if (then_expr_result == irb->codegen->invalid_inst_src) 8627 return then_expr_result; 8628 IrBasicBlockSrc *after_then_block = irb->current_basic_block; 8629 if (!instr_is_unreachable(then_expr_result)) 8630 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 8631 8632 ir_set_cursor_at_end_and_append_block(irb, else_block); 8633 IrInstSrc *else_expr_result; 8634 if (else_node) { 8635 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); 8636 if (else_expr_result == irb->codegen->invalid_inst_src) 8637 return else_expr_result; 8638 } else { 8639 else_expr_result = ir_build_const_void(irb, scope, node); 8640 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 8641 } 8642 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8643 if (!instr_is_unreachable(else_expr_result)) 8644 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 8645 8646 ir_set_cursor_at_end_and_append_block(irb, endif_block); 8647 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 8648 incoming_values[0] = then_expr_result; 8649 incoming_values[1] = else_expr_result; 8650 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 8651 incoming_blocks[0] = after_then_block; 8652 incoming_blocks[1] = after_else_block; 8653 8654 IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 8655 return ir_expr_wrap(irb, scope, phi, result_loc); 8656 } 8657 8658 static IrInstSrc *ir_gen_if_err_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 8659 ResultLoc *result_loc) 8660 { 8661 assert(node->type == NodeTypeIfErrorExpr); 8662 8663 AstNode *target_node = node->data.if_err_expr.target_node; 8664 AstNode *then_node = node->data.if_err_expr.then_node; 8665 AstNode *else_node = node->data.if_err_expr.else_node; 8666 bool var_is_ptr = node->data.if_err_expr.var_is_ptr; 8667 bool var_is_const = true; 8668 Buf *var_symbol = node->data.if_err_expr.var_symbol; 8669 Buf *err_symbol = node->data.if_err_expr.err_symbol; 8670 8671 IrInstSrc *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); 8672 if (err_val_ptr == irb->codegen->invalid_inst_src) 8673 return err_val_ptr; 8674 8675 IrInstSrc *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); 8676 IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr, true, false); 8677 8678 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, scope, "TryOk"); 8679 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "TryElse"); 8680 IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "TryEnd"); 8681 8682 bool force_comptime = ir_should_inline(irb->exec, scope); 8683 IrInstSrc *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); 8684 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); 8685 8686 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 8687 result_loc, is_comptime); 8688 8689 ir_set_cursor_at_end_and_append_block(irb, ok_block); 8690 8691 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 8692 Scope *var_scope; 8693 if (var_symbol) { 8694 bool is_shadowable = false; 8695 IrInstSrc *var_is_comptime = force_comptime ? ir_build_const_bool(irb, subexpr_scope, node, true) : ir_build_test_comptime(irb, subexpr_scope, node, err_val); 8696 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 8697 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); 8698 8699 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, subexpr_scope, node, err_val_ptr, false, false); 8700 IrInstSrc *var_value = var_is_ptr ? 8701 payload_ptr : ir_build_load_ptr(irb, subexpr_scope, node, payload_ptr); 8702 build_decl_var_and_init(irb, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), var_is_comptime); 8703 var_scope = var->child_scope; 8704 } else { 8705 var_scope = subexpr_scope; 8706 } 8707 IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, 8708 &peer_parent->peers.at(0)->base); 8709 if (then_expr_result == irb->codegen->invalid_inst_src) 8710 return then_expr_result; 8711 IrBasicBlockSrc *after_then_block = irb->current_basic_block; 8712 if (!instr_is_unreachable(then_expr_result)) 8713 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 8714 8715 ir_set_cursor_at_end_and_append_block(irb, else_block); 8716 8717 IrInstSrc *else_expr_result; 8718 if (else_node) { 8719 Scope *err_var_scope; 8720 if (err_symbol) { 8721 bool is_shadowable = false; 8722 bool is_const = true; 8723 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 8724 err_symbol, is_const, is_const, is_shadowable, is_comptime); 8725 8726 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, subexpr_scope, node, err_val_ptr); 8727 IrInstSrc *err_value = ir_build_load_ptr(irb, subexpr_scope, node, err_ptr); 8728 build_decl_var_and_init(irb, subexpr_scope, node, var, err_value, buf_ptr(err_symbol), is_comptime); 8729 err_var_scope = var->child_scope; 8730 } else { 8731 err_var_scope = subexpr_scope; 8732 } 8733 else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base); 8734 if (else_expr_result == irb->codegen->invalid_inst_src) 8735 return else_expr_result; 8736 } else { 8737 else_expr_result = ir_build_const_void(irb, scope, node); 8738 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 8739 } 8740 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8741 if (!instr_is_unreachable(else_expr_result)) 8742 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 8743 8744 ir_set_cursor_at_end_and_append_block(irb, endif_block); 8745 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 8746 incoming_values[0] = then_expr_result; 8747 incoming_values[1] = else_expr_result; 8748 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 8749 incoming_blocks[0] = after_then_block; 8750 incoming_blocks[1] = after_else_block; 8751 8752 IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 8753 return ir_expr_wrap(irb, scope, phi, result_loc); 8754 } 8755 8756 static bool ir_gen_switch_prong_expr(IrBuilderSrc *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, 8757 IrBasicBlockSrc *end_block, IrInstSrc *is_comptime, IrInstSrc *var_is_comptime, 8758 IrInstSrc *target_value_ptr, IrInstSrc **prong_values, size_t prong_values_len, 8759 ZigList<IrBasicBlockSrc *> *incoming_blocks, ZigList<IrInstSrc *> *incoming_values, 8760 IrInstSrcSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc) 8761 { 8762 assert(switch_node->type == NodeTypeSwitchExpr); 8763 assert(prong_node->type == NodeTypeSwitchProng); 8764 8765 AstNode *expr_node = prong_node->data.switch_prong.expr; 8766 AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol; 8767 Scope *child_scope; 8768 if (var_symbol_node) { 8769 assert(var_symbol_node->type == NodeTypeSymbol); 8770 Buf *var_name = var_symbol_node->data.symbol_expr.symbol; 8771 bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr; 8772 8773 bool is_shadowable = false; 8774 bool is_const = true; 8775 ZigVar *var = ir_create_var(irb, var_symbol_node, scope, 8776 var_name, is_const, is_const, is_shadowable, var_is_comptime); 8777 child_scope = var->child_scope; 8778 IrInstSrc *var_value; 8779 if (out_switch_else_var != nullptr) { 8780 IrInstSrcSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node, 8781 target_value_ptr); 8782 *out_switch_else_var = switch_else_var; 8783 IrInstSrc *payload_ptr = &switch_else_var->base; 8784 var_value = var_is_ptr ? 8785 payload_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, payload_ptr); 8786 } else if (prong_values != nullptr) { 8787 IrInstSrc *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, 8788 prong_values, prong_values_len); 8789 var_value = var_is_ptr ? 8790 payload_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, payload_ptr); 8791 } else { 8792 var_value = var_is_ptr ? 8793 target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr); 8794 } 8795 build_decl_var_and_init(irb, scope, var_symbol_node, var, var_value, buf_ptr(var_name), var_is_comptime); 8796 } else { 8797 child_scope = scope; 8798 } 8799 8800 IrInstSrc *expr_result = ir_gen_node_extra(irb, expr_node, child_scope, lval, result_loc); 8801 if (expr_result == irb->codegen->invalid_inst_src) 8802 return false; 8803 if (!instr_is_unreachable(expr_result)) 8804 ir_mark_gen(ir_build_br(irb, scope, switch_node, end_block, is_comptime)); 8805 incoming_blocks->append(irb->current_basic_block); 8806 incoming_values->append(expr_result); 8807 return true; 8808 } 8809 8810 static IrInstSrc *ir_gen_switch_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 8811 ResultLoc *result_loc) 8812 { 8813 assert(node->type == NodeTypeSwitchExpr); 8814 8815 AstNode *target_node = node->data.switch_expr.expr; 8816 IrInstSrc *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); 8817 if (target_value_ptr == irb->codegen->invalid_inst_src) 8818 return target_value_ptr; 8819 IrInstSrc *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); 8820 8821 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "SwitchElse"); 8822 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, scope, "SwitchEnd"); 8823 8824 size_t prong_count = node->data.switch_expr.prongs.length; 8825 ZigList<IrInstSrcSwitchBrCase> cases = {0}; 8826 8827 IrInstSrc *is_comptime; 8828 IrInstSrc *var_is_comptime; 8829 if (ir_should_inline(irb->exec, scope)) { 8830 is_comptime = ir_build_const_bool(irb, scope, node, true); 8831 var_is_comptime = is_comptime; 8832 } else { 8833 is_comptime = ir_build_test_comptime(irb, scope, node, target_value); 8834 var_is_comptime = ir_build_test_comptime(irb, scope, node, target_value_ptr); 8835 } 8836 8837 ZigList<IrInstSrc *> incoming_values = {0}; 8838 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 8839 ZigList<IrInstSrcCheckSwitchProngsRange> check_ranges = {0}; 8840 8841 IrInstSrcSwitchElseVar *switch_else_var = nullptr; 8842 8843 ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>(); 8844 peer_parent->base.id = ResultLocIdPeerParent; 8845 peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; 8846 peer_parent->end_bb = end_block; 8847 peer_parent->is_comptime = is_comptime; 8848 peer_parent->parent = result_loc; 8849 8850 ir_build_reset_result(irb, scope, node, &peer_parent->base); 8851 8852 // First do the else and the ranges 8853 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 8854 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 8855 AstNode *else_prong = nullptr; 8856 AstNode *underscore_prong = nullptr; 8857 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 8858 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 8859 size_t prong_item_count = prong_node->data.switch_prong.items.length; 8860 if (prong_node->data.switch_prong.any_items_are_range) { 8861 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 8862 8863 IrInstSrc *ok_bit = nullptr; 8864 AstNode *last_item_node = nullptr; 8865 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 8866 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 8867 last_item_node = item_node; 8868 if (item_node->type == NodeTypeSwitchRange) { 8869 AstNode *start_node = item_node->data.switch_range.start; 8870 AstNode *end_node = item_node->data.switch_range.end; 8871 8872 IrInstSrc *start_value = ir_gen_node(irb, start_node, comptime_scope); 8873 if (start_value == irb->codegen->invalid_inst_src) 8874 return irb->codegen->invalid_inst_src; 8875 8876 IrInstSrc *end_value = ir_gen_node(irb, end_node, comptime_scope); 8877 if (end_value == irb->codegen->invalid_inst_src) 8878 return irb->codegen->invalid_inst_src; 8879 8880 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one(); 8881 check_range->start = start_value; 8882 check_range->end = end_value; 8883 8884 IrInstSrc *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq, 8885 target_value, start_value, false); 8886 IrInstSrc *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq, 8887 target_value, end_value, false); 8888 IrInstSrc *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd, 8889 lower_range_ok, upper_range_ok, false); 8890 if (ok_bit) { 8891 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false); 8892 } else { 8893 ok_bit = both_ok; 8894 } 8895 } else { 8896 IrInstSrc *item_value = ir_gen_node(irb, item_node, comptime_scope); 8897 if (item_value == irb->codegen->invalid_inst_src) 8898 return irb->codegen->invalid_inst_src; 8899 8900 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one(); 8901 check_range->start = item_value; 8902 check_range->end = item_value; 8903 8904 IrInstSrc *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq, 8905 item_value, target_value, false); 8906 if (ok_bit) { 8907 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false); 8908 } else { 8909 ok_bit = cmp_ok; 8910 } 8911 } 8912 } 8913 8914 IrBasicBlockSrc *range_block_yes = ir_create_basic_block(irb, scope, "SwitchRangeYes"); 8915 IrBasicBlockSrc *range_block_no = ir_create_basic_block(irb, scope, "SwitchRangeNo"); 8916 8917 assert(ok_bit); 8918 assert(last_item_node); 8919 IrInstSrc *br_inst = ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, 8920 range_block_yes, range_block_no, is_comptime)); 8921 if (peer_parent->base.source_instruction == nullptr) { 8922 peer_parent->base.source_instruction = br_inst; 8923 } 8924 8925 if (peer_parent->peers.length > 0) { 8926 peer_parent->peers.last()->next_bb = range_block_yes; 8927 } 8928 peer_parent->peers.append(this_peer_result_loc); 8929 ir_set_cursor_at_end_and_append_block(irb, range_block_yes); 8930 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 8931 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, 8932 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) 8933 { 8934 return irb->codegen->invalid_inst_src; 8935 } 8936 8937 ir_set_cursor_at_end_and_append_block(irb, range_block_no); 8938 } else { 8939 if (prong_item_count == 0) { 8940 if (else_prong) { 8941 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 8942 buf_sprintf("multiple else prongs in switch expression")); 8943 add_error_note(irb->codegen, msg, else_prong, 8944 buf_sprintf("previous else prong is here")); 8945 return irb->codegen->invalid_inst_src; 8946 } 8947 else_prong = prong_node; 8948 } else if (prong_item_count == 1 && 8949 prong_node->data.switch_prong.items.at(0)->type == NodeTypeSymbol && 8950 buf_eql_str(prong_node->data.switch_prong.items.at(0)->data.symbol_expr.symbol, "_")) { 8951 if (underscore_prong) { 8952 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 8953 buf_sprintf("multiple '_' prongs in switch expression")); 8954 add_error_note(irb->codegen, msg, underscore_prong, 8955 buf_sprintf("previous '_' prong is here")); 8956 return irb->codegen->invalid_inst_src; 8957 } 8958 underscore_prong = prong_node; 8959 } else { 8960 continue; 8961 } 8962 if (underscore_prong && else_prong) { 8963 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 8964 buf_sprintf("else and '_' prong in switch expression")); 8965 if (underscore_prong == prong_node) 8966 add_error_note(irb->codegen, msg, else_prong, 8967 buf_sprintf("else prong is here")); 8968 else 8969 add_error_note(irb->codegen, msg, underscore_prong, 8970 buf_sprintf("'_' prong is here")); 8971 return irb->codegen->invalid_inst_src; 8972 } 8973 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 8974 8975 IrBasicBlockSrc *prev_block = irb->current_basic_block; 8976 if (peer_parent->peers.length > 0) { 8977 peer_parent->peers.last()->next_bb = else_block; 8978 } 8979 peer_parent->peers.append(this_peer_result_loc); 8980 ir_set_cursor_at_end_and_append_block(irb, else_block); 8981 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 8982 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, 8983 &switch_else_var, LValNone, &this_peer_result_loc->base)) 8984 { 8985 return irb->codegen->invalid_inst_src; 8986 } 8987 ir_set_cursor_at_end(irb, prev_block); 8988 } 8989 } 8990 8991 // next do the non-else non-ranges 8992 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 8993 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 8994 size_t prong_item_count = prong_node->data.switch_prong.items.length; 8995 if (prong_item_count == 0) 8996 continue; 8997 if (prong_node->data.switch_prong.any_items_are_range) 8998 continue; 8999 if (underscore_prong == prong_node) 9000 continue; 9001 9002 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 9003 9004 IrBasicBlockSrc *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); 9005 IrInstSrc **items = heap::c_allocator.allocate<IrInstSrc *>(prong_item_count); 9006 9007 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 9008 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 9009 assert(item_node->type != NodeTypeSwitchRange); 9010 9011 IrInstSrc *item_value = ir_gen_node(irb, item_node, comptime_scope); 9012 if (item_value == irb->codegen->invalid_inst_src) 9013 return irb->codegen->invalid_inst_src; 9014 9015 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one(); 9016 check_range->start = item_value; 9017 check_range->end = item_value; 9018 9019 IrInstSrcSwitchBrCase *this_case = cases.add_one(); 9020 this_case->value = item_value; 9021 this_case->block = prong_block; 9022 9023 items[item_i] = item_value; 9024 } 9025 9026 IrBasicBlockSrc *prev_block = irb->current_basic_block; 9027 if (peer_parent->peers.length > 0) { 9028 peer_parent->peers.last()->next_bb = prong_block; 9029 } 9030 peer_parent->peers.append(this_peer_result_loc); 9031 ir_set_cursor_at_end_and_append_block(irb, prong_block); 9032 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 9033 is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, 9034 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) 9035 { 9036 return irb->codegen->invalid_inst_src; 9037 } 9038 9039 ir_set_cursor_at_end(irb, prev_block); 9040 9041 } 9042 9043 IrInstSrc *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, 9044 check_ranges.items, check_ranges.length, else_prong != nullptr, underscore_prong != nullptr); 9045 9046 IrInstSrc *br_instruction; 9047 if (cases.length == 0) { 9048 br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime); 9049 } else { 9050 IrInstSrcSwitchBr *switch_br = ir_build_switch_br_src(irb, scope, node, target_value, else_block, 9051 cases.length, cases.items, is_comptime, switch_prongs_void); 9052 if (switch_else_var != nullptr) { 9053 switch_else_var->switch_br = switch_br; 9054 } 9055 br_instruction = &switch_br->base; 9056 } 9057 if (peer_parent->base.source_instruction == nullptr) { 9058 peer_parent->base.source_instruction = br_instruction; 9059 } 9060 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 9061 peer_parent->peers.at(i)->base.source_instruction = peer_parent->base.source_instruction; 9062 } 9063 9064 if (!else_prong && !underscore_prong) { 9065 if (peer_parent->peers.length != 0) { 9066 peer_parent->peers.last()->next_bb = else_block; 9067 } 9068 ir_set_cursor_at_end_and_append_block(irb, else_block); 9069 ir_build_unreachable(irb, scope, node); 9070 } else { 9071 if (peer_parent->peers.length != 0) { 9072 peer_parent->peers.last()->next_bb = end_block; 9073 } 9074 } 9075 9076 ir_set_cursor_at_end_and_append_block(irb, end_block); 9077 assert(incoming_blocks.length == incoming_values.length); 9078 IrInstSrc *result_instruction; 9079 if (incoming_blocks.length == 0) { 9080 result_instruction = ir_build_const_void(irb, scope, node); 9081 } else { 9082 result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length, 9083 incoming_blocks.items, incoming_values.items, peer_parent); 9084 } 9085 return ir_lval_wrap(irb, scope, result_instruction, lval, result_loc); 9086 } 9087 9088 static IrInstSrc *ir_gen_comptime(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) { 9089 assert(node->type == NodeTypeCompTime); 9090 9091 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); 9092 // purposefully pass null for result_loc and let EndExpr handle it 9093 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); 9094 } 9095 9096 static IrInstSrc *ir_gen_return_from_block(IrBuilderSrc *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { 9097 IrInstSrc *is_comptime; 9098 if (ir_should_inline(irb->exec, break_scope)) { 9099 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 9100 } else { 9101 is_comptime = block_scope->is_comptime; 9102 } 9103 9104 IrInstSrc *result_value; 9105 if (node->data.break_expr.expr) { 9106 ResultLocPeer *peer_result = create_peer_result(block_scope->peer_parent); 9107 block_scope->peer_parent->peers.append(peer_result); 9108 9109 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, block_scope->lval, 9110 &peer_result->base); 9111 if (result_value == irb->codegen->invalid_inst_src) 9112 return irb->codegen->invalid_inst_src; 9113 } else { 9114 result_value = ir_build_const_void(irb, break_scope, node); 9115 } 9116 9117 IrBasicBlockSrc *dest_block = block_scope->end_block; 9118 ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); 9119 9120 block_scope->incoming_blocks->append(irb->current_basic_block); 9121 block_scope->incoming_values->append(result_value); 9122 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 9123 } 9124 9125 static IrInstSrc *ir_gen_break(IrBuilderSrc *irb, Scope *break_scope, AstNode *node) { 9126 assert(node->type == NodeTypeBreak); 9127 9128 // Search up the scope. We'll find one of these things first: 9129 // * function definition scope or global scope => error, break outside loop 9130 // * defer expression scope => error, cannot break out of defer expression 9131 // * loop scope => OK 9132 // * (if it's a labeled break) labeled block => OK 9133 9134 Scope *search_scope = break_scope; 9135 ScopeLoop *loop_scope; 9136 for (;;) { 9137 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 9138 if (node->data.break_expr.name != nullptr) { 9139 add_node_error(irb->codegen, node, buf_sprintf("label not found: '%s'", buf_ptr(node->data.break_expr.name))); 9140 return irb->codegen->invalid_inst_src; 9141 } else { 9142 add_node_error(irb->codegen, node, buf_sprintf("break expression outside loop")); 9143 return irb->codegen->invalid_inst_src; 9144 } 9145 } else if (search_scope->id == ScopeIdDeferExpr) { 9146 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of defer expression")); 9147 return irb->codegen->invalid_inst_src; 9148 } else if (search_scope->id == ScopeIdLoop) { 9149 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 9150 if (node->data.break_expr.name == nullptr || 9151 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name))) 9152 { 9153 loop_scope = this_loop_scope; 9154 break; 9155 } 9156 } else if (search_scope->id == ScopeIdBlock) { 9157 ScopeBlock *this_block_scope = (ScopeBlock *)search_scope; 9158 if (node->data.break_expr.name != nullptr && 9159 (this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name))) 9160 { 9161 assert(this_block_scope->end_block != nullptr); 9162 return ir_gen_return_from_block(irb, break_scope, node, this_block_scope); 9163 } 9164 } else if (search_scope->id == ScopeIdSuspend) { 9165 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of suspend block")); 9166 return irb->codegen->invalid_inst_src; 9167 } 9168 search_scope = search_scope->parent; 9169 } 9170 9171 IrInstSrc *is_comptime; 9172 if (ir_should_inline(irb->exec, break_scope)) { 9173 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 9174 } else { 9175 is_comptime = loop_scope->is_comptime; 9176 } 9177 9178 IrInstSrc *result_value; 9179 if (node->data.break_expr.expr) { 9180 ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent); 9181 loop_scope->peer_parent->peers.append(peer_result); 9182 9183 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, 9184 loop_scope->lval, &peer_result->base); 9185 if (result_value == irb->codegen->invalid_inst_src) 9186 return irb->codegen->invalid_inst_src; 9187 } else { 9188 result_value = ir_build_const_void(irb, break_scope, node); 9189 } 9190 9191 IrBasicBlockSrc *dest_block = loop_scope->break_block; 9192 ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); 9193 9194 loop_scope->incoming_blocks->append(irb->current_basic_block); 9195 loop_scope->incoming_values->append(result_value); 9196 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 9197 } 9198 9199 static IrInstSrc *ir_gen_continue(IrBuilderSrc *irb, Scope *continue_scope, AstNode *node) { 9200 assert(node->type == NodeTypeContinue); 9201 9202 // Search up the scope. We'll find one of these things first: 9203 // * function definition scope or global scope => error, break outside loop 9204 // * defer expression scope => error, cannot break out of defer expression 9205 // * loop scope => OK 9206 9207 ZigList<ScopeRuntime *> runtime_scopes = {}; 9208 9209 Scope *search_scope = continue_scope; 9210 ScopeLoop *loop_scope; 9211 for (;;) { 9212 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 9213 if (node->data.continue_expr.name != nullptr) { 9214 add_node_error(irb->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.continue_expr.name))); 9215 return irb->codegen->invalid_inst_src; 9216 } else { 9217 add_node_error(irb->codegen, node, buf_sprintf("continue expression outside loop")); 9218 return irb->codegen->invalid_inst_src; 9219 } 9220 } else if (search_scope->id == ScopeIdDeferExpr) { 9221 add_node_error(irb->codegen, node, buf_sprintf("cannot continue out of defer expression")); 9222 return irb->codegen->invalid_inst_src; 9223 } else if (search_scope->id == ScopeIdLoop) { 9224 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 9225 if (node->data.continue_expr.name == nullptr || 9226 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name))) 9227 { 9228 loop_scope = this_loop_scope; 9229 break; 9230 } 9231 } else if (search_scope->id == ScopeIdRuntime) { 9232 ScopeRuntime *scope_runtime = (ScopeRuntime *)search_scope; 9233 runtime_scopes.append(scope_runtime); 9234 } 9235 search_scope = search_scope->parent; 9236 } 9237 9238 IrInstSrc *is_comptime; 9239 if (ir_should_inline(irb->exec, continue_scope)) { 9240 is_comptime = ir_build_const_bool(irb, continue_scope, node, true); 9241 } else { 9242 is_comptime = loop_scope->is_comptime; 9243 } 9244 9245 for (size_t i = 0; i < runtime_scopes.length; i += 1) { 9246 ScopeRuntime *scope_runtime = runtime_scopes.at(i); 9247 ir_mark_gen(ir_build_check_runtime_scope(irb, continue_scope, node, scope_runtime->is_comptime, is_comptime)); 9248 } 9249 9250 IrBasicBlockSrc *dest_block = loop_scope->continue_block; 9251 ir_gen_defers_for_block(irb, continue_scope, dest_block->scope, false); 9252 return ir_mark_gen(ir_build_br(irb, continue_scope, node, dest_block, is_comptime)); 9253 } 9254 9255 static IrInstSrc *ir_gen_error_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 9256 assert(node->type == NodeTypeErrorType); 9257 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_global_error_set); 9258 } 9259 9260 static IrInstSrc *ir_gen_defer(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 9261 assert(node->type == NodeTypeDefer); 9262 9263 ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope); 9264 node->data.defer.child_scope = &defer_child_scope->base; 9265 9266 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(irb->codegen, node, parent_scope); 9267 node->data.defer.expr_scope = &defer_expr_scope->base; 9268 9269 return ir_build_const_void(irb, parent_scope, node); 9270 } 9271 9272 static IrInstSrc *ir_gen_slice(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 9273 assert(node->type == NodeTypeSliceExpr); 9274 9275 AstNodeSliceExpr *slice_expr = &node->data.slice_expr; 9276 AstNode *array_node = slice_expr->array_ref_expr; 9277 AstNode *start_node = slice_expr->start; 9278 AstNode *end_node = slice_expr->end; 9279 AstNode *sentinel_node = slice_expr->sentinel; 9280 9281 IrInstSrc *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr); 9282 if (ptr_value == irb->codegen->invalid_inst_src) 9283 return irb->codegen->invalid_inst_src; 9284 9285 IrInstSrc *start_value = ir_gen_node(irb, start_node, scope); 9286 if (start_value == irb->codegen->invalid_inst_src) 9287 return irb->codegen->invalid_inst_src; 9288 9289 IrInstSrc *end_value; 9290 if (end_node) { 9291 end_value = ir_gen_node(irb, end_node, scope); 9292 if (end_value == irb->codegen->invalid_inst_src) 9293 return irb->codegen->invalid_inst_src; 9294 } else { 9295 end_value = nullptr; 9296 } 9297 9298 IrInstSrc *sentinel_value; 9299 if (sentinel_node) { 9300 sentinel_value = ir_gen_node(irb, sentinel_node, scope); 9301 if (sentinel_value == irb->codegen->invalid_inst_src) 9302 return irb->codegen->invalid_inst_src; 9303 } else { 9304 sentinel_value = nullptr; 9305 } 9306 9307 IrInstSrc *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value, 9308 sentinel_value, true, result_loc); 9309 return ir_lval_wrap(irb, scope, slice, lval, result_loc); 9310 } 9311 9312 static IrInstSrc *ir_gen_catch(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval, 9313 ResultLoc *result_loc) 9314 { 9315 assert(node->type == NodeTypeCatchExpr); 9316 9317 AstNode *op1_node = node->data.unwrap_err_expr.op1; 9318 AstNode *op2_node = node->data.unwrap_err_expr.op2; 9319 AstNode *var_node = node->data.unwrap_err_expr.symbol; 9320 9321 if (op2_node->type == NodeTypeUnreachable) { 9322 if (var_node != nullptr) { 9323 assert(var_node->type == NodeTypeSymbol); 9324 Buf *var_name = var_node->data.symbol_expr.symbol; 9325 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); 9326 return irb->codegen->invalid_inst_src; 9327 } 9328 return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, lval, result_loc); 9329 } 9330 9331 9332 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, op1_node, parent_scope); 9333 spill_scope->spill_harder = true; 9334 9335 IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, op1_node, &spill_scope->base, LValPtr, nullptr); 9336 if (err_union_ptr == irb->codegen->invalid_inst_src) 9337 return irb->codegen->invalid_inst_src; 9338 9339 IrInstSrc *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr, true, false); 9340 9341 IrInstSrc *is_comptime; 9342 if (ir_should_inline(irb->exec, parent_scope)) { 9343 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 9344 } else { 9345 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_err); 9346 } 9347 9348 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); 9349 IrBasicBlockSrc *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); 9350 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); 9351 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); 9352 9353 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, result_loc, 9354 is_comptime); 9355 9356 ir_set_cursor_at_end_and_append_block(irb, err_block); 9357 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, &spill_scope->base, is_comptime); 9358 Scope *err_scope; 9359 if (var_node) { 9360 assert(var_node->type == NodeTypeSymbol); 9361 Buf *var_name = var_node->data.symbol_expr.symbol; 9362 bool is_const = true; 9363 bool is_shadowable = false; 9364 ZigVar *var = ir_create_var(irb, node, subexpr_scope, var_name, 9365 is_const, is_const, is_shadowable, is_comptime); 9366 err_scope = var->child_scope; 9367 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, node, err_union_ptr); 9368 IrInstSrc *err_value = ir_build_load_ptr(irb, err_scope, var_node, err_ptr); 9369 build_decl_var_and_init(irb, err_scope, var_node, var, err_value, buf_ptr(var_name), is_comptime); 9370 } else { 9371 err_scope = subexpr_scope; 9372 } 9373 IrInstSrc *err_result = ir_gen_node_extra(irb, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base); 9374 if (err_result == irb->codegen->invalid_inst_src) 9375 return irb->codegen->invalid_inst_src; 9376 IrBasicBlockSrc *after_err_block = irb->current_basic_block; 9377 if (!instr_is_unreachable(err_result)) 9378 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 9379 9380 ir_set_cursor_at_end_and_append_block(irb, ok_block); 9381 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(irb, parent_scope, node, err_union_ptr, false, false); 9382 IrInstSrc *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 9383 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); 9384 IrBasicBlockSrc *after_ok_block = irb->current_basic_block; 9385 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 9386 9387 ir_set_cursor_at_end_and_append_block(irb, end_block); 9388 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 9389 incoming_values[0] = err_result; 9390 incoming_values[1] = unwrapped_payload; 9391 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 9392 incoming_blocks[0] = after_err_block; 9393 incoming_blocks[1] = after_ok_block; 9394 IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); 9395 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 9396 } 9397 9398 static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) { 9399 if (inner_scope == nullptr || inner_scope == outer_scope) return false; 9400 bool need_comma = render_instance_name_recursive(codegen, name, outer_scope, inner_scope->parent); 9401 if (inner_scope->id != ScopeIdVarDecl) 9402 return need_comma; 9403 9404 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; 9405 if (need_comma) 9406 buf_append_char(name, ','); 9407 // TODO: const ptr reinterpret here to make the var type agree with the value? 9408 render_const_value(codegen, name, var_scope->var->const_value); 9409 return true; 9410 } 9411 9412 static Buf *get_anon_type_name(CodeGen *codegen, IrExecutableSrc *exec, const char *kind_name, 9413 Scope *scope, AstNode *source_node, Buf *out_bare_name) 9414 { 9415 if (exec != nullptr && exec->name) { 9416 ZigType *import = get_scope_import(scope); 9417 Buf *namespace_name = buf_alloc(); 9418 append_namespace_qualification(codegen, namespace_name, import); 9419 buf_append_buf(namespace_name, exec->name); 9420 buf_init_from_buf(out_bare_name, exec->name); 9421 return namespace_name; 9422 } else if (exec != nullptr && exec->name_fn != nullptr) { 9423 Buf *name = buf_alloc(); 9424 buf_append_buf(name, &exec->name_fn->symbol_name); 9425 buf_appendf(name, "("); 9426 render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope); 9427 buf_appendf(name, ")"); 9428 buf_init_from_buf(out_bare_name, name); 9429 return name; 9430 } else { 9431 ZigType *import = get_scope_import(scope); 9432 Buf *namespace_name = buf_alloc(); 9433 append_namespace_qualification(codegen, namespace_name, import); 9434 buf_appendf(namespace_name, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, kind_name, 9435 source_node->line + 1, source_node->column + 1); 9436 buf_init_from_buf(out_bare_name, namespace_name); 9437 return namespace_name; 9438 } 9439 } 9440 9441 static IrInstSrc *ir_gen_container_decl(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 9442 assert(node->type == NodeTypeContainerDecl); 9443 9444 ContainerKind kind = node->data.container_decl.kind; 9445 Buf *bare_name = buf_alloc(); 9446 Buf *name = get_anon_type_name(irb->codegen, irb->exec, container_string(kind), parent_scope, node, bare_name); 9447 9448 ContainerLayout layout = node->data.container_decl.layout; 9449 ZigType *container_type = get_partial_container_type(irb->codegen, parent_scope, 9450 kind, node, buf_ptr(name), bare_name, layout); 9451 ScopeDecls *child_scope = get_container_scope(container_type); 9452 9453 for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) { 9454 AstNode *child_node = node->data.container_decl.decls.at(i); 9455 scan_decls(irb->codegen, child_scope, child_node); 9456 } 9457 9458 TldContainer *tld_container = heap::c_allocator.create<TldContainer>(); 9459 init_tld(&tld_container->base, TldIdContainer, bare_name, VisibModPub, node, parent_scope); 9460 tld_container->type_entry = container_type; 9461 tld_container->decls_scope = child_scope; 9462 irb->codegen->resolve_queue.append(&tld_container->base); 9463 9464 // Add this to the list to mark as invalid if analyzing this exec fails. 9465 irb->exec->tld_list.append(&tld_container->base); 9466 9467 return ir_build_const_type(irb, parent_scope, node, container_type); 9468 } 9469 9470 // errors should be populated with set1's values 9471 static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigType *set1, ZigType *set2, 9472 Buf *type_name) 9473 { 9474 assert(set1->id == ZigTypeIdErrorSet); 9475 assert(set2->id == ZigTypeIdErrorSet); 9476 9477 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 9478 err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits; 9479 err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align; 9480 err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size; 9481 if (type_name == nullptr) { 9482 buf_resize(&err_set_type->name, 0); 9483 buf_appendf(&err_set_type->name, "error{"); 9484 } else { 9485 buf_init_from_buf(&err_set_type->name, type_name); 9486 } 9487 9488 for (uint32_t i = 0, count = set1->data.error_set.err_count; i < count; i += 1) { 9489 assert(errors[set1->data.error_set.errors[i]->value] == set1->data.error_set.errors[i]); 9490 } 9491 9492 uint32_t count = set1->data.error_set.err_count; 9493 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 9494 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 9495 if (errors[error_entry->value] == nullptr) { 9496 count += 1; 9497 } 9498 } 9499 9500 err_set_type->data.error_set.err_count = count; 9501 err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(count); 9502 9503 bool need_comma = false; 9504 for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { 9505 ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; 9506 if (type_name == nullptr) { 9507 const char *comma = need_comma ? "," : ""; 9508 need_comma = true; 9509 buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&error_entry->name)); 9510 } 9511 err_set_type->data.error_set.errors[i] = error_entry; 9512 } 9513 9514 uint32_t index = set1->data.error_set.err_count; 9515 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 9516 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 9517 if (errors[error_entry->value] == nullptr) { 9518 errors[error_entry->value] = error_entry; 9519 if (type_name == nullptr) { 9520 const char *comma = need_comma ? "," : ""; 9521 need_comma = true; 9522 buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&error_entry->name)); 9523 } 9524 err_set_type->data.error_set.errors[index] = error_entry; 9525 index += 1; 9526 } 9527 } 9528 assert(index == count); 9529 9530 if (type_name == nullptr) { 9531 buf_appendf(&err_set_type->name, "}"); 9532 } 9533 9534 return err_set_type; 9535 9536 } 9537 9538 static ZigType *make_err_set_with_one_item(CodeGen *g, Scope *parent_scope, AstNode *node, 9539 ErrorTableEntry *err_entry) 9540 { 9541 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 9542 buf_resize(&err_set_type->name, 0); 9543 buf_appendf(&err_set_type->name, "error{%s}", buf_ptr(&err_entry->name)); 9544 err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits; 9545 err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align; 9546 err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size; 9547 err_set_type->data.error_set.err_count = 1; 9548 err_set_type->data.error_set.errors = heap::c_allocator.create<ErrorTableEntry *>(); 9549 9550 err_set_type->data.error_set.errors[0] = err_entry; 9551 9552 return err_set_type; 9553 } 9554 9555 static AstNode *ast_field_to_symbol_node(AstNode *err_set_field_node) { 9556 if (err_set_field_node->type == NodeTypeSymbol) { 9557 return err_set_field_node; 9558 } else if (err_set_field_node->type == NodeTypeErrorSetField) { 9559 assert(err_set_field_node->data.err_set_field.field_name->type == NodeTypeSymbol); 9560 return err_set_field_node->data.err_set_field.field_name; 9561 } else { 9562 return err_set_field_node; 9563 } 9564 } 9565 9566 static IrInstSrc *ir_gen_err_set_decl(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 9567 assert(node->type == NodeTypeErrorSetDecl); 9568 9569 uint32_t err_count = node->data.err_set_decl.decls.length; 9570 9571 Buf bare_name = BUF_INIT; 9572 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error", parent_scope, node, &bare_name); 9573 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 9574 buf_init_from_buf(&err_set_type->name, type_name); 9575 err_set_type->data.error_set.err_count = err_count; 9576 err_set_type->size_in_bits = irb->codegen->builtin_types.entry_global_error_set->size_in_bits; 9577 err_set_type->abi_align = irb->codegen->builtin_types.entry_global_error_set->abi_align; 9578 err_set_type->abi_size = irb->codegen->builtin_types.entry_global_error_set->abi_size; 9579 err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(err_count); 9580 9581 size_t errors_count = irb->codegen->errors_by_index.length + err_count; 9582 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count); 9583 9584 for (uint32_t i = 0; i < err_count; i += 1) { 9585 AstNode *field_node = node->data.err_set_decl.decls.at(i); 9586 AstNode *symbol_node = ast_field_to_symbol_node(field_node); 9587 Buf *err_name = symbol_node->data.symbol_expr.symbol; 9588 ErrorTableEntry *err = heap::c_allocator.create<ErrorTableEntry>(); 9589 err->decl_node = field_node; 9590 buf_init_from_buf(&err->name, err_name); 9591 9592 auto existing_entry = irb->codegen->error_table.put_unique(err_name, err); 9593 if (existing_entry) { 9594 err->value = existing_entry->value->value; 9595 } else { 9596 size_t error_value_count = irb->codegen->errors_by_index.length; 9597 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)irb->codegen->err_tag_type->data.integral.bit_count)); 9598 err->value = error_value_count; 9599 irb->codegen->errors_by_index.append(err); 9600 } 9601 err_set_type->data.error_set.errors[i] = err; 9602 9603 ErrorTableEntry *prev_err = errors[err->value]; 9604 if (prev_err != nullptr) { 9605 ErrorMsg *msg = add_node_error(irb->codegen, ast_field_to_symbol_node(err->decl_node), 9606 buf_sprintf("duplicate error: '%s'", buf_ptr(&err->name))); 9607 add_error_note(irb->codegen, msg, ast_field_to_symbol_node(prev_err->decl_node), 9608 buf_sprintf("other error here")); 9609 return irb->codegen->invalid_inst_src; 9610 } 9611 errors[err->value] = err; 9612 } 9613 heap::c_allocator.deallocate(errors, errors_count); 9614 return ir_build_const_type(irb, parent_scope, node, err_set_type); 9615 } 9616 9617 static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 9618 assert(node->type == NodeTypeFnProto); 9619 9620 size_t param_count = node->data.fn_proto.params.length; 9621 IrInstSrc **param_types = heap::c_allocator.allocate<IrInstSrc*>(param_count); 9622 9623 bool is_var_args = false; 9624 for (size_t i = 0; i < param_count; i += 1) { 9625 AstNode *param_node = node->data.fn_proto.params.at(i); 9626 if (param_node->data.param_decl.is_var_args) { 9627 is_var_args = true; 9628 break; 9629 } 9630 if (param_node->data.param_decl.var_token == nullptr) { 9631 AstNode *type_node = param_node->data.param_decl.type; 9632 IrInstSrc *type_value = ir_gen_node(irb, type_node, parent_scope); 9633 if (type_value == irb->codegen->invalid_inst_src) 9634 return irb->codegen->invalid_inst_src; 9635 param_types[i] = type_value; 9636 } else { 9637 param_types[i] = nullptr; 9638 } 9639 } 9640 9641 IrInstSrc *align_value = nullptr; 9642 if (node->data.fn_proto.align_expr != nullptr) { 9643 align_value = ir_gen_node(irb, node->data.fn_proto.align_expr, parent_scope); 9644 if (align_value == irb->codegen->invalid_inst_src) 9645 return irb->codegen->invalid_inst_src; 9646 } 9647 9648 IrInstSrc *callconv_value = nullptr; 9649 if (node->data.fn_proto.callconv_expr != nullptr) { 9650 callconv_value = ir_gen_node(irb, node->data.fn_proto.callconv_expr, parent_scope); 9651 if (callconv_value == irb->codegen->invalid_inst_src) 9652 return irb->codegen->invalid_inst_src; 9653 } 9654 9655 IrInstSrc *return_type; 9656 if (node->data.fn_proto.return_var_token == nullptr) { 9657 if (node->data.fn_proto.return_type == nullptr) { 9658 return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void); 9659 } else { 9660 return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope); 9661 if (return_type == irb->codegen->invalid_inst_src) 9662 return irb->codegen->invalid_inst_src; 9663 } 9664 } else { 9665 add_node_error(irb->codegen, node, 9666 buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447")); 9667 return irb->codegen->invalid_inst_src; 9668 //return_type = nullptr; 9669 } 9670 9671 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, callconv_value, return_type, is_var_args); 9672 } 9673 9674 static IrInstSrc *ir_gen_resume(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 9675 assert(node->type == NodeTypeResume); 9676 9677 IrInstSrc *target_inst = ir_gen_node_extra(irb, node->data.resume_expr.expr, scope, LValPtr, nullptr); 9678 if (target_inst == irb->codegen->invalid_inst_src) 9679 return irb->codegen->invalid_inst_src; 9680 9681 return ir_build_resume_src(irb, scope, node, target_inst); 9682 } 9683 9684 static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 9685 ResultLoc *result_loc) 9686 { 9687 assert(node->type == NodeTypeAwaitExpr); 9688 9689 bool is_noasync = node->data.await_expr.noasync_token != nullptr; 9690 9691 AstNode *expr_node = node->data.await_expr.expr; 9692 if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) { 9693 AstNode *fn_ref_expr = expr_node->data.fn_call_expr.fn_ref_expr; 9694 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 9695 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 9696 if (entry != nullptr) { 9697 BuiltinFnEntry *builtin_fn = entry->value; 9698 if (builtin_fn->id == BuiltinFnIdAsyncCall) { 9699 return ir_gen_async_call(irb, scope, node, expr_node, lval, result_loc); 9700 } 9701 } 9702 } 9703 9704 ZigFn *fn_entry = exec_fn_entry(irb->exec); 9705 if (!fn_entry) { 9706 add_node_error(irb->codegen, node, buf_sprintf("await outside function definition")); 9707 return irb->codegen->invalid_inst_src; 9708 } 9709 ScopeSuspend *existing_suspend_scope = get_scope_suspend(scope); 9710 if (existing_suspend_scope) { 9711 if (!existing_suspend_scope->reported_err) { 9712 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot await inside suspend block")); 9713 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("suspend block here")); 9714 existing_suspend_scope->reported_err = true; 9715 } 9716 return irb->codegen->invalid_inst_src; 9717 } 9718 9719 IrInstSrc *target_inst = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 9720 if (target_inst == irb->codegen->invalid_inst_src) 9721 return irb->codegen->invalid_inst_src; 9722 9723 IrInstSrc *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc, is_noasync); 9724 return ir_lval_wrap(irb, scope, await_inst, lval, result_loc); 9725 } 9726 9727 static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 9728 assert(node->type == NodeTypeSuspend); 9729 9730 ZigFn *fn_entry = exec_fn_entry(irb->exec); 9731 if (!fn_entry) { 9732 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition")); 9733 return irb->codegen->invalid_inst_src; 9734 } 9735 ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope); 9736 if (existing_suspend_scope) { 9737 if (!existing_suspend_scope->reported_err) { 9738 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside suspend block")); 9739 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here")); 9740 existing_suspend_scope->reported_err = true; 9741 } 9742 return irb->codegen->invalid_inst_src; 9743 } 9744 9745 IrInstSrcSuspendBegin *begin = ir_build_suspend_begin_src(irb, parent_scope, node); 9746 if (node->data.suspend.block != nullptr) { 9747 ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); 9748 Scope *child_scope = &suspend_scope->base; 9749 IrInstSrc *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope); 9750 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res)); 9751 } 9752 9753 return ir_mark_gen(ir_build_suspend_finish_src(irb, parent_scope, node, begin)); 9754 } 9755 9756 static IrInstSrc *ir_gen_node_raw(IrBuilderSrc *irb, AstNode *node, Scope *scope, 9757 LVal lval, ResultLoc *result_loc) 9758 { 9759 assert(scope); 9760 switch (node->type) { 9761 case NodeTypeStructValueField: 9762 case NodeTypeParamDecl: 9763 case NodeTypeUsingNamespace: 9764 case NodeTypeSwitchProng: 9765 case NodeTypeSwitchRange: 9766 case NodeTypeStructField: 9767 case NodeTypeErrorSetField: 9768 case NodeTypeFnDef: 9769 case NodeTypeTestDecl: 9770 zig_unreachable(); 9771 case NodeTypeBlock: 9772 return ir_gen_block(irb, scope, node, lval, result_loc); 9773 case NodeTypeGroupedExpr: 9774 return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc); 9775 case NodeTypeBinOpExpr: 9776 return ir_gen_bin_op(irb, scope, node, lval, result_loc); 9777 case NodeTypeIntLiteral: 9778 return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval, result_loc); 9779 case NodeTypeFloatLiteral: 9780 return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval, result_loc); 9781 case NodeTypeCharLiteral: 9782 return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval, result_loc); 9783 case NodeTypeSymbol: 9784 return ir_gen_symbol(irb, scope, node, lval, result_loc); 9785 case NodeTypeFnCallExpr: 9786 return ir_gen_fn_call(irb, scope, node, lval, result_loc); 9787 case NodeTypeIfBoolExpr: 9788 return ir_gen_if_bool_expr(irb, scope, node, lval, result_loc); 9789 case NodeTypePrefixOpExpr: 9790 return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc); 9791 case NodeTypeContainerInitExpr: 9792 return ir_gen_container_init_expr(irb, scope, node, lval, result_loc); 9793 case NodeTypeVariableDeclaration: 9794 return ir_gen_var_decl(irb, scope, node); 9795 case NodeTypeWhileExpr: 9796 return ir_gen_while_expr(irb, scope, node, lval, result_loc); 9797 case NodeTypeForExpr: 9798 return ir_gen_for_expr(irb, scope, node, lval, result_loc); 9799 case NodeTypeArrayAccessExpr: 9800 return ir_gen_array_access(irb, scope, node, lval, result_loc); 9801 case NodeTypeReturnExpr: 9802 return ir_gen_return(irb, scope, node, lval, result_loc); 9803 case NodeTypeFieldAccessExpr: 9804 { 9805 IrInstSrc *ptr_instruction = ir_gen_field_access(irb, scope, node); 9806 if (ptr_instruction == irb->codegen->invalid_inst_src) 9807 return ptr_instruction; 9808 if (lval == LValPtr) 9809 return ptr_instruction; 9810 9811 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 9812 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 9813 } 9814 case NodeTypePtrDeref: { 9815 AstNode *expr_node = node->data.ptr_deref_expr.target; 9816 IrInstSrc *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); 9817 if (value == irb->codegen->invalid_inst_src) 9818 return value; 9819 9820 // We essentially just converted any lvalue from &(x.*) to (&x).*; 9821 // this inhibits checking that x is a pointer later, so we directly 9822 // record whether the pointer check is needed 9823 IrInstSrc *un_op = ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval, result_loc); 9824 return ir_expr_wrap(irb, scope, un_op, result_loc); 9825 } 9826 case NodeTypeUnwrapOptional: { 9827 AstNode *expr_node = node->data.unwrap_optional.expr; 9828 9829 IrInstSrc *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 9830 if (maybe_ptr == irb->codegen->invalid_inst_src) 9831 return irb->codegen->invalid_inst_src; 9832 9833 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true, false); 9834 if (lval == LValPtr) 9835 return unwrapped_ptr; 9836 9837 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, unwrapped_ptr); 9838 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 9839 } 9840 case NodeTypeBoolLiteral: 9841 return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval, result_loc); 9842 case NodeTypeArrayType: 9843 return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc); 9844 case NodeTypePointerType: 9845 return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc); 9846 case NodeTypeAnyFrameType: 9847 return ir_lval_wrap(irb, scope, ir_gen_anyframe_type(irb, scope, node), lval, result_loc); 9848 case NodeTypeStringLiteral: 9849 return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc); 9850 case NodeTypeUndefinedLiteral: 9851 return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval, result_loc); 9852 case NodeTypeAsmExpr: 9853 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval, result_loc); 9854 case NodeTypeNullLiteral: 9855 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval, result_loc); 9856 case NodeTypeIfErrorExpr: 9857 return ir_gen_if_err_expr(irb, scope, node, lval, result_loc); 9858 case NodeTypeIfOptional: 9859 return ir_gen_if_optional_expr(irb, scope, node, lval, result_loc); 9860 case NodeTypeSwitchExpr: 9861 return ir_gen_switch_expr(irb, scope, node, lval, result_loc); 9862 case NodeTypeCompTime: 9863 return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc); 9864 case NodeTypeErrorType: 9865 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc); 9866 case NodeTypeBreak: 9867 return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval, result_loc); 9868 case NodeTypeContinue: 9869 return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc); 9870 case NodeTypeUnreachable: 9871 return ir_build_unreachable(irb, scope, node); 9872 case NodeTypeDefer: 9873 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc); 9874 case NodeTypeSliceExpr: 9875 return ir_gen_slice(irb, scope, node, lval, result_loc); 9876 case NodeTypeCatchExpr: 9877 return ir_gen_catch(irb, scope, node, lval, result_loc); 9878 case NodeTypeContainerDecl: 9879 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval, result_loc); 9880 case NodeTypeFnProto: 9881 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval, result_loc); 9882 case NodeTypeErrorSetDecl: 9883 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval, result_loc); 9884 case NodeTypeResume: 9885 return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval, result_loc); 9886 case NodeTypeAwaitExpr: 9887 return ir_gen_await_expr(irb, scope, node, lval, result_loc); 9888 case NodeTypeSuspend: 9889 return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval, result_loc); 9890 case NodeTypeEnumLiteral: 9891 return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval, result_loc); 9892 case NodeTypeInferredArrayType: 9893 add_node_error(irb->codegen, node, 9894 buf_sprintf("inferred array size invalid here")); 9895 return irb->codegen->invalid_inst_src; 9896 case NodeTypeVarFieldType: 9897 return ir_lval_wrap(irb, scope, 9898 ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_var), lval, result_loc); 9899 } 9900 zig_unreachable(); 9901 } 9902 9903 static ResultLoc *no_result_loc(void) { 9904 ResultLocNone *result_loc_none = heap::c_allocator.create<ResultLocNone>(); 9905 result_loc_none->base.id = ResultLocIdNone; 9906 return &result_loc_none->base; 9907 } 9908 9909 static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *scope, LVal lval, 9910 ResultLoc *result_loc) 9911 { 9912 if (result_loc == nullptr) { 9913 // Create a result location indicating there is none - but if one gets created 9914 // it will be properly distributed. 9915 result_loc = no_result_loc(); 9916 ir_build_reset_result(irb, scope, node, result_loc); 9917 } 9918 Scope *child_scope; 9919 if (irb->exec->is_inline || 9920 (irb->exec->fn_entry != nullptr && irb->exec->fn_entry->child_scope == scope)) 9921 { 9922 child_scope = scope; 9923 } else { 9924 child_scope = &create_expr_scope(irb->codegen, node, scope)->base; 9925 } 9926 IrInstSrc *result = ir_gen_node_raw(irb, node, child_scope, lval, result_loc); 9927 if (result == irb->codegen->invalid_inst_src) { 9928 if (irb->exec->first_err_trace_msg == nullptr) { 9929 irb->exec->first_err_trace_msg = irb->codegen->trace_err; 9930 } 9931 } 9932 return result; 9933 } 9934 9935 static IrInstSrc *ir_gen_node(IrBuilderSrc *irb, AstNode *node, Scope *scope) { 9936 return ir_gen_node_extra(irb, node, scope, LValNone, nullptr); 9937 } 9938 9939 static void invalidate_exec(IrExecutableSrc *exec, ErrorMsg *msg) { 9940 if (exec->first_err_trace_msg != nullptr) 9941 return; 9942 9943 exec->first_err_trace_msg = msg; 9944 9945 for (size_t i = 0; i < exec->tld_list.length; i += 1) { 9946 exec->tld_list.items[i]->resolution = TldResolutionInvalid; 9947 } 9948 } 9949 9950 static void invalidate_exec_gen(IrExecutableGen *exec, ErrorMsg *msg) { 9951 if (exec->first_err_trace_msg != nullptr) 9952 return; 9953 9954 exec->first_err_trace_msg = msg; 9955 9956 for (size_t i = 0; i < exec->tld_list.length; i += 1) { 9957 exec->tld_list.items[i]->resolution = TldResolutionInvalid; 9958 } 9959 9960 if (exec->source_exec != nullptr) 9961 invalidate_exec(exec->source_exec, msg); 9962 } 9963 9964 9965 bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutableSrc *ir_executable) { 9966 assert(node->owner); 9967 9968 IrBuilderSrc ir_builder = {0}; 9969 IrBuilderSrc *irb = &ir_builder; 9970 9971 irb->codegen = codegen; 9972 irb->exec = ir_executable; 9973 irb->main_block_node = node; 9974 9975 IrBasicBlockSrc *entry_block = ir_create_basic_block(irb, scope, "Entry"); 9976 ir_set_cursor_at_end_and_append_block(irb, entry_block); 9977 // Entry block gets a reference because we enter it to begin. 9978 ir_ref_bb(irb->current_basic_block); 9979 9980 IrInstSrc *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); 9981 9982 if (result == irb->codegen->invalid_inst_src) 9983 return false; 9984 9985 if (irb->exec->first_err_trace_msg != nullptr) { 9986 codegen->trace_err = irb->exec->first_err_trace_msg; 9987 return false; 9988 } 9989 9990 if (!instr_is_unreachable(result)) { 9991 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->base.source_node, result, nullptr)); 9992 // no need for save_err_ret_addr because this cannot return error 9993 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>(); 9994 result_loc_ret->base.id = ResultLocIdReturn; 9995 ir_build_reset_result(irb, scope, node, &result_loc_ret->base); 9996 ir_mark_gen(ir_build_end_expr(irb, scope, node, result, &result_loc_ret->base)); 9997 ir_mark_gen(ir_build_return_src(irb, scope, result->base.source_node, result)); 9998 } 9999 10000 return true; 10001 } 10002 10003 bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) { 10004 assert(fn_entry); 10005 10006 IrExecutableSrc *ir_executable = fn_entry->ir_executable; 10007 AstNode *body_node = fn_entry->body_node; 10008 10009 assert(fn_entry->child_scope); 10010 10011 return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable); 10012 } 10013 10014 static void ir_add_call_stack_errors_gen(CodeGen *codegen, IrExecutableGen *exec, ErrorMsg *err_msg, int limit) { 10015 if (!exec || !exec->source_node || limit < 0) return; 10016 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); 10017 10018 ir_add_call_stack_errors_gen(codegen, exec->parent_exec, err_msg, limit - 1); 10019 } 10020 10021 static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutableSrc *exec, ErrorMsg *err_msg, int limit) { 10022 if (!exec || !exec->source_node || limit < 0) return; 10023 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); 10024 10025 ir_add_call_stack_errors_gen(codegen, exec->parent_exec, err_msg, limit - 1); 10026 } 10027 10028 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutableSrc *exec, AstNode *source_node, Buf *msg) { 10029 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); 10030 invalidate_exec(exec, err_msg); 10031 if (exec->parent_exec) { 10032 ir_add_call_stack_errors(codegen, exec, err_msg, 10); 10033 } 10034 return err_msg; 10035 } 10036 10037 static ErrorMsg *exec_add_error_node_gen(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, Buf *msg) { 10038 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); 10039 invalidate_exec_gen(exec, err_msg); 10040 if (exec->parent_exec) { 10041 ir_add_call_stack_errors_gen(codegen, exec, err_msg, 10); 10042 } 10043 return err_msg; 10044 } 10045 10046 static ErrorMsg *ir_add_error_node(IrAnalyze *ira, AstNode *source_node, Buf *msg) { 10047 return exec_add_error_node_gen(ira->codegen, ira->new_irb.exec, source_node, msg); 10048 } 10049 10050 static ErrorMsg *opt_ir_add_error_node(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, Buf *msg) { 10051 if (ira != nullptr) 10052 return exec_add_error_node_gen(codegen, ira->new_irb.exec, source_node, msg); 10053 else 10054 return add_node_error(codegen, source_node, msg); 10055 } 10056 10057 static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInst *source_instruction, Buf *msg) { 10058 return ir_add_error_node(ira, source_instruction->source_node, msg); 10059 } 10060 10061 static void ir_assert(bool ok, IrInst *source_instruction) { 10062 if (ok) return; 10063 src_assert(ok, source_instruction->source_node); 10064 } 10065 10066 static void ir_assert_gen(bool ok, IrInstGen *source_instruction) { 10067 if (ok) return; 10068 src_assert(ok, source_instruction->base.source_node); 10069 } 10070 10071 // This function takes a comptime ptr and makes the child const value conform to the type 10072 // described by the pointer. 10073 static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 10074 ZigValue *ptr_val) 10075 { 10076 Error err; 10077 assert(ptr_val->type->id == ZigTypeIdPointer); 10078 assert(ptr_val->special == ConstValSpecialStatic); 10079 ZigValue tmp = {}; 10080 tmp.special = ConstValSpecialStatic; 10081 tmp.type = ptr_val->type->data.pointer.child_type; 10082 if ((err = ir_read_const_ptr(ira, codegen, source_node, &tmp, ptr_val))) 10083 return err; 10084 ZigValue *child_val = const_ptr_pointee_unchecked(codegen, ptr_val); 10085 copy_const_val(codegen, child_val, &tmp); 10086 return ErrorNone; 10087 } 10088 10089 ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val, 10090 AstNode *source_node) 10091 { 10092 Error err; 10093 ZigValue *val = const_ptr_pointee_unchecked(codegen, const_val); 10094 if (val == nullptr) return nullptr; 10095 assert(const_val->type->id == ZigTypeIdPointer); 10096 ZigType *expected_type = const_val->type->data.pointer.child_type; 10097 if (expected_type == codegen->builtin_types.entry_var) { 10098 return val; 10099 } 10100 switch (type_has_one_possible_value(codegen, expected_type)) { 10101 case OnePossibleValueInvalid: 10102 return nullptr; 10103 case OnePossibleValueNo: 10104 break; 10105 case OnePossibleValueYes: 10106 return get_the_one_possible_value(codegen, expected_type); 10107 } 10108 if (!types_have_same_zig_comptime_repr(codegen, expected_type, val->type)) { 10109 if ((err = eval_comptime_ptr_reinterpret(ira, codegen, source_node, const_val))) 10110 return nullptr; 10111 return const_ptr_pointee_unchecked(codegen, const_val); 10112 } 10113 return val; 10114 } 10115 10116 static Error ir_exec_scan_for_side_effects(CodeGen *codegen, IrExecutableGen *exec) { 10117 IrBasicBlockGen *bb = exec->basic_block_list.at(0); 10118 for (size_t i = 0; i < bb->instruction_list.length; i += 1) { 10119 IrInstGen *instruction = bb->instruction_list.at(i); 10120 if (instruction->id == IrInstGenIdReturn) { 10121 return ErrorNone; 10122 } else if (ir_inst_gen_has_side_effects(instruction)) { 10123 if (instr_is_comptime(instruction)) { 10124 switch (instruction->id) { 10125 case IrInstGenIdUnwrapErrPayload: 10126 case IrInstGenIdOptionalUnwrapPtr: 10127 case IrInstGenIdUnionFieldPtr: 10128 continue; 10129 default: 10130 break; 10131 } 10132 } 10133 if (get_scope_typeof(instruction->base.scope) != nullptr) { 10134 // doesn't count, it's inside a @TypeOf() 10135 continue; 10136 } 10137 exec_add_error_node_gen(codegen, exec, instruction->base.source_node, 10138 buf_sprintf("unable to evaluate constant expression")); 10139 return ErrorSemanticAnalyzeFail; 10140 } 10141 } 10142 zig_unreachable(); 10143 } 10144 10145 static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInst* source_instruction) { 10146 if (ir_should_inline(ira->old_irb.exec, source_instruction->scope)) { 10147 ir_add_error(ira, source_instruction, buf_sprintf("unable to evaluate constant expression")); 10148 return false; 10149 } 10150 return true; 10151 } 10152 10153 static bool const_val_fits_in_num_lit(ZigValue *const_val, ZigType *num_lit_type) { 10154 return ((num_lit_type->id == ZigTypeIdComptimeFloat && 10155 (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat)) || 10156 (num_lit_type->id == ZigTypeIdComptimeInt && 10157 (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt))); 10158 } 10159 10160 static bool float_has_fraction(ZigValue *const_val) { 10161 if (const_val->type->id == ZigTypeIdComptimeFloat) { 10162 return bigfloat_has_fraction(&const_val->data.x_bigfloat); 10163 } else if (const_val->type->id == ZigTypeIdFloat) { 10164 switch (const_val->type->data.floating.bit_count) { 10165 case 16: 10166 { 10167 float16_t floored = f16_roundToInt(const_val->data.x_f16, softfloat_round_minMag, false); 10168 return !f16_eq(floored, const_val->data.x_f16); 10169 } 10170 case 32: 10171 return floorf(const_val->data.x_f32) != const_val->data.x_f32; 10172 case 64: 10173 return floor(const_val->data.x_f64) != const_val->data.x_f64; 10174 case 128: 10175 { 10176 float128_t floored; 10177 f128M_roundToInt(&const_val->data.x_f128, softfloat_round_minMag, false, &floored); 10178 return !f128M_eq(&floored, &const_val->data.x_f128); 10179 } 10180 default: 10181 zig_unreachable(); 10182 } 10183 } else { 10184 zig_unreachable(); 10185 } 10186 } 10187 10188 static void float_append_buf(Buf *buf, ZigValue *const_val) { 10189 if (const_val->type->id == ZigTypeIdComptimeFloat) { 10190 bigfloat_append_buf(buf, &const_val->data.x_bigfloat); 10191 } else if (const_val->type->id == ZigTypeIdFloat) { 10192 switch (const_val->type->data.floating.bit_count) { 10193 case 16: 10194 buf_appendf(buf, "%f", zig_f16_to_double(const_val->data.x_f16)); 10195 break; 10196 case 32: 10197 buf_appendf(buf, "%f", const_val->data.x_f32); 10198 break; 10199 case 64: 10200 buf_appendf(buf, "%f", const_val->data.x_f64); 10201 break; 10202 case 128: 10203 { 10204 // TODO actual implementation 10205 const size_t extra_len = 100; 10206 size_t old_len = buf_len(buf); 10207 buf_resize(buf, old_len + extra_len); 10208 10209 float64_t f64_value = f128M_to_f64(&const_val->data.x_f128); 10210 double double_value; 10211 memcpy(&double_value, &f64_value, sizeof(double)); 10212 10213 int len = snprintf(buf_ptr(buf) + old_len, extra_len, "%f", double_value); 10214 assert(len > 0); 10215 buf_resize(buf, old_len + len); 10216 break; 10217 } 10218 default: 10219 zig_unreachable(); 10220 } 10221 } else { 10222 zig_unreachable(); 10223 } 10224 } 10225 10226 static void float_init_bigint(BigInt *bigint, ZigValue *const_val) { 10227 if (const_val->type->id == ZigTypeIdComptimeFloat) { 10228 bigint_init_bigfloat(bigint, &const_val->data.x_bigfloat); 10229 } else if (const_val->type->id == ZigTypeIdFloat) { 10230 switch (const_val->type->data.floating.bit_count) { 10231 case 16: 10232 { 10233 double x = zig_f16_to_double(const_val->data.x_f16); 10234 if (x >= 0) { 10235 bigint_init_unsigned(bigint, (uint64_t)x); 10236 } else { 10237 bigint_init_unsigned(bigint, (uint64_t)-x); 10238 bigint->is_negative = true; 10239 } 10240 break; 10241 } 10242 case 32: 10243 if (const_val->data.x_f32 >= 0) { 10244 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f32)); 10245 } else { 10246 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f32)); 10247 bigint->is_negative = true; 10248 } 10249 break; 10250 case 64: 10251 if (const_val->data.x_f64 >= 0) { 10252 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f64)); 10253 } else { 10254 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f64)); 10255 bigint->is_negative = true; 10256 } 10257 break; 10258 case 128: 10259 { 10260 BigFloat tmp_float; 10261 bigfloat_init_128(&tmp_float, const_val->data.x_f128); 10262 bigint_init_bigfloat(bigint, &tmp_float); 10263 } 10264 break; 10265 default: 10266 zig_unreachable(); 10267 } 10268 } else { 10269 zig_unreachable(); 10270 } 10271 } 10272 10273 static void float_init_bigfloat(ZigValue *dest_val, BigFloat *bigfloat) { 10274 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10275 bigfloat_init_bigfloat(&dest_val->data.x_bigfloat, bigfloat); 10276 } else if (dest_val->type->id == ZigTypeIdFloat) { 10277 switch (dest_val->type->data.floating.bit_count) { 10278 case 16: 10279 dest_val->data.x_f16 = bigfloat_to_f16(bigfloat); 10280 break; 10281 case 32: 10282 dest_val->data.x_f32 = bigfloat_to_f32(bigfloat); 10283 break; 10284 case 64: 10285 dest_val->data.x_f64 = bigfloat_to_f64(bigfloat); 10286 break; 10287 case 80: 10288 zig_panic("TODO"); 10289 case 128: 10290 dest_val->data.x_f128 = bigfloat_to_f128(bigfloat); 10291 break; 10292 default: 10293 zig_unreachable(); 10294 } 10295 } else { 10296 zig_unreachable(); 10297 } 10298 } 10299 10300 static void float_init_f16(ZigValue *dest_val, float16_t x) { 10301 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10302 bigfloat_init_16(&dest_val->data.x_bigfloat, x); 10303 } else if (dest_val->type->id == ZigTypeIdFloat) { 10304 switch (dest_val->type->data.floating.bit_count) { 10305 case 16: 10306 dest_val->data.x_f16 = x; 10307 break; 10308 case 32: 10309 dest_val->data.x_f32 = zig_f16_to_double(x); 10310 break; 10311 case 64: 10312 dest_val->data.x_f64 = zig_f16_to_double(x); 10313 break; 10314 case 128: 10315 f16_to_f128M(x, &dest_val->data.x_f128); 10316 break; 10317 default: 10318 zig_unreachable(); 10319 } 10320 } else { 10321 zig_unreachable(); 10322 } 10323 } 10324 10325 static void float_init_f32(ZigValue *dest_val, float x) { 10326 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10327 bigfloat_init_32(&dest_val->data.x_bigfloat, x); 10328 } else if (dest_val->type->id == ZigTypeIdFloat) { 10329 switch (dest_val->type->data.floating.bit_count) { 10330 case 16: 10331 dest_val->data.x_f16 = zig_double_to_f16(x); 10332 break; 10333 case 32: 10334 dest_val->data.x_f32 = x; 10335 break; 10336 case 64: 10337 dest_val->data.x_f64 = x; 10338 break; 10339 case 128: 10340 { 10341 float32_t x_f32; 10342 memcpy(&x_f32, &x, sizeof(float)); 10343 f32_to_f128M(x_f32, &dest_val->data.x_f128); 10344 break; 10345 } 10346 default: 10347 zig_unreachable(); 10348 } 10349 } else { 10350 zig_unreachable(); 10351 } 10352 } 10353 10354 static void float_init_f64(ZigValue *dest_val, double x) { 10355 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10356 bigfloat_init_64(&dest_val->data.x_bigfloat, x); 10357 } else if (dest_val->type->id == ZigTypeIdFloat) { 10358 switch (dest_val->type->data.floating.bit_count) { 10359 case 16: 10360 dest_val->data.x_f16 = zig_double_to_f16(x); 10361 break; 10362 case 32: 10363 dest_val->data.x_f32 = x; 10364 break; 10365 case 64: 10366 dest_val->data.x_f64 = x; 10367 break; 10368 case 128: 10369 { 10370 float64_t x_f64; 10371 memcpy(&x_f64, &x, sizeof(double)); 10372 f64_to_f128M(x_f64, &dest_val->data.x_f128); 10373 break; 10374 } 10375 default: 10376 zig_unreachable(); 10377 } 10378 } else { 10379 zig_unreachable(); 10380 } 10381 } 10382 10383 static void float_init_f128(ZigValue *dest_val, float128_t x) { 10384 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10385 bigfloat_init_128(&dest_val->data.x_bigfloat, x); 10386 } else if (dest_val->type->id == ZigTypeIdFloat) { 10387 switch (dest_val->type->data.floating.bit_count) { 10388 case 16: 10389 dest_val->data.x_f16 = f128M_to_f16(&x); 10390 break; 10391 case 32: 10392 { 10393 float32_t f32_val = f128M_to_f32(&x); 10394 memcpy(&dest_val->data.x_f32, &f32_val, sizeof(float)); 10395 break; 10396 } 10397 case 64: 10398 { 10399 float64_t f64_val = f128M_to_f64(&x); 10400 memcpy(&dest_val->data.x_f64, &f64_val, sizeof(double)); 10401 break; 10402 } 10403 case 128: 10404 { 10405 memcpy(&dest_val->data.x_f128, &x, sizeof(float128_t)); 10406 break; 10407 } 10408 default: 10409 zig_unreachable(); 10410 } 10411 } else { 10412 zig_unreachable(); 10413 } 10414 } 10415 10416 static void float_init_float(ZigValue *dest_val, ZigValue *src_val) { 10417 if (src_val->type->id == ZigTypeIdComptimeFloat) { 10418 float_init_bigfloat(dest_val, &src_val->data.x_bigfloat); 10419 } else if (src_val->type->id == ZigTypeIdFloat) { 10420 switch (src_val->type->data.floating.bit_count) { 10421 case 16: 10422 float_init_f16(dest_val, src_val->data.x_f16); 10423 break; 10424 case 32: 10425 float_init_f32(dest_val, src_val->data.x_f32); 10426 break; 10427 case 64: 10428 float_init_f64(dest_val, src_val->data.x_f64); 10429 break; 10430 case 128: 10431 float_init_f128(dest_val, src_val->data.x_f128); 10432 break; 10433 default: 10434 zig_unreachable(); 10435 } 10436 } else { 10437 zig_unreachable(); 10438 } 10439 } 10440 10441 static bool float_is_nan(ZigValue *op) { 10442 if (op->type->id == ZigTypeIdComptimeFloat) { 10443 return bigfloat_is_nan(&op->data.x_bigfloat); 10444 } else if (op->type->id == ZigTypeIdFloat) { 10445 switch (op->type->data.floating.bit_count) { 10446 case 16: 10447 return f16_isSignalingNaN(op->data.x_f16); 10448 case 32: 10449 return op->data.x_f32 != op->data.x_f32; 10450 case 64: 10451 return op->data.x_f64 != op->data.x_f64; 10452 case 128: 10453 return f128M_isSignalingNaN(&op->data.x_f128); 10454 default: 10455 zig_unreachable(); 10456 } 10457 } else { 10458 zig_unreachable(); 10459 } 10460 } 10461 10462 static Cmp float_cmp(ZigValue *op1, ZigValue *op2) { 10463 if (op1->type == op2->type) { 10464 if (op1->type->id == ZigTypeIdComptimeFloat) { 10465 return bigfloat_cmp(&op1->data.x_bigfloat, &op2->data.x_bigfloat); 10466 } else if (op1->type->id == ZigTypeIdFloat) { 10467 switch (op1->type->data.floating.bit_count) { 10468 case 16: 10469 if (f16_lt(op1->data.x_f16, op2->data.x_f16)) { 10470 return CmpLT; 10471 } else if (f16_lt(op2->data.x_f16, op1->data.x_f16)) { 10472 return CmpGT; 10473 } else { 10474 return CmpEQ; 10475 } 10476 case 32: 10477 if (op1->data.x_f32 > op2->data.x_f32) { 10478 return CmpGT; 10479 } else if (op1->data.x_f32 < op2->data.x_f32) { 10480 return CmpLT; 10481 } else { 10482 return CmpEQ; 10483 } 10484 case 64: 10485 if (op1->data.x_f64 > op2->data.x_f64) { 10486 return CmpGT; 10487 } else if (op1->data.x_f64 < op2->data.x_f64) { 10488 return CmpLT; 10489 } else { 10490 return CmpEQ; 10491 } 10492 case 128: 10493 if (f128M_lt(&op1->data.x_f128, &op2->data.x_f128)) { 10494 return CmpLT; 10495 } else if (f128M_eq(&op1->data.x_f128, &op2->data.x_f128)) { 10496 return CmpEQ; 10497 } else { 10498 return CmpGT; 10499 } 10500 default: 10501 zig_unreachable(); 10502 } 10503 } else { 10504 zig_unreachable(); 10505 } 10506 } 10507 BigFloat op1_big; 10508 BigFloat op2_big; 10509 float_init_bigfloat(op1, &op1_big); 10510 float_init_bigfloat(op2, &op2_big); 10511 return bigfloat_cmp(&op1_big, &op2_big); 10512 } 10513 10514 // This function cannot handle NaN 10515 static Cmp float_cmp_zero(ZigValue *op) { 10516 if (op->type->id == ZigTypeIdComptimeFloat) { 10517 return bigfloat_cmp_zero(&op->data.x_bigfloat); 10518 } else if (op->type->id == ZigTypeIdFloat) { 10519 switch (op->type->data.floating.bit_count) { 10520 case 16: 10521 { 10522 const float16_t zero = zig_double_to_f16(0); 10523 if (f16_lt(op->data.x_f16, zero)) { 10524 return CmpLT; 10525 } else if (f16_lt(zero, op->data.x_f16)) { 10526 return CmpGT; 10527 } else { 10528 return CmpEQ; 10529 } 10530 } 10531 case 32: 10532 if (op->data.x_f32 < 0.0) { 10533 return CmpLT; 10534 } else if (op->data.x_f32 > 0.0) { 10535 return CmpGT; 10536 } else { 10537 return CmpEQ; 10538 } 10539 case 64: 10540 if (op->data.x_f64 < 0.0) { 10541 return CmpLT; 10542 } else if (op->data.x_f64 > 0.0) { 10543 return CmpGT; 10544 } else { 10545 return CmpEQ; 10546 } 10547 case 128: 10548 float128_t zero_float; 10549 ui32_to_f128M(0, &zero_float); 10550 if (f128M_lt(&op->data.x_f128, &zero_float)) { 10551 return CmpLT; 10552 } else if (f128M_eq(&op->data.x_f128, &zero_float)) { 10553 return CmpEQ; 10554 } else { 10555 return CmpGT; 10556 } 10557 default: 10558 zig_unreachable(); 10559 } 10560 } else { 10561 zig_unreachable(); 10562 } 10563 } 10564 10565 static void float_add(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 10566 assert(op1->type == op2->type); 10567 out_val->type = op1->type; 10568 if (op1->type->id == ZigTypeIdComptimeFloat) { 10569 bigfloat_add(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 10570 } else if (op1->type->id == ZigTypeIdFloat) { 10571 switch (op1->type->data.floating.bit_count) { 10572 case 16: 10573 out_val->data.x_f16 = f16_add(op1->data.x_f16, op2->data.x_f16); 10574 return; 10575 case 32: 10576 out_val->data.x_f32 = op1->data.x_f32 + op2->data.x_f32; 10577 return; 10578 case 64: 10579 out_val->data.x_f64 = op1->data.x_f64 + op2->data.x_f64; 10580 return; 10581 case 128: 10582 f128M_add(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 10583 return; 10584 default: 10585 zig_unreachable(); 10586 } 10587 } else { 10588 zig_unreachable(); 10589 } 10590 } 10591 10592 static void float_sub(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 10593 assert(op1->type == op2->type); 10594 out_val->type = op1->type; 10595 if (op1->type->id == ZigTypeIdComptimeFloat) { 10596 bigfloat_sub(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 10597 } else if (op1->type->id == ZigTypeIdFloat) { 10598 switch (op1->type->data.floating.bit_count) { 10599 case 16: 10600 out_val->data.x_f16 = f16_sub(op1->data.x_f16, op2->data.x_f16); 10601 return; 10602 case 32: 10603 out_val->data.x_f32 = op1->data.x_f32 - op2->data.x_f32; 10604 return; 10605 case 64: 10606 out_val->data.x_f64 = op1->data.x_f64 - op2->data.x_f64; 10607 return; 10608 case 128: 10609 f128M_sub(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 10610 return; 10611 default: 10612 zig_unreachable(); 10613 } 10614 } else { 10615 zig_unreachable(); 10616 } 10617 } 10618 10619 static void float_mul(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 10620 assert(op1->type == op2->type); 10621 out_val->type = op1->type; 10622 if (op1->type->id == ZigTypeIdComptimeFloat) { 10623 bigfloat_mul(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 10624 } else if (op1->type->id == ZigTypeIdFloat) { 10625 switch (op1->type->data.floating.bit_count) { 10626 case 16: 10627 out_val->data.x_f16 = f16_mul(op1->data.x_f16, op2->data.x_f16); 10628 return; 10629 case 32: 10630 out_val->data.x_f32 = op1->data.x_f32 * op2->data.x_f32; 10631 return; 10632 case 64: 10633 out_val->data.x_f64 = op1->data.x_f64 * op2->data.x_f64; 10634 return; 10635 case 128: 10636 f128M_mul(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 10637 return; 10638 default: 10639 zig_unreachable(); 10640 } 10641 } else { 10642 zig_unreachable(); 10643 } 10644 } 10645 10646 static void float_div(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 10647 assert(op1->type == op2->type); 10648 out_val->type = op1->type; 10649 if (op1->type->id == ZigTypeIdComptimeFloat) { 10650 bigfloat_div(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 10651 } else if (op1->type->id == ZigTypeIdFloat) { 10652 switch (op1->type->data.floating.bit_count) { 10653 case 16: 10654 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 10655 return; 10656 case 32: 10657 out_val->data.x_f32 = op1->data.x_f32 / op2->data.x_f32; 10658 return; 10659 case 64: 10660 out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64; 10661 return; 10662 case 128: 10663 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 10664 return; 10665 default: 10666 zig_unreachable(); 10667 } 10668 } else { 10669 zig_unreachable(); 10670 } 10671 } 10672 10673 static void float_div_trunc(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 10674 assert(op1->type == op2->type); 10675 out_val->type = op1->type; 10676 if (op1->type->id == ZigTypeIdComptimeFloat) { 10677 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 10678 } else if (op1->type->id == ZigTypeIdFloat) { 10679 switch (op1->type->data.floating.bit_count) { 10680 case 16: 10681 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 10682 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_minMag, false); 10683 return; 10684 case 32: 10685 out_val->data.x_f32 = truncf(op1->data.x_f32 / op2->data.x_f32); 10686 return; 10687 case 64: 10688 out_val->data.x_f64 = trunc(op1->data.x_f64 / op2->data.x_f64); 10689 return; 10690 case 128: 10691 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 10692 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_minMag, false, &out_val->data.x_f128); 10693 return; 10694 default: 10695 zig_unreachable(); 10696 } 10697 } else { 10698 zig_unreachable(); 10699 } 10700 } 10701 10702 static void float_div_floor(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 10703 assert(op1->type == op2->type); 10704 out_val->type = op1->type; 10705 if (op1->type->id == ZigTypeIdComptimeFloat) { 10706 bigfloat_div_floor(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 10707 } else if (op1->type->id == ZigTypeIdFloat) { 10708 switch (op1->type->data.floating.bit_count) { 10709 case 16: 10710 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 10711 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_min, false); 10712 return; 10713 case 32: 10714 out_val->data.x_f32 = floorf(op1->data.x_f32 / op2->data.x_f32); 10715 return; 10716 case 64: 10717 out_val->data.x_f64 = floor(op1->data.x_f64 / op2->data.x_f64); 10718 return; 10719 case 128: 10720 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 10721 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_min, false, &out_val->data.x_f128); 10722 return; 10723 default: 10724 zig_unreachable(); 10725 } 10726 } else { 10727 zig_unreachable(); 10728 } 10729 } 10730 10731 static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 10732 assert(op1->type == op2->type); 10733 out_val->type = op1->type; 10734 if (op1->type->id == ZigTypeIdComptimeFloat) { 10735 bigfloat_rem(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 10736 } else if (op1->type->id == ZigTypeIdFloat) { 10737 switch (op1->type->data.floating.bit_count) { 10738 case 16: 10739 out_val->data.x_f16 = f16_rem(op1->data.x_f16, op2->data.x_f16); 10740 return; 10741 case 32: 10742 out_val->data.x_f32 = fmodf(op1->data.x_f32, op2->data.x_f32); 10743 return; 10744 case 64: 10745 out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64); 10746 return; 10747 case 128: 10748 f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 10749 return; 10750 default: 10751 zig_unreachable(); 10752 } 10753 } else { 10754 zig_unreachable(); 10755 } 10756 } 10757 10758 // c = a - b * trunc(a / b) 10759 static float16_t zig_f16_mod(float16_t a, float16_t b) { 10760 float16_t c; 10761 c = f16_div(a, b); 10762 c = f16_roundToInt(c, softfloat_round_min, true); 10763 c = f16_mul(b, c); 10764 c = f16_sub(a, c); 10765 return c; 10766 } 10767 10768 // c = a - b * trunc(a / b) 10769 static void zig_f128M_mod(const float128_t* a, const float128_t* b, float128_t* c) { 10770 f128M_div(a, b, c); 10771 f128M_roundToInt(c, softfloat_round_min, true, c); 10772 f128M_mul(b, c, c); 10773 f128M_sub(a, c, c); 10774 } 10775 10776 static void float_mod(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 10777 assert(op1->type == op2->type); 10778 out_val->type = op1->type; 10779 if (op1->type->id == ZigTypeIdComptimeFloat) { 10780 bigfloat_mod(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 10781 } else if (op1->type->id == ZigTypeIdFloat) { 10782 switch (op1->type->data.floating.bit_count) { 10783 case 16: 10784 out_val->data.x_f16 = zig_f16_mod(op1->data.x_f16, op2->data.x_f16); 10785 return; 10786 case 32: 10787 out_val->data.x_f32 = fmodf(fmodf(op1->data.x_f32, op2->data.x_f32) + op2->data.x_f32, op2->data.x_f32); 10788 return; 10789 case 64: 10790 out_val->data.x_f64 = fmod(fmod(op1->data.x_f64, op2->data.x_f64) + op2->data.x_f64, op2->data.x_f64); 10791 return; 10792 case 128: 10793 zig_f128M_mod(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 10794 return; 10795 default: 10796 zig_unreachable(); 10797 } 10798 } else { 10799 zig_unreachable(); 10800 } 10801 } 10802 10803 static void float_negate(ZigValue *out_val, ZigValue *op) { 10804 out_val->type = op->type; 10805 if (op->type->id == ZigTypeIdComptimeFloat) { 10806 bigfloat_negate(&out_val->data.x_bigfloat, &op->data.x_bigfloat); 10807 } else if (op->type->id == ZigTypeIdFloat) { 10808 switch (op->type->data.floating.bit_count) { 10809 case 16: 10810 { 10811 const float16_t zero = zig_double_to_f16(0); 10812 out_val->data.x_f16 = f16_sub(zero, op->data.x_f16); 10813 return; 10814 } 10815 case 32: 10816 out_val->data.x_f32 = -op->data.x_f32; 10817 return; 10818 case 64: 10819 out_val->data.x_f64 = -op->data.x_f64; 10820 return; 10821 case 128: 10822 float128_t zero_f128; 10823 ui32_to_f128M(0, &zero_f128); 10824 f128M_sub(&zero_f128, &op->data.x_f128, &out_val->data.x_f128); 10825 return; 10826 default: 10827 zig_unreachable(); 10828 } 10829 } else { 10830 zig_unreachable(); 10831 } 10832 } 10833 10834 void float_write_ieee597(ZigValue *op, uint8_t *buf, bool is_big_endian) { 10835 if (op->type->id == ZigTypeIdFloat) { 10836 switch (op->type->data.floating.bit_count) { 10837 case 16: 10838 memcpy(buf, &op->data.x_f16, 2); // TODO wrong when compiler is big endian 10839 return; 10840 case 32: 10841 memcpy(buf, &op->data.x_f32, 4); // TODO wrong when compiler is big endian 10842 return; 10843 case 64: 10844 memcpy(buf, &op->data.x_f64, 8); // TODO wrong when compiler is big endian 10845 return; 10846 case 128: 10847 memcpy(buf, &op->data.x_f128, 16); // TODO wrong when compiler is big endian 10848 return; 10849 default: 10850 zig_unreachable(); 10851 } 10852 } else { 10853 zig_unreachable(); 10854 } 10855 } 10856 10857 void float_read_ieee597(ZigValue *val, uint8_t *buf, bool is_big_endian) { 10858 if (val->type->id == ZigTypeIdFloat) { 10859 switch (val->type->data.floating.bit_count) { 10860 case 16: 10861 memcpy(&val->data.x_f16, buf, 2); // TODO wrong when compiler is big endian 10862 return; 10863 case 32: 10864 memcpy(&val->data.x_f32, buf, 4); // TODO wrong when compiler is big endian 10865 return; 10866 case 64: 10867 memcpy(&val->data.x_f64, buf, 8); // TODO wrong when compiler is big endian 10868 return; 10869 case 128: 10870 memcpy(&val->data.x_f128, buf, 16); // TODO wrong when compiler is big endian 10871 return; 10872 default: 10873 zig_unreachable(); 10874 } 10875 } else { 10876 zig_unreachable(); 10877 } 10878 } 10879 10880 static void value_to_bigfloat(BigFloat *out, ZigValue *val) { 10881 switch (val->type->id) { 10882 case ZigTypeIdInt: 10883 case ZigTypeIdComptimeInt: 10884 bigfloat_init_bigint(out, &val->data.x_bigint); 10885 return; 10886 case ZigTypeIdComptimeFloat: 10887 *out = val->data.x_bigfloat; 10888 return; 10889 case ZigTypeIdFloat: switch (val->type->data.floating.bit_count) { 10890 case 16: 10891 bigfloat_init_16(out, val->data.x_f16); 10892 return; 10893 case 32: 10894 bigfloat_init_32(out, val->data.x_f32); 10895 return; 10896 case 64: 10897 bigfloat_init_64(out, val->data.x_f64); 10898 return; 10899 case 80: 10900 zig_panic("TODO"); 10901 case 128: 10902 bigfloat_init_128(out, val->data.x_f128); 10903 return; 10904 default: 10905 zig_unreachable(); 10906 } 10907 default: 10908 zig_unreachable(); 10909 } 10910 } 10911 10912 static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstGen *instruction, ZigType *other_type, 10913 bool explicit_cast) 10914 { 10915 if (type_is_invalid(other_type)) { 10916 return false; 10917 } 10918 10919 ZigValue *const_val = ir_resolve_const(ira, instruction, LazyOkNoUndef); 10920 if (const_val == nullptr) 10921 return false; 10922 10923 if (const_val->special == ConstValSpecialLazy) { 10924 switch (const_val->data.x_lazy->id) { 10925 case LazyValueIdAlignOf: { 10926 // This is guaranteed to fit into a u29 10927 if (other_type->id == ZigTypeIdComptimeInt) 10928 return true; 10929 size_t align_bits = get_align_amt_type(ira->codegen)->data.integral.bit_count; 10930 if (other_type->id == ZigTypeIdInt && !other_type->data.integral.is_signed && 10931 other_type->data.integral.bit_count >= align_bits) 10932 { 10933 return true; 10934 } 10935 break; 10936 } 10937 case LazyValueIdSizeOf: { 10938 // This is guaranteed to fit into a usize 10939 if (other_type->id == ZigTypeIdComptimeInt) 10940 return true; 10941 size_t usize_bits = ira->codegen->builtin_types.entry_usize->data.integral.bit_count; 10942 if (other_type->id == ZigTypeIdInt && !other_type->data.integral.is_signed && 10943 other_type->data.integral.bit_count >= usize_bits) 10944 { 10945 return true; 10946 } 10947 break; 10948 } 10949 default: 10950 break; 10951 } 10952 } 10953 10954 const_val = ir_resolve_const(ira, instruction, UndefBad); 10955 if (const_val == nullptr) 10956 return false; 10957 10958 bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt); 10959 bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat); 10960 assert(const_val_is_int || const_val_is_float); 10961 10962 if (const_val_is_int && other_type->id == ZigTypeIdComptimeFloat) { 10963 return true; 10964 } 10965 if (other_type->id == ZigTypeIdFloat) { 10966 if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) { 10967 return true; 10968 } 10969 if (const_val->type->id == ZigTypeIdInt) { 10970 BigFloat tmp_bf; 10971 bigfloat_init_bigint(&tmp_bf, &const_val->data.x_bigint); 10972 BigFloat orig_bf; 10973 switch (other_type->data.floating.bit_count) { 10974 case 16: { 10975 float16_t tmp = bigfloat_to_f16(&tmp_bf); 10976 bigfloat_init_16(&orig_bf, tmp); 10977 break; 10978 } 10979 case 32: { 10980 float tmp = bigfloat_to_f32(&tmp_bf); 10981 bigfloat_init_32(&orig_bf, tmp); 10982 break; 10983 } 10984 case 64: { 10985 double tmp = bigfloat_to_f64(&tmp_bf); 10986 bigfloat_init_64(&orig_bf, tmp); 10987 break; 10988 } 10989 case 80: 10990 zig_panic("TODO"); 10991 case 128: { 10992 float128_t tmp = bigfloat_to_f128(&tmp_bf); 10993 bigfloat_init_128(&orig_bf, tmp); 10994 break; 10995 } 10996 default: 10997 zig_unreachable(); 10998 } 10999 BigInt orig_bi; 11000 bigint_init_bigfloat(&orig_bi, &orig_bf); 11001 if (bigint_cmp(&orig_bi, &const_val->data.x_bigint) == CmpEQ) { 11002 return true; 11003 } 11004 Buf *val_buf = buf_alloc(); 11005 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 11006 ir_add_error_node(ira, instruction->base.source_node, 11007 buf_sprintf("integer value %s has no representation in type '%s'", 11008 buf_ptr(val_buf), 11009 buf_ptr(&other_type->name))); 11010 return false; 11011 } 11012 if (other_type->data.floating.bit_count >= const_val->type->data.floating.bit_count) { 11013 return true; 11014 } 11015 switch (other_type->data.floating.bit_count) { 11016 case 16: 11017 switch (const_val->type->data.floating.bit_count) { 11018 case 32: { 11019 float16_t tmp = zig_double_to_f16(const_val->data.x_f32); 11020 float orig = zig_f16_to_double(tmp); 11021 if (const_val->data.x_f32 == orig) { 11022 return true; 11023 } 11024 break; 11025 } 11026 case 64: { 11027 float16_t tmp = zig_double_to_f16(const_val->data.x_f64); 11028 double orig = zig_f16_to_double(tmp); 11029 if (const_val->data.x_f64 == orig) { 11030 return true; 11031 } 11032 break; 11033 } 11034 case 80: 11035 zig_panic("TODO"); 11036 case 128: { 11037 float16_t tmp = f128M_to_f16(&const_val->data.x_f128); 11038 float128_t orig; 11039 f16_to_f128M(tmp, &orig); 11040 if (f128M_eq(&orig, &const_val->data.x_f128)) { 11041 return true; 11042 } 11043 break; 11044 } 11045 default: 11046 zig_unreachable(); 11047 } 11048 break; 11049 case 32: 11050 switch (const_val->type->data.floating.bit_count) { 11051 case 64: { 11052 float tmp = const_val->data.x_f64; 11053 double orig = tmp; 11054 if (const_val->data.x_f64 == orig) { 11055 return true; 11056 } 11057 break; 11058 } 11059 case 80: 11060 zig_panic("TODO"); 11061 case 128: { 11062 float32_t tmp = f128M_to_f32(&const_val->data.x_f128); 11063 float128_t orig; 11064 f32_to_f128M(tmp, &orig); 11065 if (f128M_eq(&orig, &const_val->data.x_f128)) { 11066 return true; 11067 } 11068 break; 11069 } 11070 default: 11071 zig_unreachable(); 11072 } 11073 break; 11074 case 64: 11075 switch (const_val->type->data.floating.bit_count) { 11076 case 80: 11077 zig_panic("TODO"); 11078 case 128: { 11079 float64_t tmp = f128M_to_f64(&const_val->data.x_f128); 11080 float128_t orig; 11081 f64_to_f128M(tmp, &orig); 11082 if (f128M_eq(&orig, &const_val->data.x_f128)) { 11083 return true; 11084 } 11085 break; 11086 } 11087 default: 11088 zig_unreachable(); 11089 } 11090 break; 11091 case 80: 11092 assert(const_val->type->data.floating.bit_count == 128); 11093 zig_panic("TODO"); 11094 case 128: 11095 return true; 11096 default: 11097 zig_unreachable(); 11098 } 11099 Buf *val_buf = buf_alloc(); 11100 float_append_buf(val_buf, const_val); 11101 ir_add_error_node(ira, instruction->base.source_node, 11102 buf_sprintf("cast of value %s to type '%s' loses information", 11103 buf_ptr(val_buf), 11104 buf_ptr(&other_type->name))); 11105 return false; 11106 } else if (other_type->id == ZigTypeIdInt && const_val_is_int) { 11107 if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 11108 Buf *val_buf = buf_alloc(); 11109 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 11110 ir_add_error_node(ira, instruction->base.source_node, 11111 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 11112 buf_ptr(val_buf), 11113 buf_ptr(&other_type->name))); 11114 return false; 11115 } 11116 if (bigint_fits_in_bits(&const_val->data.x_bigint, other_type->data.integral.bit_count, 11117 other_type->data.integral.is_signed)) 11118 { 11119 return true; 11120 } 11121 } else if (const_val_fits_in_num_lit(const_val, other_type)) { 11122 return true; 11123 } else if (other_type->id == ZigTypeIdOptional) { 11124 ZigType *child_type = other_type->data.maybe.child_type; 11125 if (const_val_fits_in_num_lit(const_val, child_type)) { 11126 return true; 11127 } else if (child_type->id == ZigTypeIdInt && const_val_is_int) { 11128 if (!child_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 11129 Buf *val_buf = buf_alloc(); 11130 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 11131 ir_add_error_node(ira, instruction->base.source_node, 11132 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 11133 buf_ptr(val_buf), 11134 buf_ptr(&child_type->name))); 11135 return false; 11136 } 11137 if (bigint_fits_in_bits(&const_val->data.x_bigint, 11138 child_type->data.integral.bit_count, 11139 child_type->data.integral.is_signed)) 11140 { 11141 return true; 11142 } 11143 } else if (child_type->id == ZigTypeIdFloat && const_val_is_float) { 11144 return true; 11145 } 11146 } 11147 if (explicit_cast && (other_type->id == ZigTypeIdInt || other_type->id == ZigTypeIdComptimeInt) && 11148 const_val_is_float) 11149 { 11150 if (float_has_fraction(const_val)) { 11151 Buf *val_buf = buf_alloc(); 11152 float_append_buf(val_buf, const_val); 11153 11154 ir_add_error_node(ira, instruction->base.source_node, 11155 buf_sprintf("fractional component prevents float value %s from being casted to type '%s'", 11156 buf_ptr(val_buf), 11157 buf_ptr(&other_type->name))); 11158 return false; 11159 } else { 11160 if (other_type->id == ZigTypeIdComptimeInt) { 11161 return true; 11162 } else { 11163 BigInt bigint; 11164 float_init_bigint(&bigint, const_val); 11165 if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count, 11166 other_type->data.integral.is_signed)) 11167 { 11168 return true; 11169 } 11170 } 11171 } 11172 } 11173 11174 const char *num_lit_str; 11175 Buf *val_buf = buf_alloc(); 11176 if (const_val_is_float) { 11177 num_lit_str = "float"; 11178 float_append_buf(val_buf, const_val); 11179 } else { 11180 num_lit_str = "integer"; 11181 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 11182 } 11183 11184 ir_add_error_node(ira, instruction->base.source_node, 11185 buf_sprintf("%s value %s cannot be coerced to type '%s'", 11186 num_lit_str, 11187 buf_ptr(val_buf), 11188 buf_ptr(&other_type->name))); 11189 return false; 11190 } 11191 11192 static bool is_tagged_union(ZigType *type) { 11193 if (type->id != ZigTypeIdUnion) 11194 return false; 11195 return (type->data.unionation.decl_node->data.container_decl.auto_enum || 11196 type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr); 11197 } 11198 11199 static void populate_error_set_table(ErrorTableEntry **errors, ZigType *set) { 11200 assert(set->id == ZigTypeIdErrorSet); 11201 for (uint32_t i = 0; i < set->data.error_set.err_count; i += 1) { 11202 ErrorTableEntry *error_entry = set->data.error_set.errors[i]; 11203 assert(errors[error_entry->value] == nullptr); 11204 errors[error_entry->value] = error_entry; 11205 } 11206 } 11207 11208 static ErrorTableEntry *better_documented_error(ErrorTableEntry *preferred, ErrorTableEntry *other) { 11209 if (preferred->decl_node->type == NodeTypeErrorSetField) 11210 return preferred; 11211 if (other->decl_node->type == NodeTypeErrorSetField) 11212 return other; 11213 return preferred; 11214 } 11215 11216 static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigType *set2, 11217 AstNode *source_node) 11218 { 11219 assert(set1->id == ZigTypeIdErrorSet); 11220 assert(set2->id == ZigTypeIdErrorSet); 11221 11222 if (!resolve_inferred_error_set(ira->codegen, set1, source_node)) { 11223 return ira->codegen->builtin_types.entry_invalid; 11224 } 11225 if (!resolve_inferred_error_set(ira->codegen, set2, source_node)) { 11226 return ira->codegen->builtin_types.entry_invalid; 11227 } 11228 if (type_is_global_error_set(set1)) { 11229 return set2; 11230 } 11231 if (type_is_global_error_set(set2)) { 11232 return set1; 11233 } 11234 size_t errors_count = ira->codegen->errors_by_index.length; 11235 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count); 11236 populate_error_set_table(errors, set1); 11237 ZigList<ErrorTableEntry *> intersection_list = {}; 11238 11239 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 11240 buf_resize(&err_set_type->name, 0); 11241 buf_appendf(&err_set_type->name, "error{"); 11242 11243 bool need_comma = false; 11244 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 11245 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 11246 ErrorTableEntry *existing_entry = errors[error_entry->value]; 11247 if (existing_entry != nullptr) { 11248 // prefer the one with docs 11249 const char *comma = need_comma ? "," : ""; 11250 need_comma = true; 11251 ErrorTableEntry *existing_entry_with_docs = better_documented_error(existing_entry, error_entry); 11252 intersection_list.append(existing_entry_with_docs); 11253 buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&existing_entry_with_docs->name)); 11254 } 11255 } 11256 heap::c_allocator.deallocate(errors, errors_count); 11257 11258 err_set_type->data.error_set.err_count = intersection_list.length; 11259 err_set_type->data.error_set.errors = intersection_list.items; 11260 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 11261 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 11262 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 11263 11264 buf_appendf(&err_set_type->name, "}"); 11265 11266 return err_set_type; 11267 } 11268 11269 static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted_type, 11270 ZigType *actual_type, AstNode *source_node, bool wanted_is_mutable) 11271 { 11272 CodeGen *g = ira->codegen; 11273 ConstCastOnly result = {}; 11274 result.id = ConstCastResultIdOk; 11275 11276 Error err; 11277 11278 if (wanted_type == actual_type) 11279 return result; 11280 11281 // If pointers have the same representation in memory, they can be "const-casted". 11282 // `const` attribute can be gained 11283 // `volatile` attribute can be gained 11284 // `allowzero` attribute can be gained (whether from explicit attribute, C pointer, or optional pointer) 11285 // but only if !wanted_is_mutable 11286 // alignment can be decreased 11287 // bit offset attributes must match exactly 11288 // PtrLenSingle/PtrLenUnknown must match exactly, but PtrLenC matches either one 11289 // sentinel-terminated pointers can coerce into PtrLenUnknown 11290 ZigType *wanted_ptr_type = get_src_ptr_type(wanted_type); 11291 ZigType *actual_ptr_type = get_src_ptr_type(actual_type); 11292 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); 11293 bool actual_allows_zero = ptr_allows_addr_zero(actual_type); 11294 bool wanted_is_c_ptr = wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC; 11295 bool actual_is_c_ptr = actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenC; 11296 bool wanted_opt_or_ptr = wanted_ptr_type != nullptr && 11297 (wanted_type->id == ZigTypeIdPointer || wanted_type->id == ZigTypeIdOptional); 11298 bool actual_opt_or_ptr = actual_ptr_type != nullptr && 11299 (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional); 11300 if (wanted_opt_or_ptr && actual_opt_or_ptr) { 11301 bool ok_null_term_ptrs = 11302 wanted_ptr_type->data.pointer.sentinel == nullptr || 11303 (actual_ptr_type->data.pointer.sentinel != nullptr && 11304 const_values_equal(ira->codegen, wanted_ptr_type->data.pointer.sentinel, 11305 actual_ptr_type->data.pointer.sentinel)) || 11306 actual_ptr_type->data.pointer.ptr_len == PtrLenC; 11307 if (!ok_null_term_ptrs) { 11308 result.id = ConstCastResultIdPtrSentinel; 11309 result.data.bad_ptr_sentinel = heap::c_allocator.allocate_nonzero<ConstCastPtrSentinel>(1); 11310 result.data.bad_ptr_sentinel->wanted_type = wanted_ptr_type; 11311 result.data.bad_ptr_sentinel->actual_type = actual_ptr_type; 11312 return result; 11313 } 11314 bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len; 11315 if (!(ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr)) { 11316 result.id = ConstCastResultIdPtrLens; 11317 return result; 11318 } 11319 11320 bool ok_cv_qualifiers = 11321 (!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 11322 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile); 11323 if (!ok_cv_qualifiers) { 11324 result.id = ConstCastResultIdCV; 11325 result.data.bad_cv = heap::c_allocator.allocate_nonzero<ConstCastBadCV>(1); 11326 result.data.bad_cv->wanted_type = wanted_ptr_type; 11327 result.data.bad_cv->actual_type = actual_ptr_type; 11328 return result; 11329 } 11330 11331 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 11332 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 11333 if (child.id == ConstCastResultIdInvalid) 11334 return child; 11335 if (child.id != ConstCastResultIdOk) { 11336 result.id = ConstCastResultIdPointerChild; 11337 result.data.pointer_mismatch = heap::c_allocator.allocate_nonzero<ConstCastPointerMismatch>(1); 11338 result.data.pointer_mismatch->child = child; 11339 result.data.pointer_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 11340 result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 11341 return result; 11342 } 11343 bool ok_allows_zero = (wanted_allows_zero && 11344 (actual_allows_zero || !wanted_is_mutable)) || 11345 (!wanted_allows_zero && !actual_allows_zero); 11346 if (!ok_allows_zero) { 11347 result.id = ConstCastResultIdBadAllowsZero; 11348 result.data.bad_allows_zero = heap::c_allocator.allocate_nonzero<ConstCastBadAllowsZero>(1); 11349 result.data.bad_allows_zero->wanted_type = wanted_type; 11350 result.data.bad_allows_zero->actual_type = actual_type; 11351 return result; 11352 } 11353 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 11354 result.id = ConstCastResultIdInvalid; 11355 return result; 11356 } 11357 if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 11358 result.id = ConstCastResultIdInvalid; 11359 return result; 11360 } 11361 if ((err = type_resolve(g, wanted_type, ResolveStatusZeroBitsKnown))) { 11362 result.id = ConstCastResultIdInvalid; 11363 return result; 11364 } 11365 if ((err = type_resolve(g, actual_type, ResolveStatusZeroBitsKnown))) { 11366 result.id = ConstCastResultIdInvalid; 11367 return result; 11368 } 11369 if (type_has_bits(wanted_type) == type_has_bits(actual_type) && 11370 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && 11371 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && 11372 get_ptr_align(ira->codegen, actual_ptr_type) >= get_ptr_align(ira->codegen, wanted_ptr_type)) 11373 { 11374 return result; 11375 } 11376 } 11377 11378 // arrays 11379 if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdArray && 11380 wanted_type->data.array.len == actual_type->data.array.len) 11381 { 11382 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.array.child_type, 11383 actual_type->data.array.child_type, source_node, wanted_is_mutable); 11384 if (child.id == ConstCastResultIdInvalid) 11385 return child; 11386 if (child.id != ConstCastResultIdOk) { 11387 result.id = ConstCastResultIdArrayChild; 11388 result.data.array_mismatch = heap::c_allocator.allocate_nonzero<ConstCastArrayMismatch>(1); 11389 result.data.array_mismatch->child = child; 11390 result.data.array_mismatch->wanted_child = wanted_type->data.array.child_type; 11391 result.data.array_mismatch->actual_child = actual_type->data.array.child_type; 11392 return result; 11393 } 11394 bool ok_null_terminated = (wanted_type->data.array.sentinel == nullptr) || 11395 (actual_type->data.array.sentinel != nullptr && 11396 const_values_equal(ira->codegen, wanted_type->data.array.sentinel, actual_type->data.array.sentinel)); 11397 if (!ok_null_terminated) { 11398 result.id = ConstCastResultIdSentinelArrays; 11399 result.data.sentinel_arrays = heap::c_allocator.allocate_nonzero<ConstCastBadNullTermArrays>(1); 11400 result.data.sentinel_arrays->child = child; 11401 result.data.sentinel_arrays->wanted_type = wanted_type; 11402 result.data.sentinel_arrays->actual_type = actual_type; 11403 return result; 11404 } 11405 return result; 11406 } 11407 11408 // slice const 11409 if (is_slice(wanted_type) && is_slice(actual_type)) { 11410 ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index]->type_entry; 11411 ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry; 11412 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 11413 result.id = ConstCastResultIdInvalid; 11414 return result; 11415 } 11416 if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 11417 result.id = ConstCastResultIdInvalid; 11418 return result; 11419 } 11420 bool ok_sentinels = 11421 wanted_ptr_type->data.pointer.sentinel == nullptr || 11422 (actual_ptr_type->data.pointer.sentinel != nullptr && 11423 const_values_equal(ira->codegen, wanted_ptr_type->data.pointer.sentinel, 11424 actual_ptr_type->data.pointer.sentinel)); 11425 if (!ok_sentinels) { 11426 result.id = ConstCastResultIdPtrSentinel; 11427 result.data.bad_ptr_sentinel = heap::c_allocator.allocate_nonzero<ConstCastPtrSentinel>(1); 11428 result.data.bad_ptr_sentinel->wanted_type = wanted_ptr_type; 11429 result.data.bad_ptr_sentinel->actual_type = actual_ptr_type; 11430 return result; 11431 } 11432 if ((!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 11433 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) && 11434 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && 11435 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && 11436 get_ptr_align(g, actual_ptr_type) >= get_ptr_align(g, wanted_ptr_type)) 11437 { 11438 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 11439 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 11440 if (child.id == ConstCastResultIdInvalid) 11441 return child; 11442 if (child.id != ConstCastResultIdOk) { 11443 result.id = ConstCastResultIdSliceChild; 11444 result.data.slice_mismatch = heap::c_allocator.allocate_nonzero<ConstCastSliceMismatch>(1); 11445 result.data.slice_mismatch->child = child; 11446 result.data.slice_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 11447 result.data.slice_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 11448 } 11449 return result; 11450 } 11451 } 11452 11453 // maybe 11454 if (wanted_type->id == ZigTypeIdOptional && actual_type->id == ZigTypeIdOptional) { 11455 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.maybe.child_type, 11456 actual_type->data.maybe.child_type, source_node, wanted_is_mutable); 11457 if (child.id == ConstCastResultIdInvalid) 11458 return child; 11459 if (child.id != ConstCastResultIdOk) { 11460 result.id = ConstCastResultIdOptionalChild; 11461 result.data.optional = heap::c_allocator.allocate_nonzero<ConstCastOptionalMismatch>(1); 11462 result.data.optional->child = child; 11463 result.data.optional->wanted_child = wanted_type->data.maybe.child_type; 11464 result.data.optional->actual_child = actual_type->data.maybe.child_type; 11465 } 11466 return result; 11467 } 11468 11469 // error union 11470 if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id == ZigTypeIdErrorUnion) { 11471 ConstCastOnly payload_child = types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, 11472 actual_type->data.error_union.payload_type, source_node, wanted_is_mutable); 11473 if (payload_child.id == ConstCastResultIdInvalid) 11474 return payload_child; 11475 if (payload_child.id != ConstCastResultIdOk) { 11476 result.id = ConstCastResultIdErrorUnionPayload; 11477 result.data.error_union_payload = heap::c_allocator.allocate_nonzero<ConstCastErrUnionPayloadMismatch>(1); 11478 result.data.error_union_payload->child = payload_child; 11479 result.data.error_union_payload->wanted_payload = wanted_type->data.error_union.payload_type; 11480 result.data.error_union_payload->actual_payload = actual_type->data.error_union.payload_type; 11481 return result; 11482 } 11483 ConstCastOnly error_set_child = types_match_const_cast_only(ira, wanted_type->data.error_union.err_set_type, 11484 actual_type->data.error_union.err_set_type, source_node, wanted_is_mutable); 11485 if (error_set_child.id == ConstCastResultIdInvalid) 11486 return error_set_child; 11487 if (error_set_child.id != ConstCastResultIdOk) { 11488 result.id = ConstCastResultIdErrorUnionErrorSet; 11489 result.data.error_union_error_set = heap::c_allocator.allocate_nonzero<ConstCastErrUnionErrSetMismatch>(1); 11490 result.data.error_union_error_set->child = error_set_child; 11491 result.data.error_union_error_set->wanted_err_set = wanted_type->data.error_union.err_set_type; 11492 result.data.error_union_error_set->actual_err_set = actual_type->data.error_union.err_set_type; 11493 return result; 11494 } 11495 return result; 11496 } 11497 11498 // error set 11499 if (wanted_type->id == ZigTypeIdErrorSet && actual_type->id == ZigTypeIdErrorSet) { 11500 ZigType *contained_set = actual_type; 11501 ZigType *container_set = wanted_type; 11502 11503 // if the container set is inferred, then this will always work. 11504 if (container_set->data.error_set.infer_fn != nullptr && container_set->data.error_set.incomplete) { 11505 return result; 11506 } 11507 // if the container set is the global one, it will always work. 11508 if (type_is_global_error_set(container_set)) { 11509 return result; 11510 } 11511 11512 if (!resolve_inferred_error_set(ira->codegen, contained_set, source_node)) { 11513 result.id = ConstCastResultIdUnresolvedInferredErrSet; 11514 return result; 11515 } 11516 11517 if (type_is_global_error_set(contained_set)) { 11518 result.id = ConstCastResultIdErrSetGlobal; 11519 return result; 11520 } 11521 11522 size_t errors_count = g->errors_by_index.length; 11523 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count); 11524 for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) { 11525 ErrorTableEntry *error_entry = container_set->data.error_set.errors[i]; 11526 assert(errors[error_entry->value] == nullptr); 11527 errors[error_entry->value] = error_entry; 11528 } 11529 for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) { 11530 ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i]; 11531 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 11532 if (error_entry == nullptr) { 11533 if (result.id == ConstCastResultIdOk) { 11534 result.id = ConstCastResultIdErrSet; 11535 result.data.error_set_mismatch = heap::c_allocator.create<ConstCastErrSetMismatch>(); 11536 } 11537 result.data.error_set_mismatch->missing_errors.append(contained_error_entry); 11538 } 11539 } 11540 heap::c_allocator.deallocate(errors, errors_count); 11541 return result; 11542 } 11543 11544 // fn 11545 if (wanted_type->id == ZigTypeIdFn && 11546 actual_type->id == ZigTypeIdFn) 11547 { 11548 if (wanted_type->data.fn.fn_type_id.alignment > actual_type->data.fn.fn_type_id.alignment) { 11549 result.id = ConstCastResultIdFnAlign; 11550 return result; 11551 } 11552 if (wanted_type->data.fn.fn_type_id.is_var_args != actual_type->data.fn.fn_type_id.is_var_args) { 11553 result.id = ConstCastResultIdFnVarArgs; 11554 return result; 11555 } 11556 if (wanted_type->data.fn.is_generic != actual_type->data.fn.is_generic) { 11557 result.id = ConstCastResultIdFnIsGeneric; 11558 return result; 11559 } 11560 if (!wanted_type->data.fn.is_generic && 11561 actual_type->data.fn.fn_type_id.return_type->id != ZigTypeIdUnreachable) 11562 { 11563 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.fn.fn_type_id.return_type, 11564 actual_type->data.fn.fn_type_id.return_type, source_node, false); 11565 if (child.id == ConstCastResultIdInvalid) 11566 return child; 11567 if (child.id != ConstCastResultIdOk) { 11568 result.id = ConstCastResultIdFnReturnType; 11569 result.data.return_type = heap::c_allocator.allocate_nonzero<ConstCastOnly>(1); 11570 *result.data.return_type = child; 11571 return result; 11572 } 11573 } 11574 if (wanted_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { 11575 result.id = ConstCastResultIdFnArgCount; 11576 return result; 11577 } 11578 if (wanted_type->data.fn.fn_type_id.next_param_index != actual_type->data.fn.fn_type_id.next_param_index) { 11579 result.id = ConstCastResultIdFnGenericArgCount; 11580 return result; 11581 } 11582 assert(wanted_type->data.fn.is_generic || 11583 wanted_type->data.fn.fn_type_id.next_param_index == wanted_type->data.fn.fn_type_id.param_count); 11584 for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.param_count; i += 1) { 11585 // note it's reversed for parameters 11586 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i]; 11587 FnTypeParamInfo *expected_param_info = &wanted_type->data.fn.fn_type_id.param_info[i]; 11588 11589 ConstCastOnly arg_child = types_match_const_cast_only(ira, actual_param_info->type, 11590 expected_param_info->type, source_node, false); 11591 if (arg_child.id == ConstCastResultIdInvalid) 11592 return arg_child; 11593 if (arg_child.id != ConstCastResultIdOk) { 11594 result.id = ConstCastResultIdFnArg; 11595 result.data.fn_arg.arg_index = i; 11596 result.data.fn_arg.actual_param_type = actual_param_info->type; 11597 result.data.fn_arg.expected_param_type = expected_param_info->type; 11598 result.data.fn_arg.child = heap::c_allocator.allocate_nonzero<ConstCastOnly>(1); 11599 *result.data.fn_arg.child = arg_child; 11600 return result; 11601 } 11602 11603 if (expected_param_info->is_noalias != actual_param_info->is_noalias) { 11604 result.id = ConstCastResultIdFnArgNoAlias; 11605 result.data.arg_no_alias.arg_index = i; 11606 return result; 11607 } 11608 } 11609 if (wanted_type->data.fn.fn_type_id.cc != actual_type->data.fn.fn_type_id.cc) { 11610 // ConstCastResultIdFnCC is guaranteed to be the last one reported, meaning everything else is ok. 11611 result.id = ConstCastResultIdFnCC; 11612 return result; 11613 } 11614 return result; 11615 } 11616 11617 if (wanted_type->id == ZigTypeIdInt && actual_type->id == ZigTypeIdInt) { 11618 if (wanted_type->data.integral.is_signed != actual_type->data.integral.is_signed || 11619 wanted_type->data.integral.bit_count != actual_type->data.integral.bit_count) 11620 { 11621 result.id = ConstCastResultIdIntShorten; 11622 result.data.int_shorten = heap::c_allocator.allocate_nonzero<ConstCastIntShorten>(1); 11623 result.data.int_shorten->wanted_type = wanted_type; 11624 result.data.int_shorten->actual_type = actual_type; 11625 return result; 11626 } 11627 return result; 11628 } 11629 11630 result.id = ConstCastResultIdType; 11631 result.data.type_mismatch = heap::c_allocator.allocate_nonzero<ConstCastTypeMismatch>(1); 11632 result.data.type_mismatch->wanted_type = wanted_type; 11633 result.data.type_mismatch->actual_type = actual_type; 11634 return result; 11635 } 11636 11637 static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) { 11638 size_t old_errors_count = *errors_count; 11639 *errors_count = g->errors_by_index.length; 11640 *errors = heap::c_allocator.reallocate(*errors, old_errors_count, *errors_count); 11641 } 11642 11643 static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigType *expected_type, 11644 IrInstGen **instructions, size_t instruction_count) 11645 { 11646 Error err; 11647 assert(instruction_count >= 1); 11648 IrInstGen *prev_inst; 11649 size_t i = 0; 11650 for (;;) { 11651 prev_inst = instructions[i]; 11652 if (type_is_invalid(prev_inst->value->type)) { 11653 return ira->codegen->builtin_types.entry_invalid; 11654 } 11655 if (prev_inst->value->type->id == ZigTypeIdUnreachable) { 11656 i += 1; 11657 if (i == instruction_count) { 11658 return prev_inst->value->type; 11659 } 11660 continue; 11661 } 11662 break; 11663 } 11664 ErrorTableEntry **errors = nullptr; 11665 size_t errors_count = 0; 11666 ZigType *err_set_type = nullptr; 11667 if (prev_inst->value->type->id == ZigTypeIdErrorSet) { 11668 if (!resolve_inferred_error_set(ira->codegen, prev_inst->value->type, prev_inst->base.source_node)) { 11669 return ira->codegen->builtin_types.entry_invalid; 11670 } 11671 if (type_is_global_error_set(prev_inst->value->type)) { 11672 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 11673 } else { 11674 err_set_type = prev_inst->value->type; 11675 update_errors_helper(ira->codegen, &errors, &errors_count); 11676 11677 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 11678 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 11679 assert(errors[error_entry->value] == nullptr); 11680 errors[error_entry->value] = error_entry; 11681 } 11682 } 11683 } 11684 11685 bool any_are_null = (prev_inst->value->type->id == ZigTypeIdNull); 11686 bool convert_to_const_slice = false; 11687 for (; i < instruction_count; i += 1) { 11688 IrInstGen *cur_inst = instructions[i]; 11689 ZigType *cur_type = cur_inst->value->type; 11690 ZigType *prev_type = prev_inst->value->type; 11691 11692 if (type_is_invalid(cur_type)) { 11693 return cur_type; 11694 } 11695 11696 if (prev_type == cur_type) { 11697 continue; 11698 } 11699 11700 if (prev_type->id == ZigTypeIdUnreachable) { 11701 prev_inst = cur_inst; 11702 continue; 11703 } 11704 11705 if (cur_type->id == ZigTypeIdUnreachable) { 11706 continue; 11707 } 11708 11709 if (prev_type->id == ZigTypeIdErrorSet) { 11710 ir_assert_gen(err_set_type != nullptr, prev_inst); 11711 if (cur_type->id == ZigTypeIdErrorSet) { 11712 if (type_is_global_error_set(err_set_type)) { 11713 continue; 11714 } 11715 bool allow_infer = cur_type->data.error_set.infer_fn != nullptr && 11716 cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 11717 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) { 11718 return ira->codegen->builtin_types.entry_invalid; 11719 } 11720 if (!allow_infer && type_is_global_error_set(cur_type)) { 11721 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 11722 prev_inst = cur_inst; 11723 continue; 11724 } 11725 11726 // number of declared errors might have increased now 11727 update_errors_helper(ira->codegen, &errors, &errors_count); 11728 11729 // if err_set_type is a superset of cur_type, keep err_set_type. 11730 // if cur_type is a superset of err_set_type, switch err_set_type to cur_type 11731 bool prev_is_superset = true; 11732 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 11733 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 11734 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 11735 if (error_entry == nullptr) { 11736 prev_is_superset = false; 11737 break; 11738 } 11739 } 11740 if (prev_is_superset) { 11741 continue; 11742 } 11743 11744 // unset everything in errors 11745 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 11746 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 11747 errors[error_entry->value] = nullptr; 11748 } 11749 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 11750 assert(errors[i] == nullptr); 11751 } 11752 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 11753 ErrorTableEntry *error_entry = cur_type->data.error_set.errors[i]; 11754 assert(errors[error_entry->value] == nullptr); 11755 errors[error_entry->value] = error_entry; 11756 } 11757 bool cur_is_superset = true; 11758 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 11759 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 11760 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 11761 if (error_entry == nullptr) { 11762 cur_is_superset = false; 11763 break; 11764 } 11765 } 11766 if (cur_is_superset) { 11767 err_set_type = cur_type; 11768 prev_inst = cur_inst; 11769 assert(errors != nullptr); 11770 continue; 11771 } 11772 11773 // neither of them are supersets. so we invent a new error set type that is a union of both of them 11774 err_set_type = get_error_set_union(ira->codegen, errors, cur_type, err_set_type, nullptr); 11775 assert(errors != nullptr); 11776 continue; 11777 } else if (cur_type->id == ZigTypeIdErrorUnion) { 11778 if (type_is_global_error_set(err_set_type)) { 11779 prev_inst = cur_inst; 11780 continue; 11781 } 11782 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 11783 bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr && 11784 cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 11785 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) { 11786 return ira->codegen->builtin_types.entry_invalid; 11787 } 11788 if (!allow_infer && type_is_global_error_set(cur_err_set_type)) { 11789 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 11790 prev_inst = cur_inst; 11791 continue; 11792 } 11793 11794 update_errors_helper(ira->codegen, &errors, &errors_count); 11795 11796 // test if err_set_type is a subset of cur_type's error set 11797 // unset everything in errors 11798 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 11799 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 11800 errors[error_entry->value] = nullptr; 11801 } 11802 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 11803 assert(errors[i] == nullptr); 11804 } 11805 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 11806 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 11807 assert(errors[error_entry->value] == nullptr); 11808 errors[error_entry->value] = error_entry; 11809 } 11810 bool cur_is_superset = true; 11811 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 11812 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 11813 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 11814 if (error_entry == nullptr) { 11815 cur_is_superset = false; 11816 break; 11817 } 11818 } 11819 if (cur_is_superset) { 11820 err_set_type = cur_err_set_type; 11821 prev_inst = cur_inst; 11822 assert(errors != nullptr); 11823 continue; 11824 } 11825 11826 // not a subset. invent new error set type, union of both of them 11827 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, err_set_type, nullptr); 11828 prev_inst = cur_inst; 11829 assert(errors != nullptr); 11830 continue; 11831 } else { 11832 prev_inst = cur_inst; 11833 continue; 11834 } 11835 } 11836 11837 if (cur_type->id == ZigTypeIdErrorSet) { 11838 bool allow_infer = cur_type->data.error_set.infer_fn != nullptr && 11839 cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 11840 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) { 11841 return ira->codegen->builtin_types.entry_invalid; 11842 } 11843 if (!allow_infer && type_is_global_error_set(cur_type)) { 11844 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 11845 continue; 11846 } 11847 if (err_set_type != nullptr && type_is_global_error_set(err_set_type)) { 11848 continue; 11849 } 11850 11851 update_errors_helper(ira->codegen, &errors, &errors_count); 11852 11853 if (err_set_type == nullptr) { 11854 bool allow_infer = false; 11855 if (prev_type->id == ZigTypeIdErrorUnion) { 11856 err_set_type = prev_type->data.error_union.err_set_type; 11857 allow_infer = err_set_type->data.error_set.infer_fn != nullptr && 11858 err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 11859 } else { 11860 err_set_type = cur_type; 11861 } 11862 11863 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, err_set_type, cur_inst->base.source_node)) { 11864 return ira->codegen->builtin_types.entry_invalid; 11865 } 11866 11867 if (!allow_infer && type_is_global_error_set(err_set_type)) { 11868 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 11869 continue; 11870 } 11871 11872 update_errors_helper(ira->codegen, &errors, &errors_count); 11873 11874 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 11875 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 11876 assert(errors[error_entry->value] == nullptr); 11877 errors[error_entry->value] = error_entry; 11878 } 11879 if (err_set_type == cur_type) { 11880 continue; 11881 } 11882 } 11883 // check if the cur type error set is a subset 11884 bool prev_is_superset = true; 11885 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 11886 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 11887 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 11888 if (error_entry == nullptr) { 11889 prev_is_superset = false; 11890 break; 11891 } 11892 } 11893 if (prev_is_superset) { 11894 continue; 11895 } 11896 // not a subset. invent new error set type, union of both of them 11897 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_type, nullptr); 11898 assert(errors != nullptr); 11899 continue; 11900 } 11901 11902 if (prev_type->id == ZigTypeIdErrorUnion && cur_type->id == ZigTypeIdErrorUnion) { 11903 ZigType *prev_payload_type = prev_type->data.error_union.payload_type; 11904 ZigType *cur_payload_type = cur_type->data.error_union.payload_type; 11905 11906 bool const_cast_prev = types_match_const_cast_only(ira, prev_payload_type, cur_payload_type, 11907 source_node, false).id == ConstCastResultIdOk; 11908 bool const_cast_cur = types_match_const_cast_only(ira, cur_payload_type, prev_payload_type, 11909 source_node, false).id == ConstCastResultIdOk; 11910 11911 if (const_cast_prev || const_cast_cur) { 11912 if (const_cast_cur) { 11913 prev_inst = cur_inst; 11914 } 11915 11916 ZigType *prev_err_set_type = (err_set_type == nullptr) ? prev_type->data.error_union.err_set_type : err_set_type; 11917 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 11918 if (prev_err_set_type == cur_err_set_type) 11919 continue; 11920 11921 bool allow_infer_prev = prev_err_set_type->data.error_set.infer_fn != nullptr && 11922 prev_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 11923 bool allow_infer_cur = cur_err_set_type->data.error_set.infer_fn != nullptr && 11924 cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 11925 11926 if (!allow_infer_prev && !resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->base.source_node)) { 11927 return ira->codegen->builtin_types.entry_invalid; 11928 } 11929 11930 if (!allow_infer_cur && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) { 11931 return ira->codegen->builtin_types.entry_invalid; 11932 } 11933 11934 if ((!allow_infer_prev && type_is_global_error_set(prev_err_set_type)) || 11935 (!allow_infer_cur && type_is_global_error_set(cur_err_set_type))) 11936 { 11937 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 11938 continue; 11939 } 11940 11941 update_errors_helper(ira->codegen, &errors, &errors_count); 11942 11943 if (err_set_type == nullptr) { 11944 err_set_type = prev_err_set_type; 11945 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 11946 ErrorTableEntry *error_entry = prev_err_set_type->data.error_set.errors[i]; 11947 assert(errors[error_entry->value] == nullptr); 11948 errors[error_entry->value] = error_entry; 11949 } 11950 } 11951 bool prev_is_superset = true; 11952 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 11953 ErrorTableEntry *contained_error_entry = cur_err_set_type->data.error_set.errors[i]; 11954 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 11955 if (error_entry == nullptr) { 11956 prev_is_superset = false; 11957 break; 11958 } 11959 } 11960 if (prev_is_superset) { 11961 continue; 11962 } 11963 // unset all the errors 11964 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 11965 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 11966 errors[error_entry->value] = nullptr; 11967 } 11968 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 11969 assert(errors[i] == nullptr); 11970 } 11971 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 11972 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 11973 assert(errors[error_entry->value] == nullptr); 11974 errors[error_entry->value] = error_entry; 11975 } 11976 bool cur_is_superset = true; 11977 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 11978 ErrorTableEntry *contained_error_entry = prev_err_set_type->data.error_set.errors[i]; 11979 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 11980 if (error_entry == nullptr) { 11981 cur_is_superset = false; 11982 break; 11983 } 11984 } 11985 if (cur_is_superset) { 11986 err_set_type = cur_err_set_type; 11987 continue; 11988 } 11989 11990 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, prev_err_set_type, nullptr); 11991 continue; 11992 } 11993 } 11994 11995 if (prev_type->id == ZigTypeIdNull) { 11996 prev_inst = cur_inst; 11997 any_are_null = true; 11998 continue; 11999 } 12000 12001 if (cur_type->id == ZigTypeIdNull) { 12002 any_are_null = true; 12003 continue; 12004 } 12005 12006 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdEnumLiteral) { 12007 TypeEnumField *field = find_enum_type_field(prev_type, cur_inst->value->data.x_enum_literal); 12008 if (field != nullptr) { 12009 continue; 12010 } 12011 } 12012 if (is_tagged_union(prev_type) && cur_type->id == ZigTypeIdEnumLiteral) { 12013 TypeUnionField *field = find_union_type_field(prev_type, cur_inst->value->data.x_enum_literal); 12014 if (field != nullptr) { 12015 continue; 12016 } 12017 } 12018 12019 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdEnumLiteral) { 12020 TypeEnumField *field = find_enum_type_field(cur_type, prev_inst->value->data.x_enum_literal); 12021 if (field != nullptr) { 12022 prev_inst = cur_inst; 12023 continue; 12024 } 12025 } 12026 12027 if (is_tagged_union(cur_type) && prev_type->id == ZigTypeIdEnumLiteral) { 12028 TypeUnionField *field = find_union_type_field(cur_type, prev_inst->value->data.x_enum_literal); 12029 if (field != nullptr) { 12030 prev_inst = cur_inst; 12031 continue; 12032 } 12033 } 12034 12035 if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenC && 12036 (cur_type->id == ZigTypeIdComptimeInt || cur_type->id == ZigTypeIdInt)) 12037 { 12038 continue; 12039 } 12040 12041 if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenC && 12042 (prev_type->id == ZigTypeIdComptimeInt || prev_type->id == ZigTypeIdInt)) 12043 { 12044 prev_inst = cur_inst; 12045 continue; 12046 } 12047 12048 if (prev_type->id == ZigTypeIdPointer && cur_type->id == ZigTypeIdPointer) { 12049 if (prev_type->data.pointer.ptr_len == PtrLenC && 12050 types_match_const_cast_only(ira, prev_type->data.pointer.child_type, 12051 cur_type->data.pointer.child_type, source_node, 12052 !prev_type->data.pointer.is_const).id == ConstCastResultIdOk) 12053 { 12054 continue; 12055 } 12056 if (cur_type->data.pointer.ptr_len == PtrLenC && 12057 types_match_const_cast_only(ira, cur_type->data.pointer.child_type, 12058 prev_type->data.pointer.child_type, source_node, 12059 !cur_type->data.pointer.is_const).id == ConstCastResultIdOk) 12060 { 12061 prev_inst = cur_inst; 12062 continue; 12063 } 12064 } 12065 12066 if (types_match_const_cast_only(ira, prev_type, cur_type, source_node, false).id == ConstCastResultIdOk) { 12067 continue; 12068 } 12069 12070 if (types_match_const_cast_only(ira, cur_type, prev_type, source_node, false).id == ConstCastResultIdOk) { 12071 prev_inst = cur_inst; 12072 continue; 12073 } 12074 12075 if (prev_type->id == ZigTypeIdInt && 12076 cur_type->id == ZigTypeIdInt && 12077 prev_type->data.integral.is_signed == cur_type->data.integral.is_signed) 12078 { 12079 if (cur_type->data.integral.bit_count > prev_type->data.integral.bit_count) { 12080 prev_inst = cur_inst; 12081 } 12082 continue; 12083 } 12084 12085 if (prev_type->id == ZigTypeIdFloat && cur_type->id == ZigTypeIdFloat) { 12086 if (cur_type->data.floating.bit_count > prev_type->data.floating.bit_count) { 12087 prev_inst = cur_inst; 12088 } 12089 continue; 12090 } 12091 12092 if (prev_type->id == ZigTypeIdErrorUnion && 12093 types_match_const_cast_only(ira, prev_type->data.error_union.payload_type, cur_type, 12094 source_node, false).id == ConstCastResultIdOk) 12095 { 12096 continue; 12097 } 12098 12099 if (cur_type->id == ZigTypeIdErrorUnion && 12100 types_match_const_cast_only(ira, cur_type->data.error_union.payload_type, prev_type, 12101 source_node, false).id == ConstCastResultIdOk) 12102 { 12103 if (err_set_type != nullptr) { 12104 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 12105 bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr && 12106 cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12107 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) { 12108 return ira->codegen->builtin_types.entry_invalid; 12109 } 12110 if ((!allow_infer && type_is_global_error_set(cur_err_set_type)) || 12111 type_is_global_error_set(err_set_type)) 12112 { 12113 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12114 prev_inst = cur_inst; 12115 continue; 12116 } 12117 12118 update_errors_helper(ira->codegen, &errors, &errors_count); 12119 12120 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_err_set_type, nullptr); 12121 } 12122 prev_inst = cur_inst; 12123 continue; 12124 } 12125 12126 if (prev_type->id == ZigTypeIdOptional && 12127 types_match_const_cast_only(ira, prev_type->data.maybe.child_type, cur_type, 12128 source_node, false).id == ConstCastResultIdOk) 12129 { 12130 continue; 12131 } 12132 12133 if (cur_type->id == ZigTypeIdOptional && 12134 types_match_const_cast_only(ira, cur_type->data.maybe.child_type, prev_type, 12135 source_node, false).id == ConstCastResultIdOk) 12136 { 12137 prev_inst = cur_inst; 12138 continue; 12139 } 12140 12141 if (prev_type->id == ZigTypeIdOptional && 12142 types_match_const_cast_only(ira, cur_type, prev_type->data.maybe.child_type, 12143 source_node, false).id == ConstCastResultIdOk) 12144 { 12145 prev_inst = cur_inst; 12146 any_are_null = true; 12147 continue; 12148 } 12149 12150 if (cur_type->id == ZigTypeIdOptional && 12151 types_match_const_cast_only(ira, prev_type, cur_type->data.maybe.child_type, 12152 source_node, false).id == ConstCastResultIdOk) 12153 { 12154 any_are_null = true; 12155 continue; 12156 } 12157 12158 if (cur_type->id == ZigTypeIdUndefined) { 12159 continue; 12160 } 12161 12162 if (prev_type->id == ZigTypeIdUndefined) { 12163 prev_inst = cur_inst; 12164 continue; 12165 } 12166 12167 if (prev_type->id == ZigTypeIdComptimeInt || 12168 prev_type->id == ZigTypeIdComptimeFloat) 12169 { 12170 if (ir_num_lit_fits_in_other_type(ira, prev_inst, cur_type, false)) { 12171 prev_inst = cur_inst; 12172 continue; 12173 } else { 12174 return ira->codegen->builtin_types.entry_invalid; 12175 } 12176 } 12177 12178 if (cur_type->id == ZigTypeIdComptimeInt || 12179 cur_type->id == ZigTypeIdComptimeFloat) 12180 { 12181 if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type, false)) { 12182 continue; 12183 } else { 12184 return ira->codegen->builtin_types.entry_invalid; 12185 } 12186 } 12187 12188 // *[N]T to []T 12189 // *[N]T to E![]T 12190 if (cur_type->id == ZigTypeIdPointer && 12191 cur_type->data.pointer.ptr_len == PtrLenSingle && 12192 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 12193 ((prev_type->id == ZigTypeIdErrorUnion && is_slice(prev_type->data.error_union.payload_type)) || 12194 is_slice(prev_type))) 12195 { 12196 ZigType *array_type = cur_type->data.pointer.child_type; 12197 ZigType *slice_type = (prev_type->id == ZigTypeIdErrorUnion) ? 12198 prev_type->data.error_union.payload_type : prev_type; 12199 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 12200 if ((slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 || 12201 !cur_type->data.pointer.is_const) && 12202 types_match_const_cast_only(ira, 12203 slice_ptr_type->data.pointer.child_type, 12204 array_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 12205 { 12206 convert_to_const_slice = false; 12207 continue; 12208 } 12209 } 12210 12211 // *[N]T to []T 12212 // *[N]T to E![]T 12213 if (prev_type->id == ZigTypeIdPointer && 12214 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 12215 prev_type->data.pointer.ptr_len == PtrLenSingle && 12216 ((cur_type->id == ZigTypeIdErrorUnion && is_slice(cur_type->data.error_union.payload_type)) || 12217 is_slice(cur_type))) 12218 { 12219 ZigType *array_type = prev_type->data.pointer.child_type; 12220 ZigType *slice_type = (cur_type->id == ZigTypeIdErrorUnion) ? 12221 cur_type->data.error_union.payload_type : cur_type; 12222 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 12223 if ((slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 || 12224 !prev_type->data.pointer.is_const) && 12225 types_match_const_cast_only(ira, 12226 slice_ptr_type->data.pointer.child_type, 12227 array_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 12228 { 12229 prev_inst = cur_inst; 12230 convert_to_const_slice = false; 12231 continue; 12232 } 12233 } 12234 12235 // *[N]T and *[M]T 12236 if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle && 12237 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 12238 prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenSingle && 12239 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 12240 (cur_type->data.pointer.is_const || !prev_type->data.pointer.is_const || 12241 prev_type->data.pointer.child_type->data.array.len == 0) && 12242 ( 12243 prev_type->data.pointer.child_type->data.array.sentinel == nullptr || 12244 (cur_type->data.pointer.child_type->data.array.sentinel != nullptr && 12245 const_values_equal(ira->codegen, prev_type->data.pointer.child_type->data.array.sentinel, 12246 cur_type->data.pointer.child_type->data.array.sentinel)) 12247 ) && 12248 types_match_const_cast_only(ira, 12249 cur_type->data.pointer.child_type->data.array.child_type, 12250 prev_type->data.pointer.child_type->data.array.child_type, 12251 source_node, !cur_type->data.pointer.is_const).id == ConstCastResultIdOk) 12252 { 12253 prev_inst = cur_inst; 12254 convert_to_const_slice = true; 12255 continue; 12256 } 12257 if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenSingle && 12258 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 12259 cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle && 12260 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 12261 (prev_type->data.pointer.is_const || !cur_type->data.pointer.is_const || 12262 cur_type->data.pointer.child_type->data.array.len == 0) && 12263 ( 12264 cur_type->data.pointer.child_type->data.array.sentinel == nullptr || 12265 (prev_type->data.pointer.child_type->data.array.sentinel != nullptr && 12266 const_values_equal(ira->codegen, cur_type->data.pointer.child_type->data.array.sentinel, 12267 prev_type->data.pointer.child_type->data.array.sentinel)) 12268 ) && 12269 types_match_const_cast_only(ira, 12270 prev_type->data.pointer.child_type->data.array.child_type, 12271 cur_type->data.pointer.child_type->data.array.child_type, 12272 source_node, !prev_type->data.pointer.is_const).id == ConstCastResultIdOk) 12273 { 12274 convert_to_const_slice = true; 12275 continue; 12276 } 12277 12278 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdUnion && 12279 (cur_type->data.unionation.decl_node->data.container_decl.auto_enum || cur_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 12280 { 12281 if ((err = type_resolve(ira->codegen, cur_type, ResolveStatusZeroBitsKnown))) 12282 return ira->codegen->builtin_types.entry_invalid; 12283 if (cur_type->data.unionation.tag_type == prev_type) { 12284 continue; 12285 } 12286 } 12287 12288 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdUnion && 12289 (prev_type->data.unionation.decl_node->data.container_decl.auto_enum || prev_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 12290 { 12291 if ((err = type_resolve(ira->codegen, prev_type, ResolveStatusZeroBitsKnown))) 12292 return ira->codegen->builtin_types.entry_invalid; 12293 if (prev_type->data.unionation.tag_type == cur_type) { 12294 prev_inst = cur_inst; 12295 continue; 12296 } 12297 } 12298 12299 ErrorMsg *msg = ir_add_error_node(ira, source_node, 12300 buf_sprintf("incompatible types: '%s' and '%s'", 12301 buf_ptr(&prev_type->name), buf_ptr(&cur_type->name))); 12302 add_error_note(ira->codegen, msg, prev_inst->base.source_node, 12303 buf_sprintf("type '%s' here", buf_ptr(&prev_type->name))); 12304 add_error_note(ira->codegen, msg, cur_inst->base.source_node, 12305 buf_sprintf("type '%s' here", buf_ptr(&cur_type->name))); 12306 12307 return ira->codegen->builtin_types.entry_invalid; 12308 } 12309 12310 heap::c_allocator.deallocate(errors, errors_count); 12311 12312 if (convert_to_const_slice) { 12313 if (prev_inst->value->type->id == ZigTypeIdPointer) { 12314 ZigType *array_type = prev_inst->value->type->data.pointer.child_type; 12315 src_assert(array_type->id == ZigTypeIdArray, source_node); 12316 ZigType *ptr_type = get_pointer_to_type_extra2( 12317 ira->codegen, array_type->data.array.child_type, 12318 prev_inst->value->type->data.pointer.is_const, false, 12319 PtrLenUnknown, 12320 0, 0, 0, false, 12321 VECTOR_INDEX_NONE, nullptr, array_type->data.array.sentinel); 12322 ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); 12323 if (err_set_type != nullptr) { 12324 return get_error_union_type(ira->codegen, err_set_type, slice_type); 12325 } else { 12326 return slice_type; 12327 } 12328 } else { 12329 zig_unreachable(); 12330 } 12331 } else if (err_set_type != nullptr) { 12332 if (prev_inst->value->type->id == ZigTypeIdErrorSet) { 12333 return err_set_type; 12334 } else if (prev_inst->value->type->id == ZigTypeIdErrorUnion) { 12335 ZigType *payload_type = prev_inst->value->type->data.error_union.payload_type; 12336 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 12337 return ira->codegen->builtin_types.entry_invalid; 12338 return get_error_union_type(ira->codegen, err_set_type, payload_type); 12339 } else if (expected_type != nullptr && expected_type->id == ZigTypeIdErrorUnion) { 12340 ZigType *payload_type = expected_type->data.error_union.payload_type; 12341 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 12342 return ira->codegen->builtin_types.entry_invalid; 12343 return get_error_union_type(ira->codegen, err_set_type, payload_type); 12344 } else { 12345 if (prev_inst->value->type->id == ZigTypeIdComptimeInt || 12346 prev_inst->value->type->id == ZigTypeIdComptimeFloat) 12347 { 12348 ir_add_error_node(ira, source_node, 12349 buf_sprintf("unable to make error union out of number literal")); 12350 return ira->codegen->builtin_types.entry_invalid; 12351 } else if (prev_inst->value->type->id == ZigTypeIdNull) { 12352 ir_add_error_node(ira, source_node, 12353 buf_sprintf("unable to make error union out of null literal")); 12354 return ira->codegen->builtin_types.entry_invalid; 12355 } else { 12356 if ((err = type_resolve(ira->codegen, prev_inst->value->type, ResolveStatusSizeKnown))) 12357 return ira->codegen->builtin_types.entry_invalid; 12358 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value->type); 12359 } 12360 } 12361 } else if (any_are_null && prev_inst->value->type->id != ZigTypeIdNull) { 12362 if (prev_inst->value->type->id == ZigTypeIdOptional) { 12363 return prev_inst->value->type; 12364 } else { 12365 if ((err = type_resolve(ira->codegen, prev_inst->value->type, ResolveStatusSizeKnown))) 12366 return ira->codegen->builtin_types.entry_invalid; 12367 return get_optional_type(ira->codegen, prev_inst->value->type); 12368 } 12369 } else { 12370 return prev_inst->value->type; 12371 } 12372 } 12373 12374 static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInst *source_instr, 12375 CastOp cast_op, 12376 ZigValue *other_val, ZigType *other_type, 12377 ZigValue *const_val, ZigType *new_type) 12378 { 12379 const_val->special = other_val->special; 12380 12381 assert(other_val != const_val); 12382 switch (cast_op) { 12383 case CastOpNoCast: 12384 zig_unreachable(); 12385 case CastOpErrSet: 12386 case CastOpBitCast: 12387 zig_panic("TODO"); 12388 case CastOpNoop: { 12389 copy_const_val(ira->codegen, const_val, other_val); 12390 const_val->type = new_type; 12391 break; 12392 } 12393 case CastOpNumLitToConcrete: 12394 if (other_val->type->id == ZigTypeIdComptimeFloat) { 12395 assert(new_type->id == ZigTypeIdFloat); 12396 switch (new_type->data.floating.bit_count) { 12397 case 16: 12398 const_val->data.x_f16 = bigfloat_to_f16(&other_val->data.x_bigfloat); 12399 break; 12400 case 32: 12401 const_val->data.x_f32 = bigfloat_to_f32(&other_val->data.x_bigfloat); 12402 break; 12403 case 64: 12404 const_val->data.x_f64 = bigfloat_to_f64(&other_val->data.x_bigfloat); 12405 break; 12406 case 80: 12407 zig_panic("TODO"); 12408 case 128: 12409 const_val->data.x_f128 = bigfloat_to_f128(&other_val->data.x_bigfloat); 12410 break; 12411 default: 12412 zig_unreachable(); 12413 } 12414 } else if (other_val->type->id == ZigTypeIdComptimeInt) { 12415 bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint); 12416 } else { 12417 zig_unreachable(); 12418 } 12419 const_val->type = new_type; 12420 break; 12421 case CastOpIntToFloat: 12422 { 12423 assert(new_type->id == ZigTypeIdFloat); 12424 12425 BigFloat bigfloat; 12426 bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint); 12427 switch (new_type->data.floating.bit_count) { 12428 case 16: 12429 const_val->data.x_f16 = bigfloat_to_f16(&bigfloat); 12430 break; 12431 case 32: 12432 const_val->data.x_f32 = bigfloat_to_f32(&bigfloat); 12433 break; 12434 case 64: 12435 const_val->data.x_f64 = bigfloat_to_f64(&bigfloat); 12436 break; 12437 case 80: 12438 zig_panic("TODO"); 12439 case 128: 12440 const_val->data.x_f128 = bigfloat_to_f128(&bigfloat); 12441 break; 12442 default: 12443 zig_unreachable(); 12444 } 12445 const_val->special = ConstValSpecialStatic; 12446 break; 12447 } 12448 case CastOpFloatToInt: 12449 float_init_bigint(&const_val->data.x_bigint, other_val); 12450 if (new_type->id == ZigTypeIdInt) { 12451 if (!bigint_fits_in_bits(&const_val->data.x_bigint, new_type->data.integral.bit_count, 12452 new_type->data.integral.is_signed)) 12453 { 12454 Buf *int_buf = buf_alloc(); 12455 bigint_append_buf(int_buf, &const_val->data.x_bigint, 10); 12456 12457 ir_add_error(ira, source_instr, 12458 buf_sprintf("integer value '%s' cannot be stored in type '%s'", 12459 buf_ptr(int_buf), buf_ptr(&new_type->name))); 12460 return false; 12461 } 12462 } 12463 12464 const_val->special = ConstValSpecialStatic; 12465 break; 12466 case CastOpBoolToInt: 12467 bigint_init_unsigned(&const_val->data.x_bigint, other_val->data.x_bool ? 1 : 0); 12468 const_val->special = ConstValSpecialStatic; 12469 break; 12470 } 12471 return true; 12472 } 12473 12474 static IrInstGen *ir_const(IrAnalyze *ira, IrInst *inst, ZigType *ty) { 12475 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 12476 inst->scope, inst->source_node); 12477 IrInstGen *new_instruction = &const_instruction->base; 12478 new_instruction->value->type = ty; 12479 new_instruction->value->special = ConstValSpecialStatic; 12480 ira->new_irb.constants.append(&heap::c_allocator, const_instruction); 12481 return new_instruction; 12482 } 12483 12484 static IrInstGen *ir_const_noval(IrAnalyze *ira, IrInst *old_instruction) { 12485 IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb, 12486 old_instruction->scope, old_instruction->source_node); 12487 ira->new_irb.constants.append(&heap::c_allocator, const_instruction); 12488 return &const_instruction->base; 12489 } 12490 12491 // This function initializes the new IrInstGen with the provided ZigValue, 12492 // rather than creating a new one. 12493 static IrInstGen *ir_const_move(IrAnalyze *ira, IrInst *old_instruction, ZigValue *val) { 12494 IrInstGen *result = ir_const_noval(ira, old_instruction); 12495 result->value = val; 12496 return result; 12497 } 12498 12499 static IrInstGen *ir_resolve_cast(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, 12500 ZigType *wanted_type, CastOp cast_op) 12501 { 12502 if (instr_is_comptime(value) || !type_has_bits(wanted_type)) { 12503 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 12504 if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, value->value, value->value->type, 12505 result->value, wanted_type)) 12506 { 12507 return ira->codegen->invalid_inst_gen; 12508 } 12509 return result; 12510 } else { 12511 return ir_build_cast(ira, source_instr, wanted_type, value, cast_op); 12512 } 12513 } 12514 12515 static IrInstGen *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, IrInst* source_instr, 12516 IrInstGen *value, ZigType *wanted_type) 12517 { 12518 ir_assert(value->value->type->id == ZigTypeIdPointer, source_instr); 12519 12520 Error err; 12521 12522 if ((err = type_resolve(ira->codegen, value->value->type->data.pointer.child_type, 12523 ResolveStatusAlignmentKnown))) 12524 { 12525 return ira->codegen->invalid_inst_gen; 12526 } 12527 12528 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value->type)); 12529 12530 if (instr_is_comptime(value)) { 12531 ZigValue *val = ir_resolve_const(ira, value, UndefOk); 12532 if (val == nullptr) 12533 return ira->codegen->invalid_inst_gen; 12534 if (val->special == ConstValSpecialUndef) 12535 return ir_const_undef(ira, source_instr, wanted_type); 12536 12537 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 12538 if (pointee == nullptr) 12539 return ira->codegen->invalid_inst_gen; 12540 if (pointee->special != ConstValSpecialRuntime) { 12541 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 12542 result->value->data.x_ptr.special = ConstPtrSpecialBaseArray; 12543 result->value->data.x_ptr.mut = val->data.x_ptr.mut; 12544 result->value->data.x_ptr.data.base_array.array_val = pointee; 12545 result->value->data.x_ptr.data.base_array.elem_index = 0; 12546 return result; 12547 } 12548 } 12549 12550 return ir_build_cast(ira, source_instr, wanted_type, value, CastOpBitCast); 12551 } 12552 12553 static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* source_instr, 12554 IrInstGen *array_ptr, ZigType *wanted_type, ResultLoc *result_loc) 12555 { 12556 Error err; 12557 12558 if ((err = type_resolve(ira->codegen, array_ptr->value->type->data.pointer.child_type, 12559 ResolveStatusAlignmentKnown))) 12560 { 12561 return ira->codegen->invalid_inst_gen; 12562 } 12563 12564 wanted_type = adjust_slice_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, array_ptr->value->type)); 12565 12566 if (instr_is_comptime(array_ptr)) { 12567 ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, UndefBad); 12568 if (array_ptr_val == nullptr) 12569 return ira->codegen->invalid_inst_gen; 12570 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, array_ptr_val, source_instr->source_node); 12571 if (pointee == nullptr) 12572 return ira->codegen->invalid_inst_gen; 12573 if (pointee->special != ConstValSpecialRuntime) { 12574 assert(array_ptr_val->type->id == ZigTypeIdPointer); 12575 ZigType *array_type = array_ptr_val->type->data.pointer.child_type; 12576 assert(is_slice(wanted_type)); 12577 bool is_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const; 12578 12579 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 12580 init_const_slice(ira->codegen, result->value, pointee, 0, array_type->data.array.len, is_const); 12581 result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; 12582 result->value->type = wanted_type; 12583 return result; 12584 } 12585 } 12586 12587 if (result_loc == nullptr) result_loc = no_result_loc(); 12588 IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); 12589 if (type_is_invalid(result_loc_inst->value->type) || 12590 result_loc_inst->value->type->id == ZigTypeIdUnreachable) 12591 { 12592 return result_loc_inst; 12593 } 12594 return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, array_ptr, result_loc_inst); 12595 } 12596 12597 static IrBasicBlockGen *ir_get_new_bb(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrInst *ref_old_instruction) { 12598 assert(old_bb); 12599 12600 if (old_bb->child) { 12601 if (ref_old_instruction == nullptr || old_bb->child->ref_instruction != ref_old_instruction) { 12602 return old_bb->child; 12603 } 12604 } 12605 12606 IrBasicBlockGen *new_bb = ir_build_bb_from(ira, old_bb); 12607 new_bb->ref_instruction = ref_old_instruction; 12608 12609 return new_bb; 12610 } 12611 12612 static IrBasicBlockGen *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrInst *ref_old_instruction) { 12613 assert(ref_old_instruction != nullptr); 12614 IrBasicBlockGen *new_bb = ir_get_new_bb(ira, old_bb, ref_old_instruction); 12615 if (new_bb->must_be_comptime_source_instr) { 12616 ErrorMsg *msg = ir_add_error(ira, ref_old_instruction, 12617 buf_sprintf("control flow attempts to use compile-time variable at runtime")); 12618 add_error_note(ira->codegen, msg, new_bb->must_be_comptime_source_instr->source_node, 12619 buf_sprintf("compile-time variable assigned here")); 12620 return nullptr; 12621 } 12622 return new_bb; 12623 } 12624 12625 static void ir_start_bb(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrBasicBlockSrc *const_predecessor_bb) { 12626 ir_assert(!old_bb->suspended, (old_bb->instruction_list.length != 0) ? &old_bb->instruction_list.at(0)->base : nullptr); 12627 ira->instruction_index = 0; 12628 ira->old_irb.current_basic_block = old_bb; 12629 ira->const_predecessor_bb = const_predecessor_bb; 12630 ira->old_bb_index = old_bb->index; 12631 } 12632 12633 static IrInstGen *ira_suspend(IrAnalyze *ira, IrInst *old_instruction, IrBasicBlockSrc *next_bb, 12634 IrSuspendPosition *suspend_pos) 12635 { 12636 if (ira->codegen->verbose_ir) { 12637 fprintf(stderr, "suspend %s_%" PRIu32 " %s_%" PRIu32 " #%" PRIu32 " (%zu,%zu)\n", 12638 ira->old_irb.current_basic_block->name_hint, 12639 ira->old_irb.current_basic_block->debug_id, 12640 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint, 12641 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id, 12642 ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->base.debug_id, 12643 ira->old_bb_index, ira->instruction_index); 12644 } 12645 suspend_pos->basic_block_index = ira->old_bb_index; 12646 suspend_pos->instruction_index = ira->instruction_index; 12647 12648 ira->old_irb.current_basic_block->suspended = true; 12649 12650 // null next_bb means that the caller plans to call ira_resume before returning 12651 if (next_bb != nullptr) { 12652 ira->old_bb_index = next_bb->index; 12653 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 12654 assert(ira->old_irb.current_basic_block == next_bb); 12655 ira->instruction_index = 0; 12656 ira->const_predecessor_bb = nullptr; 12657 next_bb->child = ir_get_new_bb_runtime(ira, next_bb, old_instruction); 12658 ira->new_irb.current_basic_block = next_bb->child; 12659 } 12660 return ira->codegen->unreach_instruction; 12661 } 12662 12663 static IrInstGen *ira_resume(IrAnalyze *ira) { 12664 IrSuspendPosition pos = ira->resume_stack.pop(); 12665 if (ira->codegen->verbose_ir) { 12666 fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index); 12667 } 12668 ira->old_bb_index = pos.basic_block_index; 12669 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 12670 assert(ira->old_irb.current_basic_block->in_resume_stack); 12671 ira->old_irb.current_basic_block->in_resume_stack = false; 12672 ira->old_irb.current_basic_block->suspended = false; 12673 ira->instruction_index = pos.instruction_index; 12674 assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length); 12675 if (ira->codegen->verbose_ir) { 12676 fprintf(stderr, "%s_%" PRIu32 " #%" PRIu32 "\n", ira->old_irb.current_basic_block->name_hint, 12677 ira->old_irb.current_basic_block->debug_id, 12678 ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->base.debug_id); 12679 } 12680 ira->const_predecessor_bb = nullptr; 12681 ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->child; 12682 assert(ira->new_irb.current_basic_block != nullptr); 12683 return ira->codegen->unreach_instruction; 12684 } 12685 12686 static void ir_start_next_bb(IrAnalyze *ira) { 12687 ira->old_bb_index += 1; 12688 12689 bool need_repeat = true; 12690 for (;;) { 12691 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 12692 IrBasicBlockSrc *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 12693 if (old_bb->child == nullptr && old_bb->suspend_instruction_ref == nullptr) { 12694 ira->old_bb_index += 1; 12695 continue; 12696 } 12697 // if it's already started, or 12698 // if it's a suspended block, 12699 // then skip it 12700 if (old_bb->suspended || 12701 (old_bb->child != nullptr && old_bb->child->instruction_list.length != 0) || 12702 (old_bb->child != nullptr && old_bb->child->already_appended)) 12703 { 12704 ira->old_bb_index += 1; 12705 continue; 12706 } 12707 12708 // if there is a resume_stack, pop one from there rather than moving on. 12709 // the last item of the resume stack will be a basic block that will 12710 // move on to the next one below 12711 if (ira->resume_stack.length != 0) { 12712 ira_resume(ira); 12713 return; 12714 } 12715 12716 if (old_bb->child == nullptr) { 12717 old_bb->child = ir_get_new_bb_runtime(ira, old_bb, old_bb->suspend_instruction_ref); 12718 } 12719 ira->new_irb.current_basic_block = old_bb->child; 12720 ir_start_bb(ira, old_bb, nullptr); 12721 return; 12722 } 12723 if (!need_repeat) { 12724 if (ira->resume_stack.length != 0) { 12725 ira_resume(ira); 12726 } 12727 return; 12728 } 12729 need_repeat = false; 12730 ira->old_bb_index = 0; 12731 continue; 12732 } 12733 } 12734 12735 static void ir_finish_bb(IrAnalyze *ira) { 12736 if (!ira->new_irb.current_basic_block->already_appended) { 12737 ira->new_irb.current_basic_block->already_appended = true; 12738 if (ira->codegen->verbose_ir) { 12739 fprintf(stderr, "append new bb %s_%" PRIu32 "\n", ira->new_irb.current_basic_block->name_hint, 12740 ira->new_irb.current_basic_block->debug_id); 12741 } 12742 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); 12743 } 12744 ira->instruction_index += 1; 12745 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { 12746 IrInstSrc *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 12747 if (!next_instruction->is_gen) { 12748 ir_add_error(ira, &next_instruction->base, buf_sprintf("unreachable code")); 12749 break; 12750 } 12751 ira->instruction_index += 1; 12752 } 12753 12754 ir_start_next_bb(ira); 12755 } 12756 12757 static IrInstGen *ir_unreach_error(IrAnalyze *ira) { 12758 ira->old_bb_index = SIZE_MAX; 12759 if (ira->new_irb.exec->first_err_trace_msg == nullptr) { 12760 ira->new_irb.exec->first_err_trace_msg = ira->codegen->trace_err; 12761 } 12762 return ira->codegen->unreach_instruction; 12763 } 12764 12765 static bool ir_emit_backward_branch(IrAnalyze *ira, IrInst* source_instruction) { 12766 size_t *bbc = ira->new_irb.exec->backward_branch_count; 12767 size_t *quota = ira->new_irb.exec->backward_branch_quota; 12768 12769 // If we're already over quota, we've already given an error message for this. 12770 if (*bbc > *quota) { 12771 assert(ira->codegen->errors.length > 0); 12772 return false; 12773 } 12774 12775 *bbc += 1; 12776 if (*bbc > *quota) { 12777 ir_add_error(ira, source_instruction, 12778 buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", *quota)); 12779 return false; 12780 } 12781 return true; 12782 } 12783 12784 static IrInstGen *ir_inline_bb(IrAnalyze *ira, IrInst* source_instruction, IrBasicBlockSrc *old_bb) { 12785 if (old_bb->debug_id <= ira->old_irb.current_basic_block->debug_id) { 12786 if (!ir_emit_backward_branch(ira, source_instruction)) 12787 return ir_unreach_error(ira); 12788 } 12789 12790 old_bb->child = ira->old_irb.current_basic_block->child; 12791 ir_start_bb(ira, old_bb, ira->old_irb.current_basic_block); 12792 return ira->codegen->unreach_instruction; 12793 } 12794 12795 static IrInstGen *ir_finish_anal(IrAnalyze *ira, IrInstGen *instruction) { 12796 if (instruction->value->type->id == ZigTypeIdUnreachable) 12797 ir_finish_bb(ira); 12798 return instruction; 12799 } 12800 12801 static IrInstGen *ir_const_fn(IrAnalyze *ira, IrInst *source_instr, ZigFn *fn_entry) { 12802 IrInstGen *result = ir_const(ira, source_instr, fn_entry->type_entry); 12803 result->value->special = ConstValSpecialStatic; 12804 result->value->data.x_ptr.data.fn.fn_entry = fn_entry; 12805 result->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 12806 result->value->data.x_ptr.special = ConstPtrSpecialFunction; 12807 return result; 12808 } 12809 12810 static IrInstGen *ir_const_bound_fn(IrAnalyze *ira, IrInst *src_inst, ZigFn *fn_entry, IrInstGen *first_arg, 12811 IrInst *first_arg_src) 12812 { 12813 IrInstGen *result = ir_const(ira, src_inst, get_bound_fn_type(ira->codegen, fn_entry)); 12814 result->value->data.x_bound_fn.fn = fn_entry; 12815 result->value->data.x_bound_fn.first_arg = first_arg; 12816 result->value->data.x_bound_fn.first_arg_src = first_arg_src; 12817 return result; 12818 } 12819 12820 static IrInstGen *ir_const_type(IrAnalyze *ira, IrInst *source_instruction, ZigType *ty) { 12821 IrInstGen *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_type); 12822 result->value->data.x_type = ty; 12823 return result; 12824 } 12825 12826 static IrInstGen *ir_const_bool(IrAnalyze *ira, IrInst *source_instruction, bool value) { 12827 IrInstGen *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_bool); 12828 result->value->data.x_bool = value; 12829 return result; 12830 } 12831 12832 static IrInstGen *ir_const_undef(IrAnalyze *ira, IrInst *source_instruction, ZigType *ty) { 12833 IrInstGen *result = ir_const(ira, source_instruction, ty); 12834 result->value->special = ConstValSpecialUndef; 12835 return result; 12836 } 12837 12838 static IrInstGen *ir_const_unreachable(IrAnalyze *ira, IrInst *source_instruction) { 12839 IrInstGen *result = ir_const_noval(ira, source_instruction); 12840 result->value = ira->codegen->intern.for_unreachable(); 12841 return result; 12842 } 12843 12844 static IrInstGen *ir_const_void(IrAnalyze *ira, IrInst *source_instruction) { 12845 IrInstGen *result = ir_const_noval(ira, source_instruction); 12846 result->value = ira->codegen->intern.for_void(); 12847 return result; 12848 } 12849 12850 static IrInstGen *ir_const_unsigned(IrAnalyze *ira, IrInst *source_instruction, uint64_t value) { 12851 IrInstGen *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_num_lit_int); 12852 bigint_init_unsigned(&result->value->data.x_bigint, value); 12853 return result; 12854 } 12855 12856 static IrInstGen *ir_get_const_ptr(IrAnalyze *ira, IrInst *instruction, 12857 ZigValue *pointee, ZigType *pointee_type, 12858 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align) 12859 { 12860 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type, 12861 ptr_is_const, ptr_is_volatile, PtrLenSingle, ptr_align, 0, 0, false); 12862 IrInstGen *const_instr = ir_const(ira, instruction, ptr_type); 12863 ZigValue *const_val = const_instr->value; 12864 const_val->data.x_ptr.special = ConstPtrSpecialRef; 12865 const_val->data.x_ptr.mut = ptr_mut; 12866 const_val->data.x_ptr.data.ref.pointee = pointee; 12867 return const_instr; 12868 } 12869 12870 static Error ir_resolve_const_val(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, 12871 ZigValue *val, UndefAllowed undef_allowed) 12872 { 12873 Error err; 12874 for (;;) { 12875 switch (val->special) { 12876 case ConstValSpecialStatic: 12877 return ErrorNone; 12878 case ConstValSpecialRuntime: 12879 if (!type_has_bits(val->type)) 12880 return ErrorNone; 12881 12882 exec_add_error_node_gen(codegen, exec, source_node, 12883 buf_sprintf("unable to evaluate constant expression")); 12884 return ErrorSemanticAnalyzeFail; 12885 case ConstValSpecialUndef: 12886 if (undef_allowed == UndefOk || undef_allowed == LazyOk) 12887 return ErrorNone; 12888 12889 exec_add_error_node_gen(codegen, exec, source_node, 12890 buf_sprintf("use of undefined value here causes undefined behavior")); 12891 return ErrorSemanticAnalyzeFail; 12892 case ConstValSpecialLazy: 12893 if (undef_allowed == LazyOk || undef_allowed == LazyOkNoUndef) 12894 return ErrorNone; 12895 12896 if ((err = ir_resolve_lazy(codegen, source_node, val))) 12897 return err; 12898 12899 continue; 12900 } 12901 } 12902 } 12903 12904 static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed undef_allowed) { 12905 Error err; 12906 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, value->base.source_node, 12907 value->value, undef_allowed))) 12908 { 12909 return nullptr; 12910 } 12911 return value->value; 12912 } 12913 12914 Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, 12915 ZigValue *return_ptr, size_t *backward_branch_count, size_t *backward_branch_quota, 12916 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, 12917 IrExecutableGen *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef_allowed) 12918 { 12919 Error err; 12920 12921 src_assert(return_ptr->type->id == ZigTypeIdPointer, source_node); 12922 12923 if (type_is_invalid(return_ptr->type)) 12924 return ErrorSemanticAnalyzeFail; 12925 12926 IrExecutableSrc *ir_executable = heap::c_allocator.create<IrExecutableSrc>(); 12927 ir_executable->source_node = source_node; 12928 ir_executable->parent_exec = parent_exec; 12929 ir_executable->name = exec_name; 12930 ir_executable->is_inline = true; 12931 ir_executable->fn_entry = fn_entry; 12932 ir_executable->c_import_buf = c_import_buf; 12933 ir_executable->begin_scope = scope; 12934 12935 if (!ir_gen(codegen, node, scope, ir_executable)) 12936 return ErrorSemanticAnalyzeFail; 12937 12938 if (ir_executable->first_err_trace_msg != nullptr) { 12939 codegen->trace_err = ir_executable->first_err_trace_msg; 12940 return ErrorSemanticAnalyzeFail; 12941 } 12942 12943 if (codegen->verbose_ir) { 12944 fprintf(stderr, "\nSource: "); 12945 ast_render(stderr, node, 4); 12946 fprintf(stderr, "\n{ // (IR)\n"); 12947 ir_print_src(codegen, stderr, ir_executable, 2); 12948 fprintf(stderr, "}\n"); 12949 } 12950 IrExecutableGen *analyzed_executable = heap::c_allocator.create<IrExecutableGen>(); 12951 analyzed_executable->source_node = source_node; 12952 analyzed_executable->parent_exec = parent_exec; 12953 analyzed_executable->source_exec = ir_executable; 12954 analyzed_executable->name = exec_name; 12955 analyzed_executable->is_inline = true; 12956 analyzed_executable->fn_entry = fn_entry; 12957 analyzed_executable->c_import_buf = c_import_buf; 12958 analyzed_executable->backward_branch_count = backward_branch_count; 12959 analyzed_executable->backward_branch_quota = backward_branch_quota; 12960 analyzed_executable->begin_scope = scope; 12961 ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, 12962 return_ptr->type->data.pointer.child_type, expected_type_source_node, return_ptr); 12963 if (type_is_invalid(result_type)) { 12964 return ErrorSemanticAnalyzeFail; 12965 } 12966 12967 if (codegen->verbose_ir) { 12968 fprintf(stderr, "{ // (analyzed)\n"); 12969 ir_print_gen(codegen, stderr, analyzed_executable, 2); 12970 fprintf(stderr, "}\n"); 12971 } 12972 12973 if ((err = ir_exec_scan_for_side_effects(codegen, analyzed_executable))) 12974 return err; 12975 12976 ZigValue *result = const_ptr_pointee(nullptr, codegen, return_ptr, source_node); 12977 if (result == nullptr) 12978 return ErrorSemanticAnalyzeFail; 12979 if ((err = ir_resolve_const_val(codegen, analyzed_executable, node, result, undef_allowed))) 12980 return err; 12981 12982 return ErrorNone; 12983 } 12984 12985 static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstGen *err_value) { 12986 if (type_is_invalid(err_value->value->type)) 12987 return nullptr; 12988 12989 if (err_value->value->type->id != ZigTypeIdErrorSet) { 12990 ir_add_error_node(ira, err_value->base.source_node, 12991 buf_sprintf("expected error, found '%s'", buf_ptr(&err_value->value->type->name))); 12992 return nullptr; 12993 } 12994 12995 ZigValue *const_val = ir_resolve_const(ira, err_value, UndefBad); 12996 if (!const_val) 12997 return nullptr; 12998 12999 assert(const_val->data.x_err_set != nullptr); 13000 return const_val->data.x_err_set; 13001 } 13002 13003 static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, 13004 ZigValue *val) 13005 { 13006 Error err; 13007 if ((err = ir_resolve_const_val(codegen, exec, source_node, val, UndefBad))) 13008 return codegen->builtin_types.entry_invalid; 13009 13010 assert(val->data.x_type != nullptr); 13011 return val->data.x_type; 13012 } 13013 13014 static ZigValue *ir_resolve_type_lazy(IrAnalyze *ira, IrInstGen *type_value) { 13015 if (type_is_invalid(type_value->value->type)) 13016 return nullptr; 13017 13018 if (type_value->value->type->id != ZigTypeIdMetaType) { 13019 ir_add_error_node(ira, type_value->base.source_node, 13020 buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->value->type->name))); 13021 return nullptr; 13022 } 13023 13024 Error err; 13025 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, type_value->base.source_node, 13026 type_value->value, LazyOk))) 13027 { 13028 return nullptr; 13029 } 13030 13031 return type_value->value; 13032 } 13033 13034 static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstGen *type_value) { 13035 ZigValue *val = ir_resolve_type_lazy(ira, type_value); 13036 if (val == nullptr) 13037 return ira->codegen->builtin_types.entry_invalid; 13038 13039 return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->base.source_node, val); 13040 } 13041 13042 static Error ir_validate_vector_elem_type(IrAnalyze *ira, AstNode *source_node, ZigType *elem_type) { 13043 if (!is_valid_vector_elem_type(elem_type)) { 13044 ir_add_error_node(ira, source_node, 13045 buf_sprintf("vector element type must be integer, float, bool, or pointer; '%s' is invalid", 13046 buf_ptr(&elem_type->name))); 13047 return ErrorSemanticAnalyzeFail; 13048 } 13049 return ErrorNone; 13050 } 13051 13052 static ZigType *ir_resolve_vector_elem_type(IrAnalyze *ira, IrInstGen *elem_type_value) { 13053 Error err; 13054 ZigType *elem_type = ir_resolve_type(ira, elem_type_value); 13055 if (type_is_invalid(elem_type)) 13056 return ira->codegen->builtin_types.entry_invalid; 13057 if ((err = ir_validate_vector_elem_type(ira, elem_type_value->base.source_node, elem_type))) 13058 return ira->codegen->builtin_types.entry_invalid; 13059 return elem_type; 13060 } 13061 13062 static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstGen *type_value) { 13063 ZigType *ty = ir_resolve_type(ira, type_value); 13064 if (type_is_invalid(ty)) 13065 return ira->codegen->builtin_types.entry_invalid; 13066 13067 if (ty->id != ZigTypeIdInt) { 13068 ErrorMsg *msg = ir_add_error_node(ira, type_value->base.source_node, 13069 buf_sprintf("expected integer type, found '%s'", buf_ptr(&ty->name))); 13070 if (ty->id == ZigTypeIdVector && 13071 ty->data.vector.elem_type->id == ZigTypeIdInt) 13072 { 13073 add_error_note(ira->codegen, msg, type_value->base.source_node, 13074 buf_sprintf("represent vectors with their element types, i.e. '%s'", 13075 buf_ptr(&ty->data.vector.elem_type->name))); 13076 } 13077 return ira->codegen->builtin_types.entry_invalid; 13078 } 13079 13080 return ty; 13081 } 13082 13083 static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInst *op_source, IrInstGen *type_value) { 13084 if (type_is_invalid(type_value->value->type)) 13085 return ira->codegen->builtin_types.entry_invalid; 13086 13087 if (type_value->value->type->id != ZigTypeIdMetaType) { 13088 ErrorMsg *msg = ir_add_error_node(ira, type_value->base.source_node, 13089 buf_sprintf("expected error set type, found '%s'", buf_ptr(&type_value->value->type->name))); 13090 add_error_note(ira->codegen, msg, op_source->source_node, 13091 buf_sprintf("`||` merges error sets; `or` performs boolean OR")); 13092 return ira->codegen->builtin_types.entry_invalid; 13093 } 13094 13095 ZigValue *const_val = ir_resolve_const(ira, type_value, UndefBad); 13096 if (!const_val) 13097 return ira->codegen->builtin_types.entry_invalid; 13098 13099 assert(const_val->data.x_type != nullptr); 13100 ZigType *result_type = const_val->data.x_type; 13101 if (result_type->id != ZigTypeIdErrorSet) { 13102 ErrorMsg *msg = ir_add_error_node(ira, type_value->base.source_node, 13103 buf_sprintf("expected error set type, found type '%s'", buf_ptr(&result_type->name))); 13104 add_error_note(ira->codegen, msg, op_source->source_node, 13105 buf_sprintf("`||` merges error sets; `or` performs boolean OR")); 13106 return ira->codegen->builtin_types.entry_invalid; 13107 } 13108 return result_type; 13109 } 13110 13111 static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstGen *fn_value) { 13112 if (type_is_invalid(fn_value->value->type)) 13113 return nullptr; 13114 13115 if (fn_value->value->type->id != ZigTypeIdFn) { 13116 ir_add_error_node(ira, fn_value->base.source_node, 13117 buf_sprintf("expected function type, found '%s'", buf_ptr(&fn_value->value->type->name))); 13118 return nullptr; 13119 } 13120 13121 ZigValue *const_val = ir_resolve_const(ira, fn_value, UndefBad); 13122 if (!const_val) 13123 return nullptr; 13124 13125 // May be a ConstPtrSpecialHardCodedAddr 13126 if (const_val->data.x_ptr.special != ConstPtrSpecialFunction) 13127 return nullptr; 13128 13129 return const_val->data.x_ptr.data.fn.fn_entry; 13130 } 13131 13132 static IrInstGen *ir_analyze_optional_wrap(IrAnalyze *ira, IrInst* source_instr, 13133 IrInstGen *value, ZigType *wanted_type, ResultLoc *result_loc) 13134 { 13135 assert(wanted_type->id == ZigTypeIdOptional); 13136 13137 if (instr_is_comptime(value)) { 13138 ZigType *payload_type = wanted_type->data.maybe.child_type; 13139 IrInstGen *casted_payload = ir_implicit_cast(ira, value, payload_type); 13140 if (type_is_invalid(casted_payload->value->type)) 13141 return ira->codegen->invalid_inst_gen; 13142 13143 ZigValue *val = ir_resolve_const(ira, casted_payload, UndefOk); 13144 if (!val) 13145 return ira->codegen->invalid_inst_gen; 13146 13147 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 13148 source_instr->scope, source_instr->source_node); 13149 const_instruction->base.value->special = ConstValSpecialStatic; 13150 if (types_have_same_zig_comptime_repr(ira->codegen, wanted_type, payload_type)) { 13151 copy_const_val(ira->codegen, const_instruction->base.value, val); 13152 } else { 13153 const_instruction->base.value->data.x_optional = val; 13154 } 13155 const_instruction->base.value->type = wanted_type; 13156 return &const_instruction->base; 13157 } 13158 13159 if (result_loc == nullptr && handle_is_ptr(wanted_type)) { 13160 result_loc = no_result_loc(); 13161 } 13162 IrInstGen *result_loc_inst = nullptr; 13163 if (result_loc != nullptr) { 13164 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); 13165 if (type_is_invalid(result_loc_inst->value->type) || 13166 result_loc_inst->value->type->id == ZigTypeIdUnreachable) 13167 { 13168 return result_loc_inst; 13169 } 13170 } 13171 IrInstGen *result = ir_build_optional_wrap(ira, source_instr, wanted_type, value, result_loc_inst); 13172 result->value->data.rh_maybe = RuntimeHintOptionalNonNull; 13173 return result; 13174 } 13175 13176 static IrInstGen *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInst* source_instr, 13177 IrInstGen *value, ZigType *wanted_type, ResultLoc *result_loc) 13178 { 13179 assert(wanted_type->id == ZigTypeIdErrorUnion); 13180 13181 ZigType *payload_type = wanted_type->data.error_union.payload_type; 13182 ZigType *err_set_type = wanted_type->data.error_union.err_set_type; 13183 if (instr_is_comptime(value)) { 13184 IrInstGen *casted_payload = ir_implicit_cast(ira, value, payload_type); 13185 if (type_is_invalid(casted_payload->value->type)) 13186 return ira->codegen->invalid_inst_gen; 13187 13188 ZigValue *val = ir_resolve_const(ira, casted_payload, UndefOk); 13189 if (val == nullptr) 13190 return ira->codegen->invalid_inst_gen; 13191 13192 ZigValue *err_set_val = ira->codegen->pass1_arena->create<ZigValue>(); 13193 err_set_val->type = err_set_type; 13194 err_set_val->special = ConstValSpecialStatic; 13195 err_set_val->data.x_err_set = nullptr; 13196 13197 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 13198 source_instr->scope, source_instr->source_node); 13199 const_instruction->base.value->type = wanted_type; 13200 const_instruction->base.value->special = ConstValSpecialStatic; 13201 const_instruction->base.value->data.x_err_union.error_set = err_set_val; 13202 const_instruction->base.value->data.x_err_union.payload = val; 13203 return &const_instruction->base; 13204 } 13205 13206 IrInstGen *result_loc_inst; 13207 if (handle_is_ptr(wanted_type)) { 13208 if (result_loc == nullptr) result_loc = no_result_loc(); 13209 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); 13210 if (type_is_invalid(result_loc_inst->value->type) || 13211 result_loc_inst->value->type->id == ZigTypeIdUnreachable) { 13212 return result_loc_inst; 13213 } 13214 } else { 13215 result_loc_inst = nullptr; 13216 } 13217 13218 IrInstGen *result = ir_build_err_wrap_payload(ira, source_instr, wanted_type, value, result_loc_inst); 13219 result->value->data.rh_error_union = RuntimeHintErrorUnionNonError; 13220 return result; 13221 } 13222 13223 static IrInstGen *ir_analyze_err_set_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 13224 ZigType *wanted_type) 13225 { 13226 assert(value->value->type->id == ZigTypeIdErrorSet); 13227 assert(wanted_type->id == ZigTypeIdErrorSet); 13228 13229 if (instr_is_comptime(value)) { 13230 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 13231 if (!val) 13232 return ira->codegen->invalid_inst_gen; 13233 13234 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 13235 return ira->codegen->invalid_inst_gen; 13236 } 13237 if (!type_is_global_error_set(wanted_type)) { 13238 bool subset = false; 13239 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 13240 if (wanted_type->data.error_set.errors[i]->value == val->data.x_err_set->value) { 13241 subset = true; 13242 break; 13243 } 13244 } 13245 if (!subset) { 13246 ir_add_error(ira, source_instr, 13247 buf_sprintf("error.%s not a member of error set '%s'", 13248 buf_ptr(&val->data.x_err_set->name), buf_ptr(&wanted_type->name))); 13249 return ira->codegen->invalid_inst_gen; 13250 } 13251 } 13252 13253 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 13254 source_instr->scope, source_instr->source_node); 13255 const_instruction->base.value->type = wanted_type; 13256 const_instruction->base.value->special = ConstValSpecialStatic; 13257 const_instruction->base.value->data.x_err_set = val->data.x_err_set; 13258 return &const_instruction->base; 13259 } 13260 13261 return ir_build_cast(ira, source_instr, wanted_type, value, CastOpErrSet); 13262 } 13263 13264 static IrInstGen *ir_analyze_frame_ptr_to_anyframe(IrAnalyze *ira, IrInst* source_instr, 13265 IrInstGen *frame_ptr, ZigType *wanted_type) 13266 { 13267 if (instr_is_comptime(frame_ptr)) { 13268 ZigValue *ptr_val = ir_resolve_const(ira, frame_ptr, UndefBad); 13269 if (ptr_val == nullptr) 13270 return ira->codegen->invalid_inst_gen; 13271 13272 ir_assert(ptr_val->type->id == ZigTypeIdPointer, source_instr); 13273 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 13274 zig_panic("TODO comptime frame pointer"); 13275 } 13276 } 13277 13278 return ir_build_cast(ira, source_instr, wanted_type, frame_ptr, CastOpBitCast); 13279 } 13280 13281 static IrInstGen *ir_analyze_anyframe_to_anyframe(IrAnalyze *ira, IrInst* source_instr, 13282 IrInstGen *value, ZigType *wanted_type) 13283 { 13284 if (instr_is_comptime(value)) { 13285 zig_panic("TODO comptime anyframe->T to anyframe"); 13286 } 13287 13288 return ir_build_cast(ira, source_instr, wanted_type, value, CastOpBitCast); 13289 } 13290 13291 13292 static IrInstGen *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 13293 ZigType *wanted_type, ResultLoc *result_loc) 13294 { 13295 assert(wanted_type->id == ZigTypeIdErrorUnion); 13296 13297 IrInstGen *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); 13298 13299 if (instr_is_comptime(casted_value)) { 13300 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); 13301 if (!val) 13302 return ira->codegen->invalid_inst_gen; 13303 13304 ZigValue *err_set_val = ira->codegen->pass1_arena->create<ZigValue>(); 13305 err_set_val->special = ConstValSpecialStatic; 13306 err_set_val->type = wanted_type->data.error_union.err_set_type; 13307 err_set_val->data.x_err_set = val->data.x_err_set; 13308 13309 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 13310 source_instr->scope, source_instr->source_node); 13311 const_instruction->base.value->type = wanted_type; 13312 const_instruction->base.value->special = ConstValSpecialStatic; 13313 const_instruction->base.value->data.x_err_union.error_set = err_set_val; 13314 const_instruction->base.value->data.x_err_union.payload = nullptr; 13315 return &const_instruction->base; 13316 } 13317 13318 IrInstGen *result_loc_inst; 13319 if (handle_is_ptr(wanted_type)) { 13320 if (result_loc == nullptr) result_loc = no_result_loc(); 13321 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); 13322 if (type_is_invalid(result_loc_inst->value->type) || 13323 result_loc_inst->value->type->id == ZigTypeIdUnreachable) 13324 { 13325 return result_loc_inst; 13326 } 13327 } else { 13328 result_loc_inst = nullptr; 13329 } 13330 13331 13332 IrInstGen *result = ir_build_err_wrap_code(ira, source_instr, wanted_type, value, result_loc_inst); 13333 result->value->data.rh_error_union = RuntimeHintErrorUnionError; 13334 return result; 13335 } 13336 13337 static IrInstGen *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, ZigType *wanted_type) { 13338 assert(wanted_type->id == ZigTypeIdOptional); 13339 assert(instr_is_comptime(value)); 13340 13341 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 13342 assert(val != nullptr); 13343 13344 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13345 result->value->special = ConstValSpecialStatic; 13346 if (get_codegen_ptr_type(wanted_type) != nullptr) { 13347 result->value->data.x_ptr.special = ConstPtrSpecialNull; 13348 } else if (is_opt_err_set(wanted_type)) { 13349 result->value->data.x_err_set = nullptr; 13350 } else { 13351 result->value->data.x_optional = nullptr; 13352 } 13353 return result; 13354 } 13355 13356 static IrInstGen *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInst *source_instr, 13357 IrInstGen *value, ZigType *wanted_type) 13358 { 13359 assert(wanted_type->id == ZigTypeIdPointer); 13360 assert(wanted_type->data.pointer.ptr_len == PtrLenC); 13361 assert(instr_is_comptime(value)); 13362 13363 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 13364 assert(val != nullptr); 13365 13366 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13367 result->value->data.x_ptr.special = ConstPtrSpecialNull; 13368 result->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 13369 return result; 13370 } 13371 13372 static IrInstGen *ir_get_ref2(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value, 13373 ZigType *elem_type, bool is_const, bool is_volatile) 13374 { 13375 Error err; 13376 13377 if (type_is_invalid(elem_type)) 13378 return ira->codegen->invalid_inst_gen; 13379 13380 if (instr_is_comptime(value)) { 13381 ZigValue *val = ir_resolve_const(ira, value, LazyOk); 13382 if (!val) 13383 return ira->codegen->invalid_inst_gen; 13384 return ir_get_const_ptr(ira, source_instruction, val, elem_type, 13385 ConstPtrMutComptimeConst, is_const, is_volatile, 0); 13386 } 13387 13388 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, elem_type, 13389 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 13390 13391 if ((err = type_resolve(ira->codegen, ptr_type, ResolveStatusZeroBitsKnown))) 13392 return ira->codegen->invalid_inst_gen; 13393 13394 IrInstGen *result_loc; 13395 if (type_has_bits(ptr_type) && !handle_is_ptr(elem_type)) { 13396 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), elem_type, nullptr, true, true); 13397 } else { 13398 result_loc = nullptr; 13399 } 13400 13401 IrInstGen *new_instruction = ir_build_ref_gen(ira, source_instruction, ptr_type, value, result_loc); 13402 new_instruction->value->data.rh_ptr = RuntimeHintPtrStack; 13403 return new_instruction; 13404 } 13405 13406 static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value, 13407 bool is_const, bool is_volatile) 13408 { 13409 return ir_get_ref2(ira, source_instruction, value, value->value->type, is_const, is_volatile); 13410 } 13411 13412 static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, AstNode *source_node, ZigType *union_type) { 13413 assert(union_type->id == ZigTypeIdUnion); 13414 13415 Error err; 13416 if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) 13417 return ira->codegen->builtin_types.entry_invalid; 13418 13419 AstNode *decl_node = union_type->data.unionation.decl_node; 13420 if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) { 13421 assert(union_type->data.unionation.tag_type != nullptr); 13422 return union_type->data.unionation.tag_type; 13423 } else { 13424 ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("union '%s' has no tag", 13425 buf_ptr(&union_type->name))); 13426 add_error_note(ira->codegen, msg, decl_node, buf_sprintf("consider 'union(enum)' here")); 13427 return ira->codegen->builtin_types.entry_invalid; 13428 } 13429 } 13430 13431 static IrInstGen *ir_analyze_enum_to_int(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target) { 13432 Error err; 13433 13434 IrInstGen *enum_target; 13435 ZigType *enum_type; 13436 if (target->value->type->id == ZigTypeIdUnion) { 13437 enum_type = ir_resolve_union_tag_type(ira, target->base.source_node, target->value->type); 13438 if (type_is_invalid(enum_type)) 13439 return ira->codegen->invalid_inst_gen; 13440 enum_target = ir_implicit_cast(ira, target, enum_type); 13441 if (type_is_invalid(enum_target->value->type)) 13442 return ira->codegen->invalid_inst_gen; 13443 } else if (target->value->type->id == ZigTypeIdEnum) { 13444 enum_target = target; 13445 enum_type = target->value->type; 13446 } else { 13447 ir_add_error_node(ira, target->base.source_node, 13448 buf_sprintf("expected enum, found type '%s'", buf_ptr(&target->value->type->name))); 13449 return ira->codegen->invalid_inst_gen; 13450 } 13451 13452 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown))) 13453 return ira->codegen->invalid_inst_gen; 13454 13455 ZigType *tag_type = enum_type->data.enumeration.tag_int_type; 13456 assert(tag_type->id == ZigTypeIdInt || tag_type->id == ZigTypeIdComptimeInt); 13457 13458 // If there is only one possible tag, then we know at comptime what it is. 13459 if (enum_type->data.enumeration.layout == ContainerLayoutAuto && 13460 enum_type->data.enumeration.src_field_count == 1) 13461 { 13462 IrInstGen *result = ir_const(ira, source_instr, tag_type); 13463 init_const_bigint(result->value, tag_type, 13464 &enum_type->data.enumeration.fields[0].value); 13465 return result; 13466 } 13467 13468 if (instr_is_comptime(enum_target)) { 13469 ZigValue *val = ir_resolve_const(ira, enum_target, UndefBad); 13470 if (!val) 13471 return ira->codegen->invalid_inst_gen; 13472 IrInstGen *result = ir_const(ira, source_instr, tag_type); 13473 init_const_bigint(result->value, tag_type, &val->data.x_enum_tag); 13474 return result; 13475 } 13476 13477 return ir_build_widen_or_shorten(ira, source_instr->scope, source_instr->source_node, enum_target, tag_type); 13478 } 13479 13480 static IrInstGen *ir_analyze_union_to_tag(IrAnalyze *ira, IrInst* source_instr, 13481 IrInstGen *target, ZigType *wanted_type) 13482 { 13483 assert(target->value->type->id == ZigTypeIdUnion); 13484 assert(wanted_type->id == ZigTypeIdEnum); 13485 assert(wanted_type == target->value->type->data.unionation.tag_type); 13486 13487 if (instr_is_comptime(target)) { 13488 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 13489 if (!val) 13490 return ira->codegen->invalid_inst_gen; 13491 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13492 result->value->special = ConstValSpecialStatic; 13493 result->value->type = wanted_type; 13494 bigint_init_bigint(&result->value->data.x_enum_tag, &val->data.x_union.tag); 13495 return result; 13496 } 13497 13498 // If there is only 1 possible tag, then we know at comptime what it is. 13499 if (wanted_type->data.enumeration.layout == ContainerLayoutAuto && 13500 wanted_type->data.enumeration.src_field_count == 1) 13501 { 13502 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13503 result->value->special = ConstValSpecialStatic; 13504 result->value->type = wanted_type; 13505 TypeEnumField *enum_field = target->value->type->data.unionation.fields[0].enum_field; 13506 bigint_init_bigint(&result->value->data.x_enum_tag, &enum_field->value); 13507 return result; 13508 } 13509 13510 return ir_build_union_tag(ira, source_instr, target, wanted_type); 13511 } 13512 13513 static IrInstGen *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInst* source_instr, 13514 IrInstGen *target, ZigType *wanted_type) 13515 { 13516 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13517 result->value->special = ConstValSpecialUndef; 13518 return result; 13519 } 13520 13521 static IrInstGen *ir_analyze_enum_to_union(IrAnalyze *ira, IrInst* source_instr, 13522 IrInstGen *uncasted_target, ZigType *wanted_type) 13523 { 13524 Error err; 13525 assert(wanted_type->id == ZigTypeIdUnion); 13526 13527 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown))) 13528 return ira->codegen->invalid_inst_gen; 13529 13530 IrInstGen *target = ir_implicit_cast(ira, uncasted_target, wanted_type->data.unionation.tag_type); 13531 if (type_is_invalid(target->value->type)) 13532 return ira->codegen->invalid_inst_gen; 13533 13534 if (instr_is_comptime(target)) { 13535 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 13536 if (!val) 13537 return ira->codegen->invalid_inst_gen; 13538 TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); 13539 assert(union_field != nullptr); 13540 ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); 13541 if (field_type == nullptr) 13542 return ira->codegen->invalid_inst_gen; 13543 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) 13544 return ira->codegen->invalid_inst_gen; 13545 13546 switch (type_has_one_possible_value(ira->codegen, field_type)) { 13547 case OnePossibleValueInvalid: 13548 return ira->codegen->invalid_inst_gen; 13549 case OnePossibleValueNo: { 13550 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at( 13551 union_field->enum_field->decl_index); 13552 ErrorMsg *msg = ir_add_error(ira, source_instr, 13553 buf_sprintf("cast to union '%s' must initialize '%s' field '%s'", 13554 buf_ptr(&wanted_type->name), 13555 buf_ptr(&field_type->name), 13556 buf_ptr(union_field->name))); 13557 add_error_note(ira->codegen, msg, field_node, 13558 buf_sprintf("field '%s' declared here", buf_ptr(union_field->name))); 13559 return ira->codegen->invalid_inst_gen; 13560 } 13561 case OnePossibleValueYes: 13562 break; 13563 } 13564 13565 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13566 result->value->special = ConstValSpecialStatic; 13567 result->value->type = wanted_type; 13568 bigint_init_bigint(&result->value->data.x_union.tag, &val->data.x_enum_tag); 13569 result->value->data.x_union.payload = ira->codegen->pass1_arena->create<ZigValue>(); 13570 result->value->data.x_union.payload->special = ConstValSpecialStatic; 13571 result->value->data.x_union.payload->type = field_type; 13572 return result; 13573 } 13574 13575 // if the union has all fields 0 bits, we can do it 13576 // and in fact it's a noop cast because the union value is just the enum value 13577 if (wanted_type->data.unionation.gen_field_count == 0) { 13578 return ir_build_cast(ira, &target->base, wanted_type, target, CastOpNoop); 13579 } 13580 13581 ErrorMsg *msg = ir_add_error(ira, source_instr, 13582 buf_sprintf("runtime cast to union '%s' which has non-void fields", 13583 buf_ptr(&wanted_type->name))); 13584 for (uint32_t i = 0; i < wanted_type->data.unionation.src_field_count; i += 1) { 13585 TypeUnionField *union_field = &wanted_type->data.unionation.fields[i]; 13586 ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); 13587 if (field_type == nullptr) 13588 return ira->codegen->invalid_inst_gen; 13589 bool has_bits; 13590 if ((err = type_has_bits2(ira->codegen, field_type, &has_bits))) 13591 return ira->codegen->invalid_inst_gen; 13592 if (has_bits) { 13593 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i); 13594 add_error_note(ira->codegen, msg, field_node, 13595 buf_sprintf("field '%s' has type '%s'", 13596 buf_ptr(union_field->name), 13597 buf_ptr(&field_type->name))); 13598 } 13599 } 13600 return ira->codegen->invalid_inst_gen; 13601 } 13602 13603 static IrInstGen *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInst* source_instr, 13604 IrInstGen *target, ZigType *wanted_type) 13605 { 13606 assert(wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdFloat); 13607 13608 if (instr_is_comptime(target)) { 13609 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 13610 if (!val) 13611 return ira->codegen->invalid_inst_gen; 13612 if (wanted_type->id == ZigTypeIdInt) { 13613 if (bigint_cmp_zero(&val->data.x_bigint) == CmpLT && !wanted_type->data.integral.is_signed) { 13614 ir_add_error(ira, source_instr, 13615 buf_sprintf("attempt to cast negative value to unsigned integer")); 13616 return ira->codegen->invalid_inst_gen; 13617 } 13618 if (!bigint_fits_in_bits(&val->data.x_bigint, wanted_type->data.integral.bit_count, 13619 wanted_type->data.integral.is_signed)) 13620 { 13621 ir_add_error(ira, source_instr, 13622 buf_sprintf("cast from '%s' to '%s' truncates bits", 13623 buf_ptr(&target->value->type->name), buf_ptr(&wanted_type->name))); 13624 return ira->codegen->invalid_inst_gen; 13625 } 13626 } 13627 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13628 result->value->type = wanted_type; 13629 if (wanted_type->id == ZigTypeIdInt) { 13630 bigint_init_bigint(&result->value->data.x_bigint, &val->data.x_bigint); 13631 } else { 13632 float_init_float(result->value, val); 13633 } 13634 return result; 13635 } 13636 13637 // If the destination integer type has no bits, then we can emit a comptime 13638 // zero. However, we still want to emit a runtime safety check to make sure 13639 // the target is zero. 13640 if (!type_has_bits(wanted_type)) { 13641 assert(wanted_type->id == ZigTypeIdInt); 13642 assert(type_has_bits(target->value->type)); 13643 ir_build_assert_zero(ira, source_instr, target); 13644 IrInstGen *result = ir_const_unsigned(ira, source_instr, 0); 13645 result->value->type = wanted_type; 13646 return result; 13647 } 13648 13649 return ir_build_widen_or_shorten(ira, source_instr->scope, source_instr->source_node, target, wanted_type); 13650 } 13651 13652 static IrInstGen *ir_analyze_int_to_enum(IrAnalyze *ira, IrInst* source_instr, 13653 IrInstGen *target, ZigType *wanted_type) 13654 { 13655 Error err; 13656 assert(wanted_type->id == ZigTypeIdEnum); 13657 13658 ZigType *actual_type = target->value->type; 13659 13660 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusSizeKnown))) 13661 return ira->codegen->invalid_inst_gen; 13662 13663 if (actual_type != wanted_type->data.enumeration.tag_int_type) { 13664 ir_add_error(ira, source_instr, 13665 buf_sprintf("integer to enum cast from '%s' instead of its tag type, '%s'", 13666 buf_ptr(&actual_type->name), 13667 buf_ptr(&wanted_type->data.enumeration.tag_int_type->name))); 13668 return ira->codegen->invalid_inst_gen; 13669 } 13670 13671 assert(actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt); 13672 13673 if (instr_is_comptime(target)) { 13674 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 13675 if (!val) 13676 return ira->codegen->invalid_inst_gen; 13677 13678 TypeEnumField *field = find_enum_field_by_tag(wanted_type, &val->data.x_bigint); 13679 if (field == nullptr && !wanted_type->data.enumeration.non_exhaustive) { 13680 Buf *val_buf = buf_alloc(); 13681 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 13682 ErrorMsg *msg = ir_add_error(ira, source_instr, 13683 buf_sprintf("enum '%s' has no tag matching integer value %s", 13684 buf_ptr(&wanted_type->name), buf_ptr(val_buf))); 13685 add_error_note(ira->codegen, msg, wanted_type->data.enumeration.decl_node, 13686 buf_sprintf("'%s' declared here", buf_ptr(&wanted_type->name))); 13687 return ira->codegen->invalid_inst_gen; 13688 } 13689 13690 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13691 bigint_init_bigint(&result->value->data.x_enum_tag, &val->data.x_bigint); 13692 return result; 13693 } 13694 13695 return ir_build_int_to_enum_gen(ira, source_instr->scope, source_instr->source_node, wanted_type, target); 13696 } 13697 13698 static IrInstGen *ir_analyze_number_to_literal(IrAnalyze *ira, IrInst* source_instr, 13699 IrInstGen *target, ZigType *wanted_type) 13700 { 13701 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 13702 if (!val) 13703 return ira->codegen->invalid_inst_gen; 13704 13705 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13706 if (wanted_type->id == ZigTypeIdComptimeFloat) { 13707 float_init_float(result->value, val); 13708 } else if (wanted_type->id == ZigTypeIdComptimeInt) { 13709 bigint_init_bigint(&result->value->data.x_bigint, &val->data.x_bigint); 13710 } else { 13711 zig_unreachable(); 13712 } 13713 return result; 13714 } 13715 13716 static IrInstGen *ir_analyze_int_to_err(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 13717 ZigType *wanted_type) 13718 { 13719 assert(target->value->type->id == ZigTypeIdInt); 13720 assert(!target->value->type->data.integral.is_signed); 13721 assert(wanted_type->id == ZigTypeIdErrorSet); 13722 13723 if (instr_is_comptime(target)) { 13724 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 13725 if (!val) 13726 return ira->codegen->invalid_inst_gen; 13727 13728 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13729 13730 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 13731 return ira->codegen->invalid_inst_gen; 13732 } 13733 13734 if (type_is_global_error_set(wanted_type)) { 13735 BigInt err_count; 13736 bigint_init_unsigned(&err_count, ira->codegen->errors_by_index.length); 13737 13738 if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) { 13739 Buf *val_buf = buf_alloc(); 13740 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 13741 ir_add_error(ira, source_instr, 13742 buf_sprintf("integer value %s represents no error", buf_ptr(val_buf))); 13743 return ira->codegen->invalid_inst_gen; 13744 } 13745 13746 size_t index = bigint_as_usize(&val->data.x_bigint); 13747 result->value->data.x_err_set = ira->codegen->errors_by_index.at(index); 13748 return result; 13749 } else { 13750 ErrorTableEntry *err = nullptr; 13751 BigInt err_int; 13752 13753 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 13754 ErrorTableEntry *this_err = wanted_type->data.error_set.errors[i]; 13755 bigint_init_unsigned(&err_int, this_err->value); 13756 if (bigint_cmp(&val->data.x_bigint, &err_int) == CmpEQ) { 13757 err = this_err; 13758 break; 13759 } 13760 } 13761 13762 if (err == nullptr) { 13763 Buf *val_buf = buf_alloc(); 13764 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 13765 ir_add_error(ira, source_instr, 13766 buf_sprintf("integer value %s represents no error in '%s'", buf_ptr(val_buf), buf_ptr(&wanted_type->name))); 13767 return ira->codegen->invalid_inst_gen; 13768 } 13769 13770 result->value->data.x_err_set = err; 13771 return result; 13772 } 13773 } 13774 13775 return ir_build_int_to_err_gen(ira, source_instr->scope, source_instr->source_node, target, wanted_type); 13776 } 13777 13778 static IrInstGen *ir_analyze_err_to_int(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 13779 ZigType *wanted_type) 13780 { 13781 assert(wanted_type->id == ZigTypeIdInt); 13782 13783 ZigType *err_type = target->value->type; 13784 13785 if (instr_is_comptime(target)) { 13786 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 13787 if (!val) 13788 return ira->codegen->invalid_inst_gen; 13789 13790 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13791 13792 ErrorTableEntry *err; 13793 if (err_type->id == ZigTypeIdErrorUnion) { 13794 err = val->data.x_err_union.error_set->data.x_err_set; 13795 } else if (err_type->id == ZigTypeIdErrorSet) { 13796 err = val->data.x_err_set; 13797 } else { 13798 zig_unreachable(); 13799 } 13800 result->value->type = wanted_type; 13801 uint64_t err_value = err ? err->value : 0; 13802 bigint_init_unsigned(&result->value->data.x_bigint, err_value); 13803 13804 if (!bigint_fits_in_bits(&result->value->data.x_bigint, 13805 wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) 13806 { 13807 ir_add_error_node(ira, source_instr->source_node, 13808 buf_sprintf("error code '%s' does not fit in '%s'", 13809 buf_ptr(&err->name), buf_ptr(&wanted_type->name))); 13810 return ira->codegen->invalid_inst_gen; 13811 } 13812 13813 return result; 13814 } 13815 13816 ZigType *err_set_type; 13817 if (err_type->id == ZigTypeIdErrorUnion) { 13818 err_set_type = err_type->data.error_union.err_set_type; 13819 } else if (err_type->id == ZigTypeIdErrorSet) { 13820 err_set_type = err_type; 13821 } else { 13822 zig_unreachable(); 13823 } 13824 if (!type_is_global_error_set(err_set_type)) { 13825 if (!resolve_inferred_error_set(ira->codegen, err_set_type, source_instr->source_node)) { 13826 return ira->codegen->invalid_inst_gen; 13827 } 13828 if (err_set_type->data.error_set.err_count == 0) { 13829 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13830 bigint_init_unsigned(&result->value->data.x_bigint, 0); 13831 return result; 13832 } else if (err_set_type->data.error_set.err_count == 1) { 13833 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13834 ErrorTableEntry *err = err_set_type->data.error_set.errors[0]; 13835 bigint_init_unsigned(&result->value->data.x_bigint, err->value); 13836 return result; 13837 } 13838 } 13839 13840 BigInt bn; 13841 bigint_init_unsigned(&bn, ira->codegen->errors_by_index.length); 13842 if (!bigint_fits_in_bits(&bn, wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) { 13843 ir_add_error_node(ira, source_instr->source_node, 13844 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name))); 13845 return ira->codegen->invalid_inst_gen; 13846 } 13847 13848 return ir_build_err_to_int_gen(ira, source_instr->scope, source_instr->source_node, target, wanted_type); 13849 } 13850 13851 static IrInstGen *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 13852 ZigType *wanted_type) 13853 { 13854 assert(wanted_type->id == ZigTypeIdPointer); 13855 Error err; 13856 if ((err = type_resolve(ira->codegen, target->value->type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 13857 return ira->codegen->invalid_inst_gen; 13858 assert((wanted_type->data.pointer.is_const && target->value->type->data.pointer.is_const) || !target->value->type->data.pointer.is_const); 13859 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, target->value->type)); 13860 ZigType *array_type = wanted_type->data.pointer.child_type; 13861 assert(array_type->id == ZigTypeIdArray); 13862 assert(array_type->data.array.len == 1); 13863 13864 if (instr_is_comptime(target)) { 13865 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 13866 if (!val) 13867 return ira->codegen->invalid_inst_gen; 13868 13869 assert(val->type->id == ZigTypeIdPointer); 13870 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 13871 if (pointee == nullptr) 13872 return ira->codegen->invalid_inst_gen; 13873 if (pointee->special != ConstValSpecialRuntime) { 13874 ZigValue *array_val = ira->codegen->pass1_arena->create<ZigValue>(); 13875 array_val->special = ConstValSpecialStatic; 13876 array_val->type = array_type; 13877 array_val->data.x_array.special = ConstArraySpecialNone; 13878 array_val->data.x_array.data.s_none.elements = pointee; 13879 array_val->parent.id = ConstParentIdScalar; 13880 array_val->parent.data.p_scalar.scalar_val = pointee; 13881 13882 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 13883 source_instr->scope, source_instr->source_node); 13884 const_instruction->base.value->type = wanted_type; 13885 const_instruction->base.value->special = ConstValSpecialStatic; 13886 const_instruction->base.value->data.x_ptr.special = ConstPtrSpecialRef; 13887 const_instruction->base.value->data.x_ptr.data.ref.pointee = array_val; 13888 const_instruction->base.value->data.x_ptr.mut = val->data.x_ptr.mut; 13889 return &const_instruction->base; 13890 } 13891 } 13892 13893 // pointer to array and pointer to single item are represented the same way at runtime 13894 return ir_build_cast(ira, &target->base, wanted_type, target, CastOpBitCast); 13895 } 13896 13897 static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCastOnly *cast_result, 13898 ErrorMsg *parent_msg) 13899 { 13900 switch (cast_result->id) { 13901 case ConstCastResultIdOk: 13902 zig_unreachable(); 13903 case ConstCastResultIdInvalid: 13904 zig_unreachable(); 13905 case ConstCastResultIdOptionalChild: { 13906 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 13907 buf_sprintf("optional type child '%s' cannot cast into optional type child '%s'", 13908 buf_ptr(&cast_result->data.optional->actual_child->name), 13909 buf_ptr(&cast_result->data.optional->wanted_child->name))); 13910 report_recursive_error(ira, source_node, &cast_result->data.optional->child, msg); 13911 break; 13912 } 13913 case ConstCastResultIdErrorUnionErrorSet: { 13914 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 13915 buf_sprintf("error set '%s' cannot cast into error set '%s'", 13916 buf_ptr(&cast_result->data.error_union_error_set->actual_err_set->name), 13917 buf_ptr(&cast_result->data.error_union_error_set->wanted_err_set->name))); 13918 report_recursive_error(ira, source_node, &cast_result->data.error_union_error_set->child, msg); 13919 break; 13920 } 13921 case ConstCastResultIdErrSet: { 13922 ZigList<ErrorTableEntry *> *missing_errors = &cast_result->data.error_set_mismatch->missing_errors; 13923 for (size_t i = 0; i < missing_errors->length; i += 1) { 13924 ErrorTableEntry *error_entry = missing_errors->at(i); 13925 add_error_note(ira->codegen, parent_msg, ast_field_to_symbol_node(error_entry->decl_node), 13926 buf_sprintf("'error.%s' not a member of destination error set", buf_ptr(&error_entry->name))); 13927 } 13928 break; 13929 } 13930 case ConstCastResultIdErrSetGlobal: { 13931 add_error_note(ira->codegen, parent_msg, source_node, 13932 buf_sprintf("cannot cast global error set into smaller set")); 13933 break; 13934 } 13935 case ConstCastResultIdPointerChild: { 13936 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 13937 buf_sprintf("pointer type child '%s' cannot cast into pointer type child '%s'", 13938 buf_ptr(&cast_result->data.pointer_mismatch->actual_child->name), 13939 buf_ptr(&cast_result->data.pointer_mismatch->wanted_child->name))); 13940 report_recursive_error(ira, source_node, &cast_result->data.pointer_mismatch->child, msg); 13941 break; 13942 } 13943 case ConstCastResultIdSliceChild: { 13944 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 13945 buf_sprintf("slice type child '%s' cannot cast into slice type child '%s'", 13946 buf_ptr(&cast_result->data.slice_mismatch->actual_child->name), 13947 buf_ptr(&cast_result->data.slice_mismatch->wanted_child->name))); 13948 report_recursive_error(ira, source_node, &cast_result->data.slice_mismatch->child, msg); 13949 break; 13950 } 13951 case ConstCastResultIdErrorUnionPayload: { 13952 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 13953 buf_sprintf("error union payload '%s' cannot cast into error union payload '%s'", 13954 buf_ptr(&cast_result->data.error_union_payload->actual_payload->name), 13955 buf_ptr(&cast_result->data.error_union_payload->wanted_payload->name))); 13956 report_recursive_error(ira, source_node, &cast_result->data.error_union_payload->child, msg); 13957 break; 13958 } 13959 case ConstCastResultIdType: { 13960 AstNode *wanted_decl_node = type_decl_node(cast_result->data.type_mismatch->wanted_type); 13961 AstNode *actual_decl_node = type_decl_node(cast_result->data.type_mismatch->actual_type); 13962 if (wanted_decl_node != nullptr) { 13963 add_error_note(ira->codegen, parent_msg, wanted_decl_node, 13964 buf_sprintf("%s declared here", 13965 buf_ptr(&cast_result->data.type_mismatch->wanted_type->name))); 13966 } 13967 if (actual_decl_node != nullptr) { 13968 add_error_note(ira->codegen, parent_msg, actual_decl_node, 13969 buf_sprintf("%s declared here", 13970 buf_ptr(&cast_result->data.type_mismatch->actual_type->name))); 13971 } 13972 break; 13973 } 13974 case ConstCastResultIdFnArg: { 13975 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 13976 buf_sprintf("parameter %" ZIG_PRI_usize ": '%s' cannot cast into '%s'", 13977 cast_result->data.fn_arg.arg_index, 13978 buf_ptr(&cast_result->data.fn_arg.actual_param_type->name), 13979 buf_ptr(&cast_result->data.fn_arg.expected_param_type->name))); 13980 report_recursive_error(ira, source_node, cast_result->data.fn_arg.child, msg); 13981 break; 13982 } 13983 case ConstCastResultIdBadAllowsZero: { 13984 ZigType *wanted_type = cast_result->data.bad_allows_zero->wanted_type; 13985 ZigType *actual_type = cast_result->data.bad_allows_zero->actual_type; 13986 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); 13987 bool actual_allows_zero = ptr_allows_addr_zero(actual_type); 13988 if (actual_allows_zero && !wanted_allows_zero) { 13989 add_error_note(ira->codegen, parent_msg, source_node, 13990 buf_sprintf("'%s' could have null values which are illegal in type '%s'", 13991 buf_ptr(&actual_type->name), 13992 buf_ptr(&wanted_type->name))); 13993 } else { 13994 add_error_note(ira->codegen, parent_msg, source_node, 13995 buf_sprintf("mutable '%s' allows illegal null values stored to type '%s'", 13996 buf_ptr(&wanted_type->name), 13997 buf_ptr(&actual_type->name))); 13998 } 13999 break; 14000 } 14001 case ConstCastResultIdPtrLens: { 14002 add_error_note(ira->codegen, parent_msg, source_node, 14003 buf_sprintf("pointer length mismatch")); 14004 break; 14005 } 14006 case ConstCastResultIdPtrSentinel: { 14007 ZigType *actual_type = cast_result->data.bad_ptr_sentinel->actual_type; 14008 ZigType *wanted_type = cast_result->data.bad_ptr_sentinel->wanted_type; 14009 { 14010 Buf *txt_msg = buf_sprintf("destination pointer requires a terminating '"); 14011 render_const_value(ira->codegen, txt_msg, wanted_type->data.pointer.sentinel); 14012 buf_appendf(txt_msg, "' sentinel"); 14013 if (actual_type->data.pointer.sentinel != nullptr) { 14014 buf_appendf(txt_msg, ", but source pointer has a terminating '"); 14015 render_const_value(ira->codegen, txt_msg, actual_type->data.pointer.sentinel); 14016 buf_appendf(txt_msg, "' sentinel"); 14017 } 14018 add_error_note(ira->codegen, parent_msg, source_node, txt_msg); 14019 } 14020 break; 14021 } 14022 case ConstCastResultIdSentinelArrays: { 14023 ZigType *actual_type = cast_result->data.sentinel_arrays->actual_type; 14024 ZigType *wanted_type = cast_result->data.sentinel_arrays->wanted_type; 14025 Buf *txt_msg = buf_sprintf("destination array requires a terminating '"); 14026 render_const_value(ira->codegen, txt_msg, wanted_type->data.array.sentinel); 14027 buf_appendf(txt_msg, "' sentinel"); 14028 if (actual_type->data.array.sentinel != nullptr) { 14029 buf_appendf(txt_msg, ", but source array has a terminating '"); 14030 render_const_value(ira->codegen, txt_msg, actual_type->data.array.sentinel); 14031 buf_appendf(txt_msg, "' sentinel"); 14032 } 14033 add_error_note(ira->codegen, parent_msg, source_node, txt_msg); 14034 break; 14035 } 14036 case ConstCastResultIdCV: { 14037 ZigType *wanted_type = cast_result->data.bad_cv->wanted_type; 14038 ZigType *actual_type = cast_result->data.bad_cv->actual_type; 14039 bool ok_const = !actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const; 14040 bool ok_volatile = !actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile; 14041 if (!ok_const) { 14042 add_error_note(ira->codegen, parent_msg, source_node, buf_sprintf("cast discards const qualifier")); 14043 } else if (!ok_volatile) { 14044 add_error_note(ira->codegen, parent_msg, source_node, buf_sprintf("cast discards volatile qualifier")); 14045 } else { 14046 zig_unreachable(); 14047 } 14048 break; 14049 } 14050 case ConstCastResultIdFnIsGeneric: 14051 add_error_note(ira->codegen, parent_msg, source_node, 14052 buf_sprintf("only one of the functions is generic")); 14053 break; 14054 case ConstCastResultIdFnCC: 14055 add_error_note(ira->codegen, parent_msg, source_node, 14056 buf_sprintf("calling convention mismatch")); 14057 break; 14058 case ConstCastResultIdIntShorten: { 14059 ZigType *wanted_type = cast_result->data.int_shorten->wanted_type; 14060 ZigType *actual_type = cast_result->data.int_shorten->actual_type; 14061 const char *wanted_signed = wanted_type->data.integral.is_signed ? "signed" : "unsigned"; 14062 const char *actual_signed = actual_type->data.integral.is_signed ? "signed" : "unsigned"; 14063 add_error_note(ira->codegen, parent_msg, source_node, 14064 buf_sprintf("%s %" PRIu32 "-bit int cannot represent all possible %s %" PRIu32 "-bit values", 14065 wanted_signed, wanted_type->data.integral.bit_count, 14066 actual_signed, actual_type->data.integral.bit_count)); 14067 break; 14068 } 14069 case ConstCastResultIdFnAlign: // TODO 14070 case ConstCastResultIdFnVarArgs: // TODO 14071 case ConstCastResultIdFnReturnType: // TODO 14072 case ConstCastResultIdFnArgCount: // TODO 14073 case ConstCastResultIdFnGenericArgCount: // TODO 14074 case ConstCastResultIdFnArgNoAlias: // TODO 14075 case ConstCastResultIdUnresolvedInferredErrSet: // TODO 14076 case ConstCastResultIdAsyncAllocatorType: // TODO 14077 case ConstCastResultIdArrayChild: // TODO 14078 break; 14079 } 14080 } 14081 14082 static IrInstGen *ir_analyze_array_to_vector(IrAnalyze *ira, IrInst* source_instr, 14083 IrInstGen *array, ZigType *vector_type) 14084 { 14085 if (instr_is_comptime(array)) { 14086 // arrays and vectors have the same ZigValue representation 14087 IrInstGen *result = ir_const(ira, source_instr, vector_type); 14088 copy_const_val(ira->codegen, result->value, array->value); 14089 result->value->type = vector_type; 14090 return result; 14091 } 14092 return ir_build_array_to_vector(ira, source_instr, array, vector_type); 14093 } 14094 14095 static IrInstGen *ir_analyze_vector_to_array(IrAnalyze *ira, IrInst* source_instr, 14096 IrInstGen *vector, ZigType *array_type, ResultLoc *result_loc) 14097 { 14098 if (instr_is_comptime(vector)) { 14099 // arrays and vectors have the same ZigValue representation 14100 IrInstGen *result = ir_const(ira, source_instr, array_type); 14101 copy_const_val(ira->codegen, result->value, vector->value); 14102 result->value->type = array_type; 14103 return result; 14104 } 14105 if (result_loc == nullptr) { 14106 result_loc = no_result_loc(); 14107 } 14108 IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, true, true); 14109 if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { 14110 return result_loc_inst; 14111 } 14112 return ir_build_vector_to_array(ira, source_instr, array_type, vector, result_loc_inst); 14113 } 14114 14115 static IrInstGen *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInst* source_instr, 14116 IrInstGen *integer, ZigType *dest_type) 14117 { 14118 IrInstGen *unsigned_integer; 14119 if (instr_is_comptime(integer)) { 14120 unsigned_integer = integer; 14121 } else { 14122 assert(integer->value->type->id == ZigTypeIdInt); 14123 14124 if (integer->value->type->data.integral.bit_count > 14125 ira->codegen->builtin_types.entry_usize->data.integral.bit_count) 14126 { 14127 ir_add_error(ira, source_instr, 14128 buf_sprintf("integer type '%s' too big for implicit @intToPtr to type '%s'", 14129 buf_ptr(&integer->value->type->name), 14130 buf_ptr(&dest_type->name))); 14131 return ira->codegen->invalid_inst_gen; 14132 } 14133 14134 if (integer->value->type->data.integral.is_signed) { 14135 ZigType *unsigned_int_type = get_int_type(ira->codegen, false, 14136 integer->value->type->data.integral.bit_count); 14137 unsigned_integer = ir_analyze_bit_cast(ira, source_instr, integer, unsigned_int_type); 14138 if (type_is_invalid(unsigned_integer->value->type)) 14139 return ira->codegen->invalid_inst_gen; 14140 } else { 14141 unsigned_integer = integer; 14142 } 14143 } 14144 14145 return ir_analyze_int_to_ptr(ira, source_instr, unsigned_integer, dest_type); 14146 } 14147 14148 static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { 14149 if (ty->id == ZigTypeIdPointer) return ty->data.pointer.child_type->id != ZigTypeIdPointer; 14150 if (ty->id == ZigTypeIdFn) return true; 14151 if (ty->id == ZigTypeIdOptional) { 14152 ZigType *ptr_ty = ty->data.maybe.child_type; 14153 if (ptr_ty->id == ZigTypeIdPointer) return ptr_ty->data.pointer.child_type->id != ZigTypeIdPointer; 14154 if (ptr_ty->id == ZigTypeIdFn) return true; 14155 } 14156 return false; 14157 } 14158 14159 static IrInstGen *ir_analyze_enum_literal(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 14160 ZigType *enum_type) 14161 { 14162 assert(enum_type->id == ZigTypeIdEnum); 14163 14164 Error err; 14165 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusZeroBitsKnown))) 14166 return ira->codegen->invalid_inst_gen; 14167 14168 TypeEnumField *field = find_enum_type_field(enum_type, value->value->data.x_enum_literal); 14169 if (field == nullptr) { 14170 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("enum '%s' has no field named '%s'", 14171 buf_ptr(&enum_type->name), buf_ptr(value->value->data.x_enum_literal))); 14172 add_error_note(ira->codegen, msg, enum_type->data.enumeration.decl_node, 14173 buf_sprintf("'%s' declared here", buf_ptr(&enum_type->name))); 14174 return ira->codegen->invalid_inst_gen; 14175 } 14176 IrInstGen *result = ir_const(ira, source_instr, enum_type); 14177 bigint_init_bigint(&result->value->data.x_enum_tag, &field->value); 14178 14179 return result; 14180 } 14181 14182 static IrInstGen *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInst* source_instr, 14183 IrInstGen *value, ZigType *wanted_type) 14184 { 14185 ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon list literal to array")); 14186 return ira->codegen->invalid_inst_gen; 14187 } 14188 14189 static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* source_instr, 14190 IrInstGen *value, ZigType *wanted_type) 14191 { 14192 ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to struct")); 14193 return ira->codegen->invalid_inst_gen; 14194 } 14195 14196 static IrInstGen *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInst* source_instr, 14197 IrInstGen *value, ZigType *wanted_type) 14198 { 14199 ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon struct literal to union")); 14200 return ira->codegen->invalid_inst_gen; 14201 } 14202 14203 // Add a compile error and return ErrorSemanticAnalyzeFail if the pointer alignment does not work, 14204 // otherwise return ErrorNone. Does not emit any instructions. 14205 // Assumes that the pointer types have element types with the same ABI alignment. Avoids resolving the 14206 // pointer types' alignments if both of the pointer types are ABI aligned. 14207 static Error ir_cast_ptr_align(IrAnalyze *ira, IrInst* source_instr, ZigType *dest_ptr_type, 14208 ZigType *src_ptr_type, AstNode *src_source_node) 14209 { 14210 Error err; 14211 14212 ir_assert(dest_ptr_type->id == ZigTypeIdPointer, source_instr); 14213 ir_assert(src_ptr_type->id == ZigTypeIdPointer, source_instr); 14214 14215 if (dest_ptr_type->data.pointer.explicit_alignment == 0 && 14216 src_ptr_type->data.pointer.explicit_alignment == 0) 14217 { 14218 return ErrorNone; 14219 } 14220 14221 if ((err = type_resolve(ira->codegen, dest_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 14222 return ErrorSemanticAnalyzeFail; 14223 14224 if ((err = type_resolve(ira->codegen, src_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 14225 return ErrorSemanticAnalyzeFail; 14226 14227 uint32_t wanted_align = get_ptr_align(ira->codegen, dest_ptr_type); 14228 uint32_t actual_align = get_ptr_align(ira->codegen, src_ptr_type); 14229 if (wanted_align > actual_align) { 14230 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 14231 add_error_note(ira->codegen, msg, src_source_node, 14232 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_ptr_type->name), actual_align)); 14233 add_error_note(ira->codegen, msg, source_instr->source_node, 14234 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&dest_ptr_type->name), wanted_align)); 14235 return ErrorSemanticAnalyzeFail; 14236 } 14237 14238 return ErrorNone; 14239 } 14240 14241 static IrInstGen *ir_analyze_struct_value_field_value(IrAnalyze *ira, IrInst* source_instr, 14242 IrInstGen *struct_operand, TypeStructField *field) 14243 { 14244 IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, struct_operand, true, false); 14245 if (type_is_invalid(struct_ptr->value->type)) 14246 return ira->codegen->invalid_inst_gen; 14247 IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, struct_ptr, 14248 struct_operand->value->type, false); 14249 if (type_is_invalid(field_ptr->value->type)) 14250 return ira->codegen->invalid_inst_gen; 14251 return ir_get_deref(ira, source_instr, field_ptr, nullptr); 14252 } 14253 14254 static IrInstGen *ir_analyze_optional_value_payload_value(IrAnalyze *ira, IrInst* source_instr, 14255 IrInstGen *optional_operand, bool safety_check_on) 14256 { 14257 IrInstGen *opt_ptr = ir_get_ref(ira, source_instr, optional_operand, true, false); 14258 IrInstGen *payload_ptr = ir_analyze_unwrap_optional_payload(ira, source_instr, opt_ptr, 14259 safety_check_on, false); 14260 return ir_get_deref(ira, source_instr, payload_ptr, nullptr); 14261 } 14262 14263 static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr, 14264 ZigType *wanted_type, IrInstGen *value) 14265 { 14266 Error err; 14267 ZigType *actual_type = value->value->type; 14268 AstNode *source_node = source_instr->source_node; 14269 14270 if (type_is_invalid(wanted_type) || type_is_invalid(actual_type)) { 14271 return ira->codegen->invalid_inst_gen; 14272 } 14273 14274 // This means the wanted type is anything. 14275 if (wanted_type == ira->codegen->builtin_types.entry_var) { 14276 return value; 14277 } 14278 14279 // perfect match or non-const to const 14280 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type, 14281 source_node, false); 14282 if (const_cast_result.id == ConstCastResultIdInvalid) 14283 return ira->codegen->invalid_inst_gen; 14284 if (const_cast_result.id == ConstCastResultIdOk) { 14285 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); 14286 } 14287 14288 if (const_cast_result.id == ConstCastResultIdFnCC) { 14289 ir_assert(value->value->type->id == ZigTypeIdFn, source_instr); 14290 // ConstCastResultIdFnCC is guaranteed to be the last one reported, meaning everything else is ok. 14291 if (wanted_type->data.fn.fn_type_id.cc == CallingConventionAsync && 14292 actual_type->data.fn.fn_type_id.cc == CallingConventionUnspecified) 14293 { 14294 ir_assert(value->value->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); 14295 ZigFn *fn = value->value->data.x_ptr.data.fn.fn_entry; 14296 if (fn->inferred_async_node == nullptr) { 14297 fn->inferred_async_node = source_instr->source_node; 14298 } 14299 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); 14300 } 14301 } 14302 14303 // cast from T to ?T 14304 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism 14305 if (wanted_type->id == ZigTypeIdOptional) { 14306 ZigType *wanted_child_type = wanted_type->data.maybe.child_type; 14307 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, 14308 false).id == ConstCastResultIdOk) 14309 { 14310 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, nullptr); 14311 } else if (actual_type->id == ZigTypeIdComptimeInt || 14312 actual_type->id == ZigTypeIdComptimeFloat) 14313 { 14314 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { 14315 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, nullptr); 14316 } else { 14317 return ira->codegen->invalid_inst_gen; 14318 } 14319 } else if ( 14320 wanted_child_type->id == ZigTypeIdPointer && 14321 wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && 14322 actual_type->id == ZigTypeIdPointer && 14323 actual_type->data.pointer.ptr_len == PtrLenSingle && 14324 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 14325 { 14326 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 14327 return ira->codegen->invalid_inst_gen; 14328 if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 14329 return ira->codegen->invalid_inst_gen; 14330 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && 14331 types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, 14332 actual_type->data.pointer.child_type->data.array.child_type, source_node, 14333 !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) 14334 { 14335 IrInstGen *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, 14336 wanted_child_type); 14337 if (type_is_invalid(cast1->value->type)) 14338 return ira->codegen->invalid_inst_gen; 14339 return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type, nullptr); 14340 } 14341 } 14342 } 14343 14344 // T to E!T 14345 if (wanted_type->id == ZigTypeIdErrorUnion) { 14346 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, 14347 source_node, false).id == ConstCastResultIdOk) 14348 { 14349 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, nullptr); 14350 } else if (actual_type->id == ZigTypeIdComptimeInt || 14351 actual_type->id == ZigTypeIdComptimeFloat) 14352 { 14353 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { 14354 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, nullptr); 14355 } else { 14356 return ira->codegen->invalid_inst_gen; 14357 } 14358 } 14359 } 14360 14361 // cast from T to E!?T 14362 if (wanted_type->id == ZigTypeIdErrorUnion && 14363 wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && 14364 actual_type->id != ZigTypeIdOptional) 14365 { 14366 ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; 14367 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || 14368 actual_type->id == ZigTypeIdNull || 14369 actual_type->id == ZigTypeIdComptimeInt || 14370 actual_type->id == ZigTypeIdComptimeFloat) 14371 { 14372 IrInstGen *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); 14373 if (type_is_invalid(cast1->value->type)) 14374 return ira->codegen->invalid_inst_gen; 14375 14376 IrInstGen *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 14377 if (type_is_invalid(cast2->value->type)) 14378 return ira->codegen->invalid_inst_gen; 14379 14380 return cast2; 14381 } 14382 } 14383 14384 14385 // cast from comptime-known number to another number type 14386 if (instr_is_comptime(value) && 14387 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt || 14388 actual_type->id == ZigTypeIdFloat || actual_type->id == ZigTypeIdComptimeFloat) && 14389 (wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdComptimeInt || 14390 wanted_type->id == ZigTypeIdFloat || wanted_type->id == ZigTypeIdComptimeFloat)) 14391 { 14392 if (value->value->special == ConstValSpecialUndef) { 14393 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14394 result->value->special = ConstValSpecialUndef; 14395 return result; 14396 } 14397 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { 14398 if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) { 14399 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14400 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { 14401 copy_const_val(ira->codegen, result->value, value->value); 14402 result->value->type = wanted_type; 14403 } else { 14404 float_init_bigint(&result->value->data.x_bigint, value->value); 14405 } 14406 return result; 14407 } else if (wanted_type->id == ZigTypeIdComptimeFloat || wanted_type->id == ZigTypeIdFloat) { 14408 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14409 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { 14410 BigFloat bf; 14411 bigfloat_init_bigint(&bf, &value->value->data.x_bigint); 14412 float_init_bigfloat(result->value, &bf); 14413 } else { 14414 float_init_float(result->value, value->value); 14415 } 14416 return result; 14417 } 14418 zig_unreachable(); 14419 } else { 14420 return ira->codegen->invalid_inst_gen; 14421 } 14422 } 14423 14424 // widening conversion 14425 if (wanted_type->id == ZigTypeIdInt && 14426 actual_type->id == ZigTypeIdInt && 14427 wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed && 14428 wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count) 14429 { 14430 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 14431 } 14432 14433 // small enough unsigned ints can get casted to large enough signed ints 14434 if (wanted_type->id == ZigTypeIdInt && wanted_type->data.integral.is_signed && 14435 actual_type->id == ZigTypeIdInt && !actual_type->data.integral.is_signed && 14436 wanted_type->data.integral.bit_count > actual_type->data.integral.bit_count) 14437 { 14438 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 14439 } 14440 14441 // float widening conversion 14442 if (wanted_type->id == ZigTypeIdFloat && 14443 actual_type->id == ZigTypeIdFloat && 14444 wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count) 14445 { 14446 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 14447 } 14448 14449 // *[N]T to ?[]const T 14450 if (wanted_type->id == ZigTypeIdOptional && 14451 is_slice(wanted_type->data.maybe.child_type) && 14452 actual_type->id == ZigTypeIdPointer && 14453 actual_type->data.pointer.ptr_len == PtrLenSingle && 14454 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 14455 { 14456 IrInstGen *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); 14457 if (type_is_invalid(cast1->value->type)) 14458 return ira->codegen->invalid_inst_gen; 14459 14460 IrInstGen *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 14461 if (type_is_invalid(cast2->value->type)) 14462 return ira->codegen->invalid_inst_gen; 14463 14464 return cast2; 14465 } 14466 14467 // *[N]T to [*]T and [*c]T 14468 if (wanted_type->id == ZigTypeIdPointer && 14469 (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC) && 14470 actual_type->id == ZigTypeIdPointer && 14471 actual_type->data.pointer.ptr_len == PtrLenSingle && 14472 actual_type->data.pointer.child_type->id == ZigTypeIdArray && 14473 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && 14474 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) 14475 { 14476 ZigType *actual_array_type = actual_type->data.pointer.child_type; 14477 if (wanted_type->data.pointer.sentinel == nullptr || 14478 (actual_array_type->data.array.sentinel != nullptr && 14479 const_values_equal(ira->codegen, wanted_type->data.pointer.sentinel, 14480 actual_array_type->data.array.sentinel))) 14481 { 14482 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 14483 return ira->codegen->invalid_inst_gen; 14484 if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 14485 return ira->codegen->invalid_inst_gen; 14486 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type) && 14487 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 14488 actual_type->data.pointer.child_type->data.array.child_type, source_node, 14489 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 14490 { 14491 return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type); 14492 } 14493 } 14494 } 14495 14496 // *[N]T to []T 14497 // *[N]T to E![]T 14498 if ((is_slice(wanted_type) || 14499 (wanted_type->id == ZigTypeIdErrorUnion && 14500 is_slice(wanted_type->data.error_union.payload_type))) && 14501 actual_type->id == ZigTypeIdPointer && 14502 actual_type->data.pointer.ptr_len == PtrLenSingle && 14503 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 14504 { 14505 ZigType *slice_type = (wanted_type->id == ZigTypeIdErrorUnion) ? 14506 wanted_type->data.error_union.payload_type : wanted_type; 14507 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 14508 assert(slice_ptr_type->id == ZigTypeIdPointer); 14509 ZigType *array_type = actual_type->data.pointer.child_type; 14510 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 14511 || !actual_type->data.pointer.is_const); 14512 if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 14513 array_type->data.array.child_type, source_node, 14514 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) 14515 { 14516 // If the pointers both have ABI align, it works. 14517 // Or if the array length is 0, alignment doesn't matter. 14518 bool ok_align = array_type->data.array.len == 0 || 14519 (slice_ptr_type->data.pointer.explicit_alignment == 0 && 14520 actual_type->data.pointer.explicit_alignment == 0); 14521 if (!ok_align) { 14522 // If either one has non ABI align, we have to resolve them both 14523 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, 14524 ResolveStatusAlignmentKnown))) 14525 { 14526 return ira->codegen->invalid_inst_gen; 14527 } 14528 if ((err = type_resolve(ira->codegen, slice_ptr_type->data.pointer.child_type, 14529 ResolveStatusAlignmentKnown))) 14530 { 14531 return ira->codegen->invalid_inst_gen; 14532 } 14533 ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type); 14534 } 14535 if (ok_align) { 14536 if (wanted_type->id == ZigTypeIdErrorUnion) { 14537 IrInstGen *cast1 = ir_analyze_cast(ira, source_instr, slice_type, value); 14538 if (type_is_invalid(cast1->value->type)) 14539 return ira->codegen->invalid_inst_gen; 14540 14541 IrInstGen *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 14542 if (type_is_invalid(cast2->value->type)) 14543 return ira->codegen->invalid_inst_gen; 14544 14545 return cast2; 14546 } else { 14547 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, slice_type, nullptr); 14548 } 14549 } 14550 } 14551 } 14552 14553 // *[N]T to E![]T 14554 if (wanted_type->id == ZigTypeIdErrorUnion && 14555 is_slice(wanted_type->data.error_union.payload_type) && 14556 actual_type->id == ZigTypeIdPointer && 14557 actual_type->data.pointer.ptr_len == PtrLenSingle && 14558 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 14559 { 14560 ZigType *slice_type = wanted_type->data.error_union.payload_type; 14561 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 14562 assert(slice_ptr_type->id == ZigTypeIdPointer); 14563 ZigType *array_type = actual_type->data.pointer.child_type; 14564 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 14565 || !actual_type->data.pointer.is_const); 14566 if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 14567 array_type->data.array.child_type, source_node, 14568 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) 14569 { 14570 // If the pointers both have ABI align, it works. 14571 bool ok_align = slice_ptr_type->data.pointer.explicit_alignment == 0 && 14572 actual_type->data.pointer.explicit_alignment == 0; 14573 if (!ok_align) { 14574 // If either one has non ABI align, we have to resolve them both 14575 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, 14576 ResolveStatusAlignmentKnown))) 14577 { 14578 return ira->codegen->invalid_inst_gen; 14579 } 14580 if ((err = type_resolve(ira->codegen, slice_ptr_type->data.pointer.child_type, 14581 ResolveStatusAlignmentKnown))) 14582 { 14583 return ira->codegen->invalid_inst_gen; 14584 } 14585 ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type); 14586 } 14587 if (ok_align) { 14588 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, slice_type, nullptr); 14589 } 14590 } 14591 } 14592 14593 // @Vector(N,T1) to @Vector(N,T2) 14594 if (actual_type->id == ZigTypeIdVector && wanted_type->id == ZigTypeIdVector) { 14595 if (actual_type->data.vector.len == wanted_type->data.vector.len && 14596 types_match_const_cast_only(ira, wanted_type->data.vector.elem_type, 14597 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 14598 { 14599 return ir_analyze_bit_cast(ira, source_instr, value, wanted_type); 14600 } 14601 } 14602 14603 // *@Frame(func) to anyframe->T or anyframe 14604 // *@Frame(func) to ?anyframe->T or ?anyframe 14605 // *@Frame(func) to E!anyframe->T or E!anyframe 14606 if (actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle && 14607 !actual_type->data.pointer.is_const && 14608 actual_type->data.pointer.child_type->id == ZigTypeIdFnFrame) 14609 { 14610 ZigType *anyframe_type; 14611 if (wanted_type->id == ZigTypeIdAnyFrame) { 14612 anyframe_type = wanted_type; 14613 } else if (wanted_type->id == ZigTypeIdOptional && 14614 wanted_type->data.maybe.child_type->id == ZigTypeIdAnyFrame) 14615 { 14616 anyframe_type = wanted_type->data.maybe.child_type; 14617 } else if (wanted_type->id == ZigTypeIdErrorUnion && 14618 wanted_type->data.error_union.payload_type->id == ZigTypeIdAnyFrame) 14619 { 14620 anyframe_type = wanted_type->data.error_union.payload_type; 14621 } else { 14622 anyframe_type = nullptr; 14623 } 14624 if (anyframe_type != nullptr) { 14625 bool ok = true; 14626 if (anyframe_type->data.any_frame.result_type != nullptr) { 14627 ZigFn *fn = actual_type->data.pointer.child_type->data.frame.fn; 14628 ZigType *fn_return_type = fn->type_entry->data.fn.fn_type_id.return_type; 14629 if (anyframe_type->data.any_frame.result_type != fn_return_type) { 14630 ok = false; 14631 } 14632 } 14633 if (ok) { 14634 IrInstGen *cast1 = ir_analyze_frame_ptr_to_anyframe(ira, source_instr, value, anyframe_type); 14635 if (anyframe_type == wanted_type) 14636 return cast1; 14637 return ir_analyze_cast(ira, source_instr, wanted_type, cast1); 14638 } 14639 } 14640 } 14641 14642 // anyframe->T to anyframe 14643 if (actual_type->id == ZigTypeIdAnyFrame && actual_type->data.any_frame.result_type != nullptr && 14644 wanted_type->id == ZigTypeIdAnyFrame && wanted_type->data.any_frame.result_type == nullptr) 14645 { 14646 return ir_analyze_anyframe_to_anyframe(ira, source_instr, value, wanted_type); 14647 } 14648 14649 // cast from null literal to maybe type 14650 if (wanted_type->id == ZigTypeIdOptional && 14651 actual_type->id == ZigTypeIdNull) 14652 { 14653 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type); 14654 } 14655 14656 // cast from null literal to C pointer 14657 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC && 14658 actual_type->id == ZigTypeIdNull) 14659 { 14660 return ir_analyze_null_to_c_pointer(ira, source_instr, value, wanted_type); 14661 } 14662 14663 // cast from E to E!T 14664 if (wanted_type->id == ZigTypeIdErrorUnion && 14665 actual_type->id == ZigTypeIdErrorSet) 14666 { 14667 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type, nullptr); 14668 } 14669 14670 // cast from typed number to integer or float literal. 14671 // works when the number is known at compile time 14672 if (instr_is_comptime(value) && 14673 ((actual_type->id == ZigTypeIdInt && wanted_type->id == ZigTypeIdComptimeInt) || 14674 (actual_type->id == ZigTypeIdFloat && wanted_type->id == ZigTypeIdComptimeFloat))) 14675 { 14676 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type); 14677 } 14678 14679 // cast from enum literal to enum with matching field name 14680 if (actual_type->id == ZigTypeIdEnumLiteral && wanted_type->id == ZigTypeIdEnum) 14681 { 14682 return ir_analyze_enum_literal(ira, source_instr, value, wanted_type); 14683 } 14684 14685 // cast from enum literal to optional enum 14686 if (actual_type->id == ZigTypeIdEnumLiteral && 14687 (wanted_type->id == ZigTypeIdOptional && wanted_type->data.maybe.child_type->id == ZigTypeIdEnum)) 14688 { 14689 IrInstGen *result = ir_analyze_enum_literal(ira, source_instr, value, wanted_type->data.maybe.child_type); 14690 if (type_is_invalid(result->value->type)) 14691 return result; 14692 14693 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, nullptr); 14694 } 14695 14696 // cast from enum literal to error union when payload is an enum 14697 if (actual_type->id == ZigTypeIdEnumLiteral && 14698 (wanted_type->id == ZigTypeIdErrorUnion && wanted_type->data.error_union.payload_type->id == ZigTypeIdEnum)) 14699 { 14700 IrInstGen *result = ir_analyze_enum_literal(ira, source_instr, value, wanted_type->data.error_union.payload_type); 14701 if (type_is_invalid(result->value->type)) 14702 return result; 14703 14704 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, nullptr); 14705 } 14706 14707 // cast from union to the enum type of the union 14708 if (actual_type->id == ZigTypeIdUnion && wanted_type->id == ZigTypeIdEnum) { 14709 if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) 14710 return ira->codegen->invalid_inst_gen; 14711 14712 if (actual_type->data.unionation.tag_type == wanted_type) { 14713 return ir_analyze_union_to_tag(ira, source_instr, value, wanted_type); 14714 } 14715 } 14716 14717 // enum to union which has the enum as the tag type, or 14718 // enum literal to union which has a matching enum as the tag type 14719 if (is_tagged_union(wanted_type) && (actual_type->id == ZigTypeIdEnum || 14720 actual_type->id == ZigTypeIdEnumLiteral)) 14721 { 14722 return ir_analyze_enum_to_union(ira, source_instr, value, wanted_type); 14723 } 14724 14725 // cast from *T to *[1]T 14726 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 14727 actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle) 14728 { 14729 ZigType *array_type = wanted_type->data.pointer.child_type; 14730 if (array_type->id == ZigTypeIdArray && array_type->data.array.len == 1 && 14731 types_match_const_cast_only(ira, array_type->data.array.child_type, 14732 actual_type->data.pointer.child_type, source_node, 14733 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk && 14734 // `types_match_const_cast_only` only gets info for child_types 14735 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && 14736 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) 14737 { 14738 if ((err = ir_cast_ptr_align(ira, source_instr, wanted_type, actual_type, value->base.source_node))) 14739 return ira->codegen->invalid_inst_gen; 14740 14741 return ir_analyze_ptr_to_array(ira, source_instr, value, wanted_type); 14742 } 14743 } 14744 14745 // [:x]T to [*:x]T 14746 // [:x]T to [*c]T 14747 if (wanted_type->id == ZigTypeIdPointer && is_slice(actual_type) && 14748 ((wanted_type->data.pointer.ptr_len == PtrLenUnknown && wanted_type->data.pointer.sentinel != nullptr) || 14749 wanted_type->data.pointer.ptr_len == PtrLenC)) 14750 { 14751 ZigType *slice_ptr_type = resolve_struct_field_type(ira->codegen, 14752 actual_type->data.structure.fields[slice_ptr_index]); 14753 if (types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 14754 slice_ptr_type->data.pointer.child_type, source_node, 14755 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk && 14756 (slice_ptr_type->data.pointer.sentinel != nullptr && 14757 (wanted_type->data.pointer.ptr_len == PtrLenC || 14758 const_values_equal(ira->codegen, wanted_type->data.pointer.sentinel, 14759 slice_ptr_type->data.pointer.sentinel)))) 14760 { 14761 TypeStructField *ptr_field = actual_type->data.structure.fields[slice_ptr_index]; 14762 IrInstGen *slice_ptr = ir_analyze_struct_value_field_value(ira, source_instr, value, ptr_field); 14763 return ir_implicit_cast2(ira, source_instr, slice_ptr, wanted_type); 14764 } 14765 } 14766 14767 // cast from *T and [*]T to *c_void and ?*c_void 14768 // but don't do it if the actual type is a double pointer 14769 if (is_pointery_and_elem_is_not_pointery(actual_type)) { 14770 ZigType *dest_ptr_type = nullptr; 14771 if (wanted_type->id == ZigTypeIdPointer && 14772 wanted_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 14773 { 14774 dest_ptr_type = wanted_type; 14775 } else if (wanted_type->id == ZigTypeIdOptional && 14776 wanted_type->data.maybe.child_type->id == ZigTypeIdPointer && 14777 wanted_type->data.maybe.child_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 14778 { 14779 dest_ptr_type = wanted_type->data.maybe.child_type; 14780 } 14781 if (dest_ptr_type != nullptr) { 14782 return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true); 14783 } 14784 } 14785 14786 // cast from T to *T where T is zero bits 14787 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 14788 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 14789 actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 14790 { 14791 bool has_bits; 14792 if ((err = type_has_bits2(ira->codegen, actual_type, &has_bits))) 14793 return ira->codegen->invalid_inst_gen; 14794 if (!has_bits) { 14795 return ir_get_ref(ira, source_instr, value, false, false); 14796 } 14797 } 14798 14799 // cast from @Vector(N, T) to [N]T 14800 if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdVector && 14801 wanted_type->data.array.len == actual_type->data.vector.len && 14802 types_match_const_cast_only(ira, wanted_type->data.array.child_type, 14803 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 14804 { 14805 return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type, nullptr); 14806 } 14807 14808 // cast from [N]T to @Vector(N, T) 14809 if (actual_type->id == ZigTypeIdArray && wanted_type->id == ZigTypeIdVector && 14810 actual_type->data.array.len == wanted_type->data.vector.len && 14811 types_match_const_cast_only(ira, actual_type->data.array.child_type, 14812 wanted_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 14813 { 14814 return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type); 14815 } 14816 14817 // casting between C pointers and normal pointers 14818 if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer && 14819 (wanted_type->data.pointer.ptr_len == PtrLenC || actual_type->data.pointer.ptr_len == PtrLenC) && 14820 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 14821 actual_type->data.pointer.child_type, source_node, 14822 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 14823 { 14824 return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true); 14825 } 14826 14827 // cast from integer to C pointer 14828 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC && 14829 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt)) 14830 { 14831 return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type); 14832 } 14833 14834 // cast from inferred struct type to array, union, or struct 14835 if (is_anon_container(actual_type)) { 14836 AstNode *decl_node = actual_type->data.structure.decl_node; 14837 ir_assert(decl_node->type == NodeTypeContainerInitExpr, source_instr); 14838 ContainerInitKind init_kind = decl_node->data.container_init_expr.kind; 14839 uint32_t field_count = actual_type->data.structure.src_field_count; 14840 if (wanted_type->id == ZigTypeIdArray && (init_kind == ContainerInitKindArray || field_count == 0) && 14841 wanted_type->data.array.len == field_count) 14842 { 14843 return ir_analyze_struct_literal_to_array(ira, source_instr, value, wanted_type); 14844 } else if (wanted_type->id == ZigTypeIdStruct && 14845 (init_kind == ContainerInitKindStruct || field_count == 0)) 14846 { 14847 return ir_analyze_struct_literal_to_struct(ira, source_instr, value, wanted_type); 14848 } else if (wanted_type->id == ZigTypeIdUnion && init_kind == ContainerInitKindStruct && field_count == 1) { 14849 return ir_analyze_struct_literal_to_union(ira, source_instr, value, wanted_type); 14850 } 14851 } 14852 14853 // cast from undefined to anything 14854 if (actual_type->id == ZigTypeIdUndefined) { 14855 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); 14856 } 14857 14858 // T to ?U, where T implicitly casts to U 14859 if (wanted_type->id == ZigTypeIdOptional && actual_type->id != ZigTypeIdOptional) { 14860 IrInstGen *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type); 14861 if (type_is_invalid(cast1->value->type)) 14862 return ira->codegen->invalid_inst_gen; 14863 return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); 14864 } 14865 14866 // T to E!U, where T implicitly casts to U 14867 if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id != ZigTypeIdErrorUnion && 14868 actual_type->id != ZigTypeIdErrorSet) 14869 { 14870 IrInstGen *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.error_union.payload_type); 14871 if (type_is_invalid(cast1->value->type)) 14872 return ira->codegen->invalid_inst_gen; 14873 return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); 14874 } 14875 14876 ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, 14877 buf_sprintf("expected type '%s', found '%s'", 14878 buf_ptr(&wanted_type->name), 14879 buf_ptr(&actual_type->name))); 14880 report_recursive_error(ira, source_instr->source_node, &const_cast_result, parent_msg); 14881 return ira->codegen->invalid_inst_gen; 14882 } 14883 14884 static IrInstGen *ir_implicit_cast2(IrAnalyze *ira, IrInst *value_source_instr, 14885 IrInstGen *value, ZigType *expected_type) 14886 { 14887 assert(value); 14888 assert(!expected_type || !type_is_invalid(expected_type)); 14889 assert(value->value->type); 14890 assert(!type_is_invalid(value->value->type)); 14891 if (expected_type == nullptr) 14892 return value; // anything will do 14893 if (expected_type == value->value->type) 14894 return value; // match 14895 if (value->value->type->id == ZigTypeIdUnreachable) 14896 return value; 14897 14898 return ir_analyze_cast(ira, value_source_instr, expected_type, value); 14899 } 14900 14901 static IrInstGen *ir_implicit_cast(IrAnalyze *ira, IrInstGen *value, ZigType *expected_type) { 14902 return ir_implicit_cast2(ira, &value->base, value, expected_type); 14903 } 14904 14905 static ZigType *get_ptr_elem_type(CodeGen *g, IrInstGen *ptr) { 14906 ir_assert_gen(ptr->value->type->id == ZigTypeIdPointer, ptr); 14907 ZigType *elem_type = ptr->value->type->data.pointer.child_type; 14908 if (elem_type != g->builtin_types.entry_var) 14909 return elem_type; 14910 14911 if (ir_resolve_lazy(g, ptr->base.source_node, ptr->value)) 14912 return g->builtin_types.entry_invalid; 14913 14914 assert(value_is_comptime(ptr->value)); 14915 ZigValue *pointee = const_ptr_pointee_unchecked(g, ptr->value); 14916 return pointee->type; 14917 } 14918 14919 static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *ptr, 14920 ResultLoc *result_loc) 14921 { 14922 Error err; 14923 ZigType *ptr_type = ptr->value->type; 14924 if (type_is_invalid(ptr_type)) 14925 return ira->codegen->invalid_inst_gen; 14926 14927 if (ptr_type->id != ZigTypeIdPointer) { 14928 ir_add_error_node(ira, source_instruction->source_node, 14929 buf_sprintf("attempt to dereference non-pointer type '%s'", 14930 buf_ptr(&ptr_type->name))); 14931 return ira->codegen->invalid_inst_gen; 14932 } 14933 14934 ZigType *child_type = ptr_type->data.pointer.child_type; 14935 if (type_is_invalid(child_type)) 14936 return ira->codegen->invalid_inst_gen; 14937 // if the child type has one possible value, the deref is comptime 14938 switch (type_has_one_possible_value(ira->codegen, child_type)) { 14939 case OnePossibleValueInvalid: 14940 return ira->codegen->invalid_inst_gen; 14941 case OnePossibleValueYes: 14942 return ir_const_move(ira, source_instruction, 14943 get_the_one_possible_value(ira->codegen, child_type)); 14944 case OnePossibleValueNo: 14945 break; 14946 } 14947 if (instr_is_comptime(ptr)) { 14948 if (ptr->value->special == ConstValSpecialUndef) { 14949 ir_add_error(ira, &ptr->base, buf_sprintf("attempt to dereference undefined value")); 14950 return ira->codegen->invalid_inst_gen; 14951 } 14952 if (ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 14953 ZigValue *pointee = const_ptr_pointee_unchecked(ira->codegen, ptr->value); 14954 if (child_type == ira->codegen->builtin_types.entry_var) { 14955 child_type = pointee->type; 14956 } 14957 if (pointee->special != ConstValSpecialRuntime) { 14958 IrInstGen *result = ir_const(ira, source_instruction, child_type); 14959 14960 if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, result->value, 14961 ptr->value))) 14962 { 14963 return ira->codegen->invalid_inst_gen; 14964 } 14965 result->value->type = child_type; 14966 return result; 14967 } 14968 } 14969 } 14970 14971 // if the instruction is a const ref instruction we can skip it 14972 if (ptr->id == IrInstGenIdRef) { 14973 IrInstGenRef *ref_inst = reinterpret_cast<IrInstGenRef *>(ptr); 14974 return ref_inst->operand; 14975 } 14976 14977 // If the instruction is a element pointer instruction to a vector, we emit 14978 // vector element extract instruction rather than load pointer. If the 14979 // pointer type has non-VECTOR_INDEX_RUNTIME value, it would have been 14980 // possible to implement this in the codegen for IrInstGenLoadPtr. 14981 // However if it has VECTOR_INDEX_RUNTIME then we must emit a compile error 14982 // if the vector index cannot be determined right here, right now, because 14983 // the type information does not contain enough information to actually 14984 // perform a dereference. 14985 if (ptr_type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) { 14986 if (ptr->id == IrInstGenIdElemPtr) { 14987 IrInstGenElemPtr *elem_ptr = (IrInstGenElemPtr *)ptr; 14988 IrInstGen *vector_loaded = ir_get_deref(ira, &elem_ptr->array_ptr->base, 14989 elem_ptr->array_ptr, nullptr); 14990 IrInstGen *elem_index = elem_ptr->elem_index; 14991 return ir_build_vector_extract_elem(ira, source_instruction, vector_loaded, elem_index); 14992 } 14993 ir_add_error(ira, &ptr->base, 14994 buf_sprintf("unable to determine vector element index of type '%s'", buf_ptr(&ptr_type->name))); 14995 return ira->codegen->invalid_inst_gen; 14996 } 14997 14998 IrInstGen *result_loc_inst; 14999 if (ptr_type->data.pointer.host_int_bytes != 0 && handle_is_ptr(child_type)) { 15000 if (result_loc == nullptr) result_loc = no_result_loc(); 15001 result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, true, true); 15002 if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { 15003 return result_loc_inst; 15004 } 15005 } else { 15006 result_loc_inst = nullptr; 15007 } 15008 15009 return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst); 15010 } 15011 15012 static bool ir_resolve_const_align(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, 15013 ZigValue *const_val, uint32_t *out) 15014 { 15015 Error err; 15016 if ((err = ir_resolve_const_val(codegen, exec, source_node, const_val, UndefBad))) 15017 return false; 15018 15019 uint32_t align_bytes = bigint_as_u32(&const_val->data.x_bigint); 15020 if (align_bytes == 0) { 15021 exec_add_error_node_gen(codegen, exec, source_node, buf_sprintf("alignment must be >= 1")); 15022 return false; 15023 } 15024 15025 if (!is_power_of_2(align_bytes)) { 15026 exec_add_error_node_gen(codegen, exec, source_node, 15027 buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); 15028 return false; 15029 } 15030 15031 *out = align_bytes; 15032 return true; 15033 } 15034 15035 static bool ir_resolve_align(IrAnalyze *ira, IrInstGen *value, ZigType *elem_type, uint32_t *out) { 15036 if (type_is_invalid(value->value->type)) 15037 return false; 15038 15039 // Look for this pattern: `*align(@alignOf(T)) T`. 15040 // This can be resolved to be `*out = 0` without resolving any alignment. 15041 if (elem_type != nullptr && value->value->special == ConstValSpecialLazy && 15042 value->value->data.x_lazy->id == LazyValueIdAlignOf) 15043 { 15044 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(value->value->data.x_lazy); 15045 15046 ZigType *lazy_elem_type = ir_resolve_type(lazy_align_of->ira, lazy_align_of->target_type); 15047 if (type_is_invalid(lazy_elem_type)) 15048 return false; 15049 15050 if (elem_type == lazy_elem_type) { 15051 *out = 0; 15052 return true; 15053 } 15054 } 15055 15056 IrInstGen *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); 15057 if (type_is_invalid(casted_value->value->type)) 15058 return false; 15059 15060 return ir_resolve_const_align(ira->codegen, ira->new_irb.exec, value->base.source_node, 15061 casted_value->value, out); 15062 } 15063 15064 static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstGen *value, ZigType *int_type, uint64_t *out) { 15065 if (type_is_invalid(value->value->type)) 15066 return false; 15067 15068 IrInstGen *casted_value = ir_implicit_cast(ira, value, int_type); 15069 if (type_is_invalid(casted_value->value->type)) 15070 return false; 15071 15072 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15073 if (!const_val) 15074 return false; 15075 15076 *out = bigint_as_u64(&const_val->data.x_bigint); 15077 return true; 15078 } 15079 15080 static bool ir_resolve_usize(IrAnalyze *ira, IrInstGen *value, uint64_t *out) { 15081 return ir_resolve_unsigned(ira, value, ira->codegen->builtin_types.entry_usize, out); 15082 } 15083 15084 static bool ir_resolve_bool(IrAnalyze *ira, IrInstGen *value, bool *out) { 15085 if (type_is_invalid(value->value->type)) 15086 return false; 15087 15088 IrInstGen *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_bool); 15089 if (type_is_invalid(casted_value->value->type)) 15090 return false; 15091 15092 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15093 if (!const_val) 15094 return false; 15095 15096 *out = const_val->data.x_bool; 15097 return true; 15098 } 15099 15100 static bool ir_resolve_comptime(IrAnalyze *ira, IrInstGen *value, bool *out) { 15101 if (!value) { 15102 *out = false; 15103 return true; 15104 } 15105 return ir_resolve_bool(ira, value, out); 15106 } 15107 15108 static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstGen *value, AtomicOrder *out) { 15109 if (type_is_invalid(value->value->type)) 15110 return false; 15111 15112 ZigType *atomic_order_type = get_builtin_type(ira->codegen, "AtomicOrder"); 15113 15114 IrInstGen *casted_value = ir_implicit_cast(ira, value, atomic_order_type); 15115 if (type_is_invalid(casted_value->value->type)) 15116 return false; 15117 15118 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15119 if (!const_val) 15120 return false; 15121 15122 *out = (AtomicOrder)bigint_as_u32(&const_val->data.x_enum_tag); 15123 return true; 15124 } 15125 15126 static bool ir_resolve_atomic_rmw_op(IrAnalyze *ira, IrInstGen *value, AtomicRmwOp *out) { 15127 if (type_is_invalid(value->value->type)) 15128 return false; 15129 15130 ZigType *atomic_rmw_op_type = get_builtin_type(ira->codegen, "AtomicRmwOp"); 15131 15132 IrInstGen *casted_value = ir_implicit_cast(ira, value, atomic_rmw_op_type); 15133 if (type_is_invalid(casted_value->value->type)) 15134 return false; 15135 15136 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15137 if (!const_val) 15138 return false; 15139 15140 *out = (AtomicRmwOp)bigint_as_u32(&const_val->data.x_enum_tag); 15141 return true; 15142 } 15143 15144 static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstGen *value, GlobalLinkageId *out) { 15145 if (type_is_invalid(value->value->type)) 15146 return false; 15147 15148 ZigType *global_linkage_type = get_builtin_type(ira->codegen, "GlobalLinkage"); 15149 15150 IrInstGen *casted_value = ir_implicit_cast(ira, value, global_linkage_type); 15151 if (type_is_invalid(casted_value->value->type)) 15152 return false; 15153 15154 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15155 if (!const_val) 15156 return false; 15157 15158 *out = (GlobalLinkageId)bigint_as_u32(&const_val->data.x_enum_tag); 15159 return true; 15160 } 15161 15162 static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstGen *value, FloatMode *out) { 15163 if (type_is_invalid(value->value->type)) 15164 return false; 15165 15166 ZigType *float_mode_type = get_builtin_type(ira->codegen, "FloatMode"); 15167 15168 IrInstGen *casted_value = ir_implicit_cast(ira, value, float_mode_type); 15169 if (type_is_invalid(casted_value->value->type)) 15170 return false; 15171 15172 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15173 if (!const_val) 15174 return false; 15175 15176 *out = (FloatMode)bigint_as_u32(&const_val->data.x_enum_tag); 15177 return true; 15178 } 15179 15180 static Buf *ir_resolve_str(IrAnalyze *ira, IrInstGen *value) { 15181 if (type_is_invalid(value->value->type)) 15182 return nullptr; 15183 15184 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 15185 true, false, PtrLenUnknown, 0, 0, 0, false); 15186 ZigType *str_type = get_slice_type(ira->codegen, ptr_type); 15187 IrInstGen *casted_value = ir_implicit_cast(ira, value, str_type); 15188 if (type_is_invalid(casted_value->value->type)) 15189 return nullptr; 15190 15191 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15192 if (!const_val) 15193 return nullptr; 15194 15195 ZigValue *ptr_field = const_val->data.x_struct.fields[slice_ptr_index]; 15196 ZigValue *len_field = const_val->data.x_struct.fields[slice_len_index]; 15197 15198 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); 15199 ZigValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; 15200 expand_undef_array(ira->codegen, array_val); 15201 size_t len = bigint_as_usize(&len_field->data.x_bigint); 15202 if (array_val->data.x_array.special == ConstArraySpecialBuf && len == buf_len(array_val->data.x_array.data.s_buf)) { 15203 return array_val->data.x_array.data.s_buf; 15204 } 15205 Buf *result = buf_alloc(); 15206 buf_resize(result, len); 15207 for (size_t i = 0; i < len; i += 1) { 15208 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; 15209 ZigValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index]; 15210 if (char_val->special == ConstValSpecialUndef) { 15211 ir_add_error(ira, &casted_value->base, buf_sprintf("use of undefined value")); 15212 return nullptr; 15213 } 15214 uint64_t big_c = bigint_as_u64(&char_val->data.x_bigint); 15215 assert(big_c <= UINT8_MAX); 15216 uint8_t c = (uint8_t)big_c; 15217 buf_ptr(result)[i] = c; 15218 } 15219 return result; 15220 } 15221 15222 static IrInstGen *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, 15223 IrInstSrcAddImplicitReturnType *instruction) 15224 { 15225 IrInstGen *value = instruction->value->child; 15226 if (type_is_invalid(value->value->type)) 15227 return ir_unreach_error(ira); 15228 15229 if (instruction->result_loc_ret == nullptr || !instruction->result_loc_ret->implicit_return_type_done) { 15230 ira->src_implicit_return_type_list.append(value); 15231 } 15232 15233 return ir_const_void(ira, &instruction->base.base); 15234 } 15235 15236 static IrInstGen *ir_analyze_instruction_return(IrAnalyze *ira, IrInstSrcReturn *instruction) { 15237 if (instruction->operand == nullptr) { 15238 // result location mechanism took care of it. 15239 IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, nullptr); 15240 return ir_finish_anal(ira, result); 15241 } 15242 15243 IrInstGen *operand = instruction->operand->child; 15244 if (type_is_invalid(operand->value->type)) 15245 return ir_unreach_error(ira); 15246 15247 IrInstGen *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type); 15248 if (type_is_invalid(casted_operand->value->type)) { 15249 AstNode *source_node = ira->explicit_return_type_source_node; 15250 if (source_node != nullptr) { 15251 ErrorMsg *msg = ira->codegen->errors.last(); 15252 add_error_note(ira->codegen, msg, source_node, 15253 buf_sprintf("return type declared here")); 15254 } 15255 return ir_unreach_error(ira); 15256 } 15257 15258 if (!instr_is_comptime(operand) && ira->explicit_return_type != nullptr && 15259 handle_is_ptr(ira->explicit_return_type)) 15260 { 15261 // result location mechanism took care of it. 15262 IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, nullptr); 15263 return ir_finish_anal(ira, result); 15264 } 15265 15266 if (casted_operand->value->special == ConstValSpecialRuntime && 15267 casted_operand->value->type->id == ZigTypeIdPointer && 15268 casted_operand->value->data.rh_ptr == RuntimeHintPtrStack) 15269 { 15270 ir_add_error(ira, &instruction->operand->base, buf_sprintf("function returns address of local variable")); 15271 return ir_unreach_error(ira); 15272 } 15273 15274 IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, casted_operand); 15275 return ir_finish_anal(ira, result); 15276 } 15277 15278 static IrInstGen *ir_analyze_instruction_const(IrAnalyze *ira, IrInstSrcConst *instruction) { 15279 return ir_const_move(ira, &instruction->base.base, instruction->value); 15280 } 15281 15282 static IrInstGen *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { 15283 IrInstGen *op1 = bin_op_instruction->op1->child; 15284 if (type_is_invalid(op1->value->type)) 15285 return ira->codegen->invalid_inst_gen; 15286 15287 IrInstGen *op2 = bin_op_instruction->op2->child; 15288 if (type_is_invalid(op2->value->type)) 15289 return ira->codegen->invalid_inst_gen; 15290 15291 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 15292 15293 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, bool_type); 15294 if (type_is_invalid(casted_op1->value->type)) 15295 return ira->codegen->invalid_inst_gen; 15296 15297 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, bool_type); 15298 if (type_is_invalid(casted_op2->value->type)) 15299 return ira->codegen->invalid_inst_gen; 15300 15301 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 15302 ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 15303 if (op1_val == nullptr) 15304 return ira->codegen->invalid_inst_gen; 15305 15306 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 15307 if (op2_val == nullptr) 15308 return ira->codegen->invalid_inst_gen; 15309 15310 assert(casted_op1->value->type->id == ZigTypeIdBool); 15311 assert(casted_op2->value->type->id == ZigTypeIdBool); 15312 bool result_bool; 15313 if (bin_op_instruction->op_id == IrBinOpBoolOr) { 15314 result_bool = op1_val->data.x_bool || op2_val->data.x_bool; 15315 } else if (bin_op_instruction->op_id == IrBinOpBoolAnd) { 15316 result_bool = op1_val->data.x_bool && op2_val->data.x_bool; 15317 } else { 15318 zig_unreachable(); 15319 } 15320 return ir_const_bool(ira, &bin_op_instruction->base.base, result_bool); 15321 } 15322 15323 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, bool_type, 15324 bin_op_instruction->op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 15325 } 15326 15327 static bool resolve_cmp_op_id(IrBinOp op_id, Cmp cmp) { 15328 switch (op_id) { 15329 case IrBinOpCmpEq: 15330 return cmp == CmpEQ; 15331 case IrBinOpCmpNotEq: 15332 return cmp != CmpEQ; 15333 case IrBinOpCmpLessThan: 15334 return cmp == CmpLT; 15335 case IrBinOpCmpGreaterThan: 15336 return cmp == CmpGT; 15337 case IrBinOpCmpLessOrEq: 15338 return cmp != CmpGT; 15339 case IrBinOpCmpGreaterOrEq: 15340 return cmp != CmpLT; 15341 default: 15342 zig_unreachable(); 15343 } 15344 } 15345 15346 static bool optional_value_is_null(ZigValue *val) { 15347 assert(val->special == ConstValSpecialStatic); 15348 if (get_codegen_ptr_type(val->type) != nullptr) { 15349 if (val->data.x_ptr.special == ConstPtrSpecialNull) { 15350 return true; 15351 } else if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 15352 return val->data.x_ptr.data.hard_coded_addr.addr == 0; 15353 } else { 15354 return false; 15355 } 15356 } else if (is_opt_err_set(val->type)) { 15357 return val->data.x_err_set == nullptr; 15358 } else { 15359 return val->data.x_optional == nullptr; 15360 } 15361 } 15362 15363 static void set_optional_value_to_null(ZigValue *val) { 15364 assert(val->special == ConstValSpecialStatic); 15365 if (val->type->id == ZigTypeIdNull) return; // nothing to do 15366 assert(val->type->id == ZigTypeIdOptional); 15367 if (get_codegen_ptr_type(val->type) != nullptr) { 15368 val->data.x_ptr.special = ConstPtrSpecialNull; 15369 } else if (is_opt_err_set(val->type)) { 15370 val->data.x_err_set = nullptr; 15371 } else { 15372 val->data.x_optional = nullptr; 15373 } 15374 } 15375 15376 static void set_optional_payload(ZigValue *opt_val, ZigValue *payload) { 15377 assert(opt_val->special == ConstValSpecialStatic); 15378 assert(opt_val->type->id == ZigTypeIdOptional); 15379 if (payload == nullptr) { 15380 set_optional_value_to_null(opt_val); 15381 } else if (is_opt_err_set(opt_val->type)) { 15382 assert(payload->type->id == ZigTypeIdErrorSet); 15383 opt_val->data.x_err_set = payload->data.x_err_set; 15384 } else { 15385 opt_val->data.x_optional = payload; 15386 } 15387 } 15388 15389 static IrInstGen *ir_evaluate_bin_op_cmp(IrAnalyze *ira, ZigType *resolved_type, 15390 ZigValue *op1_val, ZigValue *op2_val, IrInstSrcBinOp *bin_op_instruction, IrBinOp op_id, 15391 bool one_possible_value) 15392 { 15393 if (op1_val->special == ConstValSpecialUndef || 15394 op2_val->special == ConstValSpecialUndef) 15395 return ir_const_undef(ira, &bin_op_instruction->base.base, resolved_type); 15396 if (resolved_type->id == ZigTypeIdPointer && op_id != IrBinOpCmpEq && op_id != IrBinOpCmpNotEq) { 15397 if ((op1_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 15398 op1_val->data.x_ptr.special == ConstPtrSpecialNull) && 15399 (op2_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 15400 op2_val->data.x_ptr.special == ConstPtrSpecialNull)) 15401 { 15402 uint64_t op1_addr = op1_val->data.x_ptr.special == ConstPtrSpecialNull ? 15403 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr; 15404 uint64_t op2_addr = op2_val->data.x_ptr.special == ConstPtrSpecialNull ? 15405 0 : op2_val->data.x_ptr.data.hard_coded_addr.addr; 15406 Cmp cmp_result; 15407 if (op1_addr > op2_addr) { 15408 cmp_result = CmpGT; 15409 } else if (op1_addr < op2_addr) { 15410 cmp_result = CmpLT; 15411 } else { 15412 cmp_result = CmpEQ; 15413 } 15414 bool answer = resolve_cmp_op_id(op_id, cmp_result); 15415 return ir_const_bool(ira, &bin_op_instruction->base.base, answer); 15416 } 15417 } else { 15418 bool are_equal = one_possible_value || const_values_equal(ira->codegen, op1_val, op2_val); 15419 bool answer; 15420 if (op_id == IrBinOpCmpEq) { 15421 answer = are_equal; 15422 } else if (op_id == IrBinOpCmpNotEq) { 15423 answer = !are_equal; 15424 } else { 15425 zig_unreachable(); 15426 } 15427 return ir_const_bool(ira, &bin_op_instruction->base.base, answer); 15428 } 15429 zig_unreachable(); 15430 } 15431 15432 // Returns ErrorNotLazy when the value cannot be determined 15433 static Error lazy_cmp_zero(CodeGen *codegen, AstNode *source_node, ZigValue *val, Cmp *result) { 15434 Error err; 15435 15436 switch (type_has_one_possible_value(codegen, val->type)) { 15437 case OnePossibleValueInvalid: 15438 return ErrorSemanticAnalyzeFail; 15439 case OnePossibleValueNo: 15440 break; 15441 case OnePossibleValueYes: 15442 switch (val->type->id) { 15443 case ZigTypeIdInt: 15444 src_assert(val->type->data.integral.bit_count == 0, source_node); 15445 *result = CmpEQ; 15446 return ErrorNone; 15447 case ZigTypeIdUndefined: 15448 return ErrorNotLazy; 15449 default: 15450 zig_unreachable(); 15451 } 15452 } 15453 15454 switch (val->special) { 15455 case ConstValSpecialRuntime: 15456 case ConstValSpecialUndef: 15457 return ErrorNotLazy; 15458 case ConstValSpecialStatic: 15459 switch (val->type->id) { 15460 case ZigTypeIdComptimeInt: 15461 case ZigTypeIdInt: 15462 *result = bigint_cmp_zero(&val->data.x_bigint); 15463 return ErrorNone; 15464 case ZigTypeIdComptimeFloat: 15465 case ZigTypeIdFloat: 15466 if (float_is_nan(val)) 15467 return ErrorNotLazy; 15468 *result = float_cmp_zero(val); 15469 return ErrorNone; 15470 default: 15471 return ErrorNotLazy; 15472 } 15473 case ConstValSpecialLazy: 15474 switch (val->data.x_lazy->id) { 15475 case LazyValueIdInvalid: 15476 zig_unreachable(); 15477 case LazyValueIdAlignOf: 15478 *result = CmpGT; 15479 return ErrorNone; 15480 case LazyValueIdSizeOf: { 15481 LazyValueSizeOf *lazy_size_of = reinterpret_cast<LazyValueSizeOf *>(val->data.x_lazy); 15482 IrAnalyze *ira = lazy_size_of->ira; 15483 bool is_zero_bits; 15484 if ((err = type_val_resolve_zero_bits(ira->codegen, lazy_size_of->target_type->value, 15485 nullptr, nullptr, &is_zero_bits))) 15486 { 15487 return err; 15488 } 15489 *result = is_zero_bits ? CmpEQ : CmpGT; 15490 return ErrorNone; 15491 } 15492 default: 15493 return ErrorNotLazy; 15494 } 15495 } 15496 zig_unreachable(); 15497 } 15498 15499 static ErrorMsg *ir_eval_bin_op_cmp_scalar(IrAnalyze *ira, IrInst* source_instr, 15500 ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val, ZigValue *out_val) 15501 { 15502 Error err; 15503 { 15504 // Before resolving the values, we special case comparisons against zero. These can often 15505 // be done without resolving lazy values, preventing potential dependency loops. 15506 Cmp op1_cmp_zero; 15507 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op1_val, &op1_cmp_zero))) { 15508 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally; 15509 return ira->codegen->trace_err; 15510 } 15511 Cmp op2_cmp_zero; 15512 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op2_val, &op2_cmp_zero))) { 15513 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally; 15514 return ira->codegen->trace_err; 15515 } 15516 bool can_cmp_zero = false; 15517 Cmp cmp_result; 15518 if (op1_cmp_zero == CmpEQ && op2_cmp_zero == CmpEQ) { 15519 can_cmp_zero = true; 15520 cmp_result = CmpEQ; 15521 } else if (op1_cmp_zero == CmpGT && op2_cmp_zero == CmpEQ) { 15522 can_cmp_zero = true; 15523 cmp_result = CmpGT; 15524 } else if (op1_cmp_zero == CmpEQ && op2_cmp_zero == CmpGT) { 15525 can_cmp_zero = true; 15526 cmp_result = CmpLT; 15527 } else if (op1_cmp_zero == CmpLT && op2_cmp_zero == CmpEQ) { 15528 can_cmp_zero = true; 15529 cmp_result = CmpLT; 15530 } else if (op1_cmp_zero == CmpEQ && op2_cmp_zero == CmpLT) { 15531 can_cmp_zero = true; 15532 cmp_result = CmpGT; 15533 } else if (op1_cmp_zero == CmpLT && op2_cmp_zero == CmpGT) { 15534 can_cmp_zero = true; 15535 cmp_result = CmpLT; 15536 } else if (op1_cmp_zero == CmpGT && op2_cmp_zero == CmpLT) { 15537 can_cmp_zero = true; 15538 cmp_result = CmpGT; 15539 } 15540 if (can_cmp_zero) { 15541 bool answer = resolve_cmp_op_id(op_id, cmp_result); 15542 out_val->special = ConstValSpecialStatic; 15543 out_val->data.x_bool = answer; 15544 return nullptr; 15545 } 15546 } 15547 never_mind_just_calculate_it_normally: 15548 15549 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_instr->source_node, 15550 op1_val, UndefOk))) 15551 { 15552 return ira->codegen->trace_err; 15553 } 15554 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_instr->source_node, 15555 op2_val, UndefOk))) 15556 { 15557 return ira->codegen->trace_err; 15558 } 15559 15560 15561 if (op1_val->special == ConstValSpecialUndef || op2_val->special == ConstValSpecialUndef || 15562 op1_val->type->id == ZigTypeIdUndefined || op2_val->type->id == ZigTypeIdUndefined) 15563 { 15564 out_val->special = ConstValSpecialUndef; 15565 return nullptr; 15566 } 15567 15568 bool op1_is_float = op1_val->type->id == ZigTypeIdFloat || op1_val->type->id == ZigTypeIdComptimeFloat; 15569 bool op2_is_float = op2_val->type->id == ZigTypeIdFloat || op2_val->type->id == ZigTypeIdComptimeFloat; 15570 if (op1_is_float && op2_is_float) { 15571 if (float_is_nan(op1_val) || float_is_nan(op2_val)) { 15572 out_val->special = ConstValSpecialStatic; 15573 out_val->data.x_bool = op_id == IrBinOpCmpNotEq; 15574 return nullptr; 15575 } 15576 if (op1_val->type->id == ZigTypeIdComptimeFloat) { 15577 IrInstGen *tmp = ir_const_noval(ira, source_instr); 15578 tmp->value = op1_val; 15579 IrInstGen *casted = ir_implicit_cast(ira, tmp, op2_val->type); 15580 op1_val = casted->value; 15581 } else if (op2_val->type->id == ZigTypeIdComptimeFloat) { 15582 IrInstGen *tmp = ir_const_noval(ira, source_instr); 15583 tmp->value = op2_val; 15584 IrInstGen *casted = ir_implicit_cast(ira, tmp, op1_val->type); 15585 op2_val = casted->value; 15586 } 15587 Cmp cmp_result = float_cmp(op1_val, op2_val); 15588 out_val->special = ConstValSpecialStatic; 15589 out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result); 15590 return nullptr; 15591 } 15592 15593 bool op1_is_int = op1_val->type->id == ZigTypeIdInt || op1_val->type->id == ZigTypeIdComptimeInt; 15594 bool op2_is_int = op2_val->type->id == ZigTypeIdInt || op2_val->type->id == ZigTypeIdComptimeInt; 15595 15596 if (op1_is_int && op2_is_int) { 15597 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); 15598 out_val->special = ConstValSpecialStatic; 15599 out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result); 15600 15601 return nullptr; 15602 } 15603 15604 // Handle the case where one of the two operands is a fp value and the other 15605 // is an integer value 15606 ZigValue *float_val; 15607 if (op1_is_int && op2_is_float) { 15608 float_val = op2_val; 15609 } else if (op1_is_float && op2_is_int) { 15610 float_val = op1_val; 15611 } else { 15612 zig_unreachable(); 15613 } 15614 15615 // They can never be equal if the fp value has a non-zero decimal part 15616 if (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq) { 15617 if (float_has_fraction(float_val)) { 15618 out_val->special = ConstValSpecialStatic; 15619 out_val->data.x_bool = op_id == IrBinOpCmpNotEq; 15620 return nullptr; 15621 } 15622 } 15623 15624 // Cast the integer operand into a fp value to perform the comparison 15625 BigFloat op1_bigfloat; 15626 BigFloat op2_bigfloat; 15627 value_to_bigfloat(&op1_bigfloat, op1_val); 15628 value_to_bigfloat(&op2_bigfloat, op2_val); 15629 15630 Cmp cmp_result = bigfloat_cmp(&op1_bigfloat, &op2_bigfloat); 15631 out_val->special = ConstValSpecialStatic; 15632 out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result); 15633 15634 return nullptr; 15635 } 15636 15637 static IrInstGen *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInst *source_instr, 15638 IrInstGen *op1, IrInstGen *op2, IrBinOp op_id) 15639 { 15640 Error err; 15641 15642 ZigType *scalar_result_type = ira->codegen->builtin_types.entry_bool; 15643 ZigType *result_type = scalar_result_type; 15644 ZigType *op1_scalar_type = op1->value->type; 15645 ZigType *op2_scalar_type = op2->value->type; 15646 if (op1->value->type->id == ZigTypeIdVector && op2->value->type->id == ZigTypeIdVector) { 15647 if (op1->value->type->data.vector.len != op2->value->type->data.vector.len) { 15648 ir_add_error(ira, source_instr, 15649 buf_sprintf("vector length mismatch: %" PRIu32 " and %" PRIu32, 15650 op1->value->type->data.vector.len, op2->value->type->data.vector.len)); 15651 return ira->codegen->invalid_inst_gen; 15652 } 15653 result_type = get_vector_type(ira->codegen, op1->value->type->data.vector.len, scalar_result_type); 15654 op1_scalar_type = op1->value->type->data.vector.elem_type; 15655 op2_scalar_type = op2->value->type->data.vector.elem_type; 15656 } else if (op1->value->type->id == ZigTypeIdVector || op2->value->type->id == ZigTypeIdVector) { 15657 ir_add_error(ira, source_instr, 15658 buf_sprintf("mixed scalar and vector operands to comparison operator: '%s' and '%s'", 15659 buf_ptr(&op1->value->type->name), buf_ptr(&op2->value->type->name))); 15660 return ira->codegen->invalid_inst_gen; 15661 } 15662 15663 bool opv_op1; 15664 switch (type_has_one_possible_value(ira->codegen, op1->value->type)) { 15665 case OnePossibleValueInvalid: 15666 return ira->codegen->invalid_inst_gen; 15667 case OnePossibleValueYes: 15668 opv_op1 = true; 15669 break; 15670 case OnePossibleValueNo: 15671 opv_op1 = false; 15672 break; 15673 } 15674 bool opv_op2; 15675 switch (type_has_one_possible_value(ira->codegen, op2->value->type)) { 15676 case OnePossibleValueInvalid: 15677 return ira->codegen->invalid_inst_gen; 15678 case OnePossibleValueYes: 15679 opv_op2 = true; 15680 break; 15681 case OnePossibleValueNo: 15682 opv_op2 = false; 15683 break; 15684 } 15685 Cmp op1_cmp_zero; 15686 bool have_op1_cmp_zero = false; 15687 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op1->value, &op1_cmp_zero))) { 15688 if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen; 15689 } else { 15690 have_op1_cmp_zero = true; 15691 } 15692 Cmp op2_cmp_zero; 15693 bool have_op2_cmp_zero = false; 15694 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op2->value, &op2_cmp_zero))) { 15695 if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen; 15696 } else { 15697 have_op2_cmp_zero = true; 15698 } 15699 if (((opv_op1 || instr_is_comptime(op1)) && (opv_op2 || instr_is_comptime(op2))) || 15700 (have_op1_cmp_zero && have_op2_cmp_zero)) 15701 { 15702 IrInstGen *result_instruction = ir_const(ira, source_instr, result_type); 15703 ZigValue *out_val = result_instruction->value; 15704 if (result_type->id == ZigTypeIdVector) { 15705 size_t len = result_type->data.vector.len; 15706 expand_undef_array(ira->codegen, op1->value); 15707 expand_undef_array(ira->codegen, op2->value); 15708 out_val->special = ConstValSpecialUndef; 15709 expand_undef_array(ira->codegen, out_val); 15710 for (size_t i = 0; i < len; i += 1) { 15711 ZigValue *scalar_op1_val = &op1->value->data.x_array.data.s_none.elements[i]; 15712 ZigValue *scalar_op2_val = &op2->value->data.x_array.data.s_none.elements[i]; 15713 ZigValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 15714 assert(scalar_out_val->type == scalar_result_type); 15715 ErrorMsg *msg = ir_eval_bin_op_cmp_scalar(ira, source_instr, 15716 scalar_op1_val, op_id, scalar_op2_val, scalar_out_val); 15717 if (msg != nullptr) { 15718 add_error_note(ira->codegen, msg, source_instr->source_node, 15719 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 15720 return ira->codegen->invalid_inst_gen; 15721 } 15722 } 15723 out_val->type = result_type; 15724 out_val->special = ConstValSpecialStatic; 15725 } else { 15726 if (ir_eval_bin_op_cmp_scalar(ira, source_instr, op1->value, op_id, 15727 op2->value, out_val) != nullptr) 15728 { 15729 return ira->codegen->invalid_inst_gen; 15730 } 15731 } 15732 return result_instruction; 15733 } 15734 15735 // If one operand has a comptime-known comparison with 0, and the other operand is unsigned, we might 15736 // know the answer, depending on the operator. 15737 // TODO make this work with vectors 15738 if (have_op1_cmp_zero && op2_scalar_type->id == ZigTypeIdInt && !op2_scalar_type->data.integral.is_signed) { 15739 if (op1_cmp_zero == CmpEQ) { 15740 // 0 <= unsigned_x // true 15741 // 0 > unsigned_x // false 15742 switch (op_id) { 15743 case IrBinOpCmpLessOrEq: 15744 return ir_const_bool(ira, source_instr, true); 15745 case IrBinOpCmpGreaterThan: 15746 return ir_const_bool(ira, source_instr, false); 15747 default: 15748 break; 15749 } 15750 } else if (op1_cmp_zero == CmpLT) { 15751 // -1 != unsigned_x // true 15752 // -1 <= unsigned_x // true 15753 // -1 < unsigned_x // true 15754 // -1 == unsigned_x // false 15755 // -1 >= unsigned_x // false 15756 // -1 > unsigned_x // false 15757 switch (op_id) { 15758 case IrBinOpCmpNotEq: 15759 case IrBinOpCmpLessOrEq: 15760 case IrBinOpCmpLessThan: 15761 return ir_const_bool(ira, source_instr, true); 15762 case IrBinOpCmpEq: 15763 case IrBinOpCmpGreaterOrEq: 15764 case IrBinOpCmpGreaterThan: 15765 return ir_const_bool(ira, source_instr, false); 15766 default: 15767 break; 15768 } 15769 } 15770 } 15771 if (have_op2_cmp_zero && op1_scalar_type->id == ZigTypeIdInt && !op1_scalar_type->data.integral.is_signed) { 15772 if (op2_cmp_zero == CmpEQ) { 15773 // unsigned_x < 0 // false 15774 // unsigned_x >= 0 // true 15775 switch (op_id) { 15776 case IrBinOpCmpLessThan: 15777 return ir_const_bool(ira, source_instr, false); 15778 case IrBinOpCmpGreaterOrEq: 15779 return ir_const_bool(ira, source_instr, true); 15780 default: 15781 break; 15782 } 15783 } else if (op2_cmp_zero == CmpLT) { 15784 // unsigned_x != -1 // true 15785 // unsigned_x >= -1 // true 15786 // unsigned_x > -1 // true 15787 // unsigned_x == -1 // false 15788 // unsigned_x < -1 // false 15789 // unsigned_x <= -1 // false 15790 switch (op_id) { 15791 case IrBinOpCmpNotEq: 15792 case IrBinOpCmpGreaterOrEq: 15793 case IrBinOpCmpGreaterThan: 15794 return ir_const_bool(ira, source_instr, true); 15795 case IrBinOpCmpEq: 15796 case IrBinOpCmpLessThan: 15797 case IrBinOpCmpLessOrEq: 15798 return ir_const_bool(ira, source_instr, false); 15799 default: 15800 break; 15801 } 15802 } 15803 } 15804 15805 // It must be a runtime comparison. 15806 // For floats, emit a float comparison instruction. 15807 bool op1_is_float = op1_scalar_type->id == ZigTypeIdFloat || op1_scalar_type->id == ZigTypeIdComptimeFloat; 15808 bool op2_is_float = op2_scalar_type->id == ZigTypeIdFloat || op2_scalar_type->id == ZigTypeIdComptimeFloat; 15809 if (op1_is_float && op2_is_float) { 15810 // Implicit cast the smaller one to the larger one. 15811 ZigType *dest_scalar_type; 15812 if (op1_scalar_type->id == ZigTypeIdComptimeFloat) { 15813 dest_scalar_type = op2_scalar_type; 15814 } else if (op2_scalar_type->id == ZigTypeIdComptimeFloat) { 15815 dest_scalar_type = op1_scalar_type; 15816 } else if (op1_scalar_type->data.floating.bit_count >= op2_scalar_type->data.floating.bit_count) { 15817 dest_scalar_type = op1_scalar_type; 15818 } else { 15819 dest_scalar_type = op2_scalar_type; 15820 } 15821 ZigType *dest_type = (result_type->id == ZigTypeIdVector) ? 15822 get_vector_type(ira->codegen, result_type->data.vector.len, dest_scalar_type) : dest_scalar_type; 15823 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 15824 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, dest_type); 15825 if (type_is_invalid(casted_op1->value->type) || type_is_invalid(casted_op2->value->type)) 15826 return ira->codegen->invalid_inst_gen; 15827 return ir_build_bin_op_gen(ira, source_instr, result_type, op_id, casted_op1, casted_op2, true); 15828 } 15829 15830 // For mixed unsigned integer sizes, implicit cast both operands to the larger integer. 15831 // For mixed signed and unsigned integers, implicit cast both operands to a signed 15832 // integer with + 1 bit. 15833 // For mixed floats and integers, extract the integer part from the float, cast that to 15834 // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float, 15835 // add/subtract 1. 15836 bool dest_int_is_signed = false; 15837 if (have_op1_cmp_zero) { 15838 if (op1_cmp_zero == CmpLT) dest_int_is_signed = true; 15839 } else if (op1_is_float) { 15840 dest_int_is_signed = true; 15841 } else if (op1_scalar_type->id == ZigTypeIdInt && op1_scalar_type->data.integral.is_signed) { 15842 dest_int_is_signed = true; 15843 } 15844 if (have_op2_cmp_zero) { 15845 if (op2_cmp_zero == CmpLT) dest_int_is_signed = true; 15846 } else if (op2_is_float) { 15847 dest_int_is_signed = true; 15848 } else if (op2->value->type->id == ZigTypeIdInt && op2->value->type->data.integral.is_signed) { 15849 dest_int_is_signed = true; 15850 } 15851 ZigType *dest_float_type = nullptr; 15852 uint32_t op1_bits; 15853 if (instr_is_comptime(op1)) { 15854 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefOk); 15855 if (op1_val == nullptr) 15856 return ira->codegen->invalid_inst_gen; 15857 if (op1_val->special == ConstValSpecialUndef) 15858 return ir_const_undef(ira, source_instr, ira->codegen->builtin_types.entry_bool); 15859 if (result_type->id == ZigTypeIdVector) { 15860 ir_add_error(ira, &op1->base, buf_sprintf("compiler bug: TODO: support comptime vector here")); 15861 return ira->codegen->invalid_inst_gen; 15862 } 15863 bool is_unsigned; 15864 if (op1_is_float) { 15865 BigInt bigint = {}; 15866 float_init_bigint(&bigint, op1_val); 15867 Cmp zcmp = float_cmp_zero(op1_val); 15868 if (float_has_fraction(op1_val)) { 15869 if (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq) { 15870 return ir_const_bool(ira, source_instr, op_id == IrBinOpCmpNotEq); 15871 } 15872 if (zcmp == CmpLT) { 15873 bigint_decr(&bigint); 15874 } else { 15875 bigint_incr(&bigint); 15876 } 15877 } 15878 op1_bits = bigint_bits_needed(&bigint); 15879 is_unsigned = zcmp != CmpLT; 15880 } else { 15881 op1_bits = bigint_bits_needed(&op1_val->data.x_bigint); 15882 is_unsigned = bigint_cmp_zero(&op1_val->data.x_bigint) != CmpLT; 15883 } 15884 if (is_unsigned && dest_int_is_signed) { 15885 op1_bits += 1; 15886 } 15887 } else if (op1_is_float) { 15888 dest_float_type = op1_scalar_type; 15889 } else { 15890 ir_assert(op1_scalar_type->id == ZigTypeIdInt, source_instr); 15891 op1_bits = op1_scalar_type->data.integral.bit_count; 15892 if (!op1_scalar_type->data.integral.is_signed && dest_int_is_signed) { 15893 op1_bits += 1; 15894 } 15895 } 15896 uint32_t op2_bits; 15897 if (instr_is_comptime(op2)) { 15898 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefOk); 15899 if (op2_val == nullptr) 15900 return ira->codegen->invalid_inst_gen; 15901 if (op2_val->special == ConstValSpecialUndef) 15902 return ir_const_undef(ira, source_instr, ira->codegen->builtin_types.entry_bool); 15903 if (result_type->id == ZigTypeIdVector) { 15904 ir_add_error(ira, &op2->base, buf_sprintf("compiler bug: TODO: support comptime vector here")); 15905 return ira->codegen->invalid_inst_gen; 15906 } 15907 bool is_unsigned; 15908 if (op2_is_float) { 15909 BigInt bigint = {}; 15910 float_init_bigint(&bigint, op2_val); 15911 Cmp zcmp = float_cmp_zero(op2_val); 15912 if (float_has_fraction(op2_val)) { 15913 if (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq) { 15914 return ir_const_bool(ira, source_instr, op_id == IrBinOpCmpNotEq); 15915 } 15916 if (zcmp == CmpLT) { 15917 bigint_decr(&bigint); 15918 } else { 15919 bigint_incr(&bigint); 15920 } 15921 } 15922 op2_bits = bigint_bits_needed(&bigint); 15923 is_unsigned = zcmp != CmpLT; 15924 } else { 15925 op2_bits = bigint_bits_needed(&op2_val->data.x_bigint); 15926 is_unsigned = bigint_cmp_zero(&op2_val->data.x_bigint) != CmpLT; 15927 } 15928 if (is_unsigned && dest_int_is_signed) { 15929 op2_bits += 1; 15930 } 15931 } else if (op2_is_float) { 15932 dest_float_type = op2_scalar_type; 15933 } else { 15934 ir_assert(op2_scalar_type->id == ZigTypeIdInt, source_instr); 15935 op2_bits = op2_scalar_type->data.integral.bit_count; 15936 if (!op2_scalar_type->data.integral.is_signed && dest_int_is_signed) { 15937 op2_bits += 1; 15938 } 15939 } 15940 ZigType *dest_scalar_type = (dest_float_type == nullptr) ? 15941 get_int_type(ira->codegen, dest_int_is_signed, (op1_bits > op2_bits) ? op1_bits : op2_bits) : 15942 dest_float_type; 15943 ZigType *dest_type = (result_type->id == ZigTypeIdVector) ? 15944 get_vector_type(ira->codegen, result_type->data.vector.len, dest_scalar_type) : dest_scalar_type; 15945 15946 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 15947 if (type_is_invalid(casted_op1->value->type)) 15948 return ira->codegen->invalid_inst_gen; 15949 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, dest_type); 15950 if (type_is_invalid(casted_op2->value->type)) 15951 return ira->codegen->invalid_inst_gen; 15952 return ir_build_bin_op_gen(ira, source_instr, result_type, op_id, casted_op1, casted_op2, true); 15953 } 15954 15955 static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { 15956 IrInstGen *op1 = bin_op_instruction->op1->child; 15957 if (type_is_invalid(op1->value->type)) 15958 return ira->codegen->invalid_inst_gen; 15959 15960 IrInstGen *op2 = bin_op_instruction->op2->child; 15961 if (type_is_invalid(op2->value->type)) 15962 return ira->codegen->invalid_inst_gen; 15963 15964 AstNode *source_node = bin_op_instruction->base.base.source_node; 15965 15966 IrBinOp op_id = bin_op_instruction->op_id; 15967 bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 15968 if (is_equality_cmp && op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdNull) { 15969 return ir_const_bool(ira, &bin_op_instruction->base.base, (op_id == IrBinOpCmpEq)); 15970 } else if (is_equality_cmp && 15971 ((op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdOptional) || 15972 (op2->value->type->id == ZigTypeIdNull && op1->value->type->id == ZigTypeIdOptional))) 15973 { 15974 IrInstGen *maybe_op; 15975 if (op1->value->type->id == ZigTypeIdNull) { 15976 maybe_op = op2; 15977 } else if (op2->value->type->id == ZigTypeIdNull) { 15978 maybe_op = op1; 15979 } else { 15980 zig_unreachable(); 15981 } 15982 if (instr_is_comptime(maybe_op)) { 15983 ZigValue *maybe_val = ir_resolve_const(ira, maybe_op, UndefBad); 15984 if (!maybe_val) 15985 return ira->codegen->invalid_inst_gen; 15986 bool is_null = optional_value_is_null(maybe_val); 15987 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 15988 return ir_const_bool(ira, &bin_op_instruction->base.base, bool_result); 15989 } 15990 15991 IrInstGen *is_non_null = ir_build_test_non_null_gen(ira, &bin_op_instruction->base.base, maybe_op); 15992 15993 if (op_id == IrBinOpCmpEq) { 15994 return ir_build_bool_not_gen(ira, &bin_op_instruction->base.base, is_non_null); 15995 } else { 15996 return is_non_null; 15997 } 15998 } else if (is_equality_cmp && 15999 ((op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdPointer && 16000 op2->value->type->data.pointer.ptr_len == PtrLenC) || 16001 (op2->value->type->id == ZigTypeIdNull && op1->value->type->id == ZigTypeIdPointer && 16002 op1->value->type->data.pointer.ptr_len == PtrLenC))) 16003 { 16004 IrInstGen *c_ptr_op; 16005 if (op1->value->type->id == ZigTypeIdNull) { 16006 c_ptr_op = op2; 16007 } else if (op2->value->type->id == ZigTypeIdNull) { 16008 c_ptr_op = op1; 16009 } else { 16010 zig_unreachable(); 16011 } 16012 if (instr_is_comptime(c_ptr_op)) { 16013 ZigValue *c_ptr_val = ir_resolve_const(ira, c_ptr_op, UndefOk); 16014 if (!c_ptr_val) 16015 return ira->codegen->invalid_inst_gen; 16016 if (c_ptr_val->special == ConstValSpecialUndef) 16017 return ir_const_undef(ira, &bin_op_instruction->base.base, ira->codegen->builtin_types.entry_bool); 16018 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 16019 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 16020 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 16021 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 16022 return ir_const_bool(ira, &bin_op_instruction->base.base, bool_result); 16023 } 16024 IrInstGen *is_non_null = ir_build_test_non_null_gen(ira, &bin_op_instruction->base.base, c_ptr_op); 16025 16026 if (op_id == IrBinOpCmpEq) { 16027 return ir_build_bool_not_gen(ira, &bin_op_instruction->base.base, is_non_null); 16028 } else { 16029 return is_non_null; 16030 } 16031 } else if (op1->value->type->id == ZigTypeIdNull || op2->value->type->id == ZigTypeIdNull) { 16032 ZigType *non_null_type = (op1->value->type->id == ZigTypeIdNull) ? op2->value->type : op1->value->type; 16033 ir_add_error_node(ira, source_node, buf_sprintf("comparison of '%s' with null", 16034 buf_ptr(&non_null_type->name))); 16035 return ira->codegen->invalid_inst_gen; 16036 } else if (is_equality_cmp && ( 16037 (op1->value->type->id == ZigTypeIdEnumLiteral && op2->value->type->id == ZigTypeIdUnion) || 16038 (op2->value->type->id == ZigTypeIdEnumLiteral && op1->value->type->id == ZigTypeIdUnion))) 16039 { 16040 // Support equality comparison between a union's tag value and a enum literal 16041 IrInstGen *union_val = op1->value->type->id == ZigTypeIdUnion ? op1 : op2; 16042 IrInstGen *enum_val = op1->value->type->id == ZigTypeIdUnion ? op2 : op1; 16043 16044 ZigType *tag_type = union_val->value->type->data.unionation.tag_type; 16045 assert(tag_type != nullptr); 16046 16047 IrInstGen *casted_union = ir_implicit_cast(ira, union_val, tag_type); 16048 if (type_is_invalid(casted_union->value->type)) 16049 return ira->codegen->invalid_inst_gen; 16050 16051 IrInstGen *casted_val = ir_implicit_cast(ira, enum_val, tag_type); 16052 if (type_is_invalid(casted_val->value->type)) 16053 return ira->codegen->invalid_inst_gen; 16054 16055 if (instr_is_comptime(casted_union)) { 16056 ZigValue *const_union_val = ir_resolve_const(ira, casted_union, UndefBad); 16057 if (!const_union_val) 16058 return ira->codegen->invalid_inst_gen; 16059 16060 ZigValue *const_enum_val = ir_resolve_const(ira, casted_val, UndefBad); 16061 if (!const_enum_val) 16062 return ira->codegen->invalid_inst_gen; 16063 16064 Cmp cmp_result = bigint_cmp(&const_union_val->data.x_union.tag, &const_enum_val->data.x_enum_tag); 16065 bool bool_result = (op_id == IrBinOpCmpEq) ? cmp_result == CmpEQ : cmp_result != CmpEQ; 16066 16067 return ir_const_bool(ira, &bin_op_instruction->base.base, bool_result); 16068 } 16069 16070 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, ira->codegen->builtin_types.entry_bool, 16071 op_id, casted_union, casted_val, bin_op_instruction->safety_check_on); 16072 } 16073 16074 if (op1->value->type->id == ZigTypeIdErrorSet && op2->value->type->id == ZigTypeIdErrorSet) { 16075 if (!is_equality_cmp) { 16076 ir_add_error_node(ira, source_node, buf_sprintf("operator not allowed for errors")); 16077 return ira->codegen->invalid_inst_gen; 16078 } 16079 ZigType *intersect_type = get_error_set_intersection(ira, op1->value->type, op2->value->type, source_node); 16080 if (type_is_invalid(intersect_type)) { 16081 return ira->codegen->invalid_inst_gen; 16082 } 16083 16084 if (!resolve_inferred_error_set(ira->codegen, intersect_type, source_node)) { 16085 return ira->codegen->invalid_inst_gen; 16086 } 16087 16088 // exception if one of the operators has the type of the empty error set, we allow the comparison 16089 // (and make it comptime known) 16090 // this is a function which is evaluated at comptime and returns an inferred error set will have an empty 16091 // error set. 16092 if (op1->value->type->data.error_set.err_count == 0 || op2->value->type->data.error_set.err_count == 0) { 16093 bool are_equal = false; 16094 bool answer; 16095 if (op_id == IrBinOpCmpEq) { 16096 answer = are_equal; 16097 } else if (op_id == IrBinOpCmpNotEq) { 16098 answer = !are_equal; 16099 } else { 16100 zig_unreachable(); 16101 } 16102 return ir_const_bool(ira, &bin_op_instruction->base.base, answer); 16103 } 16104 16105 if (!type_is_global_error_set(intersect_type)) { 16106 if (intersect_type->data.error_set.err_count == 0) { 16107 ir_add_error_node(ira, source_node, 16108 buf_sprintf("error sets '%s' and '%s' have no common errors", 16109 buf_ptr(&op1->value->type->name), buf_ptr(&op2->value->type->name))); 16110 return ira->codegen->invalid_inst_gen; 16111 } 16112 if (op1->value->type->data.error_set.err_count == 1 && op2->value->type->data.error_set.err_count == 1) { 16113 bool are_equal = true; 16114 bool answer; 16115 if (op_id == IrBinOpCmpEq) { 16116 answer = are_equal; 16117 } else if (op_id == IrBinOpCmpNotEq) { 16118 answer = !are_equal; 16119 } else { 16120 zig_unreachable(); 16121 } 16122 return ir_const_bool(ira, &bin_op_instruction->base.base, answer); 16123 } 16124 } 16125 16126 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 16127 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 16128 if (op1_val == nullptr) 16129 return ira->codegen->invalid_inst_gen; 16130 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 16131 if (op2_val == nullptr) 16132 return ira->codegen->invalid_inst_gen; 16133 16134 bool answer; 16135 bool are_equal = op1_val->data.x_err_set->value == op2_val->data.x_err_set->value; 16136 if (op_id == IrBinOpCmpEq) { 16137 answer = are_equal; 16138 } else if (op_id == IrBinOpCmpNotEq) { 16139 answer = !are_equal; 16140 } else { 16141 zig_unreachable(); 16142 } 16143 16144 return ir_const_bool(ira, &bin_op_instruction->base.base, answer); 16145 } 16146 16147 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, ira->codegen->builtin_types.entry_bool, 16148 op_id, op1, op2, bin_op_instruction->safety_check_on); 16149 } 16150 16151 if (type_is_numeric(op1->value->type) && type_is_numeric(op2->value->type)) { 16152 // This operation allows any combination of integer and float types, regardless of the 16153 // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for 16154 // numeric types. 16155 return ir_analyze_bin_op_cmp_numeric(ira, &bin_op_instruction->base.base, op1, op2, op_id); 16156 } 16157 16158 IrInstGen *instructions[] = {op1, op2}; 16159 ZigType *resolved_type = ir_resolve_peer_types(ira, source_node, nullptr, instructions, 2); 16160 if (type_is_invalid(resolved_type)) 16161 return ira->codegen->invalid_inst_gen; 16162 16163 bool operator_allowed; 16164 switch (resolved_type->id) { 16165 case ZigTypeIdInvalid: 16166 zig_unreachable(); // handled above 16167 16168 case ZigTypeIdComptimeFloat: 16169 case ZigTypeIdComptimeInt: 16170 case ZigTypeIdInt: 16171 case ZigTypeIdFloat: 16172 zig_unreachable(); // handled with the type_is_numeric checks above 16173 16174 case ZigTypeIdVector: 16175 // Not every case is handled by the type_is_numeric checks above, 16176 // vectors of bool trigger this code path 16177 case ZigTypeIdBool: 16178 case ZigTypeIdMetaType: 16179 case ZigTypeIdVoid: 16180 case ZigTypeIdErrorSet: 16181 case ZigTypeIdFn: 16182 case ZigTypeIdOpaque: 16183 case ZigTypeIdBoundFn: 16184 case ZigTypeIdEnum: 16185 case ZigTypeIdEnumLiteral: 16186 case ZigTypeIdAnyFrame: 16187 operator_allowed = is_equality_cmp; 16188 break; 16189 16190 case ZigTypeIdPointer: 16191 operator_allowed = is_equality_cmp || (resolved_type->data.pointer.ptr_len == PtrLenC); 16192 break; 16193 16194 case ZigTypeIdUnreachable: 16195 case ZigTypeIdArray: 16196 case ZigTypeIdStruct: 16197 case ZigTypeIdUndefined: 16198 case ZigTypeIdNull: 16199 case ZigTypeIdErrorUnion: 16200 case ZigTypeIdUnion: 16201 case ZigTypeIdFnFrame: 16202 operator_allowed = false; 16203 break; 16204 case ZigTypeIdOptional: 16205 operator_allowed = is_equality_cmp && get_codegen_ptr_type(resolved_type) != nullptr; 16206 break; 16207 } 16208 if (!operator_allowed) { 16209 ir_add_error_node(ira, source_node, 16210 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name))); 16211 return ira->codegen->invalid_inst_gen; 16212 } 16213 16214 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 16215 if (type_is_invalid(casted_op1->value->type)) 16216 return ira->codegen->invalid_inst_gen; 16217 16218 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 16219 if (type_is_invalid(casted_op2->value->type)) 16220 return ira->codegen->invalid_inst_gen; 16221 16222 bool one_possible_value; 16223 switch (type_has_one_possible_value(ira->codegen, resolved_type)) { 16224 case OnePossibleValueInvalid: 16225 return ira->codegen->invalid_inst_gen; 16226 case OnePossibleValueYes: 16227 one_possible_value = true; 16228 break; 16229 case OnePossibleValueNo: 16230 one_possible_value = false; 16231 break; 16232 } 16233 16234 if (one_possible_value || (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2))) { 16235 ZigValue *op1_val = one_possible_value ? casted_op1->value : ir_resolve_const(ira, casted_op1, UndefBad); 16236 if (op1_val == nullptr) 16237 return ira->codegen->invalid_inst_gen; 16238 ZigValue *op2_val = one_possible_value ? casted_op2->value : ir_resolve_const(ira, casted_op2, UndefBad); 16239 if (op2_val == nullptr) 16240 return ira->codegen->invalid_inst_gen; 16241 if (resolved_type->id != ZigTypeIdVector) 16242 return ir_evaluate_bin_op_cmp(ira, resolved_type, op1_val, op2_val, bin_op_instruction, op_id, one_possible_value); 16243 IrInstGen *result = ir_const(ira, &bin_op_instruction->base.base, 16244 get_vector_type(ira->codegen, resolved_type->data.vector.len, ira->codegen->builtin_types.entry_bool)); 16245 result->value->data.x_array.data.s_none.elements = 16246 ira->codegen->pass1_arena->allocate<ZigValue>(resolved_type->data.vector.len); 16247 16248 expand_undef_array(ira->codegen, result->value); 16249 for (size_t i = 0;i < resolved_type->data.vector.len;i++) { 16250 IrInstGen *cur_res = ir_evaluate_bin_op_cmp(ira, resolved_type->data.vector.elem_type, 16251 &op1_val->data.x_array.data.s_none.elements[i], 16252 &op2_val->data.x_array.data.s_none.elements[i], 16253 bin_op_instruction, op_id, one_possible_value); 16254 copy_const_val(ira->codegen, &result->value->data.x_array.data.s_none.elements[i], cur_res->value); 16255 } 16256 return result; 16257 } 16258 16259 ZigType *res_type = (resolved_type->id == ZigTypeIdVector) ? 16260 get_vector_type(ira->codegen, resolved_type->data.vector.len, ira->codegen->builtin_types.entry_bool) : 16261 ira->codegen->builtin_types.entry_bool; 16262 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, res_type, 16263 op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 16264 } 16265 16266 static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInst* source_instr, ZigType *type_entry, 16267 ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val, ZigValue *out_val) 16268 { 16269 bool is_int; 16270 bool is_float; 16271 Cmp op2_zcmp; 16272 if (type_entry->id == ZigTypeIdInt || type_entry->id == ZigTypeIdComptimeInt) { 16273 is_int = true; 16274 is_float = false; 16275 op2_zcmp = bigint_cmp_zero(&op2_val->data.x_bigint); 16276 } else if (type_entry->id == ZigTypeIdFloat || 16277 type_entry->id == ZigTypeIdComptimeFloat) 16278 { 16279 is_int = false; 16280 is_float = true; 16281 op2_zcmp = float_cmp_zero(op2_val); 16282 } else { 16283 zig_unreachable(); 16284 } 16285 16286 if ((op_id == IrBinOpDivUnspecified || op_id == IrBinOpRemRem || op_id == IrBinOpRemMod || 16287 op_id == IrBinOpDivTrunc || op_id == IrBinOpDivFloor) && op2_zcmp == CmpEQ) 16288 { 16289 return ir_add_error(ira, source_instr, buf_sprintf("division by zero")); 16290 } 16291 if ((op_id == IrBinOpRemRem || op_id == IrBinOpRemMod) && op2_zcmp == CmpLT) { 16292 return ir_add_error(ira, source_instr, buf_sprintf("negative denominator")); 16293 } 16294 16295 switch (op_id) { 16296 case IrBinOpInvalid: 16297 case IrBinOpBoolOr: 16298 case IrBinOpBoolAnd: 16299 case IrBinOpCmpEq: 16300 case IrBinOpCmpNotEq: 16301 case IrBinOpCmpLessThan: 16302 case IrBinOpCmpGreaterThan: 16303 case IrBinOpCmpLessOrEq: 16304 case IrBinOpCmpGreaterOrEq: 16305 case IrBinOpArrayCat: 16306 case IrBinOpArrayMult: 16307 case IrBinOpRemUnspecified: 16308 zig_unreachable(); 16309 case IrBinOpBinOr: 16310 assert(is_int); 16311 bigint_or(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16312 break; 16313 case IrBinOpBinXor: 16314 assert(is_int); 16315 bigint_xor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16316 break; 16317 case IrBinOpBinAnd: 16318 assert(is_int); 16319 bigint_and(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16320 break; 16321 case IrBinOpBitShiftLeftExact: 16322 assert(is_int); 16323 bigint_shl(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16324 break; 16325 case IrBinOpBitShiftLeftLossy: 16326 assert(type_entry->id == ZigTypeIdInt); 16327 bigint_shl_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 16328 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 16329 break; 16330 case IrBinOpBitShiftRightExact: 16331 { 16332 assert(is_int); 16333 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16334 BigInt orig_bigint; 16335 bigint_shl(&orig_bigint, &out_val->data.x_bigint, &op2_val->data.x_bigint); 16336 if (bigint_cmp(&op1_val->data.x_bigint, &orig_bigint) != CmpEQ) { 16337 return ir_add_error(ira, source_instr, buf_sprintf("exact shift shifted out 1 bits")); 16338 } 16339 break; 16340 } 16341 case IrBinOpBitShiftRightLossy: 16342 assert(is_int); 16343 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16344 break; 16345 case IrBinOpAdd: 16346 if (is_int) { 16347 bigint_add(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16348 } else { 16349 float_add(out_val, op1_val, op2_val); 16350 } 16351 break; 16352 case IrBinOpAddWrap: 16353 assert(type_entry->id == ZigTypeIdInt); 16354 bigint_add_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 16355 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 16356 break; 16357 case IrBinOpSub: 16358 if (is_int) { 16359 bigint_sub(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16360 } else { 16361 float_sub(out_val, op1_val, op2_val); 16362 } 16363 break; 16364 case IrBinOpSubWrap: 16365 assert(type_entry->id == ZigTypeIdInt); 16366 bigint_sub_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 16367 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 16368 break; 16369 case IrBinOpMult: 16370 if (is_int) { 16371 bigint_mul(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16372 } else { 16373 float_mul(out_val, op1_val, op2_val); 16374 } 16375 break; 16376 case IrBinOpMultWrap: 16377 assert(type_entry->id == ZigTypeIdInt); 16378 bigint_mul_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 16379 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 16380 break; 16381 case IrBinOpDivUnspecified: 16382 assert(is_float); 16383 float_div(out_val, op1_val, op2_val); 16384 break; 16385 case IrBinOpDivTrunc: 16386 if (is_int) { 16387 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16388 } else { 16389 float_div_trunc(out_val, op1_val, op2_val); 16390 } 16391 break; 16392 case IrBinOpDivFloor: 16393 if (is_int) { 16394 bigint_div_floor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16395 } else { 16396 float_div_floor(out_val, op1_val, op2_val); 16397 } 16398 break; 16399 case IrBinOpDivExact: 16400 if (is_int) { 16401 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16402 BigInt remainder; 16403 bigint_rem(&remainder, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16404 if (bigint_cmp_zero(&remainder) != CmpEQ) { 16405 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); 16406 } 16407 } else { 16408 float_div_trunc(out_val, op1_val, op2_val); 16409 ZigValue remainder = {}; 16410 float_rem(&remainder, op1_val, op2_val); 16411 if (float_cmp_zero(&remainder) != CmpEQ) { 16412 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); 16413 } 16414 } 16415 break; 16416 case IrBinOpRemRem: 16417 if (is_int) { 16418 bigint_rem(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16419 } else { 16420 float_rem(out_val, op1_val, op2_val); 16421 } 16422 break; 16423 case IrBinOpRemMod: 16424 if (is_int) { 16425 bigint_mod(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16426 } else { 16427 float_mod(out_val, op1_val, op2_val); 16428 } 16429 break; 16430 } 16431 16432 if (type_entry->id == ZigTypeIdInt) { 16433 if (!bigint_fits_in_bits(&out_val->data.x_bigint, type_entry->data.integral.bit_count, 16434 type_entry->data.integral.is_signed)) 16435 { 16436 return ir_add_error(ira, source_instr, buf_sprintf("operation caused overflow")); 16437 } 16438 } 16439 16440 out_val->type = type_entry; 16441 out_val->special = ConstValSpecialStatic; 16442 return nullptr; 16443 } 16444 16445 // This works on operands that have already been checked to be comptime known. 16446 static IrInstGen *ir_analyze_math_op(IrAnalyze *ira, IrInst* source_instr, 16447 ZigType *type_entry, ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val) 16448 { 16449 IrInstGen *result_instruction = ir_const(ira, source_instr, type_entry); 16450 ZigValue *out_val = result_instruction->value; 16451 if (type_entry->id == ZigTypeIdVector) { 16452 expand_undef_array(ira->codegen, op1_val); 16453 expand_undef_array(ira->codegen, op2_val); 16454 out_val->special = ConstValSpecialUndef; 16455 expand_undef_array(ira->codegen, out_val); 16456 size_t len = type_entry->data.vector.len; 16457 ZigType *scalar_type = type_entry->data.vector.elem_type; 16458 for (size_t i = 0; i < len; i += 1) { 16459 ZigValue *scalar_op1_val = &op1_val->data.x_array.data.s_none.elements[i]; 16460 ZigValue *scalar_op2_val = &op2_val->data.x_array.data.s_none.elements[i]; 16461 ZigValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 16462 assert(scalar_op1_val->type == scalar_type); 16463 assert(scalar_op2_val->type == scalar_type); 16464 assert(scalar_out_val->type == scalar_type); 16465 ErrorMsg *msg = ir_eval_math_op_scalar(ira, source_instr, scalar_type, 16466 scalar_op1_val, op_id, scalar_op2_val, scalar_out_val); 16467 if (msg != nullptr) { 16468 add_error_note(ira->codegen, msg, source_instr->source_node, 16469 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 16470 return ira->codegen->invalid_inst_gen; 16471 } 16472 } 16473 out_val->type = type_entry; 16474 out_val->special = ConstValSpecialStatic; 16475 } else { 16476 if (ir_eval_math_op_scalar(ira, source_instr, type_entry, op1_val, op_id, op2_val, out_val) != nullptr) { 16477 return ira->codegen->invalid_inst_gen; 16478 } 16479 } 16480 return ir_implicit_cast(ira, result_instruction, type_entry); 16481 } 16482 16483 static IrInstGen *ir_analyze_bit_shift(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { 16484 IrInstGen *op1 = bin_op_instruction->op1->child; 16485 if (type_is_invalid(op1->value->type)) 16486 return ira->codegen->invalid_inst_gen; 16487 16488 if (op1->value->type->id != ZigTypeIdInt && op1->value->type->id != ZigTypeIdComptimeInt) { 16489 ir_add_error(ira, &bin_op_instruction->op1->base, 16490 buf_sprintf("bit shifting operation expected integer type, found '%s'", 16491 buf_ptr(&op1->value->type->name))); 16492 return ira->codegen->invalid_inst_gen; 16493 } 16494 16495 IrInstGen *op2 = bin_op_instruction->op2->child; 16496 if (type_is_invalid(op2->value->type)) 16497 return ira->codegen->invalid_inst_gen; 16498 16499 if (op2->value->type->id != ZigTypeIdInt && op2->value->type->id != ZigTypeIdComptimeInt) { 16500 ir_add_error(ira, &bin_op_instruction->op2->base, 16501 buf_sprintf("shift amount has to be an integer type, but found '%s'", 16502 buf_ptr(&op2->value->type->name))); 16503 return ira->codegen->invalid_inst_gen; 16504 } 16505 16506 IrInstGen *casted_op2; 16507 IrBinOp op_id = bin_op_instruction->op_id; 16508 if (op1->value->type->id == ZigTypeIdComptimeInt) { 16509 casted_op2 = op2; 16510 16511 if (op_id == IrBinOpBitShiftLeftLossy) { 16512 op_id = IrBinOpBitShiftLeftExact; 16513 } 16514 16515 if (casted_op2->value->data.x_bigint.is_negative) { 16516 Buf *val_buf = buf_alloc(); 16517 bigint_append_buf(val_buf, &casted_op2->value->data.x_bigint, 10); 16518 ir_add_error(ira, &casted_op2->base, buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); 16519 return ira->codegen->invalid_inst_gen; 16520 } 16521 } else { 16522 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 16523 op1->value->type->data.integral.bit_count - 1); 16524 if (bin_op_instruction->op_id == IrBinOpBitShiftLeftLossy && 16525 op2->value->type->id == ZigTypeIdComptimeInt) { 16526 16527 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 16528 if (op2_val == nullptr) 16529 return ira->codegen->invalid_inst_gen; 16530 if (!bigint_fits_in_bits(&op2_val->data.x_bigint, 16531 shift_amt_type->data.integral.bit_count, 16532 op2_val->data.x_bigint.is_negative)) { 16533 Buf *val_buf = buf_alloc(); 16534 bigint_append_buf(val_buf, &op2_val->data.x_bigint, 10); 16535 ErrorMsg* msg = ir_add_error(ira, 16536 &bin_op_instruction->base.base, 16537 buf_sprintf("RHS of shift is too large for LHS type")); 16538 add_error_note( 16539 ira->codegen, 16540 msg, 16541 op2->base.source_node, 16542 buf_sprintf("value %s cannot fit into type %s", 16543 buf_ptr(val_buf), 16544 buf_ptr(&shift_amt_type->name))); 16545 return ira->codegen->invalid_inst_gen; 16546 } 16547 } 16548 16549 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 16550 if (type_is_invalid(casted_op2->value->type)) 16551 return ira->codegen->invalid_inst_gen; 16552 } 16553 16554 if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) { 16555 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 16556 if (op1_val == nullptr) 16557 return ira->codegen->invalid_inst_gen; 16558 16559 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 16560 if (op2_val == nullptr) 16561 return ira->codegen->invalid_inst_gen; 16562 16563 return ir_analyze_math_op(ira, &bin_op_instruction->base.base, op1->value->type, op1_val, op_id, op2_val); 16564 } else if (op1->value->type->id == ZigTypeIdComptimeInt) { 16565 ir_add_error(ira, &bin_op_instruction->base.base, 16566 buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known")); 16567 return ira->codegen->invalid_inst_gen; 16568 } else if (instr_is_comptime(casted_op2) && bigint_cmp_zero(&casted_op2->value->data.x_bigint) == CmpEQ) { 16569 return ir_build_cast(ira, &bin_op_instruction->base.base, op1->value->type, op1, CastOpNoop); 16570 } 16571 16572 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, op1->value->type, 16573 op_id, op1, casted_op2, bin_op_instruction->safety_check_on); 16574 } 16575 16576 static bool ok_float_op(IrBinOp op) { 16577 switch (op) { 16578 case IrBinOpInvalid: 16579 zig_unreachable(); 16580 case IrBinOpAdd: 16581 case IrBinOpSub: 16582 case IrBinOpMult: 16583 case IrBinOpDivUnspecified: 16584 case IrBinOpDivTrunc: 16585 case IrBinOpDivFloor: 16586 case IrBinOpDivExact: 16587 case IrBinOpRemRem: 16588 case IrBinOpRemMod: 16589 return true; 16590 16591 case IrBinOpBoolOr: 16592 case IrBinOpBoolAnd: 16593 case IrBinOpCmpEq: 16594 case IrBinOpCmpNotEq: 16595 case IrBinOpCmpLessThan: 16596 case IrBinOpCmpGreaterThan: 16597 case IrBinOpCmpLessOrEq: 16598 case IrBinOpCmpGreaterOrEq: 16599 case IrBinOpBinOr: 16600 case IrBinOpBinXor: 16601 case IrBinOpBinAnd: 16602 case IrBinOpBitShiftLeftLossy: 16603 case IrBinOpBitShiftLeftExact: 16604 case IrBinOpBitShiftRightLossy: 16605 case IrBinOpBitShiftRightExact: 16606 case IrBinOpAddWrap: 16607 case IrBinOpSubWrap: 16608 case IrBinOpMultWrap: 16609 case IrBinOpRemUnspecified: 16610 case IrBinOpArrayCat: 16611 case IrBinOpArrayMult: 16612 return false; 16613 } 16614 zig_unreachable(); 16615 } 16616 16617 static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) { 16618 switch (op) { 16619 case IrBinOpAdd: 16620 case IrBinOpSub: 16621 break; 16622 default: 16623 return false; 16624 } 16625 if (lhs_type->id != ZigTypeIdPointer) 16626 return false; 16627 switch (lhs_type->data.pointer.ptr_len) { 16628 case PtrLenSingle: 16629 return lhs_type->data.pointer.child_type->id == ZigTypeIdArray; 16630 case PtrLenUnknown: 16631 case PtrLenC: 16632 return true; 16633 } 16634 zig_unreachable(); 16635 } 16636 16637 static IrInstGen *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstSrcBinOp *instruction) { 16638 Error err; 16639 16640 IrInstGen *op1 = instruction->op1->child; 16641 if (type_is_invalid(op1->value->type)) 16642 return ira->codegen->invalid_inst_gen; 16643 16644 IrInstGen *op2 = instruction->op2->child; 16645 if (type_is_invalid(op2->value->type)) 16646 return ira->codegen->invalid_inst_gen; 16647 16648 IrBinOp op_id = instruction->op_id; 16649 16650 // look for pointer math 16651 if (is_pointer_arithmetic_allowed(op1->value->type, op_id)) { 16652 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, ira->codegen->builtin_types.entry_usize); 16653 if (type_is_invalid(casted_op2->value->type)) 16654 return ira->codegen->invalid_inst_gen; 16655 16656 // If either operand is undef, result is undef. 16657 ZigValue *op1_val = nullptr; 16658 ZigValue *op2_val = nullptr; 16659 if (instr_is_comptime(op1)) { 16660 op1_val = ir_resolve_const(ira, op1, UndefOk); 16661 if (op1_val == nullptr) 16662 return ira->codegen->invalid_inst_gen; 16663 if (op1_val->special == ConstValSpecialUndef) 16664 return ir_const_undef(ira, &instruction->base.base, op1->value->type); 16665 } 16666 if (instr_is_comptime(casted_op2)) { 16667 op2_val = ir_resolve_const(ira, casted_op2, UndefOk); 16668 if (op2_val == nullptr) 16669 return ira->codegen->invalid_inst_gen; 16670 if (op2_val->special == ConstValSpecialUndef) 16671 return ir_const_undef(ira, &instruction->base.base, op1->value->type); 16672 } 16673 16674 ZigType *elem_type = op1->value->type->data.pointer.child_type; 16675 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) 16676 return ira->codegen->invalid_inst_gen; 16677 16678 // NOTE: this variable is meaningful iff op2_val is not null! 16679 uint64_t byte_offset; 16680 if (op2_val != nullptr) { 16681 uint64_t elem_offset; 16682 if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) 16683 return ira->codegen->invalid_inst_gen; 16684 16685 byte_offset = type_size(ira->codegen, elem_type) * elem_offset; 16686 } 16687 16688 // Fast path for cases where the RHS is zero 16689 if (op2_val != nullptr && byte_offset == 0) { 16690 return op1; 16691 } 16692 16693 ZigType *result_type = op1->value->type; 16694 // Calculate the new alignment of the pointer 16695 { 16696 uint32_t align_bytes; 16697 if ((err = resolve_ptr_align(ira, op1->value->type, &align_bytes))) 16698 return ira->codegen->invalid_inst_gen; 16699 16700 // If the addend is not a comptime-known value we can still count on 16701 // it being a multiple of the type size 16702 uint32_t addend = op2_val ? byte_offset : type_size(ira->codegen, elem_type); 16703 16704 // The resulting pointer is aligned to the lcd between the 16705 // offset (an arbitrary number) and the alignment factor (always 16706 // a power of two, non zero) 16707 uint32_t new_align = 1 << ctzll(addend | align_bytes); 16708 // Rough guard to prevent overflows 16709 assert(new_align); 16710 result_type = adjust_ptr_align(ira->codegen, result_type, new_align); 16711 } 16712 16713 if (op2_val != nullptr && op1_val != nullptr && 16714 (op1->value->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 16715 op1->value->data.x_ptr.special == ConstPtrSpecialNull)) 16716 { 16717 uint64_t start_addr = (op1_val->data.x_ptr.special == ConstPtrSpecialNull) ? 16718 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr; 16719 uint64_t new_addr; 16720 if (op_id == IrBinOpAdd) { 16721 new_addr = start_addr + byte_offset; 16722 } else if (op_id == IrBinOpSub) { 16723 new_addr = start_addr - byte_offset; 16724 } else { 16725 zig_unreachable(); 16726 } 16727 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 16728 result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 16729 result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; 16730 result->value->data.x_ptr.data.hard_coded_addr.addr = new_addr; 16731 return result; 16732 } 16733 16734 return ir_build_bin_op_gen(ira, &instruction->base.base, result_type, op_id, op1, casted_op2, true); 16735 } 16736 16737 IrInstGen *instructions[] = {op1, op2}; 16738 ZigType *resolved_type = ir_resolve_peer_types(ira, instruction->base.base.source_node, nullptr, instructions, 2); 16739 if (type_is_invalid(resolved_type)) 16740 return ira->codegen->invalid_inst_gen; 16741 16742 bool is_int = resolved_type->id == ZigTypeIdInt || resolved_type->id == ZigTypeIdComptimeInt; 16743 bool is_float = resolved_type->id == ZigTypeIdFloat || resolved_type->id == ZigTypeIdComptimeFloat; 16744 bool is_signed_div = ( 16745 (resolved_type->id == ZigTypeIdInt && resolved_type->data.integral.is_signed) || 16746 resolved_type->id == ZigTypeIdFloat || 16747 (resolved_type->id == ZigTypeIdComptimeFloat && 16748 ((bigfloat_cmp_zero(&op1->value->data.x_bigfloat) != CmpGT) != 16749 (bigfloat_cmp_zero(&op2->value->data.x_bigfloat) != CmpGT))) || 16750 (resolved_type->id == ZigTypeIdComptimeInt && 16751 ((bigint_cmp_zero(&op1->value->data.x_bigint) != CmpGT) != 16752 (bigint_cmp_zero(&op2->value->data.x_bigint) != CmpGT))) 16753 ); 16754 if (op_id == IrBinOpDivUnspecified && is_int) { 16755 if (is_signed_div) { 16756 bool ok = false; 16757 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 16758 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 16759 if (op1_val == nullptr) 16760 return ira->codegen->invalid_inst_gen; 16761 16762 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 16763 if (op2_val == nullptr) 16764 return ira->codegen->invalid_inst_gen; 16765 16766 if (bigint_cmp_zero(&op2_val->data.x_bigint) == CmpEQ) { 16767 // the division by zero error will be caught later, but we don't have a 16768 // division function ambiguity problem. 16769 op_id = IrBinOpDivTrunc; 16770 ok = true; 16771 } else { 16772 BigInt trunc_result; 16773 BigInt floor_result; 16774 bigint_div_trunc(&trunc_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16775 bigint_div_floor(&floor_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16776 if (bigint_cmp(&trunc_result, &floor_result) == CmpEQ) { 16777 ok = true; 16778 op_id = IrBinOpDivTrunc; 16779 } 16780 } 16781 } 16782 if (!ok) { 16783 ir_add_error(ira, &instruction->base.base, 16784 buf_sprintf("division with '%s' and '%s': signed integers must use @divTrunc, @divFloor, or @divExact", 16785 buf_ptr(&op1->value->type->name), 16786 buf_ptr(&op2->value->type->name))); 16787 return ira->codegen->invalid_inst_gen; 16788 } 16789 } else { 16790 op_id = IrBinOpDivTrunc; 16791 } 16792 } else if (op_id == IrBinOpRemUnspecified) { 16793 if (is_signed_div && (is_int || is_float)) { 16794 bool ok = false; 16795 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 16796 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 16797 if (op1_val == nullptr) 16798 return ira->codegen->invalid_inst_gen; 16799 16800 if (is_int) { 16801 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 16802 if (op2_val == nullptr) 16803 return ira->codegen->invalid_inst_gen; 16804 16805 if (bigint_cmp_zero(&op2->value->data.x_bigint) == CmpEQ) { 16806 // the division by zero error will be caught later, but we don't 16807 // have a remainder function ambiguity problem 16808 ok = true; 16809 } else { 16810 BigInt rem_result; 16811 BigInt mod_result; 16812 bigint_rem(&rem_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16813 bigint_mod(&mod_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 16814 ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ; 16815 } 16816 } else { 16817 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 16818 if (type_is_invalid(casted_op2->value->type)) 16819 return ira->codegen->invalid_inst_gen; 16820 16821 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 16822 if (op2_val == nullptr) 16823 return ira->codegen->invalid_inst_gen; 16824 16825 if (float_cmp_zero(casted_op2->value) == CmpEQ) { 16826 // the division by zero error will be caught later, but we don't 16827 // have a remainder function ambiguity problem 16828 ok = true; 16829 } else { 16830 ZigValue rem_result = {}; 16831 ZigValue mod_result = {}; 16832 float_rem(&rem_result, op1_val, op2_val); 16833 float_mod(&mod_result, op1_val, op2_val); 16834 ok = float_cmp(&rem_result, &mod_result) == CmpEQ; 16835 } 16836 } 16837 } 16838 if (!ok) { 16839 ir_add_error(ira, &instruction->base.base, 16840 buf_sprintf("remainder division with '%s' and '%s': signed integers and floats must use @rem or @mod", 16841 buf_ptr(&op1->value->type->name), 16842 buf_ptr(&op2->value->type->name))); 16843 return ira->codegen->invalid_inst_gen; 16844 } 16845 } 16846 op_id = IrBinOpRemRem; 16847 } 16848 16849 bool ok = false; 16850 if (is_int) { 16851 ok = true; 16852 } else if (is_float && ok_float_op(op_id)) { 16853 ok = true; 16854 } else if (resolved_type->id == ZigTypeIdVector) { 16855 ZigType *elem_type = resolved_type->data.vector.elem_type; 16856 if (elem_type->id == ZigTypeIdInt || elem_type->id == ZigTypeIdComptimeInt) { 16857 ok = true; 16858 } else if ((elem_type->id == ZigTypeIdFloat || elem_type->id == ZigTypeIdComptimeFloat) && ok_float_op(op_id)) { 16859 ok = true; 16860 } 16861 } 16862 if (!ok) { 16863 AstNode *source_node = instruction->base.base.source_node; 16864 ir_add_error_node(ira, source_node, 16865 buf_sprintf("invalid operands to binary expression: '%s' and '%s'", 16866 buf_ptr(&op1->value->type->name), 16867 buf_ptr(&op2->value->type->name))); 16868 return ira->codegen->invalid_inst_gen; 16869 } 16870 16871 if (resolved_type->id == ZigTypeIdComptimeInt) { 16872 if (op_id == IrBinOpAddWrap) { 16873 op_id = IrBinOpAdd; 16874 } else if (op_id == IrBinOpSubWrap) { 16875 op_id = IrBinOpSub; 16876 } else if (op_id == IrBinOpMultWrap) { 16877 op_id = IrBinOpMult; 16878 } 16879 } 16880 16881 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 16882 if (type_is_invalid(casted_op1->value->type)) 16883 return ira->codegen->invalid_inst_gen; 16884 16885 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 16886 if (type_is_invalid(casted_op2->value->type)) 16887 return ira->codegen->invalid_inst_gen; 16888 16889 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 16890 ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 16891 if (op1_val == nullptr) 16892 return ira->codegen->invalid_inst_gen; 16893 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 16894 if (op2_val == nullptr) 16895 return ira->codegen->invalid_inst_gen; 16896 16897 return ir_analyze_math_op(ira, &instruction->base.base, resolved_type, op1_val, op_id, op2_val); 16898 } 16899 16900 return ir_build_bin_op_gen(ira, &instruction->base.base, resolved_type, 16901 op_id, casted_op1, casted_op2, instruction->safety_check_on); 16902 } 16903 16904 static IrInstGen *ir_analyze_tuple_cat(IrAnalyze *ira, IrInst* source_instr, 16905 IrInstGen *op1, IrInstGen *op2) 16906 { 16907 Error err; 16908 ZigType *op1_type = op1->value->type; 16909 ZigType *op2_type = op2->value->type; 16910 16911 uint32_t op1_field_count = op1_type->data.structure.src_field_count; 16912 uint32_t op2_field_count = op2_type->data.structure.src_field_count; 16913 16914 Buf *bare_name = buf_alloc(); 16915 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), 16916 source_instr->scope, source_instr->source_node, bare_name); 16917 ZigType *new_type = get_partial_container_type(ira->codegen, source_instr->scope, 16918 ContainerKindStruct, source_instr->source_node, buf_ptr(name), bare_name, ContainerLayoutAuto); 16919 new_type->data.structure.special = StructSpecialInferredTuple; 16920 new_type->data.structure.resolve_status = ResolveStatusBeingInferred; 16921 16922 bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope); 16923 16924 IrInstGen *new_struct_ptr = ir_resolve_result(ira, source_instr, no_result_loc(), 16925 new_type, nullptr, false, true); 16926 uint32_t new_field_count = op1_field_count + op2_field_count; 16927 16928 new_type->data.structure.src_field_count = new_field_count; 16929 new_type->data.structure.fields = realloc_type_struct_fields(new_type->data.structure.fields, 16930 0, new_field_count); 16931 for (uint32_t i = 0; i < new_field_count; i += 1) { 16932 TypeStructField *src_field; 16933 if (i < op1_field_count) { 16934 src_field = op1_type->data.structure.fields[i]; 16935 } else { 16936 src_field = op2_type->data.structure.fields[i - op1_field_count]; 16937 } 16938 TypeStructField *new_field = new_type->data.structure.fields[i]; 16939 new_field->name = buf_sprintf("%" PRIu32, i); 16940 new_field->type_entry = src_field->type_entry; 16941 new_field->type_val = src_field->type_val; 16942 new_field->src_index = i; 16943 new_field->decl_node = src_field->decl_node; 16944 new_field->init_val = src_field->init_val; 16945 new_field->is_comptime = src_field->is_comptime; 16946 } 16947 if ((err = type_resolve(ira->codegen, new_type, ResolveStatusZeroBitsKnown))) 16948 return ira->codegen->invalid_inst_gen; 16949 16950 ZigList<IrInstGen *> const_ptrs = {}; 16951 IrInstGen *first_non_const_instruction = nullptr; 16952 for (uint32_t i = 0; i < new_field_count; i += 1) { 16953 TypeStructField *dst_field = new_type->data.structure.fields[i]; 16954 IrInstGen *src_struct_op; 16955 TypeStructField *src_field; 16956 if (i < op1_field_count) { 16957 src_field = op1_type->data.structure.fields[i]; 16958 src_struct_op = op1; 16959 } else { 16960 src_field = op2_type->data.structure.fields[i - op1_field_count]; 16961 src_struct_op = op2; 16962 } 16963 IrInstGen *field_value = ir_analyze_struct_value_field_value(ira, source_instr, 16964 src_struct_op, src_field); 16965 if (type_is_invalid(field_value->value->type)) 16966 return ira->codegen->invalid_inst_gen; 16967 IrInstGen *dest_ptr = ir_analyze_struct_field_ptr(ira, source_instr, dst_field, 16968 new_struct_ptr, new_type, true); 16969 if (type_is_invalid(dest_ptr->value->type)) 16970 return ira->codegen->invalid_inst_gen; 16971 if (instr_is_comptime(field_value)) { 16972 const_ptrs.append(dest_ptr); 16973 } else { 16974 first_non_const_instruction = field_value; 16975 } 16976 IrInstGen *store_ptr_inst = ir_analyze_store_ptr(ira, source_instr, dest_ptr, field_value, 16977 true); 16978 if (type_is_invalid(store_ptr_inst->value->type)) 16979 return ira->codegen->invalid_inst_gen; 16980 } 16981 if (const_ptrs.length != new_field_count) { 16982 new_struct_ptr->value->special = ConstValSpecialRuntime; 16983 for (size_t i = 0; i < const_ptrs.length; i += 1) { 16984 IrInstGen *elem_result_loc = const_ptrs.at(i); 16985 assert(elem_result_loc->value->special == ConstValSpecialStatic); 16986 if (elem_result_loc->value->type->data.pointer.inferred_struct_field != nullptr) { 16987 // This field will be generated comptime; no need to do this. 16988 continue; 16989 } 16990 IrInstGen *deref = ir_get_deref(ira, &elem_result_loc->base, elem_result_loc, nullptr); 16991 elem_result_loc->value->special = ConstValSpecialRuntime; 16992 ir_analyze_store_ptr(ira, &elem_result_loc->base, elem_result_loc, deref, false); 16993 } 16994 } 16995 IrInstGen *result = ir_get_deref(ira, source_instr, new_struct_ptr, nullptr); 16996 if (instr_is_comptime(result)) 16997 return result; 16998 16999 if (is_comptime) { 17000 ir_add_error(ira, &first_non_const_instruction->base, 17001 buf_sprintf("unable to evaluate constant expression")); 17002 return ira->codegen->invalid_inst_gen; 17003 } 17004 17005 return result; 17006 } 17007 17008 static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instruction) { 17009 IrInstGen *op1 = instruction->op1->child; 17010 ZigType *op1_type = op1->value->type; 17011 if (type_is_invalid(op1_type)) 17012 return ira->codegen->invalid_inst_gen; 17013 17014 IrInstGen *op2 = instruction->op2->child; 17015 ZigType *op2_type = op2->value->type; 17016 if (type_is_invalid(op2_type)) 17017 return ira->codegen->invalid_inst_gen; 17018 17019 if (is_tuple(op1_type) && is_tuple(op2_type)) { 17020 return ir_analyze_tuple_cat(ira, &instruction->base.base, op1, op2); 17021 } 17022 17023 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 17024 if (!op1_val) 17025 return ira->codegen->invalid_inst_gen; 17026 17027 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 17028 if (!op2_val) 17029 return ira->codegen->invalid_inst_gen; 17030 17031 ZigValue *sentinel1 = nullptr; 17032 ZigValue *op1_array_val; 17033 size_t op1_array_index; 17034 size_t op1_array_end; 17035 ZigType *child_type; 17036 if (op1_type->id == ZigTypeIdArray) { 17037 child_type = op1_type->data.array.child_type; 17038 op1_array_val = op1_val; 17039 op1_array_index = 0; 17040 op1_array_end = op1_type->data.array.len; 17041 sentinel1 = op1_type->data.array.sentinel; 17042 } else if (op1_type->id == ZigTypeIdPointer && 17043 op1_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && 17044 op1_type->data.pointer.sentinel != nullptr && 17045 op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray) 17046 { 17047 child_type = op1_type->data.pointer.child_type; 17048 op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; 17049 op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; 17050 op1_array_end = op1_array_val->type->data.array.len; 17051 sentinel1 = op1_type->data.pointer.sentinel; 17052 } else if (is_slice(op1_type)) { 17053 ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index]->type_entry; 17054 child_type = ptr_type->data.pointer.child_type; 17055 ZigValue *ptr_val = op1_val->data.x_struct.fields[slice_ptr_index]; 17056 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 17057 op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 17058 op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 17059 ZigValue *len_val = op1_val->data.x_struct.fields[slice_len_index]; 17060 op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint); 17061 sentinel1 = ptr_type->data.pointer.sentinel; 17062 } else if (op1_type->id == ZigTypeIdPointer && op1_type->data.pointer.ptr_len == PtrLenSingle && 17063 op1_type->data.pointer.child_type->id == ZigTypeIdArray) 17064 { 17065 ZigType *array_type = op1_type->data.pointer.child_type; 17066 child_type = array_type->data.array.child_type; 17067 op1_array_val = const_ptr_pointee(ira, ira->codegen, op1_val, op1->base.source_node); 17068 if (op1_array_val == nullptr) 17069 return ira->codegen->invalid_inst_gen; 17070 op1_array_index = 0; 17071 op1_array_end = array_type->data.array.len; 17072 sentinel1 = array_type->data.array.sentinel; 17073 } else { 17074 ir_add_error(ira, &op1->base, buf_sprintf("expected array, found '%s'", buf_ptr(&op1->value->type->name))); 17075 return ira->codegen->invalid_inst_gen; 17076 } 17077 17078 ZigValue *sentinel2 = nullptr; 17079 ZigValue *op2_array_val; 17080 size_t op2_array_index; 17081 size_t op2_array_end; 17082 bool op2_type_valid; 17083 if (op2_type->id == ZigTypeIdArray) { 17084 op2_type_valid = op2_type->data.array.child_type == child_type; 17085 op2_array_val = op2_val; 17086 op2_array_index = 0; 17087 op2_array_end = op2_array_val->type->data.array.len; 17088 sentinel2 = op2_type->data.array.sentinel; 17089 } else if (op2_type->id == ZigTypeIdPointer && 17090 op2_type->data.pointer.sentinel != nullptr && 17091 op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray) 17092 { 17093 op2_type_valid = op2_type->data.pointer.child_type == child_type; 17094 op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; 17095 op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; 17096 op2_array_end = op2_array_val->type->data.array.len; 17097 17098 sentinel2 = op2_type->data.pointer.sentinel; 17099 } else if (is_slice(op2_type)) { 17100 ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index]->type_entry; 17101 op2_type_valid = ptr_type->data.pointer.child_type == child_type; 17102 ZigValue *ptr_val = op2_val->data.x_struct.fields[slice_ptr_index]; 17103 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 17104 op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 17105 op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 17106 ZigValue *len_val = op2_val->data.x_struct.fields[slice_len_index]; 17107 op2_array_end = op2_array_index + bigint_as_usize(&len_val->data.x_bigint); 17108 17109 sentinel2 = ptr_type->data.pointer.sentinel; 17110 } else if (op2_type->id == ZigTypeIdPointer && op2_type->data.pointer.ptr_len == PtrLenSingle && 17111 op2_type->data.pointer.child_type->id == ZigTypeIdArray) 17112 { 17113 ZigType *array_type = op2_type->data.pointer.child_type; 17114 op2_type_valid = array_type->data.array.child_type == child_type; 17115 op2_array_val = const_ptr_pointee(ira, ira->codegen, op2_val, op2->base.source_node); 17116 if (op2_array_val == nullptr) 17117 return ira->codegen->invalid_inst_gen; 17118 op2_array_index = 0; 17119 op2_array_end = array_type->data.array.len; 17120 17121 sentinel2 = array_type->data.array.sentinel; 17122 } else { 17123 ir_add_error(ira, &op2->base, 17124 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value->type->name))); 17125 return ira->codegen->invalid_inst_gen; 17126 } 17127 if (!op2_type_valid) { 17128 ir_add_error(ira, &op2->base, buf_sprintf("expected array of type '%s', found '%s'", 17129 buf_ptr(&child_type->name), 17130 buf_ptr(&op2->value->type->name))); 17131 return ira->codegen->invalid_inst_gen; 17132 } 17133 17134 ZigValue *sentinel; 17135 if (sentinel1 != nullptr && sentinel2 != nullptr) { 17136 // When there is a sentinel mismatch, no sentinel on the result. The type system 17137 // will catch this if it is a problem. 17138 sentinel = const_values_equal(ira->codegen, sentinel1, sentinel2) ? sentinel1 : nullptr; 17139 } else if (sentinel1 != nullptr) { 17140 sentinel = sentinel1; 17141 } else if (sentinel2 != nullptr) { 17142 sentinel = sentinel2; 17143 } else { 17144 sentinel = nullptr; 17145 } 17146 17147 // The type of result is populated in the following if blocks 17148 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 17149 ZigValue *out_val = result->value; 17150 17151 ZigValue *out_array_val; 17152 size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); 17153 if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) { 17154 out_array_val = ira->codegen->pass1_arena->create<ZigValue>(); 17155 out_array_val->special = ConstValSpecialStatic; 17156 out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 17157 17158 out_val->data.x_ptr.special = ConstPtrSpecialRef; 17159 out_val->data.x_ptr.data.ref.pointee = out_array_val; 17160 out_val->type = get_pointer_to_type(ira->codegen, out_array_val->type, true); 17161 } else if (is_slice(op1_type) || is_slice(op2_type)) { 17162 ZigType *ptr_type = get_pointer_to_type_extra2(ira->codegen, child_type, 17163 true, false, PtrLenUnknown, 0, 0, 0, false, 17164 VECTOR_INDEX_NONE, nullptr, sentinel); 17165 result->value->type = get_slice_type(ira->codegen, ptr_type); 17166 out_array_val = ira->codegen->pass1_arena->create<ZigValue>(); 17167 out_array_val->special = ConstValSpecialStatic; 17168 out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 17169 17170 out_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, 2); 17171 17172 out_val->data.x_struct.fields[slice_ptr_index]->type = ptr_type; 17173 out_val->data.x_struct.fields[slice_ptr_index]->special = ConstValSpecialStatic; 17174 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.special = ConstPtrSpecialBaseArray; 17175 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.array_val = out_array_val; 17176 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.elem_index = 0; 17177 17178 out_val->data.x_struct.fields[slice_len_index]->type = ira->codegen->builtin_types.entry_usize; 17179 out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic; 17180 bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len); 17181 } else if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { 17182 result->value->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 17183 out_array_val = out_val; 17184 } else { 17185 result->value->type = get_pointer_to_type_extra2(ira->codegen, child_type, true, false, PtrLenUnknown, 17186 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr, sentinel); 17187 out_array_val = ira->codegen->pass1_arena->create<ZigValue>(); 17188 out_array_val->special = ConstValSpecialStatic; 17189 out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 17190 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 17191 out_val->data.x_ptr.data.base_array.array_val = out_array_val; 17192 out_val->data.x_ptr.data.base_array.elem_index = 0; 17193 } 17194 17195 if (op1_array_val->data.x_array.special == ConstArraySpecialUndef && 17196 op2_array_val->data.x_array.special == ConstArraySpecialUndef) 17197 { 17198 out_array_val->data.x_array.special = ConstArraySpecialUndef; 17199 return result; 17200 } 17201 17202 uint64_t full_len = new_len + ((sentinel != nullptr) ? 1 : 0); 17203 out_array_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(full_len); 17204 // TODO handle the buf case here for an optimization 17205 expand_undef_array(ira->codegen, op1_array_val); 17206 expand_undef_array(ira->codegen, op2_array_val); 17207 17208 size_t next_index = 0; 17209 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { 17210 ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; 17211 copy_const_val(ira->codegen, elem_dest_val, &op1_array_val->data.x_array.data.s_none.elements[i]); 17212 elem_dest_val->parent.id = ConstParentIdArray; 17213 elem_dest_val->parent.data.p_array.array_val = out_array_val; 17214 elem_dest_val->parent.data.p_array.elem_index = next_index; 17215 } 17216 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { 17217 ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; 17218 copy_const_val(ira->codegen, elem_dest_val, &op2_array_val->data.x_array.data.s_none.elements[i]); 17219 elem_dest_val->parent.id = ConstParentIdArray; 17220 elem_dest_val->parent.data.p_array.array_val = out_array_val; 17221 elem_dest_val->parent.data.p_array.elem_index = next_index; 17222 } 17223 if (next_index < full_len) { 17224 ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; 17225 copy_const_val(ira->codegen, elem_dest_val, sentinel); 17226 elem_dest_val->parent.id = ConstParentIdArray; 17227 elem_dest_val->parent.data.p_array.array_val = out_array_val; 17228 elem_dest_val->parent.data.p_array.elem_index = next_index; 17229 next_index += 1; 17230 } 17231 assert(next_index == full_len); 17232 17233 return result; 17234 } 17235 17236 static IrInstGen *ir_analyze_array_mult(IrAnalyze *ira, IrInstSrcBinOp *instruction) { 17237 IrInstGen *op1 = instruction->op1->child; 17238 if (type_is_invalid(op1->value->type)) 17239 return ira->codegen->invalid_inst_gen; 17240 17241 IrInstGen *op2 = instruction->op2->child; 17242 if (type_is_invalid(op2->value->type)) 17243 return ira->codegen->invalid_inst_gen; 17244 17245 bool want_ptr_to_array = false; 17246 ZigType *array_type; 17247 ZigValue *array_val; 17248 if (op1->value->type->id == ZigTypeIdArray) { 17249 array_type = op1->value->type; 17250 array_val = ir_resolve_const(ira, op1, UndefOk); 17251 if (array_val == nullptr) 17252 return ira->codegen->invalid_inst_gen; 17253 } else if (op1->value->type->id == ZigTypeIdPointer && op1->value->type->data.pointer.ptr_len == PtrLenSingle && 17254 op1->value->type->data.pointer.child_type->id == ZigTypeIdArray) 17255 { 17256 array_type = op1->value->type->data.pointer.child_type; 17257 IrInstGen *array_inst = ir_get_deref(ira, &op1->base, op1, nullptr); 17258 if (type_is_invalid(array_inst->value->type)) 17259 return ira->codegen->invalid_inst_gen; 17260 array_val = ir_resolve_const(ira, array_inst, UndefOk); 17261 if (array_val == nullptr) 17262 return ira->codegen->invalid_inst_gen; 17263 want_ptr_to_array = true; 17264 } else { 17265 ir_add_error(ira, &op1->base, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value->type->name))); 17266 return ira->codegen->invalid_inst_gen; 17267 } 17268 17269 uint64_t mult_amt; 17270 if (!ir_resolve_usize(ira, op2, &mult_amt)) 17271 return ira->codegen->invalid_inst_gen; 17272 17273 uint64_t old_array_len = array_type->data.array.len; 17274 uint64_t new_array_len; 17275 17276 if (mul_u64_overflow(old_array_len, mult_amt, &new_array_len)) { 17277 ir_add_error(ira, &instruction->base.base, buf_sprintf("operation results in overflow")); 17278 return ira->codegen->invalid_inst_gen; 17279 } 17280 17281 ZigType *child_type = array_type->data.array.child_type; 17282 ZigType *result_array_type = get_array_type(ira->codegen, child_type, new_array_len, 17283 array_type->data.array.sentinel); 17284 17285 IrInstGen *array_result; 17286 if (array_val->special == ConstValSpecialUndef || array_val->data.x_array.special == ConstArraySpecialUndef) { 17287 array_result = ir_const_undef(ira, &instruction->base.base, result_array_type); 17288 } else { 17289 array_result = ir_const(ira, &instruction->base.base, result_array_type); 17290 ZigValue *out_val = array_result->value; 17291 17292 switch (type_has_one_possible_value(ira->codegen, result_array_type)) { 17293 case OnePossibleValueInvalid: 17294 return ira->codegen->invalid_inst_gen; 17295 case OnePossibleValueYes: 17296 goto skip_computation; 17297 case OnePossibleValueNo: 17298 break; 17299 } 17300 17301 // TODO optimize the buf case 17302 expand_undef_array(ira->codegen, array_val); 17303 size_t extra_null_term = (array_type->data.array.sentinel != nullptr) ? 1 : 0; 17304 out_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(new_array_len + extra_null_term); 17305 17306 uint64_t i = 0; 17307 for (uint64_t x = 0; x < mult_amt; x += 1) { 17308 for (uint64_t y = 0; y < old_array_len; y += 1) { 17309 ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; 17310 copy_const_val(ira->codegen, elem_dest_val, &array_val->data.x_array.data.s_none.elements[y]); 17311 elem_dest_val->parent.id = ConstParentIdArray; 17312 elem_dest_val->parent.data.p_array.array_val = out_val; 17313 elem_dest_val->parent.data.p_array.elem_index = i; 17314 i += 1; 17315 } 17316 } 17317 assert(i == new_array_len); 17318 17319 if (array_type->data.array.sentinel != nullptr) { 17320 ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; 17321 copy_const_val(ira->codegen, elem_dest_val, array_type->data.array.sentinel); 17322 elem_dest_val->parent.id = ConstParentIdArray; 17323 elem_dest_val->parent.data.p_array.array_val = out_val; 17324 elem_dest_val->parent.data.p_array.elem_index = i; 17325 i += 1; 17326 } 17327 } 17328 skip_computation: 17329 if (want_ptr_to_array) { 17330 return ir_get_ref(ira, &instruction->base.base, array_result, true, false); 17331 } else { 17332 return array_result; 17333 } 17334 } 17335 17336 static IrInstGen *ir_analyze_instruction_merge_err_sets(IrAnalyze *ira, 17337 IrInstSrcMergeErrSets *instruction) 17338 { 17339 ZigType *op1_type = ir_resolve_error_set_type(ira, &instruction->base.base, instruction->op1->child); 17340 if (type_is_invalid(op1_type)) 17341 return ira->codegen->invalid_inst_gen; 17342 17343 ZigType *op2_type = ir_resolve_error_set_type(ira, &instruction->base.base, instruction->op2->child); 17344 if (type_is_invalid(op2_type)) 17345 return ira->codegen->invalid_inst_gen; 17346 17347 if (type_is_global_error_set(op1_type) || 17348 type_is_global_error_set(op2_type)) 17349 { 17350 return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_global_error_set); 17351 } 17352 17353 if (!resolve_inferred_error_set(ira->codegen, op1_type, instruction->op1->child->base.source_node)) { 17354 return ira->codegen->invalid_inst_gen; 17355 } 17356 17357 if (!resolve_inferred_error_set(ira->codegen, op2_type, instruction->op2->child->base.source_node)) { 17358 return ira->codegen->invalid_inst_gen; 17359 } 17360 17361 size_t errors_count = ira->codegen->errors_by_index.length; 17362 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count); 17363 for (uint32_t i = 0, count = op1_type->data.error_set.err_count; i < count; i += 1) { 17364 ErrorTableEntry *error_entry = op1_type->data.error_set.errors[i]; 17365 assert(errors[error_entry->value] == nullptr); 17366 errors[error_entry->value] = error_entry; 17367 } 17368 ZigType *result_type = get_error_set_union(ira->codegen, errors, op1_type, op2_type, instruction->type_name); 17369 heap::c_allocator.deallocate(errors, errors_count); 17370 17371 return ir_const_type(ira, &instruction->base.base, result_type); 17372 } 17373 17374 17375 static IrInstGen *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { 17376 IrBinOp op_id = bin_op_instruction->op_id; 17377 switch (op_id) { 17378 case IrBinOpInvalid: 17379 zig_unreachable(); 17380 case IrBinOpBoolOr: 17381 case IrBinOpBoolAnd: 17382 return ir_analyze_bin_op_bool(ira, bin_op_instruction); 17383 case IrBinOpCmpEq: 17384 case IrBinOpCmpNotEq: 17385 case IrBinOpCmpLessThan: 17386 case IrBinOpCmpGreaterThan: 17387 case IrBinOpCmpLessOrEq: 17388 case IrBinOpCmpGreaterOrEq: 17389 return ir_analyze_bin_op_cmp(ira, bin_op_instruction); 17390 case IrBinOpBitShiftLeftLossy: 17391 case IrBinOpBitShiftLeftExact: 17392 case IrBinOpBitShiftRightLossy: 17393 case IrBinOpBitShiftRightExact: 17394 return ir_analyze_bit_shift(ira, bin_op_instruction); 17395 case IrBinOpBinOr: 17396 case IrBinOpBinXor: 17397 case IrBinOpBinAnd: 17398 case IrBinOpAdd: 17399 case IrBinOpAddWrap: 17400 case IrBinOpSub: 17401 case IrBinOpSubWrap: 17402 case IrBinOpMult: 17403 case IrBinOpMultWrap: 17404 case IrBinOpDivUnspecified: 17405 case IrBinOpDivTrunc: 17406 case IrBinOpDivFloor: 17407 case IrBinOpDivExact: 17408 case IrBinOpRemUnspecified: 17409 case IrBinOpRemRem: 17410 case IrBinOpRemMod: 17411 return ir_analyze_bin_op_math(ira, bin_op_instruction); 17412 case IrBinOpArrayCat: 17413 return ir_analyze_array_cat(ira, bin_op_instruction); 17414 case IrBinOpArrayMult: 17415 return ir_analyze_array_mult(ira, bin_op_instruction); 17416 } 17417 zig_unreachable(); 17418 } 17419 17420 static IrInstGen *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstSrcDeclVar *decl_var_instruction) { 17421 Error err; 17422 ZigVar *var = decl_var_instruction->var; 17423 17424 ZigType *explicit_type = nullptr; 17425 IrInstGen *var_type = nullptr; 17426 if (decl_var_instruction->var_type != nullptr) { 17427 var_type = decl_var_instruction->var_type->child; 17428 ZigType *proposed_type = ir_resolve_type(ira, var_type); 17429 explicit_type = validate_var_type(ira->codegen, var_type->base.source_node, proposed_type); 17430 if (type_is_invalid(explicit_type)) { 17431 var->var_type = ira->codegen->builtin_types.entry_invalid; 17432 return ira->codegen->invalid_inst_gen; 17433 } 17434 } 17435 17436 AstNode *source_node = decl_var_instruction->base.base.source_node; 17437 17438 bool is_comptime_var = ir_get_var_is_comptime(var); 17439 17440 bool var_class_requires_const = false; 17441 17442 IrInstGen *var_ptr = decl_var_instruction->ptr->child; 17443 // if this is null, a compiler error happened and did not initialize the variable. 17444 // if there are no compile errors there may be a missing ir_expr_wrap in pass1 IR generation. 17445 if (var_ptr == nullptr || type_is_invalid(var_ptr->value->type)) { 17446 ir_assert(var_ptr != nullptr || ira->codegen->errors.length != 0, &decl_var_instruction->base.base); 17447 var->var_type = ira->codegen->builtin_types.entry_invalid; 17448 return ira->codegen->invalid_inst_gen; 17449 } 17450 17451 // The ir_build_var_decl_src call is supposed to pass a pointer to the allocation, not an initialization value. 17452 ir_assert(var_ptr->value->type->id == ZigTypeIdPointer, &decl_var_instruction->base.base); 17453 17454 ZigType *result_type = var_ptr->value->type->data.pointer.child_type; 17455 if (type_is_invalid(result_type)) { 17456 result_type = ira->codegen->builtin_types.entry_invalid; 17457 } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) { 17458 zig_unreachable(); 17459 } 17460 17461 ZigValue *init_val = nullptr; 17462 if (instr_is_comptime(var_ptr) && var_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 17463 init_val = const_ptr_pointee(ira, ira->codegen, var_ptr->value, decl_var_instruction->base.base.source_node); 17464 if (is_comptime_var) { 17465 if (var->gen_is_const) { 17466 var->const_value = init_val; 17467 } else { 17468 var->const_value = ira->codegen->pass1_arena->create<ZigValue>(); 17469 copy_const_val(ira->codegen, var->const_value, init_val); 17470 } 17471 } 17472 } 17473 17474 switch (type_requires_comptime(ira->codegen, result_type)) { 17475 case ReqCompTimeInvalid: 17476 result_type = ira->codegen->builtin_types.entry_invalid; 17477 break; 17478 case ReqCompTimeYes: 17479 var_class_requires_const = true; 17480 if (!var->gen_is_const && !is_comptime_var) { 17481 ir_add_error_node(ira, source_node, 17482 buf_sprintf("variable of type '%s' must be const or comptime", 17483 buf_ptr(&result_type->name))); 17484 result_type = ira->codegen->builtin_types.entry_invalid; 17485 } 17486 break; 17487 case ReqCompTimeNo: 17488 if (init_val != nullptr && value_is_comptime(init_val)) { 17489 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 17490 decl_var_instruction->base.base.source_node, init_val, UndefOk))) 17491 { 17492 result_type = ira->codegen->builtin_types.entry_invalid; 17493 } else if (init_val->type->id == ZigTypeIdFn && 17494 init_val->special != ConstValSpecialUndef && 17495 init_val->data.x_ptr.special == ConstPtrSpecialFunction && 17496 init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) 17497 { 17498 var_class_requires_const = true; 17499 if (!var->src_is_const && !is_comptime_var) { 17500 ErrorMsg *msg = ir_add_error_node(ira, source_node, 17501 buf_sprintf("functions marked inline must be stored in const or comptime var")); 17502 AstNode *proto_node = init_val->data.x_ptr.data.fn.fn_entry->proto_node; 17503 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); 17504 result_type = ira->codegen->builtin_types.entry_invalid; 17505 } 17506 } 17507 } 17508 break; 17509 } 17510 17511 while (var->next_var != nullptr) { 17512 var = var->next_var; 17513 } 17514 17515 // This must be done after possibly creating a new variable above 17516 var->ref_count = 0; 17517 17518 var->ptr_instruction = var_ptr; 17519 var->var_type = result_type; 17520 assert(var->var_type); 17521 17522 if (type_is_invalid(result_type)) { 17523 return ir_const_void(ira, &decl_var_instruction->base.base); 17524 } 17525 17526 if (decl_var_instruction->align_value == nullptr) { 17527 if ((err = type_resolve(ira->codegen, result_type, ResolveStatusAlignmentKnown))) { 17528 var->var_type = ira->codegen->builtin_types.entry_invalid; 17529 return ir_const_void(ira, &decl_var_instruction->base.base); 17530 } 17531 var->align_bytes = get_ptr_align(ira->codegen, var_ptr->value->type); 17532 } else { 17533 if (!ir_resolve_align(ira, decl_var_instruction->align_value->child, nullptr, &var->align_bytes)) { 17534 var->var_type = ira->codegen->builtin_types.entry_invalid; 17535 } 17536 } 17537 17538 if (init_val != nullptr && value_is_comptime(init_val)) { 17539 // Resolve ConstPtrMutInfer 17540 if (var->gen_is_const) { 17541 var_ptr->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 17542 } else if (is_comptime_var) { 17543 var_ptr->value->data.x_ptr.mut = ConstPtrMutComptimeVar; 17544 } else { 17545 // we need a runtime ptr but we have a comptime val. 17546 // since it's a comptime val there are no instructions for it. 17547 // we memcpy the init value here 17548 IrInstGen *deref = ir_get_deref(ira, &var_ptr->base, var_ptr, nullptr); 17549 if (type_is_invalid(deref->value->type)) { 17550 var->var_type = ira->codegen->builtin_types.entry_invalid; 17551 return ira->codegen->invalid_inst_gen; 17552 } 17553 // If this assertion trips, something is wrong with the IR instructions, because 17554 // we expected the above deref to return a constant value, but it created a runtime 17555 // instruction. 17556 assert(deref->value->special != ConstValSpecialRuntime); 17557 var_ptr->value->special = ConstValSpecialRuntime; 17558 ir_analyze_store_ptr(ira, &var_ptr->base, var_ptr, deref, false); 17559 } 17560 if (instr_is_comptime(var_ptr) && (is_comptime_var || (var_class_requires_const && var->gen_is_const))) { 17561 return ir_const_void(ira, &decl_var_instruction->base.base); 17562 } 17563 } else if (is_comptime_var) { 17564 ir_add_error(ira, &decl_var_instruction->base.base, 17565 buf_sprintf("cannot store runtime value in compile time variable")); 17566 var->var_type = ira->codegen->builtin_types.entry_invalid; 17567 return ira->codegen->invalid_inst_gen; 17568 } 17569 17570 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 17571 if (fn_entry) 17572 fn_entry->variable_list.append(var); 17573 17574 return ir_build_var_decl_gen(ira, &decl_var_instruction->base.base, var, var_ptr); 17575 } 17576 17577 static IrInstGen *ir_analyze_instruction_export(IrAnalyze *ira, IrInstSrcExport *instruction) { 17578 IrInstGen *target = instruction->target->child; 17579 if (type_is_invalid(target->value->type)) 17580 return ira->codegen->invalid_inst_gen; 17581 17582 IrInstGen *options = instruction->options->child; 17583 if (type_is_invalid(options->value->type)) 17584 return ira->codegen->invalid_inst_gen; 17585 17586 ZigType *options_type = options->value->type; 17587 assert(options_type->id == ZigTypeIdStruct); 17588 17589 TypeStructField *name_field = find_struct_type_field(options_type, buf_create_from_str("name")); 17590 ir_assert(name_field != nullptr, &instruction->base.base); 17591 IrInstGen *name_inst = ir_analyze_struct_value_field_value(ira, &instruction->base.base, options, name_field); 17592 if (type_is_invalid(name_inst->value->type)) 17593 return ira->codegen->invalid_inst_gen; 17594 17595 TypeStructField *linkage_field = find_struct_type_field(options_type, buf_create_from_str("linkage")); 17596 ir_assert(linkage_field != nullptr, &instruction->base.base); 17597 IrInstGen *linkage_inst = ir_analyze_struct_value_field_value(ira, &instruction->base.base, options, linkage_field); 17598 if (type_is_invalid(linkage_inst->value->type)) 17599 return ira->codegen->invalid_inst_gen; 17600 17601 TypeStructField *section_field = find_struct_type_field(options_type, buf_create_from_str("section")); 17602 ir_assert(section_field != nullptr, &instruction->base.base); 17603 IrInstGen *section_inst = ir_analyze_struct_value_field_value(ira, &instruction->base.base, options, section_field); 17604 if (type_is_invalid(section_inst->value->type)) 17605 return ira->codegen->invalid_inst_gen; 17606 17607 // The `section` field is optional, we have to unwrap it first 17608 IrInstGen *non_null_check = ir_analyze_test_non_null(ira, &instruction->base.base, section_inst); 17609 bool is_non_null; 17610 if (!ir_resolve_bool(ira, non_null_check, &is_non_null)) 17611 return ira->codegen->invalid_inst_gen; 17612 17613 IrInstGen *section_str_inst = nullptr; 17614 if (is_non_null) { 17615 section_str_inst = ir_analyze_optional_value_payload_value(ira, &instruction->base.base, section_inst, false); 17616 if (type_is_invalid(section_str_inst->value->type)) 17617 return ira->codegen->invalid_inst_gen; 17618 } 17619 17620 // Resolve all the comptime values 17621 Buf *symbol_name = ir_resolve_str(ira, name_inst); 17622 if (!symbol_name) 17623 return ira->codegen->invalid_inst_gen; 17624 17625 if (buf_len(symbol_name) < 1) { 17626 ir_add_error(ira, &name_inst->base, 17627 buf_sprintf("exported symbol name cannot be empty")); 17628 return ira->codegen->invalid_inst_gen; 17629 } 17630 17631 GlobalLinkageId global_linkage_id; 17632 if (!ir_resolve_global_linkage(ira, linkage_inst, &global_linkage_id)) 17633 return ira->codegen->invalid_inst_gen; 17634 17635 Buf *section_name = nullptr; 17636 if (section_str_inst != nullptr && !(section_name = ir_resolve_str(ira, section_str_inst))) 17637 return ira->codegen->invalid_inst_gen; 17638 17639 // TODO: This function needs to be audited. 17640 // It's not clear how all the different types are supposed to be handled. 17641 // Need comprehensive tests for exporting one thing in one file and declaring an extern var 17642 // in another file. 17643 TldFn *tld_fn = heap::c_allocator.create<TldFn>(); 17644 tld_fn->base.id = TldIdFn; 17645 tld_fn->base.source_node = instruction->base.base.source_node; 17646 17647 auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, &tld_fn->base); 17648 if (entry) { 17649 AstNode *other_export_node = entry->value->source_node; 17650 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 17651 buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name))); 17652 add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here")); 17653 return ira->codegen->invalid_inst_gen; 17654 } 17655 17656 Error err; 17657 bool want_var_export = false; 17658 switch (target->value->type->id) { 17659 case ZigTypeIdInvalid: 17660 case ZigTypeIdUnreachable: 17661 zig_unreachable(); 17662 case ZigTypeIdFn: { 17663 assert(target->value->data.x_ptr.special == ConstPtrSpecialFunction); 17664 ZigFn *fn_entry = target->value->data.x_ptr.data.fn.fn_entry; 17665 tld_fn->fn_entry = fn_entry; 17666 CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc; 17667 switch (cc) { 17668 case CallingConventionUnspecified: { 17669 ErrorMsg *msg = ir_add_error(ira, &target->base, 17670 buf_sprintf("exported function must specify calling convention")); 17671 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 17672 } break; 17673 case CallingConventionAsync: { 17674 ErrorMsg *msg = ir_add_error(ira, &target->base, 17675 buf_sprintf("exported function cannot be async")); 17676 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 17677 } break; 17678 case CallingConventionC: 17679 case CallingConventionCold: 17680 case CallingConventionNaked: 17681 case CallingConventionInterrupt: 17682 case CallingConventionSignal: 17683 case CallingConventionStdcall: 17684 case CallingConventionFastcall: 17685 case CallingConventionVectorcall: 17686 case CallingConventionThiscall: 17687 case CallingConventionAPCS: 17688 case CallingConventionAAPCS: 17689 case CallingConventionAAPCSVFP: 17690 add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc); 17691 fn_entry->section_name = section_name; 17692 break; 17693 } 17694 } break; 17695 case ZigTypeIdStruct: 17696 if (is_slice(target->value->type)) { 17697 ir_add_error(ira, &target->base, 17698 buf_sprintf("unable to export value of type '%s'", buf_ptr(&target->value->type->name))); 17699 } else if (target->value->type->data.structure.layout != ContainerLayoutExtern) { 17700 ErrorMsg *msg = ir_add_error(ira, &target->base, 17701 buf_sprintf("exported struct value must be declared extern")); 17702 add_error_note(ira->codegen, msg, target->value->type->data.structure.decl_node, buf_sprintf("declared here")); 17703 } else { 17704 want_var_export = true; 17705 } 17706 break; 17707 case ZigTypeIdUnion: 17708 if (target->value->type->data.unionation.layout != ContainerLayoutExtern) { 17709 ErrorMsg *msg = ir_add_error(ira, &target->base, 17710 buf_sprintf("exported union value must be declared extern")); 17711 add_error_note(ira->codegen, msg, target->value->type->data.unionation.decl_node, buf_sprintf("declared here")); 17712 } else { 17713 want_var_export = true; 17714 } 17715 break; 17716 case ZigTypeIdEnum: 17717 if (target->value->type->data.enumeration.layout != ContainerLayoutExtern) { 17718 ErrorMsg *msg = ir_add_error(ira, &target->base, 17719 buf_sprintf("exported enum value must be declared extern")); 17720 add_error_note(ira->codegen, msg, target->value->type->data.enumeration.decl_node, buf_sprintf("declared here")); 17721 } else { 17722 want_var_export = true; 17723 } 17724 break; 17725 case ZigTypeIdArray: { 17726 bool ok_type; 17727 if ((err = type_allowed_in_extern(ira->codegen, target->value->type->data.array.child_type, &ok_type))) 17728 return ira->codegen->invalid_inst_gen; 17729 17730 if (!ok_type) { 17731 ir_add_error(ira, &target->base, 17732 buf_sprintf("array element type '%s' not extern-compatible", 17733 buf_ptr(&target->value->type->data.array.child_type->name))); 17734 } else { 17735 want_var_export = true; 17736 } 17737 break; 17738 } 17739 case ZigTypeIdMetaType: { 17740 ZigType *type_value = target->value->data.x_type; 17741 switch (type_value->id) { 17742 case ZigTypeIdInvalid: 17743 zig_unreachable(); 17744 case ZigTypeIdStruct: 17745 if (is_slice(type_value)) { 17746 ir_add_error(ira, &target->base, 17747 buf_sprintf("unable to export type '%s'", buf_ptr(&type_value->name))); 17748 } else if (type_value->data.structure.layout != ContainerLayoutExtern) { 17749 ErrorMsg *msg = ir_add_error(ira, &target->base, 17750 buf_sprintf("exported struct must be declared extern")); 17751 add_error_note(ira->codegen, msg, type_value->data.structure.decl_node, buf_sprintf("declared here")); 17752 } 17753 break; 17754 case ZigTypeIdUnion: 17755 if (type_value->data.unionation.layout != ContainerLayoutExtern) { 17756 ErrorMsg *msg = ir_add_error(ira, &target->base, 17757 buf_sprintf("exported union must be declared extern")); 17758 add_error_note(ira->codegen, msg, type_value->data.unionation.decl_node, buf_sprintf("declared here")); 17759 } 17760 break; 17761 case ZigTypeIdEnum: 17762 if (type_value->data.enumeration.layout != ContainerLayoutExtern) { 17763 ErrorMsg *msg = ir_add_error(ira, &target->base, 17764 buf_sprintf("exported enum must be declared extern")); 17765 add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here")); 17766 } 17767 break; 17768 case ZigTypeIdFn: { 17769 if (type_value->data.fn.fn_type_id.cc == CallingConventionUnspecified) { 17770 ir_add_error(ira, &target->base, 17771 buf_sprintf("exported function type must specify calling convention")); 17772 } 17773 } break; 17774 case ZigTypeIdInt: 17775 case ZigTypeIdFloat: 17776 case ZigTypeIdPointer: 17777 case ZigTypeIdArray: 17778 case ZigTypeIdBool: 17779 case ZigTypeIdVector: 17780 break; 17781 case ZigTypeIdMetaType: 17782 case ZigTypeIdVoid: 17783 case ZigTypeIdUnreachable: 17784 case ZigTypeIdComptimeFloat: 17785 case ZigTypeIdComptimeInt: 17786 case ZigTypeIdEnumLiteral: 17787 case ZigTypeIdUndefined: 17788 case ZigTypeIdNull: 17789 case ZigTypeIdOptional: 17790 case ZigTypeIdErrorUnion: 17791 case ZigTypeIdErrorSet: 17792 case ZigTypeIdBoundFn: 17793 case ZigTypeIdOpaque: 17794 case ZigTypeIdFnFrame: 17795 case ZigTypeIdAnyFrame: 17796 ir_add_error(ira, &target->base, 17797 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name))); 17798 break; 17799 } 17800 } break; 17801 case ZigTypeIdInt: 17802 break; 17803 case ZigTypeIdVoid: 17804 case ZigTypeIdBool: 17805 case ZigTypeIdFloat: 17806 case ZigTypeIdPointer: 17807 case ZigTypeIdComptimeFloat: 17808 case ZigTypeIdComptimeInt: 17809 case ZigTypeIdUndefined: 17810 case ZigTypeIdNull: 17811 case ZigTypeIdOptional: 17812 case ZigTypeIdErrorUnion: 17813 case ZigTypeIdErrorSet: 17814 case ZigTypeIdVector: 17815 zig_panic("TODO export const value of type %s", buf_ptr(&target->value->type->name)); 17816 case ZigTypeIdBoundFn: 17817 case ZigTypeIdOpaque: 17818 case ZigTypeIdEnumLiteral: 17819 case ZigTypeIdFnFrame: 17820 case ZigTypeIdAnyFrame: 17821 ir_add_error(ira, &target->base, 17822 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value->type->name))); 17823 break; 17824 } 17825 17826 // TODO audit the various ways to use @export 17827 if (want_var_export && target->id == IrInstGenIdLoadPtr) { 17828 IrInstGenLoadPtr *load_ptr = reinterpret_cast<IrInstGenLoadPtr *>(target); 17829 if (load_ptr->ptr->id == IrInstGenIdVarPtr) { 17830 IrInstGenVarPtr *var_ptr = reinterpret_cast<IrInstGenVarPtr *>(load_ptr->ptr); 17831 ZigVar *var = var_ptr->var; 17832 add_var_export(ira->codegen, var, buf_ptr(symbol_name), global_linkage_id); 17833 var->section_name = section_name; 17834 } 17835 } 17836 17837 return ir_const_void(ira, &instruction->base.base); 17838 } 17839 17840 static bool exec_has_err_ret_trace(CodeGen *g, IrExecutableSrc *exec) { 17841 ZigFn *fn_entry = exec_fn_entry(exec); 17842 return fn_entry != nullptr && fn_entry->calls_or_awaits_errorable_fn && g->have_err_ret_tracing; 17843 } 17844 17845 static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira, 17846 IrInstSrcErrorReturnTrace *instruction) 17847 { 17848 ZigType *ptr_to_stack_trace_type = get_pointer_to_type(ira->codegen, get_stack_trace_type(ira->codegen), false); 17849 if (instruction->optional == IrInstErrorReturnTraceNull) { 17850 ZigType *optional_type = get_optional_type(ira->codegen, ptr_to_stack_trace_type); 17851 if (!exec_has_err_ret_trace(ira->codegen, ira->old_irb.exec)) { 17852 IrInstGen *result = ir_const(ira, &instruction->base.base, optional_type); 17853 ZigValue *out_val = result->value; 17854 assert(get_codegen_ptr_type(optional_type) != nullptr); 17855 out_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 17856 out_val->data.x_ptr.data.hard_coded_addr.addr = 0; 17857 return result; 17858 } 17859 return ir_build_error_return_trace_gen(ira, instruction->base.base.scope, 17860 instruction->base.base.source_node, instruction->optional, optional_type); 17861 } else { 17862 assert(ira->codegen->have_err_ret_tracing); 17863 return ir_build_error_return_trace_gen(ira, instruction->base.base.scope, 17864 instruction->base.base.source_node, instruction->optional, ptr_to_stack_trace_type); 17865 } 17866 } 17867 17868 static IrInstGen *ir_analyze_instruction_error_union(IrAnalyze *ira, IrInstSrcErrorUnion *instruction) { 17869 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); 17870 result->value->special = ConstValSpecialLazy; 17871 17872 LazyValueErrUnionType *lazy_err_union_type = heap::c_allocator.create<LazyValueErrUnionType>(); 17873 lazy_err_union_type->ira = ira; ira_ref(ira); 17874 result->value->data.x_lazy = &lazy_err_union_type->base; 17875 lazy_err_union_type->base.id = LazyValueIdErrUnionType; 17876 17877 lazy_err_union_type->err_set_type = instruction->err_set->child; 17878 if (ir_resolve_type_lazy(ira, lazy_err_union_type->err_set_type) == nullptr) 17879 return ira->codegen->invalid_inst_gen; 17880 17881 lazy_err_union_type->payload_type = instruction->payload->child; 17882 if (ir_resolve_type_lazy(ira, lazy_err_union_type->payload_type) == nullptr) 17883 return ira->codegen->invalid_inst_gen; 17884 17885 return result; 17886 } 17887 17888 static IrInstGen *ir_analyze_alloca(IrAnalyze *ira, IrInst *source_inst, ZigType *var_type, 17889 uint32_t align, const char *name_hint, bool force_comptime) 17890 { 17891 Error err; 17892 17893 ZigValue *pointee = ira->codegen->pass1_arena->create<ZigValue>(); 17894 pointee->special = ConstValSpecialUndef; 17895 pointee->llvm_align = align; 17896 17897 IrInstGenAlloca *result = ir_build_alloca_gen(ira, source_inst, align, name_hint); 17898 result->base.value->special = ConstValSpecialStatic; 17899 result->base.value->data.x_ptr.special = ConstPtrSpecialRef; 17900 result->base.value->data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer; 17901 result->base.value->data.x_ptr.data.ref.pointee = pointee; 17902 17903 bool var_type_has_bits; 17904 if ((err = type_has_bits2(ira->codegen, var_type, &var_type_has_bits))) 17905 return ira->codegen->invalid_inst_gen; 17906 if (align != 0) { 17907 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown))) 17908 return ira->codegen->invalid_inst_gen; 17909 if (!var_type_has_bits) { 17910 ir_add_error(ira, source_inst, 17911 buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned", 17912 name_hint, buf_ptr(&var_type->name))); 17913 return ira->codegen->invalid_inst_gen; 17914 } 17915 } 17916 assert(result->base.value->data.x_ptr.special != ConstPtrSpecialInvalid); 17917 17918 pointee->type = var_type; 17919 result->base.value->type = get_pointer_to_type_extra(ira->codegen, var_type, false, false, 17920 PtrLenSingle, align, 0, 0, false); 17921 17922 if (!force_comptime) { 17923 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 17924 if (fn_entry != nullptr) { 17925 fn_entry->alloca_gen_list.append(result); 17926 } 17927 } 17928 return &result->base; 17929 } 17930 17931 static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInst *suspend_source_instr, 17932 ResultLoc *result_loc) 17933 { 17934 switch (result_loc->id) { 17935 case ResultLocIdInvalid: 17936 case ResultLocIdPeerParent: 17937 zig_unreachable(); 17938 case ResultLocIdNone: 17939 case ResultLocIdVar: 17940 case ResultLocIdBitCast: 17941 case ResultLocIdCast: 17942 return nullptr; 17943 case ResultLocIdInstruction: 17944 return result_loc->source_instruction->child->value->type; 17945 case ResultLocIdReturn: 17946 return ira->explicit_return_type; 17947 case ResultLocIdPeer: 17948 return reinterpret_cast<ResultLocPeer*>(result_loc)->parent->resolved_type; 17949 } 17950 zig_unreachable(); 17951 } 17952 17953 static bool type_can_bit_cast(ZigType *t) { 17954 switch (t->id) { 17955 case ZigTypeIdInvalid: 17956 zig_unreachable(); 17957 case ZigTypeIdMetaType: 17958 case ZigTypeIdOpaque: 17959 case ZigTypeIdBoundFn: 17960 case ZigTypeIdUnreachable: 17961 case ZigTypeIdComptimeFloat: 17962 case ZigTypeIdComptimeInt: 17963 case ZigTypeIdEnumLiteral: 17964 case ZigTypeIdUndefined: 17965 case ZigTypeIdNull: 17966 case ZigTypeIdPointer: 17967 return false; 17968 default: 17969 // TODO list these types out explicitly, there are probably some other invalid ones here 17970 return true; 17971 } 17972 } 17973 17974 static void set_up_result_loc_for_inferred_comptime(IrAnalyze *ira, IrInstGen *ptr) { 17975 ZigValue *undef_child = ira->codegen->pass1_arena->create<ZigValue>(); 17976 undef_child->type = ptr->value->type->data.pointer.child_type; 17977 undef_child->special = ConstValSpecialUndef; 17978 ptr->value->special = ConstValSpecialStatic; 17979 ptr->value->data.x_ptr.mut = ConstPtrMutInfer; 17980 ptr->value->data.x_ptr.special = ConstPtrSpecialRef; 17981 ptr->value->data.x_ptr.data.ref.pointee = undef_child; 17982 } 17983 17984 static Error ir_result_has_type(IrAnalyze *ira, ResultLoc *result_loc, bool *out) { 17985 switch (result_loc->id) { 17986 case ResultLocIdInvalid: 17987 case ResultLocIdPeerParent: 17988 zig_unreachable(); 17989 case ResultLocIdNone: 17990 case ResultLocIdPeer: 17991 *out = false; 17992 return ErrorNone; 17993 case ResultLocIdReturn: 17994 case ResultLocIdInstruction: 17995 case ResultLocIdBitCast: 17996 *out = true; 17997 return ErrorNone; 17998 case ResultLocIdCast: { 17999 ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); 18000 ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); 18001 if (type_is_invalid(dest_type)) 18002 return ErrorSemanticAnalyzeFail; 18003 *out = (dest_type != ira->codegen->builtin_types.entry_var); 18004 return ErrorNone; 18005 } 18006 case ResultLocIdVar: 18007 *out = reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; 18008 return ErrorNone; 18009 } 18010 zig_unreachable(); 18011 } 18012 18013 static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_source_instr, 18014 ResultLoc *result_loc, ZigType *value_type) 18015 { 18016 if (type_is_invalid(value_type)) 18017 return ira->codegen->invalid_inst_gen; 18018 IrInstGenAlloca *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, ""); 18019 alloca_gen->base.value->type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, 18020 PtrLenSingle, 0, 0, 0, false); 18021 set_up_result_loc_for_inferred_comptime(ira, &alloca_gen->base); 18022 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 18023 if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) { 18024 fn_entry->alloca_gen_list.append(alloca_gen); 18025 } 18026 result_loc->written = true; 18027 result_loc->resolved_loc = &alloca_gen->base; 18028 return result_loc->resolved_loc; 18029 } 18030 18031 static bool result_loc_is_discard(ResultLoc *result_loc_pass1) { 18032 if (result_loc_pass1->id == ResultLocIdInstruction && 18033 result_loc_pass1->source_instruction->id == IrInstSrcIdConst) 18034 { 18035 IrInstSrcConst *const_inst = reinterpret_cast<IrInstSrcConst *>(result_loc_pass1->source_instruction); 18036 if (value_is_comptime(const_inst->value) && 18037 const_inst->value->type->id == ZigTypeIdPointer && 18038 const_inst->value->data.x_ptr.special == ConstPtrSpecialDiscard) 18039 { 18040 return true; 18041 } 18042 } 18043 return false; 18044 } 18045 18046 // when calling this function, at the callsite must check for result type noreturn and propagate it up 18047 static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_instr, 18048 ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime, 18049 bool allow_discard) 18050 { 18051 Error err; 18052 if (result_loc->resolved_loc != nullptr) { 18053 // allow to redo the result location if the value is known and comptime and the previous one isn't 18054 if (value == nullptr || !instr_is_comptime(value) || instr_is_comptime(result_loc->resolved_loc)) { 18055 return result_loc->resolved_loc; 18056 } 18057 } 18058 result_loc->gen_instruction = value; 18059 result_loc->implicit_elem_type = value_type; 18060 switch (result_loc->id) { 18061 case ResultLocIdInvalid: 18062 case ResultLocIdPeerParent: 18063 zig_unreachable(); 18064 case ResultLocIdNone: { 18065 if (value != nullptr) { 18066 return nullptr; 18067 } 18068 // need to return a result location and don't have one. use a stack allocation 18069 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type); 18070 } 18071 case ResultLocIdVar: { 18072 ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc); 18073 assert(result_loc->source_instruction->id == IrInstSrcIdAlloca); 18074 IrInstSrcAlloca *alloca_src = reinterpret_cast<IrInstSrcAlloca *>(result_loc->source_instruction); 18075 18076 ZigVar *var = result_loc_var->var; 18077 if (var->var_type != nullptr && !ir_get_var_is_comptime(var)) { 18078 // This is at least the second time we've seen this variable declaration during analysis. 18079 // This means that this is actually a different variable due to, e.g. an inline while loop. 18080 // We make a new variable so that it can hold a different type, and so the debug info can 18081 // be distinct. 18082 ZigVar *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope, 18083 buf_create_from_str(var->name), var->src_is_const, var->gen_is_const, 18084 var->shadowable, var->is_comptime, true); 18085 new_var->align_bytes = var->align_bytes; 18086 18087 var->next_var = new_var; 18088 var = new_var; 18089 } 18090 if (value_type->id == ZigTypeIdUnreachable || value_type->id == ZigTypeIdOpaque) { 18091 ir_add_error(ira, &result_loc->source_instruction->base, 18092 buf_sprintf("variable of type '%s' not allowed", buf_ptr(&value_type->name))); 18093 return ira->codegen->invalid_inst_gen; 18094 } 18095 if (alloca_src->base.child == nullptr || var->ptr_instruction == nullptr) { 18096 bool force_comptime; 18097 if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) 18098 return ira->codegen->invalid_inst_gen; 18099 uint32_t align = 0; 18100 if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, nullptr, &align)) { 18101 return ira->codegen->invalid_inst_gen; 18102 } 18103 IrInstGen *alloca_gen = ir_analyze_alloca(ira, &result_loc->source_instruction->base, value_type, 18104 align, alloca_src->name_hint, force_comptime); 18105 if (force_runtime) { 18106 alloca_gen->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; 18107 alloca_gen->value->special = ConstValSpecialRuntime; 18108 } 18109 if (alloca_src->base.child != nullptr && !result_loc->written) { 18110 alloca_src->base.child->base.ref_count = 0; 18111 } 18112 alloca_src->base.child = alloca_gen; 18113 var->ptr_instruction = alloca_gen; 18114 } 18115 result_loc->written = true; 18116 result_loc->resolved_loc = alloca_src->base.child; 18117 return alloca_src->base.child; 18118 } 18119 case ResultLocIdInstruction: { 18120 result_loc->written = true; 18121 result_loc->resolved_loc = result_loc->source_instruction->child; 18122 return result_loc->resolved_loc; 18123 } 18124 case ResultLocIdReturn: { 18125 if (value != nullptr) { 18126 reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = true; 18127 ira->src_implicit_return_type_list.append(value); 18128 } 18129 result_loc->written = true; 18130 result_loc->resolved_loc = ira->return_ptr; 18131 return result_loc->resolved_loc; 18132 } 18133 case ResultLocIdPeer: { 18134 ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(result_loc); 18135 ResultLocPeerParent *peer_parent = result_peer->parent; 18136 18137 if (peer_parent->peers.length == 1) { 18138 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 18139 value_type, value, force_runtime, true); 18140 result_peer->suspend_pos.basic_block_index = SIZE_MAX; 18141 result_peer->suspend_pos.instruction_index = SIZE_MAX; 18142 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 18143 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 18144 { 18145 return parent_result_loc; 18146 } 18147 result_loc->written = true; 18148 result_loc->resolved_loc = parent_result_loc; 18149 return result_loc->resolved_loc; 18150 } 18151 18152 bool is_condition_comptime; 18153 if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_condition_comptime)) 18154 return ira->codegen->invalid_inst_gen; 18155 if (is_condition_comptime) { 18156 peer_parent->skipped = true; 18157 return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 18158 value_type, value, force_runtime, true); 18159 } 18160 bool peer_parent_has_type; 18161 if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) 18162 return ira->codegen->invalid_inst_gen; 18163 if (peer_parent_has_type) { 18164 peer_parent->skipped = true; 18165 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 18166 value_type, value, force_runtime || !is_condition_comptime, true); 18167 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 18168 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 18169 { 18170 return parent_result_loc; 18171 } 18172 peer_parent->parent->written = true; 18173 result_loc->written = true; 18174 result_loc->resolved_loc = parent_result_loc; 18175 return result_loc->resolved_loc; 18176 } 18177 18178 if (peer_parent->resolved_type == nullptr) { 18179 if (peer_parent->end_bb->suspend_instruction_ref == nullptr) { 18180 peer_parent->end_bb->suspend_instruction_ref = suspend_source_instr; 18181 } 18182 IrInstGen *unreach_inst = ira_suspend(ira, suspend_source_instr, result_peer->next_bb, 18183 &result_peer->suspend_pos); 18184 if (result_peer->next_bb == nullptr) { 18185 ir_start_next_bb(ira); 18186 } 18187 return unreach_inst; 18188 } 18189 18190 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 18191 peer_parent->resolved_type, nullptr, force_runtime, true); 18192 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 18193 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 18194 { 18195 return parent_result_loc; 18196 } 18197 // because is_condition_comptime is false, we mark this a runtime pointer 18198 parent_result_loc->value->special = ConstValSpecialRuntime; 18199 result_loc->written = true; 18200 result_loc->resolved_loc = parent_result_loc; 18201 return result_loc->resolved_loc; 18202 } 18203 case ResultLocIdCast: { 18204 ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); 18205 ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); 18206 if (type_is_invalid(dest_type)) 18207 return ira->codegen->invalid_inst_gen; 18208 18209 if (dest_type == ira->codegen->builtin_types.entry_var) { 18210 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type); 18211 } 18212 18213 IrInstGen *casted_value; 18214 if (value != nullptr) { 18215 casted_value = ir_implicit_cast2(ira, suspend_source_instr, value, dest_type); 18216 if (type_is_invalid(casted_value->value->type)) 18217 return ira->codegen->invalid_inst_gen; 18218 dest_type = casted_value->value->type; 18219 } else { 18220 casted_value = nullptr; 18221 } 18222 18223 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent, 18224 dest_type, casted_value, force_runtime, true); 18225 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 18226 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 18227 { 18228 return parent_result_loc; 18229 } 18230 18231 ZigType *parent_ptr_type = parent_result_loc->value->type; 18232 assert(parent_ptr_type->id == ZigTypeIdPointer); 18233 18234 if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, 18235 ResolveStatusAlignmentKnown))) 18236 { 18237 return ira->codegen->invalid_inst_gen; 18238 } 18239 uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); 18240 if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { 18241 return ira->codegen->invalid_inst_gen; 18242 } 18243 if (!type_has_bits(value_type)) { 18244 parent_ptr_align = 0; 18245 } 18246 // If we're casting from a sentinel-terminated array to a non-sentinel-terminated array, 18247 // we actually need the result location pointer to *not* have a sentinel. Otherwise the generated 18248 // memcpy will write an extra byte to the destination, and THAT'S NO GOOD. 18249 ZigType *ptr_elem_type; 18250 if (value_type->id == ZigTypeIdArray && value_type->data.array.sentinel != nullptr && 18251 dest_type->id == ZigTypeIdArray && dest_type->data.array.sentinel == nullptr) 18252 { 18253 ptr_elem_type = get_array_type(ira->codegen, value_type->data.array.child_type, 18254 value_type->data.array.len, nullptr); 18255 } else { 18256 ptr_elem_type = value_type; 18257 } 18258 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ptr_elem_type, 18259 parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, 18260 parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); 18261 18262 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, 18263 parent_result_loc->value->type, ptr_type, 18264 result_cast->base.source_instruction->base.source_node, false); 18265 if (const_cast_result.id == ConstCastResultIdInvalid) 18266 return ira->codegen->invalid_inst_gen; 18267 if (const_cast_result.id != ConstCastResultIdOk) { 18268 if (allow_discard) { 18269 return parent_result_loc; 18270 } 18271 // We will not be able to provide a result location for this value. Create 18272 // a new result location. 18273 result_cast->parent->written = false; 18274 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type); 18275 } 18276 18277 result_loc->written = true; 18278 result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, 18279 &parent_result_loc->base, ptr_type, &result_cast->base.source_instruction->base, false); 18280 return result_loc->resolved_loc; 18281 } 18282 case ResultLocIdBitCast: { 18283 ResultLocBitCast *result_bit_cast = reinterpret_cast<ResultLocBitCast *>(result_loc); 18284 ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child); 18285 if (type_is_invalid(dest_type)) 18286 return ira->codegen->invalid_inst_gen; 18287 18288 if (get_codegen_ptr_type(dest_type) != nullptr) { 18289 ir_add_error(ira, &result_loc->source_instruction->base, 18290 buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); 18291 return ira->codegen->invalid_inst_gen; 18292 } 18293 18294 if (!type_can_bit_cast(dest_type)) { 18295 ir_add_error(ira, &result_loc->source_instruction->base, 18296 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); 18297 return ira->codegen->invalid_inst_gen; 18298 } 18299 18300 if (get_codegen_ptr_type(value_type) != nullptr) { 18301 ir_add_error(ira, suspend_source_instr, 18302 buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&value_type->name))); 18303 return ira->codegen->invalid_inst_gen; 18304 } 18305 18306 if (!type_can_bit_cast(value_type)) { 18307 ir_add_error(ira, suspend_source_instr, 18308 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&value_type->name))); 18309 return ira->codegen->invalid_inst_gen; 18310 } 18311 18312 IrInstGen *bitcasted_value; 18313 if (value != nullptr) { 18314 bitcasted_value = ir_analyze_bit_cast(ira, &result_loc->source_instruction->base, value, dest_type); 18315 dest_type = bitcasted_value->value->type; 18316 } else { 18317 bitcasted_value = nullptr; 18318 } 18319 18320 if (bitcasted_value != nullptr && type_is_invalid(bitcasted_value->value->type)) { 18321 return bitcasted_value; 18322 } 18323 18324 bool parent_was_written = result_bit_cast->parent->written; 18325 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent, 18326 dest_type, bitcasted_value, force_runtime, true); 18327 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 18328 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 18329 { 18330 return parent_result_loc; 18331 } 18332 ZigType *parent_ptr_type = parent_result_loc->value->type; 18333 assert(parent_ptr_type->id == ZigTypeIdPointer); 18334 ZigType *child_type = parent_ptr_type->data.pointer.child_type; 18335 18336 if (result_loc_is_discard(result_bit_cast->parent)) { 18337 assert(allow_discard); 18338 return parent_result_loc; 18339 } 18340 18341 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) { 18342 return ira->codegen->invalid_inst_gen; 18343 } 18344 18345 if ((err = type_resolve(ira->codegen, value_type, ResolveStatusSizeKnown))) { 18346 return ira->codegen->invalid_inst_gen; 18347 } 18348 18349 if (child_type != ira->codegen->builtin_types.entry_var) { 18350 if (type_size(ira->codegen, child_type) != type_size(ira->codegen, value_type)) { 18351 // pointer cast won't work; we need a temporary location. 18352 result_bit_cast->parent->written = parent_was_written; 18353 result_loc->written = true; 18354 result_loc->resolved_loc = ir_resolve_result(ira, suspend_source_instr, no_result_loc(), 18355 value_type, bitcasted_value, force_runtime, true); 18356 return result_loc->resolved_loc; 18357 } 18358 } 18359 uint64_t parent_ptr_align = 0; 18360 if (type_has_bits(value_type)) parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); 18361 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, 18362 parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, 18363 parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); 18364 18365 result_loc->written = true; 18366 result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, 18367 &parent_result_loc->base, ptr_type, &result_bit_cast->base.source_instruction->base, false); 18368 return result_loc->resolved_loc; 18369 } 18370 } 18371 zig_unreachable(); 18372 } 18373 18374 static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr, 18375 ResultLoc *result_loc_pass1, ZigType *value_type, IrInstGen *value, bool force_runtime, 18376 bool allow_discard) 18377 { 18378 if (!allow_discard && result_loc_is_discard(result_loc_pass1)) { 18379 result_loc_pass1 = no_result_loc(); 18380 } 18381 bool was_written = result_loc_pass1->written; 18382 IrInstGen *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, 18383 value, force_runtime, allow_discard); 18384 if (result_loc == nullptr || result_loc->value->type->id == ZigTypeIdUnreachable || 18385 type_is_invalid(result_loc->value->type)) 18386 { 18387 return result_loc; 18388 } 18389 18390 if ((force_runtime || (value != nullptr && !instr_is_comptime(value))) && 18391 result_loc_pass1->written && result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) 18392 { 18393 result_loc->value->special = ConstValSpecialRuntime; 18394 } 18395 18396 InferredStructField *isf = result_loc->value->type->data.pointer.inferred_struct_field; 18397 if (isf != nullptr) { 18398 TypeStructField *field; 18399 IrInstGen *casted_ptr; 18400 if (isf->already_resolved) { 18401 field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); 18402 casted_ptr = result_loc; 18403 } else { 18404 isf->already_resolved = true; 18405 // Now it's time to add the field to the struct type. 18406 uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count; 18407 uint32_t new_field_count = old_field_count + 1; 18408 isf->inferred_struct_type->data.structure.src_field_count = new_field_count; 18409 isf->inferred_struct_type->data.structure.fields = realloc_type_struct_fields( 18410 isf->inferred_struct_type->data.structure.fields, old_field_count, new_field_count); 18411 18412 field = isf->inferred_struct_type->data.structure.fields[old_field_count]; 18413 field->name = isf->field_name; 18414 field->type_entry = value_type; 18415 field->type_val = create_const_type(ira->codegen, field->type_entry); 18416 field->src_index = old_field_count; 18417 field->decl_node = value ? value->base.source_node : suspend_source_instr->source_node; 18418 if (value && instr_is_comptime(value)) { 18419 ZigValue *val = ir_resolve_const(ira, value, UndefOk); 18420 if (!val) 18421 return ira->codegen->invalid_inst_gen; 18422 field->is_comptime = true; 18423 field->init_val = ira->codegen->pass1_arena->create<ZigValue>(); 18424 copy_const_val(ira->codegen, field->init_val, val); 18425 return result_loc; 18426 } 18427 18428 ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false); 18429 if (instr_is_comptime(result_loc)) { 18430 casted_ptr = ir_const(ira, suspend_source_instr, struct_ptr_type); 18431 copy_const_val(ira->codegen, casted_ptr->value, result_loc->value); 18432 casted_ptr->value->type = struct_ptr_type; 18433 } else { 18434 casted_ptr = result_loc; 18435 } 18436 if (instr_is_comptime(casted_ptr)) { 18437 ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad); 18438 if (!ptr_val) 18439 return ira->codegen->invalid_inst_gen; 18440 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 18441 ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, 18442 suspend_source_instr->source_node); 18443 struct_val->special = ConstValSpecialStatic; 18444 struct_val->data.x_struct.fields = realloc_const_vals_ptrs(ira->codegen, 18445 struct_val->data.x_struct.fields, old_field_count, new_field_count); 18446 18447 ZigValue *field_val = struct_val->data.x_struct.fields[old_field_count]; 18448 field_val->special = ConstValSpecialUndef; 18449 field_val->type = field->type_entry; 18450 field_val->parent.id = ConstParentIdStruct; 18451 field_val->parent.data.p_struct.struct_val = struct_val; 18452 field_val->parent.data.p_struct.field_index = old_field_count; 18453 } 18454 } 18455 } 18456 18457 result_loc = ir_analyze_struct_field_ptr(ira, suspend_source_instr, field, casted_ptr, 18458 isf->inferred_struct_type, true); 18459 result_loc_pass1->resolved_loc = result_loc; 18460 } 18461 18462 if (was_written) { 18463 return result_loc; 18464 } 18465 18466 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, suspend_source_instr); 18467 ZigType *actual_elem_type = result_loc->value->type->data.pointer.child_type; 18468 if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && 18469 value_type->id != ZigTypeIdNull && value_type->id != ZigTypeIdUndefined) 18470 { 18471 bool same_comptime_repr = types_have_same_zig_comptime_repr(ira->codegen, actual_elem_type, value_type); 18472 if (!same_comptime_repr) { 18473 result_loc_pass1->written = was_written; 18474 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); 18475 } 18476 } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion && 18477 value_type->id != ZigTypeIdUndefined) 18478 { 18479 if (value_type->id == ZigTypeIdErrorSet) { 18480 return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); 18481 } else { 18482 IrInstGen *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, 18483 result_loc, false, true); 18484 ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; 18485 if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && 18486 value_type->id != ZigTypeIdNull && value_type->id != ZigTypeIdUndefined) 18487 { 18488 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); 18489 } else { 18490 return unwrapped_err_ptr; 18491 } 18492 } 18493 } 18494 return result_loc; 18495 } 18496 18497 static IrInstGen *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstSrcResolveResult *instruction) { 18498 ZigType *implicit_elem_type; 18499 if (instruction->ty == nullptr) { 18500 if (instruction->result_loc->id == ResultLocIdCast) { 18501 implicit_elem_type = ir_resolve_type(ira, 18502 instruction->result_loc->source_instruction->child); 18503 if (type_is_invalid(implicit_elem_type)) 18504 return ira->codegen->invalid_inst_gen; 18505 } else if (instruction->result_loc->id == ResultLocIdReturn) { 18506 implicit_elem_type = ira->explicit_return_type; 18507 if (type_is_invalid(implicit_elem_type)) 18508 return ira->codegen->invalid_inst_gen; 18509 } else { 18510 implicit_elem_type = ira->codegen->builtin_types.entry_var; 18511 } 18512 if (implicit_elem_type == ira->codegen->builtin_types.entry_var) { 18513 Buf *bare_name = buf_alloc(); 18514 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), 18515 instruction->base.base.scope, instruction->base.base.source_node, bare_name); 18516 18517 StructSpecial struct_special = StructSpecialInferredStruct; 18518 if (instruction->base.base.source_node->type == NodeTypeContainerInitExpr && 18519 instruction->base.base.source_node->data.container_init_expr.kind == ContainerInitKindArray) 18520 { 18521 struct_special = StructSpecialInferredTuple; 18522 } 18523 18524 ZigType *inferred_struct_type = get_partial_container_type(ira->codegen, 18525 instruction->base.base.scope, ContainerKindStruct, instruction->base.base.source_node, 18526 buf_ptr(name), bare_name, ContainerLayoutAuto); 18527 inferred_struct_type->data.structure.special = struct_special; 18528 inferred_struct_type->data.structure.resolve_status = ResolveStatusBeingInferred; 18529 implicit_elem_type = inferred_struct_type; 18530 } 18531 } else { 18532 implicit_elem_type = ir_resolve_type(ira, instruction->ty->child); 18533 if (type_is_invalid(implicit_elem_type)) 18534 return ira->codegen->invalid_inst_gen; 18535 } 18536 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 18537 implicit_elem_type, nullptr, false, true); 18538 if (result_loc != nullptr) 18539 return result_loc; 18540 18541 ZigFn *fn = ira->new_irb.exec->fn_entry; 18542 if (fn != nullptr && fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync && 18543 instruction->result_loc->id == ResultLocIdReturn) 18544 { 18545 result_loc = ir_resolve_result(ira, &instruction->base.base, no_result_loc(), 18546 implicit_elem_type, nullptr, false, true); 18547 if (result_loc != nullptr && 18548 (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) 18549 { 18550 return result_loc; 18551 } 18552 result_loc->value->special = ConstValSpecialRuntime; 18553 return result_loc; 18554 } 18555 18556 IrInstGen *result = ir_const(ira, &instruction->base.base, implicit_elem_type); 18557 result->value->special = ConstValSpecialUndef; 18558 IrInstGen *ptr = ir_get_ref(ira, &instruction->base.base, result, false, false); 18559 ptr->value->data.x_ptr.mut = ConstPtrMutComptimeVar; 18560 return ptr; 18561 } 18562 18563 static void ir_reset_result(ResultLoc *result_loc) { 18564 result_loc->written = false; 18565 result_loc->resolved_loc = nullptr; 18566 result_loc->gen_instruction = nullptr; 18567 result_loc->implicit_elem_type = nullptr; 18568 switch (result_loc->id) { 18569 case ResultLocIdInvalid: 18570 zig_unreachable(); 18571 case ResultLocIdPeerParent: { 18572 ResultLocPeerParent *peer_parent = reinterpret_cast<ResultLocPeerParent *>(result_loc); 18573 peer_parent->skipped = false; 18574 peer_parent->done_resuming = false; 18575 peer_parent->resolved_type = nullptr; 18576 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 18577 ir_reset_result(&peer_parent->peers.at(i)->base); 18578 } 18579 break; 18580 } 18581 case ResultLocIdVar: { 18582 IrInstSrcAlloca *alloca_src = reinterpret_cast<IrInstSrcAlloca *>(result_loc->source_instruction); 18583 alloca_src->base.child = nullptr; 18584 break; 18585 } 18586 case ResultLocIdReturn: 18587 reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = false; 18588 break; 18589 case ResultLocIdPeer: 18590 case ResultLocIdNone: 18591 case ResultLocIdInstruction: 18592 case ResultLocIdBitCast: 18593 case ResultLocIdCast: 18594 break; 18595 } 18596 } 18597 18598 static IrInstGen *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInstSrcResetResult *instruction) { 18599 ir_reset_result(instruction->result_loc); 18600 return ir_const_void(ira, &instruction->base.base); 18601 } 18602 18603 static IrInstGen *get_async_call_result_loc(IrAnalyze *ira, IrInst* source_instr, 18604 ZigType *fn_ret_type, bool is_async_call_builtin, IrInstGen **args_ptr, size_t args_len, 18605 IrInstGen *ret_ptr_uncasted) 18606 { 18607 ir_assert(is_async_call_builtin, source_instr); 18608 if (type_is_invalid(ret_ptr_uncasted->value->type)) 18609 return ira->codegen->invalid_inst_gen; 18610 if (ret_ptr_uncasted->value->type->id == ZigTypeIdVoid) { 18611 // Result location will be inside the async frame. 18612 return nullptr; 18613 } 18614 return ir_implicit_cast(ira, ret_ptr_uncasted, get_pointer_to_type(ira->codegen, fn_ret_type, false)); 18615 } 18616 18617 static IrInstGen *ir_analyze_async_call(IrAnalyze *ira, IrInst* source_instr, ZigFn *fn_entry, 18618 ZigType *fn_type, IrInstGen *fn_ref, IrInstGen **casted_args, size_t arg_count, 18619 IrInstGen *casted_new_stack, bool is_async_call_builtin, IrInstGen *ret_ptr_uncasted, 18620 ResultLoc *call_result_loc) 18621 { 18622 if (fn_entry == nullptr) { 18623 if (fn_type->data.fn.fn_type_id.cc != CallingConventionAsync) { 18624 ir_add_error(ira, &fn_ref->base, 18625 buf_sprintf("expected async function, found '%s'", buf_ptr(&fn_type->name))); 18626 return ira->codegen->invalid_inst_gen; 18627 } 18628 if (casted_new_stack == nullptr) { 18629 ir_add_error(ira, &fn_ref->base, buf_sprintf("function is not comptime-known; @asyncCall required")); 18630 return ira->codegen->invalid_inst_gen; 18631 } 18632 } 18633 if (casted_new_stack != nullptr) { 18634 ZigType *fn_ret_type = fn_type->data.fn.fn_type_id.return_type; 18635 IrInstGen *ret_ptr = get_async_call_result_loc(ira, source_instr, fn_ret_type, is_async_call_builtin, 18636 casted_args, arg_count, ret_ptr_uncasted); 18637 if (ret_ptr != nullptr && type_is_invalid(ret_ptr->value->type)) 18638 return ira->codegen->invalid_inst_gen; 18639 18640 ZigType *anyframe_type = get_any_frame_type(ira->codegen, fn_ret_type); 18641 18642 IrInstGenCall *call_gen = ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, 18643 arg_count, casted_args, CallModifierAsync, casted_new_stack, 18644 is_async_call_builtin, ret_ptr, anyframe_type); 18645 return &call_gen->base; 18646 } else { 18647 ZigType *frame_type = get_fn_frame_type(ira->codegen, fn_entry); 18648 IrInstGen *result_loc = ir_resolve_result(ira, source_instr, call_result_loc, 18649 frame_type, nullptr, true, false); 18650 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 18651 return result_loc; 18652 } 18653 result_loc = ir_implicit_cast2(ira, &call_result_loc->source_instruction->base, result_loc, 18654 get_pointer_to_type(ira->codegen, frame_type, false)); 18655 if (type_is_invalid(result_loc->value->type)) 18656 return ira->codegen->invalid_inst_gen; 18657 return &ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, arg_count, 18658 casted_args, CallModifierAsync, casted_new_stack, 18659 is_async_call_builtin, result_loc, frame_type)->base; 18660 } 18661 } 18662 static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, 18663 IrInstGen *arg, Scope **exec_scope, size_t *next_proto_i) 18664 { 18665 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 18666 assert(param_decl_node->type == NodeTypeParamDecl); 18667 18668 IrInstGen *casted_arg; 18669 if (param_decl_node->data.param_decl.var_token == nullptr) { 18670 AstNode *param_type_node = param_decl_node->data.param_decl.type; 18671 ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node); 18672 if (type_is_invalid(param_type)) 18673 return false; 18674 18675 casted_arg = ir_implicit_cast(ira, arg, param_type); 18676 if (type_is_invalid(casted_arg->value->type)) 18677 return false; 18678 } else { 18679 casted_arg = arg; 18680 } 18681 18682 ZigValue *arg_val = ir_resolve_const(ira, casted_arg, UndefOk); 18683 if (!arg_val) 18684 return false; 18685 18686 Buf *param_name = param_decl_node->data.param_decl.name; 18687 ZigVar *var = add_variable(ira->codegen, param_decl_node, 18688 *exec_scope, param_name, true, arg_val, nullptr, arg_val->type); 18689 *exec_scope = var->child_scope; 18690 *next_proto_i += 1; 18691 18692 return true; 18693 } 18694 18695 static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node, 18696 IrInstGen *arg, IrInst *arg_src, Scope **child_scope, size_t *next_proto_i, 18697 GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstGen **casted_args, 18698 ZigFn *impl_fn) 18699 { 18700 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 18701 assert(param_decl_node->type == NodeTypeParamDecl); 18702 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 18703 bool arg_part_of_generic_id = false; 18704 IrInstGen *casted_arg; 18705 if (is_var_args) { 18706 arg_part_of_generic_id = true; 18707 casted_arg = arg; 18708 } else { 18709 if (param_decl_node->data.param_decl.var_token == nullptr) { 18710 AstNode *param_type_node = param_decl_node->data.param_decl.type; 18711 ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node); 18712 if (type_is_invalid(param_type)) 18713 return false; 18714 18715 casted_arg = ir_implicit_cast2(ira, arg_src, arg, param_type); 18716 if (type_is_invalid(casted_arg->value->type)) 18717 return false; 18718 } else { 18719 arg_part_of_generic_id = true; 18720 casted_arg = arg; 18721 } 18722 } 18723 18724 bool comptime_arg = param_decl_node->data.param_decl.is_comptime; 18725 if (!comptime_arg) { 18726 switch (type_requires_comptime(ira->codegen, casted_arg->value->type)) { 18727 case ReqCompTimeInvalid: 18728 return false; 18729 case ReqCompTimeYes: 18730 comptime_arg = true; 18731 break; 18732 case ReqCompTimeNo: 18733 break; 18734 } 18735 } 18736 18737 ZigValue *arg_val; 18738 18739 if (comptime_arg) { 18740 arg_part_of_generic_id = true; 18741 arg_val = ir_resolve_const(ira, casted_arg, UndefBad); 18742 if (!arg_val) 18743 return false; 18744 } else { 18745 arg_val = create_const_runtime(ira->codegen, casted_arg->value->type); 18746 } 18747 if (arg_part_of_generic_id) { 18748 copy_const_val(ira->codegen, &generic_id->params[generic_id->param_count], arg_val); 18749 generic_id->param_count += 1; 18750 } 18751 18752 Buf *param_name = param_decl_node->data.param_decl.name; 18753 if (!param_name) return false; 18754 if (!is_var_args) { 18755 ZigVar *var = add_variable(ira->codegen, param_decl_node, 18756 *child_scope, param_name, true, arg_val, nullptr, arg_val->type); 18757 *child_scope = var->child_scope; 18758 var->shadowable = !comptime_arg; 18759 18760 *next_proto_i += 1; 18761 } else if (casted_arg->value->type->id == ZigTypeIdComptimeInt || 18762 casted_arg->value->type->id == ZigTypeIdComptimeFloat) 18763 { 18764 ir_add_error(ira, &casted_arg->base, 18765 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/ziglang/zig/issues/557")); 18766 return false; 18767 } 18768 18769 if (!comptime_arg) { 18770 casted_args[fn_type_id->param_count] = casted_arg; 18771 FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count]; 18772 param_info->type = casted_arg->value->type; 18773 param_info->is_noalias = param_decl_node->data.param_decl.is_noalias; 18774 impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node; 18775 fn_type_id->param_count += 1; 18776 } 18777 18778 return true; 18779 } 18780 18781 static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *var) { 18782 while (var->next_var != nullptr) { 18783 var = var->next_var; 18784 } 18785 18786 if (var->var_type == nullptr || type_is_invalid(var->var_type)) 18787 return ira->codegen->invalid_inst_gen; 18788 18789 bool is_volatile = false; 18790 ZigType *var_ptr_type = get_pointer_to_type_extra(ira->codegen, var->var_type, 18791 var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0, false); 18792 18793 if (var->ptr_instruction != nullptr) { 18794 return ir_implicit_cast(ira, var->ptr_instruction, var_ptr_type); 18795 } 18796 18797 bool comptime_var_mem = ir_get_var_is_comptime(var); 18798 bool linkage_makes_it_runtime = var->decl_node->data.variable_declaration.is_extern; 18799 18800 IrInstGen *result = ir_build_var_ptr_gen(ira, source_instr, var); 18801 result->value->type = var_ptr_type; 18802 18803 if (!linkage_makes_it_runtime && !var->is_thread_local && value_is_comptime(var->const_value)) { 18804 ZigValue *val = var->const_value; 18805 switch (val->special) { 18806 case ConstValSpecialRuntime: 18807 break; 18808 case ConstValSpecialStatic: // fallthrough 18809 case ConstValSpecialLazy: // fallthrough 18810 case ConstValSpecialUndef: { 18811 ConstPtrMut ptr_mut; 18812 if (comptime_var_mem) { 18813 ptr_mut = ConstPtrMutComptimeVar; 18814 } else if (var->gen_is_const) { 18815 ptr_mut = ConstPtrMutComptimeConst; 18816 } else { 18817 assert(!comptime_var_mem); 18818 ptr_mut = ConstPtrMutRuntimeVar; 18819 } 18820 result->value->special = ConstValSpecialStatic; 18821 result->value->data.x_ptr.mut = ptr_mut; 18822 result->value->data.x_ptr.special = ConstPtrSpecialRef; 18823 result->value->data.x_ptr.data.ref.pointee = val; 18824 return result; 18825 } 18826 } 18827 } 18828 18829 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr); 18830 result->value->data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack; 18831 18832 return result; 18833 } 18834 18835 // This function is called when a comptime value becomes accessible at runtime. 18836 static void mark_comptime_value_escape(IrAnalyze *ira, IrInst* source_instr, ZigValue *val) { 18837 ir_assert(value_is_comptime(val), source_instr); 18838 if (val->special == ConstValSpecialUndef) 18839 return; 18840 18841 if (val->type->id == ZigTypeIdFn && val->type->data.fn.fn_type_id.cc == CallingConventionUnspecified) { 18842 ir_assert(val->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); 18843 if (val->data.x_ptr.data.fn.fn_entry->non_async_node == nullptr) { 18844 val->data.x_ptr.data.fn.fn_entry->non_async_node = source_instr->source_node; 18845 } 18846 } 18847 } 18848 18849 static IrInstGen *ir_analyze_store_ptr(IrAnalyze *ira, IrInst* source_instr, 18850 IrInstGen *ptr, IrInstGen *uncasted_value, bool allow_write_through_const) 18851 { 18852 assert(ptr->value->type->id == ZigTypeIdPointer); 18853 18854 if (ptr->value->data.x_ptr.special == ConstPtrSpecialDiscard) { 18855 if (uncasted_value->value->type->id == ZigTypeIdErrorUnion || 18856 uncasted_value->value->type->id == ZigTypeIdErrorSet) 18857 { 18858 ir_add_error(ira, source_instr, buf_sprintf("error is discarded")); 18859 return ira->codegen->invalid_inst_gen; 18860 } 18861 return ir_const_void(ira, source_instr); 18862 } 18863 18864 if (ptr->value->type->data.pointer.is_const && !allow_write_through_const) { 18865 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 18866 return ira->codegen->invalid_inst_gen; 18867 } 18868 18869 ZigType *child_type = ptr->value->type->data.pointer.child_type; 18870 IrInstGen *value = ir_implicit_cast(ira, uncasted_value, child_type); 18871 if (type_is_invalid(value->value->type)) 18872 return ira->codegen->invalid_inst_gen; 18873 18874 switch (type_has_one_possible_value(ira->codegen, child_type)) { 18875 case OnePossibleValueInvalid: 18876 return ira->codegen->invalid_inst_gen; 18877 case OnePossibleValueYes: 18878 return ir_const_void(ira, source_instr); 18879 case OnePossibleValueNo: 18880 break; 18881 } 18882 18883 if (instr_is_comptime(ptr) && ptr->value->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 18884 if (!allow_write_through_const && ptr->value->data.x_ptr.mut == ConstPtrMutComptimeConst) { 18885 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 18886 return ira->codegen->invalid_inst_gen; 18887 } 18888 if ((allow_write_through_const && ptr->value->data.x_ptr.mut == ConstPtrMutComptimeConst) || 18889 ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar || 18890 ptr->value->data.x_ptr.mut == ConstPtrMutInfer) 18891 { 18892 if (instr_is_comptime(value)) { 18893 ZigValue *dest_val = const_ptr_pointee(ira, ira->codegen, ptr->value, source_instr->source_node); 18894 if (dest_val == nullptr) 18895 return ira->codegen->invalid_inst_gen; 18896 if (dest_val->special != ConstValSpecialRuntime) { 18897 copy_const_val(ira->codegen, dest_val, value->value); 18898 18899 if (ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar && 18900 !ira->new_irb.current_basic_block->must_be_comptime_source_instr) 18901 { 18902 ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; 18903 } 18904 return ir_const_void(ira, source_instr); 18905 } 18906 } 18907 if (ptr->value->data.x_ptr.mut == ConstPtrMutInfer) { 18908 ptr->value->special = ConstValSpecialRuntime; 18909 } else { 18910 ir_add_error(ira, source_instr, 18911 buf_sprintf("cannot store runtime value in compile time variable")); 18912 ZigValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, ptr->value); 18913 dest_val->type = ira->codegen->builtin_types.entry_invalid; 18914 18915 return ira->codegen->invalid_inst_gen; 18916 } 18917 } 18918 } 18919 18920 if (ptr->value->type->data.pointer.inferred_struct_field != nullptr && 18921 child_type == ira->codegen->builtin_types.entry_var) 18922 { 18923 child_type = ptr->value->type->data.pointer.inferred_struct_field->inferred_struct_type; 18924 } 18925 18926 switch (type_requires_comptime(ira->codegen, child_type)) { 18927 case ReqCompTimeInvalid: 18928 return ira->codegen->invalid_inst_gen; 18929 case ReqCompTimeYes: 18930 switch (type_has_one_possible_value(ira->codegen, ptr->value->type)) { 18931 case OnePossibleValueInvalid: 18932 return ira->codegen->invalid_inst_gen; 18933 case OnePossibleValueNo: 18934 ir_add_error(ira, source_instr, 18935 buf_sprintf("cannot store runtime value in type '%s'", buf_ptr(&child_type->name))); 18936 return ira->codegen->invalid_inst_gen; 18937 case OnePossibleValueYes: 18938 return ir_const_void(ira, source_instr); 18939 } 18940 zig_unreachable(); 18941 case ReqCompTimeNo: 18942 break; 18943 } 18944 18945 if (instr_is_comptime(value)) { 18946 mark_comptime_value_escape(ira, source_instr, value->value); 18947 } 18948 18949 // If this is a store to a pointer with a runtime-known vector index, 18950 // we have to figure out the IrInstGen which represents the index and 18951 // emit a IrInstGenVectorStoreElem, or emit a compile error 18952 // explaining why it is impossible for this store to work. Which is that 18953 // the pointer address is of the vector; without the element index being known 18954 // we cannot properly perform the insertion. 18955 if (ptr->value->type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) { 18956 if (ptr->id == IrInstGenIdElemPtr) { 18957 IrInstGenElemPtr *elem_ptr = (IrInstGenElemPtr *)ptr; 18958 return ir_build_vector_store_elem(ira, source_instr, elem_ptr->array_ptr, 18959 elem_ptr->elem_index, value); 18960 } 18961 ir_add_error(ira, &ptr->base, 18962 buf_sprintf("unable to determine vector element index of type '%s'", 18963 buf_ptr(&ptr->value->type->name))); 18964 return ira->codegen->invalid_inst_gen; 18965 } 18966 18967 return ir_build_store_ptr_gen(ira, source_instr, ptr, value); 18968 } 18969 18970 static IrInstGen *analyze_casted_new_stack(IrAnalyze *ira, IrInst* source_instr, 18971 IrInstGen *new_stack, IrInst *new_stack_src, bool is_async_call_builtin, ZigFn *fn_entry) 18972 { 18973 if (new_stack == nullptr) 18974 return nullptr; 18975 18976 if (!is_async_call_builtin && 18977 arch_stack_pointer_register_name(ira->codegen->zig_target->arch) == nullptr) 18978 { 18979 ir_add_error(ira, source_instr, 18980 buf_sprintf("target arch '%s' does not support calling with a new stack", 18981 target_arch_name(ira->codegen->zig_target->arch))); 18982 } 18983 18984 if (is_async_call_builtin && 18985 fn_entry != nullptr && new_stack->value->type->id == ZigTypeIdPointer && 18986 new_stack->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 18987 { 18988 ZigType *needed_frame_type = get_pointer_to_type(ira->codegen, 18989 get_fn_frame_type(ira->codegen, fn_entry), false); 18990 return ir_implicit_cast(ira, new_stack, needed_frame_type); 18991 } else { 18992 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 18993 false, false, PtrLenUnknown, target_fn_align(ira->codegen->zig_target), 0, 0, false); 18994 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 18995 ira->codegen->need_frame_size_prefix_data = true; 18996 return ir_implicit_cast2(ira, new_stack_src, new_stack, u8_slice); 18997 } 18998 } 18999 19000 static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, 19001 ZigFn *fn_entry, ZigType *fn_type, IrInstGen *fn_ref, 19002 IrInstGen *first_arg_ptr, IrInst *first_arg_ptr_src, CallModifier modifier, 19003 IrInstGen *new_stack, IrInst *new_stack_src, bool is_async_call_builtin, 19004 IrInstGen **args_ptr, size_t args_len, IrInstGen *ret_ptr, ResultLoc *call_result_loc) 19005 { 19006 Error err; 19007 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 19008 size_t first_arg_1_or_0 = first_arg_ptr ? 1 : 0; 19009 19010 // for extern functions, the var args argument is not counted. 19011 // for zig functions, it is. 19012 size_t var_args_1_or_0; 19013 if (fn_type_id->cc == CallingConventionC) { 19014 var_args_1_or_0 = 0; 19015 } else { 19016 var_args_1_or_0 = fn_type_id->is_var_args ? 1 : 0; 19017 } 19018 size_t src_param_count = fn_type_id->param_count - var_args_1_or_0; 19019 size_t call_param_count = args_len + first_arg_1_or_0; 19020 AstNode *source_node = source_instr->source_node; 19021 19022 AstNode *fn_proto_node = fn_entry ? fn_entry->proto_node : nullptr;; 19023 19024 if (fn_type_id->cc == CallingConventionNaked) { 19025 ErrorMsg *msg = ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to call function with naked calling convention")); 19026 if (fn_proto_node) { 19027 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 19028 } 19029 return ira->codegen->invalid_inst_gen; 19030 } 19031 19032 if (fn_type_id->is_var_args) { 19033 if (call_param_count < src_param_count) { 19034 ErrorMsg *msg = ir_add_error_node(ira, source_node, 19035 buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 19036 if (fn_proto_node) { 19037 add_error_note(ira->codegen, msg, fn_proto_node, 19038 buf_sprintf("declared here")); 19039 } 19040 return ira->codegen->invalid_inst_gen; 19041 } 19042 } else if (src_param_count != call_param_count) { 19043 ErrorMsg *msg = ir_add_error_node(ira, source_node, 19044 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 19045 if (fn_proto_node) { 19046 add_error_note(ira->codegen, msg, fn_proto_node, 19047 buf_sprintf("declared here")); 19048 } 19049 return ira->codegen->invalid_inst_gen; 19050 } 19051 19052 if (modifier == CallModifierCompileTime) { 19053 // No special handling is needed for compile time evaluation of generic functions. 19054 if (!fn_entry || fn_entry->body_node == nullptr) { 19055 ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression")); 19056 return ira->codegen->invalid_inst_gen; 19057 } 19058 19059 if (!ir_emit_backward_branch(ira, source_instr)) 19060 return ira->codegen->invalid_inst_gen; 19061 19062 // Fork a scope of the function with known values for the parameters. 19063 Scope *exec_scope = &fn_entry->fndef_scope->base; 19064 19065 size_t next_proto_i = 0; 19066 if (first_arg_ptr) { 19067 assert(first_arg_ptr->value->type->id == ZigTypeIdPointer); 19068 19069 bool first_arg_known_bare = false; 19070 if (fn_type_id->next_param_index >= 1) { 19071 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 19072 if (type_is_invalid(param_type)) 19073 return ira->codegen->invalid_inst_gen; 19074 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 19075 } 19076 19077 IrInstGen *first_arg; 19078 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) { 19079 first_arg = first_arg_ptr; 19080 } else { 19081 first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); 19082 if (type_is_invalid(first_arg->value->type)) 19083 return ira->codegen->invalid_inst_gen; 19084 } 19085 19086 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, first_arg, &exec_scope, &next_proto_i)) 19087 return ira->codegen->invalid_inst_gen; 19088 } 19089 19090 for (size_t call_i = 0; call_i < args_len; call_i += 1) { 19091 IrInstGen *old_arg = args_ptr[call_i]; 19092 19093 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_proto_i)) 19094 return ira->codegen->invalid_inst_gen; 19095 } 19096 19097 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 19098 ZigType *specified_return_type = ir_analyze_type_expr(ira, exec_scope, return_type_node); 19099 if (type_is_invalid(specified_return_type)) 19100 return ira->codegen->invalid_inst_gen; 19101 ZigType *return_type; 19102 ZigType *inferred_err_set_type = nullptr; 19103 if (fn_proto_node->data.fn_proto.auto_err_set) { 19104 inferred_err_set_type = get_auto_err_set_type(ira->codegen, fn_entry); 19105 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 19106 return ira->codegen->invalid_inst_gen; 19107 return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 19108 } else { 19109 return_type = specified_return_type; 19110 } 19111 19112 bool cacheable = fn_eval_cacheable(exec_scope, return_type); 19113 ZigValue *result = nullptr; 19114 if (cacheable) { 19115 auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope); 19116 if (entry) 19117 result = entry->value; 19118 } 19119 19120 if (result == nullptr) { 19121 // Analyze the fn body block like any other constant expression. 19122 AstNode *body_node = fn_entry->body_node; 19123 ZigValue *result_ptr; 19124 create_result_ptr(ira->codegen, return_type, &result, &result_ptr); 19125 if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr, 19126 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 19127 fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node, 19128 UndefOk))) 19129 { 19130 return ira->codegen->invalid_inst_gen; 19131 } 19132 19133 if (inferred_err_set_type != nullptr) { 19134 inferred_err_set_type->data.error_set.incomplete = false; 19135 if (result->type->id == ZigTypeIdErrorUnion) { 19136 ErrorTableEntry *err = result->data.x_err_union.error_set->data.x_err_set; 19137 if (err != nullptr) { 19138 inferred_err_set_type->data.error_set.err_count = 1; 19139 inferred_err_set_type->data.error_set.errors = heap::c_allocator.create<ErrorTableEntry *>(); 19140 inferred_err_set_type->data.error_set.errors[0] = err; 19141 } 19142 ZigType *fn_inferred_err_set_type = result->type->data.error_union.err_set_type; 19143 inferred_err_set_type->data.error_set.err_count = fn_inferred_err_set_type->data.error_set.err_count; 19144 inferred_err_set_type->data.error_set.errors = fn_inferred_err_set_type->data.error_set.errors; 19145 } else if (result->type->id == ZigTypeIdErrorSet) { 19146 inferred_err_set_type->data.error_set.err_count = result->type->data.error_set.err_count; 19147 inferred_err_set_type->data.error_set.errors = result->type->data.error_set.errors; 19148 } 19149 } 19150 19151 if (cacheable) { 19152 ira->codegen->memoized_fn_eval_table.put(exec_scope, result); 19153 } 19154 19155 if (type_is_invalid(result->type)) { 19156 return ira->codegen->invalid_inst_gen; 19157 } 19158 } 19159 19160 IrInstGen *new_instruction = ir_const_move(ira, source_instr, result); 19161 return ir_finish_anal(ira, new_instruction); 19162 } 19163 19164 if (fn_type->data.fn.is_generic) { 19165 if (!fn_entry) { 19166 ir_add_error(ira, &fn_ref->base, 19167 buf_sprintf("calling a generic function requires compile-time known function value")); 19168 return ira->codegen->invalid_inst_gen; 19169 } 19170 19171 size_t new_fn_arg_count = first_arg_1_or_0 + args_len; 19172 19173 IrInstGen **casted_args = heap::c_allocator.allocate<IrInstGen *>(new_fn_arg_count); 19174 19175 // Fork a scope of the function with known values for the parameters. 19176 Scope *parent_scope = fn_entry->fndef_scope->base.parent; 19177 ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node); 19178 impl_fn->param_source_nodes = heap::c_allocator.allocate<AstNode *>(new_fn_arg_count); 19179 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); 19180 impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn); 19181 impl_fn->child_scope = &impl_fn->fndef_scope->base; 19182 FnTypeId inst_fn_type_id = {0}; 19183 init_fn_type_id(&inst_fn_type_id, fn_proto_node, fn_type_id->cc, new_fn_arg_count); 19184 inst_fn_type_id.param_count = 0; 19185 inst_fn_type_id.is_var_args = false; 19186 19187 // TODO maybe GenericFnTypeId can be replaced with using the child_scope directly 19188 // as the key in generic_table 19189 GenericFnTypeId *generic_id = heap::c_allocator.create<GenericFnTypeId>(); 19190 generic_id->fn_entry = fn_entry; 19191 generic_id->param_count = 0; 19192 generic_id->params = ira->codegen->pass1_arena->allocate<ZigValue>(new_fn_arg_count); 19193 size_t next_proto_i = 0; 19194 19195 if (first_arg_ptr) { 19196 assert(first_arg_ptr->value->type->id == ZigTypeIdPointer); 19197 19198 bool first_arg_known_bare = false; 19199 if (fn_type_id->next_param_index >= 1) { 19200 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 19201 if (type_is_invalid(param_type)) 19202 return ira->codegen->invalid_inst_gen; 19203 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 19204 } 19205 19206 IrInstGen *first_arg; 19207 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) { 19208 first_arg = first_arg_ptr; 19209 } else { 19210 first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); 19211 if (type_is_invalid(first_arg->value->type)) 19212 return ira->codegen->invalid_inst_gen; 19213 } 19214 19215 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, first_arg, first_arg_ptr_src, 19216 &impl_fn->child_scope, &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 19217 { 19218 return ira->codegen->invalid_inst_gen; 19219 } 19220 } 19221 19222 ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry; 19223 assert(parent_fn_entry); 19224 for (size_t call_i = 0; call_i < args_len; call_i += 1) { 19225 IrInstGen *arg = args_ptr[call_i]; 19226 19227 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 19228 assert(param_decl_node->type == NodeTypeParamDecl); 19229 19230 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &arg->base, &impl_fn->child_scope, 19231 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 19232 { 19233 return ira->codegen->invalid_inst_gen; 19234 } 19235 } 19236 19237 if (fn_proto_node->data.fn_proto.align_expr != nullptr) { 19238 ZigValue *align_result; 19239 ZigValue *result_ptr; 19240 create_result_ptr(ira->codegen, get_align_amt_type(ira->codegen), &align_result, &result_ptr); 19241 if ((err = ir_eval_const_value(ira->codegen, impl_fn->child_scope, 19242 fn_proto_node->data.fn_proto.align_expr, result_ptr, 19243 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 19244 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, 19245 nullptr, UndefBad))) 19246 { 19247 return ira->codegen->invalid_inst_gen; 19248 } 19249 IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb, 19250 impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); 19251 const_instruction->base.value = align_result; 19252 19253 uint32_t align_bytes = 0; 19254 ir_resolve_align(ira, &const_instruction->base, nullptr, &align_bytes); 19255 impl_fn->align_bytes = align_bytes; 19256 inst_fn_type_id.alignment = align_bytes; 19257 } 19258 19259 if (fn_proto_node->data.fn_proto.return_var_token == nullptr) { 19260 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 19261 ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node); 19262 if (type_is_invalid(specified_return_type)) 19263 return ira->codegen->invalid_inst_gen; 19264 if (fn_proto_node->data.fn_proto.auto_err_set) { 19265 ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn); 19266 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 19267 return ira->codegen->invalid_inst_gen; 19268 inst_fn_type_id.return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 19269 } else { 19270 inst_fn_type_id.return_type = specified_return_type; 19271 } 19272 19273 switch (type_requires_comptime(ira->codegen, specified_return_type)) { 19274 case ReqCompTimeYes: 19275 // Throw out our work and call the function as if it were comptime. 19276 return ir_analyze_fn_call(ira, source_instr, fn_entry, fn_type, fn_ref, first_arg_ptr, 19277 first_arg_ptr_src, CallModifierCompileTime, new_stack, new_stack_src, is_async_call_builtin, 19278 args_ptr, args_len, ret_ptr, call_result_loc); 19279 case ReqCompTimeInvalid: 19280 return ira->codegen->invalid_inst_gen; 19281 case ReqCompTimeNo: 19282 break; 19283 } 19284 } 19285 19286 auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn); 19287 if (existing_entry) { 19288 // throw away all our work and use the existing function 19289 impl_fn = existing_entry->value; 19290 } else { 19291 // finish instantiating the function 19292 impl_fn->type_entry = get_fn_type(ira->codegen, &inst_fn_type_id); 19293 if (type_is_invalid(impl_fn->type_entry)) 19294 return ira->codegen->invalid_inst_gen; 19295 19296 impl_fn->ir_executable->source_node = source_instr->source_node; 19297 impl_fn->ir_executable->parent_exec = ira->new_irb.exec; 19298 impl_fn->analyzed_executable.source_node = source_instr->source_node; 19299 impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec; 19300 impl_fn->analyzed_executable.backward_branch_quota = ira->new_irb.exec->backward_branch_quota; 19301 impl_fn->analyzed_executable.is_generic_instantiation = true; 19302 19303 ira->codegen->fn_defs.append(impl_fn); 19304 } 19305 19306 FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id; 19307 19308 if (fn_type_can_fail(impl_fn_type_id)) { 19309 parent_fn_entry->calls_or_awaits_errorable_fn = true; 19310 } 19311 19312 IrInstGen *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack, 19313 new_stack_src, is_async_call_builtin, impl_fn); 19314 if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) 19315 return ira->codegen->invalid_inst_gen; 19316 19317 size_t impl_param_count = impl_fn_type_id->param_count; 19318 if (modifier == CallModifierAsync) { 19319 IrInstGen *result = ir_analyze_async_call(ira, source_instr, impl_fn, impl_fn->type_entry, 19320 nullptr, casted_args, impl_param_count, casted_new_stack, is_async_call_builtin, ret_ptr, 19321 call_result_loc); 19322 return ir_finish_anal(ira, result); 19323 } 19324 19325 IrInstGen *result_loc; 19326 if (handle_is_ptr(impl_fn_type_id->return_type)) { 19327 result_loc = ir_resolve_result(ira, source_instr, call_result_loc, 19328 impl_fn_type_id->return_type, nullptr, true, false); 19329 if (result_loc != nullptr) { 19330 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 19331 return result_loc; 19332 } 19333 IrInstGen *dummy_value = ir_const(ira, source_instr, impl_fn_type_id->return_type); 19334 dummy_value->value->special = ConstValSpecialRuntime; 19335 IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr, 19336 dummy_value, result_loc->value->type->data.pointer.child_type); 19337 if (type_is_invalid(dummy_result->value->type)) 19338 return ira->codegen->invalid_inst_gen; 19339 ZigType *res_child_type = result_loc->value->type->data.pointer.child_type; 19340 if (res_child_type == ira->codegen->builtin_types.entry_var) { 19341 res_child_type = impl_fn_type_id->return_type; 19342 } 19343 if (!handle_is_ptr(res_child_type)) { 19344 ir_reset_result(call_result_loc); 19345 result_loc = nullptr; 19346 } 19347 } 19348 } else if (is_async_call_builtin) { 19349 result_loc = get_async_call_result_loc(ira, source_instr, impl_fn_type_id->return_type, 19350 is_async_call_builtin, args_ptr, args_len, ret_ptr); 19351 if (result_loc != nullptr && type_is_invalid(result_loc->value->type)) 19352 return ira->codegen->invalid_inst_gen; 19353 } else { 19354 result_loc = nullptr; 19355 } 19356 19357 if (impl_fn_type_id->cc == CallingConventionAsync && 19358 parent_fn_entry->inferred_async_node == nullptr && 19359 modifier != CallModifierNoAsync) 19360 { 19361 parent_fn_entry->inferred_async_node = fn_ref->base.source_node; 19362 parent_fn_entry->inferred_async_fn = impl_fn; 19363 } 19364 19365 IrInstGenCall *new_call_instruction = ir_build_call_gen(ira, source_instr, 19366 impl_fn, nullptr, impl_param_count, casted_args, modifier, casted_new_stack, 19367 is_async_call_builtin, result_loc, impl_fn_type_id->return_type); 19368 19369 if (get_scope_typeof(source_instr->scope) == nullptr) { 19370 parent_fn_entry->call_list.append(new_call_instruction); 19371 } 19372 19373 return ir_finish_anal(ira, &new_call_instruction->base); 19374 } 19375 19376 ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry; 19377 assert(fn_type_id->return_type != nullptr); 19378 assert(parent_fn_entry != nullptr); 19379 if (fn_type_can_fail(fn_type_id)) { 19380 parent_fn_entry->calls_or_awaits_errorable_fn = true; 19381 } 19382 19383 19384 IrInstGen **casted_args = heap::c_allocator.allocate<IrInstGen *>(call_param_count); 19385 size_t next_arg_index = 0; 19386 if (first_arg_ptr) { 19387 assert(first_arg_ptr->value->type->id == ZigTypeIdPointer); 19388 19389 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 19390 if (type_is_invalid(param_type)) 19391 return ira->codegen->invalid_inst_gen; 19392 19393 IrInstGen *first_arg; 19394 if (param_type->id == ZigTypeIdPointer && 19395 handle_is_ptr(first_arg_ptr->value->type->data.pointer.child_type)) 19396 { 19397 first_arg = first_arg_ptr; 19398 } else { 19399 first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); 19400 if (type_is_invalid(first_arg->value->type)) 19401 return ira->codegen->invalid_inst_gen; 19402 } 19403 19404 IrInstGen *casted_arg = ir_implicit_cast2(ira, first_arg_ptr_src, first_arg, param_type); 19405 if (type_is_invalid(casted_arg->value->type)) 19406 return ira->codegen->invalid_inst_gen; 19407 19408 casted_args[next_arg_index] = casted_arg; 19409 next_arg_index += 1; 19410 } 19411 for (size_t call_i = 0; call_i < args_len; call_i += 1) { 19412 IrInstGen *old_arg = args_ptr[call_i]; 19413 if (type_is_invalid(old_arg->value->type)) 19414 return ira->codegen->invalid_inst_gen; 19415 19416 IrInstGen *casted_arg; 19417 if (next_arg_index < src_param_count) { 19418 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 19419 if (type_is_invalid(param_type)) 19420 return ira->codegen->invalid_inst_gen; 19421 casted_arg = ir_implicit_cast(ira, old_arg, param_type); 19422 if (type_is_invalid(casted_arg->value->type)) 19423 return ira->codegen->invalid_inst_gen; 19424 } else { 19425 casted_arg = old_arg; 19426 } 19427 19428 casted_args[next_arg_index] = casted_arg; 19429 next_arg_index += 1; 19430 } 19431 19432 assert(next_arg_index == call_param_count); 19433 19434 ZigType *return_type = fn_type_id->return_type; 19435 if (type_is_invalid(return_type)) 19436 return ira->codegen->invalid_inst_gen; 19437 19438 if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && modifier == CallModifierNeverInline) { 19439 ir_add_error(ira, source_instr, 19440 buf_sprintf("no-inline call of inline function")); 19441 return ira->codegen->invalid_inst_gen; 19442 } 19443 19444 IrInstGen *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack, new_stack_src, 19445 is_async_call_builtin, fn_entry); 19446 if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) 19447 return ira->codegen->invalid_inst_gen; 19448 19449 if (modifier == CallModifierAsync) { 19450 IrInstGen *result = ir_analyze_async_call(ira, source_instr, fn_entry, fn_type, fn_ref, 19451 casted_args, call_param_count, casted_new_stack, is_async_call_builtin, ret_ptr, call_result_loc); 19452 return ir_finish_anal(ira, result); 19453 } 19454 19455 if (fn_type_id->cc == CallingConventionAsync && 19456 parent_fn_entry->inferred_async_node == nullptr && 19457 modifier != CallModifierNoAsync) 19458 { 19459 parent_fn_entry->inferred_async_node = fn_ref->base.source_node; 19460 parent_fn_entry->inferred_async_fn = fn_entry; 19461 } 19462 19463 IrInstGen *result_loc; 19464 if (handle_is_ptr(return_type)) { 19465 result_loc = ir_resolve_result(ira, source_instr, call_result_loc, 19466 return_type, nullptr, true, false); 19467 if (result_loc != nullptr) { 19468 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 19469 return result_loc; 19470 } 19471 IrInstGen *dummy_value = ir_const(ira, source_instr, return_type); 19472 dummy_value->value->special = ConstValSpecialRuntime; 19473 IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr, 19474 dummy_value, result_loc->value->type->data.pointer.child_type); 19475 if (type_is_invalid(dummy_result->value->type)) 19476 return ira->codegen->invalid_inst_gen; 19477 ZigType *res_child_type = result_loc->value->type->data.pointer.child_type; 19478 if (res_child_type == ira->codegen->builtin_types.entry_var) { 19479 res_child_type = return_type; 19480 } 19481 if (!handle_is_ptr(res_child_type)) { 19482 ir_reset_result(call_result_loc); 19483 result_loc = nullptr; 19484 } 19485 } 19486 } else if (is_async_call_builtin) { 19487 result_loc = get_async_call_result_loc(ira, source_instr, return_type, is_async_call_builtin, 19488 args_ptr, args_len, ret_ptr); 19489 if (result_loc != nullptr && type_is_invalid(result_loc->value->type)) 19490 return ira->codegen->invalid_inst_gen; 19491 } else { 19492 result_loc = nullptr; 19493 } 19494 19495 IrInstGenCall *new_call_instruction = ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, 19496 call_param_count, casted_args, modifier, casted_new_stack, 19497 is_async_call_builtin, result_loc, return_type); 19498 if (get_scope_typeof(source_instr->scope) == nullptr) { 19499 parent_fn_entry->call_list.append(new_call_instruction); 19500 } 19501 return ir_finish_anal(ira, &new_call_instruction->base); 19502 } 19503 19504 static IrInstGen *ir_analyze_fn_call_src(IrAnalyze *ira, IrInstSrcCall *call_instruction, 19505 ZigFn *fn_entry, ZigType *fn_type, IrInstGen *fn_ref, 19506 IrInstGen *first_arg_ptr, IrInst *first_arg_ptr_src, CallModifier modifier) 19507 { 19508 IrInstGen *new_stack = nullptr; 19509 IrInst *new_stack_src = nullptr; 19510 if (call_instruction->new_stack) { 19511 new_stack = call_instruction->new_stack->child; 19512 if (type_is_invalid(new_stack->value->type)) 19513 return ira->codegen->invalid_inst_gen; 19514 new_stack_src = &call_instruction->new_stack->base; 19515 } 19516 IrInstGen **args_ptr = heap::c_allocator.allocate<IrInstGen *>(call_instruction->arg_count); 19517 for (size_t i = 0; i < call_instruction->arg_count; i += 1) { 19518 args_ptr[i] = call_instruction->args[i]->child; 19519 if (type_is_invalid(args_ptr[i]->value->type)) 19520 return ira->codegen->invalid_inst_gen; 19521 } 19522 IrInstGen *ret_ptr = nullptr; 19523 if (call_instruction->ret_ptr != nullptr) { 19524 ret_ptr = call_instruction->ret_ptr->child; 19525 if (type_is_invalid(ret_ptr->value->type)) 19526 return ira->codegen->invalid_inst_gen; 19527 } 19528 IrInstGen *result = ir_analyze_fn_call(ira, &call_instruction->base.base, fn_entry, fn_type, fn_ref, 19529 first_arg_ptr, first_arg_ptr_src, modifier, new_stack, new_stack_src, 19530 call_instruction->is_async_call_builtin, args_ptr, call_instruction->arg_count, ret_ptr, 19531 call_instruction->result_loc); 19532 heap::c_allocator.deallocate(args_ptr, call_instruction->arg_count); 19533 return result; 19534 } 19535 19536 static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr, 19537 IrInstSrc *pass1_options, IrInstSrc *pass1_fn_ref, IrInstGen **args_ptr, size_t args_len, 19538 ResultLoc *result_loc) 19539 { 19540 IrInstGen *options = pass1_options->child; 19541 if (type_is_invalid(options->value->type)) 19542 return ira->codegen->invalid_inst_gen; 19543 19544 IrInstGen *fn_ref = pass1_fn_ref->child; 19545 if (type_is_invalid(fn_ref->value->type)) 19546 return ira->codegen->invalid_inst_gen; 19547 19548 TypeStructField *modifier_field = find_struct_type_field(options->value->type, buf_create_from_str("modifier")); 19549 ir_assert(modifier_field != nullptr, source_instr); 19550 IrInstGen *modifier_inst = ir_analyze_struct_value_field_value(ira, source_instr, options, modifier_field); 19551 ZigValue *modifier_val = ir_resolve_const(ira, modifier_inst, UndefBad); 19552 if (modifier_val == nullptr) 19553 return ira->codegen->invalid_inst_gen; 19554 CallModifier modifier = (CallModifier)bigint_as_u32(&modifier_val->data.x_enum_tag); 19555 19556 if (ir_should_inline(ira->old_irb.exec, source_instr->scope)) { 19557 switch (modifier) { 19558 case CallModifierBuiltin: 19559 zig_unreachable(); 19560 case CallModifierAsync: 19561 ir_add_error(ira, source_instr, buf_sprintf("TODO: comptime @call with async modifier")); 19562 return ira->codegen->invalid_inst_gen; 19563 case CallModifierCompileTime: 19564 case CallModifierNone: 19565 case CallModifierAlwaysInline: 19566 case CallModifierAlwaysTail: 19567 case CallModifierNoAsync: 19568 modifier = CallModifierCompileTime; 19569 break; 19570 case CallModifierNeverInline: 19571 ir_add_error(ira, source_instr, 19572 buf_sprintf("unable to perform 'never_inline' call at compile-time")); 19573 return ira->codegen->invalid_inst_gen; 19574 case CallModifierNeverTail: 19575 ir_add_error(ira, source_instr, 19576 buf_sprintf("unable to perform 'never_tail' call at compile-time")); 19577 return ira->codegen->invalid_inst_gen; 19578 } 19579 } 19580 19581 IrInstGen *first_arg_ptr = nullptr; 19582 IrInst *first_arg_ptr_src = nullptr; 19583 ZigFn *fn = nullptr; 19584 if (instr_is_comptime(fn_ref)) { 19585 if (fn_ref->value->type->id == ZigTypeIdBoundFn) { 19586 assert(fn_ref->value->special == ConstValSpecialStatic); 19587 fn = fn_ref->value->data.x_bound_fn.fn; 19588 first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg; 19589 first_arg_ptr_src = fn_ref->value->data.x_bound_fn.first_arg_src; 19590 if (type_is_invalid(first_arg_ptr->value->type)) 19591 return ira->codegen->invalid_inst_gen; 19592 } else { 19593 fn = ir_resolve_fn(ira, fn_ref); 19594 } 19595 } 19596 19597 // Some modifiers require the callee to be comptime-known 19598 switch (modifier) { 19599 case CallModifierCompileTime: 19600 case CallModifierAlwaysInline: 19601 case CallModifierAsync: 19602 if (fn == nullptr) { 19603 ir_add_error(ira, &modifier_inst->base, 19604 buf_sprintf("the specified modifier requires a comptime-known function")); 19605 return ira->codegen->invalid_inst_gen; 19606 } 19607 default: 19608 break; 19609 } 19610 19611 ZigType *fn_type = (fn != nullptr) ? fn->type_entry : fn_ref->value->type; 19612 19613 TypeStructField *stack_field = find_struct_type_field(options->value->type, buf_create_from_str("stack")); 19614 ir_assert(stack_field != nullptr, source_instr); 19615 IrInstGen *opt_stack = ir_analyze_struct_value_field_value(ira, source_instr, options, stack_field); 19616 if (type_is_invalid(opt_stack->value->type)) 19617 return ira->codegen->invalid_inst_gen; 19618 19619 IrInstGen *stack_is_non_null_inst = ir_analyze_test_non_null(ira, source_instr, opt_stack); 19620 bool stack_is_non_null; 19621 if (!ir_resolve_bool(ira, stack_is_non_null_inst, &stack_is_non_null)) 19622 return ira->codegen->invalid_inst_gen; 19623 19624 IrInstGen *stack = nullptr; 19625 if (stack_is_non_null) { 19626 stack = ir_analyze_optional_value_payload_value(ira, source_instr, opt_stack, false); 19627 if (type_is_invalid(stack->value->type)) 19628 return ira->codegen->invalid_inst_gen; 19629 } 19630 19631 return ir_analyze_fn_call(ira, source_instr, fn, fn_type, fn_ref, first_arg_ptr, first_arg_ptr_src, 19632 modifier, stack, &stack->base, false, args_ptr, args_len, nullptr, result_loc); 19633 } 19634 19635 static IrInstGen *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstSrcCallExtra *instruction) { 19636 IrInstGen *args = instruction->args->child; 19637 ZigType *args_type = args->value->type; 19638 if (type_is_invalid(args_type)) 19639 return ira->codegen->invalid_inst_gen; 19640 19641 if (args_type->id != ZigTypeIdStruct) { 19642 ir_add_error(ira, &args->base, 19643 buf_sprintf("expected tuple or struct, found '%s'", buf_ptr(&args_type->name))); 19644 return ira->codegen->invalid_inst_gen; 19645 } 19646 19647 IrInstGen **args_ptr = nullptr; 19648 size_t args_len = 0; 19649 19650 if (is_tuple(args_type)) { 19651 args_len = args_type->data.structure.src_field_count; 19652 args_ptr = heap::c_allocator.allocate<IrInstGen *>(args_len); 19653 for (size_t i = 0; i < args_len; i += 1) { 19654 TypeStructField *arg_field = args_type->data.structure.fields[i]; 19655 args_ptr[i] = ir_analyze_struct_value_field_value(ira, &instruction->base.base, args, arg_field); 19656 if (type_is_invalid(args_ptr[i]->value->type)) 19657 return ira->codegen->invalid_inst_gen; 19658 } 19659 } else { 19660 ir_add_error(ira, &args->base, buf_sprintf("TODO: struct args")); 19661 return ira->codegen->invalid_inst_gen; 19662 } 19663 IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options, 19664 instruction->fn_ref, args_ptr, args_len, instruction->result_loc); 19665 heap::c_allocator.deallocate(args_ptr, args_len); 19666 return result; 19667 } 19668 19669 static IrInstGen *ir_analyze_instruction_call_args(IrAnalyze *ira, IrInstSrcCallArgs *instruction) { 19670 IrInstGen **args_ptr = heap::c_allocator.allocate<IrInstGen *>(instruction->args_len); 19671 for (size_t i = 0; i < instruction->args_len; i += 1) { 19672 args_ptr[i] = instruction->args_ptr[i]->child; 19673 if (type_is_invalid(args_ptr[i]->value->type)) 19674 return ira->codegen->invalid_inst_gen; 19675 } 19676 19677 IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options, 19678 instruction->fn_ref, args_ptr, instruction->args_len, instruction->result_loc); 19679 heap::c_allocator.deallocate(args_ptr, instruction->args_len); 19680 return result; 19681 } 19682 19683 static IrInstGen *ir_analyze_instruction_call(IrAnalyze *ira, IrInstSrcCall *call_instruction) { 19684 IrInstGen *fn_ref = call_instruction->fn_ref->child; 19685 if (type_is_invalid(fn_ref->value->type)) 19686 return ira->codegen->invalid_inst_gen; 19687 19688 bool is_comptime = (call_instruction->modifier == CallModifierCompileTime) || 19689 ir_should_inline(ira->old_irb.exec, call_instruction->base.base.scope); 19690 CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; 19691 19692 if (is_comptime || instr_is_comptime(fn_ref)) { 19693 if (fn_ref->value->type->id == ZigTypeIdMetaType) { 19694 ZigType *ty = ir_resolve_type(ira, fn_ref); 19695 if (ty == nullptr) 19696 return ira->codegen->invalid_inst_gen; 19697 ErrorMsg *msg = ir_add_error(ira, &fn_ref->base, 19698 buf_sprintf("type '%s' not a function", buf_ptr(&ty->name))); 19699 add_error_note(ira->codegen, msg, call_instruction->base.base.source_node, 19700 buf_sprintf("use @as builtin for type coercion")); 19701 return ira->codegen->invalid_inst_gen; 19702 } else if (fn_ref->value->type->id == ZigTypeIdFn) { 19703 ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref); 19704 ZigType *fn_type = fn_table_entry ? fn_table_entry->type_entry : fn_ref->value->type; 19705 CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; 19706 return ir_analyze_fn_call_src(ira, call_instruction, fn_table_entry, fn_type, 19707 fn_ref, nullptr, nullptr, modifier); 19708 } else if (fn_ref->value->type->id == ZigTypeIdBoundFn) { 19709 assert(fn_ref->value->special == ConstValSpecialStatic); 19710 ZigFn *fn_table_entry = fn_ref->value->data.x_bound_fn.fn; 19711 IrInstGen *first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg; 19712 IrInst *first_arg_ptr_src = fn_ref->value->data.x_bound_fn.first_arg_src; 19713 CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; 19714 return ir_analyze_fn_call_src(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, 19715 fn_ref, first_arg_ptr, first_arg_ptr_src, modifier); 19716 } else { 19717 ir_add_error(ira, &fn_ref->base, 19718 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value->type->name))); 19719 return ira->codegen->invalid_inst_gen; 19720 } 19721 } 19722 19723 if (fn_ref->value->type->id == ZigTypeIdFn) { 19724 return ir_analyze_fn_call_src(ira, call_instruction, nullptr, fn_ref->value->type, 19725 fn_ref, nullptr, nullptr, modifier); 19726 } else { 19727 ir_add_error(ira, &fn_ref->base, 19728 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value->type->name))); 19729 return ira->codegen->invalid_inst_gen; 19730 } 19731 } 19732 19733 // out_val->type must be the type to read the pointer as 19734 // if the type is different than the actual type then it does a comptime byte reinterpretation 19735 static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 19736 ZigValue *out_val, ZigValue *ptr_val) 19737 { 19738 Error err; 19739 assert(out_val->type != nullptr); 19740 19741 ZigValue *pointee = const_ptr_pointee_unchecked(codegen, ptr_val); 19742 src_assert(pointee->type != nullptr, source_node); 19743 19744 if ((err = type_resolve(codegen, pointee->type, ResolveStatusSizeKnown))) 19745 return ErrorSemanticAnalyzeFail; 19746 if ((err = type_resolve(codegen, out_val->type, ResolveStatusSizeKnown))) 19747 return ErrorSemanticAnalyzeFail; 19748 19749 size_t src_size = type_size(codegen, pointee->type); 19750 size_t dst_size = type_size(codegen, out_val->type); 19751 19752 if (dst_size <= src_size) { 19753 if (src_size == dst_size && types_have_same_zig_comptime_repr(codegen, out_val->type, pointee->type)) { 19754 copy_const_val(codegen, out_val, pointee); 19755 return ErrorNone; 19756 } 19757 Buf buf = BUF_INIT; 19758 buf_resize(&buf, src_size); 19759 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf), pointee); 19760 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 19761 return err; 19762 return ErrorNone; 19763 } 19764 19765 switch (ptr_val->data.x_ptr.special) { 19766 case ConstPtrSpecialInvalid: 19767 zig_unreachable(); 19768 case ConstPtrSpecialNull: 19769 if (dst_size == 0) 19770 return ErrorNone; 19771 opt_ir_add_error_node(ira, codegen, source_node, 19772 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from null pointer", 19773 dst_size)); 19774 return ErrorSemanticAnalyzeFail; 19775 case ConstPtrSpecialRef: { 19776 opt_ir_add_error_node(ira, codegen, source_node, 19777 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from pointer to %s which is %" ZIG_PRI_usize " bytes", 19778 dst_size, buf_ptr(&pointee->type->name), src_size)); 19779 return ErrorSemanticAnalyzeFail; 19780 } 19781 case ConstPtrSpecialBaseArray: { 19782 ZigValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val; 19783 assert(array_val->type->id == ZigTypeIdArray); 19784 if (array_val->data.x_array.special != ConstArraySpecialNone) 19785 zig_panic("TODO"); 19786 size_t elem_size = src_size; 19787 size_t elem_index = ptr_val->data.x_ptr.data.base_array.elem_index; 19788 src_size = elem_size * (array_val->type->data.array.len - elem_index); 19789 if (dst_size > src_size) { 19790 opt_ir_add_error_node(ira, codegen, source_node, 19791 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from %s at index %" ZIG_PRI_usize " which is %" ZIG_PRI_usize " bytes", 19792 dst_size, buf_ptr(&array_val->type->name), elem_index, src_size)); 19793 return ErrorSemanticAnalyzeFail; 19794 } 19795 size_t elem_count = (dst_size % elem_size == 0) ? (dst_size / elem_size) : (dst_size / elem_size + 1); 19796 Buf buf = BUF_INIT; 19797 buf_resize(&buf, elem_count * elem_size); 19798 for (size_t i = 0; i < elem_count; i += 1) { 19799 ZigValue *elem_val = &array_val->data.x_array.data.s_none.elements[elem_index + i]; 19800 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val); 19801 } 19802 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 19803 return err; 19804 return ErrorNone; 19805 } 19806 case ConstPtrSpecialBaseStruct: 19807 case ConstPtrSpecialBaseErrorUnionCode: 19808 case ConstPtrSpecialBaseErrorUnionPayload: 19809 case ConstPtrSpecialBaseOptionalPayload: 19810 case ConstPtrSpecialDiscard: 19811 case ConstPtrSpecialHardCodedAddr: 19812 case ConstPtrSpecialFunction: 19813 zig_panic("TODO"); 19814 } 19815 zig_unreachable(); 19816 } 19817 19818 static IrInstGen *ir_analyze_optional_type(IrAnalyze *ira, IrInstSrcUnOp *instruction) { 19819 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); 19820 result->value->special = ConstValSpecialLazy; 19821 19822 LazyValueOptType *lazy_opt_type = heap::c_allocator.create<LazyValueOptType>(); 19823 lazy_opt_type->ira = ira; ira_ref(ira); 19824 result->value->data.x_lazy = &lazy_opt_type->base; 19825 lazy_opt_type->base.id = LazyValueIdOptType; 19826 19827 lazy_opt_type->payload_type = instruction->value->child; 19828 if (ir_resolve_type_lazy(ira, lazy_opt_type->payload_type) == nullptr) 19829 return ira->codegen->invalid_inst_gen; 19830 19831 return result; 19832 } 19833 19834 static ErrorMsg *ir_eval_negation_scalar(IrAnalyze *ira, IrInst* source_instr, ZigType *scalar_type, 19835 ZigValue *operand_val, ZigValue *scalar_out_val, bool is_wrap_op) 19836 { 19837 bool is_float = (scalar_type->id == ZigTypeIdFloat || scalar_type->id == ZigTypeIdComptimeFloat); 19838 19839 bool ok_type = ((scalar_type->id == ZigTypeIdInt && scalar_type->data.integral.is_signed) || 19840 scalar_type->id == ZigTypeIdComptimeInt || (is_float && !is_wrap_op)); 19841 19842 if (!ok_type) { 19843 const char *fmt = is_wrap_op ? "invalid wrapping negation type: '%s'" : "invalid negation type: '%s'"; 19844 return ir_add_error(ira, source_instr, buf_sprintf(fmt, buf_ptr(&scalar_type->name))); 19845 } 19846 19847 if (is_float) { 19848 float_negate(scalar_out_val, operand_val); 19849 } else if (is_wrap_op) { 19850 bigint_negate_wrap(&scalar_out_val->data.x_bigint, &operand_val->data.x_bigint, 19851 scalar_type->data.integral.bit_count); 19852 } else { 19853 bigint_negate(&scalar_out_val->data.x_bigint, &operand_val->data.x_bigint); 19854 } 19855 19856 scalar_out_val->type = scalar_type; 19857 scalar_out_val->special = ConstValSpecialStatic; 19858 19859 if (is_wrap_op || is_float || scalar_type->id == ZigTypeIdComptimeInt) { 19860 return nullptr; 19861 } 19862 19863 if (!bigint_fits_in_bits(&scalar_out_val->data.x_bigint, scalar_type->data.integral.bit_count, true)) { 19864 return ir_add_error(ira, source_instr, buf_sprintf("negation caused overflow")); 19865 } 19866 return nullptr; 19867 } 19868 19869 static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction) { 19870 IrInstGen *value = instruction->value->child; 19871 ZigType *expr_type = value->value->type; 19872 if (type_is_invalid(expr_type)) 19873 return ira->codegen->invalid_inst_gen; 19874 19875 if (!(expr_type->id == ZigTypeIdInt || expr_type->id == ZigTypeIdComptimeInt || 19876 expr_type->id == ZigTypeIdFloat || expr_type->id == ZigTypeIdComptimeFloat || 19877 expr_type->id == ZigTypeIdVector)) 19878 { 19879 ir_add_error(ira, &instruction->base.base, 19880 buf_sprintf("negation of type '%s'", buf_ptr(&expr_type->name))); 19881 return ira->codegen->invalid_inst_gen; 19882 } 19883 19884 bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap); 19885 19886 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; 19887 19888 if (instr_is_comptime(value)) { 19889 ZigValue *operand_val = ir_resolve_const(ira, value, UndefBad); 19890 if (!operand_val) 19891 return ira->codegen->invalid_inst_gen; 19892 19893 IrInstGen *result_instruction = ir_const(ira, &instruction->base.base, expr_type); 19894 ZigValue *out_val = result_instruction->value; 19895 if (expr_type->id == ZigTypeIdVector) { 19896 expand_undef_array(ira->codegen, operand_val); 19897 out_val->special = ConstValSpecialUndef; 19898 expand_undef_array(ira->codegen, out_val); 19899 size_t len = expr_type->data.vector.len; 19900 for (size_t i = 0; i < len; i += 1) { 19901 ZigValue *scalar_operand_val = &operand_val->data.x_array.data.s_none.elements[i]; 19902 ZigValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 19903 assert(scalar_operand_val->type == scalar_type); 19904 assert(scalar_out_val->type == scalar_type); 19905 ErrorMsg *msg = ir_eval_negation_scalar(ira, &instruction->base.base, scalar_type, 19906 scalar_operand_val, scalar_out_val, is_wrap_op); 19907 if (msg != nullptr) { 19908 add_error_note(ira->codegen, msg, instruction->base.base.source_node, 19909 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 19910 return ira->codegen->invalid_inst_gen; 19911 } 19912 } 19913 out_val->type = expr_type; 19914 out_val->special = ConstValSpecialStatic; 19915 } else { 19916 if (ir_eval_negation_scalar(ira, &instruction->base.base, scalar_type, operand_val, out_val, 19917 is_wrap_op) != nullptr) 19918 { 19919 return ira->codegen->invalid_inst_gen; 19920 } 19921 } 19922 return result_instruction; 19923 } 19924 19925 if (is_wrap_op) { 19926 return ir_build_negation_wrapping(ira, &instruction->base.base, value, expr_type); 19927 } else { 19928 return ir_build_negation(ira, &instruction->base.base, value, expr_type); 19929 } 19930 } 19931 19932 static IrInstGen *ir_analyze_bin_not(IrAnalyze *ira, IrInstSrcUnOp *instruction) { 19933 IrInstGen *value = instruction->value->child; 19934 ZigType *expr_type = value->value->type; 19935 if (type_is_invalid(expr_type)) 19936 return ira->codegen->invalid_inst_gen; 19937 19938 if (expr_type->id == ZigTypeIdInt) { 19939 if (instr_is_comptime(value)) { 19940 ZigValue *target_const_val = ir_resolve_const(ira, value, UndefBad); 19941 if (target_const_val == nullptr) 19942 return ira->codegen->invalid_inst_gen; 19943 19944 IrInstGen *result = ir_const(ira, &instruction->base.base, expr_type); 19945 bigint_not(&result->value->data.x_bigint, &target_const_val->data.x_bigint, 19946 expr_type->data.integral.bit_count, expr_type->data.integral.is_signed); 19947 return result; 19948 } 19949 19950 return ir_build_binary_not(ira, &instruction->base.base, value, expr_type); 19951 } 19952 19953 ir_add_error(ira, &instruction->base.base, 19954 buf_sprintf("unable to perform binary not operation on type '%s'", buf_ptr(&expr_type->name))); 19955 return ira->codegen->invalid_inst_gen; 19956 } 19957 19958 static IrInstGen *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstSrcUnOp *instruction) { 19959 IrUnOp op_id = instruction->op_id; 19960 switch (op_id) { 19961 case IrUnOpInvalid: 19962 zig_unreachable(); 19963 case IrUnOpBinNot: 19964 return ir_analyze_bin_not(ira, instruction); 19965 case IrUnOpNegation: 19966 case IrUnOpNegationWrap: 19967 return ir_analyze_negation(ira, instruction); 19968 case IrUnOpDereference: { 19969 IrInstGen *ptr = instruction->value->child; 19970 if (type_is_invalid(ptr->value->type)) 19971 return ira->codegen->invalid_inst_gen; 19972 ZigType *ptr_type = ptr->value->type; 19973 if (ptr_type->id == ZigTypeIdPointer && ptr_type->data.pointer.ptr_len == PtrLenUnknown) { 19974 ir_add_error_node(ira, instruction->base.base.source_node, 19975 buf_sprintf("index syntax required for unknown-length pointer type '%s'", 19976 buf_ptr(&ptr_type->name))); 19977 return ira->codegen->invalid_inst_gen; 19978 } 19979 19980 IrInstGen *result = ir_get_deref(ira, &instruction->base.base, ptr, instruction->result_loc); 19981 if (type_is_invalid(result->value->type)) 19982 return ira->codegen->invalid_inst_gen; 19983 19984 // If the result needs to be an lvalue, type check it 19985 if (instruction->lval == LValPtr && result->value->type->id != ZigTypeIdPointer) { 19986 ir_add_error(ira, &instruction->base.base, 19987 buf_sprintf("attempt to dereference non-pointer type '%s'", buf_ptr(&result->value->type->name))); 19988 return ira->codegen->invalid_inst_gen; 19989 } 19990 19991 return result; 19992 } 19993 case IrUnOpOptional: 19994 return ir_analyze_optional_type(ira, instruction); 19995 } 19996 zig_unreachable(); 19997 } 19998 19999 static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) { 20000 IrBasicBlockSrc *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index); 20001 if (old_bb->in_resume_stack) return; 20002 ira->resume_stack.append(pos); 20003 old_bb->in_resume_stack = true; 20004 } 20005 20006 static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlockSrc *old_bb) { 20007 if (ira->resume_stack.length != 0) { 20008 ir_push_resume(ira, {old_bb->index, 0}); 20009 } 20010 } 20011 20012 static IrInstGen *ir_analyze_instruction_br(IrAnalyze *ira, IrInstSrcBr *br_instruction) { 20013 IrBasicBlockSrc *old_dest_block = br_instruction->dest_block; 20014 20015 bool is_comptime; 20016 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) 20017 return ir_unreach_error(ira); 20018 20019 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) 20020 return ir_inline_bb(ira, &br_instruction->base.base, old_dest_block); 20021 20022 IrBasicBlockGen *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base.base); 20023 if (new_bb == nullptr) 20024 return ir_unreach_error(ira); 20025 20026 ir_push_resume_block(ira, old_dest_block); 20027 20028 IrInstGen *result = ir_build_br_gen(ira, &br_instruction->base.base, new_bb); 20029 return ir_finish_anal(ira, result); 20030 } 20031 20032 static IrInstGen *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstSrcCondBr *cond_br_instruction) { 20033 IrInstGen *condition = cond_br_instruction->condition->child; 20034 if (type_is_invalid(condition->value->type)) 20035 return ir_unreach_error(ira); 20036 20037 bool is_comptime; 20038 if (!ir_resolve_comptime(ira, cond_br_instruction->is_comptime->child, &is_comptime)) 20039 return ir_unreach_error(ira); 20040 20041 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 20042 IrInstGen *casted_condition = ir_implicit_cast(ira, condition, bool_type); 20043 if (type_is_invalid(casted_condition->value->type)) 20044 return ir_unreach_error(ira); 20045 20046 if (is_comptime || instr_is_comptime(casted_condition)) { 20047 bool cond_is_true; 20048 if (!ir_resolve_bool(ira, casted_condition, &cond_is_true)) 20049 return ir_unreach_error(ira); 20050 20051 IrBasicBlockSrc *old_dest_block = cond_is_true ? 20052 cond_br_instruction->then_block : cond_br_instruction->else_block; 20053 20054 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) 20055 return ir_inline_bb(ira, &cond_br_instruction->base.base, old_dest_block); 20056 20057 IrBasicBlockGen *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base.base); 20058 if (new_dest_block == nullptr) 20059 return ir_unreach_error(ira); 20060 20061 ir_push_resume_block(ira, old_dest_block); 20062 20063 IrInstGen *result = ir_build_br_gen(ira, &cond_br_instruction->base.base, new_dest_block); 20064 return ir_finish_anal(ira, result); 20065 } 20066 20067 assert(cond_br_instruction->then_block != cond_br_instruction->else_block); 20068 IrBasicBlockGen *new_then_block = ir_get_new_bb_runtime(ira, cond_br_instruction->then_block, &cond_br_instruction->base.base); 20069 if (new_then_block == nullptr) 20070 return ir_unreach_error(ira); 20071 20072 IrBasicBlockGen *new_else_block = ir_get_new_bb_runtime(ira, cond_br_instruction->else_block, &cond_br_instruction->base.base); 20073 if (new_else_block == nullptr) 20074 return ir_unreach_error(ira); 20075 20076 ir_push_resume_block(ira, cond_br_instruction->else_block); 20077 ir_push_resume_block(ira, cond_br_instruction->then_block); 20078 20079 IrInstGen *result = ir_build_cond_br_gen(ira, &cond_br_instruction->base.base, 20080 casted_condition, new_then_block, new_else_block); 20081 return ir_finish_anal(ira, result); 20082 } 20083 20084 static IrInstGen *ir_analyze_instruction_unreachable(IrAnalyze *ira, 20085 IrInstSrcUnreachable *unreachable_instruction) 20086 { 20087 IrInstGen *result = ir_build_unreachable_gen(ira, &unreachable_instruction->base.base); 20088 return ir_finish_anal(ira, result); 20089 } 20090 20091 static IrInstGen *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstSrcPhi *phi_instruction) { 20092 Error err; 20093 20094 if (ira->const_predecessor_bb) { 20095 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 20096 IrBasicBlockSrc *predecessor = phi_instruction->incoming_blocks[i]; 20097 if (predecessor != ira->const_predecessor_bb) 20098 continue; 20099 IrInstGen *value = phi_instruction->incoming_values[i]->child; 20100 assert(value->value->type); 20101 if (type_is_invalid(value->value->type)) 20102 return ira->codegen->invalid_inst_gen; 20103 20104 if (value->value->special != ConstValSpecialRuntime) { 20105 IrInstGen *result = ir_const(ira, &phi_instruction->base.base, nullptr); 20106 copy_const_val(ira->codegen, result->value, value->value); 20107 return result; 20108 } else { 20109 return value; 20110 } 20111 } 20112 zig_unreachable(); 20113 } 20114 20115 ResultLocPeerParent *peer_parent = phi_instruction->peer_parent; 20116 if (peer_parent != nullptr && !peer_parent->skipped && !peer_parent->done_resuming && 20117 peer_parent->peers.length >= 2) 20118 { 20119 if (peer_parent->resolved_type == nullptr) { 20120 IrInstGen **instructions = heap::c_allocator.allocate<IrInstGen *>(peer_parent->peers.length); 20121 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 20122 ResultLocPeer *this_peer = peer_parent->peers.at(i); 20123 20124 IrInstGen *gen_instruction = this_peer->base.gen_instruction; 20125 if (gen_instruction == nullptr) { 20126 // unreachable instructions will cause implicit_elem_type to be null 20127 if (this_peer->base.implicit_elem_type == nullptr) { 20128 instructions[i] = ir_const_unreachable(ira, &this_peer->base.source_instruction->base); 20129 } else { 20130 instructions[i] = ir_const(ira, &this_peer->base.source_instruction->base, 20131 this_peer->base.implicit_elem_type); 20132 instructions[i]->value->special = ConstValSpecialRuntime; 20133 } 20134 } else { 20135 instructions[i] = gen_instruction; 20136 } 20137 20138 } 20139 ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base.base, peer_parent->parent); 20140 peer_parent->resolved_type = ir_resolve_peer_types(ira, 20141 peer_parent->base.source_instruction->base.source_node, expected_type, instructions, 20142 peer_parent->peers.length); 20143 if (type_is_invalid(peer_parent->resolved_type)) 20144 return ira->codegen->invalid_inst_gen; 20145 20146 // the logic below assumes there are no instructions in the new current basic block yet 20147 ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base.base); 20148 20149 // In case resolving the parent activates a suspend, do it now 20150 IrInstGen *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base.base, peer_parent->parent, 20151 peer_parent->resolved_type, nullptr, false, true); 20152 if (parent_result_loc != nullptr && 20153 (type_is_invalid(parent_result_loc->value->type) || parent_result_loc->value->type->id == ZigTypeIdUnreachable)) 20154 { 20155 return parent_result_loc; 20156 } 20157 // If the above code generated any instructions in the current basic block, we need 20158 // to move them to the peer parent predecessor. 20159 ZigList<IrInstGen *> instrs_to_move = {}; 20160 while (ira->new_irb.current_basic_block->instruction_list.length != 0) { 20161 instrs_to_move.append(ira->new_irb.current_basic_block->instruction_list.pop()); 20162 } 20163 if (instrs_to_move.length != 0) { 20164 IrBasicBlockGen *predecessor = peer_parent->base.source_instruction->child->owner_bb; 20165 IrInstGen *branch_instruction = predecessor->instruction_list.pop(); 20166 ir_assert(branch_instruction->value->type->id == ZigTypeIdUnreachable, &phi_instruction->base.base); 20167 while (instrs_to_move.length != 0) { 20168 predecessor->instruction_list.append(instrs_to_move.pop()); 20169 } 20170 predecessor->instruction_list.append(branch_instruction); 20171 } 20172 } 20173 20174 IrSuspendPosition suspend_pos; 20175 ira_suspend(ira, &phi_instruction->base.base, nullptr, &suspend_pos); 20176 ir_push_resume(ira, suspend_pos); 20177 20178 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 20179 ResultLocPeer *opposite_peer = peer_parent->peers.at(peer_parent->peers.length - i - 1); 20180 if (opposite_peer->base.implicit_elem_type != nullptr && 20181 opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) 20182 { 20183 ir_push_resume(ira, opposite_peer->suspend_pos); 20184 } 20185 } 20186 20187 peer_parent->done_resuming = true; 20188 return ira_resume(ira); 20189 } 20190 20191 ZigList<IrBasicBlockGen*> new_incoming_blocks = {0}; 20192 ZigList<IrInstGen*> new_incoming_values = {0}; 20193 20194 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 20195 IrBasicBlockSrc *predecessor = phi_instruction->incoming_blocks[i]; 20196 if (predecessor->ref_count == 0) 20197 continue; 20198 20199 20200 IrInstSrc *old_value = phi_instruction->incoming_values[i]; 20201 assert(old_value); 20202 IrInstGen *new_value = old_value->child; 20203 if (!new_value || new_value->value->type->id == ZigTypeIdUnreachable || predecessor->child == nullptr) 20204 continue; 20205 20206 if (type_is_invalid(new_value->value->type)) 20207 return ira->codegen->invalid_inst_gen; 20208 20209 20210 assert(predecessor->child); 20211 new_incoming_blocks.append(predecessor->child); 20212 new_incoming_values.append(new_value); 20213 } 20214 20215 if (new_incoming_blocks.length == 0) { 20216 IrInstGen *result = ir_build_unreachable_gen(ira, &phi_instruction->base.base); 20217 return ir_finish_anal(ira, result); 20218 } 20219 20220 if (new_incoming_blocks.length == 1) { 20221 return new_incoming_values.at(0); 20222 } 20223 20224 ZigType *resolved_type = nullptr; 20225 if (peer_parent != nullptr) { 20226 bool peer_parent_has_type; 20227 if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) 20228 return ira->codegen->invalid_inst_gen; 20229 if (peer_parent_has_type) { 20230 if (peer_parent->parent->id == ResultLocIdReturn) { 20231 resolved_type = ira->explicit_return_type; 20232 } else if (peer_parent->parent->id == ResultLocIdCast) { 20233 resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child); 20234 } else if (peer_parent->parent->resolved_loc) { 20235 ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value->type; 20236 ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base.base); 20237 resolved_type = resolved_loc_ptr_type->data.pointer.child_type; 20238 } 20239 20240 if (resolved_type != nullptr && type_is_invalid(resolved_type)) 20241 return ira->codegen->invalid_inst_gen; 20242 } 20243 } 20244 20245 if (resolved_type == nullptr) { 20246 resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.base.source_node, nullptr, 20247 new_incoming_values.items, new_incoming_values.length); 20248 if (type_is_invalid(resolved_type)) 20249 return ira->codegen->invalid_inst_gen; 20250 } 20251 20252 switch (type_has_one_possible_value(ira->codegen, resolved_type)) { 20253 case OnePossibleValueInvalid: 20254 return ira->codegen->invalid_inst_gen; 20255 case OnePossibleValueYes: 20256 return ir_const_move(ira, &phi_instruction->base.base, 20257 get_the_one_possible_value(ira->codegen, resolved_type)); 20258 case OnePossibleValueNo: 20259 break; 20260 } 20261 20262 switch (type_requires_comptime(ira->codegen, resolved_type)) { 20263 case ReqCompTimeInvalid: 20264 return ira->codegen->invalid_inst_gen; 20265 case ReqCompTimeYes: 20266 ir_add_error(ira, &phi_instruction->base.base, 20267 buf_sprintf("values of type '%s' must be comptime known", buf_ptr(&resolved_type->name))); 20268 return ira->codegen->invalid_inst_gen; 20269 case ReqCompTimeNo: 20270 break; 20271 } 20272 20273 bool all_stack_ptrs = (resolved_type->id == ZigTypeIdPointer); 20274 20275 // cast all values to the resolved type. however we can't put cast instructions in front of the phi instruction. 20276 // so we go back and insert the casts as the last instruction in the corresponding predecessor blocks, and 20277 // then make sure the branch instruction is preserved. 20278 IrBasicBlockGen *cur_bb = ira->new_irb.current_basic_block; 20279 for (size_t i = 0; i < new_incoming_values.length; i += 1) { 20280 IrInstGen *new_value = new_incoming_values.at(i); 20281 IrBasicBlockGen *predecessor = new_incoming_blocks.at(i); 20282 ir_assert(predecessor->instruction_list.length != 0, &phi_instruction->base.base); 20283 IrInstGen *branch_instruction = predecessor->instruction_list.pop(); 20284 ir_set_cursor_at_end_gen(&ira->new_irb, predecessor); 20285 IrInstGen *casted_value = ir_implicit_cast(ira, new_value, resolved_type); 20286 if (type_is_invalid(casted_value->value->type)) { 20287 return ira->codegen->invalid_inst_gen; 20288 } 20289 new_incoming_values.items[i] = casted_value; 20290 predecessor->instruction_list.append(branch_instruction); 20291 20292 if (all_stack_ptrs && (casted_value->value->special != ConstValSpecialRuntime || 20293 casted_value->value->data.rh_ptr != RuntimeHintPtrStack)) 20294 { 20295 all_stack_ptrs = false; 20296 } 20297 } 20298 ir_set_cursor_at_end_gen(&ira->new_irb, cur_bb); 20299 20300 IrInstGen *result = ir_build_phi_gen(ira, &phi_instruction->base.base, 20301 new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items, resolved_type); 20302 20303 if (all_stack_ptrs) { 20304 assert(result->value->special == ConstValSpecialRuntime); 20305 result->value->data.rh_ptr = RuntimeHintPtrStack; 20306 } 20307 20308 return result; 20309 } 20310 20311 static IrInstGen *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstSrcVarPtr *instruction) { 20312 ZigVar *var = instruction->var; 20313 IrInstGen *result = ir_get_var_ptr(ira, &instruction->base.base, var); 20314 if (instruction->crossed_fndef_scope != nullptr && !instr_is_comptime(result)) { 20315 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 20316 buf_sprintf("'%s' not accessible from inner function", var->name)); 20317 add_error_note(ira->codegen, msg, instruction->crossed_fndef_scope->base.source_node, 20318 buf_sprintf("crossed function definition here")); 20319 add_error_note(ira->codegen, msg, var->decl_node, 20320 buf_sprintf("declared here")); 20321 return ira->codegen->invalid_inst_gen; 20322 } 20323 return result; 20324 } 20325 20326 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align) { 20327 assert(ptr_type->id == ZigTypeIdPointer); 20328 return get_pointer_to_type_extra2(g, 20329 ptr_type->data.pointer.child_type, 20330 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 20331 ptr_type->data.pointer.ptr_len, 20332 new_align, 20333 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 20334 ptr_type->data.pointer.allow_zero, 20335 ptr_type->data.pointer.vector_index, 20336 ptr_type->data.pointer.inferred_struct_field, 20337 ptr_type->data.pointer.sentinel); 20338 } 20339 20340 static ZigType *adjust_ptr_sentinel(CodeGen *g, ZigType *ptr_type, ZigValue *new_sentinel) { 20341 assert(ptr_type->id == ZigTypeIdPointer); 20342 return get_pointer_to_type_extra2(g, 20343 ptr_type->data.pointer.child_type, 20344 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 20345 ptr_type->data.pointer.ptr_len, 20346 ptr_type->data.pointer.explicit_alignment, 20347 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 20348 ptr_type->data.pointer.allow_zero, 20349 ptr_type->data.pointer.vector_index, 20350 ptr_type->data.pointer.inferred_struct_field, 20351 new_sentinel); 20352 } 20353 20354 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) { 20355 assert(is_slice(slice_type)); 20356 ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index]->type_entry, 20357 new_align); 20358 return get_slice_type(g, ptr_type); 20359 } 20360 20361 static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) { 20362 assert(ptr_type->id == ZigTypeIdPointer); 20363 return get_pointer_to_type_extra(g, 20364 ptr_type->data.pointer.child_type, 20365 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 20366 ptr_len, 20367 ptr_type->data.pointer.explicit_alignment, 20368 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 20369 ptr_type->data.pointer.allow_zero); 20370 } 20371 20372 static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemPtr *elem_ptr_instruction) { 20373 Error err; 20374 IrInstGen *array_ptr = elem_ptr_instruction->array_ptr->child; 20375 if (type_is_invalid(array_ptr->value->type)) 20376 return ira->codegen->invalid_inst_gen; 20377 20378 IrInstGen *elem_index = elem_ptr_instruction->elem_index->child; 20379 if (type_is_invalid(elem_index->value->type)) 20380 return ira->codegen->invalid_inst_gen; 20381 20382 ZigValue *orig_array_ptr_val = array_ptr->value; 20383 20384 ZigType *ptr_type = orig_array_ptr_val->type; 20385 assert(ptr_type->id == ZigTypeIdPointer); 20386 20387 ZigType *array_type = ptr_type->data.pointer.child_type; 20388 20389 // At first return_type will be the pointer type we want to return, except with an optimistic alignment. 20390 // We will adjust return_type's alignment before returning it. 20391 ZigType *return_type; 20392 20393 if (type_is_invalid(array_type)) 20394 return ira->codegen->invalid_inst_gen; 20395 20396 if (array_type->id == ZigTypeIdPointer && 20397 array_type->data.pointer.ptr_len == PtrLenSingle && 20398 array_type->data.pointer.child_type->id == ZigTypeIdArray) 20399 { 20400 IrInstGen *ptr_value = ir_get_deref(ira, &elem_ptr_instruction->base.base, 20401 array_ptr, nullptr); 20402 if (type_is_invalid(ptr_value->value->type)) 20403 return ira->codegen->invalid_inst_gen; 20404 20405 array_type = array_type->data.pointer.child_type; 20406 ptr_type = ptr_type->data.pointer.child_type; 20407 20408 orig_array_ptr_val = ptr_value->value; 20409 } 20410 20411 if (array_type->id == ZigTypeIdArray) { 20412 if (array_type->data.array.len == 0) { 20413 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 20414 buf_sprintf("index 0 outside array of size 0")); 20415 return ira->codegen->invalid_inst_gen; 20416 } 20417 ZigType *child_type = array_type->data.array.child_type; 20418 if (ptr_type->data.pointer.host_int_bytes == 0) { 20419 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 20420 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 20421 elem_ptr_instruction->ptr_len, 20422 ptr_type->data.pointer.explicit_alignment, 0, 0, false); 20423 } else { 20424 uint64_t elem_val_scalar; 20425 if (!ir_resolve_usize(ira, elem_index, &elem_val_scalar)) 20426 return ira->codegen->invalid_inst_gen; 20427 20428 size_t bit_width = type_size_bits(ira->codegen, child_type); 20429 size_t bit_offset = bit_width * elem_val_scalar; 20430 20431 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 20432 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 20433 elem_ptr_instruction->ptr_len, 20434 1, (uint32_t)bit_offset, ptr_type->data.pointer.host_int_bytes, false); 20435 } 20436 } else if (array_type->id == ZigTypeIdPointer) { 20437 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 20438 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 20439 buf_sprintf("index of single-item pointer")); 20440 return ira->codegen->invalid_inst_gen; 20441 } 20442 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len); 20443 } else if (is_slice(array_type)) { 20444 return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index]->type_entry, 20445 elem_ptr_instruction->ptr_len); 20446 } else if (array_type->id == ZigTypeIdVector) { 20447 // This depends on whether the element index is comptime, so it is computed later. 20448 return_type = nullptr; 20449 } else if (elem_ptr_instruction->init_array_type_source_node != nullptr && 20450 array_type->id == ZigTypeIdStruct && 20451 array_type->data.structure.resolve_status == ResolveStatusBeingInferred) 20452 { 20453 ZigType *usize = ira->codegen->builtin_types.entry_usize; 20454 IrInstGen *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); 20455 if (type_is_invalid(casted_elem_index->value->type)) 20456 return ira->codegen->invalid_inst_gen; 20457 ir_assert(instr_is_comptime(casted_elem_index), &elem_ptr_instruction->base.base); 20458 Buf *field_name = buf_alloc(); 20459 bigint_append_buf(field_name, &casted_elem_index->value->data.x_bigint, 10); 20460 return ir_analyze_inferred_field_ptr(ira, field_name, &elem_ptr_instruction->base.base, 20461 array_ptr, array_type); 20462 } else if (is_tuple(array_type)) { 20463 uint64_t elem_index_scalar; 20464 if (!ir_resolve_usize(ira, elem_index, &elem_index_scalar)) 20465 return ira->codegen->invalid_inst_gen; 20466 if (elem_index_scalar >= array_type->data.structure.src_field_count) { 20467 ir_add_error(ira, &elem_ptr_instruction->base.base, buf_sprintf( 20468 "field index %" ZIG_PRI_u64 " outside tuple '%s' which has %" PRIu32 " fields", 20469 elem_index_scalar, buf_ptr(&array_type->name), 20470 array_type->data.structure.src_field_count)); 20471 return ira->codegen->invalid_inst_gen; 20472 } 20473 TypeStructField *field = array_type->data.structure.fields[elem_index_scalar]; 20474 return ir_analyze_struct_field_ptr(ira, &elem_ptr_instruction->base.base, field, array_ptr, 20475 array_type, false); 20476 } else { 20477 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 20478 buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name))); 20479 return ira->codegen->invalid_inst_gen; 20480 } 20481 20482 ZigType *usize = ira->codegen->builtin_types.entry_usize; 20483 IrInstGen *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); 20484 if (type_is_invalid(casted_elem_index->value->type)) 20485 return ira->codegen->invalid_inst_gen; 20486 20487 bool safety_check_on = elem_ptr_instruction->safety_check_on; 20488 if (instr_is_comptime(casted_elem_index)) { 20489 uint64_t index = bigint_as_u64(&casted_elem_index->value->data.x_bigint); 20490 if (array_type->id == ZigTypeIdArray) { 20491 uint64_t array_len = array_type->data.array.len; 20492 if (index == array_len && array_type->data.array.sentinel != nullptr) { 20493 ZigType *elem_type = array_type->data.array.child_type; 20494 IrInstGen *sentinel_elem = ir_const(ira, &elem_ptr_instruction->base.base, elem_type); 20495 copy_const_val(ira->codegen, sentinel_elem->value, array_type->data.array.sentinel); 20496 return ir_get_ref(ira, &elem_ptr_instruction->base.base, sentinel_elem, true, false); 20497 } 20498 if (index >= array_len) { 20499 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 20500 buf_sprintf("index %" ZIG_PRI_u64 " outside array of size %" ZIG_PRI_u64, 20501 index, array_len)); 20502 return ira->codegen->invalid_inst_gen; 20503 } 20504 safety_check_on = false; 20505 } 20506 if (array_type->id == ZigTypeIdVector) { 20507 ZigType *elem_type = array_type->data.vector.elem_type; 20508 uint32_t host_vec_len = array_type->data.vector.len; 20509 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 20510 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 20511 elem_ptr_instruction->ptr_len, 20512 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, (uint32_t)index, 20513 nullptr, nullptr); 20514 } else if (return_type->data.pointer.explicit_alignment != 0) { 20515 // figure out the largest alignment possible 20516 20517 if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown))) 20518 return ira->codegen->invalid_inst_gen; 20519 20520 uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); 20521 uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); 20522 uint64_t ptr_align = get_ptr_align(ira->codegen, return_type); 20523 20524 uint64_t chosen_align = abi_align; 20525 if (ptr_align >= abi_align) { 20526 while (ptr_align > abi_align) { 20527 if ((index * elem_size) % ptr_align == 0) { 20528 chosen_align = ptr_align; 20529 break; 20530 } 20531 ptr_align >>= 1; 20532 } 20533 } else if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 20534 chosen_align = ptr_align; 20535 } else { 20536 // can't get here because guaranteed elem_size >= abi_align 20537 zig_unreachable(); 20538 } 20539 return_type = adjust_ptr_align(ira->codegen, return_type, chosen_align); 20540 } 20541 20542 // TODO The `array_type->id == ZigTypeIdArray` exception here should not be an exception; 20543 // the `orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar` clause should be omitted completely. 20544 // However there are bugs to fix before this improvement can be made. 20545 if (orig_array_ptr_val->special != ConstValSpecialRuntime && 20546 orig_array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && 20547 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == ZigTypeIdArray)) 20548 { 20549 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 20550 elem_ptr_instruction->base.base.source_node, orig_array_ptr_val, UndefBad))) 20551 { 20552 return ira->codegen->invalid_inst_gen; 20553 } 20554 20555 ZigValue *array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val, 20556 elem_ptr_instruction->base.base.source_node); 20557 if (array_ptr_val == nullptr) 20558 return ira->codegen->invalid_inst_gen; 20559 20560 if (array_ptr_val->special == ConstValSpecialUndef && 20561 elem_ptr_instruction->init_array_type_source_node != nullptr) 20562 { 20563 if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) { 20564 array_ptr_val->data.x_array.special = ConstArraySpecialNone; 20565 array_ptr_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(array_type->data.array.len); 20566 array_ptr_val->special = ConstValSpecialStatic; 20567 for (size_t i = 0; i < array_type->data.array.len; i += 1) { 20568 ZigValue *elem_val = &array_ptr_val->data.x_array.data.s_none.elements[i]; 20569 elem_val->special = ConstValSpecialUndef; 20570 elem_val->type = array_type->data.array.child_type; 20571 elem_val->parent.id = ConstParentIdArray; 20572 elem_val->parent.data.p_array.array_val = array_ptr_val; 20573 elem_val->parent.data.p_array.elem_index = i; 20574 } 20575 } else if (is_slice(array_type)) { 20576 ir_assert(array_ptr->value->type->id == ZigTypeIdPointer, &elem_ptr_instruction->base.base); 20577 ZigType *actual_array_type = array_ptr->value->type->data.pointer.child_type; 20578 20579 if (type_is_invalid(actual_array_type)) 20580 return ira->codegen->invalid_inst_gen; 20581 if (actual_array_type->id != ZigTypeIdArray) { 20582 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, 20583 buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", 20584 buf_ptr(&actual_array_type->name))); 20585 return ira->codegen->invalid_inst_gen; 20586 } 20587 20588 ZigValue *array_init_val = ira->codegen->pass1_arena->create<ZigValue>(); 20589 array_init_val->special = ConstValSpecialStatic; 20590 array_init_val->type = actual_array_type; 20591 array_init_val->data.x_array.special = ConstArraySpecialNone; 20592 array_init_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(actual_array_type->data.array.len); 20593 array_init_val->special = ConstValSpecialStatic; 20594 for (size_t i = 0; i < actual_array_type->data.array.len; i += 1) { 20595 ZigValue *elem_val = &array_init_val->data.x_array.data.s_none.elements[i]; 20596 elem_val->special = ConstValSpecialUndef; 20597 elem_val->type = actual_array_type->data.array.child_type; 20598 elem_val->parent.id = ConstParentIdArray; 20599 elem_val->parent.data.p_array.array_val = array_init_val; 20600 elem_val->parent.data.p_array.elem_index = i; 20601 } 20602 20603 init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len, 20604 false); 20605 array_ptr_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutInfer; 20606 } else { 20607 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, 20608 buf_sprintf("expected array type or [_], found '%s'", 20609 buf_ptr(&array_type->name))); 20610 return ira->codegen->invalid_inst_gen; 20611 } 20612 } 20613 20614 if (array_ptr_val->special != ConstValSpecialRuntime && 20615 (array_type->id != ZigTypeIdPointer || 20616 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) 20617 { 20618 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 20619 elem_ptr_instruction->base.base.source_node, array_ptr_val, UndefOk))) 20620 { 20621 return ira->codegen->invalid_inst_gen; 20622 } 20623 if (array_type->id == ZigTypeIdPointer) { 20624 IrInstGen *result = ir_const(ira, &elem_ptr_instruction->base.base, return_type); 20625 ZigValue *out_val = result->value; 20626 out_val->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; 20627 size_t new_index; 20628 size_t mem_size; 20629 size_t old_size; 20630 switch (array_ptr_val->data.x_ptr.special) { 20631 case ConstPtrSpecialInvalid: 20632 case ConstPtrSpecialDiscard: 20633 zig_unreachable(); 20634 case ConstPtrSpecialRef: 20635 if (array_ptr_val->data.x_ptr.data.ref.pointee->type->id == ZigTypeIdArray) { 20636 ZigValue *array_val = array_ptr_val->data.x_ptr.data.ref.pointee; 20637 new_index = index; 20638 ZigType *array_type = array_val->type; 20639 mem_size = array_type->data.array.len; 20640 if (array_type->data.array.sentinel != nullptr) { 20641 mem_size += 1; 20642 } 20643 old_size = mem_size; 20644 20645 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 20646 out_val->data.x_ptr.data.base_array.array_val = array_val; 20647 out_val->data.x_ptr.data.base_array.elem_index = new_index; 20648 } else { 20649 mem_size = 1; 20650 old_size = 1; 20651 new_index = index; 20652 20653 out_val->data.x_ptr.special = ConstPtrSpecialRef; 20654 out_val->data.x_ptr.data.ref.pointee = array_ptr_val->data.x_ptr.data.ref.pointee; 20655 } 20656 break; 20657 case ConstPtrSpecialBaseArray: 20658 { 20659 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index; 20660 new_index = offset + index; 20661 ZigType *array_type = array_ptr_val->data.x_ptr.data.base_array.array_val->type; 20662 mem_size = array_type->data.array.len; 20663 if (array_type->data.array.sentinel != nullptr) { 20664 mem_size += 1; 20665 } 20666 old_size = mem_size - offset; 20667 20668 assert(array_ptr_val->data.x_ptr.data.base_array.array_val); 20669 20670 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 20671 out_val->data.x_ptr.data.base_array.array_val = 20672 array_ptr_val->data.x_ptr.data.base_array.array_val; 20673 out_val->data.x_ptr.data.base_array.elem_index = new_index; 20674 20675 break; 20676 } 20677 case ConstPtrSpecialBaseStruct: 20678 zig_panic("TODO elem ptr on a const inner struct"); 20679 case ConstPtrSpecialBaseErrorUnionCode: 20680 zig_panic("TODO elem ptr on a const inner error union code"); 20681 case ConstPtrSpecialBaseErrorUnionPayload: 20682 zig_panic("TODO elem ptr on a const inner error union payload"); 20683 case ConstPtrSpecialBaseOptionalPayload: 20684 zig_panic("TODO elem ptr on a const inner optional payload"); 20685 case ConstPtrSpecialHardCodedAddr: 20686 zig_unreachable(); 20687 case ConstPtrSpecialFunction: 20688 zig_panic("TODO element ptr of a function casted to a ptr"); 20689 case ConstPtrSpecialNull: 20690 zig_panic("TODO elem ptr on a null pointer"); 20691 } 20692 if (new_index >= mem_size) { 20693 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 20694 buf_sprintf("index %" ZIG_PRI_u64 " outside pointer of size %" ZIG_PRI_usize "", index, old_size)); 20695 return ira->codegen->invalid_inst_gen; 20696 } 20697 return result; 20698 } else if (is_slice(array_type)) { 20699 ZigValue *ptr_field = array_ptr_val->data.x_struct.fields[slice_ptr_index]; 20700 ir_assert(ptr_field != nullptr, &elem_ptr_instruction->base.base); 20701 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 20702 return ir_build_elem_ptr_gen(ira, elem_ptr_instruction->base.base.scope, 20703 elem_ptr_instruction->base.base.source_node, array_ptr, casted_elem_index, false, 20704 return_type); 20705 } 20706 ZigValue *len_field = array_ptr_val->data.x_struct.fields[slice_len_index]; 20707 IrInstGen *result = ir_const(ira, &elem_ptr_instruction->base.base, return_type); 20708 ZigValue *out_val = result->value; 20709 ZigType *slice_ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; 20710 uint64_t slice_len = bigint_as_u64(&len_field->data.x_bigint); 20711 uint64_t full_slice_len = slice_len + 20712 ((slice_ptr_type->data.pointer.sentinel != nullptr) ? 1 : 0); 20713 if (index >= full_slice_len) { 20714 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 20715 buf_sprintf("index %" ZIG_PRI_u64 " outside slice of size %" ZIG_PRI_u64, 20716 index, slice_len)); 20717 return ira->codegen->invalid_inst_gen; 20718 } 20719 out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut; 20720 switch (ptr_field->data.x_ptr.special) { 20721 case ConstPtrSpecialInvalid: 20722 case ConstPtrSpecialDiscard: 20723 zig_unreachable(); 20724 case ConstPtrSpecialRef: 20725 out_val->data.x_ptr.special = ConstPtrSpecialRef; 20726 out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee; 20727 break; 20728 case ConstPtrSpecialBaseArray: 20729 { 20730 size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index; 20731 uint64_t new_index = offset + index; 20732 if (ptr_field->data.x_ptr.data.base_array.array_val->data.x_array.special != 20733 ConstArraySpecialBuf) 20734 { 20735 ir_assert(new_index < 20736 ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len, 20737 &elem_ptr_instruction->base.base); 20738 } 20739 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 20740 out_val->data.x_ptr.data.base_array.array_val = 20741 ptr_field->data.x_ptr.data.base_array.array_val; 20742 out_val->data.x_ptr.data.base_array.elem_index = new_index; 20743 break; 20744 } 20745 case ConstPtrSpecialBaseStruct: 20746 zig_panic("TODO elem ptr on a slice backed by const inner struct"); 20747 case ConstPtrSpecialBaseErrorUnionCode: 20748 zig_panic("TODO elem ptr on a slice backed by const inner error union code"); 20749 case ConstPtrSpecialBaseErrorUnionPayload: 20750 zig_panic("TODO elem ptr on a slice backed by const inner error union payload"); 20751 case ConstPtrSpecialBaseOptionalPayload: 20752 zig_panic("TODO elem ptr on a slice backed by const optional payload"); 20753 case ConstPtrSpecialHardCodedAddr: 20754 zig_unreachable(); 20755 case ConstPtrSpecialFunction: 20756 zig_panic("TODO elem ptr on a slice that was ptrcast from a function"); 20757 case ConstPtrSpecialNull: 20758 zig_panic("TODO elem ptr on a slice has a null pointer"); 20759 } 20760 return result; 20761 } else if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) { 20762 IrInstGen *result; 20763 if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 20764 result = ir_build_elem_ptr_gen(ira, elem_ptr_instruction->base.base.scope, 20765 elem_ptr_instruction->base.base.source_node, array_ptr, casted_elem_index, 20766 false, return_type); 20767 result->value->special = ConstValSpecialStatic; 20768 } else { 20769 result = ir_const(ira, &elem_ptr_instruction->base.base, return_type); 20770 } 20771 ZigValue *out_val = result->value; 20772 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 20773 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; 20774 out_val->data.x_ptr.data.base_array.array_val = array_ptr_val; 20775 out_val->data.x_ptr.data.base_array.elem_index = index; 20776 return result; 20777 } else { 20778 zig_unreachable(); 20779 } 20780 } 20781 } 20782 } else if (array_type->id == ZigTypeIdVector) { 20783 // runtime known element index 20784 ZigType *elem_type = array_type->data.vector.elem_type; 20785 uint32_t host_vec_len = array_type->data.vector.len; 20786 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 20787 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 20788 elem_ptr_instruction->ptr_len, 20789 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, VECTOR_INDEX_RUNTIME, 20790 nullptr, nullptr); 20791 } else { 20792 // runtime known element index 20793 switch (type_requires_comptime(ira->codegen, return_type)) { 20794 case ReqCompTimeYes: 20795 ir_add_error(ira, &elem_index->base, 20796 buf_sprintf("values of type '%s' must be comptime known, but index value is runtime known", 20797 buf_ptr(&return_type->data.pointer.child_type->name))); 20798 return ira->codegen->invalid_inst_gen; 20799 case ReqCompTimeInvalid: 20800 return ira->codegen->invalid_inst_gen; 20801 case ReqCompTimeNo: 20802 break; 20803 } 20804 20805 if (return_type->data.pointer.explicit_alignment != 0) { 20806 if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown))) 20807 return ira->codegen->invalid_inst_gen; 20808 20809 uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); 20810 uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); 20811 uint64_t ptr_align = get_ptr_align(ira->codegen, return_type); 20812 if (ptr_align < abi_align) { 20813 if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 20814 return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align); 20815 } else { 20816 // can't get here because guaranteed elem_size >= abi_align 20817 zig_unreachable(); 20818 } 20819 } else { 20820 return_type = adjust_ptr_align(ira->codegen, return_type, abi_align); 20821 } 20822 } 20823 } 20824 20825 return ir_build_elem_ptr_gen(ira, elem_ptr_instruction->base.base.scope, 20826 elem_ptr_instruction->base.base.source_node, array_ptr, casted_elem_index, safety_check_on, return_type); 20827 } 20828 20829 static IrInstGen *ir_analyze_container_member_access_inner(IrAnalyze *ira, 20830 ZigType *bare_struct_type, Buf *field_name, IrInst* source_instr, 20831 IrInstGen *container_ptr, IrInst *container_ptr_src, ZigType *container_type) 20832 { 20833 if (!is_slice(bare_struct_type)) { 20834 ScopeDecls *container_scope = get_container_scope(bare_struct_type); 20835 assert(container_scope != nullptr); 20836 auto tld = find_container_decl(ira->codegen, container_scope, field_name); 20837 if (tld) { 20838 if (tld->id == TldIdFn) { 20839 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); 20840 if (tld->resolution == TldResolutionInvalid) 20841 return ira->codegen->invalid_inst_gen; 20842 if (tld->resolution == TldResolutionResolving) 20843 return ir_error_dependency_loop(ira, source_instr); 20844 20845 TldFn *tld_fn = (TldFn *)tld; 20846 ZigFn *fn_entry = tld_fn->fn_entry; 20847 assert(fn_entry != nullptr); 20848 20849 if (type_is_invalid(fn_entry->type_entry)) 20850 return ira->codegen->invalid_inst_gen; 20851 20852 IrInstGen *bound_fn_value = ir_const_bound_fn(ira, source_instr, fn_entry, container_ptr, 20853 container_ptr_src); 20854 return ir_get_ref(ira, source_instr, bound_fn_value, true, false); 20855 } else if (tld->id == TldIdVar) { 20856 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); 20857 if (tld->resolution == TldResolutionInvalid) 20858 return ira->codegen->invalid_inst_gen; 20859 if (tld->resolution == TldResolutionResolving) 20860 return ir_error_dependency_loop(ira, source_instr); 20861 20862 TldVar *tld_var = (TldVar *)tld; 20863 ZigVar *var = tld_var->var; 20864 assert(var != nullptr); 20865 20866 if (type_is_invalid(var->var_type)) 20867 return ira->codegen->invalid_inst_gen; 20868 20869 if (var->const_value->type->id == ZigTypeIdFn) { 20870 ir_assert(var->const_value->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); 20871 ZigFn *fn = var->const_value->data.x_ptr.data.fn.fn_entry; 20872 IrInstGen *bound_fn_value = ir_const_bound_fn(ira, source_instr, fn, container_ptr, 20873 container_ptr_src); 20874 return ir_get_ref(ira, source_instr, bound_fn_value, true, false); 20875 } 20876 } 20877 } 20878 } 20879 const char *prefix_name; 20880 if (is_slice(bare_struct_type)) { 20881 prefix_name = ""; 20882 } else if (bare_struct_type->id == ZigTypeIdStruct) { 20883 prefix_name = "struct "; 20884 } else if (bare_struct_type->id == ZigTypeIdEnum) { 20885 prefix_name = "enum "; 20886 } else if (bare_struct_type->id == ZigTypeIdUnion) { 20887 prefix_name = "union "; 20888 } else { 20889 prefix_name = ""; 20890 } 20891 ir_add_error_node(ira, source_instr->source_node, 20892 buf_sprintf("no member named '%s' in %s'%s'", buf_ptr(field_name), prefix_name, buf_ptr(&bare_struct_type->name))); 20893 return ira->codegen->invalid_inst_gen; 20894 } 20895 20896 static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field) { 20897 if (field->init_val != nullptr) return; 20898 if (field->decl_node->type != NodeTypeStructField) return; 20899 AstNode *init_node = field->decl_node->data.struct_field.value; 20900 if (init_node == nullptr) return; 20901 // scope is not the scope of the struct init, it's the scope of the struct type decl 20902 Scope *analyze_scope = &get_container_scope(container_type)->base; 20903 // memoize it 20904 field->init_val = analyze_const_value(codegen, analyze_scope, init_node, 20905 field->type_entry, nullptr, UndefOk); 20906 } 20907 20908 static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_instr, 20909 TypeStructField *field, IrInstGen *struct_ptr, ZigType *struct_type, bool initializing) 20910 { 20911 Error err; 20912 ZigType *field_type = resolve_struct_field_type(ira->codegen, field); 20913 if (field_type == nullptr) 20914 return ira->codegen->invalid_inst_gen; 20915 if (field->is_comptime) { 20916 IrInstGen *elem = ir_const(ira, source_instr, field_type); 20917 memoize_field_init_val(ira->codegen, struct_type, field); 20918 copy_const_val(ira->codegen, elem->value, field->init_val); 20919 return ir_get_ref2(ira, source_instr, elem, field_type, true, false); 20920 } 20921 switch (type_has_one_possible_value(ira->codegen, field_type)) { 20922 case OnePossibleValueInvalid: 20923 return ira->codegen->invalid_inst_gen; 20924 case OnePossibleValueYes: { 20925 IrInstGen *elem = ir_const_move(ira, source_instr, 20926 get_the_one_possible_value(ira->codegen, field_type)); 20927 return ir_get_ref(ira, source_instr, elem, false, false); 20928 } 20929 case OnePossibleValueNo: 20930 break; 20931 } 20932 bool is_const = struct_ptr->value->type->data.pointer.is_const; 20933 bool is_volatile = struct_ptr->value->type->data.pointer.is_volatile; 20934 ZigType *ptr_type; 20935 if (is_anon_container(struct_type)) { 20936 ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 20937 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 20938 } else { 20939 ResolveStatus needed_resolve_status = 20940 (struct_type->data.structure.layout == ContainerLayoutAuto) ? 20941 ResolveStatusZeroBitsKnown : ResolveStatusSizeKnown; 20942 if ((err = type_resolve(ira->codegen, struct_type, needed_resolve_status))) 20943 return ira->codegen->invalid_inst_gen; 20944 assert(struct_ptr->value->type->id == ZigTypeIdPointer); 20945 uint32_t ptr_bit_offset = struct_ptr->value->type->data.pointer.bit_offset_in_host; 20946 uint32_t ptr_host_int_bytes = struct_ptr->value->type->data.pointer.host_int_bytes; 20947 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? 20948 get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes; 20949 ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 20950 is_const, is_volatile, PtrLenSingle, field->align, 20951 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), 20952 (uint32_t)host_int_bytes_for_result_type, false); 20953 } 20954 if (instr_is_comptime(struct_ptr)) { 20955 ZigValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad); 20956 if (!ptr_val) 20957 return ira->codegen->invalid_inst_gen; 20958 20959 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 20960 ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 20961 if (struct_val == nullptr) 20962 return ira->codegen->invalid_inst_gen; 20963 if (type_is_invalid(struct_val->type)) 20964 return ira->codegen->invalid_inst_gen; 20965 20966 // This to allow lazy values to be resolved. 20967 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 20968 source_instr->source_node, struct_val, UndefOk))) 20969 { 20970 return ira->codegen->invalid_inst_gen; 20971 } 20972 if (initializing && struct_val->special == ConstValSpecialUndef) { 20973 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count); 20974 struct_val->special = ConstValSpecialStatic; 20975 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) { 20976 ZigValue *field_val = struct_val->data.x_struct.fields[i]; 20977 field_val->special = ConstValSpecialUndef; 20978 field_val->type = resolve_struct_field_type(ira->codegen, 20979 struct_type->data.structure.fields[i]); 20980 field_val->parent.id = ConstParentIdStruct; 20981 field_val->parent.data.p_struct.struct_val = struct_val; 20982 field_val->parent.data.p_struct.field_index = i; 20983 } 20984 } 20985 IrInstGen *result; 20986 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 20987 result = ir_build_struct_field_ptr(ira, source_instr, struct_ptr, field, ptr_type); 20988 result->value->special = ConstValSpecialStatic; 20989 } else { 20990 result = ir_const(ira, source_instr, ptr_type); 20991 } 20992 ZigValue *const_val = result->value; 20993 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; 20994 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 20995 const_val->data.x_ptr.data.base_struct.struct_val = struct_val; 20996 const_val->data.x_ptr.data.base_struct.field_index = field->src_index; 20997 return result; 20998 } 20999 } 21000 return ir_build_struct_field_ptr(ira, source_instr, struct_ptr, field, ptr_type); 21001 } 21002 21003 static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, 21004 IrInst* source_instr, IrInstGen *container_ptr, ZigType *container_type) 21005 { 21006 // The type of the field is not available until a store using this pointer happens. 21007 // So, here we create a special pointer type which has the inferred struct type and 21008 // field name encoded in the type. Later, when there is a store via this pointer, 21009 // the field type will then be available, and the field will be added to the inferred 21010 // struct. 21011 21012 ZigType *container_ptr_type = container_ptr->value->type; 21013 ir_assert(container_ptr_type->id == ZigTypeIdPointer, source_instr); 21014 21015 InferredStructField *inferred_struct_field = heap::c_allocator.create<InferredStructField>(); 21016 inferred_struct_field->inferred_struct_type = container_type; 21017 inferred_struct_field->field_name = field_name; 21018 21019 ZigType *elem_type = ira->codegen->builtin_types.entry_var; 21020 ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 21021 container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile, 21022 PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field, nullptr); 21023 21024 if (instr_is_comptime(container_ptr)) { 21025 ZigValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 21026 if (ptr_val == nullptr) 21027 return ira->codegen->invalid_inst_gen; 21028 21029 IrInstGen *result; 21030 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 21031 result = ir_build_cast(ira, source_instr, container_ptr_type, container_ptr, CastOpNoop); 21032 } else { 21033 result = ir_const(ira, source_instr, field_ptr_type); 21034 } 21035 copy_const_val(ira->codegen, result->value, ptr_val); 21036 result->value->type = field_ptr_type; 21037 return result; 21038 } 21039 21040 return ir_build_cast(ira, source_instr, field_ptr_type, container_ptr, CastOpNoop); 21041 } 21042 21043 static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 21044 IrInst* source_instr, IrInstGen *container_ptr, IrInst *container_ptr_src, 21045 ZigType *container_type, bool initializing) 21046 { 21047 Error err; 21048 21049 ZigType *bare_type = container_ref_type(container_type); 21050 21051 if (initializing && bare_type->id == ZigTypeIdStruct && 21052 bare_type->data.structure.resolve_status == ResolveStatusBeingInferred) 21053 { 21054 return ir_analyze_inferred_field_ptr(ira, field_name, source_instr, container_ptr, bare_type); 21055 } 21056 21057 if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown))) 21058 return ira->codegen->invalid_inst_gen; 21059 21060 assert(container_ptr->value->type->id == ZigTypeIdPointer); 21061 if (bare_type->id == ZigTypeIdStruct) { 21062 TypeStructField *field = find_struct_type_field(bare_type, field_name); 21063 if (field != nullptr) { 21064 return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); 21065 } else { 21066 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 21067 source_instr, container_ptr, container_ptr_src, container_type); 21068 } 21069 } 21070 21071 if (bare_type->id == ZigTypeIdEnum) { 21072 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 21073 source_instr, container_ptr, container_ptr_src, container_type); 21074 } 21075 21076 if (bare_type->id == ZigTypeIdUnion) { 21077 bool is_const = container_ptr->value->type->data.pointer.is_const; 21078 bool is_volatile = container_ptr->value->type->data.pointer.is_volatile; 21079 21080 TypeUnionField *field = find_union_type_field(bare_type, field_name); 21081 if (field == nullptr) { 21082 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 21083 source_instr, container_ptr, container_ptr_src, container_type); 21084 } 21085 21086 ZigType *field_type = resolve_union_field_type(ira->codegen, field); 21087 if (field_type == nullptr) 21088 return ira->codegen->invalid_inst_gen; 21089 21090 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 21091 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 21092 if (instr_is_comptime(container_ptr)) { 21093 ZigValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 21094 if (!ptr_val) 21095 return ira->codegen->invalid_inst_gen; 21096 21097 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && 21098 ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 21099 ZigValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 21100 if (union_val == nullptr) 21101 return ira->codegen->invalid_inst_gen; 21102 if (type_is_invalid(union_val->type)) 21103 return ira->codegen->invalid_inst_gen; 21104 21105 if (initializing) { 21106 ZigValue *payload_val = ira->codegen->pass1_arena->create<ZigValue>(); 21107 payload_val->special = ConstValSpecialUndef; 21108 payload_val->type = field_type; 21109 payload_val->parent.id = ConstParentIdUnion; 21110 payload_val->parent.data.p_union.union_val = union_val; 21111 21112 union_val->special = ConstValSpecialStatic; 21113 bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value); 21114 union_val->data.x_union.payload = payload_val; 21115 } else if (bare_type->data.unionation.layout != ContainerLayoutExtern) { 21116 TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); 21117 if (actual_field == nullptr) 21118 zig_unreachable(); 21119 21120 if (field != actual_field) { 21121 ir_add_error_node(ira, source_instr->source_node, 21122 buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), 21123 buf_ptr(actual_field->name))); 21124 return ira->codegen->invalid_inst_gen; 21125 } 21126 } 21127 21128 ZigValue *payload_val = union_val->data.x_union.payload; 21129 21130 IrInstGen *result; 21131 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 21132 result = ir_build_union_field_ptr(ira, source_instr, container_ptr, field, true, 21133 initializing, ptr_type); 21134 result->value->special = ConstValSpecialStatic; 21135 } else { 21136 result = ir_const(ira, source_instr, ptr_type); 21137 } 21138 ZigValue *const_val = result->value; 21139 const_val->data.x_ptr.special = ConstPtrSpecialRef; 21140 const_val->data.x_ptr.mut = container_ptr->value->data.x_ptr.mut; 21141 const_val->data.x_ptr.data.ref.pointee = payload_val; 21142 return result; 21143 } 21144 } 21145 21146 return ir_build_union_field_ptr(ira, source_instr, container_ptr, field, true, initializing, ptr_type); 21147 } 21148 21149 zig_unreachable(); 21150 } 21151 21152 static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { 21153 bool is_libc = target_is_libc_lib_name(ira->codegen->zig_target, buf_ptr(lib_name)); 21154 if (is_libc && ira->codegen->libc_link_lib == nullptr && !ira->codegen->reported_bad_link_libc_error) { 21155 ir_add_error_node(ira, source_node, 21156 buf_sprintf("dependency on library c must be explicitly specified in the build command")); 21157 ira->codegen->reported_bad_link_libc_error = true; 21158 } 21159 21160 LinkLib *link_lib = add_link_lib(ira->codegen, lib_name); 21161 for (size_t i = 0; i < link_lib->symbols.length; i += 1) { 21162 Buf *existing_symbol_name = link_lib->symbols.at(i); 21163 if (buf_eql_buf(existing_symbol_name, symbol_name)) { 21164 return; 21165 } 21166 } 21167 21168 if (!is_libc && !target_is_wasm(ira->codegen->zig_target) && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) { 21169 ErrorMsg *msg = ir_add_error_node(ira, source_node, 21170 buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code", 21171 buf_ptr(lib_name))); 21172 add_error_note(ira->codegen, msg, source_node, 21173 buf_sprintf("fixed by `--library %s` or `-fPIC`", buf_ptr(lib_name))); 21174 ira->codegen->reported_bad_link_libc_error = true; 21175 } 21176 21177 for (size_t i = 0; i < ira->codegen->forbidden_libs.length; i += 1) { 21178 Buf *forbidden_lib_name = ira->codegen->forbidden_libs.at(i); 21179 if (buf_eql_buf(lib_name, forbidden_lib_name)) { 21180 ir_add_error_node(ira, source_node, 21181 buf_sprintf("linking against forbidden library '%s'", buf_ptr(symbol_name))); 21182 } 21183 } 21184 link_lib->symbols.append(symbol_name); 21185 } 21186 21187 static IrInstGen *ir_error_dependency_loop(IrAnalyze *ira, IrInst* source_instr) { 21188 ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); 21189 return ira->codegen->invalid_inst_gen; 21190 } 21191 21192 static IrInstGen *ir_analyze_decl_ref(IrAnalyze *ira, IrInst* source_instruction, Tld *tld) { 21193 resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node, true); 21194 if (tld->resolution == TldResolutionInvalid) { 21195 return ira->codegen->invalid_inst_gen; 21196 } 21197 if (tld->resolution == TldResolutionResolving) 21198 return ir_error_dependency_loop(ira, source_instruction); 21199 21200 switch (tld->id) { 21201 case TldIdContainer: 21202 case TldIdCompTime: 21203 case TldIdUsingNamespace: 21204 zig_unreachable(); 21205 case TldIdVar: { 21206 TldVar *tld_var = (TldVar *)tld; 21207 ZigVar *var = tld_var->var; 21208 assert(var != nullptr); 21209 21210 if (tld_var->extern_lib_name != nullptr) { 21211 add_link_lib_symbol(ira, tld_var->extern_lib_name, buf_create_from_str(var->name), 21212 source_instruction->source_node); 21213 } 21214 21215 return ir_get_var_ptr(ira, source_instruction, var); 21216 } 21217 case TldIdFn: { 21218 TldFn *tld_fn = (TldFn *)tld; 21219 ZigFn *fn_entry = tld_fn->fn_entry; 21220 assert(fn_entry->type_entry != nullptr); 21221 21222 if (type_is_invalid(fn_entry->type_entry)) 21223 return ira->codegen->invalid_inst_gen; 21224 21225 if (tld_fn->extern_lib_name != nullptr) { 21226 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); 21227 } 21228 21229 IrInstGen *fn_inst = ir_const_fn(ira, source_instruction, fn_entry); 21230 return ir_get_ref(ira, source_instruction, fn_inst, true, false); 21231 } 21232 } 21233 zig_unreachable(); 21234 } 21235 21236 static ErrorTableEntry *find_err_table_entry(ZigType *err_set_type, Buf *field_name) { 21237 assert(err_set_type->id == ZigTypeIdErrorSet); 21238 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 21239 ErrorTableEntry *err_table_entry = err_set_type->data.error_set.errors[i]; 21240 if (buf_eql_buf(&err_table_entry->name, field_name)) { 21241 return err_table_entry; 21242 } 21243 } 21244 return nullptr; 21245 } 21246 21247 static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFieldPtr *field_ptr_instruction) { 21248 Error err; 21249 IrInstGen *container_ptr = field_ptr_instruction->container_ptr->child; 21250 if (type_is_invalid(container_ptr->value->type)) 21251 return ira->codegen->invalid_inst_gen; 21252 21253 ZigType *container_type = container_ptr->value->type->data.pointer.child_type; 21254 21255 Buf *field_name = field_ptr_instruction->field_name_buffer; 21256 if (!field_name) { 21257 IrInstGen *field_name_expr = field_ptr_instruction->field_name_expr->child; 21258 field_name = ir_resolve_str(ira, field_name_expr); 21259 if (!field_name) 21260 return ira->codegen->invalid_inst_gen; 21261 } 21262 21263 21264 AstNode *source_node = field_ptr_instruction->base.base.source_node; 21265 21266 if (type_is_invalid(container_type)) { 21267 return ira->codegen->invalid_inst_gen; 21268 } else if (is_tuple(container_type) && !field_ptr_instruction->initializing && buf_eql_str(field_name, "len")) { 21269 IrInstGen *len_inst = ir_const_unsigned(ira, &field_ptr_instruction->base.base, 21270 container_type->data.structure.src_field_count); 21271 return ir_get_ref(ira, &field_ptr_instruction->base.base, len_inst, true, false); 21272 } else if (is_slice(container_type) || is_container_ref(container_type)) { 21273 assert(container_ptr->value->type->id == ZigTypeIdPointer); 21274 if (container_type->id == ZigTypeIdPointer) { 21275 ZigType *bare_type = container_ref_type(container_type); 21276 IrInstGen *container_child = ir_get_deref(ira, &field_ptr_instruction->base.base, container_ptr, nullptr); 21277 IrInstGen *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base.base, 21278 container_child, &field_ptr_instruction->container_ptr->base, bare_type, 21279 field_ptr_instruction->initializing); 21280 return result; 21281 } else { 21282 IrInstGen *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base.base, 21283 container_ptr, &field_ptr_instruction->container_ptr->base, container_type, 21284 field_ptr_instruction->initializing); 21285 return result; 21286 } 21287 } else if (is_array_ref(container_type) && !field_ptr_instruction->initializing) { 21288 if (buf_eql_str(field_name, "len")) { 21289 ZigValue *len_val = ira->codegen->pass1_arena->create<ZigValue>(); 21290 if (container_type->id == ZigTypeIdPointer) { 21291 init_const_usize(ira->codegen, len_val, container_type->data.pointer.child_type->data.array.len); 21292 } else { 21293 init_const_usize(ira->codegen, len_val, container_type->data.array.len); 21294 } 21295 21296 ZigType *usize = ira->codegen->builtin_types.entry_usize; 21297 bool ptr_is_const = true; 21298 bool ptr_is_volatile = false; 21299 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, len_val, 21300 usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21301 } else { 21302 ir_add_error_node(ira, source_node, 21303 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), 21304 buf_ptr(&container_type->name))); 21305 return ira->codegen->invalid_inst_gen; 21306 } 21307 } else if (container_type->id == ZigTypeIdMetaType) { 21308 ZigValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 21309 if (!container_ptr_val) 21310 return ira->codegen->invalid_inst_gen; 21311 21312 assert(container_ptr->value->type->id == ZigTypeIdPointer); 21313 ZigValue *child_val = const_ptr_pointee(ira, ira->codegen, container_ptr_val, source_node); 21314 if (child_val == nullptr) 21315 return ira->codegen->invalid_inst_gen; 21316 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 21317 field_ptr_instruction->base.base.source_node, child_val, UndefBad))) 21318 { 21319 return ira->codegen->invalid_inst_gen; 21320 } 21321 ZigType *child_type = child_val->data.x_type; 21322 21323 if (type_is_invalid(child_type)) { 21324 return ira->codegen->invalid_inst_gen; 21325 } else if (is_container(child_type)) { 21326 if (child_type->id == ZigTypeIdEnum) { 21327 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) 21328 return ira->codegen->invalid_inst_gen; 21329 21330 TypeEnumField *field = find_enum_type_field(child_type, field_name); 21331 if (field) { 21332 bool ptr_is_const = true; 21333 bool ptr_is_volatile = false; 21334 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21335 create_const_enum(ira->codegen, child_type, &field->value), child_type, 21336 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21337 } 21338 } 21339 ScopeDecls *container_scope = get_container_scope(child_type); 21340 Tld *tld = find_container_decl(ira->codegen, container_scope, field_name); 21341 if (tld) { 21342 if (tld->visib_mod == VisibModPrivate && 21343 tld->import != get_scope_import(field_ptr_instruction->base.base.scope)) 21344 { 21345 ErrorMsg *msg = ir_add_error(ira, &field_ptr_instruction->base.base, 21346 buf_sprintf("'%s' is private", buf_ptr(field_name))); 21347 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); 21348 return ira->codegen->invalid_inst_gen; 21349 } 21350 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base.base, tld); 21351 } 21352 if (child_type->id == ZigTypeIdUnion && 21353 (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr || 21354 child_type->data.unionation.decl_node->data.container_decl.auto_enum)) 21355 { 21356 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) 21357 return ira->codegen->invalid_inst_gen; 21358 TypeUnionField *field = find_union_type_field(child_type, field_name); 21359 if (field) { 21360 ZigType *enum_type = child_type->data.unionation.tag_type; 21361 bool ptr_is_const = true; 21362 bool ptr_is_volatile = false; 21363 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21364 create_const_enum(ira->codegen, enum_type, &field->enum_field->value), enum_type, 21365 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21366 } 21367 } 21368 const char *container_name = (child_type == ira->codegen->root_import) ? 21369 "root source file" : buf_ptr(buf_sprintf("container '%s'", buf_ptr(&child_type->name))); 21370 ir_add_error(ira, &field_ptr_instruction->base.base, 21371 buf_sprintf("%s has no member called '%s'", 21372 container_name, buf_ptr(field_name))); 21373 return ira->codegen->invalid_inst_gen; 21374 } else if (child_type->id == ZigTypeIdErrorSet) { 21375 ErrorTableEntry *err_entry; 21376 ZigType *err_set_type; 21377 if (type_is_global_error_set(child_type)) { 21378 auto existing_entry = ira->codegen->error_table.maybe_get(field_name); 21379 if (existing_entry) { 21380 err_entry = existing_entry->value; 21381 } else { 21382 err_entry = heap::c_allocator.create<ErrorTableEntry>(); 21383 err_entry->decl_node = field_ptr_instruction->base.base.source_node; 21384 buf_init_from_buf(&err_entry->name, field_name); 21385 size_t error_value_count = ira->codegen->errors_by_index.length; 21386 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count)); 21387 err_entry->value = error_value_count; 21388 ira->codegen->errors_by_index.append(err_entry); 21389 ira->codegen->error_table.put(field_name, err_entry); 21390 } 21391 if (err_entry->set_with_only_this_in_it == nullptr) { 21392 err_entry->set_with_only_this_in_it = make_err_set_with_one_item(ira->codegen, 21393 field_ptr_instruction->base.base.scope, field_ptr_instruction->base.base.source_node, 21394 err_entry); 21395 } 21396 err_set_type = err_entry->set_with_only_this_in_it; 21397 } else { 21398 if (!resolve_inferred_error_set(ira->codegen, child_type, field_ptr_instruction->base.base.source_node)) { 21399 return ira->codegen->invalid_inst_gen; 21400 } 21401 err_entry = find_err_table_entry(child_type, field_name); 21402 if (err_entry == nullptr) { 21403 ir_add_error(ira, &field_ptr_instruction->base.base, 21404 buf_sprintf("no error named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&child_type->name))); 21405 return ira->codegen->invalid_inst_gen; 21406 } 21407 err_set_type = child_type; 21408 } 21409 ZigValue *const_val = ira->codegen->pass1_arena->create<ZigValue>(); 21410 const_val->special = ConstValSpecialStatic; 21411 const_val->type = err_set_type; 21412 const_val->data.x_err_set = err_entry; 21413 21414 bool ptr_is_const = true; 21415 bool ptr_is_volatile = false; 21416 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, const_val, 21417 err_set_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21418 } else if (child_type->id == ZigTypeIdInt) { 21419 if (buf_eql_str(field_name, "bit_count")) { 21420 bool ptr_is_const = true; 21421 bool ptr_is_volatile = false; 21422 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21423 create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int, 21424 child_type->data.integral.bit_count, false), 21425 ira->codegen->builtin_types.entry_num_lit_int, 21426 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21427 } else if (buf_eql_str(field_name, "is_signed")) { 21428 bool ptr_is_const = true; 21429 bool ptr_is_volatile = false; 21430 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21431 create_const_bool(ira->codegen, child_type->data.integral.is_signed), 21432 ira->codegen->builtin_types.entry_bool, 21433 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21434 } else { 21435 ir_add_error(ira, &field_ptr_instruction->base.base, 21436 buf_sprintf("type '%s' has no member called '%s'", 21437 buf_ptr(&child_type->name), buf_ptr(field_name))); 21438 return ira->codegen->invalid_inst_gen; 21439 } 21440 } else if (child_type->id == ZigTypeIdFloat) { 21441 if (buf_eql_str(field_name, "bit_count")) { 21442 bool ptr_is_const = true; 21443 bool ptr_is_volatile = false; 21444 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21445 create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int, 21446 child_type->data.floating.bit_count, false), 21447 ira->codegen->builtin_types.entry_num_lit_int, 21448 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21449 } else { 21450 ir_add_error(ira, &field_ptr_instruction->base.base, 21451 buf_sprintf("type '%s' has no member called '%s'", 21452 buf_ptr(&child_type->name), buf_ptr(field_name))); 21453 return ira->codegen->invalid_inst_gen; 21454 } 21455 } else if (child_type->id == ZigTypeIdPointer) { 21456 if (buf_eql_str(field_name, "Child")) { 21457 bool ptr_is_const = true; 21458 bool ptr_is_volatile = false; 21459 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21460 create_const_type(ira->codegen, child_type->data.pointer.child_type), 21461 ira->codegen->builtin_types.entry_type, 21462 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21463 } else if (buf_eql_str(field_name, "alignment")) { 21464 bool ptr_is_const = true; 21465 bool ptr_is_volatile = false; 21466 if ((err = type_resolve(ira->codegen, child_type->data.pointer.child_type, 21467 ResolveStatusAlignmentKnown))) 21468 { 21469 return ira->codegen->invalid_inst_gen; 21470 } 21471 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21472 create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int, 21473 get_ptr_align(ira->codegen, child_type), false), 21474 ira->codegen->builtin_types.entry_num_lit_int, 21475 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21476 } else { 21477 ir_add_error(ira, &field_ptr_instruction->base.base, 21478 buf_sprintf("type '%s' has no member called '%s'", 21479 buf_ptr(&child_type->name), buf_ptr(field_name))); 21480 return ira->codegen->invalid_inst_gen; 21481 } 21482 } else if (child_type->id == ZigTypeIdArray) { 21483 if (buf_eql_str(field_name, "Child")) { 21484 bool ptr_is_const = true; 21485 bool ptr_is_volatile = false; 21486 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21487 create_const_type(ira->codegen, child_type->data.array.child_type), 21488 ira->codegen->builtin_types.entry_type, 21489 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21490 } else if (buf_eql_str(field_name, "len")) { 21491 bool ptr_is_const = true; 21492 bool ptr_is_volatile = false; 21493 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21494 create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int, 21495 child_type->data.array.len, false), 21496 ira->codegen->builtin_types.entry_num_lit_int, 21497 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21498 } else { 21499 ir_add_error(ira, &field_ptr_instruction->base.base, 21500 buf_sprintf("type '%s' has no member called '%s'", 21501 buf_ptr(&child_type->name), buf_ptr(field_name))); 21502 return ira->codegen->invalid_inst_gen; 21503 } 21504 } else if (child_type->id == ZigTypeIdErrorUnion) { 21505 if (buf_eql_str(field_name, "Payload")) { 21506 bool ptr_is_const = true; 21507 bool ptr_is_volatile = false; 21508 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21509 create_const_type(ira->codegen, child_type->data.error_union.payload_type), 21510 ira->codegen->builtin_types.entry_type, 21511 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21512 } else if (buf_eql_str(field_name, "ErrorSet")) { 21513 bool ptr_is_const = true; 21514 bool ptr_is_volatile = false; 21515 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21516 create_const_type(ira->codegen, child_type->data.error_union.err_set_type), 21517 ira->codegen->builtin_types.entry_type, 21518 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21519 } else { 21520 ir_add_error(ira, &field_ptr_instruction->base.base, 21521 buf_sprintf("type '%s' has no member called '%s'", 21522 buf_ptr(&child_type->name), buf_ptr(field_name))); 21523 return ira->codegen->invalid_inst_gen; 21524 } 21525 } else if (child_type->id == ZigTypeIdOptional) { 21526 if (buf_eql_str(field_name, "Child")) { 21527 bool ptr_is_const = true; 21528 bool ptr_is_volatile = false; 21529 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21530 create_const_type(ira->codegen, child_type->data.maybe.child_type), 21531 ira->codegen->builtin_types.entry_type, 21532 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21533 } else { 21534 ir_add_error(ira, &field_ptr_instruction->base.base, 21535 buf_sprintf("type '%s' has no member called '%s'", 21536 buf_ptr(&child_type->name), buf_ptr(field_name))); 21537 return ira->codegen->invalid_inst_gen; 21538 } 21539 } else if (child_type->id == ZigTypeIdFn) { 21540 if (buf_eql_str(field_name, "ReturnType")) { 21541 if (child_type->data.fn.fn_type_id.return_type == nullptr) { 21542 // Return type can only ever be null, if the function is generic 21543 assert(child_type->data.fn.is_generic); 21544 21545 ir_add_error(ira, &field_ptr_instruction->base.base, 21546 buf_sprintf("ReturnType has not been resolved because '%s' is generic", buf_ptr(&child_type->name))); 21547 return ira->codegen->invalid_inst_gen; 21548 } 21549 21550 bool ptr_is_const = true; 21551 bool ptr_is_volatile = false; 21552 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21553 create_const_type(ira->codegen, child_type->data.fn.fn_type_id.return_type), 21554 ira->codegen->builtin_types.entry_type, 21555 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21556 } else if (buf_eql_str(field_name, "is_var_args")) { 21557 bool ptr_is_const = true; 21558 bool ptr_is_volatile = false; 21559 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21560 create_const_bool(ira->codegen, child_type->data.fn.fn_type_id.is_var_args), 21561 ira->codegen->builtin_types.entry_bool, 21562 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21563 } else if (buf_eql_str(field_name, "arg_count")) { 21564 bool ptr_is_const = true; 21565 bool ptr_is_volatile = false; 21566 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 21567 create_const_usize(ira->codegen, child_type->data.fn.fn_type_id.param_count), 21568 ira->codegen->builtin_types.entry_usize, 21569 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 21570 } else { 21571 ir_add_error(ira, &field_ptr_instruction->base.base, 21572 buf_sprintf("type '%s' has no member called '%s'", 21573 buf_ptr(&child_type->name), buf_ptr(field_name))); 21574 return ira->codegen->invalid_inst_gen; 21575 } 21576 } else { 21577 ir_add_error(ira, &field_ptr_instruction->base.base, 21578 buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); 21579 return ira->codegen->invalid_inst_gen; 21580 } 21581 } else if (field_ptr_instruction->initializing) { 21582 ir_add_error(ira, &field_ptr_instruction->base.base, 21583 buf_sprintf("type '%s' does not support struct initialization syntax", buf_ptr(&container_type->name))); 21584 return ira->codegen->invalid_inst_gen; 21585 } else { 21586 ir_add_error_node(ira, field_ptr_instruction->base.base.source_node, 21587 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); 21588 return ira->codegen->invalid_inst_gen; 21589 } 21590 } 21591 21592 static IrInstGen *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstSrcStorePtr *instruction) { 21593 IrInstGen *ptr = instruction->ptr->child; 21594 if (type_is_invalid(ptr->value->type)) 21595 return ira->codegen->invalid_inst_gen; 21596 21597 IrInstGen *value = instruction->value->child; 21598 if (type_is_invalid(value->value->type)) 21599 return ira->codegen->invalid_inst_gen; 21600 21601 return ir_analyze_store_ptr(ira, &instruction->base.base, ptr, value, instruction->allow_write_through_const); 21602 } 21603 21604 static IrInstGen *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstSrcLoadPtr *instruction) { 21605 IrInstGen *ptr = instruction->ptr->child; 21606 if (type_is_invalid(ptr->value->type)) 21607 return ira->codegen->invalid_inst_gen; 21608 return ir_get_deref(ira, &instruction->base.base, ptr, nullptr); 21609 } 21610 21611 static IrInstGen *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstSrcTypeOf *typeof_instruction) { 21612 IrInstGen *expr_value = typeof_instruction->value->child; 21613 ZigType *type_entry = expr_value->value->type; 21614 if (type_is_invalid(type_entry)) 21615 return ira->codegen->invalid_inst_gen; 21616 return ir_const_type(ira, &typeof_instruction->base.base, type_entry); 21617 } 21618 21619 static IrInstGen *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstSrcSetCold *instruction) { 21620 if (ira->new_irb.exec->is_inline) { 21621 // ignore setCold when running functions at compile time 21622 return ir_const_void(ira, &instruction->base.base); 21623 } 21624 21625 IrInstGen *is_cold_value = instruction->is_cold->child; 21626 bool want_cold; 21627 if (!ir_resolve_bool(ira, is_cold_value, &want_cold)) 21628 return ira->codegen->invalid_inst_gen; 21629 21630 ZigFn *fn_entry = scope_fn_entry(instruction->base.base.scope); 21631 if (fn_entry == nullptr) { 21632 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setCold outside function")); 21633 return ira->codegen->invalid_inst_gen; 21634 } 21635 21636 if (fn_entry->set_cold_node != nullptr) { 21637 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, buf_sprintf("cold set twice in same function")); 21638 add_error_note(ira->codegen, msg, fn_entry->set_cold_node, buf_sprintf("first set here")); 21639 return ira->codegen->invalid_inst_gen; 21640 } 21641 21642 fn_entry->set_cold_node = instruction->base.base.source_node; 21643 fn_entry->is_cold = want_cold; 21644 21645 return ir_const_void(ira, &instruction->base.base); 21646 } 21647 21648 static IrInstGen *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira, 21649 IrInstSrcSetRuntimeSafety *set_runtime_safety_instruction) 21650 { 21651 if (ira->new_irb.exec->is_inline) { 21652 // ignore setRuntimeSafety when running functions at compile time 21653 return ir_const_void(ira, &set_runtime_safety_instruction->base.base); 21654 } 21655 21656 bool *safety_off_ptr; 21657 AstNode **safety_set_node_ptr; 21658 21659 Scope *scope = set_runtime_safety_instruction->base.base.scope; 21660 while (scope != nullptr) { 21661 if (scope->id == ScopeIdBlock) { 21662 ScopeBlock *block_scope = (ScopeBlock *)scope; 21663 safety_off_ptr = &block_scope->safety_off; 21664 safety_set_node_ptr = &block_scope->safety_set_node; 21665 break; 21666 } else if (scope->id == ScopeIdFnDef) { 21667 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 21668 ZigFn *target_fn = def_scope->fn_entry; 21669 assert(target_fn->def_scope != nullptr); 21670 safety_off_ptr = &target_fn->def_scope->safety_off; 21671 safety_set_node_ptr = &target_fn->def_scope->safety_set_node; 21672 break; 21673 } else if (scope->id == ScopeIdDecls) { 21674 ScopeDecls *decls_scope = (ScopeDecls *)scope; 21675 safety_off_ptr = &decls_scope->safety_off; 21676 safety_set_node_ptr = &decls_scope->safety_set_node; 21677 break; 21678 } else { 21679 scope = scope->parent; 21680 continue; 21681 } 21682 } 21683 assert(scope != nullptr); 21684 21685 IrInstGen *safety_on_value = set_runtime_safety_instruction->safety_on->child; 21686 bool want_runtime_safety; 21687 if (!ir_resolve_bool(ira, safety_on_value, &want_runtime_safety)) 21688 return ira->codegen->invalid_inst_gen; 21689 21690 AstNode *source_node = set_runtime_safety_instruction->base.base.source_node; 21691 if (*safety_set_node_ptr) { 21692 ErrorMsg *msg = ir_add_error_node(ira, source_node, 21693 buf_sprintf("runtime safety set twice for same scope")); 21694 add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here")); 21695 return ira->codegen->invalid_inst_gen; 21696 } 21697 *safety_set_node_ptr = source_node; 21698 *safety_off_ptr = !want_runtime_safety; 21699 21700 return ir_const_void(ira, &set_runtime_safety_instruction->base.base); 21701 } 21702 21703 static IrInstGen *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, 21704 IrInstSrcSetFloatMode *instruction) 21705 { 21706 if (ira->new_irb.exec->is_inline) { 21707 // ignore setFloatMode when running functions at compile time 21708 return ir_const_void(ira, &instruction->base.base); 21709 } 21710 21711 bool *fast_math_on_ptr; 21712 AstNode **fast_math_set_node_ptr; 21713 21714 Scope *scope = instruction->base.base.scope; 21715 while (scope != nullptr) { 21716 if (scope->id == ScopeIdBlock) { 21717 ScopeBlock *block_scope = (ScopeBlock *)scope; 21718 fast_math_on_ptr = &block_scope->fast_math_on; 21719 fast_math_set_node_ptr = &block_scope->fast_math_set_node; 21720 break; 21721 } else if (scope->id == ScopeIdFnDef) { 21722 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 21723 ZigFn *target_fn = def_scope->fn_entry; 21724 assert(target_fn->def_scope != nullptr); 21725 fast_math_on_ptr = &target_fn->def_scope->fast_math_on; 21726 fast_math_set_node_ptr = &target_fn->def_scope->fast_math_set_node; 21727 break; 21728 } else if (scope->id == ScopeIdDecls) { 21729 ScopeDecls *decls_scope = (ScopeDecls *)scope; 21730 fast_math_on_ptr = &decls_scope->fast_math_on; 21731 fast_math_set_node_ptr = &decls_scope->fast_math_set_node; 21732 break; 21733 } else { 21734 scope = scope->parent; 21735 continue; 21736 } 21737 } 21738 assert(scope != nullptr); 21739 21740 IrInstGen *float_mode_value = instruction->mode_value->child; 21741 FloatMode float_mode_scalar; 21742 if (!ir_resolve_float_mode(ira, float_mode_value, &float_mode_scalar)) 21743 return ira->codegen->invalid_inst_gen; 21744 21745 AstNode *source_node = instruction->base.base.source_node; 21746 if (*fast_math_set_node_ptr) { 21747 ErrorMsg *msg = ir_add_error_node(ira, source_node, 21748 buf_sprintf("float mode set twice for same scope")); 21749 add_error_note(ira->codegen, msg, *fast_math_set_node_ptr, buf_sprintf("first set here")); 21750 return ira->codegen->invalid_inst_gen; 21751 } 21752 *fast_math_set_node_ptr = source_node; 21753 *fast_math_on_ptr = (float_mode_scalar == FloatModeOptimized); 21754 21755 return ir_const_void(ira, &instruction->base.base); 21756 } 21757 21758 static IrInstGen *ir_analyze_instruction_any_frame_type(IrAnalyze *ira, IrInstSrcAnyFrameType *instruction) { 21759 ZigType *payload_type = nullptr; 21760 if (instruction->payload_type != nullptr) { 21761 payload_type = ir_resolve_type(ira, instruction->payload_type->child); 21762 if (type_is_invalid(payload_type)) 21763 return ira->codegen->invalid_inst_gen; 21764 } 21765 21766 ZigType *any_frame_type = get_any_frame_type(ira->codegen, payload_type); 21767 return ir_const_type(ira, &instruction->base.base, any_frame_type); 21768 } 21769 21770 static IrInstGen *ir_analyze_instruction_slice_type(IrAnalyze *ira, IrInstSrcSliceType *slice_type_instruction) { 21771 IrInstGen *result = ir_const(ira, &slice_type_instruction->base.base, ira->codegen->builtin_types.entry_type); 21772 result->value->special = ConstValSpecialLazy; 21773 21774 LazyValueSliceType *lazy_slice_type = heap::c_allocator.create<LazyValueSliceType>(); 21775 lazy_slice_type->ira = ira; ira_ref(ira); 21776 result->value->data.x_lazy = &lazy_slice_type->base; 21777 lazy_slice_type->base.id = LazyValueIdSliceType; 21778 21779 if (slice_type_instruction->align_value != nullptr) { 21780 lazy_slice_type->align_inst = slice_type_instruction->align_value->child; 21781 if (ir_resolve_const(ira, lazy_slice_type->align_inst, LazyOk) == nullptr) 21782 return ira->codegen->invalid_inst_gen; 21783 } 21784 21785 if (slice_type_instruction->sentinel != nullptr) { 21786 lazy_slice_type->sentinel = slice_type_instruction->sentinel->child; 21787 if (ir_resolve_const(ira, lazy_slice_type->sentinel, LazyOk) == nullptr) 21788 return ira->codegen->invalid_inst_gen; 21789 } 21790 21791 lazy_slice_type->elem_type = slice_type_instruction->child_type->child; 21792 if (ir_resolve_type_lazy(ira, lazy_slice_type->elem_type) == nullptr) 21793 return ira->codegen->invalid_inst_gen; 21794 21795 lazy_slice_type->is_const = slice_type_instruction->is_const; 21796 lazy_slice_type->is_volatile = slice_type_instruction->is_volatile; 21797 lazy_slice_type->is_allowzero = slice_type_instruction->is_allow_zero; 21798 21799 return result; 21800 } 21801 21802 static IrInstGen *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstSrcAsm *asm_instruction) { 21803 Error err; 21804 21805 assert(asm_instruction->base.base.source_node->type == NodeTypeAsmExpr); 21806 21807 AstNode *node = asm_instruction->base.base.source_node; 21808 AstNodeAsmExpr *asm_expr = &asm_instruction->base.base.source_node->data.asm_expr; 21809 21810 Buf *template_buf = ir_resolve_str(ira, asm_instruction->asm_template->child); 21811 if (template_buf == nullptr) 21812 return ira->codegen->invalid_inst_gen; 21813 21814 if (asm_instruction->is_global) { 21815 buf_append_char(&ira->codegen->global_asm, '\n'); 21816 buf_append_buf(&ira->codegen->global_asm, template_buf); 21817 21818 return ir_const_void(ira, &asm_instruction->base.base); 21819 } 21820 21821 if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base.base)) 21822 return ira->codegen->invalid_inst_gen; 21823 21824 ZigList<AsmToken> tok_list = {}; 21825 if ((err = parse_asm_template(ira, node, template_buf, &tok_list))) { 21826 return ira->codegen->invalid_inst_gen; 21827 } 21828 21829 for (size_t token_i = 0; token_i < tok_list.length; token_i += 1) { 21830 AsmToken asm_token = tok_list.at(token_i); 21831 if (asm_token.id == AsmTokenIdVar) { 21832 size_t index = find_asm_index(ira->codegen, node, &asm_token, template_buf); 21833 if (index == SIZE_MAX) { 21834 const char *ptr = buf_ptr(template_buf) + asm_token.start + 2; 21835 uint32_t len = asm_token.end - asm_token.start - 2; 21836 21837 add_node_error(ira->codegen, node, 21838 buf_sprintf("could not find '%.*s' in the inputs or outputs", 21839 len, ptr)); 21840 return ira->codegen->invalid_inst_gen; 21841 } 21842 } 21843 } 21844 21845 // TODO validate the output types and variable types 21846 21847 IrInstGen **input_list = heap::c_allocator.allocate<IrInstGen *>(asm_expr->input_list.length); 21848 IrInstGen **output_types = heap::c_allocator.allocate<IrInstGen *>(asm_expr->output_list.length); 21849 21850 ZigType *return_type = ira->codegen->builtin_types.entry_void; 21851 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 21852 AsmOutput *asm_output = asm_expr->output_list.at(i); 21853 if (asm_output->return_type) { 21854 output_types[i] = asm_instruction->output_types[i]->child; 21855 return_type = ir_resolve_type(ira, output_types[i]); 21856 if (type_is_invalid(return_type)) 21857 return ira->codegen->invalid_inst_gen; 21858 } 21859 } 21860 21861 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 21862 IrInstGen *const input_value = asm_instruction->input_list[i]->child; 21863 if (type_is_invalid(input_value->value->type)) 21864 return ira->codegen->invalid_inst_gen; 21865 21866 if (instr_is_comptime(input_value) && 21867 (input_value->value->type->id == ZigTypeIdComptimeInt || 21868 input_value->value->type->id == ZigTypeIdComptimeFloat)) { 21869 ir_add_error(ira, &input_value->base, 21870 buf_sprintf("expected sized integer or sized float, found %s", buf_ptr(&input_value->value->type->name))); 21871 return ira->codegen->invalid_inst_gen; 21872 } 21873 21874 input_list[i] = input_value; 21875 } 21876 21877 return ir_build_asm_gen(ira, &asm_instruction->base.base, 21878 template_buf, tok_list.items, tok_list.length, 21879 input_list, output_types, asm_instruction->output_vars, asm_instruction->return_count, 21880 asm_instruction->has_side_effects, return_type); 21881 } 21882 21883 static IrInstGen *ir_analyze_instruction_array_type(IrAnalyze *ira, IrInstSrcArrayType *array_type_instruction) { 21884 IrInstGen *result = ir_const(ira, &array_type_instruction->base.base, ira->codegen->builtin_types.entry_type); 21885 result->value->special = ConstValSpecialLazy; 21886 21887 LazyValueArrayType *lazy_array_type = heap::c_allocator.create<LazyValueArrayType>(); 21888 lazy_array_type->ira = ira; ira_ref(ira); 21889 result->value->data.x_lazy = &lazy_array_type->base; 21890 lazy_array_type->base.id = LazyValueIdArrayType; 21891 21892 lazy_array_type->elem_type = array_type_instruction->child_type->child; 21893 if (ir_resolve_type_lazy(ira, lazy_array_type->elem_type) == nullptr) 21894 return ira->codegen->invalid_inst_gen; 21895 21896 if (!ir_resolve_usize(ira, array_type_instruction->size->child, &lazy_array_type->length)) 21897 return ira->codegen->invalid_inst_gen; 21898 21899 if (array_type_instruction->sentinel != nullptr) { 21900 lazy_array_type->sentinel = array_type_instruction->sentinel->child; 21901 if (ir_resolve_const(ira, lazy_array_type->sentinel, LazyOk) == nullptr) 21902 return ira->codegen->invalid_inst_gen; 21903 } 21904 21905 return result; 21906 } 21907 21908 static IrInstGen *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstSrcSizeOf *instruction) { 21909 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 21910 result->value->special = ConstValSpecialLazy; 21911 21912 LazyValueSizeOf *lazy_size_of = heap::c_allocator.create<LazyValueSizeOf>(); 21913 lazy_size_of->ira = ira; ira_ref(ira); 21914 result->value->data.x_lazy = &lazy_size_of->base; 21915 lazy_size_of->base.id = LazyValueIdSizeOf; 21916 lazy_size_of->bit_size = instruction->bit_size; 21917 21918 lazy_size_of->target_type = instruction->type_value->child; 21919 if (ir_resolve_type_lazy(ira, lazy_size_of->target_type) == nullptr) 21920 return ira->codegen->invalid_inst_gen; 21921 21922 return result; 21923 } 21924 21925 static IrInstGen *ir_analyze_test_non_null(IrAnalyze *ira, IrInst *source_inst, IrInstGen *value) { 21926 ZigType *type_entry = value->value->type; 21927 21928 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.allow_zero) { 21929 if (instr_is_comptime(value)) { 21930 ZigValue *c_ptr_val = ir_resolve_const(ira, value, UndefOk); 21931 if (c_ptr_val == nullptr) 21932 return ira->codegen->invalid_inst_gen; 21933 if (c_ptr_val->special == ConstValSpecialUndef) 21934 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); 21935 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 21936 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 21937 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 21938 return ir_const_bool(ira, source_inst, !is_null); 21939 } 21940 21941 return ir_build_test_non_null_gen(ira, source_inst, value); 21942 } else if (type_entry->id == ZigTypeIdOptional) { 21943 if (instr_is_comptime(value)) { 21944 ZigValue *maybe_val = ir_resolve_const(ira, value, UndefOk); 21945 if (maybe_val == nullptr) 21946 return ira->codegen->invalid_inst_gen; 21947 if (maybe_val->special == ConstValSpecialUndef) 21948 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); 21949 21950 return ir_const_bool(ira, source_inst, !optional_value_is_null(maybe_val)); 21951 } 21952 21953 return ir_build_test_non_null_gen(ira, source_inst, value); 21954 } else if (type_entry->id == ZigTypeIdNull) { 21955 return ir_const_bool(ira, source_inst, false); 21956 } else { 21957 return ir_const_bool(ira, source_inst, true); 21958 } 21959 } 21960 21961 static IrInstGen *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrInstSrcTestNonNull *instruction) { 21962 IrInstGen *value = instruction->value->child; 21963 if (type_is_invalid(value->value->type)) 21964 return ira->codegen->invalid_inst_gen; 21965 21966 return ir_analyze_test_non_null(ira, &instruction->base.base, value); 21967 } 21968 21969 static IrInstGen *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInst* source_instr, 21970 IrInstGen *base_ptr, bool safety_check_on, bool initializing) 21971 { 21972 Error err; 21973 21974 ZigType *type_entry = get_ptr_elem_type(ira->codegen, base_ptr); 21975 if (type_is_invalid(type_entry)) 21976 return ira->codegen->invalid_inst_gen; 21977 21978 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.ptr_len == PtrLenC) { 21979 if (instr_is_comptime(base_ptr)) { 21980 ZigValue *val = ir_resolve_const(ira, base_ptr, UndefBad); 21981 if (!val) 21982 return ira->codegen->invalid_inst_gen; 21983 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 21984 ZigValue *c_ptr_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 21985 if (c_ptr_val == nullptr) 21986 return ira->codegen->invalid_inst_gen; 21987 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 21988 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 21989 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 21990 if (is_null) { 21991 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); 21992 return ira->codegen->invalid_inst_gen; 21993 } 21994 return base_ptr; 21995 } 21996 } 21997 if (!safety_check_on) 21998 return base_ptr; 21999 IrInstGen *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr); 22000 ir_build_assert_non_null(ira, source_instr, c_ptr_val); 22001 return base_ptr; 22002 } 22003 22004 if (type_entry->id != ZigTypeIdOptional) { 22005 ir_add_error(ira, &base_ptr->base, 22006 buf_sprintf("expected optional type, found '%s'", buf_ptr(&type_entry->name))); 22007 return ira->codegen->invalid_inst_gen; 22008 } 22009 22010 ZigType *child_type = type_entry->data.maybe.child_type; 22011 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, 22012 base_ptr->value->type->data.pointer.is_const, base_ptr->value->type->data.pointer.is_volatile, 22013 PtrLenSingle, 0, 0, 0, false); 22014 22015 bool same_comptime_repr = types_have_same_zig_comptime_repr(ira->codegen, child_type, type_entry); 22016 22017 if (instr_is_comptime(base_ptr)) { 22018 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 22019 if (ptr_val == nullptr) 22020 return ira->codegen->invalid_inst_gen; 22021 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 22022 ZigValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 22023 if (optional_val == nullptr) 22024 return ira->codegen->invalid_inst_gen; 22025 22026 if (initializing) { 22027 switch (type_has_one_possible_value(ira->codegen, child_type)) { 22028 case OnePossibleValueInvalid: 22029 return ira->codegen->invalid_inst_gen; 22030 case OnePossibleValueNo: 22031 if (!same_comptime_repr) { 22032 ZigValue *payload_val = ira->codegen->pass1_arena->create<ZigValue>(); 22033 payload_val->type = child_type; 22034 payload_val->special = ConstValSpecialUndef; 22035 payload_val->parent.id = ConstParentIdOptionalPayload; 22036 payload_val->parent.data.p_optional_payload.optional_val = optional_val; 22037 22038 optional_val->data.x_optional = payload_val; 22039 optional_val->special = ConstValSpecialStatic; 22040 } 22041 break; 22042 case OnePossibleValueYes: { 22043 optional_val->special = ConstValSpecialStatic; 22044 optional_val->data.x_optional = get_the_one_possible_value(ira->codegen, child_type); 22045 break; 22046 } 22047 } 22048 } else { 22049 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 22050 source_instr->source_node, optional_val, UndefBad))) 22051 return ira->codegen->invalid_inst_gen; 22052 if (optional_value_is_null(optional_val)) { 22053 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); 22054 return ira->codegen->invalid_inst_gen; 22055 } 22056 } 22057 22058 IrInstGen *result; 22059 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 22060 result = ir_build_optional_unwrap_ptr_gen(ira, source_instr, base_ptr, false, 22061 initializing, result_type); 22062 result->value->special = ConstValSpecialStatic; 22063 } else { 22064 result = ir_const(ira, source_instr, result_type); 22065 } 22066 ZigValue *result_val = result->value; 22067 result_val->data.x_ptr.special = ConstPtrSpecialRef; 22068 result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 22069 switch (type_has_one_possible_value(ira->codegen, child_type)) { 22070 case OnePossibleValueInvalid: 22071 return ira->codegen->invalid_inst_gen; 22072 case OnePossibleValueNo: 22073 if (same_comptime_repr) { 22074 result_val->data.x_ptr.data.ref.pointee = optional_val; 22075 } else { 22076 assert(optional_val->data.x_optional != nullptr); 22077 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; 22078 } 22079 break; 22080 case OnePossibleValueYes: 22081 assert(optional_val->data.x_optional != nullptr); 22082 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; 22083 break; 22084 } 22085 return result; 22086 } 22087 } 22088 22089 return ir_build_optional_unwrap_ptr_gen(ira, source_instr, base_ptr, safety_check_on, 22090 initializing, result_type); 22091 } 22092 22093 static IrInstGen *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, 22094 IrInstSrcOptionalUnwrapPtr *instruction) 22095 { 22096 IrInstGen *base_ptr = instruction->base_ptr->child; 22097 if (type_is_invalid(base_ptr->value->type)) 22098 return ira->codegen->invalid_inst_gen; 22099 22100 return ir_analyze_unwrap_optional_payload(ira, &instruction->base.base, base_ptr, 22101 instruction->safety_check_on, false); 22102 } 22103 22104 static IrInstGen *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstSrcCtz *instruction) { 22105 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 22106 if (type_is_invalid(int_type)) 22107 return ira->codegen->invalid_inst_gen; 22108 22109 IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); 22110 if (type_is_invalid(op->value->type)) 22111 return ira->codegen->invalid_inst_gen; 22112 22113 if (int_type->data.integral.bit_count == 0) 22114 return ir_const_unsigned(ira, &instruction->base.base, 0); 22115 22116 if (instr_is_comptime(op)) { 22117 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 22118 if (val == nullptr) 22119 return ira->codegen->invalid_inst_gen; 22120 if (val->special == ConstValSpecialUndef) 22121 return ir_const_undef(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 22122 size_t result_usize = bigint_ctz(&op->value->data.x_bigint, int_type->data.integral.bit_count); 22123 return ir_const_unsigned(ira, &instruction->base.base, result_usize); 22124 } 22125 22126 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 22127 return ir_build_ctz_gen(ira, &instruction->base.base, return_type, op); 22128 } 22129 22130 static IrInstGen *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstSrcClz *instruction) { 22131 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 22132 if (type_is_invalid(int_type)) 22133 return ira->codegen->invalid_inst_gen; 22134 22135 IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); 22136 if (type_is_invalid(op->value->type)) 22137 return ira->codegen->invalid_inst_gen; 22138 22139 if (int_type->data.integral.bit_count == 0) 22140 return ir_const_unsigned(ira, &instruction->base.base, 0); 22141 22142 if (instr_is_comptime(op)) { 22143 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 22144 if (val == nullptr) 22145 return ira->codegen->invalid_inst_gen; 22146 if (val->special == ConstValSpecialUndef) 22147 return ir_const_undef(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 22148 size_t result_usize = bigint_clz(&op->value->data.x_bigint, int_type->data.integral.bit_count); 22149 return ir_const_unsigned(ira, &instruction->base.base, result_usize); 22150 } 22151 22152 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 22153 return ir_build_clz_gen(ira, &instruction->base.base, return_type, op); 22154 } 22155 22156 static IrInstGen *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstSrcPopCount *instruction) { 22157 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 22158 if (type_is_invalid(int_type)) 22159 return ira->codegen->invalid_inst_gen; 22160 22161 IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); 22162 if (type_is_invalid(op->value->type)) 22163 return ira->codegen->invalid_inst_gen; 22164 22165 if (int_type->data.integral.bit_count == 0) 22166 return ir_const_unsigned(ira, &instruction->base.base, 0); 22167 22168 if (instr_is_comptime(op)) { 22169 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 22170 if (val == nullptr) 22171 return ira->codegen->invalid_inst_gen; 22172 if (val->special == ConstValSpecialUndef) 22173 return ir_const_undef(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 22174 22175 if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { 22176 size_t result = bigint_popcount_unsigned(&val->data.x_bigint); 22177 return ir_const_unsigned(ira, &instruction->base.base, result); 22178 } 22179 size_t result = bigint_popcount_signed(&val->data.x_bigint, int_type->data.integral.bit_count); 22180 return ir_const_unsigned(ira, &instruction->base.base, result); 22181 } 22182 22183 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 22184 return ir_build_pop_count_gen(ira, &instruction->base.base, return_type, op); 22185 } 22186 22187 static IrInstGen *ir_analyze_union_tag(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, bool is_gen) { 22188 if (type_is_invalid(value->value->type)) 22189 return ira->codegen->invalid_inst_gen; 22190 22191 if (value->value->type->id != ZigTypeIdUnion) { 22192 ir_add_error(ira, &value->base, 22193 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value->type->name))); 22194 return ira->codegen->invalid_inst_gen; 22195 } 22196 if (!value->value->type->data.unionation.have_explicit_tag_type && !is_gen) { 22197 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum")); 22198 if (value->value->type->data.unionation.decl_node != nullptr) { 22199 add_error_note(ira->codegen, msg, value->value->type->data.unionation.decl_node, 22200 buf_sprintf("declared here")); 22201 } 22202 return ira->codegen->invalid_inst_gen; 22203 } 22204 22205 ZigType *tag_type = value->value->type->data.unionation.tag_type; 22206 assert(tag_type->id == ZigTypeIdEnum); 22207 22208 if (instr_is_comptime(value)) { 22209 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 22210 if (!val) 22211 return ira->codegen->invalid_inst_gen; 22212 22213 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 22214 source_instr->scope, source_instr->source_node); 22215 const_instruction->base.value->type = tag_type; 22216 const_instruction->base.value->special = ConstValSpecialStatic; 22217 bigint_init_bigint(&const_instruction->base.value->data.x_enum_tag, &val->data.x_union.tag); 22218 return &const_instruction->base; 22219 } 22220 22221 return ir_build_union_tag(ira, source_instr, value, tag_type); 22222 } 22223 22224 static IrInstGen *ir_analyze_instruction_switch_br(IrAnalyze *ira, 22225 IrInstSrcSwitchBr *switch_br_instruction) 22226 { 22227 IrInstGen *target_value = switch_br_instruction->target_value->child; 22228 if (type_is_invalid(target_value->value->type)) 22229 return ir_unreach_error(ira); 22230 22231 if (switch_br_instruction->switch_prongs_void != nullptr) { 22232 if (type_is_invalid(switch_br_instruction->switch_prongs_void->child->value->type)) { 22233 return ir_unreach_error(ira); 22234 } 22235 } 22236 22237 22238 size_t case_count = switch_br_instruction->case_count; 22239 22240 bool is_comptime; 22241 if (!ir_resolve_comptime(ira, switch_br_instruction->is_comptime->child, &is_comptime)) 22242 return ira->codegen->invalid_inst_gen; 22243 22244 if (is_comptime || instr_is_comptime(target_value)) { 22245 ZigValue *target_val = ir_resolve_const(ira, target_value, UndefBad); 22246 if (!target_val) 22247 return ir_unreach_error(ira); 22248 22249 IrBasicBlockSrc *old_dest_block = switch_br_instruction->else_block; 22250 for (size_t i = 0; i < case_count; i += 1) { 22251 IrInstSrcSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 22252 IrInstGen *case_value = old_case->value->child; 22253 if (type_is_invalid(case_value->value->type)) 22254 return ir_unreach_error(ira); 22255 22256 IrInstGen *casted_case_value = ir_implicit_cast(ira, case_value, target_value->value->type); 22257 if (type_is_invalid(casted_case_value->value->type)) 22258 return ir_unreach_error(ira); 22259 22260 ZigValue *case_val = ir_resolve_const(ira, casted_case_value, UndefBad); 22261 if (!case_val) 22262 return ir_unreach_error(ira); 22263 22264 if (const_values_equal(ira->codegen, target_val, case_val)) { 22265 old_dest_block = old_case->block; 22266 break; 22267 } 22268 } 22269 22270 if (is_comptime || old_dest_block->ref_count == 1) { 22271 return ir_inline_bb(ira, &switch_br_instruction->base.base, old_dest_block); 22272 } else { 22273 IrBasicBlockGen *new_dest_block = ir_get_new_bb(ira, old_dest_block, &switch_br_instruction->base.base); 22274 IrInstGen *result = ir_build_br_gen(ira, &switch_br_instruction->base.base, new_dest_block); 22275 return ir_finish_anal(ira, result); 22276 } 22277 } 22278 22279 IrInstGenSwitchBrCase *cases = heap::c_allocator.allocate<IrInstGenSwitchBrCase>(case_count); 22280 for (size_t i = 0; i < case_count; i += 1) { 22281 IrInstSrcSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 22282 IrInstGenSwitchBrCase *new_case = &cases[i]; 22283 new_case->block = ir_get_new_bb(ira, old_case->block, &switch_br_instruction->base.base); 22284 new_case->value = ira->codegen->invalid_inst_gen; 22285 22286 // Calling ir_get_new_bb set the ref_instruction on the new basic block. 22287 // However a switch br may branch to the same basic block which would trigger an 22288 // incorrect re-generation of the block. So we set it to null here and assign 22289 // it back after the loop. 22290 new_case->block->ref_instruction = nullptr; 22291 22292 IrInstSrc *old_value = old_case->value; 22293 IrInstGen *new_value = old_value->child; 22294 if (type_is_invalid(new_value->value->type)) 22295 continue; 22296 22297 IrInstGen *casted_new_value = ir_implicit_cast(ira, new_value, target_value->value->type); 22298 if (type_is_invalid(casted_new_value->value->type)) 22299 continue; 22300 22301 if (!ir_resolve_const(ira, casted_new_value, UndefBad)) 22302 continue; 22303 22304 new_case->value = casted_new_value; 22305 } 22306 22307 for (size_t i = 0; i < case_count; i += 1) { 22308 IrInstGenSwitchBrCase *new_case = &cases[i]; 22309 if (type_is_invalid(new_case->value->value->type)) 22310 return ir_unreach_error(ira); 22311 new_case->block->ref_instruction = &switch_br_instruction->base.base; 22312 } 22313 22314 IrBasicBlockGen *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base.base); 22315 IrInstGenSwitchBr *switch_br = ir_build_switch_br_gen(ira, &switch_br_instruction->base.base, 22316 target_value, new_else_block, case_count, cases); 22317 return ir_finish_anal(ira, &switch_br->base); 22318 } 22319 22320 static IrInstGen *ir_analyze_instruction_switch_target(IrAnalyze *ira, 22321 IrInstSrcSwitchTarget *switch_target_instruction) 22322 { 22323 Error err; 22324 IrInstGen *target_value_ptr = switch_target_instruction->target_value_ptr->child; 22325 if (type_is_invalid(target_value_ptr->value->type)) 22326 return ira->codegen->invalid_inst_gen; 22327 22328 if (target_value_ptr->value->type->id == ZigTypeIdMetaType) { 22329 assert(instr_is_comptime(target_value_ptr)); 22330 ZigType *ptr_type = target_value_ptr->value->data.x_type; 22331 assert(ptr_type->id == ZigTypeIdPointer); 22332 return ir_const_type(ira, &switch_target_instruction->base.base, ptr_type->data.pointer.child_type); 22333 } 22334 22335 ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; 22336 ZigValue *pointee_val = nullptr; 22337 if (instr_is_comptime(target_value_ptr) && target_value_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 22338 pointee_val = const_ptr_pointee(ira, ira->codegen, target_value_ptr->value, target_value_ptr->base.source_node); 22339 if (pointee_val == nullptr) 22340 return ira->codegen->invalid_inst_gen; 22341 22342 if (pointee_val->special == ConstValSpecialRuntime) 22343 pointee_val = nullptr; 22344 } 22345 if ((err = type_resolve(ira->codegen, target_type, ResolveStatusSizeKnown))) 22346 return ira->codegen->invalid_inst_gen; 22347 22348 switch (target_type->id) { 22349 case ZigTypeIdInvalid: 22350 zig_unreachable(); 22351 case ZigTypeIdMetaType: 22352 case ZigTypeIdVoid: 22353 case ZigTypeIdBool: 22354 case ZigTypeIdInt: 22355 case ZigTypeIdFloat: 22356 case ZigTypeIdComptimeFloat: 22357 case ZigTypeIdComptimeInt: 22358 case ZigTypeIdEnumLiteral: 22359 case ZigTypeIdPointer: 22360 case ZigTypeIdFn: 22361 case ZigTypeIdErrorSet: { 22362 if (pointee_val) { 22363 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, nullptr); 22364 copy_const_val(ira->codegen, result->value, pointee_val); 22365 result->value->type = target_type; 22366 return result; 22367 } 22368 22369 IrInstGen *result = ir_get_deref(ira, &switch_target_instruction->base.base, target_value_ptr, nullptr); 22370 result->value->type = target_type; 22371 return result; 22372 } 22373 case ZigTypeIdUnion: { 22374 AstNode *decl_node = target_type->data.unionation.decl_node; 22375 if (!decl_node->data.container_decl.auto_enum && 22376 decl_node->data.container_decl.init_arg_expr == nullptr) 22377 { 22378 ErrorMsg *msg = ir_add_error(ira, &target_value_ptr->base, 22379 buf_sprintf("switch on union which has no attached enum")); 22380 add_error_note(ira->codegen, msg, decl_node, 22381 buf_sprintf("consider 'union(enum)' here")); 22382 return ira->codegen->invalid_inst_gen; 22383 } 22384 ZigType *tag_type = target_type->data.unionation.tag_type; 22385 assert(tag_type != nullptr); 22386 assert(tag_type->id == ZigTypeIdEnum); 22387 if (pointee_val) { 22388 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, tag_type); 22389 bigint_init_bigint(&result->value->data.x_enum_tag, &pointee_val->data.x_union.tag); 22390 return result; 22391 } 22392 if (tag_type->data.enumeration.src_field_count == 1) { 22393 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, tag_type); 22394 TypeEnumField *only_field = &tag_type->data.enumeration.fields[0]; 22395 bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value); 22396 return result; 22397 } 22398 22399 IrInstGen *union_value = ir_get_deref(ira, &switch_target_instruction->base.base, target_value_ptr, nullptr); 22400 union_value->value->type = target_type; 22401 22402 return ir_build_union_tag(ira, &switch_target_instruction->base.base, union_value, tag_type); 22403 } 22404 case ZigTypeIdEnum: { 22405 if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown))) 22406 return ira->codegen->invalid_inst_gen; 22407 if (target_type->data.enumeration.src_field_count == 1) { 22408 TypeEnumField *only_field = &target_type->data.enumeration.fields[0]; 22409 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, target_type); 22410 bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value); 22411 return result; 22412 } 22413 22414 if (pointee_val) { 22415 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, target_type); 22416 bigint_init_bigint(&result->value->data.x_enum_tag, &pointee_val->data.x_enum_tag); 22417 return result; 22418 } 22419 22420 IrInstGen *enum_value = ir_get_deref(ira, &switch_target_instruction->base.base, target_value_ptr, nullptr); 22421 enum_value->value->type = target_type; 22422 return enum_value; 22423 } 22424 case ZigTypeIdErrorUnion: 22425 case ZigTypeIdUnreachable: 22426 case ZigTypeIdArray: 22427 case ZigTypeIdStruct: 22428 case ZigTypeIdUndefined: 22429 case ZigTypeIdNull: 22430 case ZigTypeIdOptional: 22431 case ZigTypeIdBoundFn: 22432 case ZigTypeIdOpaque: 22433 case ZigTypeIdVector: 22434 case ZigTypeIdFnFrame: 22435 case ZigTypeIdAnyFrame: 22436 ir_add_error(ira, &switch_target_instruction->base.base, 22437 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name))); 22438 return ira->codegen->invalid_inst_gen; 22439 } 22440 zig_unreachable(); 22441 } 22442 22443 static IrInstGen *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstSrcSwitchVar *instruction) { 22444 IrInstGen *target_value_ptr = instruction->target_value_ptr->child; 22445 if (type_is_invalid(target_value_ptr->value->type)) 22446 return ira->codegen->invalid_inst_gen; 22447 22448 ZigType *ref_type = target_value_ptr->value->type; 22449 assert(ref_type->id == ZigTypeIdPointer); 22450 ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; 22451 if (target_type->id == ZigTypeIdUnion) { 22452 ZigType *enum_type = target_type->data.unionation.tag_type; 22453 assert(enum_type != nullptr); 22454 assert(enum_type->id == ZigTypeIdEnum); 22455 assert(instruction->prongs_len > 0); 22456 22457 IrInstGen *first_prong_value = instruction->prongs_ptr[0]->child; 22458 if (type_is_invalid(first_prong_value->value->type)) 22459 return ira->codegen->invalid_inst_gen; 22460 22461 IrInstGen *first_casted_prong_value = ir_implicit_cast(ira, first_prong_value, enum_type); 22462 if (type_is_invalid(first_casted_prong_value->value->type)) 22463 return ira->codegen->invalid_inst_gen; 22464 22465 ZigValue *first_prong_val = ir_resolve_const(ira, first_casted_prong_value, UndefBad); 22466 if (first_prong_val == nullptr) 22467 return ira->codegen->invalid_inst_gen; 22468 22469 TypeUnionField *first_field = find_union_field_by_tag(target_type, &first_prong_val->data.x_enum_tag); 22470 22471 ErrorMsg *invalid_payload_msg = nullptr; 22472 for (size_t prong_i = 1; prong_i < instruction->prongs_len; prong_i += 1) { 22473 IrInstGen *this_prong_inst = instruction->prongs_ptr[prong_i]->child; 22474 if (type_is_invalid(this_prong_inst->value->type)) 22475 return ira->codegen->invalid_inst_gen; 22476 22477 IrInstGen *this_casted_prong_value = ir_implicit_cast(ira, this_prong_inst, enum_type); 22478 if (type_is_invalid(this_casted_prong_value->value->type)) 22479 return ira->codegen->invalid_inst_gen; 22480 22481 ZigValue *this_prong = ir_resolve_const(ira, this_casted_prong_value, UndefBad); 22482 if (this_prong == nullptr) 22483 return ira->codegen->invalid_inst_gen; 22484 22485 TypeUnionField *payload_field = find_union_field_by_tag(target_type, &this_prong->data.x_enum_tag); 22486 ZigType *payload_type = payload_field->type_entry; 22487 if (first_field->type_entry != payload_type) { 22488 if (invalid_payload_msg == nullptr) { 22489 invalid_payload_msg = ir_add_error(ira, &instruction->base.base, 22490 buf_sprintf("capture group with incompatible types")); 22491 add_error_note(ira->codegen, invalid_payload_msg, first_prong_value->base.source_node, 22492 buf_sprintf("type '%s' here", buf_ptr(&first_field->type_entry->name))); 22493 } 22494 add_error_note(ira->codegen, invalid_payload_msg, this_prong_inst->base.source_node, 22495 buf_sprintf("type '%s' here", buf_ptr(&payload_field->type_entry->name))); 22496 } 22497 } 22498 22499 if (invalid_payload_msg != nullptr) { 22500 return ira->codegen->invalid_inst_gen; 22501 } 22502 22503 if (instr_is_comptime(target_value_ptr)) { 22504 ZigValue *target_val_ptr = ir_resolve_const(ira, target_value_ptr, UndefBad); 22505 if (!target_value_ptr) 22506 return ira->codegen->invalid_inst_gen; 22507 22508 ZigValue *pointee_val = const_ptr_pointee(ira, ira->codegen, target_val_ptr, instruction->base.base.source_node); 22509 if (pointee_val == nullptr) 22510 return ira->codegen->invalid_inst_gen; 22511 22512 IrInstGen *result = ir_const(ira, &instruction->base.base, 22513 get_pointer_to_type(ira->codegen, first_field->type_entry, 22514 target_val_ptr->type->data.pointer.is_const)); 22515 ZigValue *out_val = result->value; 22516 out_val->data.x_ptr.special = ConstPtrSpecialRef; 22517 out_val->data.x_ptr.mut = target_val_ptr->data.x_ptr.mut; 22518 out_val->data.x_ptr.data.ref.pointee = pointee_val->data.x_union.payload; 22519 return result; 22520 } 22521 22522 ZigType *result_type = get_pointer_to_type(ira->codegen, first_field->type_entry, 22523 target_value_ptr->value->type->data.pointer.is_const); 22524 return ir_build_union_field_ptr(ira, &instruction->base.base, target_value_ptr, first_field, 22525 false, false, result_type); 22526 } else if (target_type->id == ZigTypeIdErrorSet) { 22527 // construct an error set from the prong values 22528 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 22529 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 22530 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 22531 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 22532 ZigList<ErrorTableEntry *> error_list = {}; 22533 buf_resize(&err_set_type->name, 0); 22534 buf_appendf(&err_set_type->name, "error{"); 22535 for (size_t i = 0; i < instruction->prongs_len; i += 1) { 22536 ErrorTableEntry *err = ir_resolve_error(ira, instruction->prongs_ptr[i]->child); 22537 if (err == nullptr) 22538 return ira->codegen->invalid_inst_gen; 22539 error_list.append(err); 22540 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&err->name)); 22541 } 22542 err_set_type->data.error_set.errors = error_list.items; 22543 err_set_type->data.error_set.err_count = error_list.length; 22544 buf_appendf(&err_set_type->name, "}"); 22545 22546 22547 ZigType *new_target_value_ptr_type = get_pointer_to_type_extra(ira->codegen, 22548 err_set_type, 22549 ref_type->data.pointer.is_const, ref_type->data.pointer.is_volatile, 22550 ref_type->data.pointer.ptr_len, 22551 ref_type->data.pointer.explicit_alignment, 22552 ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, 22553 ref_type->data.pointer.allow_zero); 22554 return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, 22555 &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false); 22556 } else { 22557 ir_add_error(ira, &instruction->base.base, 22558 buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); 22559 return ira->codegen->invalid_inst_gen; 22560 } 22561 } 22562 22563 static IrInstGen *ir_analyze_instruction_switch_else_var(IrAnalyze *ira, 22564 IrInstSrcSwitchElseVar *instruction) 22565 { 22566 IrInstGen *target_value_ptr = instruction->target_value_ptr->child; 22567 if (type_is_invalid(target_value_ptr->value->type)) 22568 return ira->codegen->invalid_inst_gen; 22569 22570 ZigType *ref_type = target_value_ptr->value->type; 22571 assert(ref_type->id == ZigTypeIdPointer); 22572 ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; 22573 if (target_type->id == ZigTypeIdErrorSet) { 22574 // make a new set that has the other cases removed 22575 if (!resolve_inferred_error_set(ira->codegen, target_type, instruction->base.base.source_node)) { 22576 return ira->codegen->invalid_inst_gen; 22577 } 22578 if (type_is_global_error_set(target_type)) { 22579 // the type of the else capture variable still has to be the global error set. 22580 // once the runtime hint system is more sophisticated, we could add some hint information here. 22581 return target_value_ptr; 22582 } 22583 // Make note of the errors handled by other cases 22584 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); 22585 // We may not have any case in the switch if this is a lone else 22586 const size_t switch_cases = instruction->switch_br ? instruction->switch_br->case_count : 0; 22587 for (size_t case_i = 0; case_i < switch_cases; case_i += 1) { 22588 IrInstSrcSwitchBrCase *br_case = &instruction->switch_br->cases[case_i]; 22589 IrInstGen *case_expr = br_case->value->child; 22590 if (case_expr->value->type->id == ZigTypeIdErrorSet) { 22591 ErrorTableEntry *err = ir_resolve_error(ira, case_expr); 22592 if (err == nullptr) 22593 return ira->codegen->invalid_inst_gen; 22594 errors[err->value] = err; 22595 } else if (case_expr->value->type->id == ZigTypeIdMetaType) { 22596 ZigType *err_set_type = ir_resolve_type(ira, case_expr); 22597 if (type_is_invalid(err_set_type)) 22598 return ira->codegen->invalid_inst_gen; 22599 populate_error_set_table(errors, err_set_type); 22600 } else { 22601 zig_unreachable(); 22602 } 22603 } 22604 ZigList<ErrorTableEntry *> result_list = {}; 22605 22606 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 22607 buf_resize(&err_set_type->name, 0); 22608 buf_appendf(&err_set_type->name, "error{"); 22609 22610 // Look at all the errors in the type switched on and add them to the result_list 22611 // if they are not handled by cases. 22612 for (uint32_t i = 0; i < target_type->data.error_set.err_count; i += 1) { 22613 ErrorTableEntry *error_entry = target_type->data.error_set.errors[i]; 22614 ErrorTableEntry *existing_entry = errors[error_entry->value]; 22615 if (existing_entry == nullptr) { 22616 result_list.append(error_entry); 22617 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); 22618 } 22619 } 22620 heap::c_allocator.deallocate(errors, ira->codegen->errors_by_index.length); 22621 22622 err_set_type->data.error_set.err_count = result_list.length; 22623 err_set_type->data.error_set.errors = result_list.items; 22624 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 22625 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 22626 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 22627 22628 buf_appendf(&err_set_type->name, "}"); 22629 22630 ZigType *new_target_value_ptr_type = get_pointer_to_type_extra(ira->codegen, 22631 err_set_type, 22632 ref_type->data.pointer.is_const, ref_type->data.pointer.is_volatile, 22633 ref_type->data.pointer.ptr_len, 22634 ref_type->data.pointer.explicit_alignment, 22635 ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, 22636 ref_type->data.pointer.allow_zero); 22637 return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, 22638 &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false); 22639 } 22640 22641 return target_value_ptr; 22642 } 22643 22644 static IrInstGen *ir_analyze_instruction_import(IrAnalyze *ira, IrInstSrcImport *import_instruction) { 22645 Error err; 22646 22647 IrInstGen *name_value = import_instruction->name->child; 22648 Buf *import_target_str = ir_resolve_str(ira, name_value); 22649 if (!import_target_str) 22650 return ira->codegen->invalid_inst_gen; 22651 22652 AstNode *source_node = import_instruction->base.base.source_node; 22653 ZigType *import = source_node->owner; 22654 22655 ZigType *target_import; 22656 Buf *import_target_path; 22657 Buf full_path = BUF_INIT; 22658 if ((err = analyze_import(ira->codegen, import, import_target_str, &target_import, 22659 &import_target_path, &full_path))) 22660 { 22661 if (err == ErrorImportOutsidePkgPath) { 22662 ir_add_error_node(ira, source_node, 22663 buf_sprintf("import of file outside package path: '%s'", 22664 buf_ptr(import_target_path))); 22665 return ira->codegen->invalid_inst_gen; 22666 } else if (err == ErrorFileNotFound) { 22667 ir_add_error_node(ira, source_node, 22668 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); 22669 return ira->codegen->invalid_inst_gen; 22670 } else { 22671 ir_add_error_node(ira, source_node, 22672 buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); 22673 return ira->codegen->invalid_inst_gen; 22674 } 22675 } 22676 22677 return ir_const_type(ira, &import_instruction->base.base, target_import); 22678 } 22679 22680 static IrInstGen *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstSrcRef *ref_instruction) { 22681 IrInstGen *value = ref_instruction->value->child; 22682 if (type_is_invalid(value->value->type)) 22683 return ira->codegen->invalid_inst_gen; 22684 return ir_get_ref(ira, &ref_instruction->base.base, value, ref_instruction->is_const, ref_instruction->is_volatile); 22685 } 22686 22687 static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instruction, 22688 AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstGen *field_result_loc, 22689 IrInstGen *result_loc) 22690 { 22691 Error err; 22692 assert(union_type->id == ZigTypeIdUnion); 22693 22694 if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) 22695 return ira->codegen->invalid_inst_gen; 22696 22697 TypeUnionField *type_field = find_union_type_field(union_type, field_name); 22698 if (type_field == nullptr) { 22699 ir_add_error_node(ira, field_source_node, 22700 buf_sprintf("no member named '%s' in union '%s'", 22701 buf_ptr(field_name), buf_ptr(&union_type->name))); 22702 return ira->codegen->invalid_inst_gen; 22703 } 22704 22705 if (type_is_invalid(type_field->type_entry)) 22706 return ira->codegen->invalid_inst_gen; 22707 22708 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { 22709 if (instr_is_comptime(field_result_loc) && 22710 field_result_loc->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 22711 { 22712 // nothing 22713 } else { 22714 result_loc->value->special = ConstValSpecialRuntime; 22715 } 22716 } 22717 22718 bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instruction->scope) 22719 || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes; 22720 22721 IrInstGen *result = ir_get_deref(ira, source_instruction, result_loc, nullptr); 22722 if (is_comptime && !instr_is_comptime(result)) { 22723 ir_add_error(ira, &field_result_loc->base, 22724 buf_sprintf("unable to evaluate constant expression")); 22725 return ira->codegen->invalid_inst_gen; 22726 } 22727 return result; 22728 } 22729 22730 static IrInstGen *ir_analyze_container_init_fields(IrAnalyze *ira, IrInst *source_instr, 22731 ZigType *container_type, size_t instr_field_count, IrInstSrcContainerInitFieldsField *fields, 22732 IrInstGen *result_loc) 22733 { 22734 Error err; 22735 if (container_type->id == ZigTypeIdUnion) { 22736 if (instr_field_count != 1) { 22737 ir_add_error(ira, source_instr, 22738 buf_sprintf("union initialization expects exactly one field")); 22739 return ira->codegen->invalid_inst_gen; 22740 } 22741 IrInstSrcContainerInitFieldsField *field = &fields[0]; 22742 IrInstGen *field_result_loc = field->result_loc->child; 22743 if (type_is_invalid(field_result_loc->value->type)) 22744 return ira->codegen->invalid_inst_gen; 22745 22746 return ir_analyze_union_init(ira, source_instr, field->source_node, container_type, field->name, 22747 field_result_loc, result_loc); 22748 } 22749 if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { 22750 ir_add_error(ira, source_instr, 22751 buf_sprintf("type '%s' does not support struct initialization syntax", 22752 buf_ptr(&container_type->name))); 22753 return ira->codegen->invalid_inst_gen; 22754 } 22755 22756 if (container_type->data.structure.resolve_status == ResolveStatusBeingInferred) { 22757 // We're now done inferring the type. 22758 container_type->data.structure.resolve_status = ResolveStatusUnstarted; 22759 } 22760 22761 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 22762 return ira->codegen->invalid_inst_gen; 22763 22764 size_t actual_field_count = container_type->data.structure.src_field_count; 22765 22766 IrInstGen *first_non_const_instruction = nullptr; 22767 22768 AstNode **field_assign_nodes = heap::c_allocator.allocate<AstNode *>(actual_field_count); 22769 ZigList<IrInstGen *> const_ptrs = {}; 22770 22771 bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope) 22772 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; 22773 22774 22775 // Here we iterate over the fields that have been initialized, and emit 22776 // compile errors for missing fields and duplicate fields. 22777 // It is only now that we find out whether the struct initialization can be a comptime 22778 // value, but we have already emitted runtime instructions for the fields that 22779 // were initialized with runtime values, and have omitted instructions that would have 22780 // initialized fields with comptime values. 22781 // So now we must clean up this situation. If it turns out the struct initialization can 22782 // be a comptime value, overwrite ConstPtrMutInfer with ConstPtrMutComptimeConst. 22783 // Otherwise, we must emit instructions to runtime-initialize the fields that have 22784 // comptime-known values. 22785 22786 for (size_t i = 0; i < instr_field_count; i += 1) { 22787 IrInstSrcContainerInitFieldsField *field = &fields[i]; 22788 22789 IrInstGen *field_result_loc = field->result_loc->child; 22790 if (type_is_invalid(field_result_loc->value->type)) 22791 return ira->codegen->invalid_inst_gen; 22792 22793 TypeStructField *type_field = find_struct_type_field(container_type, field->name); 22794 if (!type_field) { 22795 ir_add_error_node(ira, field->source_node, 22796 buf_sprintf("no member named '%s' in struct '%s'", 22797 buf_ptr(field->name), buf_ptr(&container_type->name))); 22798 return ira->codegen->invalid_inst_gen; 22799 } 22800 22801 if (type_is_invalid(type_field->type_entry)) 22802 return ira->codegen->invalid_inst_gen; 22803 22804 size_t field_index = type_field->src_index; 22805 AstNode *existing_assign_node = field_assign_nodes[field_index]; 22806 if (existing_assign_node) { 22807 ErrorMsg *msg = ir_add_error_node(ira, field->source_node, buf_sprintf("duplicate field")); 22808 add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here")); 22809 return ira->codegen->invalid_inst_gen; 22810 } 22811 field_assign_nodes[field_index] = field->source_node; 22812 22813 if (instr_is_comptime(field_result_loc) && 22814 field_result_loc->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 22815 { 22816 const_ptrs.append(field_result_loc); 22817 } else { 22818 first_non_const_instruction = field_result_loc; 22819 } 22820 } 22821 22822 bool any_missing = false; 22823 for (size_t i = 0; i < actual_field_count; i += 1) { 22824 if (field_assign_nodes[i] != nullptr) continue; 22825 22826 // look for a default field value 22827 TypeStructField *field = container_type->data.structure.fields[i]; 22828 memoize_field_init_val(ira->codegen, container_type, field); 22829 if (field->init_val == nullptr) { 22830 ir_add_error(ira, source_instr, 22831 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i]->name))); 22832 any_missing = true; 22833 continue; 22834 } 22835 if (type_is_invalid(field->init_val->type)) 22836 return ira->codegen->invalid_inst_gen; 22837 22838 IrInstGen *runtime_inst = ir_const(ira, source_instr, field->init_val->type); 22839 copy_const_val(ira->codegen, runtime_inst->value, field->init_val); 22840 22841 IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, result_loc, 22842 container_type, true); 22843 ir_analyze_store_ptr(ira, source_instr, field_ptr, runtime_inst, false); 22844 if (instr_is_comptime(field_ptr) && field_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 22845 const_ptrs.append(field_ptr); 22846 } else { 22847 first_non_const_instruction = result_loc; 22848 } 22849 } 22850 if (any_missing) 22851 return ira->codegen->invalid_inst_gen; 22852 22853 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { 22854 if (const_ptrs.length != actual_field_count) { 22855 result_loc->value->special = ConstValSpecialRuntime; 22856 for (size_t i = 0; i < const_ptrs.length; i += 1) { 22857 IrInstGen *field_result_loc = const_ptrs.at(i); 22858 IrInstGen *deref = ir_get_deref(ira, &field_result_loc->base, field_result_loc, nullptr); 22859 field_result_loc->value->special = ConstValSpecialRuntime; 22860 ir_analyze_store_ptr(ira, &field_result_loc->base, field_result_loc, deref, false); 22861 } 22862 } 22863 } 22864 22865 IrInstGen *result = ir_get_deref(ira, source_instr, result_loc, nullptr); 22866 22867 if (is_comptime && !instr_is_comptime(result)) { 22868 ir_add_error_node(ira, first_non_const_instruction->base.source_node, 22869 buf_sprintf("unable to evaluate constant expression")); 22870 return ira->codegen->invalid_inst_gen; 22871 } 22872 22873 return result; 22874 } 22875 22876 static IrInstGen *ir_analyze_instruction_container_init_list(IrAnalyze *ira, 22877 IrInstSrcContainerInitList *instruction) 22878 { 22879 ir_assert(instruction->result_loc != nullptr, &instruction->base.base); 22880 IrInstGen *result_loc = instruction->result_loc->child; 22881 if (type_is_invalid(result_loc->value->type)) 22882 return result_loc; 22883 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); 22884 22885 ZigType *container_type = result_loc->value->type->data.pointer.child_type; 22886 22887 size_t elem_count = instruction->item_count; 22888 22889 if (is_slice(container_type)) { 22890 ir_add_error_node(ira, instruction->init_array_type_source_node, 22891 buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", 22892 buf_ptr(&container_type->name))); 22893 return ira->codegen->invalid_inst_gen; 22894 } 22895 22896 if (container_type->id == ZigTypeIdVoid) { 22897 if (elem_count != 0) { 22898 ir_add_error_node(ira, instruction->base.base.source_node, 22899 buf_sprintf("void expression expects no arguments")); 22900 return ira->codegen->invalid_inst_gen; 22901 } 22902 return ir_const_void(ira, &instruction->base.base); 22903 } 22904 22905 if (container_type->id == ZigTypeIdStruct && elem_count == 0) { 22906 ir_assert(instruction->result_loc != nullptr, &instruction->base.base); 22907 IrInstGen *result_loc = instruction->result_loc->child; 22908 if (type_is_invalid(result_loc->value->type)) 22909 return result_loc; 22910 return ir_analyze_container_init_fields(ira, &instruction->base.base, container_type, 0, nullptr, result_loc); 22911 } 22912 22913 if (container_type->id == ZigTypeIdArray) { 22914 ZigType *child_type = container_type->data.array.child_type; 22915 if (container_type->data.array.len != elem_count) { 22916 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count, nullptr); 22917 22918 ir_add_error(ira, &instruction->base.base, 22919 buf_sprintf("expected %s literal, found %s literal", 22920 buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); 22921 return ira->codegen->invalid_inst_gen; 22922 } 22923 } else if (container_type->id == ZigTypeIdStruct && 22924 container_type->data.structure.resolve_status == ResolveStatusBeingInferred) 22925 { 22926 // We're now done inferring the type. 22927 container_type->data.structure.resolve_status = ResolveStatusUnstarted; 22928 } else if (container_type->id == ZigTypeIdVector) { 22929 // OK 22930 } else { 22931 ir_add_error(ira, &instruction->base.base, 22932 buf_sprintf("type '%s' does not support array initialization", 22933 buf_ptr(&container_type->name))); 22934 return ira->codegen->invalid_inst_gen; 22935 } 22936 22937 switch (type_has_one_possible_value(ira->codegen, container_type)) { 22938 case OnePossibleValueInvalid: 22939 return ira->codegen->invalid_inst_gen; 22940 case OnePossibleValueYes: 22941 return ir_const_move(ira, &instruction->base.base, 22942 get_the_one_possible_value(ira->codegen, container_type)); 22943 case OnePossibleValueNo: 22944 break; 22945 } 22946 22947 bool is_comptime; 22948 switch (type_requires_comptime(ira->codegen, container_type)) { 22949 case ReqCompTimeInvalid: 22950 return ira->codegen->invalid_inst_gen; 22951 case ReqCompTimeNo: 22952 is_comptime = ir_should_inline(ira->old_irb.exec, instruction->base.base.scope); 22953 break; 22954 case ReqCompTimeYes: 22955 is_comptime = true; 22956 break; 22957 } 22958 22959 IrInstGen *first_non_const_instruction = nullptr; 22960 22961 // The Result Location Mechanism has already emitted runtime instructions to 22962 // initialize runtime elements and has omitted instructions for the comptime 22963 // elements. However it is only now that we find out whether the array initialization 22964 // can be a comptime value. So we must clean up the situation. If it turns out 22965 // array initialization can be a comptime value, overwrite ConstPtrMutInfer with 22966 // ConstPtrMutComptimeConst. Otherwise, emit instructions to runtime-initialize the 22967 // elements that have comptime-known values. 22968 ZigList<IrInstGen *> const_ptrs = {}; 22969 22970 for (size_t i = 0; i < elem_count; i += 1) { 22971 IrInstGen *elem_result_loc = instruction->elem_result_loc_list[i]->child; 22972 if (type_is_invalid(elem_result_loc->value->type)) 22973 return ira->codegen->invalid_inst_gen; 22974 22975 assert(elem_result_loc->value->type->id == ZigTypeIdPointer); 22976 22977 if (instr_is_comptime(elem_result_loc) && 22978 elem_result_loc->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 22979 { 22980 const_ptrs.append(elem_result_loc); 22981 } else { 22982 first_non_const_instruction = elem_result_loc; 22983 } 22984 } 22985 22986 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { 22987 if (const_ptrs.length != elem_count) { 22988 result_loc->value->special = ConstValSpecialRuntime; 22989 for (size_t i = 0; i < const_ptrs.length; i += 1) { 22990 IrInstGen *elem_result_loc = const_ptrs.at(i); 22991 assert(elem_result_loc->value->special == ConstValSpecialStatic); 22992 if (elem_result_loc->value->type->data.pointer.inferred_struct_field != nullptr) { 22993 // This field will be generated comptime; no need to do this. 22994 continue; 22995 } 22996 IrInstGen *deref = ir_get_deref(ira, &elem_result_loc->base, elem_result_loc, nullptr); 22997 elem_result_loc->value->special = ConstValSpecialRuntime; 22998 ir_analyze_store_ptr(ira, &elem_result_loc->base, elem_result_loc, deref, false); 22999 } 23000 } 23001 } 23002 23003 IrInstGen *result = ir_get_deref(ira, &instruction->base.base, result_loc, nullptr); 23004 if (instr_is_comptime(result)) 23005 return result; 23006 23007 if (is_comptime) { 23008 ir_add_error(ira, &first_non_const_instruction->base, 23009 buf_sprintf("unable to evaluate constant expression")); 23010 return ira->codegen->invalid_inst_gen; 23011 } 23012 23013 ZigType *result_elem_type = result_loc->value->type->data.pointer.child_type; 23014 if (is_slice(result_elem_type)) { 23015 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 23016 buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'", 23017 buf_ptr(&result_elem_type->name))); 23018 add_error_note(ira->codegen, msg, first_non_const_instruction->base.source_node, 23019 buf_sprintf("this value is not comptime-known")); 23020 return ira->codegen->invalid_inst_gen; 23021 } 23022 return result; 23023 } 23024 23025 static IrInstGen *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, 23026 IrInstSrcContainerInitFields *instruction) 23027 { 23028 ir_assert(instruction->result_loc != nullptr, &instruction->base.base); 23029 IrInstGen *result_loc = instruction->result_loc->child; 23030 if (type_is_invalid(result_loc->value->type)) 23031 return result_loc; 23032 23033 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); 23034 ZigType *container_type = result_loc->value->type->data.pointer.child_type; 23035 23036 return ir_analyze_container_init_fields(ira, &instruction->base.base, container_type, 23037 instruction->field_count, instruction->fields, result_loc); 23038 } 23039 23040 static IrInstGen *ir_analyze_instruction_compile_err(IrAnalyze *ira, IrInstSrcCompileErr *instruction) { 23041 IrInstGen *msg_value = instruction->msg->child; 23042 Buf *msg_buf = ir_resolve_str(ira, msg_value); 23043 if (!msg_buf) 23044 return ira->codegen->invalid_inst_gen; 23045 23046 ir_add_error(ira, &instruction->base.base, msg_buf); 23047 23048 return ira->codegen->invalid_inst_gen; 23049 } 23050 23051 static IrInstGen *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInstSrcCompileLog *instruction) { 23052 Buf buf = BUF_INIT; 23053 fprintf(stderr, "| "); 23054 for (size_t i = 0; i < instruction->msg_count; i += 1) { 23055 IrInstGen *msg = instruction->msg_list[i]->child; 23056 if (type_is_invalid(msg->value->type)) 23057 return ira->codegen->invalid_inst_gen; 23058 buf_resize(&buf, 0); 23059 if (msg->value->special == ConstValSpecialLazy) { 23060 // Resolve any lazy value that's passed, we need its value 23061 if (ir_resolve_lazy(ira->codegen, msg->base.source_node, msg->value)) 23062 return ira->codegen->invalid_inst_gen; 23063 } 23064 render_const_value(ira->codegen, &buf, msg->value); 23065 const char *comma_str = (i != 0) ? ", " : ""; 23066 fprintf(stderr, "%s%s", comma_str, buf_ptr(&buf)); 23067 } 23068 fprintf(stderr, "\n"); 23069 23070 auto *expr = &instruction->base.base.source_node->data.fn_call_expr; 23071 if (!expr->seen) { 23072 // Here we bypass higher level functions such as ir_add_error because we do not want 23073 // invalidate_exec to be called. 23074 add_node_error(ira->codegen, instruction->base.base.source_node, buf_sprintf("found compile log statement")); 23075 } 23076 expr->seen = true; 23077 23078 return ir_const_void(ira, &instruction->base.base); 23079 } 23080 23081 static IrInstGen *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstSrcErrName *instruction) { 23082 IrInstGen *value = instruction->value->child; 23083 if (type_is_invalid(value->value->type)) 23084 return ira->codegen->invalid_inst_gen; 23085 23086 IrInstGen *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_global_error_set); 23087 if (type_is_invalid(casted_value->value->type)) 23088 return ira->codegen->invalid_inst_gen; 23089 23090 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 23091 true, false, PtrLenUnknown, 0, 0, 0, false); 23092 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 23093 if (instr_is_comptime(casted_value)) { 23094 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); 23095 if (val == nullptr) 23096 return ira->codegen->invalid_inst_gen; 23097 ErrorTableEntry *err = casted_value->value->data.x_err_set; 23098 if (!err->cached_error_name_val) { 23099 ZigValue *array_val = create_const_str_lit(ira->codegen, &err->name)->data.x_ptr.data.ref.pointee; 23100 err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); 23101 } 23102 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 23103 copy_const_val(ira->codegen, result->value, err->cached_error_name_val); 23104 result->value->type = str_type; 23105 return result; 23106 } 23107 23108 ira->codegen->generate_error_name_table = true; 23109 23110 return ir_build_err_name_gen(ira, &instruction->base.base, value, str_type); 23111 } 23112 23113 static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrcTagName *instruction) { 23114 Error err; 23115 IrInstGen *target = instruction->target->child; 23116 if (type_is_invalid(target->value->type)) 23117 return ira->codegen->invalid_inst_gen; 23118 23119 if (target->value->type->id == ZigTypeIdEnumLiteral) { 23120 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 23121 Buf *field_name = target->value->data.x_enum_literal; 23122 ZigValue *array_val = create_const_str_lit(ira->codegen, field_name)->data.x_ptr.data.ref.pointee; 23123 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field_name), true); 23124 return result; 23125 } 23126 23127 if (target->value->type->id == ZigTypeIdUnion) { 23128 target = ir_analyze_union_tag(ira, &instruction->base.base, target, instruction->base.is_gen); 23129 if (type_is_invalid(target->value->type)) 23130 return ira->codegen->invalid_inst_gen; 23131 } 23132 23133 if (target->value->type->id != ZigTypeIdEnum) { 23134 ir_add_error(ira, &target->base, 23135 buf_sprintf("expected enum tag, found '%s'", buf_ptr(&target->value->type->name))); 23136 return ira->codegen->invalid_inst_gen; 23137 } 23138 23139 if (target->value->type->data.enumeration.src_field_count == 1 && 23140 !target->value->type->data.enumeration.non_exhaustive) { 23141 TypeEnumField *only_field = &target->value->type->data.enumeration.fields[0]; 23142 ZigValue *array_val = create_const_str_lit(ira->codegen, only_field->name)->data.x_ptr.data.ref.pointee; 23143 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 23144 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(only_field->name), true); 23145 return result; 23146 } 23147 23148 if (instr_is_comptime(target)) { 23149 if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusZeroBitsKnown))) 23150 return ira->codegen->invalid_inst_gen; 23151 if (target->value->type->data.enumeration.non_exhaustive) { 23152 ir_add_error(ira, &instruction->base.base, 23153 buf_sprintf("TODO @tagName on non-exhaustive enum https://github.com/ziglang/zig/issues/3991")); 23154 return ira->codegen->invalid_inst_gen; 23155 } 23156 TypeEnumField *field = find_enum_field_by_tag(target->value->type, &target->value->data.x_bigint); 23157 ZigValue *array_val = create_const_str_lit(ira->codegen, field->name)->data.x_ptr.data.ref.pointee; 23158 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 23159 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field->name), true); 23160 return result; 23161 } 23162 23163 ZigType *u8_ptr_type = get_pointer_to_type_extra( 23164 ira->codegen, ira->codegen->builtin_types.entry_u8, 23165 true, false, PtrLenUnknown, 23166 0, 0, 0, false); 23167 ZigType *result_type = get_slice_type(ira->codegen, u8_ptr_type); 23168 return ir_build_tag_name_gen(ira, &instruction->base.base, target, result_type); 23169 } 23170 23171 static IrInstGen *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, 23172 IrInstSrcFieldParentPtr *instruction) 23173 { 23174 Error err; 23175 IrInstGen *type_value = instruction->type_value->child; 23176 ZigType *container_type = ir_resolve_type(ira, type_value); 23177 if (type_is_invalid(container_type)) 23178 return ira->codegen->invalid_inst_gen; 23179 23180 IrInstGen *field_name_value = instruction->field_name->child; 23181 Buf *field_name = ir_resolve_str(ira, field_name_value); 23182 if (!field_name) 23183 return ira->codegen->invalid_inst_gen; 23184 23185 IrInstGen *field_ptr = instruction->field_ptr->child; 23186 if (type_is_invalid(field_ptr->value->type)) 23187 return ira->codegen->invalid_inst_gen; 23188 23189 if (container_type->id != ZigTypeIdStruct) { 23190 ir_add_error(ira, &type_value->base, 23191 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 23192 return ira->codegen->invalid_inst_gen; 23193 } 23194 23195 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 23196 return ira->codegen->invalid_inst_gen; 23197 23198 TypeStructField *field = find_struct_type_field(container_type, field_name); 23199 if (field == nullptr) { 23200 ir_add_error(ira, &field_name_value->base, 23201 buf_sprintf("struct '%s' has no field '%s'", 23202 buf_ptr(&container_type->name), buf_ptr(field_name))); 23203 return ira->codegen->invalid_inst_gen; 23204 } 23205 23206 if (field_ptr->value->type->id != ZigTypeIdPointer) { 23207 ir_add_error(ira, &field_ptr->base, 23208 buf_sprintf("expected pointer, found '%s'", buf_ptr(&field_ptr->value->type->name))); 23209 return ira->codegen->invalid_inst_gen; 23210 } 23211 23212 bool is_packed = (container_type->data.structure.layout == ContainerLayoutPacked); 23213 uint32_t field_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); 23214 uint32_t parent_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, container_type); 23215 23216 ZigType *field_ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, 23217 field_ptr->value->type->data.pointer.is_const, 23218 field_ptr->value->type->data.pointer.is_volatile, 23219 PtrLenSingle, 23220 field_ptr_align, 0, 0, false); 23221 IrInstGen *casted_field_ptr = ir_implicit_cast(ira, field_ptr, field_ptr_type); 23222 if (type_is_invalid(casted_field_ptr->value->type)) 23223 return ira->codegen->invalid_inst_gen; 23224 23225 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, container_type, 23226 casted_field_ptr->value->type->data.pointer.is_const, 23227 casted_field_ptr->value->type->data.pointer.is_volatile, 23228 PtrLenSingle, 23229 parent_ptr_align, 0, 0, false); 23230 23231 if (instr_is_comptime(casted_field_ptr)) { 23232 ZigValue *field_ptr_val = ir_resolve_const(ira, casted_field_ptr, UndefBad); 23233 if (!field_ptr_val) 23234 return ira->codegen->invalid_inst_gen; 23235 23236 if (field_ptr_val->data.x_ptr.special != ConstPtrSpecialBaseStruct) { 23237 ir_add_error(ira, &field_ptr->base, buf_sprintf("pointer value not based on parent struct")); 23238 return ira->codegen->invalid_inst_gen; 23239 } 23240 23241 size_t ptr_field_index = field_ptr_val->data.x_ptr.data.base_struct.field_index; 23242 if (ptr_field_index != field->src_index) { 23243 ir_add_error(ira, &instruction->base.base, 23244 buf_sprintf("field '%s' has index %" ZIG_PRI_usize " but pointer value is index %" ZIG_PRI_usize " of struct '%s'", 23245 buf_ptr(field->name), field->src_index, 23246 ptr_field_index, buf_ptr(&container_type->name))); 23247 return ira->codegen->invalid_inst_gen; 23248 } 23249 23250 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 23251 ZigValue *out_val = result->value; 23252 out_val->data.x_ptr.special = ConstPtrSpecialRef; 23253 out_val->data.x_ptr.data.ref.pointee = field_ptr_val->data.x_ptr.data.base_struct.struct_val; 23254 out_val->data.x_ptr.mut = field_ptr_val->data.x_ptr.mut; 23255 return result; 23256 } 23257 23258 return ir_build_field_parent_ptr_gen(ira, &instruction->base.base, casted_field_ptr, field, result_type); 23259 } 23260 23261 static TypeStructField *validate_byte_offset(IrAnalyze *ira, 23262 IrInstGen *type_value, 23263 IrInstGen *field_name_value, 23264 size_t *byte_offset) 23265 { 23266 ZigType *container_type = ir_resolve_type(ira, type_value); 23267 if (type_is_invalid(container_type)) 23268 return nullptr; 23269 23270 Error err; 23271 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 23272 return nullptr; 23273 23274 Buf *field_name = ir_resolve_str(ira, field_name_value); 23275 if (!field_name) 23276 return nullptr; 23277 23278 if (container_type->id != ZigTypeIdStruct) { 23279 ir_add_error(ira, &type_value->base, 23280 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 23281 return nullptr; 23282 } 23283 23284 TypeStructField *field = find_struct_type_field(container_type, field_name); 23285 if (field == nullptr) { 23286 ir_add_error(ira, &field_name_value->base, 23287 buf_sprintf("struct '%s' has no field '%s'", 23288 buf_ptr(&container_type->name), buf_ptr(field_name))); 23289 return nullptr; 23290 } 23291 23292 if (!type_has_bits(field->type_entry)) { 23293 ir_add_error(ira, &field_name_value->base, 23294 buf_sprintf("zero-bit field '%s' in struct '%s' has no offset", 23295 buf_ptr(field_name), buf_ptr(&container_type->name))); 23296 return nullptr; 23297 } 23298 23299 *byte_offset = field->offset; 23300 return field; 23301 } 23302 23303 static IrInstGen *ir_analyze_instruction_byte_offset_of(IrAnalyze *ira, IrInstSrcByteOffsetOf *instruction) { 23304 IrInstGen *type_value = instruction->type_value->child; 23305 if (type_is_invalid(type_value->value->type)) 23306 return ira->codegen->invalid_inst_gen; 23307 23308 IrInstGen *field_name_value = instruction->field_name->child; 23309 size_t byte_offset = 0; 23310 if (!validate_byte_offset(ira, type_value, field_name_value, &byte_offset)) 23311 return ira->codegen->invalid_inst_gen; 23312 23313 23314 return ir_const_unsigned(ira, &instruction->base.base, byte_offset); 23315 } 23316 23317 static IrInstGen *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, IrInstSrcBitOffsetOf *instruction) { 23318 IrInstGen *type_value = instruction->type_value->child; 23319 if (type_is_invalid(type_value->value->type)) 23320 return ira->codegen->invalid_inst_gen; 23321 IrInstGen *field_name_value = instruction->field_name->child; 23322 size_t byte_offset = 0; 23323 TypeStructField *field = nullptr; 23324 if (!(field = validate_byte_offset(ira, type_value, field_name_value, &byte_offset))) 23325 return ira->codegen->invalid_inst_gen; 23326 23327 size_t bit_offset = byte_offset * 8 + field->bit_offset_in_host; 23328 return ir_const_unsigned(ira, &instruction->base.base, bit_offset); 23329 } 23330 23331 static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { 23332 Buf *field_name_buf; 23333 23334 assert(type != nullptr && !type_is_invalid(type)); 23335 field_name_buf = buf_create_from_str(field_name); 23336 TypeStructField *field = find_struct_type_field(type, field_name_buf); 23337 buf_deinit(field_name_buf); 23338 23339 if (field == nullptr || field->src_index != index) 23340 zig_panic("reference to unknown field %s", field_name); 23341 } 23342 23343 static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, ZigType *root) { 23344 Error err; 23345 ZigType *type_info_type = get_builtin_type(ira->codegen, "TypeInfo"); 23346 assert(type_info_type->id == ZigTypeIdUnion); 23347 if ((err = type_resolve(ira->codegen, type_info_type, ResolveStatusSizeKnown))) { 23348 zig_unreachable(); 23349 } 23350 23351 if (type_name == nullptr && root == nullptr) 23352 return type_info_type; 23353 else if (type_name == nullptr) 23354 return root; 23355 23356 ZigType *root_type = (root == nullptr) ? type_info_type : root; 23357 23358 ScopeDecls *type_info_scope = get_container_scope(root_type); 23359 assert(type_info_scope != nullptr); 23360 23361 Buf field_name = BUF_INIT; 23362 buf_init_from_str(&field_name, type_name); 23363 auto entry = type_info_scope->decl_table.get(&field_name); 23364 buf_deinit(&field_name); 23365 23366 TldVar *tld = (TldVar *)entry; 23367 assert(tld->base.id == TldIdVar); 23368 23369 ZigVar *var = tld->var; 23370 23371 assert(var->const_value->type->id == ZigTypeIdMetaType); 23372 23373 return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, nullptr, var->const_value); 23374 } 23375 23376 static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigValue *out_val, 23377 ScopeDecls *decls_scope, bool resolve_types) 23378 { 23379 Error err; 23380 ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr); 23381 if ((err = type_resolve(ira->codegen, type_info_declaration_type, ResolveStatusSizeKnown))) 23382 return err; 23383 23384 ensure_field_index(type_info_declaration_type, "name", 0); 23385 ensure_field_index(type_info_declaration_type, "is_pub", 1); 23386 ensure_field_index(type_info_declaration_type, "data", 2); 23387 23388 if (!resolve_types) { 23389 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, type_info_declaration_type, 23390 false, false, PtrLenUnknown, 0, 0, 0, false); 23391 23392 out_val->special = ConstValSpecialLazy; 23393 out_val->type = get_slice_type(ira->codegen, ptr_type); 23394 23395 LazyValueTypeInfoDecls *lazy_type_info_decls = heap::c_allocator.create<LazyValueTypeInfoDecls>(); 23396 lazy_type_info_decls->ira = ira; ira_ref(ira); 23397 out_val->data.x_lazy = &lazy_type_info_decls->base; 23398 lazy_type_info_decls->base.id = LazyValueIdTypeInfoDecls; 23399 23400 lazy_type_info_decls->source_instr = source_instr; 23401 lazy_type_info_decls->decls_scope = decls_scope; 23402 23403 return ErrorNone; 23404 } 23405 23406 ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type); 23407 if ((err = type_resolve(ira->codegen, type_info_declaration_data_type, ResolveStatusSizeKnown))) 23408 return err; 23409 23410 ZigType *type_info_fn_decl_type = ir_type_info_get_type(ira, "FnDecl", type_info_declaration_data_type); 23411 if ((err = type_resolve(ira->codegen, type_info_fn_decl_type, ResolveStatusSizeKnown))) 23412 return err; 23413 23414 ZigType *type_info_fn_decl_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_decl_type); 23415 if ((err = type_resolve(ira->codegen, type_info_fn_decl_inline_type, ResolveStatusSizeKnown))) 23416 return err; 23417 23418 // The unresolved declarations are collected in a separate queue to avoid 23419 // modifying decl_table while iterating over it 23420 ZigList<Tld*> resolve_decl_queue{}; 23421 23422 auto decl_it = decls_scope->decl_table.entry_iterator(); 23423 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; 23424 while ((curr_entry = decl_it.next()) != nullptr) { 23425 if (curr_entry->value->resolution == TldResolutionInvalid) { 23426 return ErrorSemanticAnalyzeFail; 23427 } 23428 23429 if (curr_entry->value->resolution == TldResolutionResolving) { 23430 ir_error_dependency_loop(ira, source_instr); 23431 return ErrorSemanticAnalyzeFail; 23432 } 23433 23434 // If the declaration is unresolved, force it to be resolved again. 23435 if (curr_entry->value->resolution == TldResolutionUnresolved) 23436 resolve_decl_queue.append(curr_entry->value); 23437 } 23438 23439 for (size_t i = 0; i < resolve_decl_queue.length; i++) { 23440 Tld *decl = resolve_decl_queue.at(i); 23441 resolve_top_level_decl(ira->codegen, decl, decl->source_node, false); 23442 if (decl->resolution == TldResolutionInvalid) { 23443 return ErrorSemanticAnalyzeFail; 23444 } 23445 } 23446 23447 resolve_decl_queue.deinit(); 23448 23449 // Loop through our declarations once to figure out how many declarations we will generate info for. 23450 int declaration_count = 0; 23451 decl_it = decls_scope->decl_table.entry_iterator(); 23452 while ((curr_entry = decl_it.next()) != nullptr) { 23453 // Skip comptime blocks and test functions. 23454 if (curr_entry->value->id == TldIdCompTime) 23455 continue; 23456 23457 if (curr_entry->value->id == TldIdFn) { 23458 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 23459 if (fn_entry->is_test) 23460 continue; 23461 } 23462 23463 declaration_count += 1; 23464 } 23465 23466 ZigValue *declaration_array = ira->codegen->pass1_arena->create<ZigValue>(); 23467 declaration_array->special = ConstValSpecialStatic; 23468 declaration_array->type = get_array_type(ira->codegen, type_info_declaration_type, declaration_count, nullptr); 23469 declaration_array->data.x_array.special = ConstArraySpecialNone; 23470 declaration_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(declaration_count); 23471 init_const_slice(ira->codegen, out_val, declaration_array, 0, declaration_count, false); 23472 23473 // Loop through the declarations and generate info. 23474 decl_it = decls_scope->decl_table.entry_iterator(); 23475 curr_entry = nullptr; 23476 int declaration_index = 0; 23477 while ((curr_entry = decl_it.next()) != nullptr) { 23478 // Skip comptime blocks and test functions. 23479 if (curr_entry->value->id == TldIdCompTime) { 23480 continue; 23481 } else if (curr_entry->value->id == TldIdFn) { 23482 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 23483 if (fn_entry->is_test) 23484 continue; 23485 } 23486 23487 ZigValue *declaration_val = &declaration_array->data.x_array.data.s_none.elements[declaration_index]; 23488 23489 declaration_val->special = ConstValSpecialStatic; 23490 declaration_val->type = type_info_declaration_type; 23491 23492 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3); 23493 ZigValue *name = create_const_str_lit(ira->codegen, curr_entry->key)->data.x_ptr.data.ref.pointee; 23494 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(curr_entry->key), true); 23495 inner_fields[1]->special = ConstValSpecialStatic; 23496 inner_fields[1]->type = ira->codegen->builtin_types.entry_bool; 23497 inner_fields[1]->data.x_bool = curr_entry->value->visib_mod == VisibModPub; 23498 inner_fields[2]->special = ConstValSpecialStatic; 23499 inner_fields[2]->type = type_info_declaration_data_type; 23500 inner_fields[2]->parent.id = ConstParentIdStruct; 23501 inner_fields[2]->parent.data.p_struct.struct_val = declaration_val; 23502 inner_fields[2]->parent.data.p_struct.field_index = 1; 23503 23504 switch (curr_entry->value->id) { 23505 case TldIdVar: 23506 { 23507 ZigVar *var = ((TldVar *)curr_entry->value)->var; 23508 assert(var != nullptr); 23509 23510 if ((err = type_resolve(ira->codegen, var->const_value->type, ResolveStatusSizeKnown))) 23511 return ErrorSemanticAnalyzeFail; 23512 23513 if (var->const_value->type->id == ZigTypeIdMetaType) { 23514 // We have a variable of type 'type', so it's actually a type declaration. 23515 // 0: Data.Type: type 23516 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0); 23517 inner_fields[2]->data.x_union.payload = var->const_value; 23518 } else { 23519 // We have a variable of another type, so we store the type of the variable. 23520 // 1: Data.Var: type 23521 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 1); 23522 23523 ZigValue *payload = ira->codegen->pass1_arena->create<ZigValue>(); 23524 payload->special = ConstValSpecialStatic; 23525 payload->type = ira->codegen->builtin_types.entry_type; 23526 payload->data.x_type = var->const_value->type; 23527 23528 inner_fields[2]->data.x_union.payload = payload; 23529 } 23530 23531 break; 23532 } 23533 case TldIdFn: 23534 { 23535 // 2: Data.Fn: Data.FnDecl 23536 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 2); 23537 23538 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 23539 assert(!fn_entry->is_test); 23540 assert(fn_entry->type_entry != nullptr); 23541 23542 AstNodeFnProto *fn_node = &fn_entry->proto_node->data.fn_proto; 23543 23544 ZigValue *fn_decl_val = ira->codegen->pass1_arena->create<ZigValue>(); 23545 fn_decl_val->special = ConstValSpecialStatic; 23546 fn_decl_val->type = type_info_fn_decl_type; 23547 fn_decl_val->parent.id = ConstParentIdUnion; 23548 fn_decl_val->parent.data.p_union.union_val = inner_fields[2]; 23549 23550 ZigValue **fn_decl_fields = alloc_const_vals_ptrs(ira->codegen, 9); 23551 fn_decl_val->data.x_struct.fields = fn_decl_fields; 23552 23553 // fn_type: type 23554 ensure_field_index(fn_decl_val->type, "fn_type", 0); 23555 fn_decl_fields[0]->special = ConstValSpecialStatic; 23556 fn_decl_fields[0]->type = ira->codegen->builtin_types.entry_type; 23557 fn_decl_fields[0]->data.x_type = fn_entry->type_entry; 23558 // inline_type: Data.FnDecl.Inline 23559 ensure_field_index(fn_decl_val->type, "inline_type", 1); 23560 fn_decl_fields[1]->special = ConstValSpecialStatic; 23561 fn_decl_fields[1]->type = type_info_fn_decl_inline_type; 23562 bigint_init_unsigned(&fn_decl_fields[1]->data.x_enum_tag, fn_entry->fn_inline); 23563 // is_var_args: bool 23564 ensure_field_index(fn_decl_val->type, "is_var_args", 2); 23565 bool is_varargs = fn_node->is_var_args; 23566 fn_decl_fields[2]->special = ConstValSpecialStatic; 23567 fn_decl_fields[2]->type = ira->codegen->builtin_types.entry_bool; 23568 fn_decl_fields[2]->data.x_bool = is_varargs; 23569 // is_extern: bool 23570 ensure_field_index(fn_decl_val->type, "is_extern", 3); 23571 fn_decl_fields[3]->special = ConstValSpecialStatic; 23572 fn_decl_fields[3]->type = ira->codegen->builtin_types.entry_bool; 23573 fn_decl_fields[3]->data.x_bool = fn_node->is_extern; 23574 // is_export: bool 23575 ensure_field_index(fn_decl_val->type, "is_export", 4); 23576 fn_decl_fields[4]->special = ConstValSpecialStatic; 23577 fn_decl_fields[4]->type = ira->codegen->builtin_types.entry_bool; 23578 fn_decl_fields[4]->data.x_bool = fn_node->is_export; 23579 // lib_name: ?[]const u8 23580 ensure_field_index(fn_decl_val->type, "lib_name", 5); 23581 fn_decl_fields[5]->special = ConstValSpecialStatic; 23582 ZigType *u8_ptr = get_pointer_to_type_extra( 23583 ira->codegen, ira->codegen->builtin_types.entry_u8, 23584 true, false, PtrLenUnknown, 23585 0, 0, 0, false); 23586 fn_decl_fields[5]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); 23587 if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) { 23588 fn_decl_fields[5]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>(); 23589 ZigValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name)->data.x_ptr.data.ref.pointee; 23590 init_const_slice(ira->codegen, fn_decl_fields[5]->data.x_optional, lib_name, 0, 23591 buf_len(fn_node->lib_name), true); 23592 } else { 23593 fn_decl_fields[5]->data.x_optional = nullptr; 23594 } 23595 // return_type: type 23596 ensure_field_index(fn_decl_val->type, "return_type", 6); 23597 fn_decl_fields[6]->special = ConstValSpecialStatic; 23598 fn_decl_fields[6]->type = ira->codegen->builtin_types.entry_type; 23599 fn_decl_fields[6]->data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; 23600 // arg_names: [][] const u8 23601 ensure_field_index(fn_decl_val->type, "arg_names", 7); 23602 size_t fn_arg_count = fn_entry->variable_list.length; 23603 ZigValue *fn_arg_name_array = ira->codegen->pass1_arena->create<ZigValue>(); 23604 fn_arg_name_array->special = ConstValSpecialStatic; 23605 fn_arg_name_array->type = get_array_type(ira->codegen, 23606 get_slice_type(ira->codegen, u8_ptr), fn_arg_count, nullptr); 23607 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; 23608 fn_arg_name_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(fn_arg_count); 23609 23610 init_const_slice(ira->codegen, fn_decl_fields[7], fn_arg_name_array, 0, fn_arg_count, false); 23611 23612 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { 23613 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index); 23614 ZigValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index]; 23615 ZigValue *arg_name = create_const_str_lit(ira->codegen, 23616 buf_create_from_str(arg_var->name))->data.x_ptr.data.ref.pointee; 23617 init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, strlen(arg_var->name), true); 23618 fn_arg_name_val->parent.id = ConstParentIdArray; 23619 fn_arg_name_val->parent.data.p_array.array_val = fn_arg_name_array; 23620 fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index; 23621 } 23622 23623 inner_fields[2]->data.x_union.payload = fn_decl_val; 23624 break; 23625 } 23626 case TldIdContainer: 23627 { 23628 ZigType *type_entry = ((TldContainer *)curr_entry->value)->type_entry; 23629 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) 23630 return ErrorSemanticAnalyzeFail; 23631 23632 // This is a type. 23633 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0); 23634 23635 ZigValue *payload = ira->codegen->pass1_arena->create<ZigValue>(); 23636 payload->special = ConstValSpecialStatic; 23637 payload->type = ira->codegen->builtin_types.entry_type; 23638 payload->data.x_type = type_entry; 23639 23640 inner_fields[2]->data.x_union.payload = payload; 23641 23642 break; 23643 } 23644 default: 23645 zig_unreachable(); 23646 } 23647 23648 declaration_val->data.x_struct.fields = inner_fields; 23649 declaration_index += 1; 23650 } 23651 23652 assert(declaration_index == declaration_count); 23653 return ErrorNone; 23654 } 23655 23656 static BuiltinPtrSize ptr_len_to_size_enum_index(PtrLen ptr_len) { 23657 switch (ptr_len) { 23658 case PtrLenSingle: 23659 return BuiltinPtrSizeOne; 23660 case PtrLenUnknown: 23661 return BuiltinPtrSizeMany; 23662 case PtrLenC: 23663 return BuiltinPtrSizeC; 23664 } 23665 zig_unreachable(); 23666 } 23667 23668 static PtrLen size_enum_index_to_ptr_len(BuiltinPtrSize size_enum_index) { 23669 switch (size_enum_index) { 23670 case BuiltinPtrSizeOne: 23671 return PtrLenSingle; 23672 case BuiltinPtrSizeMany: 23673 case BuiltinPtrSizeSlice: 23674 return PtrLenUnknown; 23675 case BuiltinPtrSizeC: 23676 return PtrLenC; 23677 } 23678 zig_unreachable(); 23679 } 23680 23681 static ZigValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_entry) { 23682 Error err; 23683 ZigType *attrs_type; 23684 BuiltinPtrSize size_enum_index; 23685 if (is_slice(ptr_type_entry)) { 23686 attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index]->type_entry; 23687 size_enum_index = BuiltinPtrSizeSlice; 23688 } else if (ptr_type_entry->id == ZigTypeIdPointer) { 23689 attrs_type = ptr_type_entry; 23690 size_enum_index = ptr_len_to_size_enum_index(ptr_type_entry->data.pointer.ptr_len); 23691 } else { 23692 zig_unreachable(); 23693 } 23694 23695 if ((err = type_resolve(ira->codegen, attrs_type->data.pointer.child_type, ResolveStatusSizeKnown))) 23696 return nullptr; 23697 23698 ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); 23699 assertNoError(type_resolve(ira->codegen, type_info_pointer_type, ResolveStatusSizeKnown)); 23700 23701 ZigValue *result = ira->codegen->pass1_arena->create<ZigValue>(); 23702 result->special = ConstValSpecialStatic; 23703 result->type = type_info_pointer_type; 23704 23705 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 7); 23706 result->data.x_struct.fields = fields; 23707 23708 // size: Size 23709 ensure_field_index(result->type, "size", 0); 23710 ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type); 23711 assertNoError(type_resolve(ira->codegen, type_info_pointer_size_type, ResolveStatusSizeKnown)); 23712 fields[0]->special = ConstValSpecialStatic; 23713 fields[0]->type = type_info_pointer_size_type; 23714 bigint_init_unsigned(&fields[0]->data.x_enum_tag, size_enum_index); 23715 23716 // is_const: bool 23717 ensure_field_index(result->type, "is_const", 1); 23718 fields[1]->special = ConstValSpecialStatic; 23719 fields[1]->type = ira->codegen->builtin_types.entry_bool; 23720 fields[1]->data.x_bool = attrs_type->data.pointer.is_const; 23721 // is_volatile: bool 23722 ensure_field_index(result->type, "is_volatile", 2); 23723 fields[2]->special = ConstValSpecialStatic; 23724 fields[2]->type = ira->codegen->builtin_types.entry_bool; 23725 fields[2]->data.x_bool = attrs_type->data.pointer.is_volatile; 23726 // alignment: u32 23727 ensure_field_index(result->type, "alignment", 3); 23728 fields[3]->special = ConstValSpecialStatic; 23729 fields[3]->type = ira->codegen->builtin_types.entry_num_lit_int; 23730 bigint_init_unsigned(&fields[3]->data.x_bigint, get_ptr_align(ira->codegen, attrs_type)); 23731 // child: type 23732 ensure_field_index(result->type, "child", 4); 23733 fields[4]->special = ConstValSpecialStatic; 23734 fields[4]->type = ira->codegen->builtin_types.entry_type; 23735 fields[4]->data.x_type = attrs_type->data.pointer.child_type; 23736 // is_allowzero: bool 23737 ensure_field_index(result->type, "is_allowzero", 5); 23738 fields[5]->special = ConstValSpecialStatic; 23739 fields[5]->type = ira->codegen->builtin_types.entry_bool; 23740 fields[5]->data.x_bool = attrs_type->data.pointer.allow_zero; 23741 // sentinel: var 23742 ensure_field_index(result->type, "sentinel", 6); 23743 fields[6]->special = ConstValSpecialStatic; 23744 if (attrs_type->data.pointer.child_type->id != ZigTypeIdOpaque) { 23745 fields[6]->type = get_optional_type(ira->codegen, attrs_type->data.pointer.child_type); 23746 set_optional_payload(fields[6], attrs_type->data.pointer.sentinel); 23747 } else { 23748 fields[6]->type = ira->codegen->builtin_types.entry_null; 23749 } 23750 23751 return result; 23752 }; 23753 23754 static void make_enum_field_val(IrAnalyze *ira, ZigValue *enum_field_val, TypeEnumField *enum_field, 23755 ZigType *type_info_enum_field_type) 23756 { 23757 enum_field_val->special = ConstValSpecialStatic; 23758 enum_field_val->type = type_info_enum_field_type; 23759 23760 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 2); 23761 inner_fields[1]->special = ConstValSpecialStatic; 23762 inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; 23763 23764 ZigValue *name = create_const_str_lit(ira->codegen, enum_field->name)->data.x_ptr.data.ref.pointee; 23765 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(enum_field->name), true); 23766 23767 bigint_init_bigint(&inner_fields[1]->data.x_bigint, &enum_field->value); 23768 23769 enum_field_val->data.x_struct.fields = inner_fields; 23770 } 23771 23772 static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigType *type_entry, 23773 ZigValue **out) 23774 { 23775 Error err; 23776 assert(type_entry != nullptr); 23777 assert(!type_is_invalid(type_entry)); 23778 23779 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) 23780 return err; 23781 23782 auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); 23783 if (entry != nullptr) { 23784 *out = entry->value; 23785 return ErrorNone; 23786 } 23787 23788 ZigValue *result = nullptr; 23789 switch (type_entry->id) { 23790 case ZigTypeIdInvalid: 23791 zig_unreachable(); 23792 case ZigTypeIdMetaType: 23793 case ZigTypeIdVoid: 23794 case ZigTypeIdBool: 23795 case ZigTypeIdUnreachable: 23796 case ZigTypeIdComptimeFloat: 23797 case ZigTypeIdComptimeInt: 23798 case ZigTypeIdEnumLiteral: 23799 case ZigTypeIdUndefined: 23800 case ZigTypeIdNull: 23801 case ZigTypeIdOpaque: 23802 result = ira->codegen->intern.for_void(); 23803 break; 23804 case ZigTypeIdInt: 23805 { 23806 result = ira->codegen->pass1_arena->create<ZigValue>(); 23807 result->special = ConstValSpecialStatic; 23808 result->type = ir_type_info_get_type(ira, "Int", nullptr); 23809 23810 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2); 23811 result->data.x_struct.fields = fields; 23812 23813 // is_signed: bool 23814 ensure_field_index(result->type, "is_signed", 0); 23815 fields[0]->special = ConstValSpecialStatic; 23816 fields[0]->type = ira->codegen->builtin_types.entry_bool; 23817 fields[0]->data.x_bool = type_entry->data.integral.is_signed; 23818 // bits: u8 23819 ensure_field_index(result->type, "bits", 1); 23820 fields[1]->special = ConstValSpecialStatic; 23821 fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; 23822 bigint_init_unsigned(&fields[1]->data.x_bigint, type_entry->data.integral.bit_count); 23823 23824 break; 23825 } 23826 case ZigTypeIdFloat: 23827 { 23828 result = ira->codegen->pass1_arena->create<ZigValue>(); 23829 result->special = ConstValSpecialStatic; 23830 result->type = ir_type_info_get_type(ira, "Float", nullptr); 23831 23832 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); 23833 result->data.x_struct.fields = fields; 23834 23835 // bits: u8 23836 ensure_field_index(result->type, "bits", 0); 23837 fields[0]->special = ConstValSpecialStatic; 23838 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; 23839 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.floating.bit_count); 23840 23841 break; 23842 } 23843 case ZigTypeIdPointer: 23844 { 23845 result = create_ptr_like_type_info(ira, type_entry); 23846 if (result == nullptr) 23847 return ErrorSemanticAnalyzeFail; 23848 break; 23849 } 23850 case ZigTypeIdArray: 23851 { 23852 result = ira->codegen->pass1_arena->create<ZigValue>(); 23853 result->special = ConstValSpecialStatic; 23854 result->type = ir_type_info_get_type(ira, "Array", nullptr); 23855 23856 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 3); 23857 result->data.x_struct.fields = fields; 23858 23859 // len: usize 23860 ensure_field_index(result->type, "len", 0); 23861 fields[0]->special = ConstValSpecialStatic; 23862 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; 23863 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.array.len); 23864 // child: type 23865 ensure_field_index(result->type, "child", 1); 23866 fields[1]->special = ConstValSpecialStatic; 23867 fields[1]->type = ira->codegen->builtin_types.entry_type; 23868 fields[1]->data.x_type = type_entry->data.array.child_type; 23869 // sentinel: var 23870 fields[2]->special = ConstValSpecialStatic; 23871 fields[2]->type = get_optional_type(ira->codegen, type_entry->data.array.child_type); 23872 fields[2]->data.x_optional = type_entry->data.array.sentinel; 23873 break; 23874 } 23875 case ZigTypeIdVector: { 23876 result = ira->codegen->pass1_arena->create<ZigValue>(); 23877 result->special = ConstValSpecialStatic; 23878 result->type = ir_type_info_get_type(ira, "Vector", nullptr); 23879 23880 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2); 23881 result->data.x_struct.fields = fields; 23882 23883 // len: usize 23884 ensure_field_index(result->type, "len", 0); 23885 fields[0]->special = ConstValSpecialStatic; 23886 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; 23887 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.vector.len); 23888 // child: type 23889 ensure_field_index(result->type, "child", 1); 23890 fields[1]->special = ConstValSpecialStatic; 23891 fields[1]->type = ira->codegen->builtin_types.entry_type; 23892 fields[1]->data.x_type = type_entry->data.vector.elem_type; 23893 23894 break; 23895 } 23896 case ZigTypeIdOptional: 23897 { 23898 result = ira->codegen->pass1_arena->create<ZigValue>(); 23899 result->special = ConstValSpecialStatic; 23900 result->type = ir_type_info_get_type(ira, "Optional", nullptr); 23901 23902 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); 23903 result->data.x_struct.fields = fields; 23904 23905 // child: type 23906 ensure_field_index(result->type, "child", 0); 23907 fields[0]->special = ConstValSpecialStatic; 23908 fields[0]->type = ira->codegen->builtin_types.entry_type; 23909 fields[0]->data.x_type = type_entry->data.maybe.child_type; 23910 23911 break; 23912 } 23913 case ZigTypeIdAnyFrame: { 23914 result = ira->codegen->pass1_arena->create<ZigValue>(); 23915 result->special = ConstValSpecialStatic; 23916 result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr); 23917 23918 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); 23919 result->data.x_struct.fields = fields; 23920 23921 // child: ?type 23922 ensure_field_index(result->type, "child", 0); 23923 fields[0]->special = ConstValSpecialStatic; 23924 fields[0]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 23925 fields[0]->data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr : 23926 create_const_type(ira->codegen, type_entry->data.any_frame.result_type); 23927 break; 23928 } 23929 case ZigTypeIdEnum: 23930 { 23931 result = ira->codegen->pass1_arena->create<ZigValue>(); 23932 result->special = ConstValSpecialStatic; 23933 result->type = ir_type_info_get_type(ira, "Enum", nullptr); 23934 23935 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 5); 23936 result->data.x_struct.fields = fields; 23937 23938 // layout: ContainerLayout 23939 ensure_field_index(result->type, "layout", 0); 23940 fields[0]->special = ConstValSpecialStatic; 23941 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 23942 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.enumeration.layout); 23943 // tag_type: type 23944 ensure_field_index(result->type, "tag_type", 1); 23945 fields[1]->special = ConstValSpecialStatic; 23946 fields[1]->type = ira->codegen->builtin_types.entry_type; 23947 fields[1]->data.x_type = type_entry->data.enumeration.tag_int_type; 23948 // fields: []TypeInfo.EnumField 23949 ensure_field_index(result->type, "fields", 2); 23950 23951 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 23952 if ((err = type_resolve(ira->codegen, type_info_enum_field_type, ResolveStatusSizeKnown))) { 23953 zig_unreachable(); 23954 } 23955 uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; 23956 23957 ZigValue *enum_field_array = ira->codegen->pass1_arena->create<ZigValue>(); 23958 enum_field_array->special = ConstValSpecialStatic; 23959 enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count, nullptr); 23960 enum_field_array->data.x_array.special = ConstArraySpecialNone; 23961 enum_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(enum_field_count); 23962 23963 init_const_slice(ira->codegen, fields[2], enum_field_array, 0, enum_field_count, false); 23964 23965 for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) 23966 { 23967 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index]; 23968 ZigValue *enum_field_val = &enum_field_array->data.x_array.data.s_none.elements[enum_field_index]; 23969 make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type); 23970 enum_field_val->parent.id = ConstParentIdArray; 23971 enum_field_val->parent.data.p_array.array_val = enum_field_array; 23972 enum_field_val->parent.data.p_array.elem_index = enum_field_index; 23973 } 23974 // decls: []TypeInfo.Declaration 23975 ensure_field_index(result->type, "decls", 3); 23976 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3], 23977 type_entry->data.enumeration.decls_scope, false))) 23978 { 23979 return err; 23980 } 23981 // is_exhaustive: bool 23982 ensure_field_index(result->type, "is_exhaustive", 4); 23983 fields[4]->special = ConstValSpecialStatic; 23984 fields[4]->type = ira->codegen->builtin_types.entry_bool; 23985 fields[4]->data.x_bool = !type_entry->data.enumeration.non_exhaustive; 23986 23987 break; 23988 } 23989 case ZigTypeIdErrorSet: 23990 { 23991 result = ira->codegen->pass1_arena->create<ZigValue>(); 23992 result->special = ConstValSpecialStatic; 23993 result->type = ir_type_info_get_type(ira, "ErrorSet", nullptr); 23994 23995 ZigType *type_info_error_type = ir_type_info_get_type(ira, "Error", nullptr); 23996 if (!resolve_inferred_error_set(ira->codegen, type_entry, source_instr->source_node)) { 23997 return ErrorSemanticAnalyzeFail; 23998 } 23999 if (type_is_global_error_set(type_entry)) { 24000 result->data.x_optional = nullptr; 24001 break; 24002 } 24003 if ((err = type_resolve(ira->codegen, type_info_error_type, ResolveStatusSizeKnown))) { 24004 zig_unreachable(); 24005 } 24006 ZigValue *slice_val = ira->codegen->pass1_arena->create<ZigValue>(); 24007 result->data.x_optional = slice_val; 24008 24009 uint32_t error_count = type_entry->data.error_set.err_count; 24010 ZigValue *error_array = ira->codegen->pass1_arena->create<ZigValue>(); 24011 error_array->special = ConstValSpecialStatic; 24012 error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count, nullptr); 24013 error_array->data.x_array.special = ConstArraySpecialNone; 24014 error_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(error_count); 24015 24016 init_const_slice(ira->codegen, slice_val, error_array, 0, error_count, false); 24017 for (uint32_t error_index = 0; error_index < error_count; error_index++) { 24018 ErrorTableEntry *error = type_entry->data.error_set.errors[error_index]; 24019 ZigValue *error_val = &error_array->data.x_array.data.s_none.elements[error_index]; 24020 24021 error_val->special = ConstValSpecialStatic; 24022 error_val->type = type_info_error_type; 24023 24024 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 2); 24025 inner_fields[1]->special = ConstValSpecialStatic; 24026 inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; 24027 24028 ZigValue *name = nullptr; 24029 if (error->cached_error_name_val != nullptr) 24030 name = error->cached_error_name_val; 24031 if (name == nullptr) 24032 name = create_const_str_lit(ira->codegen, &error->name)->data.x_ptr.data.ref.pointee; 24033 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(&error->name), true); 24034 bigint_init_unsigned(&inner_fields[1]->data.x_bigint, error->value); 24035 24036 error_val->data.x_struct.fields = inner_fields; 24037 error_val->parent.id = ConstParentIdArray; 24038 error_val->parent.data.p_array.array_val = error_array; 24039 error_val->parent.data.p_array.elem_index = error_index; 24040 } 24041 24042 break; 24043 } 24044 case ZigTypeIdErrorUnion: 24045 { 24046 result = ira->codegen->pass1_arena->create<ZigValue>(); 24047 result->special = ConstValSpecialStatic; 24048 result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr); 24049 24050 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2); 24051 result->data.x_struct.fields = fields; 24052 24053 // error_set: type 24054 ensure_field_index(result->type, "error_set", 0); 24055 fields[0]->special = ConstValSpecialStatic; 24056 fields[0]->type = ira->codegen->builtin_types.entry_type; 24057 fields[0]->data.x_type = type_entry->data.error_union.err_set_type; 24058 24059 // payload: type 24060 ensure_field_index(result->type, "payload", 1); 24061 fields[1]->special = ConstValSpecialStatic; 24062 fields[1]->type = ira->codegen->builtin_types.entry_type; 24063 fields[1]->data.x_type = type_entry->data.error_union.payload_type; 24064 24065 break; 24066 } 24067 case ZigTypeIdUnion: 24068 { 24069 result = ira->codegen->pass1_arena->create<ZigValue>(); 24070 result->special = ConstValSpecialStatic; 24071 result->type = ir_type_info_get_type(ira, "Union", nullptr); 24072 24073 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 4); 24074 result->data.x_struct.fields = fields; 24075 24076 // layout: ContainerLayout 24077 ensure_field_index(result->type, "layout", 0); 24078 fields[0]->special = ConstValSpecialStatic; 24079 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 24080 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.unionation.layout); 24081 // tag_type: ?type 24082 ensure_field_index(result->type, "tag_type", 1); 24083 fields[1]->special = ConstValSpecialStatic; 24084 fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 24085 24086 AstNode *union_decl_node = type_entry->data.unionation.decl_node; 24087 if (union_decl_node->data.container_decl.auto_enum || 24088 union_decl_node->data.container_decl.init_arg_expr != nullptr) 24089 { 24090 ZigValue *tag_type = ira->codegen->pass1_arena->create<ZigValue>(); 24091 tag_type->special = ConstValSpecialStatic; 24092 tag_type->type = ira->codegen->builtin_types.entry_type; 24093 tag_type->data.x_type = type_entry->data.unionation.tag_type; 24094 fields[1]->data.x_optional = tag_type; 24095 } else { 24096 fields[1]->data.x_optional = nullptr; 24097 } 24098 // fields: []TypeInfo.UnionField 24099 ensure_field_index(result->type, "fields", 2); 24100 24101 ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr); 24102 if ((err = type_resolve(ira->codegen, type_info_union_field_type, ResolveStatusSizeKnown))) 24103 zig_unreachable(); 24104 uint32_t union_field_count = type_entry->data.unionation.src_field_count; 24105 24106 ZigValue *union_field_array = ira->codegen->pass1_arena->create<ZigValue>(); 24107 union_field_array->special = ConstValSpecialStatic; 24108 union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count, nullptr); 24109 union_field_array->data.x_array.special = ConstArraySpecialNone; 24110 union_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(union_field_count); 24111 24112 init_const_slice(ira->codegen, fields[2], union_field_array, 0, union_field_count, false); 24113 24114 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 24115 24116 for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) { 24117 TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index]; 24118 ZigValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index]; 24119 24120 union_field_val->special = ConstValSpecialStatic; 24121 union_field_val->type = type_info_union_field_type; 24122 24123 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3); 24124 inner_fields[1]->special = ConstValSpecialStatic; 24125 inner_fields[1]->type = get_optional_type(ira->codegen, type_info_enum_field_type); 24126 24127 if (fields[1]->data.x_optional == nullptr) { 24128 inner_fields[1]->data.x_optional = nullptr; 24129 } else { 24130 inner_fields[1]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>(); 24131 make_enum_field_val(ira, inner_fields[1]->data.x_optional, union_field->enum_field, type_info_enum_field_type); 24132 } 24133 24134 inner_fields[2]->special = ConstValSpecialStatic; 24135 inner_fields[2]->type = ira->codegen->builtin_types.entry_type; 24136 inner_fields[2]->data.x_type = union_field->type_entry; 24137 24138 ZigValue *name = create_const_str_lit(ira->codegen, union_field->name)->data.x_ptr.data.ref.pointee; 24139 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true); 24140 24141 union_field_val->data.x_struct.fields = inner_fields; 24142 union_field_val->parent.id = ConstParentIdArray; 24143 union_field_val->parent.data.p_array.array_val = union_field_array; 24144 union_field_val->parent.data.p_array.elem_index = union_field_index; 24145 } 24146 // decls: []TypeInfo.Declaration 24147 ensure_field_index(result->type, "decls", 3); 24148 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3], 24149 type_entry->data.unionation.decls_scope, false))) 24150 { 24151 return err; 24152 } 24153 24154 break; 24155 } 24156 case ZigTypeIdStruct: 24157 { 24158 if (type_entry->data.structure.special == StructSpecialSlice) { 24159 result = create_ptr_like_type_info(ira, type_entry); 24160 if (result == nullptr) 24161 return ErrorSemanticAnalyzeFail; 24162 break; 24163 } 24164 24165 result = ira->codegen->pass1_arena->create<ZigValue>(); 24166 result->special = ConstValSpecialStatic; 24167 result->type = ir_type_info_get_type(ira, "Struct", nullptr); 24168 24169 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 3); 24170 result->data.x_struct.fields = fields; 24171 24172 // layout: ContainerLayout 24173 ensure_field_index(result->type, "layout", 0); 24174 fields[0]->special = ConstValSpecialStatic; 24175 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 24176 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.structure.layout); 24177 // fields: []TypeInfo.StructField 24178 ensure_field_index(result->type, "fields", 1); 24179 24180 ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr); 24181 if ((err = type_resolve(ira->codegen, type_info_struct_field_type, ResolveStatusSizeKnown))) { 24182 zig_unreachable(); 24183 } 24184 uint32_t struct_field_count = type_entry->data.structure.src_field_count; 24185 24186 ZigValue *struct_field_array = ira->codegen->pass1_arena->create<ZigValue>(); 24187 struct_field_array->special = ConstValSpecialStatic; 24188 struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count, nullptr); 24189 struct_field_array->data.x_array.special = ConstArraySpecialNone; 24190 struct_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(struct_field_count); 24191 24192 init_const_slice(ira->codegen, fields[1], struct_field_array, 0, struct_field_count, false); 24193 24194 for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) { 24195 TypeStructField *struct_field = type_entry->data.structure.fields[struct_field_index]; 24196 ZigValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index]; 24197 24198 struct_field_val->special = ConstValSpecialStatic; 24199 struct_field_val->type = type_info_struct_field_type; 24200 24201 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 4); 24202 inner_fields[1]->special = ConstValSpecialStatic; 24203 inner_fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int); 24204 24205 ZigType *field_type = resolve_struct_field_type(ira->codegen, struct_field); 24206 if (field_type == nullptr) 24207 return ErrorSemanticAnalyzeFail; 24208 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) 24209 return err; 24210 if (!type_has_bits(struct_field->type_entry)) { 24211 inner_fields[1]->data.x_optional = nullptr; 24212 } else { 24213 size_t byte_offset = struct_field->offset; 24214 inner_fields[1]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>(); 24215 inner_fields[1]->data.x_optional->special = ConstValSpecialStatic; 24216 inner_fields[1]->data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int; 24217 bigint_init_unsigned(&inner_fields[1]->data.x_optional->data.x_bigint, byte_offset); 24218 } 24219 24220 inner_fields[2]->special = ConstValSpecialStatic; 24221 inner_fields[2]->type = ira->codegen->builtin_types.entry_type; 24222 inner_fields[2]->data.x_type = struct_field->type_entry; 24223 24224 // default_value: var 24225 inner_fields[3]->special = ConstValSpecialStatic; 24226 inner_fields[3]->type = get_optional_type(ira->codegen, struct_field->type_entry); 24227 memoize_field_init_val(ira->codegen, type_entry, struct_field); 24228 set_optional_payload(inner_fields[3], struct_field->init_val); 24229 24230 ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee; 24231 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true); 24232 24233 struct_field_val->data.x_struct.fields = inner_fields; 24234 struct_field_val->parent.id = ConstParentIdArray; 24235 struct_field_val->parent.data.p_array.array_val = struct_field_array; 24236 struct_field_val->parent.data.p_array.elem_index = struct_field_index; 24237 } 24238 // decls: []TypeInfo.Declaration 24239 ensure_field_index(result->type, "decls", 2); 24240 if ((err = ir_make_type_info_decls(ira, source_instr, fields[2], 24241 type_entry->data.structure.decls_scope, false))) 24242 { 24243 return err; 24244 } 24245 24246 break; 24247 } 24248 case ZigTypeIdFn: 24249 { 24250 result = ira->codegen->pass1_arena->create<ZigValue>(); 24251 result->special = ConstValSpecialStatic; 24252 result->type = ir_type_info_get_type(ira, "Fn", nullptr); 24253 24254 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 5); 24255 result->data.x_struct.fields = fields; 24256 24257 // calling_convention: TypeInfo.CallingConvention 24258 ensure_field_index(result->type, "calling_convention", 0); 24259 fields[0]->special = ConstValSpecialStatic; 24260 fields[0]->type = get_builtin_type(ira->codegen, "CallingConvention"); 24261 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); 24262 // is_generic: bool 24263 ensure_field_index(result->type, "is_generic", 1); 24264 bool is_generic = type_entry->data.fn.is_generic; 24265 fields[1]->special = ConstValSpecialStatic; 24266 fields[1]->type = ira->codegen->builtin_types.entry_bool; 24267 fields[1]->data.x_bool = is_generic; 24268 // is_varargs: bool 24269 ensure_field_index(result->type, "is_var_args", 2); 24270 bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; 24271 fields[2]->special = ConstValSpecialStatic; 24272 fields[2]->type = ira->codegen->builtin_types.entry_bool; 24273 fields[2]->data.x_bool = type_entry->data.fn.fn_type_id.is_var_args; 24274 // return_type: ?type 24275 ensure_field_index(result->type, "return_type", 3); 24276 fields[3]->special = ConstValSpecialStatic; 24277 fields[3]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 24278 if (type_entry->data.fn.fn_type_id.return_type == nullptr) 24279 fields[3]->data.x_optional = nullptr; 24280 else { 24281 ZigValue *return_type = ira->codegen->pass1_arena->create<ZigValue>(); 24282 return_type->special = ConstValSpecialStatic; 24283 return_type->type = ira->codegen->builtin_types.entry_type; 24284 return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; 24285 fields[3]->data.x_optional = return_type; 24286 } 24287 // args: []TypeInfo.FnArg 24288 ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); 24289 if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { 24290 zig_unreachable(); 24291 } 24292 size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - 24293 (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); 24294 24295 ZigValue *fn_arg_array = ira->codegen->pass1_arena->create<ZigValue>(); 24296 fn_arg_array->special = ConstValSpecialStatic; 24297 fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count, nullptr); 24298 fn_arg_array->data.x_array.special = ConstArraySpecialNone; 24299 fn_arg_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(fn_arg_count); 24300 24301 init_const_slice(ira->codegen, fields[4], fn_arg_array, 0, fn_arg_count, false); 24302 24303 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { 24304 FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; 24305 ZigValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index]; 24306 24307 fn_arg_val->special = ConstValSpecialStatic; 24308 fn_arg_val->type = type_info_fn_arg_type; 24309 24310 bool arg_is_generic = fn_param_info->type == nullptr; 24311 if (arg_is_generic) assert(is_generic); 24312 24313 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3); 24314 inner_fields[0]->special = ConstValSpecialStatic; 24315 inner_fields[0]->type = ira->codegen->builtin_types.entry_bool; 24316 inner_fields[0]->data.x_bool = arg_is_generic; 24317 inner_fields[1]->special = ConstValSpecialStatic; 24318 inner_fields[1]->type = ira->codegen->builtin_types.entry_bool; 24319 inner_fields[1]->data.x_bool = fn_param_info->is_noalias; 24320 inner_fields[2]->special = ConstValSpecialStatic; 24321 inner_fields[2]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 24322 24323 if (arg_is_generic) 24324 inner_fields[2]->data.x_optional = nullptr; 24325 else { 24326 ZigValue *arg_type = ira->codegen->pass1_arena->create<ZigValue>(); 24327 arg_type->special = ConstValSpecialStatic; 24328 arg_type->type = ira->codegen->builtin_types.entry_type; 24329 arg_type->data.x_type = fn_param_info->type; 24330 inner_fields[2]->data.x_optional = arg_type; 24331 } 24332 24333 fn_arg_val->data.x_struct.fields = inner_fields; 24334 fn_arg_val->parent.id = ConstParentIdArray; 24335 fn_arg_val->parent.data.p_array.array_val = fn_arg_array; 24336 fn_arg_val->parent.data.p_array.elem_index = fn_arg_index; 24337 } 24338 24339 break; 24340 } 24341 case ZigTypeIdBoundFn: 24342 { 24343 ZigType *fn_type = type_entry->data.bound_fn.fn_type; 24344 assert(fn_type->id == ZigTypeIdFn); 24345 if ((err = ir_make_type_info_value(ira, source_instr, fn_type, &result))) 24346 return err; 24347 24348 break; 24349 } 24350 case ZigTypeIdFnFrame: 24351 ir_add_error(ira, source_instr, 24352 buf_sprintf("compiler bug: TODO @typeInfo for async function frames. https://github.com/ziglang/zig/issues/3066")); 24353 return ErrorSemanticAnalyzeFail; 24354 } 24355 24356 assert(result != nullptr); 24357 ira->codegen->type_info_cache.put(type_entry, result); 24358 *out = result; 24359 return ErrorNone; 24360 } 24361 24362 static IrInstGen *ir_analyze_instruction_type_info(IrAnalyze *ira, IrInstSrcTypeInfo *instruction) { 24363 Error err; 24364 IrInstGen *type_value = instruction->type_value->child; 24365 ZigType *type_entry = ir_resolve_type(ira, type_value); 24366 if (type_is_invalid(type_entry)) 24367 return ira->codegen->invalid_inst_gen; 24368 24369 ZigType *result_type = ir_type_info_get_type(ira, nullptr, nullptr); 24370 24371 ZigValue *payload; 24372 if ((err = ir_make_type_info_value(ira, &instruction->base.base, type_entry, &payload))) 24373 return ira->codegen->invalid_inst_gen; 24374 24375 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 24376 ZigValue *out_val = result->value; 24377 bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry)); 24378 out_val->data.x_union.payload = payload; 24379 24380 if (payload != nullptr) { 24381 payload->parent.id = ConstParentIdUnion; 24382 payload->parent.data.p_union.union_val = out_val; 24383 } 24384 24385 return result; 24386 } 24387 24388 static ZigValue *get_const_field(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, 24389 const char *name, size_t field_index) 24390 { 24391 Error err; 24392 ensure_field_index(struct_value->type, name, field_index); 24393 ZigValue *val = struct_value->data.x_struct.fields[field_index]; 24394 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_node, val, UndefBad))) 24395 return nullptr; 24396 return val; 24397 } 24398 24399 static Error get_const_field_sentinel(IrAnalyze *ira, IrInst* source_instr, ZigValue *struct_value, 24400 const char *name, size_t field_index, ZigType *elem_type, ZigValue **result) 24401 { 24402 ZigValue *field_val = get_const_field(ira, source_instr->source_node, struct_value, name, field_index); 24403 if (field_val == nullptr) 24404 return ErrorSemanticAnalyzeFail; 24405 24406 IrInstGen *field_inst = ir_const_move(ira, source_instr, field_val); 24407 IrInstGen *casted_field_inst = ir_implicit_cast(ira, field_inst, 24408 get_optional_type(ira->codegen, elem_type)); 24409 if (type_is_invalid(casted_field_inst->value->type)) 24410 return ErrorSemanticAnalyzeFail; 24411 24412 if (optional_value_is_null(casted_field_inst->value)) { 24413 *result = nullptr; 24414 } else { 24415 assert(type_has_optional_repr(casted_field_inst->value->type)); 24416 *result = casted_field_inst->value->data.x_optional; 24417 } 24418 24419 return ErrorNone; 24420 } 24421 24422 static Error get_const_field_bool(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, 24423 const char *name, size_t field_index, bool *out) 24424 { 24425 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 24426 if (value == nullptr) 24427 return ErrorSemanticAnalyzeFail; 24428 assert(value->type == ira->codegen->builtin_types.entry_bool); 24429 *out = value->data.x_bool; 24430 return ErrorNone; 24431 } 24432 24433 static BigInt *get_const_field_lit_int(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) 24434 { 24435 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 24436 if (value == nullptr) 24437 return nullptr; 24438 assert(value->type == ira->codegen->builtin_types.entry_num_lit_int); 24439 return &value->data.x_bigint; 24440 } 24441 24442 static ZigType *get_const_field_meta_type(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) 24443 { 24444 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 24445 if (value == nullptr) 24446 return ira->codegen->invalid_inst_gen->value->type; 24447 assert(value->type == ira->codegen->builtin_types.entry_type); 24448 return value->data.x_type; 24449 } 24450 24451 static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeId tagTypeId, ZigValue *payload) { 24452 Error err; 24453 switch (tagTypeId) { 24454 case ZigTypeIdInvalid: 24455 zig_unreachable(); 24456 case ZigTypeIdMetaType: 24457 return ira->codegen->builtin_types.entry_type; 24458 case ZigTypeIdVoid: 24459 return ira->codegen->builtin_types.entry_void; 24460 case ZigTypeIdBool: 24461 return ira->codegen->builtin_types.entry_bool; 24462 case ZigTypeIdUnreachable: 24463 return ira->codegen->builtin_types.entry_unreachable; 24464 case ZigTypeIdInt: { 24465 assert(payload->special == ConstValSpecialStatic); 24466 assert(payload->type == ir_type_info_get_type(ira, "Int", nullptr)); 24467 BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "bits", 1); 24468 if (bi == nullptr) 24469 return ira->codegen->invalid_inst_gen->value->type; 24470 bool is_signed; 24471 if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_signed", 0, &is_signed))) 24472 return ira->codegen->invalid_inst_gen->value->type; 24473 return get_int_type(ira->codegen, is_signed, bigint_as_u32(bi)); 24474 } 24475 case ZigTypeIdFloat: 24476 { 24477 assert(payload->special == ConstValSpecialStatic); 24478 assert(payload->type == ir_type_info_get_type(ira, "Float", nullptr)); 24479 BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "bits", 0); 24480 if (bi == nullptr) 24481 return ira->codegen->invalid_inst_gen->value->type; 24482 uint32_t bits = bigint_as_u32(bi); 24483 switch (bits) { 24484 case 16: return ira->codegen->builtin_types.entry_f16; 24485 case 32: return ira->codegen->builtin_types.entry_f32; 24486 case 64: return ira->codegen->builtin_types.entry_f64; 24487 case 128: return ira->codegen->builtin_types.entry_f128; 24488 } 24489 ir_add_error(ira, source_instr, buf_sprintf("%d-bit float unsupported", bits)); 24490 return ira->codegen->invalid_inst_gen->value->type; 24491 } 24492 case ZigTypeIdPointer: 24493 { 24494 ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); 24495 assert(payload->special == ConstValSpecialStatic); 24496 assert(payload->type == type_info_pointer_type); 24497 ZigValue *size_value = get_const_field(ira, source_instr->source_node, payload, "size", 0); 24498 assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type)); 24499 BuiltinPtrSize size_enum_index = (BuiltinPtrSize)bigint_as_u32(&size_value->data.x_enum_tag); 24500 PtrLen ptr_len = size_enum_index_to_ptr_len(size_enum_index); 24501 ZigType *elem_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 4); 24502 if (type_is_invalid(elem_type)) 24503 return ira->codegen->invalid_inst_gen->value->type; 24504 ZigValue *sentinel; 24505 if ((err = get_const_field_sentinel(ira, source_instr, payload, "sentinel", 6, 24506 elem_type, &sentinel))) 24507 { 24508 return ira->codegen->invalid_inst_gen->value->type; 24509 } 24510 BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "alignment", 3); 24511 if (bi == nullptr) 24512 return ira->codegen->invalid_inst_gen->value->type; 24513 24514 bool is_const; 24515 if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_const", 1, &is_const))) 24516 return ira->codegen->invalid_inst_gen->value->type; 24517 24518 bool is_volatile; 24519 if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_volatile", 2, 24520 &is_volatile))) 24521 { 24522 return ira->codegen->invalid_inst_gen->value->type; 24523 } 24524 24525 bool is_allowzero; 24526 if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_allowzero", 5, 24527 &is_allowzero))) 24528 { 24529 return ira->codegen->invalid_inst_gen->value->type; 24530 } 24531 24532 24533 ZigType *ptr_type = get_pointer_to_type_extra2(ira->codegen, 24534 elem_type, 24535 is_const, 24536 is_volatile, 24537 ptr_len, 24538 bigint_as_u32(bi), 24539 0, // bit_offset_in_host 24540 0, // host_int_bytes 24541 is_allowzero, 24542 VECTOR_INDEX_NONE, nullptr, sentinel); 24543 if (size_enum_index != 2) 24544 return ptr_type; 24545 return get_slice_type(ira->codegen, ptr_type); 24546 } 24547 case ZigTypeIdArray: { 24548 assert(payload->special == ConstValSpecialStatic); 24549 assert(payload->type == ir_type_info_get_type(ira, "Array", nullptr)); 24550 ZigType *elem_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 1); 24551 if (type_is_invalid(elem_type)) 24552 return ira->codegen->invalid_inst_gen->value->type; 24553 ZigValue *sentinel; 24554 if ((err = get_const_field_sentinel(ira, source_instr, payload, "sentinel", 2, 24555 elem_type, &sentinel))) 24556 { 24557 return ira->codegen->invalid_inst_gen->value->type; 24558 } 24559 BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "len", 0); 24560 if (bi == nullptr) 24561 return ira->codegen->invalid_inst_gen->value->type; 24562 return get_array_type(ira->codegen, elem_type, bigint_as_u64(bi), sentinel); 24563 } 24564 case ZigTypeIdComptimeFloat: 24565 return ira->codegen->builtin_types.entry_num_lit_float; 24566 case ZigTypeIdComptimeInt: 24567 return ira->codegen->builtin_types.entry_num_lit_int; 24568 case ZigTypeIdUndefined: 24569 return ira->codegen->builtin_types.entry_undef; 24570 case ZigTypeIdNull: 24571 return ira->codegen->builtin_types.entry_null; 24572 case ZigTypeIdOptional: 24573 case ZigTypeIdErrorUnion: 24574 case ZigTypeIdErrorSet: 24575 case ZigTypeIdEnum: 24576 case ZigTypeIdOpaque: 24577 case ZigTypeIdFnFrame: 24578 case ZigTypeIdAnyFrame: 24579 case ZigTypeIdVector: 24580 case ZigTypeIdEnumLiteral: 24581 ir_add_error(ira, source_instr, buf_sprintf( 24582 "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId))); 24583 return ira->codegen->invalid_inst_gen->value->type; 24584 case ZigTypeIdUnion: 24585 case ZigTypeIdFn: 24586 case ZigTypeIdBoundFn: 24587 case ZigTypeIdStruct: 24588 ir_add_error(ira, source_instr, buf_sprintf( 24589 "@Type not availble for 'TypeInfo.%s'", type_id_name(tagTypeId))); 24590 return ira->codegen->invalid_inst_gen->value->type; 24591 } 24592 zig_unreachable(); 24593 } 24594 24595 static IrInstGen *ir_analyze_instruction_type(IrAnalyze *ira, IrInstSrcType *instruction) { 24596 IrInstGen *uncasted_type_info = instruction->type_info->child; 24597 if (type_is_invalid(uncasted_type_info->value->type)) 24598 return ira->codegen->invalid_inst_gen; 24599 24600 IrInstGen *type_info = ir_implicit_cast(ira, uncasted_type_info, ir_type_info_get_type(ira, nullptr, nullptr)); 24601 if (type_is_invalid(type_info->value->type)) 24602 return ira->codegen->invalid_inst_gen; 24603 24604 ZigValue *type_info_val = ir_resolve_const(ira, type_info, UndefBad); 24605 if (type_info_val == nullptr) 24606 return ira->codegen->invalid_inst_gen; 24607 ZigTypeId type_id_tag = type_id_at_index(bigint_as_usize(&type_info_val->data.x_union.tag)); 24608 ZigType *type = type_info_to_type(ira, &uncasted_type_info->base, type_id_tag, 24609 type_info_val->data.x_union.payload); 24610 if (type_is_invalid(type)) 24611 return ira->codegen->invalid_inst_gen; 24612 return ir_const_type(ira, &instruction->base.base, type); 24613 } 24614 24615 static IrInstGen *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira, 24616 IrInstSrcSetEvalBranchQuota *instruction) 24617 { 24618 uint64_t new_quota; 24619 if (!ir_resolve_usize(ira, instruction->new_quota->child, &new_quota)) 24620 return ira->codegen->invalid_inst_gen; 24621 24622 if (new_quota > *ira->new_irb.exec->backward_branch_quota) { 24623 *ira->new_irb.exec->backward_branch_quota = new_quota; 24624 } 24625 24626 return ir_const_void(ira, &instruction->base.base); 24627 } 24628 24629 static IrInstGen *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstSrcTypeName *instruction) { 24630 IrInstGen *type_value = instruction->type_value->child; 24631 ZigType *type_entry = ir_resolve_type(ira, type_value); 24632 if (type_is_invalid(type_entry)) 24633 return ira->codegen->invalid_inst_gen; 24634 24635 if (!type_entry->cached_const_name_val) { 24636 type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, type_bare_name(type_entry)); 24637 } 24638 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 24639 copy_const_val(ira->codegen, result->value, type_entry->cached_const_name_val); 24640 return result; 24641 } 24642 24643 static void ir_cimport_cache_paths(Buf *cache_dir, Buf *tmp_c_file_digest, Buf *out_zig_dir, Buf *out_zig_path) { 24644 buf_resize(out_zig_dir, 0); 24645 buf_resize(out_zig_path, 0); 24646 buf_appendf(out_zig_dir, "%s" OS_SEP "o" OS_SEP "%s", 24647 buf_ptr(cache_dir), buf_ptr(tmp_c_file_digest)); 24648 buf_appendf(out_zig_path, "%s" OS_SEP "cimport.zig", buf_ptr(out_zig_dir)); 24649 } 24650 static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImport *instruction) { 24651 Error err; 24652 AstNode *node = instruction->base.base.source_node; 24653 assert(node->type == NodeTypeFnCallExpr); 24654 AstNode *block_node = node->data.fn_call_expr.params.at(0); 24655 24656 ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.base.scope); 24657 24658 // Execute the C import block like an inline function 24659 ZigType *void_type = ira->codegen->builtin_types.entry_void; 24660 ZigValue *cimport_result; 24661 ZigValue *result_ptr; 24662 create_result_ptr(ira->codegen, void_type, &cimport_result, &result_ptr); 24663 if ((err = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, result_ptr, 24664 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, 24665 &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, UndefBad))) 24666 { 24667 return ira->codegen->invalid_inst_gen; 24668 } 24669 if (type_is_invalid(cimport_result->type)) 24670 return ira->codegen->invalid_inst_gen; 24671 24672 ZigPackage *cur_scope_pkg = scope_package(instruction->base.base.scope); 24673 Buf *namespace_name = buf_sprintf("%s.cimport:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, 24674 buf_ptr(&cur_scope_pkg->pkg_path), node->line + 1, node->column + 1); 24675 24676 ZigPackage *cimport_pkg = new_anonymous_package(); 24677 cimport_pkg->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package); 24678 cimport_pkg->package_table.put(buf_create_from_str("std"), ira->codegen->std_package); 24679 buf_init_from_buf(&cimport_pkg->pkg_path, namespace_name); 24680 24681 CacheHash *cache_hash; 24682 if ((err = create_c_object_cache(ira->codegen, &cache_hash, false))) { 24683 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to create cache: %s", err_str(err))); 24684 return ira->codegen->invalid_inst_gen; 24685 } 24686 cache_buf(cache_hash, &cimport_scope->buf); 24687 24688 // Set this because we're not adding any files before checking for a hit. 24689 cache_hash->force_check_manifest = true; 24690 24691 Buf tmp_c_file_digest = BUF_INIT; 24692 buf_resize(&tmp_c_file_digest, 0); 24693 if ((err = cache_hit(cache_hash, &tmp_c_file_digest))) { 24694 if (err != ErrorInvalidFormat) { 24695 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to check cache: %s", err_str(err))); 24696 return ira->codegen->invalid_inst_gen; 24697 } 24698 } 24699 ira->codegen->caches_to_release.append(cache_hash); 24700 24701 Buf *out_zig_dir = buf_alloc(); 24702 Buf *out_zig_path = buf_alloc(); 24703 if (buf_len(&tmp_c_file_digest) == 0 || cache_hash->files.length == 0) { 24704 // Cache Miss 24705 Buf *tmp_c_file_dir = buf_sprintf("%s" OS_SEP "o" OS_SEP "%s", 24706 buf_ptr(ira->codegen->cache_dir), buf_ptr(&cache_hash->b64_digest)); 24707 Buf *resolve_paths[] = { 24708 tmp_c_file_dir, 24709 buf_create_from_str("cimport.h"), 24710 }; 24711 Buf tmp_c_file_path = os_path_resolve(resolve_paths, 2); 24712 24713 if ((err = os_make_path(tmp_c_file_dir))) { 24714 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); 24715 return ira->codegen->invalid_inst_gen; 24716 } 24717 24718 if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { 24719 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); 24720 return ira->codegen->invalid_inst_gen; 24721 } 24722 if (ira->codegen->verbose_cimport) { 24723 fprintf(stderr, "@cImport source: %s\n", buf_ptr(&tmp_c_file_path)); 24724 } 24725 24726 Buf *tmp_dep_file = buf_sprintf("%s.d", buf_ptr(&tmp_c_file_path)); 24727 24728 ZigList<const char *> clang_argv = {0}; 24729 24730 add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true); 24731 24732 clang_argv.append(buf_ptr(&tmp_c_file_path)); 24733 24734 if (ira->codegen->verbose_cc) { 24735 fprintf(stderr, "clang"); 24736 for (size_t i = 0; i < clang_argv.length; i += 1) { 24737 fprintf(stderr, " %s", clang_argv.at(i)); 24738 } 24739 fprintf(stderr, "\n"); 24740 } 24741 24742 clang_argv.append(nullptr); // to make the [start...end] argument work 24743 24744 Stage2ErrorMsg *errors_ptr; 24745 size_t errors_len; 24746 Stage2Ast *ast; 24747 24748 const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir); 24749 24750 if ((err = stage2_translate_c(&ast, &errors_ptr, &errors_len, 24751 &clang_argv.at(0), &clang_argv.last(), resources_path))) 24752 { 24753 if (err != ErrorCCompileErrors) { 24754 ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err))); 24755 return ira->codegen->invalid_inst_gen; 24756 } 24757 24758 ErrorMsg *parent_err_msg = ir_add_error_node(ira, node, buf_sprintf("C import failed")); 24759 if (ira->codegen->libc_link_lib == nullptr) { 24760 add_error_note(ira->codegen, parent_err_msg, node, 24761 buf_sprintf("libc headers not available; compilation does not link against libc")); 24762 } 24763 for (size_t i = 0; i < errors_len; i += 1) { 24764 Stage2ErrorMsg *clang_err = &errors_ptr[i]; 24765 // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null 24766 if (clang_err->source && clang_err->filename_ptr) { 24767 ErrorMsg *err_msg = err_msg_create_with_offset( 24768 clang_err->filename_ptr ? 24769 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(), 24770 clang_err->line, clang_err->column, clang_err->offset, clang_err->source, 24771 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); 24772 err_msg_add_note(parent_err_msg, err_msg); 24773 } 24774 } 24775 24776 return ira->codegen->invalid_inst_gen; 24777 } 24778 if (ira->codegen->verbose_cimport) { 24779 fprintf(stderr, "@cImport .d file: %s\n", buf_ptr(tmp_dep_file)); 24780 } 24781 24782 if ((err = cache_add_dep_file(cache_hash, tmp_dep_file, false))) { 24783 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to parse .d file: %s", err_str(err))); 24784 return ira->codegen->invalid_inst_gen; 24785 } 24786 if ((err = cache_final(cache_hash, &tmp_c_file_digest))) { 24787 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to finalize cache: %s", err_str(err))); 24788 return ira->codegen->invalid_inst_gen; 24789 } 24790 24791 ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); 24792 if ((err = os_make_path(out_zig_dir))) { 24793 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make output dir: %s", err_str(err))); 24794 return ira->codegen->invalid_inst_gen; 24795 } 24796 FILE *out_file = fopen(buf_ptr(out_zig_path), "wb"); 24797 if (out_file == nullptr) { 24798 ir_add_error_node(ira, node, 24799 buf_sprintf("C import failed: unable to open output file: %s", strerror(errno))); 24800 return ira->codegen->invalid_inst_gen; 24801 } 24802 stage2_render_ast(ast, out_file); 24803 if (fclose(out_file) != 0) { 24804 ir_add_error_node(ira, node, 24805 buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno))); 24806 return ira->codegen->invalid_inst_gen; 24807 } 24808 24809 if (ira->codegen->verbose_cimport) { 24810 fprintf(stderr, "@cImport output: %s\n", buf_ptr(out_zig_path)); 24811 } 24812 24813 } else { 24814 // Cache Hit 24815 ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); 24816 if (ira->codegen->verbose_cimport) { 24817 fprintf(stderr, "@cImport cache hit: %s\n", buf_ptr(out_zig_path)); 24818 } 24819 } 24820 24821 Buf *import_code = buf_alloc(); 24822 if ((err = file_fetch(ira->codegen, out_zig_path, import_code))) { 24823 ir_add_error_node(ira, node, 24824 buf_sprintf("unable to open '%s': %s", buf_ptr(out_zig_path), err_str(err))); 24825 return ira->codegen->invalid_inst_gen; 24826 } 24827 ZigType *child_import = add_source_file(ira->codegen, cimport_pkg, out_zig_path, 24828 import_code, SourceKindCImport); 24829 return ir_const_type(ira, &instruction->base.base, child_import); 24830 } 24831 24832 static IrInstGen *ir_analyze_instruction_c_include(IrAnalyze *ira, IrInstSrcCInclude *instruction) { 24833 IrInstGen *name_value = instruction->name->child; 24834 if (type_is_invalid(name_value->value->type)) 24835 return ira->codegen->invalid_inst_gen; 24836 24837 Buf *include_name = ir_resolve_str(ira, name_value); 24838 if (!include_name) 24839 return ira->codegen->invalid_inst_gen; 24840 24841 Buf *c_import_buf = ira->new_irb.exec->c_import_buf; 24842 // We check for this error in pass1 24843 assert(c_import_buf); 24844 24845 buf_appendf(c_import_buf, "#include <%s>\n", buf_ptr(include_name)); 24846 24847 return ir_const_void(ira, &instruction->base.base); 24848 } 24849 24850 static IrInstGen *ir_analyze_instruction_c_define(IrAnalyze *ira, IrInstSrcCDefine *instruction) { 24851 IrInstGen *name = instruction->name->child; 24852 if (type_is_invalid(name->value->type)) 24853 return ira->codegen->invalid_inst_gen; 24854 24855 Buf *define_name = ir_resolve_str(ira, name); 24856 if (!define_name) 24857 return ira->codegen->invalid_inst_gen; 24858 24859 IrInstGen *value = instruction->value->child; 24860 if (type_is_invalid(value->value->type)) 24861 return ira->codegen->invalid_inst_gen; 24862 24863 Buf *define_value = nullptr; 24864 // The second parameter is either a string or void (equivalent to "") 24865 if (value->value->type->id != ZigTypeIdVoid) { 24866 define_value = ir_resolve_str(ira, value); 24867 if (!define_value) 24868 return ira->codegen->invalid_inst_gen; 24869 } 24870 24871 Buf *c_import_buf = ira->new_irb.exec->c_import_buf; 24872 // We check for this error in pass1 24873 assert(c_import_buf); 24874 24875 buf_appendf(c_import_buf, "#define %s %s\n", buf_ptr(define_name), 24876 define_value ? buf_ptr(define_value) : ""); 24877 24878 return ir_const_void(ira, &instruction->base.base); 24879 } 24880 24881 static IrInstGen *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstSrcCUndef *instruction) { 24882 IrInstGen *name = instruction->name->child; 24883 if (type_is_invalid(name->value->type)) 24884 return ira->codegen->invalid_inst_gen; 24885 24886 Buf *undef_name = ir_resolve_str(ira, name); 24887 if (!undef_name) 24888 return ira->codegen->invalid_inst_gen; 24889 24890 Buf *c_import_buf = ira->new_irb.exec->c_import_buf; 24891 // We check for this error in pass1 24892 assert(c_import_buf); 24893 24894 buf_appendf(c_import_buf, "#undef %s\n", buf_ptr(undef_name)); 24895 24896 return ir_const_void(ira, &instruction->base.base); 24897 } 24898 24899 static IrInstGen *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstSrcEmbedFile *instruction) { 24900 IrInstGen *name = instruction->name->child; 24901 if (type_is_invalid(name->value->type)) 24902 return ira->codegen->invalid_inst_gen; 24903 24904 Buf *rel_file_path = ir_resolve_str(ira, name); 24905 if (!rel_file_path) 24906 return ira->codegen->invalid_inst_gen; 24907 24908 ZigType *import = get_scope_import(instruction->base.base.scope); 24909 // figure out absolute path to resource 24910 Buf source_dir_path = BUF_INIT; 24911 os_path_dirname(import->data.structure.root_struct->path, &source_dir_path); 24912 24913 Buf *resolve_paths[] = { 24914 &source_dir_path, 24915 rel_file_path, 24916 }; 24917 Buf *file_path = buf_alloc(); 24918 *file_path = os_path_resolve(resolve_paths, 2); 24919 24920 // load from file system into const expr 24921 Buf *file_contents = buf_alloc(); 24922 Error err; 24923 if ((err = file_fetch(ira->codegen, file_path, file_contents))) { 24924 if (err == ErrorFileNotFound) { 24925 ir_add_error(ira, &instruction->name->base, 24926 buf_sprintf("unable to find '%s'", buf_ptr(file_path))); 24927 return ira->codegen->invalid_inst_gen; 24928 } else { 24929 ir_add_error(ira, &instruction->name->base, 24930 buf_sprintf("unable to open '%s': %s", buf_ptr(file_path), err_str(err))); 24931 return ira->codegen->invalid_inst_gen; 24932 } 24933 } 24934 24935 ZigType *result_type = get_array_type(ira->codegen, 24936 ira->codegen->builtin_types.entry_u8, buf_len(file_contents), nullptr); 24937 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 24938 init_const_str_lit(ira->codegen, result->value, file_contents); 24939 return result; 24940 } 24941 24942 static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxchg *instruction) { 24943 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->type_value->child); 24944 if (type_is_invalid(operand_type)) 24945 return ira->codegen->invalid_inst_gen; 24946 24947 if (operand_type->id == ZigTypeIdFloat) { 24948 ir_add_error(ira, &instruction->type_value->child->base, 24949 buf_sprintf("expected integer, enum or pointer type, found '%s'", buf_ptr(&operand_type->name))); 24950 return ira->codegen->invalid_inst_gen; 24951 } 24952 24953 IrInstGen *ptr = instruction->ptr->child; 24954 if (type_is_invalid(ptr->value->type)) 24955 return ira->codegen->invalid_inst_gen; 24956 24957 // TODO let this be volatile 24958 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 24959 IrInstGen *casted_ptr = ir_implicit_cast2(ira, &instruction->ptr->base, ptr, ptr_type); 24960 if (type_is_invalid(casted_ptr->value->type)) 24961 return ira->codegen->invalid_inst_gen; 24962 24963 IrInstGen *cmp_value = instruction->cmp_value->child; 24964 if (type_is_invalid(cmp_value->value->type)) 24965 return ira->codegen->invalid_inst_gen; 24966 24967 IrInstGen *new_value = instruction->new_value->child; 24968 if (type_is_invalid(new_value->value->type)) 24969 return ira->codegen->invalid_inst_gen; 24970 24971 IrInstGen *success_order_value = instruction->success_order_value->child; 24972 if (type_is_invalid(success_order_value->value->type)) 24973 return ira->codegen->invalid_inst_gen; 24974 24975 AtomicOrder success_order; 24976 if (!ir_resolve_atomic_order(ira, success_order_value, &success_order)) 24977 return ira->codegen->invalid_inst_gen; 24978 24979 IrInstGen *failure_order_value = instruction->failure_order_value->child; 24980 if (type_is_invalid(failure_order_value->value->type)) 24981 return ira->codegen->invalid_inst_gen; 24982 24983 AtomicOrder failure_order; 24984 if (!ir_resolve_atomic_order(ira, failure_order_value, &failure_order)) 24985 return ira->codegen->invalid_inst_gen; 24986 24987 IrInstGen *casted_cmp_value = ir_implicit_cast2(ira, &instruction->cmp_value->base, cmp_value, operand_type); 24988 if (type_is_invalid(casted_cmp_value->value->type)) 24989 return ira->codegen->invalid_inst_gen; 24990 24991 IrInstGen *casted_new_value = ir_implicit_cast2(ira, &instruction->new_value->base, new_value, operand_type); 24992 if (type_is_invalid(casted_new_value->value->type)) 24993 return ira->codegen->invalid_inst_gen; 24994 24995 if (success_order < AtomicOrderMonotonic) { 24996 ir_add_error(ira, &success_order_value->base, 24997 buf_sprintf("success atomic ordering must be Monotonic or stricter")); 24998 return ira->codegen->invalid_inst_gen; 24999 } 25000 if (failure_order < AtomicOrderMonotonic) { 25001 ir_add_error(ira, &failure_order_value->base, 25002 buf_sprintf("failure atomic ordering must be Monotonic or stricter")); 25003 return ira->codegen->invalid_inst_gen; 25004 } 25005 if (failure_order > success_order) { 25006 ir_add_error(ira, &failure_order_value->base, 25007 buf_sprintf("failure atomic ordering must be no stricter than success")); 25008 return ira->codegen->invalid_inst_gen; 25009 } 25010 if (failure_order == AtomicOrderRelease || failure_order == AtomicOrderAcqRel) { 25011 ir_add_error(ira, &failure_order_value->base, 25012 buf_sprintf("failure atomic ordering must not be Release or AcqRel")); 25013 return ira->codegen->invalid_inst_gen; 25014 } 25015 25016 if (instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar && 25017 instr_is_comptime(casted_cmp_value) && instr_is_comptime(casted_new_value)) { 25018 zig_panic("TODO compile-time execution of cmpxchg"); 25019 } 25020 25021 ZigType *result_type = get_optional_type(ira->codegen, operand_type); 25022 IrInstGen *result_loc; 25023 if (handle_is_ptr(result_type)) { 25024 result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 25025 result_type, nullptr, true, true); 25026 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 25027 return result_loc; 25028 } 25029 } else { 25030 result_loc = nullptr; 25031 } 25032 25033 return ir_build_cmpxchg_gen(ira, &instruction->base.base, result_type, 25034 casted_ptr, casted_cmp_value, casted_new_value, 25035 success_order, failure_order, instruction->is_weak, result_loc); 25036 } 25037 25038 static IrInstGen *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstSrcFence *instruction) { 25039 IrInstGen *order_inst = instruction->order->child; 25040 if (type_is_invalid(order_inst->value->type)) 25041 return ira->codegen->invalid_inst_gen; 25042 25043 AtomicOrder order; 25044 if (!ir_resolve_atomic_order(ira, order_inst, &order)) 25045 return ira->codegen->invalid_inst_gen; 25046 25047 if (order < AtomicOrderAcquire) { 25048 ir_add_error(ira, &order_inst->base, 25049 buf_sprintf("atomic ordering must be Acquire or stricter")); 25050 return ira->codegen->invalid_inst_gen; 25051 } 25052 25053 return ir_build_fence_gen(ira, &instruction->base.base, order); 25054 } 25055 25056 static IrInstGen *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstSrcTruncate *instruction) { 25057 IrInstGen *dest_type_value = instruction->dest_type->child; 25058 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 25059 if (type_is_invalid(dest_type)) 25060 return ira->codegen->invalid_inst_gen; 25061 25062 if (dest_type->id != ZigTypeIdInt && 25063 dest_type->id != ZigTypeIdComptimeInt) 25064 { 25065 ir_add_error(ira, &dest_type_value->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 25066 return ira->codegen->invalid_inst_gen; 25067 } 25068 25069 IrInstGen *target = instruction->target->child; 25070 ZigType *src_type = target->value->type; 25071 if (type_is_invalid(src_type)) 25072 return ira->codegen->invalid_inst_gen; 25073 25074 if (src_type->id != ZigTypeIdInt && 25075 src_type->id != ZigTypeIdComptimeInt) 25076 { 25077 ir_add_error(ira, &target->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&src_type->name))); 25078 return ira->codegen->invalid_inst_gen; 25079 } 25080 25081 if (dest_type->id == ZigTypeIdComptimeInt) { 25082 return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); 25083 } 25084 25085 if (instr_is_comptime(target)) { 25086 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 25087 if (val == nullptr) 25088 return ira->codegen->invalid_inst_gen; 25089 25090 IrInstGen *result = ir_const(ira, &instruction->base.base, dest_type); 25091 bigint_truncate(&result->value->data.x_bigint, &val->data.x_bigint, 25092 dest_type->data.integral.bit_count, dest_type->data.integral.is_signed); 25093 return result; 25094 } 25095 25096 if (src_type->data.integral.bit_count == 0 || dest_type->data.integral.bit_count == 0) { 25097 IrInstGen *result = ir_const(ira, &instruction->base.base, dest_type); 25098 bigint_init_unsigned(&result->value->data.x_bigint, 0); 25099 return result; 25100 } 25101 25102 if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) { 25103 const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned"; 25104 ir_add_error(ira, &target->base, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name))); 25105 return ira->codegen->invalid_inst_gen; 25106 } else if (src_type->data.integral.bit_count < dest_type->data.integral.bit_count) { 25107 ir_add_error(ira, &target->base, buf_sprintf("type '%s' has fewer bits than destination type '%s'", 25108 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 25109 return ira->codegen->invalid_inst_gen; 25110 } 25111 25112 return ir_build_truncate_gen(ira, &instruction->base.base, dest_type, target); 25113 } 25114 25115 static IrInstGen *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstSrcIntCast *instruction) { 25116 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 25117 if (type_is_invalid(dest_type)) 25118 return ira->codegen->invalid_inst_gen; 25119 25120 if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { 25121 ir_add_error(ira, &instruction->dest_type->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 25122 return ira->codegen->invalid_inst_gen; 25123 } 25124 25125 IrInstGen *target = instruction->target->child; 25126 if (type_is_invalid(target->value->type)) 25127 return ira->codegen->invalid_inst_gen; 25128 25129 if (target->value->type->id != ZigTypeIdInt && target->value->type->id != ZigTypeIdComptimeInt) { 25130 ir_add_error(ira, &instruction->target->base, buf_sprintf("expected integer type, found '%s'", 25131 buf_ptr(&target->value->type->name))); 25132 return ira->codegen->invalid_inst_gen; 25133 } 25134 25135 if (instr_is_comptime(target)) { 25136 return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); 25137 } 25138 25139 if (dest_type->id == ZigTypeIdComptimeInt) { 25140 ir_add_error(ira, &instruction->target->base, buf_sprintf("attempt to cast runtime value to '%s'", 25141 buf_ptr(&dest_type->name))); 25142 return ira->codegen->invalid_inst_gen; 25143 } 25144 25145 return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type); 25146 } 25147 25148 static IrInstGen *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstSrcFloatCast *instruction) { 25149 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 25150 if (type_is_invalid(dest_type)) 25151 return ira->codegen->invalid_inst_gen; 25152 25153 if (dest_type->id != ZigTypeIdFloat) { 25154 ir_add_error(ira, &instruction->dest_type->base, 25155 buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); 25156 return ira->codegen->invalid_inst_gen; 25157 } 25158 25159 IrInstGen *target = instruction->target->child; 25160 if (type_is_invalid(target->value->type)) 25161 return ira->codegen->invalid_inst_gen; 25162 25163 if (target->value->type->id == ZigTypeIdComptimeInt || 25164 target->value->type->id == ZigTypeIdComptimeFloat) 25165 { 25166 if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { 25167 CastOp op; 25168 if (target->value->type->id == ZigTypeIdComptimeInt) { 25169 op = CastOpIntToFloat; 25170 } else { 25171 op = CastOpNumLitToConcrete; 25172 } 25173 return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, op); 25174 } else { 25175 return ira->codegen->invalid_inst_gen; 25176 } 25177 } 25178 25179 if (target->value->type->id != ZigTypeIdFloat) { 25180 ir_add_error(ira, &instruction->target->base, buf_sprintf("expected float type, found '%s'", 25181 buf_ptr(&target->value->type->name))); 25182 return ira->codegen->invalid_inst_gen; 25183 } 25184 25185 return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type); 25186 } 25187 25188 static IrInstGen *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstSrcErrSetCast *instruction) { 25189 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 25190 if (type_is_invalid(dest_type)) 25191 return ira->codegen->invalid_inst_gen; 25192 25193 if (dest_type->id != ZigTypeIdErrorSet) { 25194 ir_add_error(ira, &instruction->dest_type->base, 25195 buf_sprintf("expected error set type, found '%s'", buf_ptr(&dest_type->name))); 25196 return ira->codegen->invalid_inst_gen; 25197 } 25198 25199 IrInstGen *target = instruction->target->child; 25200 if (type_is_invalid(target->value->type)) 25201 return ira->codegen->invalid_inst_gen; 25202 25203 if (target->value->type->id != ZigTypeIdErrorSet) { 25204 ir_add_error(ira, &instruction->target->base, 25205 buf_sprintf("expected error set type, found '%s'", buf_ptr(&target->value->type->name))); 25206 return ira->codegen->invalid_inst_gen; 25207 } 25208 25209 return ir_analyze_err_set_cast(ira, &instruction->base.base, target, dest_type); 25210 } 25211 25212 static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { 25213 Error err; 25214 25215 ZigType *ptr_type = get_src_ptr_type(ty); 25216 assert(ptr_type != nullptr); 25217 if (ptr_type->id == ZigTypeIdPointer) { 25218 if ((err = type_resolve(ira->codegen, ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 25219 return err; 25220 } 25221 25222 *result_align = get_ptr_align(ira->codegen, ty); 25223 return ErrorNone; 25224 } 25225 25226 static IrInstGen *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstSrcIntToFloat *instruction) { 25227 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 25228 if (type_is_invalid(dest_type)) 25229 return ira->codegen->invalid_inst_gen; 25230 25231 IrInstGen *target = instruction->target->child; 25232 if (type_is_invalid(target->value->type)) 25233 return ira->codegen->invalid_inst_gen; 25234 25235 if (target->value->type->id != ZigTypeIdInt && target->value->type->id != ZigTypeIdComptimeInt) { 25236 ir_add_error(ira, &instruction->target->base, buf_sprintf("expected int type, found '%s'", 25237 buf_ptr(&target->value->type->name))); 25238 return ira->codegen->invalid_inst_gen; 25239 } 25240 25241 return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, CastOpIntToFloat); 25242 } 25243 25244 static IrInstGen *ir_analyze_float_to_int(IrAnalyze *ira, IrInst* source_instr, 25245 ZigType *dest_type, IrInstGen *operand, AstNode *operand_source_node) 25246 { 25247 if (operand->value->type->id == ZigTypeIdComptimeInt) { 25248 return ir_implicit_cast(ira, operand, dest_type); 25249 } 25250 25251 if (operand->value->type->id != ZigTypeIdFloat && operand->value->type->id != ZigTypeIdComptimeFloat) { 25252 ir_add_error_node(ira, operand_source_node, buf_sprintf("expected float type, found '%s'", 25253 buf_ptr(&operand->value->type->name))); 25254 return ira->codegen->invalid_inst_gen; 25255 } 25256 25257 return ir_resolve_cast(ira, source_instr, operand, dest_type, CastOpFloatToInt); 25258 } 25259 25260 static IrInstGen *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstSrcFloatToInt *instruction) { 25261 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 25262 if (type_is_invalid(dest_type)) 25263 return ira->codegen->invalid_inst_gen; 25264 25265 IrInstGen *operand = instruction->target->child; 25266 if (type_is_invalid(operand->value->type)) 25267 return ira->codegen->invalid_inst_gen; 25268 25269 return ir_analyze_float_to_int(ira, &instruction->base.base, dest_type, operand, 25270 instruction->target->base.source_node); 25271 } 25272 25273 static IrInstGen *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstSrcErrToInt *instruction) { 25274 IrInstGen *target = instruction->target->child; 25275 if (type_is_invalid(target->value->type)) 25276 return ira->codegen->invalid_inst_gen; 25277 25278 IrInstGen *casted_target; 25279 if (target->value->type->id == ZigTypeIdErrorSet) { 25280 casted_target = target; 25281 } else { 25282 casted_target = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_global_error_set); 25283 if (type_is_invalid(casted_target->value->type)) 25284 return ira->codegen->invalid_inst_gen; 25285 } 25286 25287 return ir_analyze_err_to_int(ira, &instruction->base.base, casted_target, ira->codegen->err_tag_type); 25288 } 25289 25290 static IrInstGen *ir_analyze_instruction_int_to_err(IrAnalyze *ira, IrInstSrcIntToErr *instruction) { 25291 IrInstGen *target = instruction->target->child; 25292 if (type_is_invalid(target->value->type)) 25293 return ira->codegen->invalid_inst_gen; 25294 25295 IrInstGen *casted_target = ir_implicit_cast(ira, target, ira->codegen->err_tag_type); 25296 if (type_is_invalid(casted_target->value->type)) 25297 return ira->codegen->invalid_inst_gen; 25298 25299 return ir_analyze_int_to_err(ira, &instruction->base.base, casted_target, ira->codegen->builtin_types.entry_global_error_set); 25300 } 25301 25302 static IrInstGen *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstSrcBoolToInt *instruction) { 25303 IrInstGen *target = instruction->target->child; 25304 if (type_is_invalid(target->value->type)) 25305 return ira->codegen->invalid_inst_gen; 25306 25307 if (target->value->type->id != ZigTypeIdBool) { 25308 ir_add_error(ira, &instruction->target->base, buf_sprintf("expected bool, found '%s'", 25309 buf_ptr(&target->value->type->name))); 25310 return ira->codegen->invalid_inst_gen; 25311 } 25312 25313 if (instr_is_comptime(target)) { 25314 bool is_true; 25315 if (!ir_resolve_bool(ira, target, &is_true)) 25316 return ira->codegen->invalid_inst_gen; 25317 25318 return ir_const_unsigned(ira, &instruction->base.base, is_true ? 1 : 0); 25319 } 25320 25321 ZigType *u1_type = get_int_type(ira->codegen, false, 1); 25322 return ir_resolve_cast(ira, &instruction->base.base, target, u1_type, CastOpBoolToInt); 25323 } 25324 25325 static IrInstGen *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstSrcVectorType *instruction) { 25326 uint64_t len; 25327 if (!ir_resolve_unsigned(ira, instruction->len->child, ira->codegen->builtin_types.entry_u32, &len)) 25328 return ira->codegen->invalid_inst_gen; 25329 25330 ZigType *elem_type = ir_resolve_vector_elem_type(ira, instruction->elem_type->child); 25331 if (type_is_invalid(elem_type)) 25332 return ira->codegen->invalid_inst_gen; 25333 25334 ZigType *vector_type = get_vector_type(ira->codegen, len, elem_type); 25335 25336 return ir_const_type(ira, &instruction->base.base, vector_type); 25337 } 25338 25339 static IrInstGen *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInst* source_instr, 25340 ZigType *scalar_type, IrInstGen *a, IrInstGen *b, IrInstGen *mask) 25341 { 25342 ir_assert(source_instr && scalar_type && a && b && mask, source_instr); 25343 ir_assert(is_valid_vector_elem_type(scalar_type), source_instr); 25344 25345 uint32_t len_mask; 25346 if (mask->value->type->id == ZigTypeIdVector) { 25347 len_mask = mask->value->type->data.vector.len; 25348 } else if (mask->value->type->id == ZigTypeIdArray) { 25349 len_mask = mask->value->type->data.array.len; 25350 } else { 25351 ir_add_error(ira, &mask->base, 25352 buf_sprintf("expected vector or array, found '%s'", 25353 buf_ptr(&mask->value->type->name))); 25354 return ira->codegen->invalid_inst_gen; 25355 } 25356 mask = ir_implicit_cast(ira, mask, get_vector_type(ira->codegen, len_mask, 25357 ira->codegen->builtin_types.entry_i32)); 25358 if (type_is_invalid(mask->value->type)) 25359 return ira->codegen->invalid_inst_gen; 25360 25361 uint32_t len_a; 25362 if (a->value->type->id == ZigTypeIdVector) { 25363 len_a = a->value->type->data.vector.len; 25364 } else if (a->value->type->id == ZigTypeIdArray) { 25365 len_a = a->value->type->data.array.len; 25366 } else if (a->value->type->id == ZigTypeIdUndefined) { 25367 len_a = UINT32_MAX; 25368 } else { 25369 ir_add_error(ira, &a->base, 25370 buf_sprintf("expected vector or array with element type '%s', found '%s'", 25371 buf_ptr(&scalar_type->name), 25372 buf_ptr(&a->value->type->name))); 25373 return ira->codegen->invalid_inst_gen; 25374 } 25375 25376 uint32_t len_b; 25377 if (b->value->type->id == ZigTypeIdVector) { 25378 len_b = b->value->type->data.vector.len; 25379 } else if (b->value->type->id == ZigTypeIdArray) { 25380 len_b = b->value->type->data.array.len; 25381 } else if (b->value->type->id == ZigTypeIdUndefined) { 25382 len_b = UINT32_MAX; 25383 } else { 25384 ir_add_error(ira, &b->base, 25385 buf_sprintf("expected vector or array with element type '%s', found '%s'", 25386 buf_ptr(&scalar_type->name), 25387 buf_ptr(&b->value->type->name))); 25388 return ira->codegen->invalid_inst_gen; 25389 } 25390 25391 if (len_a == UINT32_MAX && len_b == UINT32_MAX) { 25392 return ir_const_undef(ira, &a->base, get_vector_type(ira->codegen, len_mask, scalar_type)); 25393 } 25394 25395 if (len_a == UINT32_MAX) { 25396 len_a = len_b; 25397 a = ir_const_undef(ira, &a->base, get_vector_type(ira->codegen, len_a, scalar_type)); 25398 } else { 25399 a = ir_implicit_cast(ira, a, get_vector_type(ira->codegen, len_a, scalar_type)); 25400 if (type_is_invalid(a->value->type)) 25401 return ira->codegen->invalid_inst_gen; 25402 } 25403 25404 if (len_b == UINT32_MAX) { 25405 len_b = len_a; 25406 b = ir_const_undef(ira, &b->base, get_vector_type(ira->codegen, len_b, scalar_type)); 25407 } else { 25408 b = ir_implicit_cast(ira, b, get_vector_type(ira->codegen, len_b, scalar_type)); 25409 if (type_is_invalid(b->value->type)) 25410 return ira->codegen->invalid_inst_gen; 25411 } 25412 25413 ZigValue *mask_val = ir_resolve_const(ira, mask, UndefOk); 25414 if (mask_val == nullptr) 25415 return ira->codegen->invalid_inst_gen; 25416 25417 expand_undef_array(ira->codegen, mask_val); 25418 25419 for (uint32_t i = 0; i < len_mask; i += 1) { 25420 ZigValue *mask_elem_val = &mask_val->data.x_array.data.s_none.elements[i]; 25421 if (mask_elem_val->special == ConstValSpecialUndef) 25422 continue; 25423 int32_t v_i32 = bigint_as_signed(&mask_elem_val->data.x_bigint); 25424 uint32_t v; 25425 IrInstGen *chosen_operand; 25426 if (v_i32 >= 0) { 25427 v = (uint32_t)v_i32; 25428 chosen_operand = a; 25429 } else { 25430 v = (uint32_t)~v_i32; 25431 chosen_operand = b; 25432 } 25433 if (v >= chosen_operand->value->type->data.vector.len) { 25434 ErrorMsg *msg = ir_add_error(ira, &mask->base, 25435 buf_sprintf("mask index '%u' has out-of-bounds selection", i)); 25436 add_error_note(ira->codegen, msg, chosen_operand->base.source_node, 25437 buf_sprintf("selected index '%u' out of bounds of %s", v, 25438 buf_ptr(&chosen_operand->value->type->name))); 25439 if (chosen_operand == a && v < len_a + len_b) { 25440 add_error_note(ira->codegen, msg, b->base.source_node, 25441 buf_create_from_str("selections from the second vector are specified with negative numbers")); 25442 } 25443 return ira->codegen->invalid_inst_gen; 25444 } 25445 } 25446 25447 ZigType *result_type = get_vector_type(ira->codegen, len_mask, scalar_type); 25448 if (instr_is_comptime(a) && instr_is_comptime(b)) { 25449 ZigValue *a_val = ir_resolve_const(ira, a, UndefOk); 25450 if (a_val == nullptr) 25451 return ira->codegen->invalid_inst_gen; 25452 25453 ZigValue *b_val = ir_resolve_const(ira, b, UndefOk); 25454 if (b_val == nullptr) 25455 return ira->codegen->invalid_inst_gen; 25456 25457 expand_undef_array(ira->codegen, a_val); 25458 expand_undef_array(ira->codegen, b_val); 25459 25460 IrInstGen *result = ir_const(ira, source_instr, result_type); 25461 result->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(len_mask); 25462 for (uint32_t i = 0; i < mask_val->type->data.vector.len; i += 1) { 25463 ZigValue *mask_elem_val = &mask_val->data.x_array.data.s_none.elements[i]; 25464 ZigValue *result_elem_val = &result->value->data.x_array.data.s_none.elements[i]; 25465 if (mask_elem_val->special == ConstValSpecialUndef) { 25466 result_elem_val->special = ConstValSpecialUndef; 25467 continue; 25468 } 25469 int32_t v = bigint_as_signed(&mask_elem_val->data.x_bigint); 25470 // We've already checked for and emitted compile errors for index out of bounds here. 25471 ZigValue *src_elem_val = (v >= 0) ? 25472 &a->value->data.x_array.data.s_none.elements[v] : 25473 &b->value->data.x_array.data.s_none.elements[~v]; 25474 copy_const_val(ira->codegen, result_elem_val, src_elem_val); 25475 25476 ir_assert(result_elem_val->special == ConstValSpecialStatic, source_instr); 25477 } 25478 result->value->special = ConstValSpecialStatic; 25479 return result; 25480 } 25481 25482 // All static analysis passed, and not comptime. 25483 // For runtime codegen, vectors a and b must be the same length. Here we 25484 // recursively @shuffle the smaller vector to append undefined elements 25485 // to it up to the length of the longer vector. This recursion terminates 25486 // in 1 call because these calls to ir_analyze_shuffle_vector guarantee 25487 // len_a == len_b. 25488 if (len_a != len_b) { 25489 uint32_t len_min = min(len_a, len_b); 25490 uint32_t len_max = max(len_a, len_b); 25491 25492 IrInstGen *expand_mask = ir_const(ira, &mask->base, 25493 get_vector_type(ira->codegen, len_max, ira->codegen->builtin_types.entry_i32)); 25494 expand_mask->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(len_max); 25495 uint32_t i = 0; 25496 for (; i < len_min; i += 1) 25497 bigint_init_unsigned(&expand_mask->value->data.x_array.data.s_none.elements[i].data.x_bigint, i); 25498 for (; i < len_max; i += 1) 25499 bigint_init_signed(&expand_mask->value->data.x_array.data.s_none.elements[i].data.x_bigint, -1); 25500 25501 IrInstGen *undef = ir_const_undef(ira, source_instr, 25502 get_vector_type(ira->codegen, len_min, scalar_type)); 25503 25504 if (len_b < len_a) { 25505 b = ir_analyze_shuffle_vector(ira, source_instr, scalar_type, b, undef, expand_mask); 25506 } else { 25507 a = ir_analyze_shuffle_vector(ira, source_instr, scalar_type, a, undef, expand_mask); 25508 } 25509 } 25510 25511 return ir_build_shuffle_vector_gen(ira, source_instr->scope, source_instr->source_node, 25512 result_type, a, b, mask); 25513 } 25514 25515 static IrInstGen *ir_analyze_instruction_shuffle_vector(IrAnalyze *ira, IrInstSrcShuffleVector *instruction) { 25516 ZigType *scalar_type = ir_resolve_vector_elem_type(ira, instruction->scalar_type->child); 25517 if (type_is_invalid(scalar_type)) 25518 return ira->codegen->invalid_inst_gen; 25519 25520 IrInstGen *a = instruction->a->child; 25521 if (type_is_invalid(a->value->type)) 25522 return ira->codegen->invalid_inst_gen; 25523 25524 IrInstGen *b = instruction->b->child; 25525 if (type_is_invalid(b->value->type)) 25526 return ira->codegen->invalid_inst_gen; 25527 25528 IrInstGen *mask = instruction->mask->child; 25529 if (type_is_invalid(mask->value->type)) 25530 return ira->codegen->invalid_inst_gen; 25531 25532 return ir_analyze_shuffle_vector(ira, &instruction->base.base, scalar_type, a, b, mask); 25533 } 25534 25535 static IrInstGen *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstSrcSplat *instruction) { 25536 Error err; 25537 25538 IrInstGen *len = instruction->len->child; 25539 if (type_is_invalid(len->value->type)) 25540 return ira->codegen->invalid_inst_gen; 25541 25542 IrInstGen *scalar = instruction->scalar->child; 25543 if (type_is_invalid(scalar->value->type)) 25544 return ira->codegen->invalid_inst_gen; 25545 25546 uint64_t len_u64; 25547 if (!ir_resolve_unsigned(ira, len, ira->codegen->builtin_types.entry_u32, &len_u64)) 25548 return ira->codegen->invalid_inst_gen; 25549 uint32_t len_int = len_u64; 25550 25551 if ((err = ir_validate_vector_elem_type(ira, scalar->base.source_node, scalar->value->type))) 25552 return ira->codegen->invalid_inst_gen; 25553 25554 ZigType *return_type = get_vector_type(ira->codegen, len_int, scalar->value->type); 25555 25556 if (instr_is_comptime(scalar)) { 25557 ZigValue *scalar_val = ir_resolve_const(ira, scalar, UndefOk); 25558 if (scalar_val == nullptr) 25559 return ira->codegen->invalid_inst_gen; 25560 if (scalar_val->special == ConstValSpecialUndef) 25561 return ir_const_undef(ira, &instruction->base.base, return_type); 25562 25563 IrInstGen *result = ir_const(ira, &instruction->base.base, return_type); 25564 result->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(len_int); 25565 for (uint32_t i = 0; i < len_int; i += 1) { 25566 copy_const_val(ira->codegen, &result->value->data.x_array.data.s_none.elements[i], scalar_val); 25567 } 25568 return result; 25569 } 25570 25571 return ir_build_splat_gen(ira, &instruction->base.base, return_type, scalar); 25572 } 25573 25574 static IrInstGen *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstSrcBoolNot *instruction) { 25575 IrInstGen *value = instruction->value->child; 25576 if (type_is_invalid(value->value->type)) 25577 return ira->codegen->invalid_inst_gen; 25578 25579 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 25580 25581 IrInstGen *casted_value = ir_implicit_cast(ira, value, bool_type); 25582 if (type_is_invalid(casted_value->value->type)) 25583 return ira->codegen->invalid_inst_gen; 25584 25585 if (instr_is_comptime(casted_value)) { 25586 ZigValue *value = ir_resolve_const(ira, casted_value, UndefBad); 25587 if (value == nullptr) 25588 return ira->codegen->invalid_inst_gen; 25589 25590 return ir_const_bool(ira, &instruction->base.base, !value->data.x_bool); 25591 } 25592 25593 return ir_build_bool_not_gen(ira, &instruction->base.base, casted_value); 25594 } 25595 25596 static IrInstGen *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstSrcMemset *instruction) { 25597 Error err; 25598 25599 IrInstGen *dest_ptr = instruction->dest_ptr->child; 25600 if (type_is_invalid(dest_ptr->value->type)) 25601 return ira->codegen->invalid_inst_gen; 25602 25603 IrInstGen *byte_value = instruction->byte->child; 25604 if (type_is_invalid(byte_value->value->type)) 25605 return ira->codegen->invalid_inst_gen; 25606 25607 IrInstGen *count_value = instruction->count->child; 25608 if (type_is_invalid(count_value->value->type)) 25609 return ira->codegen->invalid_inst_gen; 25610 25611 ZigType *dest_uncasted_type = dest_ptr->value->type; 25612 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 25613 dest_uncasted_type->data.pointer.is_volatile; 25614 25615 ZigType *usize = ira->codegen->builtin_types.entry_usize; 25616 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 25617 uint32_t dest_align; 25618 if (dest_uncasted_type->id == ZigTypeIdPointer) { 25619 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 25620 return ira->codegen->invalid_inst_gen; 25621 } else { 25622 dest_align = get_abi_alignment(ira->codegen, u8); 25623 } 25624 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 25625 PtrLenUnknown, dest_align, 0, 0, false); 25626 25627 IrInstGen *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr); 25628 if (type_is_invalid(casted_dest_ptr->value->type)) 25629 return ira->codegen->invalid_inst_gen; 25630 25631 IrInstGen *casted_byte = ir_implicit_cast(ira, byte_value, u8); 25632 if (type_is_invalid(casted_byte->value->type)) 25633 return ira->codegen->invalid_inst_gen; 25634 25635 IrInstGen *casted_count = ir_implicit_cast(ira, count_value, usize); 25636 if (type_is_invalid(casted_count->value->type)) 25637 return ira->codegen->invalid_inst_gen; 25638 25639 // TODO test this at comptime with u8 and non-u8 types 25640 if (instr_is_comptime(casted_dest_ptr) && 25641 instr_is_comptime(casted_byte) && 25642 instr_is_comptime(casted_count)) 25643 { 25644 ZigValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); 25645 if (dest_ptr_val == nullptr) 25646 return ira->codegen->invalid_inst_gen; 25647 25648 ZigValue *byte_val = ir_resolve_const(ira, casted_byte, UndefOk); 25649 if (byte_val == nullptr) 25650 return ira->codegen->invalid_inst_gen; 25651 25652 ZigValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); 25653 if (count_val == nullptr) 25654 return ira->codegen->invalid_inst_gen; 25655 25656 if (casted_dest_ptr->value->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && 25657 casted_dest_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 25658 { 25659 ZigValue *dest_elements; 25660 size_t start; 25661 size_t bound_end; 25662 switch (dest_ptr_val->data.x_ptr.special) { 25663 case ConstPtrSpecialInvalid: 25664 case ConstPtrSpecialDiscard: 25665 zig_unreachable(); 25666 case ConstPtrSpecialRef: 25667 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 25668 start = 0; 25669 bound_end = 1; 25670 break; 25671 case ConstPtrSpecialBaseArray: 25672 { 25673 ZigValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 25674 expand_undef_array(ira->codegen, array_val); 25675 dest_elements = array_val->data.x_array.data.s_none.elements; 25676 start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 25677 bound_end = array_val->type->data.array.len; 25678 break; 25679 } 25680 case ConstPtrSpecialBaseStruct: 25681 zig_panic("TODO memset on const inner struct"); 25682 case ConstPtrSpecialBaseErrorUnionCode: 25683 zig_panic("TODO memset on const inner error union code"); 25684 case ConstPtrSpecialBaseErrorUnionPayload: 25685 zig_panic("TODO memset on const inner error union payload"); 25686 case ConstPtrSpecialBaseOptionalPayload: 25687 zig_panic("TODO memset on const inner optional payload"); 25688 case ConstPtrSpecialHardCodedAddr: 25689 zig_unreachable(); 25690 case ConstPtrSpecialFunction: 25691 zig_panic("TODO memset on ptr cast from function"); 25692 case ConstPtrSpecialNull: 25693 zig_panic("TODO memset on null ptr"); 25694 } 25695 25696 size_t count = bigint_as_usize(&count_val->data.x_bigint); 25697 size_t end = start + count; 25698 if (end > bound_end) { 25699 ir_add_error(ira, &count_value->base, buf_sprintf("out of bounds pointer access")); 25700 return ira->codegen->invalid_inst_gen; 25701 } 25702 25703 for (size_t i = start; i < end; i += 1) { 25704 copy_const_val(ira->codegen, &dest_elements[i], byte_val); 25705 } 25706 25707 return ir_const_void(ira, &instruction->base.base); 25708 } 25709 } 25710 25711 return ir_build_memset_gen(ira, &instruction->base.base, casted_dest_ptr, casted_byte, casted_count); 25712 } 25713 25714 static IrInstGen *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstSrcMemcpy *instruction) { 25715 Error err; 25716 25717 IrInstGen *dest_ptr = instruction->dest_ptr->child; 25718 if (type_is_invalid(dest_ptr->value->type)) 25719 return ira->codegen->invalid_inst_gen; 25720 25721 IrInstGen *src_ptr = instruction->src_ptr->child; 25722 if (type_is_invalid(src_ptr->value->type)) 25723 return ira->codegen->invalid_inst_gen; 25724 25725 IrInstGen *count_value = instruction->count->child; 25726 if (type_is_invalid(count_value->value->type)) 25727 return ira->codegen->invalid_inst_gen; 25728 25729 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 25730 ZigType *dest_uncasted_type = dest_ptr->value->type; 25731 ZigType *src_uncasted_type = src_ptr->value->type; 25732 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 25733 dest_uncasted_type->data.pointer.is_volatile; 25734 bool src_is_volatile = (src_uncasted_type->id == ZigTypeIdPointer) && 25735 src_uncasted_type->data.pointer.is_volatile; 25736 25737 uint32_t dest_align; 25738 if (dest_uncasted_type->id == ZigTypeIdPointer) { 25739 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 25740 return ira->codegen->invalid_inst_gen; 25741 } else { 25742 dest_align = get_abi_alignment(ira->codegen, u8); 25743 } 25744 25745 uint32_t src_align; 25746 if (src_uncasted_type->id == ZigTypeIdPointer) { 25747 if ((err = resolve_ptr_align(ira, src_uncasted_type, &src_align))) 25748 return ira->codegen->invalid_inst_gen; 25749 } else { 25750 src_align = get_abi_alignment(ira->codegen, u8); 25751 } 25752 25753 ZigType *usize = ira->codegen->builtin_types.entry_usize; 25754 ZigType *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 25755 PtrLenUnknown, dest_align, 0, 0, false); 25756 ZigType *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, src_is_volatile, 25757 PtrLenUnknown, src_align, 0, 0, false); 25758 25759 IrInstGen *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut); 25760 if (type_is_invalid(casted_dest_ptr->value->type)) 25761 return ira->codegen->invalid_inst_gen; 25762 25763 IrInstGen *casted_src_ptr = ir_implicit_cast(ira, src_ptr, u8_ptr_const); 25764 if (type_is_invalid(casted_src_ptr->value->type)) 25765 return ira->codegen->invalid_inst_gen; 25766 25767 IrInstGen *casted_count = ir_implicit_cast(ira, count_value, usize); 25768 if (type_is_invalid(casted_count->value->type)) 25769 return ira->codegen->invalid_inst_gen; 25770 25771 // TODO test this at comptime with u8 and non-u8 types 25772 // TODO test with dest ptr being a global runtime variable 25773 if (instr_is_comptime(casted_dest_ptr) && 25774 instr_is_comptime(casted_src_ptr) && 25775 instr_is_comptime(casted_count)) 25776 { 25777 ZigValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); 25778 if (dest_ptr_val == nullptr) 25779 return ira->codegen->invalid_inst_gen; 25780 25781 ZigValue *src_ptr_val = ir_resolve_const(ira, casted_src_ptr, UndefBad); 25782 if (src_ptr_val == nullptr) 25783 return ira->codegen->invalid_inst_gen; 25784 25785 ZigValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); 25786 if (count_val == nullptr) 25787 return ira->codegen->invalid_inst_gen; 25788 25789 if (dest_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 25790 size_t count = bigint_as_usize(&count_val->data.x_bigint); 25791 25792 ZigValue *dest_elements; 25793 size_t dest_start; 25794 size_t dest_end; 25795 switch (dest_ptr_val->data.x_ptr.special) { 25796 case ConstPtrSpecialInvalid: 25797 case ConstPtrSpecialDiscard: 25798 zig_unreachable(); 25799 case ConstPtrSpecialRef: 25800 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 25801 dest_start = 0; 25802 dest_end = 1; 25803 break; 25804 case ConstPtrSpecialBaseArray: 25805 { 25806 ZigValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 25807 expand_undef_array(ira->codegen, array_val); 25808 dest_elements = array_val->data.x_array.data.s_none.elements; 25809 dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 25810 dest_end = array_val->type->data.array.len; 25811 break; 25812 } 25813 case ConstPtrSpecialBaseStruct: 25814 zig_panic("TODO memcpy on const inner struct"); 25815 case ConstPtrSpecialBaseErrorUnionCode: 25816 zig_panic("TODO memcpy on const inner error union code"); 25817 case ConstPtrSpecialBaseErrorUnionPayload: 25818 zig_panic("TODO memcpy on const inner error union payload"); 25819 case ConstPtrSpecialBaseOptionalPayload: 25820 zig_panic("TODO memcpy on const inner optional payload"); 25821 case ConstPtrSpecialHardCodedAddr: 25822 zig_unreachable(); 25823 case ConstPtrSpecialFunction: 25824 zig_panic("TODO memcpy on ptr cast from function"); 25825 case ConstPtrSpecialNull: 25826 zig_panic("TODO memcpy on null ptr"); 25827 } 25828 25829 if (dest_start + count > dest_end) { 25830 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds pointer access")); 25831 return ira->codegen->invalid_inst_gen; 25832 } 25833 25834 ZigValue *src_elements; 25835 size_t src_start; 25836 size_t src_end; 25837 25838 switch (src_ptr_val->data.x_ptr.special) { 25839 case ConstPtrSpecialInvalid: 25840 case ConstPtrSpecialDiscard: 25841 zig_unreachable(); 25842 case ConstPtrSpecialRef: 25843 src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; 25844 src_start = 0; 25845 src_end = 1; 25846 break; 25847 case ConstPtrSpecialBaseArray: 25848 { 25849 ZigValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; 25850 expand_undef_array(ira->codegen, array_val); 25851 src_elements = array_val->data.x_array.data.s_none.elements; 25852 src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; 25853 src_end = array_val->type->data.array.len; 25854 break; 25855 } 25856 case ConstPtrSpecialBaseStruct: 25857 zig_panic("TODO memcpy on const inner struct"); 25858 case ConstPtrSpecialBaseErrorUnionCode: 25859 zig_panic("TODO memcpy on const inner error union code"); 25860 case ConstPtrSpecialBaseErrorUnionPayload: 25861 zig_panic("TODO memcpy on const inner error union payload"); 25862 case ConstPtrSpecialBaseOptionalPayload: 25863 zig_panic("TODO memcpy on const inner optional payload"); 25864 case ConstPtrSpecialHardCodedAddr: 25865 zig_unreachable(); 25866 case ConstPtrSpecialFunction: 25867 zig_panic("TODO memcpy on ptr cast from function"); 25868 case ConstPtrSpecialNull: 25869 zig_panic("TODO memcpy on null ptr"); 25870 } 25871 25872 if (src_start + count > src_end) { 25873 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds pointer access")); 25874 return ira->codegen->invalid_inst_gen; 25875 } 25876 25877 // TODO check for noalias violations - this should be generalized to work for any function 25878 25879 for (size_t i = 0; i < count; i += 1) { 25880 copy_const_val(ira->codegen, &dest_elements[dest_start + i], &src_elements[src_start + i]); 25881 } 25882 25883 return ir_const_void(ira, &instruction->base.base); 25884 } 25885 } 25886 25887 return ir_build_memcpy_gen(ira, &instruction->base.base, casted_dest_ptr, casted_src_ptr, casted_count); 25888 } 25889 25890 static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *instruction) { 25891 IrInstGen *ptr_ptr = instruction->ptr->child; 25892 if (type_is_invalid(ptr_ptr->value->type)) 25893 return ira->codegen->invalid_inst_gen; 25894 25895 ZigType *ptr_ptr_type = ptr_ptr->value->type; 25896 assert(ptr_ptr_type->id == ZigTypeIdPointer); 25897 ZigType *array_type = ptr_ptr_type->data.pointer.child_type; 25898 25899 IrInstGen *start = instruction->start->child; 25900 if (type_is_invalid(start->value->type)) 25901 return ira->codegen->invalid_inst_gen; 25902 25903 ZigType *usize = ira->codegen->builtin_types.entry_usize; 25904 IrInstGen *casted_start = ir_implicit_cast(ira, start, usize); 25905 if (type_is_invalid(casted_start->value->type)) 25906 return ira->codegen->invalid_inst_gen; 25907 25908 IrInstGen *end; 25909 if (instruction->end) { 25910 end = instruction->end->child; 25911 if (type_is_invalid(end->value->type)) 25912 return ira->codegen->invalid_inst_gen; 25913 end = ir_implicit_cast(ira, end, usize); 25914 if (type_is_invalid(end->value->type)) 25915 return ira->codegen->invalid_inst_gen; 25916 } else { 25917 end = nullptr; 25918 } 25919 25920 ZigType *non_sentinel_slice_ptr_type; 25921 ZigType *elem_type; 25922 25923 if (array_type->id == ZigTypeIdArray) { 25924 elem_type = array_type->data.array.child_type; 25925 bool is_comptime_const = ptr_ptr->value->special == ConstValSpecialStatic && 25926 ptr_ptr->value->data.x_ptr.mut == ConstPtrMutComptimeConst; 25927 non_sentinel_slice_ptr_type = get_pointer_to_type_extra(ira->codegen, elem_type, 25928 ptr_ptr_type->data.pointer.is_const || is_comptime_const, 25929 ptr_ptr_type->data.pointer.is_volatile, 25930 PtrLenUnknown, 25931 ptr_ptr_type->data.pointer.explicit_alignment, 0, 0, false); 25932 } else if (array_type->id == ZigTypeIdPointer) { 25933 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 25934 ZigType *main_type = array_type->data.pointer.child_type; 25935 if (main_type->id == ZigTypeIdArray) { 25936 elem_type = main_type->data.pointer.child_type; 25937 non_sentinel_slice_ptr_type = get_pointer_to_type_extra(ira->codegen, 25938 elem_type, 25939 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile, 25940 PtrLenUnknown, 25941 array_type->data.pointer.explicit_alignment, 0, 0, false); 25942 } else { 25943 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of single-item pointer")); 25944 return ira->codegen->invalid_inst_gen; 25945 } 25946 } else { 25947 elem_type = array_type->data.pointer.child_type; 25948 if (array_type->data.pointer.ptr_len == PtrLenC) { 25949 array_type = adjust_ptr_len(ira->codegen, array_type, PtrLenUnknown); 25950 } 25951 ZigType *maybe_sentineled_slice_ptr_type = array_type; 25952 non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr); 25953 if (!end) { 25954 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of pointer must include end value")); 25955 return ira->codegen->invalid_inst_gen; 25956 } 25957 } 25958 } else if (is_slice(array_type)) { 25959 ZigType *maybe_sentineled_slice_ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; 25960 non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr); 25961 elem_type = non_sentinel_slice_ptr_type->data.pointer.child_type; 25962 } else { 25963 ir_add_error(ira, &instruction->base.base, 25964 buf_sprintf("slice of non-array type '%s'", buf_ptr(&array_type->name))); 25965 return ira->codegen->invalid_inst_gen; 25966 } 25967 25968 ZigType *return_type; 25969 ZigValue *sentinel_val = nullptr; 25970 if (instruction->sentinel) { 25971 IrInstGen *uncasted_sentinel = instruction->sentinel->child; 25972 if (type_is_invalid(uncasted_sentinel->value->type)) 25973 return ira->codegen->invalid_inst_gen; 25974 IrInstGen *sentinel = ir_implicit_cast(ira, uncasted_sentinel, elem_type); 25975 if (type_is_invalid(sentinel->value->type)) 25976 return ira->codegen->invalid_inst_gen; 25977 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 25978 if (sentinel_val == nullptr) 25979 return ira->codegen->invalid_inst_gen; 25980 ZigType *slice_ptr_type = adjust_ptr_sentinel(ira->codegen, non_sentinel_slice_ptr_type, sentinel_val); 25981 return_type = get_slice_type(ira->codegen, slice_ptr_type); 25982 } else { 25983 return_type = get_slice_type(ira->codegen, non_sentinel_slice_ptr_type); 25984 } 25985 25986 if (instr_is_comptime(ptr_ptr) && 25987 value_is_comptime(casted_start->value) && 25988 (!end || value_is_comptime(end->value))) 25989 { 25990 ZigValue *array_val; 25991 ZigValue *parent_ptr; 25992 size_t abs_offset; 25993 size_t rel_end; 25994 bool ptr_is_undef = false; 25995 if (array_type->id == ZigTypeIdArray || 25996 (array_type->id == ZigTypeIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle)) 25997 { 25998 if (array_type->id == ZigTypeIdPointer) { 25999 ZigType *child_array_type = array_type->data.pointer.child_type; 26000 assert(child_array_type->id == ZigTypeIdArray); 26001 parent_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 26002 if (parent_ptr == nullptr) 26003 return ira->codegen->invalid_inst_gen; 26004 26005 26006 if (parent_ptr->special == ConstValSpecialUndef) { 26007 array_val = nullptr; 26008 abs_offset = 0; 26009 rel_end = SIZE_MAX; 26010 ptr_is_undef = true; 26011 } else { 26012 array_val = const_ptr_pointee(ira, ira->codegen, parent_ptr, instruction->base.base.source_node); 26013 if (array_val == nullptr) 26014 return ira->codegen->invalid_inst_gen; 26015 26016 rel_end = child_array_type->data.array.len; 26017 abs_offset = 0; 26018 } 26019 } else { 26020 array_val = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 26021 if (array_val == nullptr) 26022 return ira->codegen->invalid_inst_gen; 26023 rel_end = array_type->data.array.len; 26024 parent_ptr = nullptr; 26025 abs_offset = 0; 26026 } 26027 } else if (array_type->id == ZigTypeIdPointer) { 26028 assert(array_type->data.pointer.ptr_len == PtrLenUnknown); 26029 parent_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 26030 if (parent_ptr == nullptr) 26031 return ira->codegen->invalid_inst_gen; 26032 26033 if (parent_ptr->special == ConstValSpecialUndef) { 26034 array_val = nullptr; 26035 abs_offset = 0; 26036 rel_end = SIZE_MAX; 26037 ptr_is_undef = true; 26038 } else switch (parent_ptr->data.x_ptr.special) { 26039 case ConstPtrSpecialInvalid: 26040 case ConstPtrSpecialDiscard: 26041 zig_unreachable(); 26042 case ConstPtrSpecialRef: 26043 if (parent_ptr->data.x_ptr.data.ref.pointee->type->id == ZigTypeIdArray) { 26044 array_val = parent_ptr->data.x_ptr.data.ref.pointee; 26045 abs_offset = 0; 26046 rel_end = array_val->type->data.array.len; 26047 } else { 26048 array_val = nullptr; 26049 abs_offset = SIZE_MAX; 26050 rel_end = 1; 26051 } 26052 break; 26053 case ConstPtrSpecialBaseArray: 26054 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 26055 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 26056 rel_end = array_val->type->data.array.len - abs_offset; 26057 break; 26058 case ConstPtrSpecialBaseStruct: 26059 zig_panic("TODO slice const inner struct"); 26060 case ConstPtrSpecialBaseErrorUnionCode: 26061 zig_panic("TODO slice const inner error union code"); 26062 case ConstPtrSpecialBaseErrorUnionPayload: 26063 zig_panic("TODO slice const inner error union payload"); 26064 case ConstPtrSpecialBaseOptionalPayload: 26065 zig_panic("TODO slice const inner optional payload"); 26066 case ConstPtrSpecialHardCodedAddr: 26067 array_val = nullptr; 26068 abs_offset = 0; 26069 rel_end = SIZE_MAX; 26070 break; 26071 case ConstPtrSpecialFunction: 26072 zig_panic("TODO slice of ptr cast from function"); 26073 case ConstPtrSpecialNull: 26074 zig_panic("TODO slice of null ptr"); 26075 } 26076 } else if (is_slice(array_type)) { 26077 ZigValue *slice_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 26078 if (slice_ptr == nullptr) 26079 return ira->codegen->invalid_inst_gen; 26080 26081 if (slice_ptr->special == ConstValSpecialUndef) { 26082 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of undefined")); 26083 return ira->codegen->invalid_inst_gen; 26084 } 26085 26086 parent_ptr = slice_ptr->data.x_struct.fields[slice_ptr_index]; 26087 if (parent_ptr->special == ConstValSpecialUndef) { 26088 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of undefined")); 26089 return ira->codegen->invalid_inst_gen; 26090 } 26091 26092 ZigValue *len_val = slice_ptr->data.x_struct.fields[slice_len_index]; 26093 26094 switch (parent_ptr->data.x_ptr.special) { 26095 case ConstPtrSpecialInvalid: 26096 case ConstPtrSpecialDiscard: 26097 zig_unreachable(); 26098 case ConstPtrSpecialRef: 26099 array_val = nullptr; 26100 abs_offset = SIZE_MAX; 26101 rel_end = 1; 26102 break; 26103 case ConstPtrSpecialBaseArray: 26104 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 26105 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 26106 rel_end = bigint_as_usize(&len_val->data.x_bigint); 26107 break; 26108 case ConstPtrSpecialBaseStruct: 26109 zig_panic("TODO slice const inner struct"); 26110 case ConstPtrSpecialBaseErrorUnionCode: 26111 zig_panic("TODO slice const inner error union code"); 26112 case ConstPtrSpecialBaseErrorUnionPayload: 26113 zig_panic("TODO slice const inner error union payload"); 26114 case ConstPtrSpecialBaseOptionalPayload: 26115 zig_panic("TODO slice const inner optional payload"); 26116 case ConstPtrSpecialHardCodedAddr: 26117 array_val = nullptr; 26118 abs_offset = 0; 26119 rel_end = bigint_as_usize(&len_val->data.x_bigint); 26120 break; 26121 case ConstPtrSpecialFunction: 26122 zig_panic("TODO slice of slice cast from function"); 26123 case ConstPtrSpecialNull: 26124 zig_panic("TODO slice of null"); 26125 } 26126 } else { 26127 zig_unreachable(); 26128 } 26129 26130 ZigValue *start_val = ir_resolve_const(ira, casted_start, UndefBad); 26131 if (!start_val) 26132 return ira->codegen->invalid_inst_gen; 26133 26134 uint64_t start_scalar = bigint_as_u64(&start_val->data.x_bigint); 26135 if (!ptr_is_undef && start_scalar > rel_end) { 26136 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds slice")); 26137 return ira->codegen->invalid_inst_gen; 26138 } 26139 26140 uint64_t end_scalar = rel_end; 26141 if (end) { 26142 ZigValue *end_val = ir_resolve_const(ira, end, UndefBad); 26143 if (!end_val) 26144 return ira->codegen->invalid_inst_gen; 26145 end_scalar = bigint_as_u64(&end_val->data.x_bigint); 26146 } 26147 if (!ptr_is_undef) { 26148 if (end_scalar > rel_end) { 26149 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds slice")); 26150 return ira->codegen->invalid_inst_gen; 26151 } 26152 if (start_scalar > end_scalar) { 26153 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice start is greater than end")); 26154 return ira->codegen->invalid_inst_gen; 26155 } 26156 } 26157 if (ptr_is_undef && start_scalar != end_scalar) { 26158 ir_add_error(ira, &instruction->base.base, buf_sprintf("non-zero length slice of undefined pointer")); 26159 return ira->codegen->invalid_inst_gen; 26160 } 26161 26162 IrInstGen *result = ir_const(ira, &instruction->base.base, return_type); 26163 ZigValue *out_val = result->value; 26164 out_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, 2); 26165 26166 ZigValue *ptr_val = out_val->data.x_struct.fields[slice_ptr_index]; 26167 26168 if (array_val) { 26169 size_t index = abs_offset + start_scalar; 26170 bool is_const = slice_is_const(return_type); 26171 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const, PtrLenUnknown); 26172 if (array_type->id == ZigTypeIdArray) { 26173 ptr_val->data.x_ptr.mut = ptr_ptr->value->data.x_ptr.mut; 26174 } else if (is_slice(array_type)) { 26175 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 26176 } else if (array_type->id == ZigTypeIdPointer) { 26177 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 26178 } 26179 } else if (ptr_is_undef) { 26180 ptr_val->type = get_pointer_to_type(ira->codegen, parent_ptr->type->data.pointer.child_type, 26181 slice_is_const(return_type)); 26182 ptr_val->special = ConstValSpecialUndef; 26183 } else switch (parent_ptr->data.x_ptr.special) { 26184 case ConstPtrSpecialInvalid: 26185 case ConstPtrSpecialDiscard: 26186 zig_unreachable(); 26187 case ConstPtrSpecialRef: 26188 init_const_ptr_ref(ira->codegen, ptr_val, 26189 parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type)); 26190 break; 26191 case ConstPtrSpecialBaseArray: 26192 zig_unreachable(); 26193 case ConstPtrSpecialBaseStruct: 26194 zig_panic("TODO"); 26195 case ConstPtrSpecialBaseErrorUnionCode: 26196 zig_panic("TODO"); 26197 case ConstPtrSpecialBaseErrorUnionPayload: 26198 zig_panic("TODO"); 26199 case ConstPtrSpecialBaseOptionalPayload: 26200 zig_panic("TODO"); 26201 case ConstPtrSpecialHardCodedAddr: 26202 init_const_ptr_hard_coded_addr(ira->codegen, ptr_val, 26203 parent_ptr->type->data.pointer.child_type, 26204 parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar, 26205 slice_is_const(return_type)); 26206 break; 26207 case ConstPtrSpecialFunction: 26208 zig_panic("TODO"); 26209 case ConstPtrSpecialNull: 26210 zig_panic("TODO"); 26211 } 26212 26213 ZigValue *len_val = out_val->data.x_struct.fields[slice_len_index]; 26214 init_const_usize(ira->codegen, len_val, end_scalar - start_scalar); 26215 26216 return result; 26217 } 26218 26219 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 26220 return_type, nullptr, true, true); 26221 26222 if (result_loc != nullptr) { 26223 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 26224 return result_loc; 26225 } 26226 IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type); 26227 dummy_value->value->special = ConstValSpecialRuntime; 26228 IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base, 26229 dummy_value, result_loc->value->type->data.pointer.child_type); 26230 if (type_is_invalid(dummy_result->value->type)) 26231 return ira->codegen->invalid_inst_gen; 26232 } 26233 26234 return ir_build_slice_gen(ira, &instruction->base.base, return_type, 26235 ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc); 26236 } 26237 26238 static IrInstGen *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstSrcHasField *instruction) { 26239 Error err; 26240 ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); 26241 if (type_is_invalid(container_type)) 26242 return ira->codegen->invalid_inst_gen; 26243 26244 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusZeroBitsKnown))) 26245 return ira->codegen->invalid_inst_gen; 26246 26247 Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); 26248 if (field_name == nullptr) 26249 return ira->codegen->invalid_inst_gen; 26250 26251 bool result; 26252 if (container_type->id == ZigTypeIdStruct) { 26253 result = find_struct_type_field(container_type, field_name) != nullptr; 26254 } else if (container_type->id == ZigTypeIdEnum) { 26255 result = find_enum_type_field(container_type, field_name) != nullptr; 26256 } else if (container_type->id == ZigTypeIdUnion) { 26257 result = find_union_type_field(container_type, field_name) != nullptr; 26258 } else { 26259 ir_add_error(ira, &instruction->container_type->base, 26260 buf_sprintf("type '%s' does not support @hasField", buf_ptr(&container_type->name))); 26261 return ira->codegen->invalid_inst_gen; 26262 } 26263 return ir_const_bool(ira, &instruction->base.base, result); 26264 } 26265 26266 static IrInstGen *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstSrcBreakpoint *instruction) { 26267 return ir_build_breakpoint_gen(ira, &instruction->base.base); 26268 } 26269 26270 static IrInstGen *ir_analyze_instruction_return_address(IrAnalyze *ira, IrInstSrcReturnAddress *instruction) { 26271 return ir_build_return_address_gen(ira, &instruction->base.base); 26272 } 26273 26274 static IrInstGen *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstSrcFrameAddress *instruction) { 26275 return ir_build_frame_address_gen(ira, &instruction->base.base); 26276 } 26277 26278 static IrInstGen *ir_analyze_instruction_frame_handle(IrAnalyze *ira, IrInstSrcFrameHandle *instruction) { 26279 ZigFn *fn = ira->new_irb.exec->fn_entry; 26280 ir_assert(fn != nullptr, &instruction->base.base); 26281 26282 if (fn->inferred_async_node == nullptr) { 26283 fn->inferred_async_node = instruction->base.base.source_node; 26284 } 26285 26286 ZigType *frame_type = get_fn_frame_type(ira->codegen, fn); 26287 ZigType *ptr_frame_type = get_pointer_to_type(ira->codegen, frame_type, false); 26288 26289 return ir_build_handle_gen(ira, &instruction->base.base, ptr_frame_type); 26290 } 26291 26292 static IrInstGen *ir_analyze_instruction_frame_type(IrAnalyze *ira, IrInstSrcFrameType *instruction) { 26293 ZigFn *fn = ir_resolve_fn(ira, instruction->fn->child); 26294 if (fn == nullptr) 26295 return ira->codegen->invalid_inst_gen; 26296 26297 if (fn->type_entry->data.fn.is_generic) { 26298 ir_add_error(ira, &instruction->base.base, 26299 buf_sprintf("@Frame() of generic function")); 26300 return ira->codegen->invalid_inst_gen; 26301 } 26302 26303 ZigType *ty = get_fn_frame_type(ira->codegen, fn); 26304 return ir_const_type(ira, &instruction->base.base, ty); 26305 } 26306 26307 static IrInstGen *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstSrcFrameSize *instruction) { 26308 IrInstGen *fn = instruction->fn->child; 26309 if (type_is_invalid(fn->value->type)) 26310 return ira->codegen->invalid_inst_gen; 26311 26312 if (fn->value->type->id != ZigTypeIdFn) { 26313 ir_add_error(ira, &fn->base, 26314 buf_sprintf("expected function, found '%s'", buf_ptr(&fn->value->type->name))); 26315 return ira->codegen->invalid_inst_gen; 26316 } 26317 26318 ira->codegen->need_frame_size_prefix_data = true; 26319 26320 return ir_build_frame_size_gen(ira, &instruction->base.base, fn); 26321 } 26322 26323 static IrInstGen *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstSrcAlignOf *instruction) { 26324 // Here we create a lazy value in order to avoid resolving the alignment of the type 26325 // immediately. This avoids false positive dependency loops such as: 26326 // const Node = struct { 26327 // field: []align(@alignOf(Node)) Node, 26328 // }; 26329 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 26330 result->value->special = ConstValSpecialLazy; 26331 26332 LazyValueAlignOf *lazy_align_of = heap::c_allocator.create<LazyValueAlignOf>(); 26333 lazy_align_of->ira = ira; ira_ref(ira); 26334 result->value->data.x_lazy = &lazy_align_of->base; 26335 lazy_align_of->base.id = LazyValueIdAlignOf; 26336 26337 lazy_align_of->target_type = instruction->type_value->child; 26338 if (ir_resolve_type_lazy(ira, lazy_align_of->target_type) == nullptr) 26339 return ira->codegen->invalid_inst_gen; 26340 26341 return result; 26342 } 26343 26344 static IrInstGen *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstSrcOverflowOp *instruction) { 26345 Error err; 26346 26347 IrInstGen *type_value = instruction->type_value->child; 26348 if (type_is_invalid(type_value->value->type)) 26349 return ira->codegen->invalid_inst_gen; 26350 26351 ZigType *dest_type = ir_resolve_type(ira, type_value); 26352 if (type_is_invalid(dest_type)) 26353 return ira->codegen->invalid_inst_gen; 26354 26355 if (dest_type->id != ZigTypeIdInt) { 26356 ir_add_error(ira, &type_value->base, 26357 buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 26358 return ira->codegen->invalid_inst_gen; 26359 } 26360 26361 IrInstGen *op1 = instruction->op1->child; 26362 if (type_is_invalid(op1->value->type)) 26363 return ira->codegen->invalid_inst_gen; 26364 26365 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 26366 if (type_is_invalid(casted_op1->value->type)) 26367 return ira->codegen->invalid_inst_gen; 26368 26369 IrInstGen *op2 = instruction->op2->child; 26370 if (type_is_invalid(op2->value->type)) 26371 return ira->codegen->invalid_inst_gen; 26372 26373 IrInstGen *casted_op2; 26374 if (instruction->op == IrOverflowOpShl) { 26375 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 26376 dest_type->data.integral.bit_count - 1); 26377 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 26378 } else { 26379 casted_op2 = ir_implicit_cast(ira, op2, dest_type); 26380 } 26381 if (type_is_invalid(casted_op2->value->type)) 26382 return ira->codegen->invalid_inst_gen; 26383 26384 IrInstGen *result_ptr = instruction->result_ptr->child; 26385 if (type_is_invalid(result_ptr->value->type)) 26386 return ira->codegen->invalid_inst_gen; 26387 26388 ZigType *expected_ptr_type; 26389 if (result_ptr->value->type->id == ZigTypeIdPointer) { 26390 uint32_t alignment; 26391 if ((err = resolve_ptr_align(ira, result_ptr->value->type, &alignment))) 26392 return ira->codegen->invalid_inst_gen; 26393 expected_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_type, 26394 false, result_ptr->value->type->data.pointer.is_volatile, 26395 PtrLenSingle, 26396 alignment, 0, 0, false); 26397 } else { 26398 expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false); 26399 } 26400 26401 IrInstGen *casted_result_ptr = ir_implicit_cast(ira, result_ptr, expected_ptr_type); 26402 if (type_is_invalid(casted_result_ptr->value->type)) 26403 return ira->codegen->invalid_inst_gen; 26404 26405 if (instr_is_comptime(casted_op1) && 26406 instr_is_comptime(casted_op2) && 26407 instr_is_comptime(casted_result_ptr)) 26408 { 26409 ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 26410 if (op1_val == nullptr) 26411 return ira->codegen->invalid_inst_gen; 26412 26413 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 26414 if (op2_val == nullptr) 26415 return ira->codegen->invalid_inst_gen; 26416 26417 ZigValue *result_val = ir_resolve_const(ira, casted_result_ptr, UndefBad); 26418 if (result_val == nullptr) 26419 return ira->codegen->invalid_inst_gen; 26420 26421 BigInt *op1_bigint = &op1_val->data.x_bigint; 26422 BigInt *op2_bigint = &op2_val->data.x_bigint; 26423 ZigValue *pointee_val = const_ptr_pointee(ira, ira->codegen, result_val, 26424 casted_result_ptr->base.source_node); 26425 if (pointee_val == nullptr) 26426 return ira->codegen->invalid_inst_gen; 26427 BigInt *dest_bigint = &pointee_val->data.x_bigint; 26428 switch (instruction->op) { 26429 case IrOverflowOpAdd: 26430 bigint_add(dest_bigint, op1_bigint, op2_bigint); 26431 break; 26432 case IrOverflowOpSub: 26433 bigint_sub(dest_bigint, op1_bigint, op2_bigint); 26434 break; 26435 case IrOverflowOpMul: 26436 bigint_mul(dest_bigint, op1_bigint, op2_bigint); 26437 break; 26438 case IrOverflowOpShl: 26439 bigint_shl(dest_bigint, op1_bigint, op2_bigint); 26440 break; 26441 } 26442 bool result_bool = false; 26443 if (!bigint_fits_in_bits(dest_bigint, dest_type->data.integral.bit_count, 26444 dest_type->data.integral.is_signed)) 26445 { 26446 result_bool = true; 26447 BigInt tmp_bigint; 26448 bigint_init_bigint(&tmp_bigint, dest_bigint); 26449 bigint_truncate(dest_bigint, &tmp_bigint, dest_type->data.integral.bit_count, 26450 dest_type->data.integral.is_signed); 26451 } 26452 pointee_val->special = ConstValSpecialStatic; 26453 return ir_const_bool(ira, &instruction->base.base, result_bool); 26454 } 26455 26456 return ir_build_overflow_op_gen(ira, &instruction->base.base, instruction->op, 26457 casted_op1, casted_op2, casted_result_ptr, dest_type); 26458 } 26459 26460 static void ir_eval_mul_add(IrAnalyze *ira, IrInstSrcMulAdd *source_instr, ZigType *float_type, 26461 ZigValue *op1, ZigValue *op2, ZigValue *op3, ZigValue *out_val) { 26462 if (float_type->id == ZigTypeIdComptimeFloat) { 26463 f128M_mulAdd(&out_val->data.x_bigfloat.value, &op1->data.x_bigfloat.value, &op2->data.x_bigfloat.value, 26464 &op3->data.x_bigfloat.value); 26465 } else if (float_type->id == ZigTypeIdFloat) { 26466 switch (float_type->data.floating.bit_count) { 26467 case 16: 26468 out_val->data.x_f16 = f16_mulAdd(op1->data.x_f16, op2->data.x_f16, op3->data.x_f16); 26469 break; 26470 case 32: 26471 out_val->data.x_f32 = fmaf(op1->data.x_f32, op2->data.x_f32, op3->data.x_f32); 26472 break; 26473 case 64: 26474 out_val->data.x_f64 = fma(op1->data.x_f64, op2->data.x_f64, op3->data.x_f64); 26475 break; 26476 case 128: 26477 f128M_mulAdd(&op1->data.x_f128, &op2->data.x_f128, &op3->data.x_f128, &out_val->data.x_f128); 26478 break; 26479 default: 26480 zig_unreachable(); 26481 } 26482 } else { 26483 zig_unreachable(); 26484 } 26485 } 26486 26487 static IrInstGen *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstSrcMulAdd *instruction) { 26488 IrInstGen *type_value = instruction->type_value->child; 26489 if (type_is_invalid(type_value->value->type)) 26490 return ira->codegen->invalid_inst_gen; 26491 26492 ZigType *expr_type = ir_resolve_type(ira, type_value); 26493 if (type_is_invalid(expr_type)) 26494 return ira->codegen->invalid_inst_gen; 26495 26496 // Only allow float types, and vectors of floats. 26497 ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; 26498 if (float_type->id != ZigTypeIdFloat) { 26499 ir_add_error(ira, &type_value->base, 26500 buf_sprintf("expected float or vector of float type, found '%s'", buf_ptr(&float_type->name))); 26501 return ira->codegen->invalid_inst_gen; 26502 } 26503 26504 IrInstGen *op1 = instruction->op1->child; 26505 if (type_is_invalid(op1->value->type)) 26506 return ira->codegen->invalid_inst_gen; 26507 26508 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, expr_type); 26509 if (type_is_invalid(casted_op1->value->type)) 26510 return ira->codegen->invalid_inst_gen; 26511 26512 IrInstGen *op2 = instruction->op2->child; 26513 if (type_is_invalid(op2->value->type)) 26514 return ira->codegen->invalid_inst_gen; 26515 26516 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, expr_type); 26517 if (type_is_invalid(casted_op2->value->type)) 26518 return ira->codegen->invalid_inst_gen; 26519 26520 IrInstGen *op3 = instruction->op3->child; 26521 if (type_is_invalid(op3->value->type)) 26522 return ira->codegen->invalid_inst_gen; 26523 26524 IrInstGen *casted_op3 = ir_implicit_cast(ira, op3, expr_type); 26525 if (type_is_invalid(casted_op3->value->type)) 26526 return ira->codegen->invalid_inst_gen; 26527 26528 if (instr_is_comptime(casted_op1) && 26529 instr_is_comptime(casted_op2) && 26530 instr_is_comptime(casted_op3)) { 26531 ZigValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad); 26532 if (!op1_const) 26533 return ira->codegen->invalid_inst_gen; 26534 ZigValue *op2_const = ir_resolve_const(ira, casted_op2, UndefBad); 26535 if (!op2_const) 26536 return ira->codegen->invalid_inst_gen; 26537 ZigValue *op3_const = ir_resolve_const(ira, casted_op3, UndefBad); 26538 if (!op3_const) 26539 return ira->codegen->invalid_inst_gen; 26540 26541 IrInstGen *result = ir_const(ira, &instruction->base.base, expr_type); 26542 ZigValue *out_val = result->value; 26543 26544 if (expr_type->id == ZigTypeIdVector) { 26545 expand_undef_array(ira->codegen, op1_const); 26546 expand_undef_array(ira->codegen, op2_const); 26547 expand_undef_array(ira->codegen, op3_const); 26548 out_val->special = ConstValSpecialUndef; 26549 expand_undef_array(ira->codegen, out_val); 26550 size_t len = expr_type->data.vector.len; 26551 for (size_t i = 0; i < len; i += 1) { 26552 ZigValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i]; 26553 ZigValue *float_operand_op2 = &op2_const->data.x_array.data.s_none.elements[i]; 26554 ZigValue *float_operand_op3 = &op3_const->data.x_array.data.s_none.elements[i]; 26555 ZigValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; 26556 assert(float_operand_op1->type == float_type); 26557 assert(float_operand_op2->type == float_type); 26558 assert(float_operand_op3->type == float_type); 26559 assert(float_out_val->type == float_type); 26560 ir_eval_mul_add(ira, instruction, float_type, 26561 op1_const, op2_const, op3_const, float_out_val); 26562 float_out_val->type = float_type; 26563 } 26564 out_val->type = expr_type; 26565 out_val->special = ConstValSpecialStatic; 26566 } else { 26567 ir_eval_mul_add(ira, instruction, float_type, op1_const, op2_const, op3_const, out_val); 26568 } 26569 return result; 26570 } 26571 26572 return ir_build_mul_add_gen(ira, &instruction->base.base, casted_op1, casted_op2, casted_op3, expr_type); 26573 } 26574 26575 static IrInstGen *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstSrcTestErr *instruction) { 26576 IrInstGen *base_ptr = instruction->base_ptr->child; 26577 if (type_is_invalid(base_ptr->value->type)) 26578 return ira->codegen->invalid_inst_gen; 26579 26580 IrInstGen *value; 26581 if (instruction->base_ptr_is_payload) { 26582 value = base_ptr; 26583 } else { 26584 value = ir_get_deref(ira, &instruction->base.base, base_ptr, nullptr); 26585 } 26586 26587 ZigType *type_entry = value->value->type; 26588 if (type_is_invalid(type_entry)) 26589 return ira->codegen->invalid_inst_gen; 26590 if (type_entry->id == ZigTypeIdErrorUnion) { 26591 if (instr_is_comptime(value)) { 26592 ZigValue *err_union_val = ir_resolve_const(ira, value, UndefBad); 26593 if (!err_union_val) 26594 return ira->codegen->invalid_inst_gen; 26595 26596 if (err_union_val->special != ConstValSpecialRuntime) { 26597 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; 26598 return ir_const_bool(ira, &instruction->base.base, (err != nullptr)); 26599 } 26600 } 26601 26602 if (instruction->resolve_err_set) { 26603 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 26604 if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.base.source_node)) { 26605 return ira->codegen->invalid_inst_gen; 26606 } 26607 if (!type_is_global_error_set(err_set_type) && 26608 err_set_type->data.error_set.err_count == 0) 26609 { 26610 assert(!err_set_type->data.error_set.incomplete); 26611 return ir_const_bool(ira, &instruction->base.base, false); 26612 } 26613 } 26614 26615 return ir_build_test_err_gen(ira, &instruction->base.base, value); 26616 } else if (type_entry->id == ZigTypeIdErrorSet) { 26617 return ir_const_bool(ira, &instruction->base.base, true); 26618 } else { 26619 return ir_const_bool(ira, &instruction->base.base, false); 26620 } 26621 } 26622 26623 static IrInstGen *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInst* source_instr, 26624 IrInstGen *base_ptr, bool initializing) 26625 { 26626 ZigType *ptr_type = base_ptr->value->type; 26627 26628 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 26629 assert(ptr_type->id == ZigTypeIdPointer); 26630 26631 ZigType *type_entry = ptr_type->data.pointer.child_type; 26632 if (type_is_invalid(type_entry)) 26633 return ira->codegen->invalid_inst_gen; 26634 26635 if (type_entry->id != ZigTypeIdErrorUnion) { 26636 ir_add_error(ira, &base_ptr->base, 26637 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 26638 return ira->codegen->invalid_inst_gen; 26639 } 26640 26641 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 26642 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, err_set_type, 26643 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 26644 ptr_type->data.pointer.explicit_alignment, 0, 0, false); 26645 26646 if (instr_is_comptime(base_ptr)) { 26647 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 26648 if (!ptr_val) 26649 return ira->codegen->invalid_inst_gen; 26650 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && 26651 ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) 26652 { 26653 ZigValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 26654 if (err_union_val == nullptr) 26655 return ira->codegen->invalid_inst_gen; 26656 26657 if (initializing && err_union_val->special == ConstValSpecialUndef) { 26658 ZigValue *vals = ira->codegen->pass1_arena->allocate<ZigValue>(2); 26659 ZigValue *err_set_val = &vals[0]; 26660 ZigValue *payload_val = &vals[1]; 26661 26662 err_set_val->special = ConstValSpecialUndef; 26663 err_set_val->type = err_set_type; 26664 err_set_val->parent.id = ConstParentIdErrUnionCode; 26665 err_set_val->parent.data.p_err_union_code.err_union_val = err_union_val; 26666 26667 payload_val->special = ConstValSpecialUndef; 26668 payload_val->type = type_entry->data.error_union.payload_type; 26669 payload_val->parent.id = ConstParentIdErrUnionPayload; 26670 payload_val->parent.data.p_err_union_payload.err_union_val = err_union_val; 26671 26672 err_union_val->special = ConstValSpecialStatic; 26673 err_union_val->data.x_err_union.error_set = err_set_val; 26674 err_union_val->data.x_err_union.payload = payload_val; 26675 } 26676 ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr); 26677 26678 IrInstGen *result; 26679 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 26680 result = ir_build_unwrap_err_code_gen(ira, source_instr->scope, 26681 source_instr->source_node, base_ptr, result_type); 26682 result->value->special = ConstValSpecialStatic; 26683 } else { 26684 result = ir_const(ira, source_instr, result_type); 26685 } 26686 ZigValue *const_val = result->value; 26687 const_val->data.x_ptr.special = ConstPtrSpecialBaseErrorUnionCode; 26688 const_val->data.x_ptr.data.base_err_union_code.err_union_val = err_union_val; 26689 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 26690 return result; 26691 } 26692 } 26693 26694 return ir_build_unwrap_err_code_gen(ira, source_instr->scope, source_instr->source_node, base_ptr, result_type); 26695 } 26696 26697 static IrInstGen *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrInstSrcUnwrapErrCode *instruction) { 26698 IrInstGen *base_ptr = instruction->err_union_ptr->child; 26699 if (type_is_invalid(base_ptr->value->type)) 26700 return ira->codegen->invalid_inst_gen; 26701 return ir_analyze_unwrap_err_code(ira, &instruction->base.base, base_ptr, false); 26702 } 26703 26704 static IrInstGen *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInst* source_instr, 26705 IrInstGen *base_ptr, bool safety_check_on, bool initializing) 26706 { 26707 ZigType *ptr_type = base_ptr->value->type; 26708 26709 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 26710 assert(ptr_type->id == ZigTypeIdPointer); 26711 26712 ZigType *type_entry = ptr_type->data.pointer.child_type; 26713 if (type_is_invalid(type_entry)) 26714 return ira->codegen->invalid_inst_gen; 26715 26716 if (type_entry->id != ZigTypeIdErrorUnion) { 26717 ir_add_error(ira, &base_ptr->base, 26718 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 26719 return ira->codegen->invalid_inst_gen; 26720 } 26721 26722 ZigType *payload_type = type_entry->data.error_union.payload_type; 26723 if (type_is_invalid(payload_type)) 26724 return ira->codegen->invalid_inst_gen; 26725 26726 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, 26727 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 26728 PtrLenSingle, 0, 0, 0, false); 26729 26730 if (instr_is_comptime(base_ptr)) { 26731 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 26732 if (!ptr_val) 26733 return ira->codegen->invalid_inst_gen; 26734 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 26735 ZigValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 26736 if (err_union_val == nullptr) 26737 return ira->codegen->invalid_inst_gen; 26738 if (initializing && err_union_val->special == ConstValSpecialUndef) { 26739 ZigValue *vals = ira->codegen->pass1_arena->allocate<ZigValue>(2); 26740 ZigValue *err_set_val = &vals[0]; 26741 ZigValue *payload_val = &vals[1]; 26742 26743 err_set_val->special = ConstValSpecialStatic; 26744 err_set_val->type = type_entry->data.error_union.err_set_type; 26745 err_set_val->data.x_err_set = nullptr; 26746 26747 payload_val->special = ConstValSpecialUndef; 26748 payload_val->type = payload_type; 26749 26750 err_union_val->special = ConstValSpecialStatic; 26751 err_union_val->data.x_err_union.error_set = err_set_val; 26752 err_union_val->data.x_err_union.payload = payload_val; 26753 } 26754 26755 if (err_union_val->special != ConstValSpecialRuntime) { 26756 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; 26757 if (err != nullptr) { 26758 ir_add_error(ira, source_instr, 26759 buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); 26760 return ira->codegen->invalid_inst_gen; 26761 } 26762 26763 IrInstGen *result; 26764 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 26765 result = ir_build_unwrap_err_payload_gen(ira, source_instr->scope, 26766 source_instr->source_node, base_ptr, safety_check_on, initializing, result_type); 26767 result->value->special = ConstValSpecialStatic; 26768 } else { 26769 result = ir_const(ira, source_instr, result_type); 26770 } 26771 result->value->data.x_ptr.special = ConstPtrSpecialRef; 26772 result->value->data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; 26773 result->value->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 26774 return result; 26775 } 26776 } 26777 } 26778 26779 return ir_build_unwrap_err_payload_gen(ira, source_instr->scope, source_instr->source_node, 26780 base_ptr, safety_check_on, initializing, result_type); 26781 } 26782 26783 static IrInstGen *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, 26784 IrInstSrcUnwrapErrPayload *instruction) 26785 { 26786 assert(instruction->value->child); 26787 IrInstGen *value = instruction->value->child; 26788 if (type_is_invalid(value->value->type)) 26789 return ira->codegen->invalid_inst_gen; 26790 26791 return ir_analyze_unwrap_error_payload(ira, &instruction->base.base, value, instruction->safety_check_on, false); 26792 } 26793 26794 static IrInstGen *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstSrcFnProto *instruction) { 26795 AstNode *proto_node = instruction->base.base.source_node; 26796 assert(proto_node->type == NodeTypeFnProto); 26797 26798 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); 26799 result->value->special = ConstValSpecialLazy; 26800 26801 LazyValueFnType *lazy_fn_type = heap::c_allocator.create<LazyValueFnType>(); 26802 lazy_fn_type->ira = ira; ira_ref(ira); 26803 result->value->data.x_lazy = &lazy_fn_type->base; 26804 lazy_fn_type->base.id = LazyValueIdFnType; 26805 26806 if (proto_node->data.fn_proto.auto_err_set) { 26807 ir_add_error(ira, &instruction->base.base, 26808 buf_sprintf("inferring error set of return type valid only for function definitions")); 26809 return ira->codegen->invalid_inst_gen; 26810 } 26811 26812 lazy_fn_type->cc = cc_from_fn_proto(&proto_node->data.fn_proto); 26813 if (instruction->callconv_value != nullptr) { 26814 ZigType *cc_enum_type = get_builtin_type(ira->codegen, "CallingConvention"); 26815 26816 IrInstGen *casted_value = ir_implicit_cast(ira, instruction->callconv_value->child, cc_enum_type); 26817 if (type_is_invalid(casted_value->value->type)) 26818 return ira->codegen->invalid_inst_gen; 26819 26820 ZigValue *const_value = ir_resolve_const(ira, casted_value, UndefBad); 26821 if (const_value == nullptr) 26822 return ira->codegen->invalid_inst_gen; 26823 26824 lazy_fn_type->cc = (CallingConvention)bigint_as_u32(&const_value->data.x_enum_tag); 26825 } 26826 26827 size_t param_count = proto_node->data.fn_proto.params.length; 26828 lazy_fn_type->proto_node = proto_node; 26829 lazy_fn_type->param_types = heap::c_allocator.allocate<IrInstGen *>(param_count); 26830 26831 for (size_t param_index = 0; param_index < param_count; param_index += 1) { 26832 AstNode *param_node = proto_node->data.fn_proto.params.at(param_index); 26833 assert(param_node->type == NodeTypeParamDecl); 26834 26835 bool param_is_var_args = param_node->data.param_decl.is_var_args; 26836 if (param_is_var_args) { 26837 const CallingConvention cc = lazy_fn_type->cc; 26838 26839 if (cc == CallingConventionC) { 26840 break; 26841 } else if (cc == CallingConventionUnspecified) { 26842 lazy_fn_type->is_generic = true; 26843 return result; 26844 } else { 26845 zig_unreachable(); 26846 } 26847 } 26848 26849 if (instruction->param_types[param_index] == nullptr) { 26850 lazy_fn_type->is_generic = true; 26851 return result; 26852 } 26853 26854 IrInstGen *param_type_value = instruction->param_types[param_index]->child; 26855 if (type_is_invalid(param_type_value->value->type)) 26856 return ira->codegen->invalid_inst_gen; 26857 if (ir_resolve_const(ira, param_type_value, LazyOk) == nullptr) 26858 return ira->codegen->invalid_inst_gen; 26859 lazy_fn_type->param_types[param_index] = param_type_value; 26860 } 26861 26862 if (instruction->align_value != nullptr) { 26863 lazy_fn_type->align_inst = instruction->align_value->child; 26864 if (ir_resolve_const(ira, lazy_fn_type->align_inst, LazyOk) == nullptr) 26865 return ira->codegen->invalid_inst_gen; 26866 } 26867 26868 lazy_fn_type->return_type = instruction->return_type->child; 26869 if (ir_resolve_const(ira, lazy_fn_type->return_type, LazyOk) == nullptr) 26870 return ira->codegen->invalid_inst_gen; 26871 26872 return result; 26873 } 26874 26875 static IrInstGen *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstSrcTestComptime *instruction) { 26876 IrInstGen *value = instruction->value->child; 26877 if (type_is_invalid(value->value->type)) 26878 return ira->codegen->invalid_inst_gen; 26879 26880 return ir_const_bool(ira, &instruction->base.base, instr_is_comptime(value)); 26881 } 26882 26883 static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, 26884 IrInstSrcCheckSwitchProngs *instruction) 26885 { 26886 IrInstGen *target_value = instruction->target_value->child; 26887 ZigType *switch_type = target_value->value->type; 26888 if (type_is_invalid(switch_type)) 26889 return ira->codegen->invalid_inst_gen; 26890 26891 if (switch_type->id == ZigTypeIdEnum) { 26892 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> field_prev_uses = {}; 26893 field_prev_uses.init(switch_type->data.enumeration.src_field_count); 26894 26895 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 26896 IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 26897 26898 IrInstGen *start_value_uncasted = range->start->child; 26899 if (type_is_invalid(start_value_uncasted->value->type)) 26900 return ira->codegen->invalid_inst_gen; 26901 IrInstGen *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); 26902 if (type_is_invalid(start_value->value->type)) 26903 return ira->codegen->invalid_inst_gen; 26904 26905 IrInstGen *end_value_uncasted = range->end->child; 26906 if (type_is_invalid(end_value_uncasted->value->type)) 26907 return ira->codegen->invalid_inst_gen; 26908 IrInstGen *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); 26909 if (type_is_invalid(end_value->value->type)) 26910 return ira->codegen->invalid_inst_gen; 26911 26912 assert(start_value->value->type->id == ZigTypeIdEnum); 26913 BigInt start_index; 26914 bigint_init_bigint(&start_index, &start_value->value->data.x_enum_tag); 26915 26916 assert(end_value->value->type->id == ZigTypeIdEnum); 26917 BigInt end_index; 26918 bigint_init_bigint(&end_index, &end_value->value->data.x_enum_tag); 26919 26920 if (bigint_cmp(&start_index, &end_index) == CmpGT) { 26921 ir_add_error(ira, &start_value->base, 26922 buf_sprintf("range start value is greater than the end value")); 26923 } 26924 26925 BigInt field_index; 26926 bigint_init_bigint(&field_index, &start_index); 26927 for (;;) { 26928 Cmp cmp = bigint_cmp(&field_index, &end_index); 26929 if (cmp == CmpGT) { 26930 break; 26931 } 26932 auto entry = field_prev_uses.put_unique(field_index, start_value->base.source_node); 26933 if (entry) { 26934 AstNode *prev_node = entry->value; 26935 TypeEnumField *enum_field = find_enum_field_by_tag(switch_type, &field_index); 26936 assert(enum_field != nullptr); 26937 ErrorMsg *msg = ir_add_error(ira, &start_value->base, 26938 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), 26939 buf_ptr(enum_field->name))); 26940 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 26941 } 26942 bigint_incr(&field_index); 26943 } 26944 } 26945 if (instruction->have_underscore_prong) { 26946 if (!switch_type->data.enumeration.non_exhaustive){ 26947 ir_add_error(ira, &instruction->base.base, 26948 buf_sprintf("switch on non-exhaustive enum has `_` prong")); 26949 } 26950 for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { 26951 TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i]; 26952 if (buf_eql_str(enum_field->name, "_")) 26953 continue; 26954 26955 auto entry = field_prev_uses.maybe_get(enum_field->value); 26956 if (!entry) { 26957 ir_add_error(ira, &instruction->base.base, 26958 buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name), 26959 buf_ptr(enum_field->name))); 26960 } 26961 } 26962 } else if (!instruction->have_else_prong) { 26963 if (switch_type->data.enumeration.non_exhaustive) { 26964 ir_add_error(ira, &instruction->base.base, 26965 buf_sprintf("switch on non-exhaustive enum must include `else` or `_` prong")); 26966 } 26967 for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { 26968 TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i]; 26969 26970 auto entry = field_prev_uses.maybe_get(enum_field->value); 26971 if (!entry) { 26972 ir_add_error(ira, &instruction->base.base, 26973 buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name), 26974 buf_ptr(enum_field->name))); 26975 } 26976 } 26977 } 26978 } else if (switch_type->id == ZigTypeIdErrorSet) { 26979 if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->base.source_node)) { 26980 return ira->codegen->invalid_inst_gen; 26981 } 26982 26983 size_t field_prev_uses_count = ira->codegen->errors_by_index.length; 26984 AstNode **field_prev_uses = heap::c_allocator.allocate<AstNode *>(field_prev_uses_count); 26985 26986 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 26987 IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 26988 26989 IrInstGen *start_value_uncasted = range->start->child; 26990 if (type_is_invalid(start_value_uncasted->value->type)) 26991 return ira->codegen->invalid_inst_gen; 26992 IrInstGen *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); 26993 if (type_is_invalid(start_value->value->type)) 26994 return ira->codegen->invalid_inst_gen; 26995 26996 IrInstGen *end_value_uncasted = range->end->child; 26997 if (type_is_invalid(end_value_uncasted->value->type)) 26998 return ira->codegen->invalid_inst_gen; 26999 IrInstGen *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); 27000 if (type_is_invalid(end_value->value->type)) 27001 return ira->codegen->invalid_inst_gen; 27002 27003 ir_assert(start_value->value->type->id == ZigTypeIdErrorSet, &instruction->base.base); 27004 uint32_t start_index = start_value->value->data.x_err_set->value; 27005 27006 ir_assert(end_value->value->type->id == ZigTypeIdErrorSet, &instruction->base.base); 27007 uint32_t end_index = end_value->value->data.x_err_set->value; 27008 27009 if (start_index != end_index) { 27010 ir_add_error(ira, &end_value->base, buf_sprintf("ranges not allowed when switching on errors")); 27011 return ira->codegen->invalid_inst_gen; 27012 } 27013 27014 AstNode *prev_node = field_prev_uses[start_index]; 27015 if (prev_node != nullptr) { 27016 Buf *err_name = &ira->codegen->errors_by_index.at(start_index)->name; 27017 ErrorMsg *msg = ir_add_error(ira, &start_value->base, 27018 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), buf_ptr(err_name))); 27019 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 27020 } 27021 field_prev_uses[start_index] = start_value->base.source_node; 27022 } 27023 if (!instruction->have_else_prong) { 27024 if (type_is_global_error_set(switch_type)) { 27025 ir_add_error(ira, &instruction->base.base, 27026 buf_sprintf("else prong required when switching on type 'anyerror'")); 27027 return ira->codegen->invalid_inst_gen; 27028 } else { 27029 for (uint32_t i = 0; i < switch_type->data.error_set.err_count; i += 1) { 27030 ErrorTableEntry *err_entry = switch_type->data.error_set.errors[i]; 27031 27032 AstNode *prev_node = field_prev_uses[err_entry->value]; 27033 if (prev_node == nullptr) { 27034 ir_add_error(ira, &instruction->base.base, 27035 buf_sprintf("error.%s not handled in switch", buf_ptr(&err_entry->name))); 27036 } 27037 } 27038 } 27039 } 27040 27041 heap::c_allocator.deallocate(field_prev_uses, field_prev_uses_count); 27042 } else if (switch_type->id == ZigTypeIdInt) { 27043 RangeSet rs = {0}; 27044 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 27045 IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 27046 27047 IrInstGen *start_value = range->start->child; 27048 if (type_is_invalid(start_value->value->type)) 27049 return ira->codegen->invalid_inst_gen; 27050 IrInstGen *casted_start_value = ir_implicit_cast(ira, start_value, switch_type); 27051 if (type_is_invalid(casted_start_value->value->type)) 27052 return ira->codegen->invalid_inst_gen; 27053 27054 IrInstGen *end_value = range->end->child; 27055 if (type_is_invalid(end_value->value->type)) 27056 return ira->codegen->invalid_inst_gen; 27057 IrInstGen *casted_end_value = ir_implicit_cast(ira, end_value, switch_type); 27058 if (type_is_invalid(casted_end_value->value->type)) 27059 return ira->codegen->invalid_inst_gen; 27060 27061 ZigValue *start_val = ir_resolve_const(ira, casted_start_value, UndefBad); 27062 if (!start_val) 27063 return ira->codegen->invalid_inst_gen; 27064 27065 ZigValue *end_val = ir_resolve_const(ira, casted_end_value, UndefBad); 27066 if (!end_val) 27067 return ira->codegen->invalid_inst_gen; 27068 27069 assert(start_val->type->id == ZigTypeIdInt || start_val->type->id == ZigTypeIdComptimeInt); 27070 assert(end_val->type->id == ZigTypeIdInt || end_val->type->id == ZigTypeIdComptimeInt); 27071 27072 if (bigint_cmp(&start_val->data.x_bigint, &end_val->data.x_bigint) == CmpGT) { 27073 ir_add_error(ira, &start_value->base, 27074 buf_sprintf("range start value is greater than the end value")); 27075 } 27076 27077 AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint, 27078 start_value->base.source_node); 27079 if (prev_node != nullptr) { 27080 ErrorMsg *msg = ir_add_error(ira, &start_value->base, buf_sprintf("duplicate switch value")); 27081 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("previous value is here")); 27082 return ira->codegen->invalid_inst_gen; 27083 } 27084 } 27085 if (!instruction->have_else_prong) { 27086 BigInt min_val; 27087 eval_min_max_value_int(ira->codegen, switch_type, &min_val, false); 27088 BigInt max_val; 27089 eval_min_max_value_int(ira->codegen, switch_type, &max_val, true); 27090 if (!rangeset_spans(&rs, &min_val, &max_val)) { 27091 ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities")); 27092 return ira->codegen->invalid_inst_gen; 27093 } 27094 } 27095 } else if (switch_type->id == ZigTypeIdBool) { 27096 int seenTrue = 0; 27097 int seenFalse = 0; 27098 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 27099 IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 27100 27101 IrInstGen *value = range->start->child; 27102 27103 IrInstGen *casted_value = ir_implicit_cast(ira, value, switch_type); 27104 if (type_is_invalid(casted_value->value->type)) 27105 return ira->codegen->invalid_inst_gen; 27106 27107 ZigValue *const_expr_val = ir_resolve_const(ira, casted_value, UndefBad); 27108 if (!const_expr_val) 27109 return ira->codegen->invalid_inst_gen; 27110 27111 assert(const_expr_val->type->id == ZigTypeIdBool); 27112 27113 if (const_expr_val->data.x_bool == true) { 27114 seenTrue += 1; 27115 } else { 27116 seenFalse += 1; 27117 } 27118 27119 if ((seenTrue > 1) || (seenFalse > 1)) { 27120 ir_add_error(ira, &value->base, buf_sprintf("duplicate switch value")); 27121 return ira->codegen->invalid_inst_gen; 27122 } 27123 } 27124 if (((seenTrue < 1) || (seenFalse < 1)) && !instruction->have_else_prong) { 27125 ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities")); 27126 return ira->codegen->invalid_inst_gen; 27127 } 27128 } else if (!instruction->have_else_prong) { 27129 ir_add_error(ira, &instruction->base.base, 27130 buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name))); 27131 return ira->codegen->invalid_inst_gen; 27132 } 27133 return ir_const_void(ira, &instruction->base.base); 27134 } 27135 27136 static IrInstGen *ir_analyze_instruction_check_statement_is_void(IrAnalyze *ira, 27137 IrInstSrcCheckStatementIsVoid *instruction) 27138 { 27139 IrInstGen *statement_value = instruction->statement_value->child; 27140 ZigType *statement_type = statement_value->value->type; 27141 if (type_is_invalid(statement_type)) 27142 return ira->codegen->invalid_inst_gen; 27143 27144 if (statement_type->id != ZigTypeIdVoid && statement_type->id != ZigTypeIdUnreachable) { 27145 ir_add_error(ira, &instruction->base.base, buf_sprintf("expression value is ignored")); 27146 } 27147 27148 return ir_const_void(ira, &instruction->base.base); 27149 } 27150 27151 static IrInstGen *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstSrcPanic *instruction) { 27152 IrInstGen *msg = instruction->msg->child; 27153 if (type_is_invalid(msg->value->type)) 27154 return ir_unreach_error(ira); 27155 27156 if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope)) { 27157 ir_add_error(ira, &instruction->base.base, buf_sprintf("encountered @panic at compile-time")); 27158 return ir_unreach_error(ira); 27159 } 27160 27161 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 27162 true, false, PtrLenUnknown, 0, 0, 0, false); 27163 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 27164 IrInstGen *casted_msg = ir_implicit_cast(ira, msg, str_type); 27165 if (type_is_invalid(casted_msg->value->type)) 27166 return ir_unreach_error(ira); 27167 27168 IrInstGen *new_instruction = ir_build_panic_gen(ira, &instruction->base.base, casted_msg); 27169 return ir_finish_anal(ira, new_instruction); 27170 } 27171 27172 static IrInstGen *ir_align_cast(IrAnalyze *ira, IrInstGen *target, uint32_t align_bytes, bool safety_check_on) { 27173 Error err; 27174 27175 ZigType *target_type = target->value->type; 27176 assert(!type_is_invalid(target_type)); 27177 27178 ZigType *result_type; 27179 uint32_t old_align_bytes; 27180 27181 if (target_type->id == ZigTypeIdPointer) { 27182 result_type = adjust_ptr_align(ira->codegen, target_type, align_bytes); 27183 if ((err = resolve_ptr_align(ira, target_type, &old_align_bytes))) 27184 return ira->codegen->invalid_inst_gen; 27185 } else if (target_type->id == ZigTypeIdFn) { 27186 FnTypeId fn_type_id = target_type->data.fn.fn_type_id; 27187 old_align_bytes = fn_type_id.alignment; 27188 fn_type_id.alignment = align_bytes; 27189 result_type = get_fn_type(ira->codegen, &fn_type_id); 27190 } else if (target_type->id == ZigTypeIdOptional && 27191 target_type->data.maybe.child_type->id == ZigTypeIdPointer) 27192 { 27193 ZigType *ptr_type = target_type->data.maybe.child_type; 27194 if ((err = resolve_ptr_align(ira, ptr_type, &old_align_bytes))) 27195 return ira->codegen->invalid_inst_gen; 27196 ZigType *better_ptr_type = adjust_ptr_align(ira->codegen, ptr_type, align_bytes); 27197 27198 result_type = get_optional_type(ira->codegen, better_ptr_type); 27199 } else if (target_type->id == ZigTypeIdOptional && 27200 target_type->data.maybe.child_type->id == ZigTypeIdFn) 27201 { 27202 FnTypeId fn_type_id = target_type->data.maybe.child_type->data.fn.fn_type_id; 27203 old_align_bytes = fn_type_id.alignment; 27204 fn_type_id.alignment = align_bytes; 27205 ZigType *fn_type = get_fn_type(ira->codegen, &fn_type_id); 27206 result_type = get_optional_type(ira->codegen, fn_type); 27207 } else if (is_slice(target_type)) { 27208 ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry; 27209 if ((err = resolve_ptr_align(ira, slice_ptr_type, &old_align_bytes))) 27210 return ira->codegen->invalid_inst_gen; 27211 ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes); 27212 result_type = get_slice_type(ira->codegen, result_ptr_type); 27213 } else { 27214 ir_add_error(ira, &target->base, 27215 buf_sprintf("expected pointer or slice, found '%s'", buf_ptr(&target_type->name))); 27216 return ira->codegen->invalid_inst_gen; 27217 } 27218 27219 if (instr_is_comptime(target)) { 27220 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 27221 if (!val) 27222 return ira->codegen->invalid_inst_gen; 27223 27224 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 27225 val->data.x_ptr.data.hard_coded_addr.addr % align_bytes != 0) 27226 { 27227 ir_add_error(ira, &target->base, 27228 buf_sprintf("pointer address 0x%" ZIG_PRI_x64 " is not aligned to %" PRIu32 " bytes", 27229 val->data.x_ptr.data.hard_coded_addr.addr, align_bytes)); 27230 return ira->codegen->invalid_inst_gen; 27231 } 27232 27233 IrInstGen *result = ir_const(ira, &target->base, result_type); 27234 copy_const_val(ira->codegen, result->value, val); 27235 result->value->type = result_type; 27236 return result; 27237 } 27238 27239 if (safety_check_on && align_bytes > old_align_bytes && align_bytes != 1) { 27240 return ir_build_align_cast_gen(ira, target->base.scope, target->base.source_node, target, result_type); 27241 } else { 27242 return ir_build_cast(ira, &target->base, result_type, target, CastOpNoop); 27243 } 27244 } 27245 27246 static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr, 27247 IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on) 27248 { 27249 Error err; 27250 27251 ZigType *src_type = ptr->value->type; 27252 assert(!type_is_invalid(src_type)); 27253 27254 if (src_type == dest_type) { 27255 return ptr; 27256 } 27257 27258 // We have a check for zero bits later so we use get_src_ptr_type to 27259 // validate src_type and dest_type. 27260 27261 ZigType *src_ptr_type = get_src_ptr_type(src_type); 27262 if (src_ptr_type == nullptr) { 27263 ir_add_error(ira, ptr_src, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name))); 27264 return ira->codegen->invalid_inst_gen; 27265 } 27266 27267 ZigType *dest_ptr_type = get_src_ptr_type(dest_type); 27268 if (dest_ptr_type == nullptr) { 27269 ir_add_error(ira, dest_type_src, 27270 buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 27271 return ira->codegen->invalid_inst_gen; 27272 } 27273 27274 if (get_ptr_const(src_type) && !get_ptr_const(dest_type)) { 27275 ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); 27276 return ira->codegen->invalid_inst_gen; 27277 } 27278 uint32_t src_align_bytes; 27279 if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) 27280 return ira->codegen->invalid_inst_gen; 27281 27282 uint32_t dest_align_bytes; 27283 if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) 27284 return ira->codegen->invalid_inst_gen; 27285 27286 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 27287 return ira->codegen->invalid_inst_gen; 27288 27289 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown))) 27290 return ira->codegen->invalid_inst_gen; 27291 27292 if (type_has_bits(dest_type) && !type_has_bits(src_type) && safety_check_on) { 27293 ErrorMsg *msg = ir_add_error(ira, source_instr, 27294 buf_sprintf("'%s' and '%s' do not have the same in-memory representation", 27295 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 27296 add_error_note(ira->codegen, msg, ptr_src->source_node, 27297 buf_sprintf("'%s' has no in-memory bits", buf_ptr(&src_type->name))); 27298 add_error_note(ira->codegen, msg, dest_type_src->source_node, 27299 buf_sprintf("'%s' has in-memory bits", buf_ptr(&dest_type->name))); 27300 return ira->codegen->invalid_inst_gen; 27301 } 27302 27303 if (instr_is_comptime(ptr)) { 27304 bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); 27305 UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad; 27306 ZigValue *val = ir_resolve_const(ira, ptr, is_undef_allowed); 27307 if (val == nullptr) 27308 return ira->codegen->invalid_inst_gen; 27309 27310 if (value_is_comptime(val) && val->special != ConstValSpecialUndef) { 27311 bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull || 27312 (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 27313 val->data.x_ptr.data.hard_coded_addr.addr == 0); 27314 if (is_addr_zero && !dest_allows_addr_zero) { 27315 ir_add_error(ira, source_instr, 27316 buf_sprintf("null pointer casted to type '%s'", buf_ptr(&dest_type->name))); 27317 return ira->codegen->invalid_inst_gen; 27318 } 27319 } 27320 27321 IrInstGen *result; 27322 if (val->data.x_ptr.mut == ConstPtrMutInfer) { 27323 result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); 27324 } else { 27325 result = ir_const(ira, source_instr, dest_type); 27326 } 27327 InferredStructField *isf = (val->type->id == ZigTypeIdPointer) ? 27328 val->type->data.pointer.inferred_struct_field : nullptr; 27329 if (isf == nullptr) { 27330 copy_const_val(ira->codegen, result->value, val); 27331 } else { 27332 // The destination value should have x_ptr struct pointing to underlying struct value 27333 result->value->data.x_ptr.mut = val->data.x_ptr.mut; 27334 TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); 27335 assert(field != nullptr); 27336 if (field->is_comptime) { 27337 result->value->data.x_ptr.special = ConstPtrSpecialRef; 27338 result->value->data.x_ptr.data.ref.pointee = field->init_val; 27339 } else { 27340 assert(val->data.x_ptr.special == ConstPtrSpecialRef); 27341 result->value->data.x_ptr.special = ConstPtrSpecialBaseStruct; 27342 result->value->data.x_ptr.data.base_struct.struct_val = val->data.x_ptr.data.ref.pointee; 27343 result->value->data.x_ptr.data.base_struct.field_index = field->src_index; 27344 } 27345 result->value->special = ConstValSpecialStatic; 27346 } 27347 result->value->type = dest_type; 27348 27349 // Keep the bigger alignment, it can only help- 27350 // unless the target is zero bits. 27351 if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { 27352 result = ir_align_cast(ira, result, src_align_bytes, false); 27353 } 27354 27355 return result; 27356 } 27357 27358 if (dest_align_bytes > src_align_bytes) { 27359 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 27360 add_error_note(ira->codegen, msg, ptr_src->source_node, 27361 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_type->name), src_align_bytes)); 27362 add_error_note(ira->codegen, msg, dest_type_src->source_node, 27363 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&dest_type->name), dest_align_bytes)); 27364 return ira->codegen->invalid_inst_gen; 27365 } 27366 27367 IrInstGen *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); 27368 27369 // Keep the bigger alignment, it can only help- 27370 // unless the target is zero bits. 27371 IrInstGen *result; 27372 if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { 27373 result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); 27374 if (type_is_invalid(result->value->type)) 27375 return ira->codegen->invalid_inst_gen; 27376 } else { 27377 result = casted_ptr; 27378 } 27379 return result; 27380 } 27381 27382 static IrInstGen *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstSrcPtrCast *instruction) { 27383 IrInstGen *dest_type_value = instruction->dest_type->child; 27384 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 27385 if (type_is_invalid(dest_type)) 27386 return ira->codegen->invalid_inst_gen; 27387 27388 IrInstGen *ptr = instruction->ptr->child; 27389 ZigType *src_type = ptr->value->type; 27390 if (type_is_invalid(src_type)) 27391 return ira->codegen->invalid_inst_gen; 27392 27393 return ir_analyze_ptr_cast(ira, &instruction->base.base, ptr, &instruction->ptr->base, 27394 dest_type, &dest_type_value->base, instruction->safety_check_on); 27395 } 27396 27397 static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ZigValue *val, size_t len) { 27398 size_t buf_i = 0; 27399 // TODO optimize the buf case 27400 expand_undef_array(codegen, val); 27401 for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) { 27402 ZigValue *elem = &val->data.x_array.data.s_none.elements[elem_i]; 27403 buf_write_value_bytes(codegen, &buf[buf_i], elem); 27404 buf_i += type_size(codegen, elem->type); 27405 } 27406 } 27407 27408 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val) { 27409 if (val->special == ConstValSpecialUndef) { 27410 expand_undef_struct(codegen, val); 27411 val->special = ConstValSpecialStatic; 27412 } 27413 assert(val->special == ConstValSpecialStatic); 27414 switch (val->type->id) { 27415 case ZigTypeIdInvalid: 27416 case ZigTypeIdMetaType: 27417 case ZigTypeIdOpaque: 27418 case ZigTypeIdBoundFn: 27419 case ZigTypeIdUnreachable: 27420 case ZigTypeIdComptimeFloat: 27421 case ZigTypeIdComptimeInt: 27422 case ZigTypeIdEnumLiteral: 27423 case ZigTypeIdUndefined: 27424 case ZigTypeIdNull: 27425 case ZigTypeIdErrorUnion: 27426 case ZigTypeIdErrorSet: 27427 zig_unreachable(); 27428 case ZigTypeIdVoid: 27429 return; 27430 case ZigTypeIdBool: 27431 buf[0] = val->data.x_bool ? 1 : 0; 27432 return; 27433 case ZigTypeIdInt: 27434 bigint_write_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 27435 codegen->is_big_endian); 27436 return; 27437 case ZigTypeIdEnum: 27438 bigint_write_twos_complement(&val->data.x_enum_tag, buf, 27439 val->type->data.enumeration.tag_int_type->data.integral.bit_count, 27440 codegen->is_big_endian); 27441 return; 27442 case ZigTypeIdFloat: 27443 float_write_ieee597(val, buf, codegen->is_big_endian); 27444 return; 27445 case ZigTypeIdPointer: 27446 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 27447 BigInt bn; 27448 bigint_init_unsigned(&bn, val->data.x_ptr.data.hard_coded_addr.addr); 27449 bigint_write_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, codegen->is_big_endian); 27450 return; 27451 } else { 27452 zig_unreachable(); 27453 } 27454 case ZigTypeIdArray: 27455 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.array.len); 27456 case ZigTypeIdVector: 27457 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.vector.len); 27458 case ZigTypeIdStruct: 27459 switch (val->type->data.structure.layout) { 27460 case ContainerLayoutAuto: 27461 zig_unreachable(); 27462 case ContainerLayoutExtern: { 27463 size_t src_field_count = val->type->data.structure.src_field_count; 27464 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { 27465 TypeStructField *struct_field = val->type->data.structure.fields[field_i]; 27466 if (struct_field->gen_index == SIZE_MAX) 27467 continue; 27468 ZigValue *field_val = val->data.x_struct.fields[field_i]; 27469 size_t offset = struct_field->offset; 27470 buf_write_value_bytes(codegen, buf + offset, field_val); 27471 } 27472 return; 27473 } 27474 case ContainerLayoutPacked: { 27475 size_t src_field_count = val->type->data.structure.src_field_count; 27476 size_t gen_field_count = val->type->data.structure.gen_field_count; 27477 size_t gen_i = 0; 27478 size_t src_i = 0; 27479 size_t offset = 0; 27480 bool is_big_endian = codegen->is_big_endian; 27481 uint8_t child_buf_prealloc[16]; 27482 size_t child_buf_len = 16; 27483 uint8_t *child_buf = child_buf_prealloc; 27484 while (gen_i < gen_field_count) { 27485 size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i]; 27486 if (big_int_byte_count > child_buf_len) { 27487 child_buf = heap::c_allocator.allocate_nonzero<uint8_t>(big_int_byte_count); 27488 child_buf_len = big_int_byte_count; 27489 } 27490 BigInt big_int; 27491 bigint_init_unsigned(&big_int, 0); 27492 size_t used_bits = 0; 27493 while (src_i < src_field_count) { 27494 TypeStructField *field = val->type->data.structure.fields[src_i]; 27495 assert(field->gen_index != SIZE_MAX); 27496 if (field->gen_index != gen_i) 27497 break; 27498 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); 27499 buf_write_value_bytes(codegen, child_buf, val->data.x_struct.fields[src_i]); 27500 BigInt child_val; 27501 bigint_read_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian, 27502 false); 27503 if (is_big_endian) { 27504 BigInt shift_amt; 27505 bigint_init_unsigned(&shift_amt, packed_bits_size); 27506 BigInt shifted; 27507 bigint_shl(&shifted, &big_int, &shift_amt); 27508 bigint_or(&big_int, &shifted, &child_val); 27509 } else { 27510 BigInt shift_amt; 27511 bigint_init_unsigned(&shift_amt, used_bits); 27512 BigInt child_val_shifted; 27513 bigint_shl(&child_val_shifted, &child_val, &shift_amt); 27514 BigInt tmp; 27515 bigint_or(&tmp, &big_int, &child_val_shifted); 27516 big_int = tmp; 27517 used_bits += packed_bits_size; 27518 } 27519 src_i += 1; 27520 } 27521 bigint_write_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian); 27522 offset += big_int_byte_count; 27523 gen_i += 1; 27524 } 27525 return; 27526 } 27527 } 27528 case ZigTypeIdOptional: 27529 zig_panic("TODO buf_write_value_bytes maybe type"); 27530 case ZigTypeIdFn: 27531 zig_panic("TODO buf_write_value_bytes fn type"); 27532 case ZigTypeIdUnion: 27533 zig_panic("TODO buf_write_value_bytes union type"); 27534 case ZigTypeIdFnFrame: 27535 zig_panic("TODO buf_write_value_bytes async fn frame type"); 27536 case ZigTypeIdAnyFrame: 27537 zig_panic("TODO buf_write_value_bytes anyframe type"); 27538 } 27539 zig_unreachable(); 27540 } 27541 27542 static Error buf_read_value_bytes_array(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, 27543 ZigValue *val, ZigType *elem_type, size_t len) 27544 { 27545 Error err; 27546 uint64_t elem_size = type_size(codegen, elem_type); 27547 27548 switch (val->data.x_array.special) { 27549 case ConstArraySpecialNone: 27550 val->data.x_array.data.s_none.elements = codegen->pass1_arena->allocate<ZigValue>(len); 27551 for (size_t i = 0; i < len; i++) { 27552 ZigValue *elem = &val->data.x_array.data.s_none.elements[i]; 27553 elem->special = ConstValSpecialStatic; 27554 elem->type = elem_type; 27555 if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem))) 27556 return err; 27557 } 27558 return ErrorNone; 27559 case ConstArraySpecialUndef: 27560 zig_panic("TODO buf_read_value_bytes ConstArraySpecialUndef array type"); 27561 case ConstArraySpecialBuf: 27562 zig_panic("TODO buf_read_value_bytes ConstArraySpecialBuf array type"); 27563 } 27564 zig_unreachable(); 27565 } 27566 27567 static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ZigValue *val) { 27568 Error err; 27569 src_assert(val->special == ConstValSpecialStatic, source_node); 27570 switch (val->type->id) { 27571 case ZigTypeIdInvalid: 27572 case ZigTypeIdMetaType: 27573 case ZigTypeIdOpaque: 27574 case ZigTypeIdBoundFn: 27575 case ZigTypeIdUnreachable: 27576 case ZigTypeIdComptimeFloat: 27577 case ZigTypeIdComptimeInt: 27578 case ZigTypeIdEnumLiteral: 27579 case ZigTypeIdUndefined: 27580 case ZigTypeIdNull: 27581 zig_unreachable(); 27582 case ZigTypeIdVoid: 27583 return ErrorNone; 27584 case ZigTypeIdBool: 27585 val->data.x_bool = (buf[0] != 0); 27586 return ErrorNone; 27587 case ZigTypeIdInt: 27588 bigint_read_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 27589 codegen->is_big_endian, val->type->data.integral.is_signed); 27590 return ErrorNone; 27591 case ZigTypeIdFloat: 27592 float_read_ieee597(val, buf, codegen->is_big_endian); 27593 return ErrorNone; 27594 case ZigTypeIdPointer: 27595 { 27596 val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 27597 BigInt bn; 27598 bigint_read_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, 27599 codegen->is_big_endian, false); 27600 val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_usize(&bn); 27601 return ErrorNone; 27602 } 27603 case ZigTypeIdArray: 27604 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.array.child_type, 27605 val->type->data.array.len); 27606 case ZigTypeIdVector: 27607 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.vector.elem_type, 27608 val->type->data.vector.len); 27609 case ZigTypeIdEnum: 27610 switch (val->type->data.enumeration.layout) { 27611 case ContainerLayoutAuto: 27612 zig_panic("TODO buf_read_value_bytes enum auto"); 27613 case ContainerLayoutPacked: 27614 zig_panic("TODO buf_read_value_bytes enum packed"); 27615 case ContainerLayoutExtern: { 27616 ZigType *tag_int_type = val->type->data.enumeration.tag_int_type; 27617 src_assert(tag_int_type->id == ZigTypeIdInt, source_node); 27618 bigint_read_twos_complement(&val->data.x_enum_tag, buf, tag_int_type->data.integral.bit_count, 27619 codegen->is_big_endian, tag_int_type->data.integral.is_signed); 27620 return ErrorNone; 27621 } 27622 } 27623 zig_unreachable(); 27624 case ZigTypeIdStruct: 27625 switch (val->type->data.structure.layout) { 27626 case ContainerLayoutAuto: { 27627 ErrorMsg *msg = opt_ir_add_error_node(ira, codegen, source_node, 27628 buf_sprintf("non-extern, non-packed struct '%s' cannot have its bytes reinterpreted", 27629 buf_ptr(&val->type->name))); 27630 add_error_note(codegen, msg, val->type->data.structure.decl_node, 27631 buf_sprintf("declared here")); 27632 return ErrorSemanticAnalyzeFail; 27633 } 27634 case ContainerLayoutExtern: { 27635 size_t src_field_count = val->type->data.structure.src_field_count; 27636 val->data.x_struct.fields = alloc_const_vals_ptrs(codegen, src_field_count); 27637 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { 27638 ZigValue *field_val = val->data.x_struct.fields[field_i]; 27639 field_val->special = ConstValSpecialStatic; 27640 TypeStructField *struct_field = val->type->data.structure.fields[field_i]; 27641 field_val->type = struct_field->type_entry; 27642 if (struct_field->gen_index == SIZE_MAX) 27643 continue; 27644 size_t offset = struct_field->offset; 27645 uint8_t *new_buf = buf + offset; 27646 if ((err = buf_read_value_bytes(ira, codegen, source_node, new_buf, field_val))) 27647 return err; 27648 } 27649 return ErrorNone; 27650 } 27651 case ContainerLayoutPacked: { 27652 size_t src_field_count = val->type->data.structure.src_field_count; 27653 val->data.x_struct.fields = alloc_const_vals_ptrs(codegen, src_field_count); 27654 size_t gen_field_count = val->type->data.structure.gen_field_count; 27655 size_t gen_i = 0; 27656 size_t src_i = 0; 27657 size_t offset = 0; 27658 bool is_big_endian = codegen->is_big_endian; 27659 uint8_t child_buf_prealloc[16]; 27660 size_t child_buf_len = 16; 27661 uint8_t *child_buf = child_buf_prealloc; 27662 while (gen_i < gen_field_count) { 27663 size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i]; 27664 if (big_int_byte_count > child_buf_len) { 27665 child_buf = heap::c_allocator.allocate_nonzero<uint8_t>(big_int_byte_count); 27666 child_buf_len = big_int_byte_count; 27667 } 27668 BigInt big_int; 27669 bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false); 27670 while (src_i < src_field_count) { 27671 TypeStructField *field = val->type->data.structure.fields[src_i]; 27672 src_assert(field->gen_index != SIZE_MAX, source_node); 27673 if (field->gen_index != gen_i) 27674 break; 27675 ZigValue *field_val = val->data.x_struct.fields[src_i]; 27676 field_val->special = ConstValSpecialStatic; 27677 field_val->type = field->type_entry; 27678 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); 27679 27680 BigInt child_val; 27681 if (is_big_endian) { 27682 zig_panic("TODO buf_read_value_bytes packed struct big endian"); 27683 } else { 27684 BigInt packed_bits_size_bi; 27685 bigint_init_unsigned(&packed_bits_size_bi, packed_bits_size); 27686 bigint_truncate(&child_val, &big_int, packed_bits_size, false); 27687 BigInt tmp; 27688 bigint_shr(&tmp, &big_int, &packed_bits_size_bi); 27689 big_int = tmp; 27690 } 27691 27692 bigint_write_twos_complement(&child_val, child_buf, big_int_byte_count * 8, is_big_endian); 27693 if ((err = buf_read_value_bytes(ira, codegen, source_node, child_buf, field_val))) { 27694 return err; 27695 } 27696 27697 src_i += 1; 27698 } 27699 offset += big_int_byte_count; 27700 gen_i += 1; 27701 } 27702 return ErrorNone; 27703 } 27704 } 27705 zig_unreachable(); 27706 case ZigTypeIdOptional: 27707 zig_panic("TODO buf_read_value_bytes maybe type"); 27708 case ZigTypeIdErrorUnion: 27709 zig_panic("TODO buf_read_value_bytes error union"); 27710 case ZigTypeIdErrorSet: 27711 zig_panic("TODO buf_read_value_bytes pure error type"); 27712 case ZigTypeIdFn: 27713 zig_panic("TODO buf_read_value_bytes fn type"); 27714 case ZigTypeIdUnion: 27715 zig_panic("TODO buf_read_value_bytes union type"); 27716 case ZigTypeIdFnFrame: 27717 zig_panic("TODO buf_read_value_bytes async fn frame type"); 27718 case ZigTypeIdAnyFrame: 27719 zig_panic("TODO buf_read_value_bytes anyframe type"); 27720 } 27721 zig_unreachable(); 27722 } 27723 27724 static IrInstGen *ir_analyze_bit_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 27725 ZigType *dest_type) 27726 { 27727 Error err; 27728 27729 ZigType *src_type = value->value->type; 27730 ir_assert(get_codegen_ptr_type(src_type) == nullptr, source_instr); 27731 ir_assert(type_can_bit_cast(src_type), source_instr); 27732 ir_assert(get_codegen_ptr_type(dest_type) == nullptr, source_instr); 27733 ir_assert(type_can_bit_cast(dest_type), source_instr); 27734 27735 if (dest_type->id == ZigTypeIdEnum) { 27736 ErrorMsg *msg = ir_add_error_node(ira, source_instr->source_node, 27737 buf_sprintf("cannot cast a value of type '%s'", buf_ptr(&dest_type->name))); 27738 add_error_note(ira->codegen, msg, source_instr->source_node, 27739 buf_sprintf("use @intToEnum for type coercion")); 27740 return ira->codegen->invalid_inst_gen; 27741 } 27742 27743 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown))) 27744 return ira->codegen->invalid_inst_gen; 27745 27746 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusSizeKnown))) 27747 return ira->codegen->invalid_inst_gen; 27748 27749 uint64_t dest_size_bytes = type_size(ira->codegen, dest_type); 27750 uint64_t src_size_bytes = type_size(ira->codegen, src_type); 27751 if (dest_size_bytes != src_size_bytes) { 27752 ir_add_error(ira, source_instr, 27753 buf_sprintf("destination type '%s' has size %" ZIG_PRI_u64 " but source type '%s' has size %" ZIG_PRI_u64, 27754 buf_ptr(&dest_type->name), dest_size_bytes, 27755 buf_ptr(&src_type->name), src_size_bytes)); 27756 return ira->codegen->invalid_inst_gen; 27757 } 27758 27759 uint64_t dest_size_bits = type_size_bits(ira->codegen, dest_type); 27760 uint64_t src_size_bits = type_size_bits(ira->codegen, src_type); 27761 if (dest_size_bits != src_size_bits) { 27762 ir_add_error(ira, source_instr, 27763 buf_sprintf("destination type '%s' has %" ZIG_PRI_u64 " bits but source type '%s' has %" ZIG_PRI_u64 " bits", 27764 buf_ptr(&dest_type->name), dest_size_bits, 27765 buf_ptr(&src_type->name), src_size_bits)); 27766 return ira->codegen->invalid_inst_gen; 27767 } 27768 27769 if (instr_is_comptime(value)) { 27770 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 27771 if (!val) 27772 return ira->codegen->invalid_inst_gen; 27773 27774 IrInstGen *result = ir_const(ira, source_instr, dest_type); 27775 uint8_t *buf = heap::c_allocator.allocate_nonzero<uint8_t>(src_size_bytes); 27776 buf_write_value_bytes(ira->codegen, buf, val); 27777 if ((err = buf_read_value_bytes(ira, ira->codegen, source_instr->source_node, buf, result->value))) 27778 return ira->codegen->invalid_inst_gen; 27779 return result; 27780 } 27781 27782 return ir_build_bit_cast_gen(ira, source_instr, value, dest_type); 27783 } 27784 27785 static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 27786 ZigType *ptr_type) 27787 { 27788 Error err; 27789 27790 ir_assert(get_src_ptr_type(ptr_type) != nullptr, source_instr); 27791 ir_assert(type_has_bits(ptr_type), source_instr); 27792 27793 IrInstGen *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize); 27794 if (type_is_invalid(casted_int->value->type)) 27795 return ira->codegen->invalid_inst_gen; 27796 27797 if (instr_is_comptime(casted_int)) { 27798 ZigValue *val = ir_resolve_const(ira, casted_int, UndefBad); 27799 if (!val) 27800 return ira->codegen->invalid_inst_gen; 27801 27802 uint64_t addr = bigint_as_u64(&val->data.x_bigint); 27803 if (!ptr_allows_addr_zero(ptr_type) && addr == 0) { 27804 ir_add_error(ira, source_instr, 27805 buf_sprintf("pointer type '%s' does not allow address zero", buf_ptr(&ptr_type->name))); 27806 return ira->codegen->invalid_inst_gen; 27807 } 27808 27809 uint32_t align_bytes; 27810 if ((err = resolve_ptr_align(ira, ptr_type, &align_bytes))) 27811 return ira->codegen->invalid_inst_gen; 27812 27813 if (addr != 0 && addr % align_bytes != 0) { 27814 ir_add_error(ira, source_instr, 27815 buf_sprintf("pointer type '%s' requires aligned address", 27816 buf_ptr(&ptr_type->name))); 27817 return ira->codegen->invalid_inst_gen; 27818 } 27819 27820 IrInstGen *result = ir_const(ira, source_instr, ptr_type); 27821 result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 27822 result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; 27823 result->value->data.x_ptr.data.hard_coded_addr.addr = addr; 27824 return result; 27825 } 27826 27827 return ir_build_int_to_ptr_gen(ira, source_instr->scope, source_instr->source_node, casted_int, ptr_type); 27828 } 27829 27830 static IrInstGen *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstSrcIntToPtr *instruction) { 27831 Error err; 27832 IrInstGen *dest_type_value = instruction->dest_type->child; 27833 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 27834 if (type_is_invalid(dest_type)) 27835 return ira->codegen->invalid_inst_gen; 27836 27837 // We explicitly check for the size, so we can use get_src_ptr_type 27838 if (get_src_ptr_type(dest_type) == nullptr) { 27839 ir_add_error(ira, &dest_type_value->base, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 27840 return ira->codegen->invalid_inst_gen; 27841 } 27842 27843 bool has_bits; 27844 if ((err = type_has_bits2(ira->codegen, dest_type, &has_bits))) 27845 return ira->codegen->invalid_inst_gen; 27846 27847 if (!has_bits) { 27848 ir_add_error(ira, &dest_type_value->base, 27849 buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name))); 27850 return ira->codegen->invalid_inst_gen; 27851 } 27852 27853 IrInstGen *target = instruction->target->child; 27854 if (type_is_invalid(target->value->type)) 27855 return ira->codegen->invalid_inst_gen; 27856 27857 return ir_analyze_int_to_ptr(ira, &instruction->base.base, target, dest_type); 27858 } 27859 27860 static IrInstGen *ir_analyze_instruction_decl_ref(IrAnalyze *ira, IrInstSrcDeclRef *instruction) { 27861 IrInstGen *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base.base, instruction->tld); 27862 if (type_is_invalid(ref_instruction->value->type)) { 27863 return ira->codegen->invalid_inst_gen; 27864 } 27865 27866 if (instruction->lval == LValPtr) { 27867 return ref_instruction; 27868 } else { 27869 return ir_get_deref(ira, &instruction->base.base, ref_instruction, nullptr); 27870 } 27871 } 27872 27873 static IrInstGen *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstSrcPtrToInt *instruction) { 27874 Error err; 27875 IrInstGen *target = instruction->target->child; 27876 if (type_is_invalid(target->value->type)) 27877 return ira->codegen->invalid_inst_gen; 27878 27879 ZigType *usize = ira->codegen->builtin_types.entry_usize; 27880 27881 // We check size explicitly so we can use get_src_ptr_type here. 27882 if (get_src_ptr_type(target->value->type) == nullptr) { 27883 ir_add_error(ira, &target->base, 27884 buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value->type->name))); 27885 return ira->codegen->invalid_inst_gen; 27886 } 27887 27888 bool has_bits; 27889 if ((err = type_has_bits2(ira->codegen, target->value->type, &has_bits))) 27890 return ira->codegen->invalid_inst_gen; 27891 27892 if (!has_bits) { 27893 ir_add_error(ira, &target->base, 27894 buf_sprintf("pointer to size 0 type has no address")); 27895 return ira->codegen->invalid_inst_gen; 27896 } 27897 27898 if (instr_is_comptime(target)) { 27899 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 27900 if (!val) 27901 return ira->codegen->invalid_inst_gen; 27902 if (val->type->id == ZigTypeIdPointer && val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 27903 IrInstGen *result = ir_const(ira, &instruction->base.base, usize); 27904 bigint_init_unsigned(&result->value->data.x_bigint, val->data.x_ptr.data.hard_coded_addr.addr); 27905 result->value->type = usize; 27906 return result; 27907 } 27908 } 27909 27910 return ir_build_ptr_to_int_gen(ira, &instruction->base.base, target); 27911 } 27912 27913 static IrInstGen *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstSrcPtrType *instruction) { 27914 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); 27915 result->value->special = ConstValSpecialLazy; 27916 27917 LazyValuePtrType *lazy_ptr_type = heap::c_allocator.create<LazyValuePtrType>(); 27918 lazy_ptr_type->ira = ira; ira_ref(ira); 27919 result->value->data.x_lazy = &lazy_ptr_type->base; 27920 lazy_ptr_type->base.id = LazyValueIdPtrType; 27921 27922 if (instruction->sentinel != nullptr) { 27923 lazy_ptr_type->sentinel = instruction->sentinel->child; 27924 if (ir_resolve_const(ira, lazy_ptr_type->sentinel, LazyOk) == nullptr) 27925 return ira->codegen->invalid_inst_gen; 27926 } 27927 27928 lazy_ptr_type->elem_type = instruction->child_type->child; 27929 if (ir_resolve_type_lazy(ira, lazy_ptr_type->elem_type) == nullptr) 27930 return ira->codegen->invalid_inst_gen; 27931 27932 if (instruction->align_value != nullptr) { 27933 lazy_ptr_type->align_inst = instruction->align_value->child; 27934 if (ir_resolve_const(ira, lazy_ptr_type->align_inst, LazyOk) == nullptr) 27935 return ira->codegen->invalid_inst_gen; 27936 } 27937 27938 lazy_ptr_type->ptr_len = instruction->ptr_len; 27939 lazy_ptr_type->is_const = instruction->is_const; 27940 lazy_ptr_type->is_volatile = instruction->is_volatile; 27941 lazy_ptr_type->is_allowzero = instruction->is_allow_zero; 27942 lazy_ptr_type->bit_offset_in_host = instruction->bit_offset_start; 27943 lazy_ptr_type->host_int_bytes = instruction->host_int_bytes; 27944 27945 return result; 27946 } 27947 27948 static IrInstGen *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstSrcAlignCast *instruction) { 27949 IrInstGen *target = instruction->target->child; 27950 if (type_is_invalid(target->value->type)) 27951 return ira->codegen->invalid_inst_gen; 27952 27953 ZigType *elem_type = nullptr; 27954 if (is_slice(target->value->type)) { 27955 ZigType *slice_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry; 27956 elem_type = slice_ptr_type->data.pointer.child_type; 27957 } else if (target->value->type->id == ZigTypeIdPointer) { 27958 elem_type = target->value->type->data.pointer.child_type; 27959 } 27960 27961 uint32_t align_bytes; 27962 IrInstGen *align_bytes_inst = instruction->align_bytes->child; 27963 if (!ir_resolve_align(ira, align_bytes_inst, elem_type, &align_bytes)) 27964 return ira->codegen->invalid_inst_gen; 27965 27966 IrInstGen *result = ir_align_cast(ira, target, align_bytes, true); 27967 if (type_is_invalid(result->value->type)) 27968 return ira->codegen->invalid_inst_gen; 27969 27970 return result; 27971 } 27972 27973 static IrInstGen *ir_analyze_instruction_opaque_type(IrAnalyze *ira, IrInstSrcOpaqueType *instruction) { 27974 Buf *bare_name = buf_alloc(); 27975 Buf *full_name = get_anon_type_name(ira->codegen, ira->old_irb.exec, "opaque", 27976 instruction->base.base.scope, instruction->base.base.source_node, bare_name); 27977 ZigType *result_type = get_opaque_type(ira->codegen, instruction->base.base.scope, 27978 instruction->base.base.source_node, buf_ptr(full_name), bare_name); 27979 return ir_const_type(ira, &instruction->base.base, result_type); 27980 } 27981 27982 static IrInstGen *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstSrcSetAlignStack *instruction) { 27983 uint32_t align_bytes; 27984 IrInstGen *align_bytes_inst = instruction->align_bytes->child; 27985 if (!ir_resolve_align(ira, align_bytes_inst, nullptr, &align_bytes)) 27986 return ira->codegen->invalid_inst_gen; 27987 27988 if (align_bytes > 256) { 27989 ir_add_error(ira, &instruction->base.base, buf_sprintf("attempt to @setAlignStack(%" PRIu32 "); maximum is 256", align_bytes)); 27990 return ira->codegen->invalid_inst_gen; 27991 } 27992 27993 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 27994 if (fn_entry == nullptr) { 27995 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack outside function")); 27996 return ira->codegen->invalid_inst_gen; 27997 } 27998 if (fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionNaked) { 27999 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack in naked function")); 28000 return ira->codegen->invalid_inst_gen; 28001 } 28002 28003 if (fn_entry->fn_inline == FnInlineAlways) { 28004 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack in inline function")); 28005 return ira->codegen->invalid_inst_gen; 28006 } 28007 28008 if (fn_entry->set_alignstack_node != nullptr) { 28009 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 28010 buf_sprintf("alignstack set twice")); 28011 add_error_note(ira->codegen, msg, fn_entry->set_alignstack_node, buf_sprintf("first set here")); 28012 return ira->codegen->invalid_inst_gen; 28013 } 28014 28015 fn_entry->set_alignstack_node = instruction->base.base.source_node; 28016 fn_entry->alignstack_value = align_bytes; 28017 28018 return ir_const_void(ira, &instruction->base.base); 28019 } 28020 28021 static IrInstGen *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstSrcArgType *instruction) { 28022 IrInstGen *fn_type_inst = instruction->fn_type->child; 28023 ZigType *fn_type = ir_resolve_type(ira, fn_type_inst); 28024 if (type_is_invalid(fn_type)) 28025 return ira->codegen->invalid_inst_gen; 28026 28027 IrInstGen *arg_index_inst = instruction->arg_index->child; 28028 uint64_t arg_index; 28029 if (!ir_resolve_usize(ira, arg_index_inst, &arg_index)) 28030 return ira->codegen->invalid_inst_gen; 28031 28032 if (fn_type->id == ZigTypeIdBoundFn) { 28033 fn_type = fn_type->data.bound_fn.fn_type; 28034 arg_index += 1; 28035 } 28036 if (fn_type->id != ZigTypeIdFn) { 28037 ir_add_error(ira, &fn_type_inst->base, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); 28038 return ira->codegen->invalid_inst_gen; 28039 } 28040 28041 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 28042 if (arg_index >= fn_type_id->param_count) { 28043 if (instruction->allow_var) { 28044 // TODO remove this with var args 28045 return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_var); 28046 } 28047 ir_add_error(ira, &arg_index_inst->base, 28048 buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments", 28049 arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count)); 28050 return ira->codegen->invalid_inst_gen; 28051 } 28052 28053 ZigType *result_type = fn_type_id->param_info[arg_index].type; 28054 if (result_type == nullptr) { 28055 // Args are only unresolved if our function is generic. 28056 ir_assert(fn_type->data.fn.is_generic, &instruction->base.base); 28057 28058 if (instruction->allow_var) { 28059 return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_var); 28060 } else { 28061 ir_add_error(ira, &arg_index_inst->base, 28062 buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", 28063 arg_index, buf_ptr(&fn_type->name))); 28064 return ira->codegen->invalid_inst_gen; 28065 } 28066 } 28067 return ir_const_type(ira, &instruction->base.base, result_type); 28068 } 28069 28070 static IrInstGen *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstSrcTagType *instruction) { 28071 Error err; 28072 IrInstGen *target_inst = instruction->target->child; 28073 ZigType *enum_type = ir_resolve_type(ira, target_inst); 28074 if (type_is_invalid(enum_type)) 28075 return ira->codegen->invalid_inst_gen; 28076 28077 if (enum_type->id == ZigTypeIdEnum) { 28078 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown))) 28079 return ira->codegen->invalid_inst_gen; 28080 28081 return ir_const_type(ira, &instruction->base.base, enum_type->data.enumeration.tag_int_type); 28082 } else if (enum_type->id == ZigTypeIdUnion) { 28083 ZigType *tag_type = ir_resolve_union_tag_type(ira, instruction->target->base.source_node, enum_type); 28084 if (type_is_invalid(tag_type)) 28085 return ira->codegen->invalid_inst_gen; 28086 return ir_const_type(ira, &instruction->base.base, tag_type); 28087 } else { 28088 ir_add_error(ira, &target_inst->base, buf_sprintf("expected enum or union, found '%s'", 28089 buf_ptr(&enum_type->name))); 28090 return ira->codegen->invalid_inst_gen; 28091 } 28092 } 28093 28094 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) { 28095 ZigType *operand_type = ir_resolve_type(ira, op); 28096 if (type_is_invalid(operand_type)) 28097 return ira->codegen->builtin_types.entry_invalid; 28098 28099 if (operand_type->id == ZigTypeIdInt) { 28100 if (operand_type->data.integral.bit_count < 8) { 28101 ir_add_error(ira, &op->base, 28102 buf_sprintf("expected integer type 8 bits or larger, found %" PRIu32 "-bit integer type", 28103 operand_type->data.integral.bit_count)); 28104 return ira->codegen->builtin_types.entry_invalid; 28105 } 28106 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); 28107 if (operand_type->data.integral.bit_count > max_atomic_bits) { 28108 ir_add_error(ira, &op->base, 28109 buf_sprintf("expected %" PRIu32 "-bit integer type or smaller, found %" PRIu32 "-bit integer type", 28110 max_atomic_bits, operand_type->data.integral.bit_count)); 28111 return ira->codegen->builtin_types.entry_invalid; 28112 } 28113 if (!is_power_of_2(operand_type->data.integral.bit_count)) { 28114 ir_add_error(ira, &op->base, 28115 buf_sprintf("%" PRIu32 "-bit integer type is not a power of 2", operand_type->data.integral.bit_count)); 28116 return ira->codegen->builtin_types.entry_invalid; 28117 } 28118 } else if (operand_type->id == ZigTypeIdEnum) { 28119 ZigType *int_type = operand_type->data.enumeration.tag_int_type; 28120 if (int_type->data.integral.bit_count < 8) { 28121 ir_add_error(ira, &op->base, 28122 buf_sprintf("expected enum tag type 8 bits or larger, found %" PRIu32 "-bit tag type", 28123 int_type->data.integral.bit_count)); 28124 return ira->codegen->builtin_types.entry_invalid; 28125 } 28126 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); 28127 if (int_type->data.integral.bit_count > max_atomic_bits) { 28128 ir_add_error(ira, &op->base, 28129 buf_sprintf("expected %" PRIu32 "-bit enum tag type or smaller, found %" PRIu32 "-bit tag type", 28130 max_atomic_bits, int_type->data.integral.bit_count)); 28131 return ira->codegen->builtin_types.entry_invalid; 28132 } 28133 if (!is_power_of_2(int_type->data.integral.bit_count)) { 28134 ir_add_error(ira, &op->base, 28135 buf_sprintf("%" PRIu32 "-bit enum tag type is not a power of 2", int_type->data.integral.bit_count)); 28136 return ira->codegen->builtin_types.entry_invalid; 28137 } 28138 } else if (operand_type->id == ZigTypeIdFloat) { 28139 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); 28140 if (operand_type->data.floating.bit_count > max_atomic_bits) { 28141 ir_add_error(ira, &op->base, 28142 buf_sprintf("expected %" PRIu32 "-bit float or smaller, found %" PRIu32 "-bit float", 28143 max_atomic_bits, (uint32_t) operand_type->data.floating.bit_count)); 28144 return ira->codegen->builtin_types.entry_invalid; 28145 } 28146 } else if (get_codegen_ptr_type(operand_type) == nullptr) { 28147 ir_add_error(ira, &op->base, 28148 buf_sprintf("expected integer, float, enum or pointer type, found '%s'", buf_ptr(&operand_type->name))); 28149 return ira->codegen->builtin_types.entry_invalid; 28150 } 28151 28152 return operand_type; 28153 } 28154 28155 static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAtomicRmw *instruction) { 28156 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 28157 if (type_is_invalid(operand_type)) 28158 return ira->codegen->invalid_inst_gen; 28159 28160 IrInstGen *ptr_inst = instruction->ptr->child; 28161 if (type_is_invalid(ptr_inst->value->type)) 28162 return ira->codegen->invalid_inst_gen; 28163 28164 // TODO let this be volatile 28165 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 28166 IrInstGen *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 28167 if (type_is_invalid(casted_ptr->value->type)) 28168 return ira->codegen->invalid_inst_gen; 28169 28170 AtomicRmwOp op; 28171 if (!ir_resolve_atomic_rmw_op(ira, instruction->op->child, &op)) { 28172 return ira->codegen->invalid_inst_gen; 28173 } 28174 28175 if (operand_type->id == ZigTypeIdEnum && op != AtomicRmwOp_xchg) { 28176 ir_add_error(ira, &instruction->op->base, 28177 buf_sprintf("@atomicRmw on enum only works with .Xchg")); 28178 return ira->codegen->invalid_inst_gen; 28179 } else if (operand_type->id == ZigTypeIdFloat && op > AtomicRmwOp_sub) { 28180 ir_add_error(ira, &instruction->op->base, 28181 buf_sprintf("@atomicRmw with float only works with .Xchg, .Add and .Sub")); 28182 return ira->codegen->invalid_inst_gen; 28183 } 28184 28185 IrInstGen *operand = instruction->operand->child; 28186 if (type_is_invalid(operand->value->type)) 28187 return ira->codegen->invalid_inst_gen; 28188 28189 IrInstGen *casted_operand = ir_implicit_cast(ira, operand, operand_type); 28190 if (type_is_invalid(casted_operand->value->type)) 28191 return ira->codegen->invalid_inst_gen; 28192 28193 AtomicOrder ordering; 28194 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 28195 return ira->codegen->invalid_inst_gen; 28196 if (ordering == AtomicOrderUnordered) { 28197 ir_add_error(ira, &instruction->ordering->base, 28198 buf_sprintf("@atomicRmw atomic ordering must not be Unordered")); 28199 return ira->codegen->invalid_inst_gen; 28200 } 28201 28202 if (instr_is_comptime(casted_operand) && instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar) 28203 { 28204 ir_add_error(ira, &instruction->base.base, 28205 buf_sprintf("compiler bug: TODO compile-time execution of @atomicRmw")); 28206 return ira->codegen->invalid_inst_gen; 28207 } 28208 28209 return ir_build_atomic_rmw_gen(ira, &instruction->base.base, casted_ptr, casted_operand, op, 28210 ordering, operand_type); 28211 } 28212 28213 static IrInstGen *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstSrcAtomicLoad *instruction) { 28214 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 28215 if (type_is_invalid(operand_type)) 28216 return ira->codegen->invalid_inst_gen; 28217 28218 IrInstGen *ptr_inst = instruction->ptr->child; 28219 if (type_is_invalid(ptr_inst->value->type)) 28220 return ira->codegen->invalid_inst_gen; 28221 28222 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, true); 28223 IrInstGen *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 28224 if (type_is_invalid(casted_ptr->value->type)) 28225 return ira->codegen->invalid_inst_gen; 28226 28227 AtomicOrder ordering; 28228 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 28229 return ira->codegen->invalid_inst_gen; 28230 28231 if (ordering == AtomicOrderRelease || ordering == AtomicOrderAcqRel) { 28232 ir_assert(instruction->ordering != nullptr, &instruction->base.base); 28233 ir_add_error(ira, &instruction->ordering->base, 28234 buf_sprintf("@atomicLoad atomic ordering must not be Release or AcqRel")); 28235 return ira->codegen->invalid_inst_gen; 28236 } 28237 28238 if (instr_is_comptime(casted_ptr)) { 28239 IrInstGen *result = ir_get_deref(ira, &instruction->base.base, casted_ptr, nullptr); 28240 ir_assert(result->value->type != nullptr, &instruction->base.base); 28241 return result; 28242 } 28243 28244 return ir_build_atomic_load_gen(ira, &instruction->base.base, casted_ptr, ordering, operand_type); 28245 } 28246 28247 static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcAtomicStore *instruction) { 28248 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 28249 if (type_is_invalid(operand_type)) 28250 return ira->codegen->invalid_inst_gen; 28251 28252 IrInstGen *ptr_inst = instruction->ptr->child; 28253 if (type_is_invalid(ptr_inst->value->type)) 28254 return ira->codegen->invalid_inst_gen; 28255 28256 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 28257 IrInstGen *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 28258 if (type_is_invalid(casted_ptr->value->type)) 28259 return ira->codegen->invalid_inst_gen; 28260 28261 IrInstGen *value = instruction->value->child; 28262 if (type_is_invalid(value->value->type)) 28263 return ira->codegen->invalid_inst_gen; 28264 28265 IrInstGen *casted_value = ir_implicit_cast(ira, value, operand_type); 28266 if (type_is_invalid(casted_value->value->type)) 28267 return ira->codegen->invalid_inst_gen; 28268 28269 28270 AtomicOrder ordering; 28271 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 28272 return ira->codegen->invalid_inst_gen; 28273 28274 if (ordering == AtomicOrderAcquire || ordering == AtomicOrderAcqRel) { 28275 ir_assert(instruction->ordering != nullptr, &instruction->base.base); 28276 ir_add_error(ira, &instruction->ordering->base, 28277 buf_sprintf("@atomicStore atomic ordering must not be Acquire or AcqRel")); 28278 return ira->codegen->invalid_inst_gen; 28279 } 28280 28281 if (instr_is_comptime(casted_value) && instr_is_comptime(casted_ptr)) { 28282 IrInstGen *result = ir_analyze_store_ptr(ira, &instruction->base.base, casted_ptr, value, false); 28283 result->value->type = ira->codegen->builtin_types.entry_void; 28284 return result; 28285 } 28286 28287 return ir_build_atomic_store_gen(ira, &instruction->base.base, casted_ptr, casted_value, ordering); 28288 } 28289 28290 static IrInstGen *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstSrcSaveErrRetAddr *instruction) { 28291 return ir_build_save_err_ret_addr_gen(ira, &instruction->base.base); 28292 } 28293 28294 static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinFnId fop, ZigType *float_type, 28295 ZigValue *op, ZigValue *out_val) 28296 { 28297 assert(ira && source_instr && float_type && out_val && op); 28298 assert(float_type->id == ZigTypeIdFloat || 28299 float_type->id == ZigTypeIdComptimeFloat); 28300 28301 unsigned bits; 28302 28303 switch (float_type->id) { 28304 case ZigTypeIdComptimeFloat: 28305 bits = 128; 28306 break; 28307 case ZigTypeIdFloat: 28308 bits = float_type->data.floating.bit_count; 28309 break; 28310 default: 28311 zig_unreachable(); 28312 } 28313 28314 switch (bits) { 28315 case 16: { 28316 switch (fop) { 28317 case BuiltinFnIdSqrt: 28318 out_val->data.x_f16 = f16_sqrt(op->data.x_f16); 28319 break; 28320 case BuiltinFnIdSin: 28321 out_val->data.x_f16 = zig_double_to_f16(sin(zig_f16_to_double(op->data.x_f16))); 28322 break; 28323 case BuiltinFnIdCos: 28324 out_val->data.x_f16 = zig_double_to_f16(cos(zig_f16_to_double(op->data.x_f16))); 28325 break; 28326 case BuiltinFnIdExp: 28327 out_val->data.x_f16 = zig_double_to_f16(exp(zig_f16_to_double(op->data.x_f16))); 28328 break; 28329 case BuiltinFnIdExp2: 28330 out_val->data.x_f16 = zig_double_to_f16(exp2(zig_f16_to_double(op->data.x_f16))); 28331 break; 28332 case BuiltinFnIdLog: 28333 out_val->data.x_f16 = zig_double_to_f16(log(zig_f16_to_double(op->data.x_f16))); 28334 break; 28335 case BuiltinFnIdLog10: 28336 out_val->data.x_f16 = zig_double_to_f16(log10(zig_f16_to_double(op->data.x_f16))); 28337 break; 28338 case BuiltinFnIdLog2: 28339 out_val->data.x_f16 = zig_double_to_f16(log2(zig_f16_to_double(op->data.x_f16))); 28340 break; 28341 case BuiltinFnIdFabs: 28342 out_val->data.x_f16 = zig_double_to_f16(fabs(zig_f16_to_double(op->data.x_f16))); 28343 break; 28344 case BuiltinFnIdFloor: 28345 out_val->data.x_f16 = zig_double_to_f16(floor(zig_f16_to_double(op->data.x_f16))); 28346 break; 28347 case BuiltinFnIdCeil: 28348 out_val->data.x_f16 = zig_double_to_f16(ceil(zig_f16_to_double(op->data.x_f16))); 28349 break; 28350 case BuiltinFnIdTrunc: 28351 out_val->data.x_f16 = zig_double_to_f16(trunc(zig_f16_to_double(op->data.x_f16))); 28352 break; 28353 case BuiltinFnIdNearbyInt: 28354 out_val->data.x_f16 = zig_double_to_f16(nearbyint(zig_f16_to_double(op->data.x_f16))); 28355 break; 28356 case BuiltinFnIdRound: 28357 out_val->data.x_f16 = zig_double_to_f16(round(zig_f16_to_double(op->data.x_f16))); 28358 break; 28359 default: 28360 zig_unreachable(); 28361 }; 28362 break; 28363 } 28364 case 32: { 28365 switch (fop) { 28366 case BuiltinFnIdSqrt: 28367 out_val->data.x_f32 = sqrtf(op->data.x_f32); 28368 break; 28369 case BuiltinFnIdSin: 28370 out_val->data.x_f32 = sinf(op->data.x_f32); 28371 break; 28372 case BuiltinFnIdCos: 28373 out_val->data.x_f32 = cosf(op->data.x_f32); 28374 break; 28375 case BuiltinFnIdExp: 28376 out_val->data.x_f32 = expf(op->data.x_f32); 28377 break; 28378 case BuiltinFnIdExp2: 28379 out_val->data.x_f32 = exp2f(op->data.x_f32); 28380 break; 28381 case BuiltinFnIdLog: 28382 out_val->data.x_f32 = logf(op->data.x_f32); 28383 break; 28384 case BuiltinFnIdLog10: 28385 out_val->data.x_f32 = log10f(op->data.x_f32); 28386 break; 28387 case BuiltinFnIdLog2: 28388 out_val->data.x_f32 = log2f(op->data.x_f32); 28389 break; 28390 case BuiltinFnIdFabs: 28391 out_val->data.x_f32 = fabsf(op->data.x_f32); 28392 break; 28393 case BuiltinFnIdFloor: 28394 out_val->data.x_f32 = floorf(op->data.x_f32); 28395 break; 28396 case BuiltinFnIdCeil: 28397 out_val->data.x_f32 = ceilf(op->data.x_f32); 28398 break; 28399 case BuiltinFnIdTrunc: 28400 out_val->data.x_f32 = truncf(op->data.x_f32); 28401 break; 28402 case BuiltinFnIdNearbyInt: 28403 out_val->data.x_f32 = nearbyintf(op->data.x_f32); 28404 break; 28405 case BuiltinFnIdRound: 28406 out_val->data.x_f32 = roundf(op->data.x_f32); 28407 break; 28408 default: 28409 zig_unreachable(); 28410 }; 28411 break; 28412 } 28413 case 64: { 28414 switch (fop) { 28415 case BuiltinFnIdSqrt: 28416 out_val->data.x_f64 = sqrt(op->data.x_f64); 28417 break; 28418 case BuiltinFnIdSin: 28419 out_val->data.x_f64 = sin(op->data.x_f64); 28420 break; 28421 case BuiltinFnIdCos: 28422 out_val->data.x_f64 = cos(op->data.x_f64); 28423 break; 28424 case BuiltinFnIdExp: 28425 out_val->data.x_f64 = exp(op->data.x_f64); 28426 break; 28427 case BuiltinFnIdExp2: 28428 out_val->data.x_f64 = exp2(op->data.x_f64); 28429 break; 28430 case BuiltinFnIdLog: 28431 out_val->data.x_f64 = log(op->data.x_f64); 28432 break; 28433 case BuiltinFnIdLog10: 28434 out_val->data.x_f64 = log10(op->data.x_f64); 28435 break; 28436 case BuiltinFnIdLog2: 28437 out_val->data.x_f64 = log2(op->data.x_f64); 28438 break; 28439 case BuiltinFnIdFabs: 28440 out_val->data.x_f64 = fabs(op->data.x_f64); 28441 break; 28442 case BuiltinFnIdFloor: 28443 out_val->data.x_f64 = floor(op->data.x_f64); 28444 break; 28445 case BuiltinFnIdCeil: 28446 out_val->data.x_f64 = ceil(op->data.x_f64); 28447 break; 28448 case BuiltinFnIdTrunc: 28449 out_val->data.x_f64 = trunc(op->data.x_f64); 28450 break; 28451 case BuiltinFnIdNearbyInt: 28452 out_val->data.x_f64 = nearbyint(op->data.x_f64); 28453 break; 28454 case BuiltinFnIdRound: 28455 out_val->data.x_f64 = round(op->data.x_f64); 28456 break; 28457 default: 28458 zig_unreachable(); 28459 } 28460 break; 28461 } 28462 case 80: 28463 return ir_add_error(ira, source_instr, 28464 buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026", 28465 float_op_to_name(fop), buf_ptr(&float_type->name))); 28466 case 128: { 28467 float128_t *out, *in; 28468 if (float_type->id == ZigTypeIdComptimeFloat) { 28469 out = &out_val->data.x_bigfloat.value; 28470 in = &op->data.x_bigfloat.value; 28471 } else { 28472 out = &out_val->data.x_f128; 28473 in = &op->data.x_f128; 28474 } 28475 switch (fop) { 28476 case BuiltinFnIdSqrt: 28477 f128M_sqrt(in, out); 28478 break; 28479 case BuiltinFnIdNearbyInt: 28480 case BuiltinFnIdSin: 28481 case BuiltinFnIdCos: 28482 case BuiltinFnIdExp: 28483 case BuiltinFnIdExp2: 28484 case BuiltinFnIdLog: 28485 case BuiltinFnIdLog10: 28486 case BuiltinFnIdLog2: 28487 case BuiltinFnIdFabs: 28488 case BuiltinFnIdFloor: 28489 case BuiltinFnIdCeil: 28490 case BuiltinFnIdTrunc: 28491 case BuiltinFnIdRound: 28492 return ir_add_error(ira, source_instr, 28493 buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026", 28494 float_op_to_name(fop), buf_ptr(&float_type->name))); 28495 default: 28496 zig_unreachable(); 28497 } 28498 break; 28499 } 28500 default: 28501 zig_unreachable(); 28502 } 28503 out_val->special = ConstValSpecialStatic; 28504 return nullptr; 28505 } 28506 28507 static IrInstGen *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstSrcFloatOp *instruction) { 28508 IrInstGen *operand = instruction->operand->child; 28509 ZigType *operand_type = operand->value->type; 28510 if (type_is_invalid(operand_type)) 28511 return ira->codegen->invalid_inst_gen; 28512 28513 // This instruction accepts floats and vectors of floats. 28514 ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ? 28515 operand_type->data.vector.elem_type : operand_type; 28516 28517 if (scalar_type->id != ZigTypeIdFloat && scalar_type->id != ZigTypeIdComptimeFloat) { 28518 ir_add_error(ira, &operand->base, 28519 buf_sprintf("expected float type, found '%s'", buf_ptr(&scalar_type->name))); 28520 return ira->codegen->invalid_inst_gen; 28521 } 28522 28523 if (instr_is_comptime(operand)) { 28524 ZigValue *operand_val = ir_resolve_const(ira, operand, UndefOk); 28525 if (operand_val == nullptr) 28526 return ira->codegen->invalid_inst_gen; 28527 if (operand_val->special == ConstValSpecialUndef) 28528 return ir_const_undef(ira, &instruction->base.base, operand_type); 28529 28530 IrInstGen *result = ir_const(ira, &instruction->base.base, operand_type); 28531 ZigValue *out_val = result->value; 28532 28533 if (operand_type->id == ZigTypeIdVector) { 28534 expand_undef_array(ira->codegen, operand_val); 28535 out_val->special = ConstValSpecialUndef; 28536 expand_undef_array(ira->codegen, out_val); 28537 size_t len = operand_type->data.vector.len; 28538 for (size_t i = 0; i < len; i += 1) { 28539 ZigValue *elem_operand = &operand_val->data.x_array.data.s_none.elements[i]; 28540 ZigValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; 28541 ir_assert(elem_operand->type == scalar_type, &instruction->base.base); 28542 ir_assert(float_out_val->type == scalar_type, &instruction->base.base); 28543 ErrorMsg *msg = ir_eval_float_op(ira, &instruction->base.base, instruction->fn_id, scalar_type, 28544 elem_operand, float_out_val); 28545 if (msg != nullptr) { 28546 add_error_note(ira->codegen, msg, instruction->base.base.source_node, 28547 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 28548 return ira->codegen->invalid_inst_gen; 28549 } 28550 float_out_val->type = scalar_type; 28551 } 28552 out_val->type = operand_type; 28553 out_val->special = ConstValSpecialStatic; 28554 } else { 28555 if (ir_eval_float_op(ira, &instruction->base.base, instruction->fn_id, scalar_type, 28556 operand_val, out_val) != nullptr) 28557 { 28558 return ira->codegen->invalid_inst_gen; 28559 } 28560 } 28561 return result; 28562 } 28563 28564 ir_assert(scalar_type->id == ZigTypeIdFloat, &instruction->base.base); 28565 28566 return ir_build_float_op_gen(ira, &instruction->base.base, operand, instruction->fn_id, operand_type); 28567 } 28568 28569 static IrInstGen *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstSrcBswap *instruction) { 28570 Error err; 28571 28572 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 28573 if (type_is_invalid(int_type)) 28574 return ira->codegen->invalid_inst_gen; 28575 28576 IrInstGen *uncasted_op = instruction->op->child; 28577 if (type_is_invalid(uncasted_op->value->type)) 28578 return ira->codegen->invalid_inst_gen; 28579 28580 uint32_t vector_len; // UINT32_MAX means not a vector 28581 if (uncasted_op->value->type->id == ZigTypeIdArray && 28582 is_valid_vector_elem_type(uncasted_op->value->type->data.array.child_type)) 28583 { 28584 vector_len = uncasted_op->value->type->data.array.len; 28585 } else if (uncasted_op->value->type->id == ZigTypeIdVector) { 28586 vector_len = uncasted_op->value->type->data.vector.len; 28587 } else { 28588 vector_len = UINT32_MAX; 28589 } 28590 28591 bool is_vector = (vector_len != UINT32_MAX); 28592 ZigType *op_type = is_vector ? get_vector_type(ira->codegen, vector_len, int_type) : int_type; 28593 28594 IrInstGen *op = ir_implicit_cast(ira, uncasted_op, op_type); 28595 if (type_is_invalid(op->value->type)) 28596 return ira->codegen->invalid_inst_gen; 28597 28598 if (int_type->data.integral.bit_count == 8 || int_type->data.integral.bit_count == 0) 28599 return op; 28600 28601 if (int_type->data.integral.bit_count % 8 != 0) { 28602 ir_add_error(ira, &instruction->op->base, 28603 buf_sprintf("@byteSwap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8", 28604 buf_ptr(&int_type->name), int_type->data.integral.bit_count)); 28605 return ira->codegen->invalid_inst_gen; 28606 } 28607 28608 if (instr_is_comptime(op)) { 28609 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 28610 if (val == nullptr) 28611 return ira->codegen->invalid_inst_gen; 28612 if (val->special == ConstValSpecialUndef) 28613 return ir_const_undef(ira, &instruction->base.base, op_type); 28614 28615 IrInstGen *result = ir_const(ira, &instruction->base.base, op_type); 28616 const size_t buf_size = int_type->data.integral.bit_count / 8; 28617 uint8_t *buf = heap::c_allocator.allocate_nonzero<uint8_t>(buf_size); 28618 if (is_vector) { 28619 expand_undef_array(ira->codegen, val); 28620 result->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(op_type->data.vector.len); 28621 for (unsigned i = 0; i < op_type->data.vector.len; i += 1) { 28622 ZigValue *op_elem_val = &val->data.x_array.data.s_none.elements[i]; 28623 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, instruction->base.base.source_node, 28624 op_elem_val, UndefOk))) 28625 { 28626 return ira->codegen->invalid_inst_gen; 28627 } 28628 ZigValue *result_elem_val = &result->value->data.x_array.data.s_none.elements[i]; 28629 result_elem_val->type = int_type; 28630 result_elem_val->special = op_elem_val->special; 28631 if (op_elem_val->special == ConstValSpecialUndef) 28632 continue; 28633 28634 bigint_write_twos_complement(&op_elem_val->data.x_bigint, buf, int_type->data.integral.bit_count, true); 28635 bigint_read_twos_complement(&result->value->data.x_array.data.s_none.elements[i].data.x_bigint, 28636 buf, int_type->data.integral.bit_count, false, 28637 int_type->data.integral.is_signed); 28638 } 28639 } else { 28640 bigint_write_twos_complement(&val->data.x_bigint, buf, int_type->data.integral.bit_count, true); 28641 bigint_read_twos_complement(&result->value->data.x_bigint, buf, int_type->data.integral.bit_count, false, 28642 int_type->data.integral.is_signed); 28643 } 28644 heap::c_allocator.deallocate(buf, buf_size); 28645 return result; 28646 } 28647 28648 return ir_build_bswap_gen(ira, &instruction->base.base, op_type, op); 28649 } 28650 28651 static IrInstGen *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstSrcBitReverse *instruction) { 28652 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 28653 if (type_is_invalid(int_type)) 28654 return ira->codegen->invalid_inst_gen; 28655 28656 IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); 28657 if (type_is_invalid(op->value->type)) 28658 return ira->codegen->invalid_inst_gen; 28659 28660 if (int_type->data.integral.bit_count == 0) { 28661 IrInstGen *result = ir_const(ira, &instruction->base.base, int_type); 28662 bigint_init_unsigned(&result->value->data.x_bigint, 0); 28663 return result; 28664 } 28665 28666 if (instr_is_comptime(op)) { 28667 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 28668 if (val == nullptr) 28669 return ira->codegen->invalid_inst_gen; 28670 if (val->special == ConstValSpecialUndef) 28671 return ir_const_undef(ira, &instruction->base.base, int_type); 28672 28673 IrInstGen *result = ir_const(ira, &instruction->base.base, int_type); 28674 size_t num_bits = int_type->data.integral.bit_count; 28675 size_t buf_size = (num_bits + 7) / 8; 28676 uint8_t *comptime_buf = heap::c_allocator.allocate_nonzero<uint8_t>(buf_size); 28677 uint8_t *result_buf = heap::c_allocator.allocate_nonzero<uint8_t>(buf_size); 28678 memset(comptime_buf,0,buf_size); 28679 memset(result_buf,0,buf_size); 28680 28681 bigint_write_twos_complement(&val->data.x_bigint,comptime_buf,num_bits,ira->codegen->is_big_endian); 28682 28683 size_t bit_i = 0; 28684 size_t bit_rev_i = num_bits - 1; 28685 for (; bit_i < num_bits; bit_i++, bit_rev_i--) { 28686 if (comptime_buf[bit_i / 8] & (1 << (bit_i % 8))) { 28687 result_buf[bit_rev_i / 8] |= (1 << (bit_rev_i % 8)); 28688 } 28689 } 28690 28691 bigint_read_twos_complement(&result->value->data.x_bigint, 28692 result_buf, 28693 int_type->data.integral.bit_count, 28694 ira->codegen->is_big_endian, 28695 int_type->data.integral.is_signed); 28696 28697 return result; 28698 } 28699 28700 return ir_build_bit_reverse_gen(ira, &instruction->base.base, int_type, op); 28701 } 28702 28703 28704 static IrInstGen *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstSrcEnumToInt *instruction) { 28705 IrInstGen *target = instruction->target->child; 28706 if (type_is_invalid(target->value->type)) 28707 return ira->codegen->invalid_inst_gen; 28708 28709 return ir_analyze_enum_to_int(ira, &instruction->base.base, target); 28710 } 28711 28712 static IrInstGen *ir_analyze_instruction_int_to_enum(IrAnalyze *ira, IrInstSrcIntToEnum *instruction) { 28713 Error err; 28714 IrInstGen *dest_type_value = instruction->dest_type->child; 28715 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 28716 if (type_is_invalid(dest_type)) 28717 return ira->codegen->invalid_inst_gen; 28718 28719 if (dest_type->id != ZigTypeIdEnum) { 28720 ir_add_error(ira, &instruction->dest_type->base, 28721 buf_sprintf("expected enum, found type '%s'", buf_ptr(&dest_type->name))); 28722 return ira->codegen->invalid_inst_gen; 28723 } 28724 28725 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 28726 return ira->codegen->invalid_inst_gen; 28727 28728 ZigType *tag_type = dest_type->data.enumeration.tag_int_type; 28729 28730 IrInstGen *target = instruction->target->child; 28731 if (type_is_invalid(target->value->type)) 28732 return ira->codegen->invalid_inst_gen; 28733 28734 IrInstGen *casted_target = ir_implicit_cast(ira, target, tag_type); 28735 if (type_is_invalid(casted_target->value->type)) 28736 return ira->codegen->invalid_inst_gen; 28737 28738 return ir_analyze_int_to_enum(ira, &instruction->base.base, casted_target, dest_type); 28739 } 28740 28741 static IrInstGen *ir_analyze_instruction_check_runtime_scope(IrAnalyze *ira, IrInstSrcCheckRuntimeScope *instruction) { 28742 IrInstGen *block_comptime_inst = instruction->scope_is_comptime->child; 28743 bool scope_is_comptime; 28744 if (!ir_resolve_bool(ira, block_comptime_inst, &scope_is_comptime)) 28745 return ira->codegen->invalid_inst_gen; 28746 28747 IrInstGen *is_comptime_inst = instruction->is_comptime->child; 28748 bool is_comptime; 28749 if (!ir_resolve_bool(ira, is_comptime_inst, &is_comptime)) 28750 return ira->codegen->invalid_inst_gen; 28751 28752 if (!scope_is_comptime && is_comptime) { 28753 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 28754 buf_sprintf("comptime control flow inside runtime block")); 28755 add_error_note(ira->codegen, msg, block_comptime_inst->base.source_node, 28756 buf_sprintf("runtime block created here")); 28757 return ira->codegen->invalid_inst_gen; 28758 } 28759 28760 return ir_const_void(ira, &instruction->base.base); 28761 } 28762 28763 static IrInstGen *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstSrcHasDecl *instruction) { 28764 ZigType *container_type = ir_resolve_type(ira, instruction->container->child); 28765 if (type_is_invalid(container_type)) 28766 return ira->codegen->invalid_inst_gen; 28767 28768 Buf *name = ir_resolve_str(ira, instruction->name->child); 28769 if (name == nullptr) 28770 return ira->codegen->invalid_inst_gen; 28771 28772 if (!is_container(container_type)) { 28773 ir_add_error(ira, &instruction->container->base, 28774 buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&container_type->name))); 28775 return ira->codegen->invalid_inst_gen; 28776 } 28777 28778 ScopeDecls *container_scope = get_container_scope(container_type); 28779 Tld *tld = find_container_decl(ira->codegen, container_scope, name); 28780 if (tld == nullptr) 28781 return ir_const_bool(ira, &instruction->base.base, false); 28782 28783 if (tld->visib_mod == VisibModPrivate && tld->import != get_scope_import(instruction->base.base.scope)) { 28784 return ir_const_bool(ira, &instruction->base.base, false); 28785 } 28786 28787 return ir_const_bool(ira, &instruction->base.base, true); 28788 } 28789 28790 static IrInstGen *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, IrInstSrcUndeclaredIdent *instruction) { 28791 // put a variable of same name with invalid type in global scope 28792 // so that future references to this same name will find a variable with an invalid type 28793 populate_invalid_variable_in_scope(ira->codegen, instruction->base.base.scope, 28794 instruction->base.base.source_node, instruction->name); 28795 ir_add_error(ira, &instruction->base.base, 28796 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(instruction->name))); 28797 return ira->codegen->invalid_inst_gen; 28798 } 28799 28800 static IrInstGen *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstSrcEndExpr *instruction) { 28801 IrInstGen *value = instruction->value->child; 28802 if (type_is_invalid(value->value->type)) 28803 return ira->codegen->invalid_inst_gen; 28804 28805 bool was_written = instruction->result_loc->written; 28806 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 28807 value->value->type, value, false, true); 28808 if (result_loc != nullptr) { 28809 if (type_is_invalid(result_loc->value->type)) 28810 return ira->codegen->invalid_inst_gen; 28811 if (result_loc->value->type->id == ZigTypeIdUnreachable) 28812 return result_loc; 28813 28814 if (!was_written || instruction->result_loc->id == ResultLocIdPeer) { 28815 IrInstGen *store_ptr = ir_analyze_store_ptr(ira, &instruction->base.base, result_loc, value, 28816 instruction->result_loc->allow_write_through_const); 28817 if (type_is_invalid(store_ptr->value->type)) { 28818 return ira->codegen->invalid_inst_gen; 28819 } 28820 } 28821 28822 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer && 28823 instruction->result_loc->id != ResultLocIdPeer) 28824 { 28825 if (instr_is_comptime(value)) { 28826 result_loc->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 28827 } else { 28828 result_loc->value->special = ConstValSpecialRuntime; 28829 } 28830 } 28831 } 28832 28833 return ir_const_void(ira, &instruction->base.base); 28834 } 28835 28836 static IrInstGen *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstSrcImplicitCast *instruction) { 28837 IrInstGen *operand = instruction->operand->child; 28838 if (type_is_invalid(operand->value->type)) 28839 return operand; 28840 28841 ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child); 28842 if (type_is_invalid(dest_type)) 28843 return ira->codegen->invalid_inst_gen; 28844 return ir_implicit_cast2(ira, &instruction->base.base, operand, dest_type); 28845 } 28846 28847 static IrInstGen *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstSrcBitCast *instruction) { 28848 IrInstGen *operand = instruction->operand->child; 28849 if (type_is_invalid(operand->value->type)) 28850 return operand; 28851 28852 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, 28853 &instruction->result_loc_bit_cast->base, operand->value->type, operand, false, true); 28854 if (result_loc != nullptr && 28855 (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) 28856 { 28857 return result_loc; 28858 } 28859 28860 ZigType *dest_type = ir_resolve_type(ira, 28861 instruction->result_loc_bit_cast->base.source_instruction->child); 28862 if (type_is_invalid(dest_type)) 28863 return ira->codegen->invalid_inst_gen; 28864 return ir_analyze_bit_cast(ira, &instruction->base.base, operand, dest_type); 28865 } 28866 28867 static IrInstGen *ir_analyze_instruction_union_init_named_field(IrAnalyze *ira, 28868 IrInstSrcUnionInitNamedField *instruction) 28869 { 28870 ZigType *union_type = ir_resolve_type(ira, instruction->union_type->child); 28871 if (type_is_invalid(union_type)) 28872 return ira->codegen->invalid_inst_gen; 28873 28874 if (union_type->id != ZigTypeIdUnion) { 28875 ir_add_error(ira, &instruction->union_type->base, 28876 buf_sprintf("non-union type '%s' passed to @unionInit", buf_ptr(&union_type->name))); 28877 return ira->codegen->invalid_inst_gen; 28878 } 28879 28880 Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); 28881 if (field_name == nullptr) 28882 return ira->codegen->invalid_inst_gen; 28883 28884 IrInstGen *field_result_loc = instruction->field_result_loc->child; 28885 if (type_is_invalid(field_result_loc->value->type)) 28886 return ira->codegen->invalid_inst_gen; 28887 28888 IrInstGen *result_loc = instruction->result_loc->child; 28889 if (type_is_invalid(result_loc->value->type)) 28890 return ira->codegen->invalid_inst_gen; 28891 28892 return ir_analyze_union_init(ira, &instruction->base.base, instruction->base.base.source_node, 28893 union_type, field_name, field_result_loc, result_loc); 28894 } 28895 28896 static IrInstGen *ir_analyze_instruction_suspend_begin(IrAnalyze *ira, IrInstSrcSuspendBegin *instruction) { 28897 return ir_build_suspend_begin_gen(ira, &instruction->base.base); 28898 } 28899 28900 static IrInstGen *ir_analyze_instruction_suspend_finish(IrAnalyze *ira, IrInstSrcSuspendFinish *instruction) { 28901 IrInstGen *begin_base = instruction->begin->base.child; 28902 if (type_is_invalid(begin_base->value->type)) 28903 return ira->codegen->invalid_inst_gen; 28904 ir_assert(begin_base->id == IrInstGenIdSuspendBegin, &instruction->base.base); 28905 IrInstGenSuspendBegin *begin = reinterpret_cast<IrInstGenSuspendBegin *>(begin_base); 28906 28907 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 28908 ir_assert(fn_entry != nullptr, &instruction->base.base); 28909 28910 if (fn_entry->inferred_async_node == nullptr) { 28911 fn_entry->inferred_async_node = instruction->base.base.source_node; 28912 } 28913 28914 return ir_build_suspend_finish_gen(ira, &instruction->base.base, begin); 28915 } 28916 28917 static IrInstGen *analyze_frame_ptr_to_anyframe_T(IrAnalyze *ira, IrInst* source_instr, 28918 IrInstGen *frame_ptr, ZigFn **target_fn) 28919 { 28920 if (type_is_invalid(frame_ptr->value->type)) 28921 return ira->codegen->invalid_inst_gen; 28922 28923 *target_fn = nullptr; 28924 28925 ZigType *result_type; 28926 IrInstGen *frame; 28927 if (frame_ptr->value->type->id == ZigTypeIdPointer && 28928 frame_ptr->value->type->data.pointer.ptr_len == PtrLenSingle && 28929 frame_ptr->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 28930 { 28931 ZigFn *func = frame_ptr->value->type->data.pointer.child_type->data.frame.fn; 28932 result_type = func->type_entry->data.fn.fn_type_id.return_type; 28933 *target_fn = func; 28934 frame = frame_ptr; 28935 } else { 28936 frame = ir_get_deref(ira, source_instr, frame_ptr, nullptr); 28937 if (frame->value->type->id == ZigTypeIdPointer && 28938 frame->value->type->data.pointer.ptr_len == PtrLenSingle && 28939 frame->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 28940 { 28941 ZigFn *func = frame->value->type->data.pointer.child_type->data.frame.fn; 28942 result_type = func->type_entry->data.fn.fn_type_id.return_type; 28943 *target_fn = func; 28944 } else if (frame->value->type->id != ZigTypeIdAnyFrame || 28945 frame->value->type->data.any_frame.result_type == nullptr) 28946 { 28947 ir_add_error(ira, source_instr, 28948 buf_sprintf("expected anyframe->T, found '%s'", buf_ptr(&frame->value->type->name))); 28949 return ira->codegen->invalid_inst_gen; 28950 } else { 28951 result_type = frame->value->type->data.any_frame.result_type; 28952 } 28953 } 28954 28955 ZigType *any_frame_type = get_any_frame_type(ira->codegen, result_type); 28956 IrInstGen *casted_frame = ir_implicit_cast(ira, frame, any_frame_type); 28957 if (type_is_invalid(casted_frame->value->type)) 28958 return ira->codegen->invalid_inst_gen; 28959 28960 return casted_frame; 28961 } 28962 28963 static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *instruction) { 28964 IrInstGen *operand = instruction->frame->child; 28965 if (type_is_invalid(operand->value->type)) 28966 return ira->codegen->invalid_inst_gen; 28967 ZigFn *target_fn; 28968 IrInstGen *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base.base, operand, &target_fn); 28969 if (type_is_invalid(frame->value->type)) 28970 return ira->codegen->invalid_inst_gen; 28971 28972 ZigType *result_type = frame->value->type->data.any_frame.result_type; 28973 28974 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 28975 ir_assert(fn_entry != nullptr, &instruction->base.base); 28976 28977 // If it's not @Frame(func) then it's definitely a suspend point 28978 if (target_fn == nullptr && !instruction->is_noasync) { 28979 if (fn_entry->inferred_async_node == nullptr) { 28980 fn_entry->inferred_async_node = instruction->base.base.source_node; 28981 } 28982 } 28983 28984 if (type_can_fail(result_type)) { 28985 fn_entry->calls_or_awaits_errorable_fn = true; 28986 } 28987 28988 IrInstGen *result_loc; 28989 if (type_has_bits(result_type)) { 28990 result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 28991 result_type, nullptr, true, true); 28992 if (result_loc != nullptr && 28993 (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) 28994 { 28995 return result_loc; 28996 } 28997 } else { 28998 result_loc = nullptr; 28999 } 29000 29001 IrInstGenAwait *result = ir_build_await_gen(ira, &instruction->base.base, frame, result_type, result_loc, 29002 instruction->is_noasync); 29003 result->target_fn = target_fn; 29004 fn_entry->await_list.append(result); 29005 return ir_finish_anal(ira, &result->base); 29006 } 29007 29008 static IrInstGen *ir_analyze_instruction_resume(IrAnalyze *ira, IrInstSrcResume *instruction) { 29009 IrInstGen *frame_ptr = instruction->frame->child; 29010 if (type_is_invalid(frame_ptr->value->type)) 29011 return ira->codegen->invalid_inst_gen; 29012 29013 IrInstGen *frame; 29014 if (frame_ptr->value->type->id == ZigTypeIdPointer && 29015 frame_ptr->value->type->data.pointer.ptr_len == PtrLenSingle && 29016 frame_ptr->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 29017 { 29018 frame = frame_ptr; 29019 } else { 29020 frame = ir_get_deref(ira, &instruction->base.base, frame_ptr, nullptr); 29021 } 29022 29023 ZigType *any_frame_type = get_any_frame_type(ira->codegen, nullptr); 29024 IrInstGen *casted_frame = ir_implicit_cast2(ira, &instruction->frame->base, frame, any_frame_type); 29025 if (type_is_invalid(casted_frame->value->type)) 29026 return ira->codegen->invalid_inst_gen; 29027 29028 return ir_build_resume_gen(ira, &instruction->base.base, casted_frame); 29029 } 29030 29031 static IrInstGen *ir_analyze_instruction_spill_begin(IrAnalyze *ira, IrInstSrcSpillBegin *instruction) { 29032 if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope)) 29033 return ir_const_void(ira, &instruction->base.base); 29034 29035 IrInstGen *operand = instruction->operand->child; 29036 if (type_is_invalid(operand->value->type)) 29037 return ira->codegen->invalid_inst_gen; 29038 29039 if (!type_has_bits(operand->value->type)) 29040 return ir_const_void(ira, &instruction->base.base); 29041 29042 switch (instruction->spill_id) { 29043 case SpillIdInvalid: 29044 zig_unreachable(); 29045 case SpillIdRetErrCode: 29046 ira->new_irb.exec->need_err_code_spill = true; 29047 break; 29048 } 29049 29050 return ir_build_spill_begin_gen(ira, &instruction->base.base, operand, instruction->spill_id); 29051 } 29052 29053 static IrInstGen *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstSrcSpillEnd *instruction) { 29054 IrInstGen *operand = instruction->begin->operand->child; 29055 if (type_is_invalid(operand->value->type)) 29056 return ira->codegen->invalid_inst_gen; 29057 29058 if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope) || 29059 !type_has_bits(operand->value->type) || 29060 instr_is_comptime(operand)) 29061 { 29062 return operand; 29063 } 29064 29065 ir_assert(instruction->begin->base.child->id == IrInstGenIdSpillBegin, &instruction->base.base); 29066 IrInstGenSpillBegin *begin = reinterpret_cast<IrInstGenSpillBegin *>(instruction->begin->base.child); 29067 29068 return ir_build_spill_end_gen(ira, &instruction->base.base, begin, operand->value->type); 29069 } 29070 29071 static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruction) { 29072 switch (instruction->id) { 29073 case IrInstSrcIdInvalid: 29074 zig_unreachable(); 29075 29076 case IrInstSrcIdReturn: 29077 return ir_analyze_instruction_return(ira, (IrInstSrcReturn *)instruction); 29078 case IrInstSrcIdConst: 29079 return ir_analyze_instruction_const(ira, (IrInstSrcConst *)instruction); 29080 case IrInstSrcIdUnOp: 29081 return ir_analyze_instruction_un_op(ira, (IrInstSrcUnOp *)instruction); 29082 case IrInstSrcIdBinOp: 29083 return ir_analyze_instruction_bin_op(ira, (IrInstSrcBinOp *)instruction); 29084 case IrInstSrcIdMergeErrSets: 29085 return ir_analyze_instruction_merge_err_sets(ira, (IrInstSrcMergeErrSets *)instruction); 29086 case IrInstSrcIdDeclVar: 29087 return ir_analyze_instruction_decl_var(ira, (IrInstSrcDeclVar *)instruction); 29088 case IrInstSrcIdLoadPtr: 29089 return ir_analyze_instruction_load_ptr(ira, (IrInstSrcLoadPtr *)instruction); 29090 case IrInstSrcIdStorePtr: 29091 return ir_analyze_instruction_store_ptr(ira, (IrInstSrcStorePtr *)instruction); 29092 case IrInstSrcIdElemPtr: 29093 return ir_analyze_instruction_elem_ptr(ira, (IrInstSrcElemPtr *)instruction); 29094 case IrInstSrcIdVarPtr: 29095 return ir_analyze_instruction_var_ptr(ira, (IrInstSrcVarPtr *)instruction); 29096 case IrInstSrcIdFieldPtr: 29097 return ir_analyze_instruction_field_ptr(ira, (IrInstSrcFieldPtr *)instruction); 29098 case IrInstSrcIdCall: 29099 return ir_analyze_instruction_call(ira, (IrInstSrcCall *)instruction); 29100 case IrInstSrcIdCallArgs: 29101 return ir_analyze_instruction_call_args(ira, (IrInstSrcCallArgs *)instruction); 29102 case IrInstSrcIdCallExtra: 29103 return ir_analyze_instruction_call_extra(ira, (IrInstSrcCallExtra *)instruction); 29104 case IrInstSrcIdBr: 29105 return ir_analyze_instruction_br(ira, (IrInstSrcBr *)instruction); 29106 case IrInstSrcIdCondBr: 29107 return ir_analyze_instruction_cond_br(ira, (IrInstSrcCondBr *)instruction); 29108 case IrInstSrcIdUnreachable: 29109 return ir_analyze_instruction_unreachable(ira, (IrInstSrcUnreachable *)instruction); 29110 case IrInstSrcIdPhi: 29111 return ir_analyze_instruction_phi(ira, (IrInstSrcPhi *)instruction); 29112 case IrInstSrcIdTypeOf: 29113 return ir_analyze_instruction_typeof(ira, (IrInstSrcTypeOf *)instruction); 29114 case IrInstSrcIdSetCold: 29115 return ir_analyze_instruction_set_cold(ira, (IrInstSrcSetCold *)instruction); 29116 case IrInstSrcIdSetRuntimeSafety: 29117 return ir_analyze_instruction_set_runtime_safety(ira, (IrInstSrcSetRuntimeSafety *)instruction); 29118 case IrInstSrcIdSetFloatMode: 29119 return ir_analyze_instruction_set_float_mode(ira, (IrInstSrcSetFloatMode *)instruction); 29120 case IrInstSrcIdAnyFrameType: 29121 return ir_analyze_instruction_any_frame_type(ira, (IrInstSrcAnyFrameType *)instruction); 29122 case IrInstSrcIdSliceType: 29123 return ir_analyze_instruction_slice_type(ira, (IrInstSrcSliceType *)instruction); 29124 case IrInstSrcIdAsm: 29125 return ir_analyze_instruction_asm(ira, (IrInstSrcAsm *)instruction); 29126 case IrInstSrcIdArrayType: 29127 return ir_analyze_instruction_array_type(ira, (IrInstSrcArrayType *)instruction); 29128 case IrInstSrcIdSizeOf: 29129 return ir_analyze_instruction_size_of(ira, (IrInstSrcSizeOf *)instruction); 29130 case IrInstSrcIdTestNonNull: 29131 return ir_analyze_instruction_test_non_null(ira, (IrInstSrcTestNonNull *)instruction); 29132 case IrInstSrcIdOptionalUnwrapPtr: 29133 return ir_analyze_instruction_optional_unwrap_ptr(ira, (IrInstSrcOptionalUnwrapPtr *)instruction); 29134 case IrInstSrcIdClz: 29135 return ir_analyze_instruction_clz(ira, (IrInstSrcClz *)instruction); 29136 case IrInstSrcIdCtz: 29137 return ir_analyze_instruction_ctz(ira, (IrInstSrcCtz *)instruction); 29138 case IrInstSrcIdPopCount: 29139 return ir_analyze_instruction_pop_count(ira, (IrInstSrcPopCount *)instruction); 29140 case IrInstSrcIdBswap: 29141 return ir_analyze_instruction_bswap(ira, (IrInstSrcBswap *)instruction); 29142 case IrInstSrcIdBitReverse: 29143 return ir_analyze_instruction_bit_reverse(ira, (IrInstSrcBitReverse *)instruction); 29144 case IrInstSrcIdSwitchBr: 29145 return ir_analyze_instruction_switch_br(ira, (IrInstSrcSwitchBr *)instruction); 29146 case IrInstSrcIdSwitchTarget: 29147 return ir_analyze_instruction_switch_target(ira, (IrInstSrcSwitchTarget *)instruction); 29148 case IrInstSrcIdSwitchVar: 29149 return ir_analyze_instruction_switch_var(ira, (IrInstSrcSwitchVar *)instruction); 29150 case IrInstSrcIdSwitchElseVar: 29151 return ir_analyze_instruction_switch_else_var(ira, (IrInstSrcSwitchElseVar *)instruction); 29152 case IrInstSrcIdImport: 29153 return ir_analyze_instruction_import(ira, (IrInstSrcImport *)instruction); 29154 case IrInstSrcIdRef: 29155 return ir_analyze_instruction_ref(ira, (IrInstSrcRef *)instruction); 29156 case IrInstSrcIdContainerInitList: 29157 return ir_analyze_instruction_container_init_list(ira, (IrInstSrcContainerInitList *)instruction); 29158 case IrInstSrcIdContainerInitFields: 29159 return ir_analyze_instruction_container_init_fields(ira, (IrInstSrcContainerInitFields *)instruction); 29160 case IrInstSrcIdCompileErr: 29161 return ir_analyze_instruction_compile_err(ira, (IrInstSrcCompileErr *)instruction); 29162 case IrInstSrcIdCompileLog: 29163 return ir_analyze_instruction_compile_log(ira, (IrInstSrcCompileLog *)instruction); 29164 case IrInstSrcIdErrName: 29165 return ir_analyze_instruction_err_name(ira, (IrInstSrcErrName *)instruction); 29166 case IrInstSrcIdTypeName: 29167 return ir_analyze_instruction_type_name(ira, (IrInstSrcTypeName *)instruction); 29168 case IrInstSrcIdCImport: 29169 return ir_analyze_instruction_c_import(ira, (IrInstSrcCImport *)instruction); 29170 case IrInstSrcIdCInclude: 29171 return ir_analyze_instruction_c_include(ira, (IrInstSrcCInclude *)instruction); 29172 case IrInstSrcIdCDefine: 29173 return ir_analyze_instruction_c_define(ira, (IrInstSrcCDefine *)instruction); 29174 case IrInstSrcIdCUndef: 29175 return ir_analyze_instruction_c_undef(ira, (IrInstSrcCUndef *)instruction); 29176 case IrInstSrcIdEmbedFile: 29177 return ir_analyze_instruction_embed_file(ira, (IrInstSrcEmbedFile *)instruction); 29178 case IrInstSrcIdCmpxchg: 29179 return ir_analyze_instruction_cmpxchg(ira, (IrInstSrcCmpxchg *)instruction); 29180 case IrInstSrcIdFence: 29181 return ir_analyze_instruction_fence(ira, (IrInstSrcFence *)instruction); 29182 case IrInstSrcIdTruncate: 29183 return ir_analyze_instruction_truncate(ira, (IrInstSrcTruncate *)instruction); 29184 case IrInstSrcIdIntCast: 29185 return ir_analyze_instruction_int_cast(ira, (IrInstSrcIntCast *)instruction); 29186 case IrInstSrcIdFloatCast: 29187 return ir_analyze_instruction_float_cast(ira, (IrInstSrcFloatCast *)instruction); 29188 case IrInstSrcIdErrSetCast: 29189 return ir_analyze_instruction_err_set_cast(ira, (IrInstSrcErrSetCast *)instruction); 29190 case IrInstSrcIdIntToFloat: 29191 return ir_analyze_instruction_int_to_float(ira, (IrInstSrcIntToFloat *)instruction); 29192 case IrInstSrcIdFloatToInt: 29193 return ir_analyze_instruction_float_to_int(ira, (IrInstSrcFloatToInt *)instruction); 29194 case IrInstSrcIdBoolToInt: 29195 return ir_analyze_instruction_bool_to_int(ira, (IrInstSrcBoolToInt *)instruction); 29196 case IrInstSrcIdVectorType: 29197 return ir_analyze_instruction_vector_type(ira, (IrInstSrcVectorType *)instruction); 29198 case IrInstSrcIdShuffleVector: 29199 return ir_analyze_instruction_shuffle_vector(ira, (IrInstSrcShuffleVector *)instruction); 29200 case IrInstSrcIdSplat: 29201 return ir_analyze_instruction_splat(ira, (IrInstSrcSplat *)instruction); 29202 case IrInstSrcIdBoolNot: 29203 return ir_analyze_instruction_bool_not(ira, (IrInstSrcBoolNot *)instruction); 29204 case IrInstSrcIdMemset: 29205 return ir_analyze_instruction_memset(ira, (IrInstSrcMemset *)instruction); 29206 case IrInstSrcIdMemcpy: 29207 return ir_analyze_instruction_memcpy(ira, (IrInstSrcMemcpy *)instruction); 29208 case IrInstSrcIdSlice: 29209 return ir_analyze_instruction_slice(ira, (IrInstSrcSlice *)instruction); 29210 case IrInstSrcIdBreakpoint: 29211 return ir_analyze_instruction_breakpoint(ira, (IrInstSrcBreakpoint *)instruction); 29212 case IrInstSrcIdReturnAddress: 29213 return ir_analyze_instruction_return_address(ira, (IrInstSrcReturnAddress *)instruction); 29214 case IrInstSrcIdFrameAddress: 29215 return ir_analyze_instruction_frame_address(ira, (IrInstSrcFrameAddress *)instruction); 29216 case IrInstSrcIdFrameHandle: 29217 return ir_analyze_instruction_frame_handle(ira, (IrInstSrcFrameHandle *)instruction); 29218 case IrInstSrcIdFrameType: 29219 return ir_analyze_instruction_frame_type(ira, (IrInstSrcFrameType *)instruction); 29220 case IrInstSrcIdFrameSize: 29221 return ir_analyze_instruction_frame_size(ira, (IrInstSrcFrameSize *)instruction); 29222 case IrInstSrcIdAlignOf: 29223 return ir_analyze_instruction_align_of(ira, (IrInstSrcAlignOf *)instruction); 29224 case IrInstSrcIdOverflowOp: 29225 return ir_analyze_instruction_overflow_op(ira, (IrInstSrcOverflowOp *)instruction); 29226 case IrInstSrcIdTestErr: 29227 return ir_analyze_instruction_test_err(ira, (IrInstSrcTestErr *)instruction); 29228 case IrInstSrcIdUnwrapErrCode: 29229 return ir_analyze_instruction_unwrap_err_code(ira, (IrInstSrcUnwrapErrCode *)instruction); 29230 case IrInstSrcIdUnwrapErrPayload: 29231 return ir_analyze_instruction_unwrap_err_payload(ira, (IrInstSrcUnwrapErrPayload *)instruction); 29232 case IrInstSrcIdFnProto: 29233 return ir_analyze_instruction_fn_proto(ira, (IrInstSrcFnProto *)instruction); 29234 case IrInstSrcIdTestComptime: 29235 return ir_analyze_instruction_test_comptime(ira, (IrInstSrcTestComptime *)instruction); 29236 case IrInstSrcIdCheckSwitchProngs: 29237 return ir_analyze_instruction_check_switch_prongs(ira, (IrInstSrcCheckSwitchProngs *)instruction); 29238 case IrInstSrcIdCheckStatementIsVoid: 29239 return ir_analyze_instruction_check_statement_is_void(ira, (IrInstSrcCheckStatementIsVoid *)instruction); 29240 case IrInstSrcIdDeclRef: 29241 return ir_analyze_instruction_decl_ref(ira, (IrInstSrcDeclRef *)instruction); 29242 case IrInstSrcIdPanic: 29243 return ir_analyze_instruction_panic(ira, (IrInstSrcPanic *)instruction); 29244 case IrInstSrcIdPtrCast: 29245 return ir_analyze_instruction_ptr_cast(ira, (IrInstSrcPtrCast *)instruction); 29246 case IrInstSrcIdIntToPtr: 29247 return ir_analyze_instruction_int_to_ptr(ira, (IrInstSrcIntToPtr *)instruction); 29248 case IrInstSrcIdPtrToInt: 29249 return ir_analyze_instruction_ptr_to_int(ira, (IrInstSrcPtrToInt *)instruction); 29250 case IrInstSrcIdTagName: 29251 return ir_analyze_instruction_enum_tag_name(ira, (IrInstSrcTagName *)instruction); 29252 case IrInstSrcIdFieldParentPtr: 29253 return ir_analyze_instruction_field_parent_ptr(ira, (IrInstSrcFieldParentPtr *)instruction); 29254 case IrInstSrcIdByteOffsetOf: 29255 return ir_analyze_instruction_byte_offset_of(ira, (IrInstSrcByteOffsetOf *)instruction); 29256 case IrInstSrcIdBitOffsetOf: 29257 return ir_analyze_instruction_bit_offset_of(ira, (IrInstSrcBitOffsetOf *)instruction); 29258 case IrInstSrcIdTypeInfo: 29259 return ir_analyze_instruction_type_info(ira, (IrInstSrcTypeInfo *) instruction); 29260 case IrInstSrcIdType: 29261 return ir_analyze_instruction_type(ira, (IrInstSrcType *)instruction); 29262 case IrInstSrcIdHasField: 29263 return ir_analyze_instruction_has_field(ira, (IrInstSrcHasField *) instruction); 29264 case IrInstSrcIdSetEvalBranchQuota: 29265 return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstSrcSetEvalBranchQuota *)instruction); 29266 case IrInstSrcIdPtrType: 29267 return ir_analyze_instruction_ptr_type(ira, (IrInstSrcPtrType *)instruction); 29268 case IrInstSrcIdAlignCast: 29269 return ir_analyze_instruction_align_cast(ira, (IrInstSrcAlignCast *)instruction); 29270 case IrInstSrcIdImplicitCast: 29271 return ir_analyze_instruction_implicit_cast(ira, (IrInstSrcImplicitCast *)instruction); 29272 case IrInstSrcIdResolveResult: 29273 return ir_analyze_instruction_resolve_result(ira, (IrInstSrcResolveResult *)instruction); 29274 case IrInstSrcIdResetResult: 29275 return ir_analyze_instruction_reset_result(ira, (IrInstSrcResetResult *)instruction); 29276 case IrInstSrcIdOpaqueType: 29277 return ir_analyze_instruction_opaque_type(ira, (IrInstSrcOpaqueType *)instruction); 29278 case IrInstSrcIdSetAlignStack: 29279 return ir_analyze_instruction_set_align_stack(ira, (IrInstSrcSetAlignStack *)instruction); 29280 case IrInstSrcIdArgType: 29281 return ir_analyze_instruction_arg_type(ira, (IrInstSrcArgType *)instruction); 29282 case IrInstSrcIdTagType: 29283 return ir_analyze_instruction_tag_type(ira, (IrInstSrcTagType *)instruction); 29284 case IrInstSrcIdExport: 29285 return ir_analyze_instruction_export(ira, (IrInstSrcExport *)instruction); 29286 case IrInstSrcIdErrorReturnTrace: 29287 return ir_analyze_instruction_error_return_trace(ira, (IrInstSrcErrorReturnTrace *)instruction); 29288 case IrInstSrcIdErrorUnion: 29289 return ir_analyze_instruction_error_union(ira, (IrInstSrcErrorUnion *)instruction); 29290 case IrInstSrcIdAtomicRmw: 29291 return ir_analyze_instruction_atomic_rmw(ira, (IrInstSrcAtomicRmw *)instruction); 29292 case IrInstSrcIdAtomicLoad: 29293 return ir_analyze_instruction_atomic_load(ira, (IrInstSrcAtomicLoad *)instruction); 29294 case IrInstSrcIdAtomicStore: 29295 return ir_analyze_instruction_atomic_store(ira, (IrInstSrcAtomicStore *)instruction); 29296 case IrInstSrcIdSaveErrRetAddr: 29297 return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstSrcSaveErrRetAddr *)instruction); 29298 case IrInstSrcIdAddImplicitReturnType: 29299 return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstSrcAddImplicitReturnType *)instruction); 29300 case IrInstSrcIdFloatOp: 29301 return ir_analyze_instruction_float_op(ira, (IrInstSrcFloatOp *)instruction); 29302 case IrInstSrcIdMulAdd: 29303 return ir_analyze_instruction_mul_add(ira, (IrInstSrcMulAdd *)instruction); 29304 case IrInstSrcIdIntToErr: 29305 return ir_analyze_instruction_int_to_err(ira, (IrInstSrcIntToErr *)instruction); 29306 case IrInstSrcIdErrToInt: 29307 return ir_analyze_instruction_err_to_int(ira, (IrInstSrcErrToInt *)instruction); 29308 case IrInstSrcIdIntToEnum: 29309 return ir_analyze_instruction_int_to_enum(ira, (IrInstSrcIntToEnum *)instruction); 29310 case IrInstSrcIdEnumToInt: 29311 return ir_analyze_instruction_enum_to_int(ira, (IrInstSrcEnumToInt *)instruction); 29312 case IrInstSrcIdCheckRuntimeScope: 29313 return ir_analyze_instruction_check_runtime_scope(ira, (IrInstSrcCheckRuntimeScope *)instruction); 29314 case IrInstSrcIdHasDecl: 29315 return ir_analyze_instruction_has_decl(ira, (IrInstSrcHasDecl *)instruction); 29316 case IrInstSrcIdUndeclaredIdent: 29317 return ir_analyze_instruction_undeclared_ident(ira, (IrInstSrcUndeclaredIdent *)instruction); 29318 case IrInstSrcIdAlloca: 29319 return nullptr; 29320 case IrInstSrcIdEndExpr: 29321 return ir_analyze_instruction_end_expr(ira, (IrInstSrcEndExpr *)instruction); 29322 case IrInstSrcIdBitCast: 29323 return ir_analyze_instruction_bit_cast_src(ira, (IrInstSrcBitCast *)instruction); 29324 case IrInstSrcIdUnionInitNamedField: 29325 return ir_analyze_instruction_union_init_named_field(ira, (IrInstSrcUnionInitNamedField *)instruction); 29326 case IrInstSrcIdSuspendBegin: 29327 return ir_analyze_instruction_suspend_begin(ira, (IrInstSrcSuspendBegin *)instruction); 29328 case IrInstSrcIdSuspendFinish: 29329 return ir_analyze_instruction_suspend_finish(ira, (IrInstSrcSuspendFinish *)instruction); 29330 case IrInstSrcIdResume: 29331 return ir_analyze_instruction_resume(ira, (IrInstSrcResume *)instruction); 29332 case IrInstSrcIdAwait: 29333 return ir_analyze_instruction_await(ira, (IrInstSrcAwait *)instruction); 29334 case IrInstSrcIdSpillBegin: 29335 return ir_analyze_instruction_spill_begin(ira, (IrInstSrcSpillBegin *)instruction); 29336 case IrInstSrcIdSpillEnd: 29337 return ir_analyze_instruction_spill_end(ira, (IrInstSrcSpillEnd *)instruction); 29338 } 29339 zig_unreachable(); 29340 } 29341 29342 // This function attempts to evaluate IR code while doing type checking and other analysis. 29343 // It emits to a new IrExecutableGen which is partially evaluated IR code. 29344 ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen *new_exec, 29345 ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *result_ptr) 29346 { 29347 assert(old_exec->first_err_trace_msg == nullptr); 29348 assert(expected_type == nullptr || !type_is_invalid(expected_type)); 29349 29350 IrAnalyze *ira = heap::c_allocator.create<IrAnalyze>(); 29351 ira->ref_count = 1; 29352 old_exec->analysis = ira; 29353 ira->codegen = codegen; 29354 29355 ira->explicit_return_type = expected_type; 29356 ira->explicit_return_type_source_node = expected_type_source_node; 29357 29358 ira->old_irb.codegen = codegen; 29359 ira->old_irb.exec = old_exec; 29360 29361 ira->new_irb.codegen = codegen; 29362 ira->new_irb.exec = new_exec; 29363 29364 IrBasicBlockSrc *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); 29365 IrBasicBlockGen *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); 29366 ir_ref_bb_gen(new_entry_bb); 29367 ira->new_irb.current_basic_block = new_entry_bb; 29368 ira->old_bb_index = 0; 29369 29370 ir_start_bb(ira, old_entry_bb, nullptr); 29371 29372 if (result_ptr != nullptr) { 29373 assert(result_ptr->type->id == ZigTypeIdPointer); 29374 IrInstGenConst *const_inst = ir_create_inst_noval<IrInstGenConst>( 29375 &ira->new_irb, new_exec->begin_scope, new_exec->source_node); 29376 const_inst->base.value = result_ptr; 29377 ira->return_ptr = &const_inst->base; 29378 } else { 29379 assert(new_exec->begin_scope != nullptr); 29380 assert(new_exec->source_node != nullptr); 29381 ira->return_ptr = ir_build_return_ptr(ira, new_exec->begin_scope, new_exec->source_node, 29382 get_pointer_to_type(codegen, expected_type, false)); 29383 } 29384 29385 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 29386 IrInstSrc *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 29387 29388 if (old_instruction->base.ref_count == 0 && !ir_inst_src_has_side_effects(old_instruction)) { 29389 ira->instruction_index += 1; 29390 continue; 29391 } 29392 29393 if (ira->codegen->verbose_ir) { 29394 fprintf(stderr, "~ "); 29395 old_instruction->src(); 29396 fprintf(stderr, "~ "); 29397 ir_print_inst_src(codegen, stderr, old_instruction, 0); 29398 bool want_break = false; 29399 if (ira->break_debug_id == old_instruction->base.debug_id) { 29400 want_break = true; 29401 } else if (old_instruction->base.source_node != nullptr) { 29402 for (size_t i = 0; i < dbg_ir_breakpoints_count; i += 1) { 29403 if (dbg_ir_breakpoints_buf[i].line == old_instruction->base.source_node->line + 1 && 29404 buf_ends_with_str(old_instruction->base.source_node->owner->data.structure.root_struct->path, 29405 dbg_ir_breakpoints_buf[i].src_file)) 29406 { 29407 want_break = true; 29408 } 29409 } 29410 } 29411 if (want_break) BREAKPOINT; 29412 } 29413 IrInstGen *new_instruction = ir_analyze_instruction_base(ira, old_instruction); 29414 if (new_instruction != nullptr) { 29415 ir_assert(new_instruction->value->type != nullptr || new_instruction->value->type != nullptr, &old_instruction->base); 29416 old_instruction->child = new_instruction; 29417 29418 if (type_is_invalid(new_instruction->value->type)) { 29419 if (ira->codegen->verbose_ir) { 29420 fprintf(stderr, "-> (invalid)"); 29421 } 29422 29423 if (new_exec->first_err_trace_msg != nullptr) { 29424 ira->codegen->trace_err = new_exec->first_err_trace_msg; 29425 } else { 29426 new_exec->first_err_trace_msg = ira->codegen->trace_err; 29427 } 29428 if (new_exec->first_err_trace_msg != nullptr && 29429 !old_instruction->base.source_node->already_traced_this_node) 29430 { 29431 old_instruction->base.source_node->already_traced_this_node = true; 29432 new_exec->first_err_trace_msg = add_error_note(ira->codegen, new_exec->first_err_trace_msg, 29433 old_instruction->base.source_node, buf_create_from_str("referenced here")); 29434 } 29435 return ira->codegen->builtin_types.entry_invalid; 29436 } else if (ira->codegen->verbose_ir) { 29437 fprintf(stderr, "-> "); 29438 if (new_instruction->value->type->id == ZigTypeIdUnreachable) { 29439 fprintf(stderr, "(noreturn)\n"); 29440 } else { 29441 ir_print_inst_gen(codegen, stderr, new_instruction, 0); 29442 } 29443 } 29444 29445 // unreachable instructions do their own control flow. 29446 if (new_instruction->value->type->id == ZigTypeIdUnreachable) 29447 continue; 29448 } else { 29449 if (ira->codegen->verbose_ir) { 29450 fprintf(stderr, "-> (null"); 29451 } 29452 } 29453 29454 ira->instruction_index += 1; 29455 } 29456 29457 ZigType *res_type; 29458 if (new_exec->first_err_trace_msg != nullptr) { 29459 codegen->trace_err = new_exec->first_err_trace_msg; 29460 if (codegen->trace_err != nullptr && new_exec->source_node != nullptr && 29461 !new_exec->source_node->already_traced_this_node) 29462 { 29463 new_exec->source_node->already_traced_this_node = true; 29464 codegen->trace_err = add_error_note(codegen, codegen->trace_err, 29465 new_exec->source_node, buf_create_from_str("referenced here")); 29466 } 29467 res_type = ira->codegen->builtin_types.entry_invalid; 29468 } else if (ira->src_implicit_return_type_list.length == 0) { 29469 res_type = codegen->builtin_types.entry_unreachable; 29470 } else { 29471 res_type = ir_resolve_peer_types(ira, expected_type_source_node, expected_type, ira->src_implicit_return_type_list.items, 29472 ira->src_implicit_return_type_list.length); 29473 } 29474 29475 // It is now safe to free Pass 1 IR instructions. 29476 ira_deref(ira); 29477 29478 return res_type; 29479 } 29480 29481 bool ir_inst_gen_has_side_effects(IrInstGen *instruction) { 29482 switch (instruction->id) { 29483 case IrInstGenIdInvalid: 29484 zig_unreachable(); 29485 case IrInstGenIdBr: 29486 case IrInstGenIdCondBr: 29487 case IrInstGenIdSwitchBr: 29488 case IrInstGenIdDeclVar: 29489 case IrInstGenIdStorePtr: 29490 case IrInstGenIdVectorStoreElem: 29491 case IrInstGenIdCall: 29492 case IrInstGenIdReturn: 29493 case IrInstGenIdUnreachable: 29494 case IrInstGenIdFence: 29495 case IrInstGenIdMemset: 29496 case IrInstGenIdMemcpy: 29497 case IrInstGenIdBreakpoint: 29498 case IrInstGenIdOverflowOp: // TODO when we support multiple returns this can be side effect free 29499 case IrInstGenIdPanic: 29500 case IrInstGenIdSaveErrRetAddr: 29501 case IrInstGenIdAtomicRmw: 29502 case IrInstGenIdAtomicStore: 29503 case IrInstGenIdCmpxchg: 29504 case IrInstGenIdAssertZero: 29505 case IrInstGenIdAssertNonNull: 29506 case IrInstGenIdPtrOfArrayToSlice: 29507 case IrInstGenIdSlice: 29508 case IrInstGenIdOptionalWrap: 29509 case IrInstGenIdVectorToArray: 29510 case IrInstGenIdSuspendBegin: 29511 case IrInstGenIdSuspendFinish: 29512 case IrInstGenIdResume: 29513 case IrInstGenIdAwait: 29514 case IrInstGenIdSpillBegin: 29515 return true; 29516 29517 case IrInstGenIdPhi: 29518 case IrInstGenIdBinOp: 29519 case IrInstGenIdConst: 29520 case IrInstGenIdCast: 29521 case IrInstGenIdElemPtr: 29522 case IrInstGenIdVarPtr: 29523 case IrInstGenIdReturnPtr: 29524 case IrInstGenIdStructFieldPtr: 29525 case IrInstGenIdTestNonNull: 29526 case IrInstGenIdClz: 29527 case IrInstGenIdCtz: 29528 case IrInstGenIdPopCount: 29529 case IrInstGenIdBswap: 29530 case IrInstGenIdBitReverse: 29531 case IrInstGenIdUnionTag: 29532 case IrInstGenIdTruncate: 29533 case IrInstGenIdShuffleVector: 29534 case IrInstGenIdSplat: 29535 case IrInstGenIdBoolNot: 29536 case IrInstGenIdReturnAddress: 29537 case IrInstGenIdFrameAddress: 29538 case IrInstGenIdFrameHandle: 29539 case IrInstGenIdFrameSize: 29540 case IrInstGenIdTestErr: 29541 case IrInstGenIdPtrCast: 29542 case IrInstGenIdBitCast: 29543 case IrInstGenIdWidenOrShorten: 29544 case IrInstGenIdPtrToInt: 29545 case IrInstGenIdIntToPtr: 29546 case IrInstGenIdIntToEnum: 29547 case IrInstGenIdIntToErr: 29548 case IrInstGenIdErrToInt: 29549 case IrInstGenIdErrName: 29550 case IrInstGenIdTagName: 29551 case IrInstGenIdFieldParentPtr: 29552 case IrInstGenIdAlignCast: 29553 case IrInstGenIdErrorReturnTrace: 29554 case IrInstGenIdFloatOp: 29555 case IrInstGenIdMulAdd: 29556 case IrInstGenIdAtomicLoad: 29557 case IrInstGenIdArrayToVector: 29558 case IrInstGenIdAlloca: 29559 case IrInstGenIdSpillEnd: 29560 case IrInstGenIdVectorExtractElem: 29561 case IrInstGenIdBinaryNot: 29562 case IrInstGenIdNegation: 29563 case IrInstGenIdNegationWrapping: 29564 return false; 29565 29566 case IrInstGenIdAsm: 29567 { 29568 IrInstGenAsm *asm_instruction = (IrInstGenAsm *)instruction; 29569 return asm_instruction->has_side_effects; 29570 } 29571 case IrInstGenIdUnwrapErrPayload: 29572 { 29573 IrInstGenUnwrapErrPayload *unwrap_err_payload_instruction = 29574 (IrInstGenUnwrapErrPayload *)instruction; 29575 return unwrap_err_payload_instruction->safety_check_on || 29576 unwrap_err_payload_instruction->initializing; 29577 } 29578 case IrInstGenIdUnwrapErrCode: 29579 return reinterpret_cast<IrInstGenUnwrapErrCode *>(instruction)->initializing; 29580 case IrInstGenIdUnionFieldPtr: 29581 return reinterpret_cast<IrInstGenUnionFieldPtr *>(instruction)->initializing; 29582 case IrInstGenIdOptionalUnwrapPtr: 29583 return reinterpret_cast<IrInstGenOptionalUnwrapPtr *>(instruction)->initializing; 29584 case IrInstGenIdErrWrapPayload: 29585 return reinterpret_cast<IrInstGenErrWrapPayload *>(instruction)->result_loc != nullptr; 29586 case IrInstGenIdErrWrapCode: 29587 return reinterpret_cast<IrInstGenErrWrapCode *>(instruction)->result_loc != nullptr; 29588 case IrInstGenIdLoadPtr: 29589 return reinterpret_cast<IrInstGenLoadPtr *>(instruction)->result_loc != nullptr; 29590 case IrInstGenIdRef: 29591 return reinterpret_cast<IrInstGenRef *>(instruction)->result_loc != nullptr; 29592 } 29593 zig_unreachable(); 29594 } 29595 29596 bool ir_inst_src_has_side_effects(IrInstSrc *instruction) { 29597 switch (instruction->id) { 29598 case IrInstSrcIdInvalid: 29599 zig_unreachable(); 29600 case IrInstSrcIdBr: 29601 case IrInstSrcIdCondBr: 29602 case IrInstSrcIdSwitchBr: 29603 case IrInstSrcIdDeclVar: 29604 case IrInstSrcIdStorePtr: 29605 case IrInstSrcIdCallExtra: 29606 case IrInstSrcIdCall: 29607 case IrInstSrcIdCallArgs: 29608 case IrInstSrcIdReturn: 29609 case IrInstSrcIdUnreachable: 29610 case IrInstSrcIdSetCold: 29611 case IrInstSrcIdSetRuntimeSafety: 29612 case IrInstSrcIdSetFloatMode: 29613 case IrInstSrcIdImport: 29614 case IrInstSrcIdCompileErr: 29615 case IrInstSrcIdCompileLog: 29616 case IrInstSrcIdCImport: 29617 case IrInstSrcIdCInclude: 29618 case IrInstSrcIdCDefine: 29619 case IrInstSrcIdCUndef: 29620 case IrInstSrcIdFence: 29621 case IrInstSrcIdMemset: 29622 case IrInstSrcIdMemcpy: 29623 case IrInstSrcIdBreakpoint: 29624 case IrInstSrcIdOverflowOp: // TODO when we support multiple returns this can be side effect free 29625 case IrInstSrcIdCheckSwitchProngs: 29626 case IrInstSrcIdCheckStatementIsVoid: 29627 case IrInstSrcIdCheckRuntimeScope: 29628 case IrInstSrcIdPanic: 29629 case IrInstSrcIdSetEvalBranchQuota: 29630 case IrInstSrcIdPtrType: 29631 case IrInstSrcIdSetAlignStack: 29632 case IrInstSrcIdExport: 29633 case IrInstSrcIdSaveErrRetAddr: 29634 case IrInstSrcIdAddImplicitReturnType: 29635 case IrInstSrcIdAtomicRmw: 29636 case IrInstSrcIdAtomicStore: 29637 case IrInstSrcIdCmpxchg: 29638 case IrInstSrcIdUndeclaredIdent: 29639 case IrInstSrcIdEndExpr: 29640 case IrInstSrcIdResetResult: 29641 case IrInstSrcIdSuspendBegin: 29642 case IrInstSrcIdSuspendFinish: 29643 case IrInstSrcIdResume: 29644 case IrInstSrcIdAwait: 29645 case IrInstSrcIdSpillBegin: 29646 return true; 29647 29648 case IrInstSrcIdPhi: 29649 case IrInstSrcIdUnOp: 29650 case IrInstSrcIdBinOp: 29651 case IrInstSrcIdMergeErrSets: 29652 case IrInstSrcIdLoadPtr: 29653 case IrInstSrcIdConst: 29654 case IrInstSrcIdContainerInitList: 29655 case IrInstSrcIdContainerInitFields: 29656 case IrInstSrcIdUnionInitNamedField: 29657 case IrInstSrcIdFieldPtr: 29658 case IrInstSrcIdElemPtr: 29659 case IrInstSrcIdVarPtr: 29660 case IrInstSrcIdTypeOf: 29661 case IrInstSrcIdArrayType: 29662 case IrInstSrcIdSliceType: 29663 case IrInstSrcIdAnyFrameType: 29664 case IrInstSrcIdSizeOf: 29665 case IrInstSrcIdTestNonNull: 29666 case IrInstSrcIdOptionalUnwrapPtr: 29667 case IrInstSrcIdClz: 29668 case IrInstSrcIdCtz: 29669 case IrInstSrcIdPopCount: 29670 case IrInstSrcIdBswap: 29671 case IrInstSrcIdBitReverse: 29672 case IrInstSrcIdSwitchVar: 29673 case IrInstSrcIdSwitchElseVar: 29674 case IrInstSrcIdSwitchTarget: 29675 case IrInstSrcIdRef: 29676 case IrInstSrcIdEmbedFile: 29677 case IrInstSrcIdTruncate: 29678 case IrInstSrcIdVectorType: 29679 case IrInstSrcIdShuffleVector: 29680 case IrInstSrcIdSplat: 29681 case IrInstSrcIdBoolNot: 29682 case IrInstSrcIdSlice: 29683 case IrInstSrcIdAlignOf: 29684 case IrInstSrcIdReturnAddress: 29685 case IrInstSrcIdFrameAddress: 29686 case IrInstSrcIdFrameHandle: 29687 case IrInstSrcIdFrameType: 29688 case IrInstSrcIdFrameSize: 29689 case IrInstSrcIdTestErr: 29690 case IrInstSrcIdFnProto: 29691 case IrInstSrcIdTestComptime: 29692 case IrInstSrcIdPtrCast: 29693 case IrInstSrcIdBitCast: 29694 case IrInstSrcIdPtrToInt: 29695 case IrInstSrcIdIntToPtr: 29696 case IrInstSrcIdIntToEnum: 29697 case IrInstSrcIdIntToErr: 29698 case IrInstSrcIdErrToInt: 29699 case IrInstSrcIdDeclRef: 29700 case IrInstSrcIdErrName: 29701 case IrInstSrcIdTypeName: 29702 case IrInstSrcIdTagName: 29703 case IrInstSrcIdFieldParentPtr: 29704 case IrInstSrcIdByteOffsetOf: 29705 case IrInstSrcIdBitOffsetOf: 29706 case IrInstSrcIdTypeInfo: 29707 case IrInstSrcIdType: 29708 case IrInstSrcIdHasField: 29709 case IrInstSrcIdAlignCast: 29710 case IrInstSrcIdImplicitCast: 29711 case IrInstSrcIdResolveResult: 29712 case IrInstSrcIdOpaqueType: 29713 case IrInstSrcIdArgType: 29714 case IrInstSrcIdTagType: 29715 case IrInstSrcIdErrorReturnTrace: 29716 case IrInstSrcIdErrorUnion: 29717 case IrInstSrcIdFloatOp: 29718 case IrInstSrcIdMulAdd: 29719 case IrInstSrcIdAtomicLoad: 29720 case IrInstSrcIdIntCast: 29721 case IrInstSrcIdFloatCast: 29722 case IrInstSrcIdErrSetCast: 29723 case IrInstSrcIdIntToFloat: 29724 case IrInstSrcIdFloatToInt: 29725 case IrInstSrcIdBoolToInt: 29726 case IrInstSrcIdEnumToInt: 29727 case IrInstSrcIdHasDecl: 29728 case IrInstSrcIdAlloca: 29729 case IrInstSrcIdSpillEnd: 29730 return false; 29731 29732 case IrInstSrcIdAsm: 29733 { 29734 IrInstSrcAsm *asm_instruction = (IrInstSrcAsm *)instruction; 29735 return asm_instruction->has_side_effects; 29736 } 29737 29738 case IrInstSrcIdUnwrapErrPayload: 29739 { 29740 IrInstSrcUnwrapErrPayload *unwrap_err_payload_instruction = 29741 (IrInstSrcUnwrapErrPayload *)instruction; 29742 return unwrap_err_payload_instruction->safety_check_on || 29743 unwrap_err_payload_instruction->initializing; 29744 } 29745 case IrInstSrcIdUnwrapErrCode: 29746 return reinterpret_cast<IrInstSrcUnwrapErrCode *>(instruction)->initializing; 29747 } 29748 zig_unreachable(); 29749 } 29750 29751 static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, LazyValueFnType *lazy_fn_type) { 29752 Error err; 29753 AstNode *proto_node = lazy_fn_type->proto_node; 29754 29755 FnTypeId fn_type_id = {0}; 29756 init_fn_type_id(&fn_type_id, proto_node, lazy_fn_type->cc, proto_node->data.fn_proto.params.length); 29757 29758 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { 29759 AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); 29760 assert(param_node->type == NodeTypeParamDecl); 29761 29762 bool param_is_var_args = param_node->data.param_decl.is_var_args; 29763 if (param_is_var_args) { 29764 if (fn_type_id.cc == CallingConventionC) { 29765 fn_type_id.param_count = fn_type_id.next_param_index; 29766 break; 29767 } else if (fn_type_id.cc == CallingConventionUnspecified) { 29768 return get_generic_fn_type(ira->codegen, &fn_type_id); 29769 } else { 29770 zig_unreachable(); 29771 } 29772 } 29773 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; 29774 param_info->is_noalias = param_node->data.param_decl.is_noalias; 29775 29776 if (lazy_fn_type->param_types[fn_type_id.next_param_index] == nullptr) { 29777 param_info->type = nullptr; 29778 return get_generic_fn_type(ira->codegen, &fn_type_id); 29779 } else { 29780 IrInstGen *param_type_inst = lazy_fn_type->param_types[fn_type_id.next_param_index]; 29781 ZigType *param_type = ir_resolve_type(ira, param_type_inst); 29782 if (type_is_invalid(param_type)) 29783 return nullptr; 29784 switch (type_requires_comptime(ira->codegen, param_type)) { 29785 case ReqCompTimeYes: 29786 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 29787 ir_add_error(ira, ¶m_type_inst->base, 29788 buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", 29789 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 29790 return nullptr; 29791 } 29792 param_info->type = param_type; 29793 fn_type_id.next_param_index += 1; 29794 return get_generic_fn_type(ira->codegen, &fn_type_id); 29795 case ReqCompTimeInvalid: 29796 return nullptr; 29797 case ReqCompTimeNo: 29798 break; 29799 } 29800 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 29801 bool has_bits; 29802 if ((err = type_has_bits2(ira->codegen, param_type, &has_bits))) 29803 return nullptr; 29804 if (!has_bits) { 29805 ir_add_error(ira, ¶m_type_inst->base, 29806 buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", 29807 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 29808 return nullptr; 29809 } 29810 } 29811 param_info->type = param_type; 29812 } 29813 } 29814 29815 if (lazy_fn_type->align_inst != nullptr) { 29816 if (!ir_resolve_align(ira, lazy_fn_type->align_inst, nullptr, &fn_type_id.alignment)) 29817 return nullptr; 29818 } 29819 29820 fn_type_id.return_type = ir_resolve_type(ira, lazy_fn_type->return_type); 29821 if (type_is_invalid(fn_type_id.return_type)) 29822 return nullptr; 29823 if (fn_type_id.return_type->id == ZigTypeIdOpaque) { 29824 ir_add_error(ira, &lazy_fn_type->return_type->base, buf_create_from_str("return type cannot be opaque")); 29825 return nullptr; 29826 } 29827 29828 return get_fn_type(ira->codegen, &fn_type_id); 29829 } 29830 29831 static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { 29832 Error err; 29833 if (val->special != ConstValSpecialLazy) 29834 return ErrorNone; 29835 switch (val->data.x_lazy->id) { 29836 case LazyValueIdInvalid: 29837 zig_unreachable(); 29838 case LazyValueIdTypeInfoDecls: { 29839 LazyValueTypeInfoDecls *type_info_decls = reinterpret_cast<LazyValueTypeInfoDecls *>(val->data.x_lazy); 29840 IrAnalyze *ira = type_info_decls->ira; 29841 29842 if ((err = ir_make_type_info_decls(ira, type_info_decls->source_instr, val, type_info_decls->decls_scope, true))) 29843 { 29844 return err; 29845 }; 29846 29847 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 29848 return ErrorNone; 29849 } 29850 case LazyValueIdAlignOf: { 29851 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy); 29852 IrAnalyze *ira = lazy_align_of->ira; 29853 29854 if (lazy_align_of->target_type->value->special == ConstValSpecialStatic) { 29855 switch (lazy_align_of->target_type->value->data.x_type->id) { 29856 case ZigTypeIdInvalid: 29857 zig_unreachable(); 29858 case ZigTypeIdMetaType: 29859 case ZigTypeIdUnreachable: 29860 case ZigTypeIdComptimeFloat: 29861 case ZigTypeIdComptimeInt: 29862 case ZigTypeIdEnumLiteral: 29863 case ZigTypeIdUndefined: 29864 case ZigTypeIdNull: 29865 case ZigTypeIdBoundFn: 29866 case ZigTypeIdVoid: 29867 case ZigTypeIdOpaque: 29868 ir_add_error(ira, &lazy_align_of->target_type->base, 29869 buf_sprintf("no align available for type '%s'", 29870 buf_ptr(&lazy_align_of->target_type->value->data.x_type->name))); 29871 return ErrorSemanticAnalyzeFail; 29872 case ZigTypeIdBool: 29873 case ZigTypeIdInt: 29874 case ZigTypeIdFloat: 29875 case ZigTypeIdPointer: 29876 case ZigTypeIdArray: 29877 case ZigTypeIdStruct: 29878 case ZigTypeIdOptional: 29879 case ZigTypeIdErrorUnion: 29880 case ZigTypeIdErrorSet: 29881 case ZigTypeIdEnum: 29882 case ZigTypeIdUnion: 29883 case ZigTypeIdFn: 29884 case ZigTypeIdVector: 29885 case ZigTypeIdFnFrame: 29886 case ZigTypeIdAnyFrame: 29887 break; 29888 } 29889 } 29890 29891 uint32_t align_in_bytes; 29892 if ((err = type_val_resolve_abi_align(ira->codegen, source_node, 29893 lazy_align_of->target_type->value, &align_in_bytes))) 29894 { 29895 return err; 29896 } 29897 29898 val->special = ConstValSpecialStatic; 29899 assert(val->type->id == ZigTypeIdComptimeInt || val->type->id == ZigTypeIdInt); 29900 bigint_init_unsigned(&val->data.x_bigint, align_in_bytes); 29901 29902 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 29903 return ErrorNone; 29904 } 29905 case LazyValueIdSizeOf: { 29906 LazyValueSizeOf *lazy_size_of = reinterpret_cast<LazyValueSizeOf *>(val->data.x_lazy); 29907 IrAnalyze *ira = lazy_size_of->ira; 29908 29909 if (lazy_size_of->target_type->value->special == ConstValSpecialStatic) { 29910 switch (lazy_size_of->target_type->value->data.x_type->id) { 29911 case ZigTypeIdInvalid: // handled above 29912 zig_unreachable(); 29913 case ZigTypeIdUnreachable: 29914 case ZigTypeIdUndefined: 29915 case ZigTypeIdNull: 29916 case ZigTypeIdBoundFn: 29917 case ZigTypeIdOpaque: 29918 ir_add_error(ira, &lazy_size_of->target_type->base, 29919 buf_sprintf("no size available for type '%s'", 29920 buf_ptr(&lazy_size_of->target_type->value->data.x_type->name))); 29921 return ErrorSemanticAnalyzeFail; 29922 case ZigTypeIdMetaType: 29923 case ZigTypeIdEnumLiteral: 29924 case ZigTypeIdComptimeFloat: 29925 case ZigTypeIdComptimeInt: 29926 case ZigTypeIdVoid: 29927 case ZigTypeIdBool: 29928 case ZigTypeIdInt: 29929 case ZigTypeIdFloat: 29930 case ZigTypeIdPointer: 29931 case ZigTypeIdArray: 29932 case ZigTypeIdStruct: 29933 case ZigTypeIdOptional: 29934 case ZigTypeIdErrorUnion: 29935 case ZigTypeIdErrorSet: 29936 case ZigTypeIdEnum: 29937 case ZigTypeIdUnion: 29938 case ZigTypeIdFn: 29939 case ZigTypeIdVector: 29940 case ZigTypeIdFnFrame: 29941 case ZigTypeIdAnyFrame: 29942 break; 29943 } 29944 } 29945 29946 size_t abi_size; 29947 size_t size_in_bits; 29948 if ((err = type_val_resolve_abi_size(ira->codegen, source_node, lazy_size_of->target_type->value, 29949 &abi_size, &size_in_bits))) 29950 { 29951 return err; 29952 } 29953 29954 val->special = ConstValSpecialStatic; 29955 assert(val->type->id == ZigTypeIdComptimeInt || val->type->id == ZigTypeIdInt); 29956 if (lazy_size_of->bit_size) 29957 bigint_init_unsigned(&val->data.x_bigint, size_in_bits); 29958 else 29959 bigint_init_unsigned(&val->data.x_bigint, abi_size); 29960 29961 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 29962 return ErrorNone; 29963 } 29964 case LazyValueIdSliceType: { 29965 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(val->data.x_lazy); 29966 IrAnalyze *ira = lazy_slice_type->ira; 29967 29968 ZigType *elem_type = ir_resolve_type(ira, lazy_slice_type->elem_type); 29969 if (type_is_invalid(elem_type)) 29970 return ErrorSemanticAnalyzeFail; 29971 29972 ZigValue *sentinel_val; 29973 if (lazy_slice_type->sentinel != nullptr) { 29974 if (type_is_invalid(lazy_slice_type->sentinel->value->type)) 29975 return ErrorSemanticAnalyzeFail; 29976 IrInstGen *sentinel = ir_implicit_cast(ira, lazy_slice_type->sentinel, elem_type); 29977 if (type_is_invalid(sentinel->value->type)) 29978 return ErrorSemanticAnalyzeFail; 29979 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 29980 if (sentinel_val == nullptr) 29981 return ErrorSemanticAnalyzeFail; 29982 } else { 29983 sentinel_val = nullptr; 29984 } 29985 29986 uint32_t align_bytes = 0; 29987 if (lazy_slice_type->align_inst != nullptr) { 29988 if (!ir_resolve_align(ira, lazy_slice_type->align_inst, elem_type, &align_bytes)) 29989 return ErrorSemanticAnalyzeFail; 29990 } 29991 29992 switch (elem_type->id) { 29993 case ZigTypeIdInvalid: // handled above 29994 zig_unreachable(); 29995 case ZigTypeIdUnreachable: 29996 case ZigTypeIdUndefined: 29997 case ZigTypeIdNull: 29998 case ZigTypeIdOpaque: 29999 ir_add_error(ira, &lazy_slice_type->elem_type->base, 30000 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&elem_type->name))); 30001 return ErrorSemanticAnalyzeFail; 30002 case ZigTypeIdMetaType: 30003 case ZigTypeIdVoid: 30004 case ZigTypeIdBool: 30005 case ZigTypeIdInt: 30006 case ZigTypeIdFloat: 30007 case ZigTypeIdPointer: 30008 case ZigTypeIdArray: 30009 case ZigTypeIdStruct: 30010 case ZigTypeIdComptimeFloat: 30011 case ZigTypeIdComptimeInt: 30012 case ZigTypeIdEnumLiteral: 30013 case ZigTypeIdOptional: 30014 case ZigTypeIdErrorUnion: 30015 case ZigTypeIdErrorSet: 30016 case ZigTypeIdEnum: 30017 case ZigTypeIdUnion: 30018 case ZigTypeIdFn: 30019 case ZigTypeIdBoundFn: 30020 case ZigTypeIdVector: 30021 case ZigTypeIdFnFrame: 30022 case ZigTypeIdAnyFrame: 30023 break; 30024 } 30025 30026 ResolveStatus needed_status = (align_bytes == 0) ? 30027 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; 30028 if ((err = type_resolve(ira->codegen, elem_type, needed_status))) 30029 return err; 30030 ZigType *slice_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 30031 lazy_slice_type->is_const, lazy_slice_type->is_volatile, 30032 PtrLenUnknown, 30033 align_bytes, 30034 0, 0, lazy_slice_type->is_allowzero, 30035 VECTOR_INDEX_NONE, nullptr, sentinel_val); 30036 val->special = ConstValSpecialStatic; 30037 assert(val->type->id == ZigTypeIdMetaType); 30038 val->data.x_type = get_slice_type(ira->codegen, slice_ptr_type); 30039 30040 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 30041 return ErrorNone; 30042 } 30043 case LazyValueIdPtrType: { 30044 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(val->data.x_lazy); 30045 IrAnalyze *ira = lazy_ptr_type->ira; 30046 30047 ZigType *elem_type = ir_resolve_type(ira, lazy_ptr_type->elem_type); 30048 if (type_is_invalid(elem_type)) 30049 return ErrorSemanticAnalyzeFail; 30050 30051 ZigValue *sentinel_val; 30052 if (lazy_ptr_type->sentinel != nullptr) { 30053 if (type_is_invalid(lazy_ptr_type->sentinel->value->type)) 30054 return ErrorSemanticAnalyzeFail; 30055 IrInstGen *sentinel = ir_implicit_cast(ira, lazy_ptr_type->sentinel, elem_type); 30056 if (type_is_invalid(sentinel->value->type)) 30057 return ErrorSemanticAnalyzeFail; 30058 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 30059 if (sentinel_val == nullptr) 30060 return ErrorSemanticAnalyzeFail; 30061 } else { 30062 sentinel_val = nullptr; 30063 } 30064 30065 uint32_t align_bytes = 0; 30066 if (lazy_ptr_type->align_inst != nullptr) { 30067 if (!ir_resolve_align(ira, lazy_ptr_type->align_inst, elem_type, &align_bytes)) 30068 return ErrorSemanticAnalyzeFail; 30069 } 30070 30071 if (elem_type->id == ZigTypeIdUnreachable) { 30072 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 30073 buf_create_from_str("pointer to noreturn not allowed")); 30074 return ErrorSemanticAnalyzeFail; 30075 } else if (elem_type->id == ZigTypeIdOpaque && lazy_ptr_type->ptr_len == PtrLenUnknown) { 30076 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 30077 buf_create_from_str("unknown-length pointer to opaque")); 30078 return ErrorSemanticAnalyzeFail; 30079 } else if (lazy_ptr_type->ptr_len == PtrLenC) { 30080 bool ok_type; 30081 if ((err = type_allowed_in_extern(ira->codegen, elem_type, &ok_type))) 30082 return err; 30083 if (!ok_type) { 30084 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 30085 buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", 30086 buf_ptr(&elem_type->name))); 30087 return ErrorSemanticAnalyzeFail; 30088 } else if (elem_type->id == ZigTypeIdOpaque) { 30089 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 30090 buf_sprintf("C pointers cannot point opaque types")); 30091 return ErrorSemanticAnalyzeFail; 30092 } else if (lazy_ptr_type->is_allowzero) { 30093 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 30094 buf_sprintf("C pointers always allow address zero")); 30095 return ErrorSemanticAnalyzeFail; 30096 } 30097 } 30098 30099 if (align_bytes != 0) { 30100 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown))) 30101 return err; 30102 if (!type_has_bits(elem_type)) 30103 align_bytes = 0; 30104 } 30105 bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC; 30106 assert(val->type->id == ZigTypeIdMetaType); 30107 val->data.x_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 30108 lazy_ptr_type->is_const, lazy_ptr_type->is_volatile, lazy_ptr_type->ptr_len, align_bytes, 30109 lazy_ptr_type->bit_offset_in_host, lazy_ptr_type->host_int_bytes, 30110 allow_zero, VECTOR_INDEX_NONE, nullptr, sentinel_val); 30111 val->special = ConstValSpecialStatic; 30112 30113 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 30114 return ErrorNone; 30115 } 30116 case LazyValueIdArrayType: { 30117 LazyValueArrayType *lazy_array_type = reinterpret_cast<LazyValueArrayType *>(val->data.x_lazy); 30118 IrAnalyze *ira = lazy_array_type->ira; 30119 30120 ZigType *elem_type = ir_resolve_type(ira, lazy_array_type->elem_type); 30121 if (type_is_invalid(elem_type)) 30122 return ErrorSemanticAnalyzeFail; 30123 30124 switch (elem_type->id) { 30125 case ZigTypeIdInvalid: // handled above 30126 zig_unreachable(); 30127 case ZigTypeIdUnreachable: 30128 case ZigTypeIdUndefined: 30129 case ZigTypeIdNull: 30130 case ZigTypeIdOpaque: 30131 ir_add_error(ira, &lazy_array_type->elem_type->base, 30132 buf_sprintf("array of type '%s' not allowed", 30133 buf_ptr(&elem_type->name))); 30134 return ErrorSemanticAnalyzeFail; 30135 case ZigTypeIdMetaType: 30136 case ZigTypeIdVoid: 30137 case ZigTypeIdBool: 30138 case ZigTypeIdInt: 30139 case ZigTypeIdFloat: 30140 case ZigTypeIdPointer: 30141 case ZigTypeIdArray: 30142 case ZigTypeIdStruct: 30143 case ZigTypeIdComptimeFloat: 30144 case ZigTypeIdComptimeInt: 30145 case ZigTypeIdEnumLiteral: 30146 case ZigTypeIdOptional: 30147 case ZigTypeIdErrorUnion: 30148 case ZigTypeIdErrorSet: 30149 case ZigTypeIdEnum: 30150 case ZigTypeIdUnion: 30151 case ZigTypeIdFn: 30152 case ZigTypeIdBoundFn: 30153 case ZigTypeIdVector: 30154 case ZigTypeIdFnFrame: 30155 case ZigTypeIdAnyFrame: 30156 break; 30157 } 30158 30159 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) 30160 return err; 30161 30162 ZigValue *sentinel_val = nullptr; 30163 if (lazy_array_type->sentinel != nullptr) { 30164 if (type_is_invalid(lazy_array_type->sentinel->value->type)) 30165 return ErrorSemanticAnalyzeFail; 30166 IrInstGen *sentinel = ir_implicit_cast(ira, lazy_array_type->sentinel, elem_type); 30167 if (type_is_invalid(sentinel->value->type)) 30168 return ErrorSemanticAnalyzeFail; 30169 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 30170 if (sentinel_val == nullptr) 30171 return ErrorSemanticAnalyzeFail; 30172 } 30173 30174 assert(val->type->id == ZigTypeIdMetaType); 30175 val->data.x_type = get_array_type(ira->codegen, elem_type, lazy_array_type->length, sentinel_val); 30176 val->special = ConstValSpecialStatic; 30177 30178 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 30179 return ErrorNone; 30180 } 30181 case LazyValueIdOptType: { 30182 LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(val->data.x_lazy); 30183 IrAnalyze *ira = lazy_opt_type->ira; 30184 30185 ZigType *payload_type = ir_resolve_type(ira, lazy_opt_type->payload_type); 30186 if (type_is_invalid(payload_type)) 30187 return ErrorSemanticAnalyzeFail; 30188 30189 if (payload_type->id == ZigTypeIdOpaque || payload_type->id == ZigTypeIdUnreachable) { 30190 ir_add_error(ira, &lazy_opt_type->payload_type->base, 30191 buf_sprintf("type '%s' cannot be optional", buf_ptr(&payload_type->name))); 30192 return ErrorSemanticAnalyzeFail; 30193 } 30194 30195 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 30196 return err; 30197 30198 assert(val->type->id == ZigTypeIdMetaType); 30199 val->data.x_type = get_optional_type(ira->codegen, payload_type); 30200 val->special = ConstValSpecialStatic; 30201 30202 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 30203 return ErrorNone; 30204 } 30205 case LazyValueIdFnType: { 30206 LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(val->data.x_lazy); 30207 IrAnalyze *ira = lazy_fn_type->ira; 30208 ZigType *fn_type = ir_resolve_lazy_fn_type(ira, source_node, lazy_fn_type); 30209 if (fn_type == nullptr) 30210 return ErrorSemanticAnalyzeFail; 30211 val->special = ConstValSpecialStatic; 30212 assert(val->type->id == ZigTypeIdMetaType); 30213 val->data.x_type = fn_type; 30214 30215 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 30216 return ErrorNone; 30217 } 30218 case LazyValueIdErrUnionType: { 30219 LazyValueErrUnionType *lazy_err_union_type = 30220 reinterpret_cast<LazyValueErrUnionType *>(val->data.x_lazy); 30221 IrAnalyze *ira = lazy_err_union_type->ira; 30222 30223 ZigType *err_set_type = ir_resolve_type(ira, lazy_err_union_type->err_set_type); 30224 if (type_is_invalid(err_set_type)) 30225 return ErrorSemanticAnalyzeFail; 30226 30227 ZigType *payload_type = ir_resolve_type(ira, lazy_err_union_type->payload_type); 30228 if (type_is_invalid(payload_type)) 30229 return ErrorSemanticAnalyzeFail; 30230 30231 if (err_set_type->id != ZigTypeIdErrorSet) { 30232 ir_add_error(ira, &lazy_err_union_type->err_set_type->base, 30233 buf_sprintf("expected error set type, found type '%s'", 30234 buf_ptr(&err_set_type->name))); 30235 return ErrorSemanticAnalyzeFail; 30236 } 30237 30238 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 30239 return ErrorSemanticAnalyzeFail; 30240 30241 assert(val->type->id == ZigTypeIdMetaType); 30242 val->data.x_type = get_error_union_type(ira->codegen, err_set_type, payload_type); 30243 val->special = ConstValSpecialStatic; 30244 30245 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 30246 return ErrorNone; 30247 } 30248 } 30249 zig_unreachable(); 30250 } 30251 30252 Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val) { 30253 Error err; 30254 if ((err = ir_resolve_lazy_raw(source_node, val))) { 30255 if (codegen->trace_err != nullptr && source_node != nullptr && !source_node->already_traced_this_node) { 30256 source_node->already_traced_this_node = true; 30257 codegen->trace_err = add_error_note(codegen, codegen->trace_err, source_node, 30258 buf_create_from_str("referenced here")); 30259 } 30260 return err; 30261 } 30262 if (type_is_invalid(val->type)) { 30263 return ErrorSemanticAnalyzeFail; 30264 } 30265 return ErrorNone; 30266 } 30267 30268 void IrInst::src() { 30269 IrInst *inst = this; 30270 if (inst->source_node != nullptr) { 30271 inst->source_node->src(); 30272 } else { 30273 fprintf(stderr, "(null source node)\n"); 30274 } 30275 } 30276 30277 void IrInst::dump() { 30278 this->src(); 30279 fprintf(stderr, "IrInst(#%" PRIu32 ")\n", this->debug_id); 30280 } 30281 30282 void IrInstSrc::src() { 30283 this->base.src(); 30284 } 30285 30286 void IrInstGen::src() { 30287 this->base.src(); 30288 } 30289 30290 void IrInstSrc::dump() { 30291 IrInstSrc *inst = this; 30292 inst->src(); 30293 if (inst->base.scope == nullptr) { 30294 fprintf(stderr, "(null scope)\n"); 30295 } else { 30296 ir_print_inst_src(inst->base.scope->codegen, stderr, inst, 0); 30297 fprintf(stderr, "-> "); 30298 ir_print_inst_gen(inst->base.scope->codegen, stderr, inst->child, 0); 30299 } 30300 } 30301 void IrInstGen::dump() { 30302 IrInstGen *inst = this; 30303 inst->src(); 30304 if (inst->base.scope == nullptr) { 30305 fprintf(stderr, "(null scope)\n"); 30306 } else { 30307 ir_print_inst_gen(inst->base.scope->codegen, stderr, inst, 0); 30308 } 30309 } 30310 30311 void IrAnalyze::dump() { 30312 ir_print_gen(this->codegen, stderr, this->new_irb.exec, 0); 30313 if (this->new_irb.current_basic_block != nullptr) { 30314 fprintf(stderr, "Current basic block:\n"); 30315 ir_print_basic_block_gen(this->codegen, stderr, this->new_irb.current_basic_block, 1); 30316 } 30317 } 30318 30319 void dbg_ir_break(const char *src_file, uint32_t line) { 30320 dbg_ir_breakpoints_buf[dbg_ir_breakpoints_count] = {src_file, line}; 30321 dbg_ir_breakpoints_count += 1; 30322 } 30323 void dbg_ir_clear(void) { 30324 dbg_ir_breakpoints_count = 0; 30325 }