blob 88e111cc (1464235B) - 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 "softfloat_ext.hpp" 17 #include "util.hpp" 18 #include "mem_list.hpp" 19 #include "all_types.hpp" 20 21 #include <errno.h> 22 23 struct IrBuilderSrc { 24 CodeGen *codegen; 25 IrExecutableSrc *exec; 26 IrBasicBlockSrc *current_basic_block; 27 AstNode *main_block_node; 28 }; 29 30 struct IrBuilderGen { 31 CodeGen *codegen; 32 IrExecutableGen *exec; 33 IrBasicBlockGen *current_basic_block; 34 35 // track for immediate post-analysis destruction 36 mem::List<IrInstGenConst *> constants; 37 }; 38 39 struct IrAnalyze { 40 CodeGen *codegen; 41 IrBuilderSrc old_irb; 42 IrBuilderGen new_irb; 43 size_t old_bb_index; 44 size_t instruction_index; 45 ZigType *explicit_return_type; 46 AstNode *explicit_return_type_source_node; 47 ZigList<IrInstGen *> src_implicit_return_type_list; 48 ZigList<IrSuspendPosition> resume_stack; 49 IrBasicBlockSrc *const_predecessor_bb; 50 size_t ref_count; 51 size_t break_debug_id; // for debugging purposes 52 IrInstGen *return_ptr; 53 54 // For the purpose of using in a debugger 55 void dump(); 56 }; 57 58 enum ConstCastResultId { 59 ConstCastResultIdOk, 60 ConstCastResultIdInvalid, 61 ConstCastResultIdErrSet, 62 ConstCastResultIdErrSetGlobal, 63 ConstCastResultIdPointerChild, 64 ConstCastResultIdSliceChild, 65 ConstCastResultIdOptionalChild, 66 ConstCastResultIdErrorUnionPayload, 67 ConstCastResultIdErrorUnionErrorSet, 68 ConstCastResultIdFnAlign, 69 ConstCastResultIdFnCC, 70 ConstCastResultIdFnVarArgs, 71 ConstCastResultIdFnIsGeneric, 72 ConstCastResultIdFnReturnType, 73 ConstCastResultIdFnArgCount, 74 ConstCastResultIdFnGenericArgCount, 75 ConstCastResultIdFnArg, 76 ConstCastResultIdFnArgNoAlias, 77 ConstCastResultIdType, 78 ConstCastResultIdUnresolvedInferredErrSet, 79 ConstCastResultIdAsyncAllocatorType, 80 ConstCastResultIdBadAllowsZero, 81 ConstCastResultIdArrayChild, 82 ConstCastResultIdSentinelArrays, 83 ConstCastResultIdPtrLens, 84 ConstCastResultIdCV, 85 ConstCastResultIdPtrSentinel, 86 ConstCastResultIdIntShorten, 87 }; 88 89 struct ConstCastOnly; 90 struct ConstCastArg { 91 size_t arg_index; 92 ZigType *actual_param_type; 93 ZigType *expected_param_type; 94 ConstCastOnly *child; 95 }; 96 97 struct ConstCastArgNoAlias { 98 size_t arg_index; 99 }; 100 101 struct ConstCastOptionalMismatch; 102 struct ConstCastPointerMismatch; 103 struct ConstCastSliceMismatch; 104 struct ConstCastErrUnionErrSetMismatch; 105 struct ConstCastErrUnionPayloadMismatch; 106 struct ConstCastErrSetMismatch; 107 struct ConstCastTypeMismatch; 108 struct ConstCastArrayMismatch; 109 struct ConstCastBadAllowsZero; 110 struct ConstCastBadNullTermArrays; 111 struct ConstCastBadCV; 112 struct ConstCastPtrSentinel; 113 struct ConstCastIntShorten; 114 115 struct ConstCastOnly { 116 ConstCastResultId id; 117 union { 118 ConstCastErrSetMismatch *error_set_mismatch; 119 ConstCastPointerMismatch *pointer_mismatch; 120 ConstCastSliceMismatch *slice_mismatch; 121 ConstCastOptionalMismatch *optional; 122 ConstCastErrUnionPayloadMismatch *error_union_payload; 123 ConstCastErrUnionErrSetMismatch *error_union_error_set; 124 ConstCastTypeMismatch *type_mismatch; 125 ConstCastArrayMismatch *array_mismatch; 126 ConstCastOnly *return_type; 127 ConstCastOnly *null_wrap_ptr_child; 128 ConstCastArg fn_arg; 129 ConstCastArgNoAlias arg_no_alias; 130 ConstCastBadAllowsZero *bad_allows_zero; 131 ConstCastBadNullTermArrays *sentinel_arrays; 132 ConstCastBadCV *bad_cv; 133 ConstCastPtrSentinel *bad_ptr_sentinel; 134 ConstCastIntShorten *int_shorten; 135 } data; 136 }; 137 138 struct ConstCastTypeMismatch { 139 ZigType *wanted_type; 140 ZigType *actual_type; 141 }; 142 143 struct ConstCastOptionalMismatch { 144 ConstCastOnly child; 145 ZigType *wanted_child; 146 ZigType *actual_child; 147 }; 148 149 struct ConstCastPointerMismatch { 150 ConstCastOnly child; 151 ZigType *wanted_child; 152 ZigType *actual_child; 153 }; 154 155 struct ConstCastSliceMismatch { 156 ConstCastOnly child; 157 ZigType *wanted_child; 158 ZigType *actual_child; 159 }; 160 161 struct ConstCastArrayMismatch { 162 ConstCastOnly child; 163 ZigType *wanted_child; 164 ZigType *actual_child; 165 }; 166 167 struct ConstCastErrUnionErrSetMismatch { 168 ConstCastOnly child; 169 ZigType *wanted_err_set; 170 ZigType *actual_err_set; 171 }; 172 173 struct ConstCastErrUnionPayloadMismatch { 174 ConstCastOnly child; 175 ZigType *wanted_payload; 176 ZigType *actual_payload; 177 }; 178 179 struct ConstCastErrSetMismatch { 180 ZigList<ErrorTableEntry *> missing_errors; 181 }; 182 183 struct ConstCastBadAllowsZero { 184 ZigType *wanted_type; 185 ZigType *actual_type; 186 }; 187 188 struct ConstCastBadNullTermArrays { 189 ConstCastOnly child; 190 ZigType *wanted_type; 191 ZigType *actual_type; 192 }; 193 194 struct ConstCastBadCV { 195 ZigType *wanted_type; 196 ZigType *actual_type; 197 }; 198 199 struct ConstCastPtrSentinel { 200 ZigType *wanted_type; 201 ZigType *actual_type; 202 }; 203 204 struct ConstCastIntShorten { 205 ZigType *wanted_type; 206 ZigType *actual_type; 207 }; 208 209 // for debugging purposes 210 struct DbgIrBreakPoint { 211 const char *src_file; 212 uint32_t line; 213 }; 214 DbgIrBreakPoint dbg_ir_breakpoints_buf[20]; 215 size_t dbg_ir_breakpoints_count = 0; 216 217 static IrInstSrc *ir_gen_node(IrBuilderSrc *irb, AstNode *node, Scope *scope); 218 static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *scope, LVal lval, 219 ResultLoc *result_loc); 220 static IrInstGen *ir_implicit_cast(IrAnalyze *ira, IrInstGen *value, ZigType *expected_type); 221 static IrInstGen *ir_implicit_cast2(IrAnalyze *ira, IrInst *value_source_instr, 222 IrInstGen *value, ZigType *expected_type); 223 static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst *source_instr, IrInstGen *ptr, 224 ResultLoc *result_loc); 225 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutableSrc *exec, AstNode *source_node, Buf *msg); 226 static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 227 IrInst* source_instr, IrInstGen *container_ptr, IrInst *container_ptr_src, 228 ZigType *container_type, bool initializing); 229 static void ir_assert_impl(bool ok, IrInst* source_instruction, const char *file, unsigned int line); 230 static void ir_assert_gen_impl(bool ok, IrInstGen *source_instruction, const char *file, unsigned int line); 231 static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *var); 232 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op); 233 static IrInstSrc *ir_lval_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *value, LVal lval, ResultLoc *result_loc); 234 static IrInstSrc *ir_expr_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *inst, ResultLoc *result_loc); 235 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align); 236 static ZigType *adjust_ptr_const(CodeGen *g, ZigType *ptr_type, bool is_const); 237 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align); 238 static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ZigValue *val); 239 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val); 240 static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 241 ZigValue *out_val, ZigValue *ptr_val); 242 static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr, 243 IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on, 244 bool keep_bigger_alignment); 245 static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed undef_allowed); 246 static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); 247 static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 248 ZigType *ptr_type); 249 static IrInstGen *ir_analyze_bit_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 250 ZigType *dest_type); 251 static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_instr, 252 ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime, bool allow_discard); 253 static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr, 254 ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime, bool allow_discard); 255 static IrInstGen *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInst* source_instr, 256 IrInstGen *base_ptr, bool safety_check_on, bool initializing); 257 static IrInstGen *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInst* source_instr, 258 IrInstGen *base_ptr, bool safety_check_on, bool initializing); 259 static IrInstGen *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInst* source_instr, 260 IrInstGen *base_ptr, bool initializing); 261 static IrInstGen *ir_analyze_store_ptr(IrAnalyze *ira, IrInst* source_instr, 262 IrInstGen *ptr, IrInstGen *uncasted_value, bool allow_write_through_const); 263 static IrInstSrc *ir_gen_union_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 264 IrInstSrc *union_type, IrInstSrc *field_name, AstNode *expr_node, 265 LVal lval, ResultLoc *parent_result_loc); 266 static void ir_reset_result(ResultLoc *result_loc); 267 static Buf *get_anon_type_name(CodeGen *codegen, IrExecutableSrc *exec, const char *kind_name, 268 Scope *scope, AstNode *source_node, Buf *out_bare_name); 269 static ResultLocCast *ir_build_cast_result_loc(IrBuilderSrc *irb, IrInstSrc *dest_type, 270 ResultLoc *parent_result_loc); 271 static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_instr, 272 TypeStructField *field, IrInstGen *struct_ptr, ZigType *struct_type, bool initializing); 273 static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, 274 IrInst* source_instr, IrInstGen *container_ptr, ZigType *container_type); 275 static ResultLoc *no_result_loc(void); 276 static IrInstGen *ir_analyze_test_non_null(IrAnalyze *ira, IrInst *source_inst, IrInstGen *value); 277 static IrInstGen *ir_error_dependency_loop(IrAnalyze *ira, IrInst *source_instr); 278 static IrInstGen *ir_const_undef(IrAnalyze *ira, IrInst *source_instruction, ZigType *ty); 279 static ZigVar *ir_create_var(IrBuilderSrc *irb, AstNode *node, Scope *scope, Buf *name, 280 bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime); 281 static void build_decl_var_and_init(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var, 282 IrInstSrc *init, const char *name_hint, IrInstSrc *is_comptime); 283 static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instruction, 284 AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstGen *field_result_loc, 285 IrInstGen *result_loc); 286 static IrInstGen *ir_analyze_struct_value_field_value(IrAnalyze *ira, IrInst* source_instr, 287 IrInstGen *struct_operand, TypeStructField *field); 288 static bool value_cmp_numeric_val_any(ZigValue *left, Cmp predicate, ZigValue *right); 289 static bool value_cmp_numeric_val_all(ZigValue *left, Cmp predicate, ZigValue *right); 290 static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field); 291 292 #define ir_assert(OK, SOURCE_INSTRUCTION) ir_assert_impl((OK), (SOURCE_INSTRUCTION), __FILE__, __LINE__) 293 #define ir_assert_gen(OK, SOURCE_INSTRUCTION) ir_assert_gen_impl((OK), (SOURCE_INSTRUCTION), __FILE__, __LINE__) 294 295 static void destroy_instruction_src(IrInstSrc *inst) { 296 switch (inst->id) { 297 case IrInstSrcIdInvalid: 298 zig_unreachable(); 299 case IrInstSrcIdReturn: 300 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcReturn *>(inst)); 301 case IrInstSrcIdConst: 302 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcConst *>(inst)); 303 case IrInstSrcIdBinOp: 304 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBinOp *>(inst)); 305 case IrInstSrcIdMergeErrSets: 306 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMergeErrSets *>(inst)); 307 case IrInstSrcIdDeclVar: 308 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcDeclVar *>(inst)); 309 case IrInstSrcIdCall: 310 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCall *>(inst)); 311 case IrInstSrcIdCallExtra: 312 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallExtra *>(inst)); 313 case IrInstSrcIdAsyncCallExtra: 314 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAsyncCallExtra *>(inst)); 315 case IrInstSrcIdUnOp: 316 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnOp *>(inst)); 317 case IrInstSrcIdCondBr: 318 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCondBr *>(inst)); 319 case IrInstSrcIdBr: 320 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBr *>(inst)); 321 case IrInstSrcIdPhi: 322 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPhi *>(inst)); 323 case IrInstSrcIdContainerInitList: 324 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcContainerInitList *>(inst)); 325 case IrInstSrcIdContainerInitFields: 326 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcContainerInitFields *>(inst)); 327 case IrInstSrcIdUnreachable: 328 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnreachable *>(inst)); 329 case IrInstSrcIdElemPtr: 330 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcElemPtr *>(inst)); 331 case IrInstSrcIdVarPtr: 332 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVarPtr *>(inst)); 333 case IrInstSrcIdLoadPtr: 334 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcLoadPtr *>(inst)); 335 case IrInstSrcIdStorePtr: 336 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcStorePtr *>(inst)); 337 case IrInstSrcIdTypeOf: 338 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeOf *>(inst)); 339 case IrInstSrcIdFieldPtr: 340 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFieldPtr *>(inst)); 341 case IrInstSrcIdSetCold: 342 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetCold *>(inst)); 343 case IrInstSrcIdSetRuntimeSafety: 344 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetRuntimeSafety *>(inst)); 345 case IrInstSrcIdSetFloatMode: 346 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetFloatMode *>(inst)); 347 case IrInstSrcIdArrayType: 348 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcArrayType *>(inst)); 349 case IrInstSrcIdSliceType: 350 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSliceType *>(inst)); 351 case IrInstSrcIdAnyFrameType: 352 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAnyFrameType *>(inst)); 353 case IrInstSrcIdAsm: 354 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAsm *>(inst)); 355 case IrInstSrcIdSizeOf: 356 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSizeOf *>(inst)); 357 case IrInstSrcIdTestNonNull: 358 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestNonNull *>(inst)); 359 case IrInstSrcIdOptionalUnwrapPtr: 360 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOptionalUnwrapPtr *>(inst)); 361 case IrInstSrcIdPopCount: 362 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPopCount *>(inst)); 363 case IrInstSrcIdClz: 364 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcClz *>(inst)); 365 case IrInstSrcIdCtz: 366 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCtz *>(inst)); 367 case IrInstSrcIdBswap: 368 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBswap *>(inst)); 369 case IrInstSrcIdBitReverse: 370 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitReverse *>(inst)); 371 case IrInstSrcIdSwitchBr: 372 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchBr *>(inst)); 373 case IrInstSrcIdSwitchVar: 374 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchVar *>(inst)); 375 case IrInstSrcIdSwitchElseVar: 376 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchElseVar *>(inst)); 377 case IrInstSrcIdSwitchTarget: 378 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchTarget *>(inst)); 379 case IrInstSrcIdImport: 380 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcImport *>(inst)); 381 case IrInstSrcIdRef: 382 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcRef *>(inst)); 383 case IrInstSrcIdCompileErr: 384 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCompileErr *>(inst)); 385 case IrInstSrcIdCompileLog: 386 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCompileLog *>(inst)); 387 case IrInstSrcIdErrName: 388 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrName *>(inst)); 389 case IrInstSrcIdCImport: 390 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCImport *>(inst)); 391 case IrInstSrcIdCInclude: 392 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCInclude *>(inst)); 393 case IrInstSrcIdCDefine: 394 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCDefine *>(inst)); 395 case IrInstSrcIdCUndef: 396 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCUndef *>(inst)); 397 case IrInstSrcIdEmbedFile: 398 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEmbedFile *>(inst)); 399 case IrInstSrcIdCmpxchg: 400 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCmpxchg *>(inst)); 401 case IrInstSrcIdFence: 402 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFence *>(inst)); 403 case IrInstSrcIdTruncate: 404 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTruncate *>(inst)); 405 case IrInstSrcIdIntCast: 406 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntCast *>(inst)); 407 case IrInstSrcIdFloatCast: 408 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst)); 409 case IrInstSrcIdErrSetCast: 410 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst)); 411 case IrInstSrcIdIntToFloat: 412 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst)); 413 case IrInstSrcIdFloatToInt: 414 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatToInt *>(inst)); 415 case IrInstSrcIdBoolToInt: 416 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolToInt *>(inst)); 417 case IrInstSrcIdVectorType: 418 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVectorType *>(inst)); 419 case IrInstSrcIdShuffleVector: 420 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcShuffleVector *>(inst)); 421 case IrInstSrcIdSplat: 422 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSplat *>(inst)); 423 case IrInstSrcIdBoolNot: 424 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolNot *>(inst)); 425 case IrInstSrcIdMemset: 426 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemset *>(inst)); 427 case IrInstSrcIdMemcpy: 428 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemcpy *>(inst)); 429 case IrInstSrcIdSlice: 430 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSlice *>(inst)); 431 case IrInstSrcIdBreakpoint: 432 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBreakpoint *>(inst)); 433 case IrInstSrcIdReturnAddress: 434 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcReturnAddress *>(inst)); 435 case IrInstSrcIdFrameAddress: 436 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameAddress *>(inst)); 437 case IrInstSrcIdFrameHandle: 438 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameHandle *>(inst)); 439 case IrInstSrcIdFrameType: 440 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameType *>(inst)); 441 case IrInstSrcIdFrameSize: 442 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameSize *>(inst)); 443 case IrInstSrcIdAlignOf: 444 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlignOf *>(inst)); 445 case IrInstSrcIdOverflowOp: 446 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOverflowOp *>(inst)); 447 case IrInstSrcIdTestErr: 448 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestErr *>(inst)); 449 case IrInstSrcIdUnwrapErrCode: 450 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnwrapErrCode *>(inst)); 451 case IrInstSrcIdUnwrapErrPayload: 452 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnwrapErrPayload *>(inst)); 453 case IrInstSrcIdFnProto: 454 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFnProto *>(inst)); 455 case IrInstSrcIdTestComptime: 456 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestComptime *>(inst)); 457 case IrInstSrcIdPtrCast: 458 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrCast *>(inst)); 459 case IrInstSrcIdBitCast: 460 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitCast *>(inst)); 461 case IrInstSrcIdPtrToInt: 462 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrToInt *>(inst)); 463 case IrInstSrcIdIntToPtr: 464 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToPtr *>(inst)); 465 case IrInstSrcIdIntToEnum: 466 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToEnum *>(inst)); 467 case IrInstSrcIdIntToErr: 468 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToErr *>(inst)); 469 case IrInstSrcIdErrToInt: 470 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrToInt *>(inst)); 471 case IrInstSrcIdCheckSwitchProngs: 472 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckSwitchProngs *>(inst)); 473 case IrInstSrcIdCheckStatementIsVoid: 474 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckStatementIsVoid *>(inst)); 475 case IrInstSrcIdTypeName: 476 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeName *>(inst)); 477 case IrInstSrcIdTagName: 478 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTagName *>(inst)); 479 case IrInstSrcIdPtrType: 480 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrType *>(inst)); 481 case IrInstSrcIdDeclRef: 482 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcDeclRef *>(inst)); 483 case IrInstSrcIdPanic: 484 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPanic *>(inst)); 485 case IrInstSrcIdFieldParentPtr: 486 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFieldParentPtr *>(inst)); 487 case IrInstSrcIdByteOffsetOf: 488 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcByteOffsetOf *>(inst)); 489 case IrInstSrcIdBitOffsetOf: 490 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitOffsetOf *>(inst)); 491 case IrInstSrcIdTypeInfo: 492 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeInfo *>(inst)); 493 case IrInstSrcIdType: 494 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcType *>(inst)); 495 case IrInstSrcIdHasField: 496 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasField *>(inst)); 497 case IrInstSrcIdSetEvalBranchQuota: 498 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetEvalBranchQuota *>(inst)); 499 case IrInstSrcIdAlignCast: 500 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlignCast *>(inst)); 501 case IrInstSrcIdImplicitCast: 502 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcImplicitCast *>(inst)); 503 case IrInstSrcIdResolveResult: 504 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResolveResult *>(inst)); 505 case IrInstSrcIdResetResult: 506 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResetResult *>(inst)); 507 case IrInstSrcIdOpaqueType: 508 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOpaqueType *>(inst)); 509 case IrInstSrcIdSetAlignStack: 510 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetAlignStack *>(inst)); 511 case IrInstSrcIdArgType: 512 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcArgType *>(inst)); 513 case IrInstSrcIdTagType: 514 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTagType *>(inst)); 515 case IrInstSrcIdExport: 516 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcExport *>(inst)); 517 case IrInstSrcIdErrorReturnTrace: 518 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrorReturnTrace *>(inst)); 519 case IrInstSrcIdErrorUnion: 520 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrorUnion *>(inst)); 521 case IrInstSrcIdAtomicRmw: 522 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicRmw *>(inst)); 523 case IrInstSrcIdSaveErrRetAddr: 524 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSaveErrRetAddr *>(inst)); 525 case IrInstSrcIdAddImplicitReturnType: 526 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAddImplicitReturnType *>(inst)); 527 case IrInstSrcIdFloatOp: 528 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatOp *>(inst)); 529 case IrInstSrcIdMulAdd: 530 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMulAdd *>(inst)); 531 case IrInstSrcIdAtomicLoad: 532 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicLoad *>(inst)); 533 case IrInstSrcIdAtomicStore: 534 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicStore *>(inst)); 535 case IrInstSrcIdEnumToInt: 536 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEnumToInt *>(inst)); 537 case IrInstSrcIdCheckRuntimeScope: 538 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckRuntimeScope *>(inst)); 539 case IrInstSrcIdHasDecl: 540 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasDecl *>(inst)); 541 case IrInstSrcIdUndeclaredIdent: 542 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUndeclaredIdent *>(inst)); 543 case IrInstSrcIdAlloca: 544 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlloca *>(inst)); 545 case IrInstSrcIdEndExpr: 546 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEndExpr *>(inst)); 547 case IrInstSrcIdUnionInitNamedField: 548 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnionInitNamedField *>(inst)); 549 case IrInstSrcIdSuspendBegin: 550 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSuspendBegin *>(inst)); 551 case IrInstSrcIdSuspendFinish: 552 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSuspendFinish *>(inst)); 553 case IrInstSrcIdResume: 554 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResume *>(inst)); 555 case IrInstSrcIdAwait: 556 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAwait *>(inst)); 557 case IrInstSrcIdSpillBegin: 558 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSpillBegin *>(inst)); 559 case IrInstSrcIdSpillEnd: 560 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSpillEnd *>(inst)); 561 case IrInstSrcIdCallArgs: 562 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallArgs *>(inst)); 563 case IrInstSrcIdWasmMemorySize: 564 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcWasmMemorySize *>(inst)); 565 case IrInstSrcIdWasmMemoryGrow: 566 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcWasmMemoryGrow *>(inst)); 567 case IrInstSrcIdSrc: 568 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSrc *>(inst)); 569 } 570 zig_unreachable(); 571 } 572 573 void destroy_instruction_gen(IrInstGen *inst) { 574 switch (inst->id) { 575 case IrInstGenIdInvalid: 576 zig_unreachable(); 577 case IrInstGenIdReturn: 578 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenReturn *>(inst)); 579 case IrInstGenIdConst: 580 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenConst *>(inst)); 581 case IrInstGenIdBinOp: 582 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinOp *>(inst)); 583 case IrInstGenIdCast: 584 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCast *>(inst)); 585 case IrInstGenIdCall: 586 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCall *>(inst)); 587 case IrInstGenIdCondBr: 588 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCondBr *>(inst)); 589 case IrInstGenIdBr: 590 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBr *>(inst)); 591 case IrInstGenIdPhi: 592 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPhi *>(inst)); 593 case IrInstGenIdUnreachable: 594 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnreachable *>(inst)); 595 case IrInstGenIdElemPtr: 596 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenElemPtr *>(inst)); 597 case IrInstGenIdVarPtr: 598 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVarPtr *>(inst)); 599 case IrInstGenIdReturnPtr: 600 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenReturnPtr *>(inst)); 601 case IrInstGenIdLoadPtr: 602 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenLoadPtr *>(inst)); 603 case IrInstGenIdStorePtr: 604 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenStorePtr *>(inst)); 605 case IrInstGenIdVectorStoreElem: 606 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVectorStoreElem *>(inst)); 607 case IrInstGenIdStructFieldPtr: 608 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenStructFieldPtr *>(inst)); 609 case IrInstGenIdUnionFieldPtr: 610 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnionFieldPtr *>(inst)); 611 case IrInstGenIdAsm: 612 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAsm *>(inst)); 613 case IrInstGenIdTestNonNull: 614 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTestNonNull *>(inst)); 615 case IrInstGenIdOptionalUnwrapPtr: 616 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenOptionalUnwrapPtr *>(inst)); 617 case IrInstGenIdPopCount: 618 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPopCount *>(inst)); 619 case IrInstGenIdClz: 620 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenClz *>(inst)); 621 case IrInstGenIdCtz: 622 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCtz *>(inst)); 623 case IrInstGenIdBswap: 624 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBswap *>(inst)); 625 case IrInstGenIdBitReverse: 626 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBitReverse *>(inst)); 627 case IrInstGenIdSwitchBr: 628 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSwitchBr *>(inst)); 629 case IrInstGenIdUnionTag: 630 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnionTag *>(inst)); 631 case IrInstGenIdRef: 632 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenRef *>(inst)); 633 case IrInstGenIdErrName: 634 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrName *>(inst)); 635 case IrInstGenIdCmpxchg: 636 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCmpxchg *>(inst)); 637 case IrInstGenIdFence: 638 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFence *>(inst)); 639 case IrInstGenIdTruncate: 640 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTruncate *>(inst)); 641 case IrInstGenIdShuffleVector: 642 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenShuffleVector *>(inst)); 643 case IrInstGenIdSplat: 644 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSplat *>(inst)); 645 case IrInstGenIdBoolNot: 646 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBoolNot *>(inst)); 647 case IrInstGenIdMemset: 648 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenMemset *>(inst)); 649 case IrInstGenIdMemcpy: 650 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenMemcpy *>(inst)); 651 case IrInstGenIdSlice: 652 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSlice *>(inst)); 653 case IrInstGenIdBreakpoint: 654 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBreakpoint *>(inst)); 655 case IrInstGenIdReturnAddress: 656 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenReturnAddress *>(inst)); 657 case IrInstGenIdFrameAddress: 658 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFrameAddress *>(inst)); 659 case IrInstGenIdFrameHandle: 660 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFrameHandle *>(inst)); 661 case IrInstGenIdFrameSize: 662 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFrameSize *>(inst)); 663 case IrInstGenIdOverflowOp: 664 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenOverflowOp *>(inst)); 665 case IrInstGenIdTestErr: 666 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTestErr *>(inst)); 667 case IrInstGenIdUnwrapErrCode: 668 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnwrapErrCode *>(inst)); 669 case IrInstGenIdUnwrapErrPayload: 670 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnwrapErrPayload *>(inst)); 671 case IrInstGenIdOptionalWrap: 672 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenOptionalWrap *>(inst)); 673 case IrInstGenIdErrWrapCode: 674 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrWrapCode *>(inst)); 675 case IrInstGenIdErrWrapPayload: 676 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrWrapPayload *>(inst)); 677 case IrInstGenIdPtrCast: 678 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPtrCast *>(inst)); 679 case IrInstGenIdBitCast: 680 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBitCast *>(inst)); 681 case IrInstGenIdWidenOrShorten: 682 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWidenOrShorten *>(inst)); 683 case IrInstGenIdPtrToInt: 684 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPtrToInt *>(inst)); 685 case IrInstGenIdIntToPtr: 686 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenIntToPtr *>(inst)); 687 case IrInstGenIdIntToEnum: 688 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenIntToEnum *>(inst)); 689 case IrInstGenIdIntToErr: 690 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenIntToErr *>(inst)); 691 case IrInstGenIdErrToInt: 692 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrToInt *>(inst)); 693 case IrInstGenIdTagName: 694 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTagName *>(inst)); 695 case IrInstGenIdPanic: 696 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPanic *>(inst)); 697 case IrInstGenIdFieldParentPtr: 698 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFieldParentPtr *>(inst)); 699 case IrInstGenIdAlignCast: 700 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlignCast *>(inst)); 701 case IrInstGenIdErrorReturnTrace: 702 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrorReturnTrace *>(inst)); 703 case IrInstGenIdAtomicRmw: 704 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAtomicRmw *>(inst)); 705 case IrInstGenIdSaveErrRetAddr: 706 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSaveErrRetAddr *>(inst)); 707 case IrInstGenIdFloatOp: 708 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFloatOp *>(inst)); 709 case IrInstGenIdMulAdd: 710 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenMulAdd *>(inst)); 711 case IrInstGenIdAtomicLoad: 712 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAtomicLoad *>(inst)); 713 case IrInstGenIdAtomicStore: 714 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAtomicStore *>(inst)); 715 case IrInstGenIdDeclVar: 716 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenDeclVar *>(inst)); 717 case IrInstGenIdArrayToVector: 718 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenArrayToVector *>(inst)); 719 case IrInstGenIdVectorToArray: 720 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVectorToArray *>(inst)); 721 case IrInstGenIdPtrOfArrayToSlice: 722 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPtrOfArrayToSlice *>(inst)); 723 case IrInstGenIdAssertZero: 724 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertZero *>(inst)); 725 case IrInstGenIdAssertNonNull: 726 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertNonNull *>(inst)); 727 case IrInstGenIdAlloca: 728 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlloca *>(inst)); 729 case IrInstGenIdSuspendBegin: 730 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSuspendBegin *>(inst)); 731 case IrInstGenIdSuspendFinish: 732 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSuspendFinish *>(inst)); 733 case IrInstGenIdResume: 734 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenResume *>(inst)); 735 case IrInstGenIdAwait: 736 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAwait *>(inst)); 737 case IrInstGenIdSpillBegin: 738 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSpillBegin *>(inst)); 739 case IrInstGenIdSpillEnd: 740 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSpillEnd *>(inst)); 741 case IrInstGenIdVectorExtractElem: 742 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVectorExtractElem *>(inst)); 743 case IrInstGenIdBinaryNot: 744 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinaryNot *>(inst)); 745 case IrInstGenIdNegation: 746 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegation *>(inst)); 747 case IrInstGenIdNegationWrapping: 748 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegationWrapping *>(inst)); 749 case IrInstGenIdWasmMemorySize: 750 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWasmMemorySize *>(inst)); 751 case IrInstGenIdWasmMemoryGrow: 752 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWasmMemoryGrow *>(inst)); 753 } 754 zig_unreachable(); 755 } 756 757 static void ira_ref(IrAnalyze *ira) { 758 ira->ref_count += 1; 759 } 760 static void ira_deref(IrAnalyze *ira) { 761 if (ira->ref_count > 1) { 762 ira->ref_count -= 1; 763 764 // immediate destruction of dangling IrInstGenConst is not possible 765 // free tracking memory because it will never be used 766 ira->new_irb.constants.deinit(&heap::c_allocator); 767 return; 768 } 769 assert(ira->ref_count != 0); 770 771 for (size_t bb_i = 0; bb_i < ira->old_irb.exec->basic_block_list.length; bb_i += 1) { 772 IrBasicBlockSrc *pass1_bb = ira->old_irb.exec->basic_block_list.items[bb_i]; 773 for (size_t inst_i = 0; inst_i < pass1_bb->instruction_list.length; inst_i += 1) { 774 IrInstSrc *pass1_inst = pass1_bb->instruction_list.items[inst_i]; 775 destroy_instruction_src(pass1_inst); 776 } 777 heap::c_allocator.destroy(pass1_bb); 778 } 779 ira->old_irb.exec->basic_block_list.deinit(); 780 ira->old_irb.exec->tld_list.deinit(); 781 heap::c_allocator.destroy(ira->old_irb.exec); 782 ira->src_implicit_return_type_list.deinit(); 783 ira->resume_stack.deinit(); 784 785 // destroy dangling IrInstGenConst 786 for (size_t i = 0; i < ira->new_irb.constants.length; i += 1) { 787 auto constant = ira->new_irb.constants.items[i]; 788 if (constant->base.base.ref_count == 0 && !ir_inst_gen_has_side_effects(&constant->base)) 789 destroy_instruction_gen(&constant->base); 790 } 791 ira->new_irb.constants.deinit(&heap::c_allocator); 792 793 heap::c_allocator.destroy(ira); 794 } 795 796 static ZigValue *const_ptr_pointee_unchecked_no_isf(CodeGen *g, ZigValue *const_val) { 797 assert(get_src_ptr_type(const_val->type) != nullptr); 798 assert(const_val->special == ConstValSpecialStatic); 799 800 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { 801 case OnePossibleValueInvalid: 802 return nullptr; 803 case OnePossibleValueYes: 804 return get_the_one_possible_value(g, const_val->type->data.pointer.child_type); 805 case OnePossibleValueNo: 806 break; 807 } 808 809 ZigValue *result; 810 switch (const_val->data.x_ptr.special) { 811 case ConstPtrSpecialInvalid: 812 zig_unreachable(); 813 case ConstPtrSpecialRef: 814 result = const_val->data.x_ptr.data.ref.pointee; 815 break; 816 case ConstPtrSpecialBaseArray: { 817 ZigValue *array_val = const_val->data.x_ptr.data.base_array.array_val; 818 size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index; 819 if (elem_index == array_val->type->data.array.len) { 820 result = array_val->type->data.array.sentinel; 821 } else { 822 expand_undef_array(g, array_val); 823 result = &array_val->data.x_array.data.s_none.elements[elem_index]; 824 } 825 break; 826 } 827 case ConstPtrSpecialSubArray: { 828 ZigValue *array_val = const_val->data.x_ptr.data.base_array.array_val; 829 size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index; 830 831 expand_undef_array(g, array_val); 832 result = g->pass1_arena->create<ZigValue>(); 833 result->special = array_val->special; 834 result->type = get_array_type(g, array_val->type->data.array.child_type, 835 array_val->type->data.array.len - elem_index, array_val->type->data.array.sentinel); 836 result->data.x_array.special = ConstArraySpecialNone; 837 result->data.x_array.data.s_none.elements = &array_val->data.x_array.data.s_none.elements[elem_index]; 838 result->parent.id = ConstParentIdArray; 839 result->parent.data.p_array.array_val = array_val; 840 result->parent.data.p_array.elem_index = elem_index; 841 break; 842 } 843 case ConstPtrSpecialBaseStruct: { 844 ZigValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val; 845 expand_undef_struct(g, struct_val); 846 result = struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index]; 847 break; 848 } 849 case ConstPtrSpecialBaseErrorUnionCode: 850 result = const_val->data.x_ptr.data.base_err_union_code.err_union_val->data.x_err_union.error_set; 851 break; 852 case ConstPtrSpecialBaseErrorUnionPayload: 853 result = const_val->data.x_ptr.data.base_err_union_payload.err_union_val->data.x_err_union.payload; 854 break; 855 case ConstPtrSpecialBaseOptionalPayload: 856 result = const_val->data.x_ptr.data.base_optional_payload.optional_val->data.x_optional; 857 break; 858 case ConstPtrSpecialNull: 859 result = const_val; 860 break; 861 case ConstPtrSpecialHardCodedAddr: 862 zig_unreachable(); 863 case ConstPtrSpecialDiscard: 864 zig_unreachable(); 865 case ConstPtrSpecialFunction: 866 zig_unreachable(); 867 } 868 assert(result != nullptr); 869 return result; 870 } 871 872 static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) { 873 assert(get_src_ptr_type(const_val->type) != nullptr); 874 assert(const_val->special == ConstValSpecialStatic); 875 876 InferredStructField *isf = const_val->type->data.pointer.inferred_struct_field; 877 if (isf != nullptr) { 878 TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); 879 assert(field != nullptr); 880 if (field->is_comptime) { 881 assert(field->init_val != nullptr); 882 return field->init_val; 883 } 884 ZigValue *struct_val = const_ptr_pointee_unchecked_no_isf(g, const_val); 885 assert(struct_val->type->id == ZigTypeIdStruct); 886 return struct_val->data.x_struct.fields[field->src_index]; 887 } 888 889 return const_ptr_pointee_unchecked_no_isf(g, const_val); 890 } 891 892 static bool is_tuple(ZigType *type) { 893 return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialInferredTuple; 894 } 895 896 static bool is_slice(ZigType *type) { 897 return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialSlice; 898 } 899 900 // This function returns true when you can change the type of a ZigValue and the 901 // value remains meaningful. 902 static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expected, ZigType *actual) { 903 if (expected == actual) 904 return true; 905 906 if (get_src_ptr_type(expected) != nullptr && get_src_ptr_type(actual) != nullptr) 907 return true; 908 909 if (is_opt_err_set(expected) && is_opt_err_set(actual)) 910 return true; 911 912 if (expected->id != actual->id) 913 return false; 914 915 switch (expected->id) { 916 case ZigTypeIdInvalid: 917 case ZigTypeIdUnreachable: 918 zig_unreachable(); 919 case ZigTypeIdMetaType: 920 case ZigTypeIdVoid: 921 case ZigTypeIdBool: 922 case ZigTypeIdComptimeFloat: 923 case ZigTypeIdComptimeInt: 924 case ZigTypeIdEnumLiteral: 925 case ZigTypeIdUndefined: 926 case ZigTypeIdNull: 927 case ZigTypeIdBoundFn: 928 case ZigTypeIdErrorSet: 929 case ZigTypeIdOpaque: 930 case ZigTypeIdAnyFrame: 931 case ZigTypeIdFn: 932 return true; 933 case ZigTypeIdPointer: 934 return expected->data.pointer.inferred_struct_field == actual->data.pointer.inferred_struct_field; 935 case ZigTypeIdFloat: 936 return expected->data.floating.bit_count == actual->data.floating.bit_count; 937 case ZigTypeIdInt: 938 return expected->data.integral.is_signed == actual->data.integral.is_signed; 939 case ZigTypeIdStruct: 940 return is_slice(expected) && is_slice(actual); 941 case ZigTypeIdOptional: 942 case ZigTypeIdErrorUnion: 943 case ZigTypeIdEnum: 944 case ZigTypeIdUnion: 945 case ZigTypeIdVector: 946 case ZigTypeIdFnFrame: 947 return false; 948 case ZigTypeIdArray: 949 return expected->data.array.len == actual->data.array.len && 950 expected->data.array.child_type == actual->data.array.child_type && 951 (expected->data.array.sentinel == nullptr || (actual->data.array.sentinel != nullptr && 952 const_values_equal(codegen, expected->data.array.sentinel, actual->data.array.sentinel))); 953 } 954 zig_unreachable(); 955 } 956 957 static bool ir_should_inline(IrExecutableSrc *exec, Scope *scope) { 958 if (exec->is_inline) 959 return true; 960 961 while (scope != nullptr) { 962 if (scope->id == ScopeIdCompTime) 963 return true; 964 if (scope->id == ScopeIdTypeOf) 965 return false; 966 if (scope->id == ScopeIdFnDef) 967 break; 968 scope = scope->parent; 969 } 970 return false; 971 } 972 973 static void ir_instruction_append(IrBasicBlockSrc *basic_block, IrInstSrc *instruction) { 974 assert(basic_block); 975 assert(instruction); 976 basic_block->instruction_list.append(instruction); 977 } 978 979 static void ir_inst_gen_append(IrBasicBlockGen *basic_block, IrInstGen *instruction) { 980 assert(basic_block); 981 assert(instruction); 982 basic_block->instruction_list.append(instruction); 983 } 984 985 static size_t exec_next_debug_id(IrExecutableSrc *exec) { 986 size_t result = exec->next_debug_id; 987 exec->next_debug_id += 1; 988 return result; 989 } 990 991 static size_t exec_next_debug_id_gen(IrExecutableGen *exec) { 992 size_t result = exec->next_debug_id; 993 exec->next_debug_id += 1; 994 return result; 995 } 996 997 static ZigFn *exec_fn_entry(IrExecutableSrc *exec) { 998 return exec->fn_entry; 999 } 1000 1001 static Buf *exec_c_import_buf(IrExecutableSrc *exec) { 1002 return exec->c_import_buf; 1003 } 1004 1005 static bool value_is_comptime(ZigValue *const_val) { 1006 return const_val->special != ConstValSpecialRuntime; 1007 } 1008 1009 static bool instr_is_comptime(IrInstGen *instruction) { 1010 return value_is_comptime(instruction->value); 1011 } 1012 1013 static bool instr_is_unreachable(IrInstSrc *instruction) { 1014 return instruction->is_noreturn; 1015 } 1016 1017 static void ir_ref_bb(IrBasicBlockSrc *bb) { 1018 bb->ref_count += 1; 1019 } 1020 1021 static void ir_ref_instruction(IrInstSrc *instruction, IrBasicBlockSrc *cur_bb) { 1022 assert(instruction->id != IrInstSrcIdInvalid); 1023 instruction->base.ref_count += 1; 1024 if (instruction->owner_bb != cur_bb && !instr_is_unreachable(instruction) 1025 && instruction->id != IrInstSrcIdConst) 1026 { 1027 ir_ref_bb(instruction->owner_bb); 1028 } 1029 } 1030 1031 static void ir_ref_inst_gen(IrInstGen *instruction) { 1032 assert(instruction->id != IrInstGenIdInvalid); 1033 instruction->base.ref_count += 1; 1034 } 1035 1036 static void ir_ref_var(ZigVar *var) { 1037 var->ref_count += 1; 1038 } 1039 1040 static void create_result_ptr(CodeGen *codegen, ZigType *expected_type, 1041 ZigValue **out_result, ZigValue **out_result_ptr) 1042 { 1043 ZigValue *result = codegen->pass1_arena->create<ZigValue>(); 1044 ZigValue *result_ptr = codegen->pass1_arena->create<ZigValue>(); 1045 result->special = ConstValSpecialUndef; 1046 result->type = expected_type; 1047 result_ptr->special = ConstValSpecialStatic; 1048 result_ptr->type = get_pointer_to_type(codegen, result->type, false); 1049 result_ptr->data.x_ptr.mut = ConstPtrMutComptimeVar; 1050 result_ptr->data.x_ptr.special = ConstPtrSpecialRef; 1051 result_ptr->data.x_ptr.data.ref.pointee = result; 1052 1053 *out_result = result; 1054 *out_result_ptr = result_ptr; 1055 } 1056 1057 ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) { 1058 Error err; 1059 1060 ZigValue *result; 1061 ZigValue *result_ptr; 1062 create_result_ptr(ira->codegen, ira->codegen->builtin_types.entry_type, &result, &result_ptr); 1063 1064 if ((err = ir_eval_const_value(ira->codegen, scope, node, result_ptr, 1065 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 1066 nullptr, nullptr, node, nullptr, ira->new_irb.exec, nullptr, UndefBad))) 1067 { 1068 return ira->codegen->builtin_types.entry_invalid; 1069 } 1070 if (type_is_invalid(result->type)) 1071 return ira->codegen->builtin_types.entry_invalid; 1072 1073 assert(result->special != ConstValSpecialRuntime); 1074 ZigType *res_type = result->data.x_type; 1075 1076 return res_type; 1077 } 1078 1079 static IrBasicBlockSrc *ir_create_basic_block(IrBuilderSrc *irb, Scope *scope, const char *name_hint) { 1080 IrBasicBlockSrc *result = heap::c_allocator.create<IrBasicBlockSrc>(); 1081 result->scope = scope; 1082 result->name_hint = name_hint; 1083 result->debug_id = exec_next_debug_id(irb->exec); 1084 result->index = UINT32_MAX; // set later 1085 return result; 1086 } 1087 1088 static IrBasicBlockGen *ir_create_basic_block_gen(IrAnalyze *ira, Scope *scope, const char *name_hint) { 1089 IrBasicBlockGen *result = heap::c_allocator.create<IrBasicBlockGen>(); 1090 result->scope = scope; 1091 result->name_hint = name_hint; 1092 result->debug_id = exec_next_debug_id_gen(ira->new_irb.exec); 1093 return result; 1094 } 1095 1096 static IrBasicBlockGen *ir_build_bb_from(IrAnalyze *ira, IrBasicBlockSrc *other_bb) { 1097 IrBasicBlockGen *new_bb = ir_create_basic_block_gen(ira, other_bb->scope, other_bb->name_hint); 1098 other_bb->child = new_bb; 1099 return new_bb; 1100 } 1101 1102 static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclVar *) { 1103 return IrInstSrcIdDeclVar; 1104 } 1105 1106 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBr *) { 1107 return IrInstSrcIdBr; 1108 } 1109 1110 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCondBr *) { 1111 return IrInstSrcIdCondBr; 1112 } 1113 1114 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchBr *) { 1115 return IrInstSrcIdSwitchBr; 1116 } 1117 1118 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchVar *) { 1119 return IrInstSrcIdSwitchVar; 1120 } 1121 1122 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchElseVar *) { 1123 return IrInstSrcIdSwitchElseVar; 1124 } 1125 1126 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchTarget *) { 1127 return IrInstSrcIdSwitchTarget; 1128 } 1129 1130 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPhi *) { 1131 return IrInstSrcIdPhi; 1132 } 1133 1134 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnOp *) { 1135 return IrInstSrcIdUnOp; 1136 } 1137 1138 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBinOp *) { 1139 return IrInstSrcIdBinOp; 1140 } 1141 1142 static constexpr IrInstSrcId ir_inst_id(IrInstSrcMergeErrSets *) { 1143 return IrInstSrcIdMergeErrSets; 1144 } 1145 1146 static constexpr IrInstSrcId ir_inst_id(IrInstSrcLoadPtr *) { 1147 return IrInstSrcIdLoadPtr; 1148 } 1149 1150 static constexpr IrInstSrcId ir_inst_id(IrInstSrcStorePtr *) { 1151 return IrInstSrcIdStorePtr; 1152 } 1153 1154 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldPtr *) { 1155 return IrInstSrcIdFieldPtr; 1156 } 1157 1158 static constexpr IrInstSrcId ir_inst_id(IrInstSrcElemPtr *) { 1159 return IrInstSrcIdElemPtr; 1160 } 1161 1162 static constexpr IrInstSrcId ir_inst_id(IrInstSrcVarPtr *) { 1163 return IrInstSrcIdVarPtr; 1164 } 1165 1166 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCall *) { 1167 return IrInstSrcIdCall; 1168 } 1169 1170 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallArgs *) { 1171 return IrInstSrcIdCallArgs; 1172 } 1173 1174 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallExtra *) { 1175 return IrInstSrcIdCallExtra; 1176 } 1177 1178 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAsyncCallExtra *) { 1179 return IrInstSrcIdAsyncCallExtra; 1180 } 1181 1182 static constexpr IrInstSrcId ir_inst_id(IrInstSrcConst *) { 1183 return IrInstSrcIdConst; 1184 } 1185 1186 static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturn *) { 1187 return IrInstSrcIdReturn; 1188 } 1189 1190 static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitList *) { 1191 return IrInstSrcIdContainerInitList; 1192 } 1193 1194 static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitFields *) { 1195 return IrInstSrcIdContainerInitFields; 1196 } 1197 1198 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnreachable *) { 1199 return IrInstSrcIdUnreachable; 1200 } 1201 1202 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeOf *) { 1203 return IrInstSrcIdTypeOf; 1204 } 1205 1206 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetCold *) { 1207 return IrInstSrcIdSetCold; 1208 } 1209 1210 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetRuntimeSafety *) { 1211 return IrInstSrcIdSetRuntimeSafety; 1212 } 1213 1214 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetFloatMode *) { 1215 return IrInstSrcIdSetFloatMode; 1216 } 1217 1218 static constexpr IrInstSrcId ir_inst_id(IrInstSrcArrayType *) { 1219 return IrInstSrcIdArrayType; 1220 } 1221 1222 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAnyFrameType *) { 1223 return IrInstSrcIdAnyFrameType; 1224 } 1225 1226 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSliceType *) { 1227 return IrInstSrcIdSliceType; 1228 } 1229 1230 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAsm *) { 1231 return IrInstSrcIdAsm; 1232 } 1233 1234 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSizeOf *) { 1235 return IrInstSrcIdSizeOf; 1236 } 1237 1238 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestNonNull *) { 1239 return IrInstSrcIdTestNonNull; 1240 } 1241 1242 static constexpr IrInstSrcId ir_inst_id(IrInstSrcOptionalUnwrapPtr *) { 1243 return IrInstSrcIdOptionalUnwrapPtr; 1244 } 1245 1246 static constexpr IrInstSrcId ir_inst_id(IrInstSrcClz *) { 1247 return IrInstSrcIdClz; 1248 } 1249 1250 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCtz *) { 1251 return IrInstSrcIdCtz; 1252 } 1253 1254 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPopCount *) { 1255 return IrInstSrcIdPopCount; 1256 } 1257 1258 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBswap *) { 1259 return IrInstSrcIdBswap; 1260 } 1261 1262 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitReverse *) { 1263 return IrInstSrcIdBitReverse; 1264 } 1265 1266 static constexpr IrInstSrcId ir_inst_id(IrInstSrcImport *) { 1267 return IrInstSrcIdImport; 1268 } 1269 1270 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCImport *) { 1271 return IrInstSrcIdCImport; 1272 } 1273 1274 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCInclude *) { 1275 return IrInstSrcIdCInclude; 1276 } 1277 1278 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCDefine *) { 1279 return IrInstSrcIdCDefine; 1280 } 1281 1282 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCUndef *) { 1283 return IrInstSrcIdCUndef; 1284 } 1285 1286 static constexpr IrInstSrcId ir_inst_id(IrInstSrcRef *) { 1287 return IrInstSrcIdRef; 1288 } 1289 1290 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileErr *) { 1291 return IrInstSrcIdCompileErr; 1292 } 1293 1294 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileLog *) { 1295 return IrInstSrcIdCompileLog; 1296 } 1297 1298 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrName *) { 1299 return IrInstSrcIdErrName; 1300 } 1301 1302 static constexpr IrInstSrcId ir_inst_id(IrInstSrcEmbedFile *) { 1303 return IrInstSrcIdEmbedFile; 1304 } 1305 1306 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCmpxchg *) { 1307 return IrInstSrcIdCmpxchg; 1308 } 1309 1310 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFence *) { 1311 return IrInstSrcIdFence; 1312 } 1313 1314 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTruncate *) { 1315 return IrInstSrcIdTruncate; 1316 } 1317 1318 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntCast *) { 1319 return IrInstSrcIdIntCast; 1320 } 1321 1322 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatCast *) { 1323 return IrInstSrcIdFloatCast; 1324 } 1325 1326 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToFloat *) { 1327 return IrInstSrcIdIntToFloat; 1328 } 1329 1330 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatToInt *) { 1331 return IrInstSrcIdFloatToInt; 1332 } 1333 1334 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolToInt *) { 1335 return IrInstSrcIdBoolToInt; 1336 } 1337 1338 static constexpr IrInstSrcId ir_inst_id(IrInstSrcVectorType *) { 1339 return IrInstSrcIdVectorType; 1340 } 1341 1342 static constexpr IrInstSrcId ir_inst_id(IrInstSrcShuffleVector *) { 1343 return IrInstSrcIdShuffleVector; 1344 } 1345 1346 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSplat *) { 1347 return IrInstSrcIdSplat; 1348 } 1349 1350 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolNot *) { 1351 return IrInstSrcIdBoolNot; 1352 } 1353 1354 static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemset *) { 1355 return IrInstSrcIdMemset; 1356 } 1357 1358 static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemcpy *) { 1359 return IrInstSrcIdMemcpy; 1360 } 1361 1362 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSlice *) { 1363 return IrInstSrcIdSlice; 1364 } 1365 1366 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBreakpoint *) { 1367 return IrInstSrcIdBreakpoint; 1368 } 1369 1370 static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturnAddress *) { 1371 return IrInstSrcIdReturnAddress; 1372 } 1373 1374 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameAddress *) { 1375 return IrInstSrcIdFrameAddress; 1376 } 1377 1378 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameHandle *) { 1379 return IrInstSrcIdFrameHandle; 1380 } 1381 1382 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameType *) { 1383 return IrInstSrcIdFrameType; 1384 } 1385 1386 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameSize *) { 1387 return IrInstSrcIdFrameSize; 1388 } 1389 1390 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignOf *) { 1391 return IrInstSrcIdAlignOf; 1392 } 1393 1394 static constexpr IrInstSrcId ir_inst_id(IrInstSrcOverflowOp *) { 1395 return IrInstSrcIdOverflowOp; 1396 } 1397 1398 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestErr *) { 1399 return IrInstSrcIdTestErr; 1400 } 1401 1402 static constexpr IrInstSrcId ir_inst_id(IrInstSrcMulAdd *) { 1403 return IrInstSrcIdMulAdd; 1404 } 1405 1406 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatOp *) { 1407 return IrInstSrcIdFloatOp; 1408 } 1409 1410 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrCode *) { 1411 return IrInstSrcIdUnwrapErrCode; 1412 } 1413 1414 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrPayload *) { 1415 return IrInstSrcIdUnwrapErrPayload; 1416 } 1417 1418 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFnProto *) { 1419 return IrInstSrcIdFnProto; 1420 } 1421 1422 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestComptime *) { 1423 return IrInstSrcIdTestComptime; 1424 } 1425 1426 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrCast *) { 1427 return IrInstSrcIdPtrCast; 1428 } 1429 1430 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitCast *) { 1431 return IrInstSrcIdBitCast; 1432 } 1433 1434 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToPtr *) { 1435 return IrInstSrcIdIntToPtr; 1436 } 1437 1438 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrToInt *) { 1439 return IrInstSrcIdPtrToInt; 1440 } 1441 1442 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToEnum *) { 1443 return IrInstSrcIdIntToEnum; 1444 } 1445 1446 static constexpr IrInstSrcId ir_inst_id(IrInstSrcEnumToInt *) { 1447 return IrInstSrcIdEnumToInt; 1448 } 1449 1450 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToErr *) { 1451 return IrInstSrcIdIntToErr; 1452 } 1453 1454 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrToInt *) { 1455 return IrInstSrcIdErrToInt; 1456 } 1457 1458 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckSwitchProngs *) { 1459 return IrInstSrcIdCheckSwitchProngs; 1460 } 1461 1462 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckStatementIsVoid *) { 1463 return IrInstSrcIdCheckStatementIsVoid; 1464 } 1465 1466 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeName *) { 1467 return IrInstSrcIdTypeName; 1468 } 1469 1470 static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclRef *) { 1471 return IrInstSrcIdDeclRef; 1472 } 1473 1474 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPanic *) { 1475 return IrInstSrcIdPanic; 1476 } 1477 1478 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTagName *) { 1479 return IrInstSrcIdTagName; 1480 } 1481 1482 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTagType *) { 1483 return IrInstSrcIdTagType; 1484 } 1485 1486 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldParentPtr *) { 1487 return IrInstSrcIdFieldParentPtr; 1488 } 1489 1490 static constexpr IrInstSrcId ir_inst_id(IrInstSrcByteOffsetOf *) { 1491 return IrInstSrcIdByteOffsetOf; 1492 } 1493 1494 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitOffsetOf *) { 1495 return IrInstSrcIdBitOffsetOf; 1496 } 1497 1498 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeInfo *) { 1499 return IrInstSrcIdTypeInfo; 1500 } 1501 1502 static constexpr IrInstSrcId ir_inst_id(IrInstSrcType *) { 1503 return IrInstSrcIdType; 1504 } 1505 1506 static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasField *) { 1507 return IrInstSrcIdHasField; 1508 } 1509 1510 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetEvalBranchQuota *) { 1511 return IrInstSrcIdSetEvalBranchQuota; 1512 } 1513 1514 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrType *) { 1515 return IrInstSrcIdPtrType; 1516 } 1517 1518 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignCast *) { 1519 return IrInstSrcIdAlignCast; 1520 } 1521 1522 static constexpr IrInstSrcId ir_inst_id(IrInstSrcImplicitCast *) { 1523 return IrInstSrcIdImplicitCast; 1524 } 1525 1526 static constexpr IrInstSrcId ir_inst_id(IrInstSrcResolveResult *) { 1527 return IrInstSrcIdResolveResult; 1528 } 1529 1530 static constexpr IrInstSrcId ir_inst_id(IrInstSrcResetResult *) { 1531 return IrInstSrcIdResetResult; 1532 } 1533 1534 static constexpr IrInstSrcId ir_inst_id(IrInstSrcOpaqueType *) { 1535 return IrInstSrcIdOpaqueType; 1536 } 1537 1538 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetAlignStack *) { 1539 return IrInstSrcIdSetAlignStack; 1540 } 1541 1542 static constexpr IrInstSrcId ir_inst_id(IrInstSrcArgType *) { 1543 return IrInstSrcIdArgType; 1544 } 1545 1546 static constexpr IrInstSrcId ir_inst_id(IrInstSrcExport *) { 1547 return IrInstSrcIdExport; 1548 } 1549 1550 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorReturnTrace *) { 1551 return IrInstSrcIdErrorReturnTrace; 1552 } 1553 1554 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorUnion *) { 1555 return IrInstSrcIdErrorUnion; 1556 } 1557 1558 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicRmw *) { 1559 return IrInstSrcIdAtomicRmw; 1560 } 1561 1562 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicLoad *) { 1563 return IrInstSrcIdAtomicLoad; 1564 } 1565 1566 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicStore *) { 1567 return IrInstSrcIdAtomicStore; 1568 } 1569 1570 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSaveErrRetAddr *) { 1571 return IrInstSrcIdSaveErrRetAddr; 1572 } 1573 1574 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAddImplicitReturnType *) { 1575 return IrInstSrcIdAddImplicitReturnType; 1576 } 1577 1578 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrSetCast *) { 1579 return IrInstSrcIdErrSetCast; 1580 } 1581 1582 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckRuntimeScope *) { 1583 return IrInstSrcIdCheckRuntimeScope; 1584 } 1585 1586 static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasDecl *) { 1587 return IrInstSrcIdHasDecl; 1588 } 1589 1590 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUndeclaredIdent *) { 1591 return IrInstSrcIdUndeclaredIdent; 1592 } 1593 1594 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlloca *) { 1595 return IrInstSrcIdAlloca; 1596 } 1597 1598 static constexpr IrInstSrcId ir_inst_id(IrInstSrcEndExpr *) { 1599 return IrInstSrcIdEndExpr; 1600 } 1601 1602 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnionInitNamedField *) { 1603 return IrInstSrcIdUnionInitNamedField; 1604 } 1605 1606 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSuspendBegin *) { 1607 return IrInstSrcIdSuspendBegin; 1608 } 1609 1610 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSuspendFinish *) { 1611 return IrInstSrcIdSuspendFinish; 1612 } 1613 1614 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAwait *) { 1615 return IrInstSrcIdAwait; 1616 } 1617 1618 static constexpr IrInstSrcId ir_inst_id(IrInstSrcResume *) { 1619 return IrInstSrcIdResume; 1620 } 1621 1622 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSpillBegin *) { 1623 return IrInstSrcIdSpillBegin; 1624 } 1625 1626 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSpillEnd *) { 1627 return IrInstSrcIdSpillEnd; 1628 } 1629 1630 static constexpr IrInstSrcId ir_inst_id(IrInstSrcWasmMemorySize *) { 1631 return IrInstSrcIdWasmMemorySize; 1632 } 1633 1634 static constexpr IrInstSrcId ir_inst_id(IrInstSrcWasmMemoryGrow *) { 1635 return IrInstSrcIdWasmMemoryGrow; 1636 } 1637 1638 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSrc *) { 1639 return IrInstSrcIdSrc; 1640 } 1641 1642 static constexpr IrInstGenId ir_inst_id(IrInstGenDeclVar *) { 1643 return IrInstGenIdDeclVar; 1644 } 1645 1646 static constexpr IrInstGenId ir_inst_id(IrInstGenBr *) { 1647 return IrInstGenIdBr; 1648 } 1649 1650 static constexpr IrInstGenId ir_inst_id(IrInstGenCondBr *) { 1651 return IrInstGenIdCondBr; 1652 } 1653 1654 static constexpr IrInstGenId ir_inst_id(IrInstGenSwitchBr *) { 1655 return IrInstGenIdSwitchBr; 1656 } 1657 1658 static constexpr IrInstGenId ir_inst_id(IrInstGenPhi *) { 1659 return IrInstGenIdPhi; 1660 } 1661 1662 static constexpr IrInstGenId ir_inst_id(IrInstGenBinaryNot *) { 1663 return IrInstGenIdBinaryNot; 1664 } 1665 1666 static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) { 1667 return IrInstGenIdNegation; 1668 } 1669 1670 static constexpr IrInstGenId ir_inst_id(IrInstGenNegationWrapping *) { 1671 return IrInstGenIdNegationWrapping; 1672 } 1673 1674 static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) { 1675 return IrInstGenIdBinOp; 1676 } 1677 1678 static constexpr IrInstGenId ir_inst_id(IrInstGenLoadPtr *) { 1679 return IrInstGenIdLoadPtr; 1680 } 1681 1682 static constexpr IrInstGenId ir_inst_id(IrInstGenStorePtr *) { 1683 return IrInstGenIdStorePtr; 1684 } 1685 1686 static constexpr IrInstGenId ir_inst_id(IrInstGenVectorStoreElem *) { 1687 return IrInstGenIdVectorStoreElem; 1688 } 1689 1690 static constexpr IrInstGenId ir_inst_id(IrInstGenStructFieldPtr *) { 1691 return IrInstGenIdStructFieldPtr; 1692 } 1693 1694 static constexpr IrInstGenId ir_inst_id(IrInstGenUnionFieldPtr *) { 1695 return IrInstGenIdUnionFieldPtr; 1696 } 1697 1698 static constexpr IrInstGenId ir_inst_id(IrInstGenElemPtr *) { 1699 return IrInstGenIdElemPtr; 1700 } 1701 1702 static constexpr IrInstGenId ir_inst_id(IrInstGenVarPtr *) { 1703 return IrInstGenIdVarPtr; 1704 } 1705 1706 static constexpr IrInstGenId ir_inst_id(IrInstGenReturnPtr *) { 1707 return IrInstGenIdReturnPtr; 1708 } 1709 1710 static constexpr IrInstGenId ir_inst_id(IrInstGenCall *) { 1711 return IrInstGenIdCall; 1712 } 1713 1714 static constexpr IrInstGenId ir_inst_id(IrInstGenReturn *) { 1715 return IrInstGenIdReturn; 1716 } 1717 1718 static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) { 1719 return IrInstGenIdCast; 1720 } 1721 1722 static constexpr IrInstGenId ir_inst_id(IrInstGenUnreachable *) { 1723 return IrInstGenIdUnreachable; 1724 } 1725 1726 static constexpr IrInstGenId ir_inst_id(IrInstGenAsm *) { 1727 return IrInstGenIdAsm; 1728 } 1729 1730 static constexpr IrInstGenId ir_inst_id(IrInstGenTestNonNull *) { 1731 return IrInstGenIdTestNonNull; 1732 } 1733 1734 static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalUnwrapPtr *) { 1735 return IrInstGenIdOptionalUnwrapPtr; 1736 } 1737 1738 static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalWrap *) { 1739 return IrInstGenIdOptionalWrap; 1740 } 1741 1742 static constexpr IrInstGenId ir_inst_id(IrInstGenUnionTag *) { 1743 return IrInstGenIdUnionTag; 1744 } 1745 1746 static constexpr IrInstGenId ir_inst_id(IrInstGenClz *) { 1747 return IrInstGenIdClz; 1748 } 1749 1750 static constexpr IrInstGenId ir_inst_id(IrInstGenCtz *) { 1751 return IrInstGenIdCtz; 1752 } 1753 1754 static constexpr IrInstGenId ir_inst_id(IrInstGenPopCount *) { 1755 return IrInstGenIdPopCount; 1756 } 1757 1758 static constexpr IrInstGenId ir_inst_id(IrInstGenBswap *) { 1759 return IrInstGenIdBswap; 1760 } 1761 1762 static constexpr IrInstGenId ir_inst_id(IrInstGenBitReverse *) { 1763 return IrInstGenIdBitReverse; 1764 } 1765 1766 static constexpr IrInstGenId ir_inst_id(IrInstGenRef *) { 1767 return IrInstGenIdRef; 1768 } 1769 1770 static constexpr IrInstGenId ir_inst_id(IrInstGenErrName *) { 1771 return IrInstGenIdErrName; 1772 } 1773 1774 static constexpr IrInstGenId ir_inst_id(IrInstGenCmpxchg *) { 1775 return IrInstGenIdCmpxchg; 1776 } 1777 1778 static constexpr IrInstGenId ir_inst_id(IrInstGenFence *) { 1779 return IrInstGenIdFence; 1780 } 1781 1782 static constexpr IrInstGenId ir_inst_id(IrInstGenTruncate *) { 1783 return IrInstGenIdTruncate; 1784 } 1785 1786 static constexpr IrInstGenId ir_inst_id(IrInstGenShuffleVector *) { 1787 return IrInstGenIdShuffleVector; 1788 } 1789 1790 static constexpr IrInstGenId ir_inst_id(IrInstGenSplat *) { 1791 return IrInstGenIdSplat; 1792 } 1793 1794 static constexpr IrInstGenId ir_inst_id(IrInstGenBoolNot *) { 1795 return IrInstGenIdBoolNot; 1796 } 1797 1798 static constexpr IrInstGenId ir_inst_id(IrInstGenMemset *) { 1799 return IrInstGenIdMemset; 1800 } 1801 1802 static constexpr IrInstGenId ir_inst_id(IrInstGenMemcpy *) { 1803 return IrInstGenIdMemcpy; 1804 } 1805 1806 static constexpr IrInstGenId ir_inst_id(IrInstGenSlice *) { 1807 return IrInstGenIdSlice; 1808 } 1809 1810 static constexpr IrInstGenId ir_inst_id(IrInstGenBreakpoint *) { 1811 return IrInstGenIdBreakpoint; 1812 } 1813 1814 static constexpr IrInstGenId ir_inst_id(IrInstGenReturnAddress *) { 1815 return IrInstGenIdReturnAddress; 1816 } 1817 1818 static constexpr IrInstGenId ir_inst_id(IrInstGenFrameAddress *) { 1819 return IrInstGenIdFrameAddress; 1820 } 1821 1822 static constexpr IrInstGenId ir_inst_id(IrInstGenFrameHandle *) { 1823 return IrInstGenIdFrameHandle; 1824 } 1825 1826 static constexpr IrInstGenId ir_inst_id(IrInstGenFrameSize *) { 1827 return IrInstGenIdFrameSize; 1828 } 1829 1830 static constexpr IrInstGenId ir_inst_id(IrInstGenOverflowOp *) { 1831 return IrInstGenIdOverflowOp; 1832 } 1833 1834 static constexpr IrInstGenId ir_inst_id(IrInstGenTestErr *) { 1835 return IrInstGenIdTestErr; 1836 } 1837 1838 static constexpr IrInstGenId ir_inst_id(IrInstGenMulAdd *) { 1839 return IrInstGenIdMulAdd; 1840 } 1841 1842 static constexpr IrInstGenId ir_inst_id(IrInstGenFloatOp *) { 1843 return IrInstGenIdFloatOp; 1844 } 1845 1846 static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrCode *) { 1847 return IrInstGenIdUnwrapErrCode; 1848 } 1849 1850 static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrPayload *) { 1851 return IrInstGenIdUnwrapErrPayload; 1852 } 1853 1854 static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapCode *) { 1855 return IrInstGenIdErrWrapCode; 1856 } 1857 1858 static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapPayload *) { 1859 return IrInstGenIdErrWrapPayload; 1860 } 1861 1862 static constexpr IrInstGenId ir_inst_id(IrInstGenPtrCast *) { 1863 return IrInstGenIdPtrCast; 1864 } 1865 1866 static constexpr IrInstGenId ir_inst_id(IrInstGenBitCast *) { 1867 return IrInstGenIdBitCast; 1868 } 1869 1870 static constexpr IrInstGenId ir_inst_id(IrInstGenWidenOrShorten *) { 1871 return IrInstGenIdWidenOrShorten; 1872 } 1873 1874 static constexpr IrInstGenId ir_inst_id(IrInstGenIntToPtr *) { 1875 return IrInstGenIdIntToPtr; 1876 } 1877 1878 static constexpr IrInstGenId ir_inst_id(IrInstGenPtrToInt *) { 1879 return IrInstGenIdPtrToInt; 1880 } 1881 1882 static constexpr IrInstGenId ir_inst_id(IrInstGenIntToEnum *) { 1883 return IrInstGenIdIntToEnum; 1884 } 1885 1886 static constexpr IrInstGenId ir_inst_id(IrInstGenIntToErr *) { 1887 return IrInstGenIdIntToErr; 1888 } 1889 1890 static constexpr IrInstGenId ir_inst_id(IrInstGenErrToInt *) { 1891 return IrInstGenIdErrToInt; 1892 } 1893 1894 static constexpr IrInstGenId ir_inst_id(IrInstGenPanic *) { 1895 return IrInstGenIdPanic; 1896 } 1897 1898 static constexpr IrInstGenId ir_inst_id(IrInstGenTagName *) { 1899 return IrInstGenIdTagName; 1900 } 1901 1902 static constexpr IrInstGenId ir_inst_id(IrInstGenFieldParentPtr *) { 1903 return IrInstGenIdFieldParentPtr; 1904 } 1905 1906 static constexpr IrInstGenId ir_inst_id(IrInstGenAlignCast *) { 1907 return IrInstGenIdAlignCast; 1908 } 1909 1910 static constexpr IrInstGenId ir_inst_id(IrInstGenErrorReturnTrace *) { 1911 return IrInstGenIdErrorReturnTrace; 1912 } 1913 1914 static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicRmw *) { 1915 return IrInstGenIdAtomicRmw; 1916 } 1917 1918 static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicLoad *) { 1919 return IrInstGenIdAtomicLoad; 1920 } 1921 1922 static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicStore *) { 1923 return IrInstGenIdAtomicStore; 1924 } 1925 1926 static constexpr IrInstGenId ir_inst_id(IrInstGenSaveErrRetAddr *) { 1927 return IrInstGenIdSaveErrRetAddr; 1928 } 1929 1930 static constexpr IrInstGenId ir_inst_id(IrInstGenVectorToArray *) { 1931 return IrInstGenIdVectorToArray; 1932 } 1933 1934 static constexpr IrInstGenId ir_inst_id(IrInstGenArrayToVector *) { 1935 return IrInstGenIdArrayToVector; 1936 } 1937 1938 static constexpr IrInstGenId ir_inst_id(IrInstGenAssertZero *) { 1939 return IrInstGenIdAssertZero; 1940 } 1941 1942 static constexpr IrInstGenId ir_inst_id(IrInstGenAssertNonNull *) { 1943 return IrInstGenIdAssertNonNull; 1944 } 1945 1946 static constexpr IrInstGenId ir_inst_id(IrInstGenPtrOfArrayToSlice *) { 1947 return IrInstGenIdPtrOfArrayToSlice; 1948 } 1949 1950 static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendBegin *) { 1951 return IrInstGenIdSuspendBegin; 1952 } 1953 1954 static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendFinish *) { 1955 return IrInstGenIdSuspendFinish; 1956 } 1957 1958 static constexpr IrInstGenId ir_inst_id(IrInstGenAwait *) { 1959 return IrInstGenIdAwait; 1960 } 1961 1962 static constexpr IrInstGenId ir_inst_id(IrInstGenResume *) { 1963 return IrInstGenIdResume; 1964 } 1965 1966 static constexpr IrInstGenId ir_inst_id(IrInstGenSpillBegin *) { 1967 return IrInstGenIdSpillBegin; 1968 } 1969 1970 static constexpr IrInstGenId ir_inst_id(IrInstGenSpillEnd *) { 1971 return IrInstGenIdSpillEnd; 1972 } 1973 1974 static constexpr IrInstGenId ir_inst_id(IrInstGenVectorExtractElem *) { 1975 return IrInstGenIdVectorExtractElem; 1976 } 1977 1978 static constexpr IrInstGenId ir_inst_id(IrInstGenAlloca *) { 1979 return IrInstGenIdAlloca; 1980 } 1981 1982 static constexpr IrInstGenId ir_inst_id(IrInstGenConst *) { 1983 return IrInstGenIdConst; 1984 } 1985 1986 static constexpr IrInstGenId ir_inst_id(IrInstGenWasmMemorySize *) { 1987 return IrInstGenIdWasmMemorySize; 1988 } 1989 1990 static constexpr IrInstGenId ir_inst_id(IrInstGenWasmMemoryGrow *) { 1991 return IrInstGenIdWasmMemoryGrow; 1992 } 1993 1994 template<typename T> 1995 static T *ir_create_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 1996 T *special_instruction = heap::c_allocator.create<T>(); 1997 special_instruction->base.id = ir_inst_id(special_instruction); 1998 special_instruction->base.base.scope = scope; 1999 special_instruction->base.base.source_node = source_node; 2000 special_instruction->base.base.debug_id = exec_next_debug_id(irb->exec); 2001 special_instruction->base.owner_bb = irb->current_basic_block; 2002 return special_instruction; 2003 } 2004 2005 template<typename T> 2006 static T *ir_create_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 2007 T *special_instruction = heap::c_allocator.create<T>(); 2008 special_instruction->base.id = ir_inst_id(special_instruction); 2009 special_instruction->base.base.scope = scope; 2010 special_instruction->base.base.source_node = source_node; 2011 special_instruction->base.base.debug_id = exec_next_debug_id_gen(irb->exec); 2012 special_instruction->base.owner_bb = irb->current_basic_block; 2013 special_instruction->base.value = irb->codegen->pass1_arena->create<ZigValue>(); 2014 return special_instruction; 2015 } 2016 2017 template<typename T> 2018 static T *ir_create_inst_noval(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 2019 T *special_instruction = heap::c_allocator.create<T>(); 2020 special_instruction->base.id = ir_inst_id(special_instruction); 2021 special_instruction->base.base.scope = scope; 2022 special_instruction->base.base.source_node = source_node; 2023 special_instruction->base.base.debug_id = exec_next_debug_id_gen(irb->exec); 2024 special_instruction->base.owner_bb = irb->current_basic_block; 2025 return special_instruction; 2026 } 2027 2028 template<typename T> 2029 static T *ir_build_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2030 T *special_instruction = ir_create_instruction<T>(irb, scope, source_node); 2031 ir_instruction_append(irb->current_basic_block, &special_instruction->base); 2032 return special_instruction; 2033 } 2034 2035 template<typename T> 2036 static T *ir_build_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 2037 T *special_instruction = ir_create_inst_gen<T>(irb, scope, source_node); 2038 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base); 2039 return special_instruction; 2040 } 2041 2042 template<typename T> 2043 static T *ir_build_inst_noreturn(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 2044 T *special_instruction = ir_create_inst_noval<T>(irb, scope, source_node); 2045 special_instruction->base.value = irb->codegen->intern.for_unreachable(); 2046 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base); 2047 return special_instruction; 2048 } 2049 2050 template<typename T> 2051 static T *ir_build_inst_void(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 2052 T *special_instruction = ir_create_inst_noval<T>(irb, scope, source_node); 2053 special_instruction->base.value = irb->codegen->intern.for_void(); 2054 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base); 2055 return special_instruction; 2056 } 2057 2058 IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn, 2059 ZigType *var_type, const char *name_hint) 2060 { 2061 IrInstGenAlloca *alloca_gen = heap::c_allocator.create<IrInstGenAlloca>(); 2062 alloca_gen->base.id = IrInstGenIdAlloca; 2063 alloca_gen->base.base.source_node = source_node; 2064 alloca_gen->base.base.scope = scope; 2065 alloca_gen->base.value = g->pass1_arena->create<ZigValue>(); 2066 alloca_gen->base.value->type = get_pointer_to_type(g, var_type, false); 2067 alloca_gen->base.base.ref_count = 1; 2068 alloca_gen->name_hint = name_hint; 2069 fn->alloca_gen_list.append(alloca_gen); 2070 return &alloca_gen->base; 2071 } 2072 2073 static IrInstGen *ir_build_cast(IrAnalyze *ira, IrInst *source_instr,ZigType *dest_type, 2074 IrInstGen *value, CastOp cast_op) 2075 { 2076 IrInstGenCast *inst = ir_build_inst_gen<IrInstGenCast>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2077 inst->base.value->type = dest_type; 2078 inst->value = value; 2079 inst->cast_op = cast_op; 2080 2081 ir_ref_inst_gen(value); 2082 2083 return &inst->base; 2084 } 2085 2086 static IrInstSrc *ir_build_cond_br(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *condition, 2087 IrBasicBlockSrc *then_block, IrBasicBlockSrc *else_block, IrInstSrc *is_comptime) 2088 { 2089 IrInstSrcCondBr *inst = ir_build_instruction<IrInstSrcCondBr>(irb, scope, source_node); 2090 inst->base.is_noreturn = true; 2091 inst->condition = condition; 2092 inst->then_block = then_block; 2093 inst->else_block = else_block; 2094 inst->is_comptime = is_comptime; 2095 2096 ir_ref_instruction(condition, irb->current_basic_block); 2097 ir_ref_bb(then_block); 2098 ir_ref_bb(else_block); 2099 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); 2100 2101 return &inst->base; 2102 } 2103 2104 static IrInstGen *ir_build_cond_br_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *condition, 2105 IrBasicBlockGen *then_block, IrBasicBlockGen *else_block) 2106 { 2107 IrInstGenCondBr *inst = ir_build_inst_noreturn<IrInstGenCondBr>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2108 inst->condition = condition; 2109 inst->then_block = then_block; 2110 inst->else_block = else_block; 2111 2112 ir_ref_inst_gen(condition); 2113 2114 return &inst->base; 2115 } 2116 2117 static IrInstSrc *ir_build_return_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *operand) { 2118 IrInstSrcReturn *inst = ir_build_instruction<IrInstSrcReturn>(irb, scope, source_node); 2119 inst->base.is_noreturn = true; 2120 inst->operand = operand; 2121 2122 if (operand != nullptr) ir_ref_instruction(operand, irb->current_basic_block); 2123 2124 return &inst->base; 2125 } 2126 2127 static IrInstGen *ir_build_return_gen(IrAnalyze *ira, IrInst *source_inst, IrInstGen *operand) { 2128 IrInstGenReturn *inst = ir_build_inst_noreturn<IrInstGenReturn>(&ira->new_irb, 2129 source_inst->scope, source_inst->source_node); 2130 inst->operand = operand; 2131 2132 if (operand != nullptr) ir_ref_inst_gen(operand); 2133 2134 return &inst->base; 2135 } 2136 2137 static IrInstSrc *ir_build_const_void(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2138 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2139 ir_instruction_append(irb->current_basic_block, &const_instruction->base); 2140 const_instruction->value = irb->codegen->intern.for_void(); 2141 return &const_instruction->base; 2142 } 2143 2144 static IrInstSrc *ir_build_const_undefined(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2145 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2146 ir_instruction_append(irb->current_basic_block, &const_instruction->base); 2147 const_instruction->value = irb->codegen->intern.for_undefined(); 2148 return &const_instruction->base; 2149 } 2150 2151 static IrInstSrc *ir_build_const_uint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, uint64_t value) { 2152 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2153 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2154 const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_int; 2155 const_instruction->value->special = ConstValSpecialStatic; 2156 bigint_init_unsigned(&const_instruction->value->data.x_bigint, value); 2157 return &const_instruction->base; 2158 } 2159 2160 static IrInstSrc *ir_build_const_bigint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigInt *bigint) { 2161 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2162 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2163 const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_int; 2164 const_instruction->value->special = ConstValSpecialStatic; 2165 bigint_init_bigint(&const_instruction->value->data.x_bigint, bigint); 2166 return &const_instruction->base; 2167 } 2168 2169 static IrInstSrc *ir_build_const_bigfloat(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigFloat *bigfloat) { 2170 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2171 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2172 const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_float; 2173 const_instruction->value->special = ConstValSpecialStatic; 2174 bigfloat_init_bigfloat(&const_instruction->value->data.x_bigfloat, bigfloat); 2175 return &const_instruction->base; 2176 } 2177 2178 static IrInstSrc *ir_build_const_null(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2179 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2180 ir_instruction_append(irb->current_basic_block, &const_instruction->base); 2181 const_instruction->value = irb->codegen->intern.for_null(); 2182 return &const_instruction->base; 2183 } 2184 2185 static IrInstSrc *ir_build_const_usize(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, uint64_t value) { 2186 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2187 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2188 const_instruction->value->type = irb->codegen->builtin_types.entry_usize; 2189 const_instruction->value->special = ConstValSpecialStatic; 2190 bigint_init_unsigned(&const_instruction->value->data.x_bigint, value); 2191 return &const_instruction->base; 2192 } 2193 2194 static IrInstSrc *ir_create_const_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2195 ZigType *type_entry) 2196 { 2197 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2198 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2199 const_instruction->value->type = irb->codegen->builtin_types.entry_type; 2200 const_instruction->value->special = ConstValSpecialStatic; 2201 const_instruction->value->data.x_type = type_entry; 2202 return &const_instruction->base; 2203 } 2204 2205 static IrInstSrc *ir_build_const_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2206 ZigType *type_entry) 2207 { 2208 IrInstSrc *instruction = ir_create_const_type(irb, scope, source_node, type_entry); 2209 ir_instruction_append(irb->current_basic_block, instruction); 2210 return instruction; 2211 } 2212 2213 static IrInstSrc *ir_build_const_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigType *import) { 2214 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2215 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2216 const_instruction->value->type = irb->codegen->builtin_types.entry_type; 2217 const_instruction->value->special = ConstValSpecialStatic; 2218 const_instruction->value->data.x_type = import; 2219 return &const_instruction->base; 2220 } 2221 2222 static IrInstSrc *ir_build_const_bool(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, bool value) { 2223 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2224 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2225 const_instruction->value->type = irb->codegen->builtin_types.entry_bool; 2226 const_instruction->value->special = ConstValSpecialStatic; 2227 const_instruction->value->data.x_bool = value; 2228 return &const_instruction->base; 2229 } 2230 2231 static IrInstSrc *ir_build_const_enum_literal(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *name) { 2232 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2233 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2234 const_instruction->value->type = irb->codegen->builtin_types.entry_enum_literal; 2235 const_instruction->value->special = ConstValSpecialStatic; 2236 const_instruction->value->data.x_enum_literal = name; 2237 return &const_instruction->base; 2238 } 2239 2240 static IrInstSrc *ir_create_const_str_lit(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *str) { 2241 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2242 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2243 init_const_str_lit(irb->codegen, const_instruction->value, str); 2244 2245 return &const_instruction->base; 2246 } 2247 2248 static IrInstSrc *ir_build_const_str_lit(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *str) { 2249 IrInstSrc *instruction = ir_create_const_str_lit(irb, scope, source_node, str); 2250 ir_instruction_append(irb->current_basic_block, instruction); 2251 return instruction; 2252 } 2253 2254 static IrInstSrc *ir_build_bin_op(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, 2255 IrInstSrc *op1, IrInstSrc *op2, bool safety_check_on) 2256 { 2257 IrInstSrcBinOp *inst = ir_build_instruction<IrInstSrcBinOp>(irb, scope, source_node); 2258 inst->op_id = op_id; 2259 inst->op1 = op1; 2260 inst->op2 = op2; 2261 inst->safety_check_on = safety_check_on; 2262 2263 ir_ref_instruction(op1, irb->current_basic_block); 2264 ir_ref_instruction(op2, irb->current_basic_block); 2265 2266 return &inst->base; 2267 } 2268 2269 static IrInstGen *ir_build_bin_op_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *res_type, 2270 IrBinOp op_id, IrInstGen *op1, IrInstGen *op2, bool safety_check_on) 2271 { 2272 IrInstGenBinOp *inst = ir_build_inst_gen<IrInstGenBinOp>(&ira->new_irb, 2273 source_instr->scope, source_instr->source_node); 2274 inst->base.value->type = res_type; 2275 inst->op_id = op_id; 2276 inst->op1 = op1; 2277 inst->op2 = op2; 2278 inst->safety_check_on = safety_check_on; 2279 2280 ir_ref_inst_gen(op1); 2281 ir_ref_inst_gen(op2); 2282 2283 return &inst->base; 2284 } 2285 2286 2287 static IrInstSrc *ir_build_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2288 IrInstSrc *op1, IrInstSrc *op2, Buf *type_name) 2289 { 2290 IrInstSrcMergeErrSets *inst = ir_build_instruction<IrInstSrcMergeErrSets>(irb, scope, source_node); 2291 inst->op1 = op1; 2292 inst->op2 = op2; 2293 inst->type_name = type_name; 2294 2295 ir_ref_instruction(op1, irb->current_basic_block); 2296 ir_ref_instruction(op2, irb->current_basic_block); 2297 2298 return &inst->base; 2299 } 2300 2301 static IrInstSrc *ir_build_var_ptr_x(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var, 2302 ScopeFnDef *crossed_fndef_scope) 2303 { 2304 IrInstSrcVarPtr *instruction = ir_build_instruction<IrInstSrcVarPtr>(irb, scope, source_node); 2305 instruction->var = var; 2306 instruction->crossed_fndef_scope = crossed_fndef_scope; 2307 2308 ir_ref_var(var); 2309 2310 return &instruction->base; 2311 } 2312 2313 static IrInstSrc *ir_build_var_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var) { 2314 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr); 2315 } 2316 2317 static IrInstGen *ir_build_var_ptr_gen(IrAnalyze *ira, IrInst *source_instr, ZigVar *var) { 2318 IrInstGenVarPtr *instruction = ir_build_inst_gen<IrInstGenVarPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2319 instruction->var = var; 2320 2321 ir_ref_var(var); 2322 2323 return &instruction->base; 2324 } 2325 2326 static IrInstGen *ir_build_return_ptr(IrAnalyze *ira, Scope *scope, AstNode *source_node, ZigType *ty) { 2327 IrInstGenReturnPtr *instruction = ir_build_inst_gen<IrInstGenReturnPtr>(&ira->new_irb, scope, source_node); 2328 instruction->base.value->type = ty; 2329 return &instruction->base; 2330 } 2331 2332 static IrInstSrc *ir_build_elem_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2333 IrInstSrc *array_ptr, IrInstSrc *elem_index, bool safety_check_on, PtrLen ptr_len, 2334 AstNode *init_array_type_source_node) 2335 { 2336 IrInstSrcElemPtr *instruction = ir_build_instruction<IrInstSrcElemPtr>(irb, scope, source_node); 2337 instruction->array_ptr = array_ptr; 2338 instruction->elem_index = elem_index; 2339 instruction->safety_check_on = safety_check_on; 2340 instruction->ptr_len = ptr_len; 2341 instruction->init_array_type_source_node = init_array_type_source_node; 2342 2343 ir_ref_instruction(array_ptr, irb->current_basic_block); 2344 ir_ref_instruction(elem_index, irb->current_basic_block); 2345 2346 return &instruction->base; 2347 } 2348 2349 static IrInstGen *ir_build_elem_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 2350 IrInstGen *array_ptr, IrInstGen *elem_index, bool safety_check_on, ZigType *return_type) 2351 { 2352 IrInstGenElemPtr *instruction = ir_build_inst_gen<IrInstGenElemPtr>(&ira->new_irb, scope, source_node); 2353 instruction->base.value->type = return_type; 2354 instruction->array_ptr = array_ptr; 2355 instruction->elem_index = elem_index; 2356 instruction->safety_check_on = safety_check_on; 2357 2358 ir_ref_inst_gen(array_ptr); 2359 ir_ref_inst_gen(elem_index); 2360 2361 return &instruction->base; 2362 } 2363 2364 static IrInstSrc *ir_build_field_ptr_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2365 IrInstSrc *container_ptr, IrInstSrc *field_name_expr, bool initializing) 2366 { 2367 IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(irb, scope, source_node); 2368 instruction->container_ptr = container_ptr; 2369 instruction->field_name_buffer = nullptr; 2370 instruction->field_name_expr = field_name_expr; 2371 instruction->initializing = initializing; 2372 2373 ir_ref_instruction(container_ptr, irb->current_basic_block); 2374 ir_ref_instruction(field_name_expr, irb->current_basic_block); 2375 2376 return &instruction->base; 2377 } 2378 2379 static IrInstSrc *ir_build_field_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2380 IrInstSrc *container_ptr, Buf *field_name, bool initializing) 2381 { 2382 IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(irb, scope, source_node); 2383 instruction->container_ptr = container_ptr; 2384 instruction->field_name_buffer = field_name; 2385 instruction->field_name_expr = nullptr; 2386 instruction->initializing = initializing; 2387 2388 ir_ref_instruction(container_ptr, irb->current_basic_block); 2389 2390 return &instruction->base; 2391 } 2392 2393 static IrInstSrc *ir_build_has_field(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2394 IrInstSrc *container_type, IrInstSrc *field_name) 2395 { 2396 IrInstSrcHasField *instruction = ir_build_instruction<IrInstSrcHasField>(irb, scope, source_node); 2397 instruction->container_type = container_type; 2398 instruction->field_name = field_name; 2399 2400 ir_ref_instruction(container_type, irb->current_basic_block); 2401 ir_ref_instruction(field_name, irb->current_basic_block); 2402 2403 return &instruction->base; 2404 } 2405 2406 static IrInstGen *ir_build_struct_field_ptr(IrAnalyze *ira, IrInst *source_instr, 2407 IrInstGen *struct_ptr, TypeStructField *field, ZigType *ptr_type) 2408 { 2409 IrInstGenStructFieldPtr *inst = ir_build_inst_gen<IrInstGenStructFieldPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2410 inst->base.value->type = ptr_type; 2411 inst->struct_ptr = struct_ptr; 2412 inst->field = field; 2413 2414 ir_ref_inst_gen(struct_ptr); 2415 2416 return &inst->base; 2417 } 2418 2419 static IrInstGen *ir_build_union_field_ptr(IrAnalyze *ira, IrInst *source_instr, 2420 IrInstGen *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing, ZigType *ptr_type) 2421 { 2422 IrInstGenUnionFieldPtr *inst = ir_build_inst_gen<IrInstGenUnionFieldPtr>(&ira->new_irb, 2423 source_instr->scope, source_instr->source_node); 2424 inst->base.value->type = ptr_type; 2425 inst->initializing = initializing; 2426 inst->safety_check_on = safety_check_on; 2427 inst->union_ptr = union_ptr; 2428 inst->field = field; 2429 2430 ir_ref_inst_gen(union_ptr); 2431 2432 return &inst->base; 2433 } 2434 2435 static IrInstSrc *ir_build_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2436 IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc *args, ResultLoc *result_loc) 2437 { 2438 IrInstSrcCallExtra *call_instruction = ir_build_instruction<IrInstSrcCallExtra>(irb, scope, source_node); 2439 call_instruction->options = options; 2440 call_instruction->fn_ref = fn_ref; 2441 call_instruction->args = args; 2442 call_instruction->result_loc = result_loc; 2443 2444 ir_ref_instruction(options, irb->current_basic_block); 2445 ir_ref_instruction(fn_ref, irb->current_basic_block); 2446 ir_ref_instruction(args, irb->current_basic_block); 2447 2448 return &call_instruction->base; 2449 } 2450 2451 static IrInstSrc *ir_build_async_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2452 CallModifier modifier, IrInstSrc *fn_ref, IrInstSrc *ret_ptr, IrInstSrc *new_stack, IrInstSrc *args, ResultLoc *result_loc) 2453 { 2454 IrInstSrcAsyncCallExtra *call_instruction = ir_build_instruction<IrInstSrcAsyncCallExtra>(irb, scope, source_node); 2455 call_instruction->modifier = modifier; 2456 call_instruction->fn_ref = fn_ref; 2457 call_instruction->ret_ptr = ret_ptr; 2458 call_instruction->new_stack = new_stack; 2459 call_instruction->args = args; 2460 call_instruction->result_loc = result_loc; 2461 2462 ir_ref_instruction(fn_ref, irb->current_basic_block); 2463 if (ret_ptr != nullptr) ir_ref_instruction(ret_ptr, irb->current_basic_block); 2464 ir_ref_instruction(new_stack, irb->current_basic_block); 2465 ir_ref_instruction(args, irb->current_basic_block); 2466 2467 return &call_instruction->base; 2468 } 2469 2470 static IrInstSrc *ir_build_call_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2471 IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc **args_ptr, size_t args_len, 2472 ResultLoc *result_loc) 2473 { 2474 IrInstSrcCallArgs *call_instruction = ir_build_instruction<IrInstSrcCallArgs>(irb, scope, source_node); 2475 call_instruction->options = options; 2476 call_instruction->fn_ref = fn_ref; 2477 call_instruction->args_ptr = args_ptr; 2478 call_instruction->args_len = args_len; 2479 call_instruction->result_loc = result_loc; 2480 2481 ir_ref_instruction(options, irb->current_basic_block); 2482 ir_ref_instruction(fn_ref, irb->current_basic_block); 2483 for (size_t i = 0; i < args_len; i += 1) 2484 ir_ref_instruction(args_ptr[i], irb->current_basic_block); 2485 2486 return &call_instruction->base; 2487 } 2488 2489 static IrInstSrc *ir_build_call_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2490 ZigFn *fn_entry, IrInstSrc *fn_ref, size_t arg_count, IrInstSrc **args, 2491 IrInstSrc *ret_ptr, CallModifier modifier, bool is_async_call_builtin, 2492 IrInstSrc *new_stack, ResultLoc *result_loc) 2493 { 2494 IrInstSrcCall *call_instruction = ir_build_instruction<IrInstSrcCall>(irb, scope, source_node); 2495 call_instruction->fn_entry = fn_entry; 2496 call_instruction->fn_ref = fn_ref; 2497 call_instruction->args = args; 2498 call_instruction->arg_count = arg_count; 2499 call_instruction->modifier = modifier; 2500 call_instruction->is_async_call_builtin = is_async_call_builtin; 2501 call_instruction->new_stack = new_stack; 2502 call_instruction->result_loc = result_loc; 2503 call_instruction->ret_ptr = ret_ptr; 2504 2505 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); 2506 for (size_t i = 0; i < arg_count; i += 1) 2507 ir_ref_instruction(args[i], irb->current_basic_block); 2508 if (ret_ptr != nullptr) ir_ref_instruction(ret_ptr, irb->current_basic_block); 2509 if (new_stack != nullptr) ir_ref_instruction(new_stack, irb->current_basic_block); 2510 2511 return &call_instruction->base; 2512 } 2513 2514 static IrInstGenCall *ir_build_call_gen(IrAnalyze *ira, IrInst *source_instruction, 2515 ZigFn *fn_entry, IrInstGen *fn_ref, size_t arg_count, IrInstGen **args, 2516 CallModifier modifier, IrInstGen *new_stack, bool is_async_call_builtin, 2517 IrInstGen *result_loc, ZigType *return_type) 2518 { 2519 IrInstGenCall *call_instruction = ir_build_inst_gen<IrInstGenCall>(&ira->new_irb, 2520 source_instruction->scope, source_instruction->source_node); 2521 call_instruction->base.value->type = return_type; 2522 call_instruction->fn_entry = fn_entry; 2523 call_instruction->fn_ref = fn_ref; 2524 call_instruction->args = args; 2525 call_instruction->arg_count = arg_count; 2526 call_instruction->modifier = modifier; 2527 call_instruction->is_async_call_builtin = is_async_call_builtin; 2528 call_instruction->new_stack = new_stack; 2529 call_instruction->result_loc = result_loc; 2530 2531 if (fn_ref != nullptr) ir_ref_inst_gen(fn_ref); 2532 for (size_t i = 0; i < arg_count; i += 1) 2533 ir_ref_inst_gen(args[i]); 2534 if (new_stack != nullptr) ir_ref_inst_gen(new_stack); 2535 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 2536 2537 return call_instruction; 2538 } 2539 2540 static IrInstSrc *ir_build_phi(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2541 size_t incoming_count, IrBasicBlockSrc **incoming_blocks, IrInstSrc **incoming_values, 2542 ResultLocPeerParent *peer_parent) 2543 { 2544 assert(incoming_count != 0); 2545 assert(incoming_count != SIZE_MAX); 2546 2547 IrInstSrcPhi *phi_instruction = ir_build_instruction<IrInstSrcPhi>(irb, scope, source_node); 2548 phi_instruction->incoming_count = incoming_count; 2549 phi_instruction->incoming_blocks = incoming_blocks; 2550 phi_instruction->incoming_values = incoming_values; 2551 phi_instruction->peer_parent = peer_parent; 2552 2553 for (size_t i = 0; i < incoming_count; i += 1) { 2554 ir_ref_bb(incoming_blocks[i]); 2555 ir_ref_instruction(incoming_values[i], irb->current_basic_block); 2556 } 2557 2558 return &phi_instruction->base; 2559 } 2560 2561 static IrInstGen *ir_build_phi_gen(IrAnalyze *ira, IrInst *source_instr, size_t incoming_count, 2562 IrBasicBlockGen **incoming_blocks, IrInstGen **incoming_values, ZigType *result_type) 2563 { 2564 assert(incoming_count != 0); 2565 assert(incoming_count != SIZE_MAX); 2566 2567 IrInstGenPhi *phi_instruction = ir_build_inst_gen<IrInstGenPhi>(&ira->new_irb, 2568 source_instr->scope, source_instr->source_node); 2569 phi_instruction->base.value->type = result_type; 2570 phi_instruction->incoming_count = incoming_count; 2571 phi_instruction->incoming_blocks = incoming_blocks; 2572 phi_instruction->incoming_values = incoming_values; 2573 2574 for (size_t i = 0; i < incoming_count; i += 1) { 2575 ir_ref_inst_gen(incoming_values[i]); 2576 } 2577 2578 return &phi_instruction->base; 2579 } 2580 2581 static IrInstSrc *ir_build_br(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2582 IrBasicBlockSrc *dest_block, IrInstSrc *is_comptime) 2583 { 2584 IrInstSrcBr *inst = ir_build_instruction<IrInstSrcBr>(irb, scope, source_node); 2585 inst->base.is_noreturn = true; 2586 inst->dest_block = dest_block; 2587 inst->is_comptime = is_comptime; 2588 2589 ir_ref_bb(dest_block); 2590 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 2591 2592 return &inst->base; 2593 } 2594 2595 static IrInstGen *ir_build_br_gen(IrAnalyze *ira, IrInst *source_instr, IrBasicBlockGen *dest_block) { 2596 IrInstGenBr *inst = ir_build_inst_noreturn<IrInstGenBr>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2597 inst->dest_block = dest_block; 2598 2599 return &inst->base; 2600 } 2601 2602 static IrInstSrc *ir_build_ptr_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2603 IrInstSrc *child_type, bool is_const, bool is_volatile, PtrLen ptr_len, 2604 IrInstSrc *sentinel, IrInstSrc *align_value, 2605 uint32_t bit_offset_start, uint32_t host_int_bytes, bool is_allow_zero) 2606 { 2607 IrInstSrcPtrType *inst = ir_build_instruction<IrInstSrcPtrType>(irb, scope, source_node); 2608 inst->sentinel = sentinel; 2609 inst->align_value = align_value; 2610 inst->child_type = child_type; 2611 inst->is_const = is_const; 2612 inst->is_volatile = is_volatile; 2613 inst->ptr_len = ptr_len; 2614 inst->bit_offset_start = bit_offset_start; 2615 inst->host_int_bytes = host_int_bytes; 2616 inst->is_allow_zero = is_allow_zero; 2617 2618 if (sentinel) ir_ref_instruction(sentinel, irb->current_basic_block); 2619 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 2620 ir_ref_instruction(child_type, irb->current_basic_block); 2621 2622 return &inst->base; 2623 } 2624 2625 static IrInstSrc *ir_build_un_op_lval(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, 2626 IrInstSrc *value, LVal lval, ResultLoc *result_loc) 2627 { 2628 IrInstSrcUnOp *instruction = ir_build_instruction<IrInstSrcUnOp>(irb, scope, source_node); 2629 instruction->op_id = op_id; 2630 instruction->value = value; 2631 instruction->lval = lval; 2632 instruction->result_loc = result_loc; 2633 2634 ir_ref_instruction(value, irb->current_basic_block); 2635 2636 return &instruction->base; 2637 } 2638 2639 static IrInstSrc *ir_build_un_op(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, 2640 IrInstSrc *value) 2641 { 2642 return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr); 2643 } 2644 2645 static IrInstGen *ir_build_negation(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, ZigType *expr_type) { 2646 IrInstGenNegation *instruction = ir_build_inst_gen<IrInstGenNegation>(&ira->new_irb, 2647 source_instr->scope, source_instr->source_node); 2648 instruction->base.value->type = expr_type; 2649 instruction->operand = operand; 2650 2651 ir_ref_inst_gen(operand); 2652 2653 return &instruction->base; 2654 } 2655 2656 static IrInstGen *ir_build_negation_wrapping(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, 2657 ZigType *expr_type) 2658 { 2659 IrInstGenNegationWrapping *instruction = ir_build_inst_gen<IrInstGenNegationWrapping>(&ira->new_irb, 2660 source_instr->scope, source_instr->source_node); 2661 instruction->base.value->type = expr_type; 2662 instruction->operand = operand; 2663 2664 ir_ref_inst_gen(operand); 2665 2666 return &instruction->base; 2667 } 2668 2669 static IrInstGen *ir_build_binary_not(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, 2670 ZigType *expr_type) 2671 { 2672 IrInstGenBinaryNot *instruction = ir_build_inst_gen<IrInstGenBinaryNot>(&ira->new_irb, 2673 source_instr->scope, source_instr->source_node); 2674 instruction->base.value->type = expr_type; 2675 instruction->operand = operand; 2676 2677 ir_ref_inst_gen(operand); 2678 2679 return &instruction->base; 2680 } 2681 2682 static IrInstSrc *ir_build_container_init_list(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2683 size_t item_count, IrInstSrc **elem_result_loc_list, IrInstSrc *result_loc, 2684 AstNode *init_array_type_source_node) 2685 { 2686 IrInstSrcContainerInitList *container_init_list_instruction = 2687 ir_build_instruction<IrInstSrcContainerInitList>(irb, scope, source_node); 2688 container_init_list_instruction->item_count = item_count; 2689 container_init_list_instruction->elem_result_loc_list = elem_result_loc_list; 2690 container_init_list_instruction->result_loc = result_loc; 2691 container_init_list_instruction->init_array_type_source_node = init_array_type_source_node; 2692 2693 for (size_t i = 0; i < item_count; i += 1) { 2694 ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block); 2695 } 2696 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 2697 2698 return &container_init_list_instruction->base; 2699 } 2700 2701 static IrInstSrc *ir_build_container_init_fields(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2702 size_t field_count, IrInstSrcContainerInitFieldsField *fields, IrInstSrc *result_loc) 2703 { 2704 IrInstSrcContainerInitFields *container_init_fields_instruction = 2705 ir_build_instruction<IrInstSrcContainerInitFields>(irb, scope, source_node); 2706 container_init_fields_instruction->field_count = field_count; 2707 container_init_fields_instruction->fields = fields; 2708 container_init_fields_instruction->result_loc = result_loc; 2709 2710 for (size_t i = 0; i < field_count; i += 1) { 2711 ir_ref_instruction(fields[i].result_loc, irb->current_basic_block); 2712 } 2713 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 2714 2715 return &container_init_fields_instruction->base; 2716 } 2717 2718 static IrInstSrc *ir_build_unreachable(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2719 IrInstSrcUnreachable *inst = ir_build_instruction<IrInstSrcUnreachable>(irb, scope, source_node); 2720 inst->base.is_noreturn = true; 2721 return &inst->base; 2722 } 2723 2724 static IrInstGen *ir_build_unreachable_gen(IrAnalyze *ira, IrInst *source_instr) { 2725 IrInstGenUnreachable *inst = ir_build_inst_noreturn<IrInstGenUnreachable>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2726 return &inst->base; 2727 } 2728 2729 static IrInstSrcStorePtr *ir_build_store_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2730 IrInstSrc *ptr, IrInstSrc *value) 2731 { 2732 IrInstSrcStorePtr *instruction = ir_build_instruction<IrInstSrcStorePtr>(irb, scope, source_node); 2733 instruction->ptr = ptr; 2734 instruction->value = value; 2735 2736 ir_ref_instruction(ptr, irb->current_basic_block); 2737 ir_ref_instruction(value, irb->current_basic_block); 2738 2739 return instruction; 2740 } 2741 2742 static IrInstGen *ir_build_store_ptr_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *ptr, IrInstGen *value) { 2743 IrInstGenStorePtr *instruction = ir_build_inst_void<IrInstGenStorePtr>(&ira->new_irb, 2744 source_instr->scope, source_instr->source_node); 2745 instruction->ptr = ptr; 2746 instruction->value = value; 2747 2748 ir_ref_inst_gen(ptr); 2749 ir_ref_inst_gen(value); 2750 2751 return &instruction->base; 2752 } 2753 2754 static IrInstGen *ir_build_vector_store_elem(IrAnalyze *ira, IrInst *src_inst, 2755 IrInstGen *vector_ptr, IrInstGen *index, IrInstGen *value) 2756 { 2757 IrInstGenVectorStoreElem *inst = ir_build_inst_void<IrInstGenVectorStoreElem>( 2758 &ira->new_irb, src_inst->scope, src_inst->source_node); 2759 inst->vector_ptr = vector_ptr; 2760 inst->index = index; 2761 inst->value = value; 2762 2763 ir_ref_inst_gen(vector_ptr); 2764 ir_ref_inst_gen(index); 2765 ir_ref_inst_gen(value); 2766 2767 return &inst->base; 2768 } 2769 2770 static IrInstSrc *ir_build_var_decl_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2771 ZigVar *var, IrInstSrc *align_value, IrInstSrc *ptr) 2772 { 2773 IrInstSrcDeclVar *inst = ir_build_instruction<IrInstSrcDeclVar>(irb, scope, source_node); 2774 inst->var = var; 2775 inst->align_value = align_value; 2776 inst->ptr = ptr; 2777 2778 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 2779 ir_ref_instruction(ptr, irb->current_basic_block); 2780 2781 return &inst->base; 2782 } 2783 2784 static IrInstGen *ir_build_var_decl_gen(IrAnalyze *ira, IrInst *source_instruction, 2785 ZigVar *var, IrInstGen *var_ptr) 2786 { 2787 IrInstGenDeclVar *inst = ir_build_inst_gen<IrInstGenDeclVar>(&ira->new_irb, 2788 source_instruction->scope, source_instruction->source_node); 2789 inst->base.value->special = ConstValSpecialStatic; 2790 inst->base.value->type = ira->codegen->builtin_types.entry_void; 2791 inst->var = var; 2792 inst->var_ptr = var_ptr; 2793 2794 ir_ref_inst_gen(var_ptr); 2795 2796 return &inst->base; 2797 } 2798 2799 static IrInstSrc *ir_build_export(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2800 IrInstSrc *target, IrInstSrc *options) 2801 { 2802 IrInstSrcExport *export_instruction = ir_build_instruction<IrInstSrcExport>( 2803 irb, scope, source_node); 2804 export_instruction->target = target; 2805 export_instruction->options = options; 2806 2807 ir_ref_instruction(target, irb->current_basic_block); 2808 ir_ref_instruction(options, irb->current_basic_block); 2809 2810 return &export_instruction->base; 2811 } 2812 2813 static IrInstSrc *ir_build_load_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *ptr) { 2814 IrInstSrcLoadPtr *instruction = ir_build_instruction<IrInstSrcLoadPtr>(irb, scope, source_node); 2815 instruction->ptr = ptr; 2816 2817 ir_ref_instruction(ptr, irb->current_basic_block); 2818 2819 return &instruction->base; 2820 } 2821 2822 static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instruction, 2823 IrInstGen *ptr, ZigType *ty, IrInstGen *result_loc) 2824 { 2825 IrInstGenLoadPtr *instruction = ir_build_inst_gen<IrInstGenLoadPtr>( 2826 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2827 instruction->base.value->type = ty; 2828 instruction->ptr = ptr; 2829 instruction->result_loc = result_loc; 2830 2831 ir_ref_inst_gen(ptr); 2832 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 2833 2834 return &instruction->base; 2835 } 2836 2837 static IrInstSrc *ir_build_typeof_n(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2838 IrInstSrc **values, size_t value_count) 2839 { 2840 assert(value_count >= 2); 2841 2842 IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node); 2843 instruction->value.list = values; 2844 instruction->value_count = value_count; 2845 2846 for (size_t i = 0; i < value_count; i++) 2847 ir_ref_instruction(values[i], irb->current_basic_block); 2848 2849 return &instruction->base; 2850 } 2851 2852 static IrInstSrc *ir_build_typeof_1(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 2853 IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node); 2854 instruction->value.scalar = value; 2855 2856 ir_ref_instruction(value, irb->current_basic_block); 2857 2858 return &instruction->base; 2859 } 2860 2861 static IrInstSrc *ir_build_set_cold(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_cold) { 2862 IrInstSrcSetCold *instruction = ir_build_instruction<IrInstSrcSetCold>(irb, scope, source_node); 2863 instruction->is_cold = is_cold; 2864 2865 ir_ref_instruction(is_cold, irb->current_basic_block); 2866 2867 return &instruction->base; 2868 } 2869 2870 static IrInstSrc *ir_build_set_runtime_safety(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2871 IrInstSrc *safety_on) 2872 { 2873 IrInstSrcSetRuntimeSafety *inst = ir_build_instruction<IrInstSrcSetRuntimeSafety>(irb, scope, source_node); 2874 inst->safety_on = safety_on; 2875 2876 ir_ref_instruction(safety_on, irb->current_basic_block); 2877 2878 return &inst->base; 2879 } 2880 2881 static IrInstSrc *ir_build_set_float_mode(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2882 IrInstSrc *mode_value) 2883 { 2884 IrInstSrcSetFloatMode *instruction = ir_build_instruction<IrInstSrcSetFloatMode>(irb, scope, source_node); 2885 instruction->mode_value = mode_value; 2886 2887 ir_ref_instruction(mode_value, irb->current_basic_block); 2888 2889 return &instruction->base; 2890 } 2891 2892 static IrInstSrc *ir_build_array_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *size, 2893 IrInstSrc *sentinel, IrInstSrc *child_type) 2894 { 2895 IrInstSrcArrayType *instruction = ir_build_instruction<IrInstSrcArrayType>(irb, scope, source_node); 2896 instruction->size = size; 2897 instruction->sentinel = sentinel; 2898 instruction->child_type = child_type; 2899 2900 ir_ref_instruction(size, irb->current_basic_block); 2901 if (sentinel != nullptr) ir_ref_instruction(sentinel, irb->current_basic_block); 2902 ir_ref_instruction(child_type, irb->current_basic_block); 2903 2904 return &instruction->base; 2905 } 2906 2907 static IrInstSrc *ir_build_anyframe_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2908 IrInstSrc *payload_type) 2909 { 2910 IrInstSrcAnyFrameType *instruction = ir_build_instruction<IrInstSrcAnyFrameType>(irb, scope, source_node); 2911 instruction->payload_type = payload_type; 2912 2913 if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block); 2914 2915 return &instruction->base; 2916 } 2917 2918 static IrInstSrc *ir_build_slice_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2919 IrInstSrc *child_type, bool is_const, bool is_volatile, 2920 IrInstSrc *sentinel, IrInstSrc *align_value, bool is_allow_zero) 2921 { 2922 IrInstSrcSliceType *instruction = ir_build_instruction<IrInstSrcSliceType>(irb, scope, source_node); 2923 instruction->is_const = is_const; 2924 instruction->is_volatile = is_volatile; 2925 instruction->child_type = child_type; 2926 instruction->sentinel = sentinel; 2927 instruction->align_value = align_value; 2928 instruction->is_allow_zero = is_allow_zero; 2929 2930 if (sentinel != nullptr) ir_ref_instruction(sentinel, irb->current_basic_block); 2931 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 2932 ir_ref_instruction(child_type, irb->current_basic_block); 2933 2934 return &instruction->base; 2935 } 2936 2937 static IrInstSrc *ir_build_asm_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2938 IrInstSrc *asm_template, IrInstSrc **input_list, IrInstSrc **output_types, 2939 ZigVar **output_vars, size_t return_count, bool has_side_effects, bool is_global) 2940 { 2941 IrInstSrcAsm *instruction = ir_build_instruction<IrInstSrcAsm>(irb, scope, source_node); 2942 instruction->asm_template = asm_template; 2943 instruction->input_list = input_list; 2944 instruction->output_types = output_types; 2945 instruction->output_vars = output_vars; 2946 instruction->return_count = return_count; 2947 instruction->has_side_effects = has_side_effects; 2948 instruction->is_global = is_global; 2949 2950 assert(source_node->type == NodeTypeAsmExpr); 2951 for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) { 2952 IrInstSrc *output_type = output_types[i]; 2953 if (output_type) ir_ref_instruction(output_type, irb->current_basic_block); 2954 } 2955 2956 for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) { 2957 IrInstSrc *input_value = input_list[i]; 2958 ir_ref_instruction(input_value, irb->current_basic_block); 2959 } 2960 2961 return &instruction->base; 2962 } 2963 2964 static IrInstGen *ir_build_asm_gen(IrAnalyze *ira, IrInst *source_instr, 2965 Buf *asm_template, AsmToken *token_list, size_t token_list_len, 2966 IrInstGen **input_list, IrInstGen **output_types, ZigVar **output_vars, size_t return_count, 2967 bool has_side_effects, ZigType *return_type) 2968 { 2969 IrInstGenAsm *instruction = ir_build_inst_gen<IrInstGenAsm>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2970 instruction->base.value->type = return_type; 2971 instruction->asm_template = asm_template; 2972 instruction->token_list = token_list; 2973 instruction->token_list_len = token_list_len; 2974 instruction->input_list = input_list; 2975 instruction->output_types = output_types; 2976 instruction->output_vars = output_vars; 2977 instruction->return_count = return_count; 2978 instruction->has_side_effects = has_side_effects; 2979 2980 assert(source_instr->source_node->type == NodeTypeAsmExpr); 2981 for (size_t i = 0; i < source_instr->source_node->data.asm_expr.output_list.length; i += 1) { 2982 IrInstGen *output_type = output_types[i]; 2983 if (output_type) ir_ref_inst_gen(output_type); 2984 } 2985 2986 for (size_t i = 0; i < source_instr->source_node->data.asm_expr.input_list.length; i += 1) { 2987 IrInstGen *input_value = input_list[i]; 2988 ir_ref_inst_gen(input_value); 2989 } 2990 2991 return &instruction->base; 2992 } 2993 2994 static IrInstSrc *ir_build_size_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value, 2995 bool bit_size) 2996 { 2997 IrInstSrcSizeOf *instruction = ir_build_instruction<IrInstSrcSizeOf>(irb, scope, source_node); 2998 instruction->type_value = type_value; 2999 instruction->bit_size = bit_size; 3000 3001 ir_ref_instruction(type_value, irb->current_basic_block); 3002 3003 return &instruction->base; 3004 } 3005 3006 static IrInstSrc *ir_build_test_non_null_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3007 IrInstSrc *value) 3008 { 3009 IrInstSrcTestNonNull *instruction = ir_build_instruction<IrInstSrcTestNonNull>(irb, scope, source_node); 3010 instruction->value = value; 3011 3012 ir_ref_instruction(value, irb->current_basic_block); 3013 3014 return &instruction->base; 3015 } 3016 3017 static IrInstGen *ir_build_test_non_null_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) { 3018 IrInstGenTestNonNull *inst = ir_build_inst_gen<IrInstGenTestNonNull>(&ira->new_irb, 3019 source_instr->scope, source_instr->source_node); 3020 inst->base.value->type = ira->codegen->builtin_types.entry_bool; 3021 inst->value = value; 3022 3023 ir_ref_inst_gen(value); 3024 3025 return &inst->base; 3026 } 3027 3028 static IrInstSrc *ir_build_optional_unwrap_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3029 IrInstSrc *base_ptr, bool safety_check_on) 3030 { 3031 IrInstSrcOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstSrcOptionalUnwrapPtr>(irb, scope, source_node); 3032 instruction->base_ptr = base_ptr; 3033 instruction->safety_check_on = safety_check_on; 3034 3035 ir_ref_instruction(base_ptr, irb->current_basic_block); 3036 3037 return &instruction->base; 3038 } 3039 3040 static IrInstGen *ir_build_optional_unwrap_ptr_gen(IrAnalyze *ira, IrInst *source_instr, 3041 IrInstGen *base_ptr, bool safety_check_on, bool initializing, ZigType *result_type) 3042 { 3043 IrInstGenOptionalUnwrapPtr *inst = ir_build_inst_gen<IrInstGenOptionalUnwrapPtr>(&ira->new_irb, 3044 source_instr->scope, source_instr->source_node); 3045 inst->base.value->type = result_type; 3046 inst->base_ptr = base_ptr; 3047 inst->safety_check_on = safety_check_on; 3048 inst->initializing = initializing; 3049 3050 ir_ref_inst_gen(base_ptr); 3051 3052 return &inst->base; 3053 } 3054 3055 static IrInstGen *ir_build_optional_wrap(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_ty, 3056 IrInstGen *operand, IrInstGen *result_loc) 3057 { 3058 IrInstGenOptionalWrap *instruction = ir_build_inst_gen<IrInstGenOptionalWrap>( 3059 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3060 instruction->base.value->type = result_ty; 3061 instruction->operand = operand; 3062 instruction->result_loc = result_loc; 3063 3064 ir_ref_inst_gen(operand); 3065 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 3066 3067 return &instruction->base; 3068 } 3069 3070 static IrInstGen *ir_build_err_wrap_payload(IrAnalyze *ira, IrInst *source_instruction, 3071 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc) 3072 { 3073 IrInstGenErrWrapPayload *instruction = ir_build_inst_gen<IrInstGenErrWrapPayload>( 3074 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3075 instruction->base.value->type = result_type; 3076 instruction->operand = operand; 3077 instruction->result_loc = result_loc; 3078 3079 ir_ref_inst_gen(operand); 3080 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 3081 3082 return &instruction->base; 3083 } 3084 3085 static IrInstGen *ir_build_err_wrap_code(IrAnalyze *ira, IrInst *source_instruction, 3086 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc) 3087 { 3088 IrInstGenErrWrapCode *instruction = ir_build_inst_gen<IrInstGenErrWrapCode>( 3089 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3090 instruction->base.value->type = result_type; 3091 instruction->operand = operand; 3092 instruction->result_loc = result_loc; 3093 3094 ir_ref_inst_gen(operand); 3095 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 3096 3097 return &instruction->base; 3098 } 3099 3100 static IrInstSrc *ir_build_clz(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3101 IrInstSrc *op) 3102 { 3103 IrInstSrcClz *instruction = ir_build_instruction<IrInstSrcClz>(irb, scope, source_node); 3104 instruction->type = type; 3105 instruction->op = op; 3106 3107 ir_ref_instruction(type, irb->current_basic_block); 3108 ir_ref_instruction(op, irb->current_basic_block); 3109 3110 return &instruction->base; 3111 } 3112 3113 static IrInstGen *ir_build_clz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) { 3114 IrInstGenClz *instruction = ir_build_inst_gen<IrInstGenClz>(&ira->new_irb, 3115 source_instr->scope, source_instr->source_node); 3116 instruction->base.value->type = result_type; 3117 instruction->op = op; 3118 3119 ir_ref_inst_gen(op); 3120 3121 return &instruction->base; 3122 } 3123 3124 static IrInstSrc *ir_build_ctz(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3125 IrInstSrc *op) 3126 { 3127 IrInstSrcCtz *instruction = ir_build_instruction<IrInstSrcCtz>(irb, scope, source_node); 3128 instruction->type = type; 3129 instruction->op = op; 3130 3131 ir_ref_instruction(type, irb->current_basic_block); 3132 ir_ref_instruction(op, irb->current_basic_block); 3133 3134 return &instruction->base; 3135 } 3136 3137 static IrInstGen *ir_build_ctz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) { 3138 IrInstGenCtz *instruction = ir_build_inst_gen<IrInstGenCtz>(&ira->new_irb, 3139 source_instr->scope, source_instr->source_node); 3140 instruction->base.value->type = result_type; 3141 instruction->op = op; 3142 3143 ir_ref_inst_gen(op); 3144 3145 return &instruction->base; 3146 } 3147 3148 static IrInstSrc *ir_build_pop_count(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3149 IrInstSrc *op) 3150 { 3151 IrInstSrcPopCount *instruction = ir_build_instruction<IrInstSrcPopCount>(irb, scope, source_node); 3152 instruction->type = type; 3153 instruction->op = op; 3154 3155 ir_ref_instruction(type, irb->current_basic_block); 3156 ir_ref_instruction(op, irb->current_basic_block); 3157 3158 return &instruction->base; 3159 } 3160 3161 static IrInstGen *ir_build_pop_count_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, 3162 IrInstGen *op) 3163 { 3164 IrInstGenPopCount *instruction = ir_build_inst_gen<IrInstGenPopCount>(&ira->new_irb, 3165 source_instr->scope, source_instr->source_node); 3166 instruction->base.value->type = result_type; 3167 instruction->op = op; 3168 3169 ir_ref_inst_gen(op); 3170 3171 return &instruction->base; 3172 } 3173 3174 static IrInstSrc *ir_build_bswap(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3175 IrInstSrc *op) 3176 { 3177 IrInstSrcBswap *instruction = ir_build_instruction<IrInstSrcBswap>(irb, scope, source_node); 3178 instruction->type = type; 3179 instruction->op = op; 3180 3181 ir_ref_instruction(type, irb->current_basic_block); 3182 ir_ref_instruction(op, irb->current_basic_block); 3183 3184 return &instruction->base; 3185 } 3186 3187 static IrInstGen *ir_build_bswap_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *op_type, 3188 IrInstGen *op) 3189 { 3190 IrInstGenBswap *instruction = ir_build_inst_gen<IrInstGenBswap>(&ira->new_irb, 3191 source_instr->scope, source_instr->source_node); 3192 instruction->base.value->type = op_type; 3193 instruction->op = op; 3194 3195 ir_ref_inst_gen(op); 3196 3197 return &instruction->base; 3198 } 3199 3200 static IrInstSrc *ir_build_bit_reverse(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3201 IrInstSrc *op) 3202 { 3203 IrInstSrcBitReverse *instruction = ir_build_instruction<IrInstSrcBitReverse>(irb, scope, source_node); 3204 instruction->type = type; 3205 instruction->op = op; 3206 3207 ir_ref_instruction(type, irb->current_basic_block); 3208 ir_ref_instruction(op, irb->current_basic_block); 3209 3210 return &instruction->base; 3211 } 3212 3213 static IrInstGen *ir_build_bit_reverse_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *int_type, 3214 IrInstGen *op) 3215 { 3216 IrInstGenBitReverse *instruction = ir_build_inst_gen<IrInstGenBitReverse>(&ira->new_irb, 3217 source_instr->scope, source_instr->source_node); 3218 instruction->base.value->type = int_type; 3219 instruction->op = op; 3220 3221 ir_ref_inst_gen(op); 3222 3223 return &instruction->base; 3224 } 3225 3226 static IrInstSrcSwitchBr *ir_build_switch_br_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3227 IrInstSrc *target_value, IrBasicBlockSrc *else_block, size_t case_count, IrInstSrcSwitchBrCase *cases, 3228 IrInstSrc *is_comptime, IrInstSrc *switch_prongs_void) 3229 { 3230 IrInstSrcSwitchBr *instruction = ir_build_instruction<IrInstSrcSwitchBr>(irb, scope, source_node); 3231 instruction->base.is_noreturn = true; 3232 instruction->target_value = target_value; 3233 instruction->else_block = else_block; 3234 instruction->case_count = case_count; 3235 instruction->cases = cases; 3236 instruction->is_comptime = is_comptime; 3237 instruction->switch_prongs_void = switch_prongs_void; 3238 3239 ir_ref_instruction(target_value, irb->current_basic_block); 3240 ir_ref_instruction(is_comptime, irb->current_basic_block); 3241 ir_ref_bb(else_block); 3242 ir_ref_instruction(switch_prongs_void, irb->current_basic_block); 3243 3244 for (size_t i = 0; i < case_count; i += 1) { 3245 ir_ref_instruction(cases[i].value, irb->current_basic_block); 3246 ir_ref_bb(cases[i].block); 3247 } 3248 3249 return instruction; 3250 } 3251 3252 static IrInstGenSwitchBr *ir_build_switch_br_gen(IrAnalyze *ira, IrInst *source_instr, 3253 IrInstGen *target_value, IrBasicBlockGen *else_block, size_t case_count, IrInstGenSwitchBrCase *cases) 3254 { 3255 IrInstGenSwitchBr *instruction = ir_build_inst_noreturn<IrInstGenSwitchBr>(&ira->new_irb, 3256 source_instr->scope, source_instr->source_node); 3257 instruction->target_value = target_value; 3258 instruction->else_block = else_block; 3259 instruction->case_count = case_count; 3260 instruction->cases = cases; 3261 3262 ir_ref_inst_gen(target_value); 3263 3264 for (size_t i = 0; i < case_count; i += 1) { 3265 ir_ref_inst_gen(cases[i].value); 3266 } 3267 3268 return instruction; 3269 } 3270 3271 static IrInstSrc *ir_build_switch_target(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3272 IrInstSrc *target_value_ptr) 3273 { 3274 IrInstSrcSwitchTarget *instruction = ir_build_instruction<IrInstSrcSwitchTarget>(irb, scope, source_node); 3275 instruction->target_value_ptr = target_value_ptr; 3276 3277 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 3278 3279 return &instruction->base; 3280 } 3281 3282 static IrInstSrc *ir_build_switch_var(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3283 IrInstSrc *target_value_ptr, IrInstSrc **prongs_ptr, size_t prongs_len) 3284 { 3285 IrInstSrcSwitchVar *instruction = ir_build_instruction<IrInstSrcSwitchVar>(irb, scope, source_node); 3286 instruction->target_value_ptr = target_value_ptr; 3287 instruction->prongs_ptr = prongs_ptr; 3288 instruction->prongs_len = prongs_len; 3289 3290 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 3291 for (size_t i = 0; i < prongs_len; i += 1) { 3292 ir_ref_instruction(prongs_ptr[i], irb->current_basic_block); 3293 } 3294 3295 return &instruction->base; 3296 } 3297 3298 // For this instruction the switch_br must be set later. 3299 static IrInstSrcSwitchElseVar *ir_build_switch_else_var(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3300 IrInstSrc *target_value_ptr) 3301 { 3302 IrInstSrcSwitchElseVar *instruction = ir_build_instruction<IrInstSrcSwitchElseVar>(irb, scope, source_node); 3303 instruction->target_value_ptr = target_value_ptr; 3304 3305 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 3306 3307 return instruction; 3308 } 3309 3310 static IrInstGen *ir_build_union_tag(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, 3311 ZigType *tag_type) 3312 { 3313 IrInstGenUnionTag *instruction = ir_build_inst_gen<IrInstGenUnionTag>(&ira->new_irb, 3314 source_instr->scope, source_instr->source_node); 3315 instruction->value = value; 3316 instruction->base.value->type = tag_type; 3317 3318 ir_ref_inst_gen(value); 3319 3320 return &instruction->base; 3321 } 3322 3323 static IrInstSrc *ir_build_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { 3324 IrInstSrcImport *instruction = ir_build_instruction<IrInstSrcImport>(irb, scope, source_node); 3325 instruction->name = name; 3326 3327 ir_ref_instruction(name, irb->current_basic_block); 3328 3329 return &instruction->base; 3330 } 3331 3332 static IrInstSrc *ir_build_ref_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 3333 IrInstSrcRef *instruction = ir_build_instruction<IrInstSrcRef>(irb, scope, source_node); 3334 instruction->value = value; 3335 3336 ir_ref_instruction(value, irb->current_basic_block); 3337 3338 return &instruction->base; 3339 } 3340 3341 static IrInstGen *ir_build_ref_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type, 3342 IrInstGen *operand, IrInstGen *result_loc) 3343 { 3344 IrInstGenRef *instruction = ir_build_inst_gen<IrInstGenRef>(&ira->new_irb, 3345 source_instruction->scope, source_instruction->source_node); 3346 instruction->base.value->type = result_type; 3347 instruction->operand = operand; 3348 instruction->result_loc = result_loc; 3349 3350 ir_ref_inst_gen(operand); 3351 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 3352 3353 return &instruction->base; 3354 } 3355 3356 static IrInstSrc *ir_build_compile_err(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *msg) { 3357 IrInstSrcCompileErr *instruction = ir_build_instruction<IrInstSrcCompileErr>(irb, scope, source_node); 3358 instruction->msg = msg; 3359 3360 ir_ref_instruction(msg, irb->current_basic_block); 3361 3362 return &instruction->base; 3363 } 3364 3365 static IrInstSrc *ir_build_compile_log(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3366 size_t msg_count, IrInstSrc **msg_list) 3367 { 3368 IrInstSrcCompileLog *instruction = ir_build_instruction<IrInstSrcCompileLog>(irb, scope, source_node); 3369 instruction->msg_count = msg_count; 3370 instruction->msg_list = msg_list; 3371 3372 for (size_t i = 0; i < msg_count; i += 1) { 3373 ir_ref_instruction(msg_list[i], irb->current_basic_block); 3374 } 3375 3376 return &instruction->base; 3377 } 3378 3379 static IrInstSrc *ir_build_err_name(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 3380 IrInstSrcErrName *instruction = ir_build_instruction<IrInstSrcErrName>(irb, scope, source_node); 3381 instruction->value = value; 3382 3383 ir_ref_instruction(value, irb->current_basic_block); 3384 3385 return &instruction->base; 3386 } 3387 3388 static IrInstGen *ir_build_err_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, 3389 ZigType *str_type) 3390 { 3391 IrInstGenErrName *instruction = ir_build_inst_gen<IrInstGenErrName>(&ira->new_irb, 3392 source_instr->scope, source_instr->source_node); 3393 instruction->base.value->type = str_type; 3394 instruction->value = value; 3395 3396 ir_ref_inst_gen(value); 3397 3398 return &instruction->base; 3399 } 3400 3401 static IrInstSrc *ir_build_c_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3402 IrInstSrcCImport *instruction = ir_build_instruction<IrInstSrcCImport>(irb, scope, source_node); 3403 return &instruction->base; 3404 } 3405 3406 static IrInstSrc *ir_build_c_include(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { 3407 IrInstSrcCInclude *instruction = ir_build_instruction<IrInstSrcCInclude>(irb, scope, source_node); 3408 instruction->name = name; 3409 3410 ir_ref_instruction(name, irb->current_basic_block); 3411 3412 return &instruction->base; 3413 } 3414 3415 static IrInstSrc *ir_build_c_define(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name, IrInstSrc *value) { 3416 IrInstSrcCDefine *instruction = ir_build_instruction<IrInstSrcCDefine>(irb, scope, source_node); 3417 instruction->name = name; 3418 instruction->value = value; 3419 3420 ir_ref_instruction(name, irb->current_basic_block); 3421 ir_ref_instruction(value, irb->current_basic_block); 3422 3423 return &instruction->base; 3424 } 3425 3426 static IrInstSrc *ir_build_c_undef(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { 3427 IrInstSrcCUndef *instruction = ir_build_instruction<IrInstSrcCUndef>(irb, scope, source_node); 3428 instruction->name = name; 3429 3430 ir_ref_instruction(name, irb->current_basic_block); 3431 3432 return &instruction->base; 3433 } 3434 3435 static IrInstSrc *ir_build_embed_file(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { 3436 IrInstSrcEmbedFile *instruction = ir_build_instruction<IrInstSrcEmbedFile>(irb, scope, source_node); 3437 instruction->name = name; 3438 3439 ir_ref_instruction(name, irb->current_basic_block); 3440 3441 return &instruction->base; 3442 } 3443 3444 static IrInstSrc *ir_build_cmpxchg_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3445 IrInstSrc *type_value, IrInstSrc *ptr, IrInstSrc *cmp_value, IrInstSrc *new_value, 3446 IrInstSrc *success_order_value, IrInstSrc *failure_order_value, bool is_weak, ResultLoc *result_loc) 3447 { 3448 IrInstSrcCmpxchg *instruction = ir_build_instruction<IrInstSrcCmpxchg>(irb, scope, source_node); 3449 instruction->type_value = type_value; 3450 instruction->ptr = ptr; 3451 instruction->cmp_value = cmp_value; 3452 instruction->new_value = new_value; 3453 instruction->success_order_value = success_order_value; 3454 instruction->failure_order_value = failure_order_value; 3455 instruction->is_weak = is_weak; 3456 instruction->result_loc = result_loc; 3457 3458 ir_ref_instruction(type_value, irb->current_basic_block); 3459 ir_ref_instruction(ptr, irb->current_basic_block); 3460 ir_ref_instruction(cmp_value, irb->current_basic_block); 3461 ir_ref_instruction(new_value, irb->current_basic_block); 3462 ir_ref_instruction(success_order_value, irb->current_basic_block); 3463 ir_ref_instruction(failure_order_value, irb->current_basic_block); 3464 3465 return &instruction->base; 3466 } 3467 3468 static IrInstGen *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type, 3469 IrInstGen *ptr, IrInstGen *cmp_value, IrInstGen *new_value, 3470 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstGen *result_loc) 3471 { 3472 IrInstGenCmpxchg *instruction = ir_build_inst_gen<IrInstGenCmpxchg>(&ira->new_irb, 3473 source_instruction->scope, source_instruction->source_node); 3474 instruction->base.value->type = result_type; 3475 instruction->ptr = ptr; 3476 instruction->cmp_value = cmp_value; 3477 instruction->new_value = new_value; 3478 instruction->success_order = success_order; 3479 instruction->failure_order = failure_order; 3480 instruction->is_weak = is_weak; 3481 instruction->result_loc = result_loc; 3482 3483 ir_ref_inst_gen(ptr); 3484 ir_ref_inst_gen(cmp_value); 3485 ir_ref_inst_gen(new_value); 3486 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 3487 3488 return &instruction->base; 3489 } 3490 3491 static IrInstSrc *ir_build_fence(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *order) { 3492 IrInstSrcFence *instruction = ir_build_instruction<IrInstSrcFence>(irb, scope, source_node); 3493 instruction->order = order; 3494 3495 ir_ref_instruction(order, irb->current_basic_block); 3496 3497 return &instruction->base; 3498 } 3499 3500 static IrInstGen *ir_build_fence_gen(IrAnalyze *ira, IrInst *source_instr, AtomicOrder order) { 3501 IrInstGenFence *instruction = ir_build_inst_void<IrInstGenFence>(&ira->new_irb, 3502 source_instr->scope, source_instr->source_node); 3503 instruction->order = order; 3504 3505 return &instruction->base; 3506 } 3507 3508 static IrInstSrc *ir_build_truncate(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3509 IrInstSrc *dest_type, IrInstSrc *target) 3510 { 3511 IrInstSrcTruncate *instruction = ir_build_instruction<IrInstSrcTruncate>(irb, scope, source_node); 3512 instruction->dest_type = dest_type; 3513 instruction->target = target; 3514 3515 ir_ref_instruction(dest_type, irb->current_basic_block); 3516 ir_ref_instruction(target, irb->current_basic_block); 3517 3518 return &instruction->base; 3519 } 3520 3521 static IrInstGen *ir_build_truncate_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *dest_type, 3522 IrInstGen *target) 3523 { 3524 IrInstGenTruncate *instruction = ir_build_inst_gen<IrInstGenTruncate>(&ira->new_irb, 3525 source_instr->scope, source_instr->source_node); 3526 instruction->base.value->type = dest_type; 3527 instruction->target = target; 3528 3529 ir_ref_inst_gen(target); 3530 3531 return &instruction->base; 3532 } 3533 3534 static IrInstSrc *ir_build_int_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *dest_type, 3535 IrInstSrc *target) 3536 { 3537 IrInstSrcIntCast *instruction = ir_build_instruction<IrInstSrcIntCast>(irb, scope, source_node); 3538 instruction->dest_type = dest_type; 3539 instruction->target = target; 3540 3541 ir_ref_instruction(dest_type, irb->current_basic_block); 3542 ir_ref_instruction(target, irb->current_basic_block); 3543 3544 return &instruction->base; 3545 } 3546 3547 static IrInstSrc *ir_build_float_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *dest_type, 3548 IrInstSrc *target) 3549 { 3550 IrInstSrcFloatCast *instruction = ir_build_instruction<IrInstSrcFloatCast>(irb, scope, source_node); 3551 instruction->dest_type = dest_type; 3552 instruction->target = target; 3553 3554 ir_ref_instruction(dest_type, irb->current_basic_block); 3555 ir_ref_instruction(target, irb->current_basic_block); 3556 3557 return &instruction->base; 3558 } 3559 3560 static IrInstSrc *ir_build_err_set_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3561 IrInstSrc *dest_type, IrInstSrc *target) 3562 { 3563 IrInstSrcErrSetCast *instruction = ir_build_instruction<IrInstSrcErrSetCast>(irb, scope, source_node); 3564 instruction->dest_type = dest_type; 3565 instruction->target = target; 3566 3567 ir_ref_instruction(dest_type, irb->current_basic_block); 3568 ir_ref_instruction(target, irb->current_basic_block); 3569 3570 return &instruction->base; 3571 } 3572 3573 static IrInstSrc *ir_build_int_to_float(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3574 IrInstSrc *dest_type, IrInstSrc *target) 3575 { 3576 IrInstSrcIntToFloat *instruction = ir_build_instruction<IrInstSrcIntToFloat>(irb, scope, source_node); 3577 instruction->dest_type = dest_type; 3578 instruction->target = target; 3579 3580 ir_ref_instruction(dest_type, irb->current_basic_block); 3581 ir_ref_instruction(target, irb->current_basic_block); 3582 3583 return &instruction->base; 3584 } 3585 3586 static IrInstSrc *ir_build_float_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3587 IrInstSrc *dest_type, IrInstSrc *target) 3588 { 3589 IrInstSrcFloatToInt *instruction = ir_build_instruction<IrInstSrcFloatToInt>(irb, scope, source_node); 3590 instruction->dest_type = dest_type; 3591 instruction->target = target; 3592 3593 ir_ref_instruction(dest_type, irb->current_basic_block); 3594 ir_ref_instruction(target, irb->current_basic_block); 3595 3596 return &instruction->base; 3597 } 3598 3599 static IrInstSrc *ir_build_bool_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target) { 3600 IrInstSrcBoolToInt *instruction = ir_build_instruction<IrInstSrcBoolToInt>(irb, scope, source_node); 3601 instruction->target = target; 3602 3603 ir_ref_instruction(target, irb->current_basic_block); 3604 3605 return &instruction->base; 3606 } 3607 3608 static IrInstSrc *ir_build_vector_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *len, 3609 IrInstSrc *elem_type) 3610 { 3611 IrInstSrcVectorType *instruction = ir_build_instruction<IrInstSrcVectorType>(irb, scope, source_node); 3612 instruction->len = len; 3613 instruction->elem_type = elem_type; 3614 3615 ir_ref_instruction(len, irb->current_basic_block); 3616 ir_ref_instruction(elem_type, irb->current_basic_block); 3617 3618 return &instruction->base; 3619 } 3620 3621 static IrInstSrc *ir_build_shuffle_vector(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3622 IrInstSrc *scalar_type, IrInstSrc *a, IrInstSrc *b, IrInstSrc *mask) 3623 { 3624 IrInstSrcShuffleVector *instruction = ir_build_instruction<IrInstSrcShuffleVector>(irb, scope, source_node); 3625 instruction->scalar_type = scalar_type; 3626 instruction->a = a; 3627 instruction->b = b; 3628 instruction->mask = mask; 3629 3630 if (scalar_type != nullptr) ir_ref_instruction(scalar_type, irb->current_basic_block); 3631 ir_ref_instruction(a, irb->current_basic_block); 3632 ir_ref_instruction(b, irb->current_basic_block); 3633 ir_ref_instruction(mask, irb->current_basic_block); 3634 3635 return &instruction->base; 3636 } 3637 3638 static IrInstGen *ir_build_shuffle_vector_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 3639 ZigType *result_type, IrInstGen *a, IrInstGen *b, IrInstGen *mask) 3640 { 3641 IrInstGenShuffleVector *inst = ir_build_inst_gen<IrInstGenShuffleVector>(&ira->new_irb, scope, source_node); 3642 inst->base.value->type = result_type; 3643 inst->a = a; 3644 inst->b = b; 3645 inst->mask = mask; 3646 3647 ir_ref_inst_gen(a); 3648 ir_ref_inst_gen(b); 3649 ir_ref_inst_gen(mask); 3650 3651 return &inst->base; 3652 } 3653 3654 static IrInstSrc *ir_build_splat_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3655 IrInstSrc *len, IrInstSrc *scalar) 3656 { 3657 IrInstSrcSplat *instruction = ir_build_instruction<IrInstSrcSplat>(irb, scope, source_node); 3658 instruction->len = len; 3659 instruction->scalar = scalar; 3660 3661 ir_ref_instruction(len, irb->current_basic_block); 3662 ir_ref_instruction(scalar, irb->current_basic_block); 3663 3664 return &instruction->base; 3665 } 3666 3667 static IrInstGen *ir_build_splat_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type, 3668 IrInstGen *scalar) 3669 { 3670 IrInstGenSplat *instruction = ir_build_inst_gen<IrInstGenSplat>( 3671 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3672 instruction->base.value->type = result_type; 3673 instruction->scalar = scalar; 3674 3675 ir_ref_inst_gen(scalar); 3676 3677 return &instruction->base; 3678 } 3679 3680 static IrInstSrc *ir_build_bool_not(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 3681 IrInstSrcBoolNot *instruction = ir_build_instruction<IrInstSrcBoolNot>(irb, scope, source_node); 3682 instruction->value = value; 3683 3684 ir_ref_instruction(value, irb->current_basic_block); 3685 3686 return &instruction->base; 3687 } 3688 3689 static IrInstGen *ir_build_bool_not_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) { 3690 IrInstGenBoolNot *instruction = ir_build_inst_gen<IrInstGenBoolNot>(&ira->new_irb, 3691 source_instr->scope, source_instr->source_node); 3692 instruction->base.value->type = ira->codegen->builtin_types.entry_bool; 3693 instruction->value = value; 3694 3695 ir_ref_inst_gen(value); 3696 3697 return &instruction->base; 3698 } 3699 3700 static IrInstSrc *ir_build_memset_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3701 IrInstSrc *dest_ptr, IrInstSrc *byte, IrInstSrc *count) 3702 { 3703 IrInstSrcMemset *instruction = ir_build_instruction<IrInstSrcMemset>(irb, scope, source_node); 3704 instruction->dest_ptr = dest_ptr; 3705 instruction->byte = byte; 3706 instruction->count = count; 3707 3708 ir_ref_instruction(dest_ptr, irb->current_basic_block); 3709 ir_ref_instruction(byte, irb->current_basic_block); 3710 ir_ref_instruction(count, irb->current_basic_block); 3711 3712 return &instruction->base; 3713 } 3714 3715 static IrInstGen *ir_build_memset_gen(IrAnalyze *ira, IrInst *source_instr, 3716 IrInstGen *dest_ptr, IrInstGen *byte, IrInstGen *count) 3717 { 3718 IrInstGenMemset *instruction = ir_build_inst_void<IrInstGenMemset>(&ira->new_irb, 3719 source_instr->scope, source_instr->source_node); 3720 instruction->dest_ptr = dest_ptr; 3721 instruction->byte = byte; 3722 instruction->count = count; 3723 3724 ir_ref_inst_gen(dest_ptr); 3725 ir_ref_inst_gen(byte); 3726 ir_ref_inst_gen(count); 3727 3728 return &instruction->base; 3729 } 3730 3731 static IrInstSrc *ir_build_memcpy_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3732 IrInstSrc *dest_ptr, IrInstSrc *src_ptr, IrInstSrc *count) 3733 { 3734 IrInstSrcMemcpy *instruction = ir_build_instruction<IrInstSrcMemcpy>(irb, scope, source_node); 3735 instruction->dest_ptr = dest_ptr; 3736 instruction->src_ptr = src_ptr; 3737 instruction->count = count; 3738 3739 ir_ref_instruction(dest_ptr, irb->current_basic_block); 3740 ir_ref_instruction(src_ptr, irb->current_basic_block); 3741 ir_ref_instruction(count, irb->current_basic_block); 3742 3743 return &instruction->base; 3744 } 3745 3746 static IrInstGen *ir_build_memcpy_gen(IrAnalyze *ira, IrInst *source_instr, 3747 IrInstGen *dest_ptr, IrInstGen *src_ptr, IrInstGen *count) 3748 { 3749 IrInstGenMemcpy *instruction = ir_build_inst_void<IrInstGenMemcpy>(&ira->new_irb, 3750 source_instr->scope, source_instr->source_node); 3751 instruction->dest_ptr = dest_ptr; 3752 instruction->src_ptr = src_ptr; 3753 instruction->count = count; 3754 3755 ir_ref_inst_gen(dest_ptr); 3756 ir_ref_inst_gen(src_ptr); 3757 ir_ref_inst_gen(count); 3758 3759 return &instruction->base; 3760 } 3761 3762 static IrInstSrc *ir_build_slice_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3763 IrInstSrc *ptr, IrInstSrc *start, IrInstSrc *end, IrInstSrc *sentinel, 3764 bool safety_check_on, ResultLoc *result_loc) 3765 { 3766 IrInstSrcSlice *instruction = ir_build_instruction<IrInstSrcSlice>(irb, scope, source_node); 3767 instruction->ptr = ptr; 3768 instruction->start = start; 3769 instruction->end = end; 3770 instruction->sentinel = sentinel; 3771 instruction->safety_check_on = safety_check_on; 3772 instruction->result_loc = result_loc; 3773 3774 ir_ref_instruction(ptr, irb->current_basic_block); 3775 ir_ref_instruction(start, irb->current_basic_block); 3776 if (end) ir_ref_instruction(end, irb->current_basic_block); 3777 if (sentinel) ir_ref_instruction(sentinel, irb->current_basic_block); 3778 3779 return &instruction->base; 3780 } 3781 3782 static IrInstGen *ir_build_slice_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *slice_type, 3783 IrInstGen *ptr, IrInstGen *start, IrInstGen *end, bool safety_check_on, IrInstGen *result_loc, 3784 ZigValue *sentinel) 3785 { 3786 IrInstGenSlice *instruction = ir_build_inst_gen<IrInstGenSlice>( 3787 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3788 instruction->base.value->type = slice_type; 3789 instruction->ptr = ptr; 3790 instruction->start = start; 3791 instruction->end = end; 3792 instruction->safety_check_on = safety_check_on; 3793 instruction->result_loc = result_loc; 3794 instruction->sentinel = sentinel; 3795 3796 ir_ref_inst_gen(ptr); 3797 ir_ref_inst_gen(start); 3798 if (end != nullptr) ir_ref_inst_gen(end); 3799 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 3800 3801 return &instruction->base; 3802 } 3803 3804 static IrInstSrc *ir_build_breakpoint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3805 IrInstSrcBreakpoint *instruction = ir_build_instruction<IrInstSrcBreakpoint>(irb, scope, source_node); 3806 return &instruction->base; 3807 } 3808 3809 static IrInstGen *ir_build_breakpoint_gen(IrAnalyze *ira, IrInst *source_instr) { 3810 IrInstGenBreakpoint *instruction = ir_build_inst_void<IrInstGenBreakpoint>(&ira->new_irb, 3811 source_instr->scope, source_instr->source_node); 3812 return &instruction->base; 3813 } 3814 3815 static IrInstSrc *ir_build_return_address_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3816 IrInstSrcReturnAddress *instruction = ir_build_instruction<IrInstSrcReturnAddress>(irb, scope, source_node); 3817 return &instruction->base; 3818 } 3819 3820 static IrInstGen *ir_build_return_address_gen(IrAnalyze *ira, IrInst *source_instr) { 3821 IrInstGenReturnAddress *inst = ir_build_inst_gen<IrInstGenReturnAddress>(&ira->new_irb, source_instr->scope, source_instr->source_node); 3822 inst->base.value->type = ira->codegen->builtin_types.entry_usize; 3823 return &inst->base; 3824 } 3825 3826 static IrInstSrc *ir_build_frame_address_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3827 IrInstSrcFrameAddress *inst = ir_build_instruction<IrInstSrcFrameAddress>(irb, scope, source_node); 3828 return &inst->base; 3829 } 3830 3831 static IrInstGen *ir_build_frame_address_gen(IrAnalyze *ira, IrInst *source_instr) { 3832 IrInstGenFrameAddress *inst = ir_build_inst_gen<IrInstGenFrameAddress>(&ira->new_irb, source_instr->scope, source_instr->source_node); 3833 inst->base.value->type = ira->codegen->builtin_types.entry_usize; 3834 return &inst->base; 3835 } 3836 3837 static IrInstSrc *ir_build_handle_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3838 IrInstSrcFrameHandle *inst = ir_build_instruction<IrInstSrcFrameHandle>(irb, scope, source_node); 3839 return &inst->base; 3840 } 3841 3842 static IrInstGen *ir_build_handle_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *ty) { 3843 IrInstGenFrameHandle *inst = ir_build_inst_gen<IrInstGenFrameHandle>(&ira->new_irb, source_instr->scope, source_instr->source_node); 3844 inst->base.value->type = ty; 3845 return &inst->base; 3846 } 3847 3848 static IrInstSrc *ir_build_frame_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *fn) { 3849 IrInstSrcFrameType *inst = ir_build_instruction<IrInstSrcFrameType>(irb, scope, source_node); 3850 inst->fn = fn; 3851 3852 ir_ref_instruction(fn, irb->current_basic_block); 3853 3854 return &inst->base; 3855 } 3856 3857 static IrInstSrc *ir_build_frame_size_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *fn) { 3858 IrInstSrcFrameSize *inst = ir_build_instruction<IrInstSrcFrameSize>(irb, scope, source_node); 3859 inst->fn = fn; 3860 3861 ir_ref_instruction(fn, irb->current_basic_block); 3862 3863 return &inst->base; 3864 } 3865 3866 static IrInstGen *ir_build_frame_size_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *fn) 3867 { 3868 IrInstGenFrameSize *inst = ir_build_inst_gen<IrInstGenFrameSize>(&ira->new_irb, source_instr->scope, source_instr->source_node); 3869 inst->base.value->type = ira->codegen->builtin_types.entry_usize; 3870 inst->fn = fn; 3871 3872 ir_ref_inst_gen(fn); 3873 3874 return &inst->base; 3875 } 3876 3877 static IrInstSrc *ir_build_overflow_op_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3878 IrOverflowOp op, IrInstSrc *type_value, IrInstSrc *op1, IrInstSrc *op2, IrInstSrc *result_ptr) 3879 { 3880 IrInstSrcOverflowOp *instruction = ir_build_instruction<IrInstSrcOverflowOp>(irb, scope, source_node); 3881 instruction->op = op; 3882 instruction->type_value = type_value; 3883 instruction->op1 = op1; 3884 instruction->op2 = op2; 3885 instruction->result_ptr = result_ptr; 3886 3887 ir_ref_instruction(type_value, irb->current_basic_block); 3888 ir_ref_instruction(op1, irb->current_basic_block); 3889 ir_ref_instruction(op2, irb->current_basic_block); 3890 ir_ref_instruction(result_ptr, irb->current_basic_block); 3891 3892 return &instruction->base; 3893 } 3894 3895 static IrInstGen *ir_build_overflow_op_gen(IrAnalyze *ira, IrInst *source_instr, 3896 IrOverflowOp op, IrInstGen *op1, IrInstGen *op2, IrInstGen *result_ptr, 3897 ZigType *result_ptr_type) 3898 { 3899 IrInstGenOverflowOp *instruction = ir_build_inst_gen<IrInstGenOverflowOp>(&ira->new_irb, 3900 source_instr->scope, source_instr->source_node); 3901 instruction->base.value->type = ira->codegen->builtin_types.entry_bool; 3902 instruction->op = op; 3903 instruction->op1 = op1; 3904 instruction->op2 = op2; 3905 instruction->result_ptr = result_ptr; 3906 instruction->result_ptr_type = result_ptr_type; 3907 3908 ir_ref_inst_gen(op1); 3909 ir_ref_inst_gen(op2); 3910 ir_ref_inst_gen(result_ptr); 3911 3912 return &instruction->base; 3913 } 3914 3915 static IrInstSrc *ir_build_float_op_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *operand, 3916 BuiltinFnId fn_id) 3917 { 3918 IrInstSrcFloatOp *instruction = ir_build_instruction<IrInstSrcFloatOp>(irb, scope, source_node); 3919 instruction->operand = operand; 3920 instruction->fn_id = fn_id; 3921 3922 ir_ref_instruction(operand, irb->current_basic_block); 3923 3924 return &instruction->base; 3925 } 3926 3927 static IrInstGen *ir_build_float_op_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, 3928 BuiltinFnId fn_id, ZigType *operand_type) 3929 { 3930 IrInstGenFloatOp *instruction = ir_build_inst_gen<IrInstGenFloatOp>(&ira->new_irb, 3931 source_instr->scope, source_instr->source_node); 3932 instruction->base.value->type = operand_type; 3933 instruction->operand = operand; 3934 instruction->fn_id = fn_id; 3935 3936 ir_ref_inst_gen(operand); 3937 3938 return &instruction->base; 3939 } 3940 3941 static IrInstSrc *ir_build_mul_add_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3942 IrInstSrc *type_value, IrInstSrc *op1, IrInstSrc *op2, IrInstSrc *op3) 3943 { 3944 IrInstSrcMulAdd *instruction = ir_build_instruction<IrInstSrcMulAdd>(irb, scope, source_node); 3945 instruction->type_value = type_value; 3946 instruction->op1 = op1; 3947 instruction->op2 = op2; 3948 instruction->op3 = op3; 3949 3950 ir_ref_instruction(type_value, irb->current_basic_block); 3951 ir_ref_instruction(op1, irb->current_basic_block); 3952 ir_ref_instruction(op2, irb->current_basic_block); 3953 ir_ref_instruction(op3, irb->current_basic_block); 3954 3955 return &instruction->base; 3956 } 3957 3958 static IrInstGen *ir_build_mul_add_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *op1, IrInstGen *op2, 3959 IrInstGen *op3, ZigType *expr_type) 3960 { 3961 IrInstGenMulAdd *instruction = ir_build_inst_gen<IrInstGenMulAdd>(&ira->new_irb, 3962 source_instr->scope, source_instr->source_node); 3963 instruction->base.value->type = expr_type; 3964 instruction->op1 = op1; 3965 instruction->op2 = op2; 3966 instruction->op3 = op3; 3967 3968 ir_ref_inst_gen(op1); 3969 ir_ref_inst_gen(op2); 3970 ir_ref_inst_gen(op3); 3971 3972 return &instruction->base; 3973 } 3974 3975 static IrInstSrc *ir_build_align_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value) { 3976 IrInstSrcAlignOf *instruction = ir_build_instruction<IrInstSrcAlignOf>(irb, scope, source_node); 3977 instruction->type_value = type_value; 3978 3979 ir_ref_instruction(type_value, irb->current_basic_block); 3980 3981 return &instruction->base; 3982 } 3983 3984 static IrInstSrc *ir_build_test_err_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3985 IrInstSrc *base_ptr, bool resolve_err_set, bool base_ptr_is_payload) 3986 { 3987 IrInstSrcTestErr *instruction = ir_build_instruction<IrInstSrcTestErr>(irb, scope, source_node); 3988 instruction->base_ptr = base_ptr; 3989 instruction->resolve_err_set = resolve_err_set; 3990 instruction->base_ptr_is_payload = base_ptr_is_payload; 3991 3992 ir_ref_instruction(base_ptr, irb->current_basic_block); 3993 3994 return &instruction->base; 3995 } 3996 3997 static IrInstGen *ir_build_test_err_gen(IrAnalyze *ira, IrInst *source_instruction, IrInstGen *err_union) { 3998 IrInstGenTestErr *instruction = ir_build_inst_gen<IrInstGenTestErr>( 3999 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 4000 instruction->base.value->type = ira->codegen->builtin_types.entry_bool; 4001 instruction->err_union = err_union; 4002 4003 ir_ref_inst_gen(err_union); 4004 4005 return &instruction->base; 4006 } 4007 4008 static IrInstSrc *ir_build_unwrap_err_code_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4009 IrInstSrc *err_union_ptr) 4010 { 4011 IrInstSrcUnwrapErrCode *inst = ir_build_instruction<IrInstSrcUnwrapErrCode>(irb, scope, source_node); 4012 inst->err_union_ptr = err_union_ptr; 4013 4014 ir_ref_instruction(err_union_ptr, irb->current_basic_block); 4015 4016 return &inst->base; 4017 } 4018 4019 static IrInstGen *ir_build_unwrap_err_code_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 4020 IrInstGen *err_union_ptr, ZigType *result_type) 4021 { 4022 IrInstGenUnwrapErrCode *inst = ir_build_inst_gen<IrInstGenUnwrapErrCode>(&ira->new_irb, scope, source_node); 4023 inst->base.value->type = result_type; 4024 inst->err_union_ptr = err_union_ptr; 4025 4026 ir_ref_inst_gen(err_union_ptr); 4027 4028 return &inst->base; 4029 } 4030 4031 static IrInstSrc *ir_build_unwrap_err_payload_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4032 IrInstSrc *value, bool safety_check_on, bool initializing) 4033 { 4034 IrInstSrcUnwrapErrPayload *inst = ir_build_instruction<IrInstSrcUnwrapErrPayload>(irb, scope, source_node); 4035 inst->value = value; 4036 inst->safety_check_on = safety_check_on; 4037 inst->initializing = initializing; 4038 4039 ir_ref_instruction(value, irb->current_basic_block); 4040 4041 return &inst->base; 4042 } 4043 4044 static IrInstGen *ir_build_unwrap_err_payload_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 4045 IrInstGen *value, bool safety_check_on, bool initializing, ZigType *result_type) 4046 { 4047 IrInstGenUnwrapErrPayload *inst = ir_build_inst_gen<IrInstGenUnwrapErrPayload>(&ira->new_irb, scope, source_node); 4048 inst->base.value->type = result_type; 4049 inst->value = value; 4050 inst->safety_check_on = safety_check_on; 4051 inst->initializing = initializing; 4052 4053 ir_ref_inst_gen(value); 4054 4055 return &inst->base; 4056 } 4057 4058 static IrInstSrc *ir_build_fn_proto(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4059 IrInstSrc **param_types, IrInstSrc *align_value, IrInstSrc *callconv_value, 4060 IrInstSrc *return_type, bool is_var_args) 4061 { 4062 IrInstSrcFnProto *instruction = ir_build_instruction<IrInstSrcFnProto>(irb, scope, source_node); 4063 instruction->param_types = param_types; 4064 instruction->align_value = align_value; 4065 instruction->callconv_value = callconv_value; 4066 instruction->return_type = return_type; 4067 instruction->is_var_args = is_var_args; 4068 4069 assert(source_node->type == NodeTypeFnProto); 4070 size_t param_count = source_node->data.fn_proto.params.length; 4071 if (is_var_args) param_count -= 1; 4072 for (size_t i = 0; i < param_count; i += 1) { 4073 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block); 4074 } 4075 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 4076 if (callconv_value != nullptr) ir_ref_instruction(callconv_value, irb->current_basic_block); 4077 ir_ref_instruction(return_type, irb->current_basic_block); 4078 4079 return &instruction->base; 4080 } 4081 4082 static IrInstSrc *ir_build_test_comptime(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 4083 IrInstSrcTestComptime *instruction = ir_build_instruction<IrInstSrcTestComptime>(irb, scope, source_node); 4084 instruction->value = value; 4085 4086 ir_ref_instruction(value, irb->current_basic_block); 4087 4088 return &instruction->base; 4089 } 4090 4091 static IrInstSrc *ir_build_ptr_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4092 IrInstSrc *dest_type, IrInstSrc *ptr, bool safety_check_on) 4093 { 4094 IrInstSrcPtrCast *instruction = ir_build_instruction<IrInstSrcPtrCast>( 4095 irb, scope, source_node); 4096 instruction->dest_type = dest_type; 4097 instruction->ptr = ptr; 4098 instruction->safety_check_on = safety_check_on; 4099 4100 ir_ref_instruction(dest_type, irb->current_basic_block); 4101 ir_ref_instruction(ptr, irb->current_basic_block); 4102 4103 return &instruction->base; 4104 } 4105 4106 static IrInstGen *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInst *source_instruction, 4107 ZigType *ptr_type, IrInstGen *ptr, bool safety_check_on) 4108 { 4109 IrInstGenPtrCast *instruction = ir_build_inst_gen<IrInstGenPtrCast>( 4110 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 4111 instruction->base.value->type = ptr_type; 4112 instruction->ptr = ptr; 4113 instruction->safety_check_on = safety_check_on; 4114 4115 ir_ref_inst_gen(ptr); 4116 4117 return &instruction->base; 4118 } 4119 4120 static IrInstSrc *ir_build_implicit_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4121 IrInstSrc *operand, ResultLocCast *result_loc_cast) 4122 { 4123 IrInstSrcImplicitCast *instruction = ir_build_instruction<IrInstSrcImplicitCast>(irb, scope, source_node); 4124 instruction->operand = operand; 4125 instruction->result_loc_cast = result_loc_cast; 4126 4127 ir_ref_instruction(operand, irb->current_basic_block); 4128 4129 return &instruction->base; 4130 } 4131 4132 static IrInstSrc *ir_build_bit_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4133 IrInstSrc *operand, ResultLocBitCast *result_loc_bit_cast) 4134 { 4135 IrInstSrcBitCast *instruction = ir_build_instruction<IrInstSrcBitCast>(irb, scope, source_node); 4136 instruction->operand = operand; 4137 instruction->result_loc_bit_cast = result_loc_bit_cast; 4138 4139 ir_ref_instruction(operand, irb->current_basic_block); 4140 4141 return &instruction->base; 4142 } 4143 4144 static IrInstGen *ir_build_bit_cast_gen(IrAnalyze *ira, IrInst *source_instruction, 4145 IrInstGen *operand, ZigType *ty) 4146 { 4147 IrInstGenBitCast *instruction = ir_build_inst_gen<IrInstGenBitCast>( 4148 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 4149 instruction->base.value->type = ty; 4150 instruction->operand = operand; 4151 4152 ir_ref_inst_gen(operand); 4153 4154 return &instruction->base; 4155 } 4156 4157 static IrInstGen *ir_build_widen_or_shorten(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, 4158 ZigType *result_type) 4159 { 4160 IrInstGenWidenOrShorten *inst = ir_build_inst_gen<IrInstGenWidenOrShorten>(&ira->new_irb, scope, source_node); 4161 inst->base.value->type = result_type; 4162 inst->target = target; 4163 4164 ir_ref_inst_gen(target); 4165 4166 return &inst->base; 4167 } 4168 4169 static IrInstSrc *ir_build_int_to_ptr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4170 IrInstSrc *dest_type, IrInstSrc *target) 4171 { 4172 IrInstSrcIntToPtr *instruction = ir_build_instruction<IrInstSrcIntToPtr>(irb, scope, source_node); 4173 instruction->dest_type = dest_type; 4174 instruction->target = target; 4175 4176 ir_ref_instruction(dest_type, irb->current_basic_block); 4177 ir_ref_instruction(target, irb->current_basic_block); 4178 4179 return &instruction->base; 4180 } 4181 4182 static IrInstGen *ir_build_int_to_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 4183 IrInstGen *target, ZigType *ptr_type) 4184 { 4185 IrInstGenIntToPtr *instruction = ir_build_inst_gen<IrInstGenIntToPtr>(&ira->new_irb, scope, source_node); 4186 instruction->base.value->type = ptr_type; 4187 instruction->target = target; 4188 4189 ir_ref_inst_gen(target); 4190 4191 return &instruction->base; 4192 } 4193 4194 static IrInstSrc *ir_build_ptr_to_int_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4195 IrInstSrc *target) 4196 { 4197 IrInstSrcPtrToInt *inst = ir_build_instruction<IrInstSrcPtrToInt>(irb, scope, source_node); 4198 inst->target = target; 4199 4200 ir_ref_instruction(target, irb->current_basic_block); 4201 4202 return &inst->base; 4203 } 4204 4205 static IrInstGen *ir_build_ptr_to_int_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target) { 4206 IrInstGenPtrToInt *inst = ir_build_inst_gen<IrInstGenPtrToInt>(&ira->new_irb, source_instr->scope, source_instr->source_node); 4207 inst->base.value->type = ira->codegen->builtin_types.entry_usize; 4208 inst->target = target; 4209 4210 ir_ref_inst_gen(target); 4211 4212 return &inst->base; 4213 } 4214 4215 static IrInstSrc *ir_build_int_to_enum_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4216 IrInstSrc *dest_type, IrInstSrc *target) 4217 { 4218 IrInstSrcIntToEnum *instruction = ir_build_instruction<IrInstSrcIntToEnum>(irb, scope, source_node); 4219 instruction->dest_type = dest_type; 4220 instruction->target = target; 4221 4222 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 4223 ir_ref_instruction(target, irb->current_basic_block); 4224 4225 return &instruction->base; 4226 } 4227 4228 static IrInstGen *ir_build_int_to_enum_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 4229 ZigType *dest_type, IrInstGen *target) 4230 { 4231 IrInstGenIntToEnum *instruction = ir_build_inst_gen<IrInstGenIntToEnum>(&ira->new_irb, scope, source_node); 4232 instruction->base.value->type = dest_type; 4233 instruction->target = target; 4234 4235 ir_ref_inst_gen(target); 4236 4237 return &instruction->base; 4238 } 4239 4240 static IrInstSrc *ir_build_enum_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4241 IrInstSrc *target) 4242 { 4243 IrInstSrcEnumToInt *instruction = ir_build_instruction<IrInstSrcEnumToInt>( 4244 irb, scope, source_node); 4245 instruction->target = target; 4246 4247 ir_ref_instruction(target, irb->current_basic_block); 4248 4249 return &instruction->base; 4250 } 4251 4252 static IrInstSrc *ir_build_int_to_err_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4253 IrInstSrc *target) 4254 { 4255 IrInstSrcIntToErr *instruction = ir_build_instruction<IrInstSrcIntToErr>(irb, scope, source_node); 4256 instruction->target = target; 4257 4258 ir_ref_instruction(target, irb->current_basic_block); 4259 4260 return &instruction->base; 4261 } 4262 4263 static IrInstGen *ir_build_int_to_err_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, 4264 ZigType *wanted_type) 4265 { 4266 IrInstGenIntToErr *instruction = ir_build_inst_gen<IrInstGenIntToErr>(&ira->new_irb, scope, source_node); 4267 instruction->base.value->type = wanted_type; 4268 instruction->target = target; 4269 4270 ir_ref_inst_gen(target); 4271 4272 return &instruction->base; 4273 } 4274 4275 static IrInstSrc *ir_build_err_to_int_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4276 IrInstSrc *target) 4277 { 4278 IrInstSrcErrToInt *instruction = ir_build_instruction<IrInstSrcErrToInt>( 4279 irb, scope, source_node); 4280 instruction->target = target; 4281 4282 ir_ref_instruction(target, irb->current_basic_block); 4283 4284 return &instruction->base; 4285 } 4286 4287 static IrInstGen *ir_build_err_to_int_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, 4288 ZigType *wanted_type) 4289 { 4290 IrInstGenErrToInt *instruction = ir_build_inst_gen<IrInstGenErrToInt>(&ira->new_irb, scope, source_node); 4291 instruction->base.value->type = wanted_type; 4292 instruction->target = target; 4293 4294 ir_ref_inst_gen(target); 4295 4296 return &instruction->base; 4297 } 4298 4299 static IrInstSrc *ir_build_check_switch_prongs(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4300 IrInstSrc *target_value, IrInstSrcCheckSwitchProngsRange *ranges, size_t range_count, 4301 bool have_else_prong, bool have_underscore_prong) 4302 { 4303 IrInstSrcCheckSwitchProngs *instruction = ir_build_instruction<IrInstSrcCheckSwitchProngs>( 4304 irb, scope, source_node); 4305 instruction->target_value = target_value; 4306 instruction->ranges = ranges; 4307 instruction->range_count = range_count; 4308 instruction->have_else_prong = have_else_prong; 4309 instruction->have_underscore_prong = have_underscore_prong; 4310 4311 ir_ref_instruction(target_value, irb->current_basic_block); 4312 for (size_t i = 0; i < range_count; i += 1) { 4313 ir_ref_instruction(ranges[i].start, irb->current_basic_block); 4314 ir_ref_instruction(ranges[i].end, irb->current_basic_block); 4315 } 4316 4317 return &instruction->base; 4318 } 4319 4320 static IrInstSrc *ir_build_check_statement_is_void(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4321 IrInstSrc* statement_value) 4322 { 4323 IrInstSrcCheckStatementIsVoid *instruction = ir_build_instruction<IrInstSrcCheckStatementIsVoid>( 4324 irb, scope, source_node); 4325 instruction->statement_value = statement_value; 4326 4327 ir_ref_instruction(statement_value, irb->current_basic_block); 4328 4329 return &instruction->base; 4330 } 4331 4332 static IrInstSrc *ir_build_type_name(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4333 IrInstSrc *type_value) 4334 { 4335 IrInstSrcTypeName *instruction = ir_build_instruction<IrInstSrcTypeName>(irb, scope, source_node); 4336 instruction->type_value = type_value; 4337 4338 ir_ref_instruction(type_value, irb->current_basic_block); 4339 4340 return &instruction->base; 4341 } 4342 4343 static IrInstSrc *ir_build_decl_ref(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) { 4344 IrInstSrcDeclRef *instruction = ir_build_instruction<IrInstSrcDeclRef>(irb, scope, source_node); 4345 instruction->tld = tld; 4346 instruction->lval = lval; 4347 4348 return &instruction->base; 4349 } 4350 4351 static IrInstSrc *ir_build_panic_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *msg) { 4352 IrInstSrcPanic *instruction = ir_build_instruction<IrInstSrcPanic>(irb, scope, source_node); 4353 instruction->base.is_noreturn = true; 4354 instruction->msg = msg; 4355 4356 ir_ref_instruction(msg, irb->current_basic_block); 4357 4358 return &instruction->base; 4359 } 4360 4361 static IrInstGen *ir_build_panic_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *msg) { 4362 IrInstGenPanic *instruction = ir_build_inst_noreturn<IrInstGenPanic>(&ira->new_irb, 4363 source_instr->scope, source_instr->source_node); 4364 instruction->msg = msg; 4365 4366 ir_ref_inst_gen(msg); 4367 4368 return &instruction->base; 4369 } 4370 4371 static IrInstSrc *ir_build_tag_name_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target) { 4372 IrInstSrcTagName *instruction = ir_build_instruction<IrInstSrcTagName>(irb, scope, source_node); 4373 instruction->target = target; 4374 4375 ir_ref_instruction(target, irb->current_basic_block); 4376 4377 return &instruction->base; 4378 } 4379 4380 static IrInstGen *ir_build_tag_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target, 4381 ZigType *result_type) 4382 { 4383 IrInstGenTagName *instruction = ir_build_inst_gen<IrInstGenTagName>(&ira->new_irb, 4384 source_instr->scope, source_instr->source_node); 4385 instruction->base.value->type = result_type; 4386 instruction->target = target; 4387 4388 ir_ref_inst_gen(target); 4389 4390 return &instruction->base; 4391 } 4392 4393 static IrInstSrc *ir_build_tag_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4394 IrInstSrc *target) 4395 { 4396 IrInstSrcTagType *instruction = ir_build_instruction<IrInstSrcTagType>(irb, scope, source_node); 4397 instruction->target = target; 4398 4399 ir_ref_instruction(target, irb->current_basic_block); 4400 4401 return &instruction->base; 4402 } 4403 4404 static IrInstSrc *ir_build_field_parent_ptr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4405 IrInstSrc *type_value, IrInstSrc *field_name, IrInstSrc *field_ptr) 4406 { 4407 IrInstSrcFieldParentPtr *inst = ir_build_instruction<IrInstSrcFieldParentPtr>( 4408 irb, scope, source_node); 4409 inst->type_value = type_value; 4410 inst->field_name = field_name; 4411 inst->field_ptr = field_ptr; 4412 4413 ir_ref_instruction(type_value, irb->current_basic_block); 4414 ir_ref_instruction(field_name, irb->current_basic_block); 4415 ir_ref_instruction(field_ptr, irb->current_basic_block); 4416 4417 return &inst->base; 4418 } 4419 4420 static IrInstGen *ir_build_field_parent_ptr_gen(IrAnalyze *ira, IrInst *source_instr, 4421 IrInstGen *field_ptr, TypeStructField *field, ZigType *result_type) 4422 { 4423 IrInstGenFieldParentPtr *inst = ir_build_inst_gen<IrInstGenFieldParentPtr>(&ira->new_irb, 4424 source_instr->scope, source_instr->source_node); 4425 inst->base.value->type = result_type; 4426 inst->field_ptr = field_ptr; 4427 inst->field = field; 4428 4429 ir_ref_inst_gen(field_ptr); 4430 4431 return &inst->base; 4432 } 4433 4434 static IrInstSrc *ir_build_byte_offset_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4435 IrInstSrc *type_value, IrInstSrc *field_name) 4436 { 4437 IrInstSrcByteOffsetOf *instruction = ir_build_instruction<IrInstSrcByteOffsetOf>(irb, scope, source_node); 4438 instruction->type_value = type_value; 4439 instruction->field_name = field_name; 4440 4441 ir_ref_instruction(type_value, irb->current_basic_block); 4442 ir_ref_instruction(field_name, irb->current_basic_block); 4443 4444 return &instruction->base; 4445 } 4446 4447 static IrInstSrc *ir_build_bit_offset_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4448 IrInstSrc *type_value, IrInstSrc *field_name) 4449 { 4450 IrInstSrcBitOffsetOf *instruction = ir_build_instruction<IrInstSrcBitOffsetOf>(irb, scope, source_node); 4451 instruction->type_value = type_value; 4452 instruction->field_name = field_name; 4453 4454 ir_ref_instruction(type_value, irb->current_basic_block); 4455 ir_ref_instruction(field_name, irb->current_basic_block); 4456 4457 return &instruction->base; 4458 } 4459 4460 static IrInstSrc *ir_build_type_info(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value) { 4461 IrInstSrcTypeInfo *instruction = ir_build_instruction<IrInstSrcTypeInfo>(irb, scope, source_node); 4462 instruction->type_value = type_value; 4463 4464 ir_ref_instruction(type_value, irb->current_basic_block); 4465 4466 return &instruction->base; 4467 } 4468 4469 static IrInstSrc *ir_build_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_info) { 4470 IrInstSrcType *instruction = ir_build_instruction<IrInstSrcType>(irb, scope, source_node); 4471 instruction->type_info = type_info; 4472 4473 ir_ref_instruction(type_info, irb->current_basic_block); 4474 4475 return &instruction->base; 4476 } 4477 4478 static IrInstSrc *ir_build_set_eval_branch_quota(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4479 IrInstSrc *new_quota) 4480 { 4481 IrInstSrcSetEvalBranchQuota *instruction = ir_build_instruction<IrInstSrcSetEvalBranchQuota>(irb, scope, source_node); 4482 instruction->new_quota = new_quota; 4483 4484 ir_ref_instruction(new_quota, irb->current_basic_block); 4485 4486 return &instruction->base; 4487 } 4488 4489 static IrInstSrc *ir_build_align_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4490 IrInstSrc *align_bytes, IrInstSrc *target) 4491 { 4492 IrInstSrcAlignCast *instruction = ir_build_instruction<IrInstSrcAlignCast>(irb, scope, source_node); 4493 instruction->align_bytes = align_bytes; 4494 instruction->target = target; 4495 4496 ir_ref_instruction(align_bytes, irb->current_basic_block); 4497 ir_ref_instruction(target, irb->current_basic_block); 4498 4499 return &instruction->base; 4500 } 4501 4502 static IrInstGen *ir_build_align_cast_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, 4503 ZigType *result_type) 4504 { 4505 IrInstGenAlignCast *instruction = ir_build_inst_gen<IrInstGenAlignCast>(&ira->new_irb, scope, source_node); 4506 instruction->base.value->type = result_type; 4507 instruction->target = target; 4508 4509 ir_ref_inst_gen(target); 4510 4511 return &instruction->base; 4512 } 4513 4514 static IrInstSrc *ir_build_resolve_result(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4515 ResultLoc *result_loc, IrInstSrc *ty) 4516 { 4517 IrInstSrcResolveResult *instruction = ir_build_instruction<IrInstSrcResolveResult>(irb, scope, source_node); 4518 instruction->result_loc = result_loc; 4519 instruction->ty = ty; 4520 4521 if (ty != nullptr) ir_ref_instruction(ty, irb->current_basic_block); 4522 4523 return &instruction->base; 4524 } 4525 4526 static IrInstSrc *ir_build_reset_result(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4527 ResultLoc *result_loc) 4528 { 4529 IrInstSrcResetResult *instruction = ir_build_instruction<IrInstSrcResetResult>(irb, scope, source_node); 4530 instruction->result_loc = result_loc; 4531 instruction->base.is_gen = true; 4532 4533 return &instruction->base; 4534 } 4535 4536 static IrInstSrc *ir_build_opaque_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 4537 IrInstSrcOpaqueType *instruction = ir_build_instruction<IrInstSrcOpaqueType>(irb, scope, source_node); 4538 4539 return &instruction->base; 4540 } 4541 4542 static IrInstSrc *ir_build_set_align_stack(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4543 IrInstSrc *align_bytes) 4544 { 4545 IrInstSrcSetAlignStack *instruction = ir_build_instruction<IrInstSrcSetAlignStack>(irb, scope, source_node); 4546 instruction->align_bytes = align_bytes; 4547 4548 ir_ref_instruction(align_bytes, irb->current_basic_block); 4549 4550 return &instruction->base; 4551 } 4552 4553 static IrInstSrc *ir_build_arg_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4554 IrInstSrc *fn_type, IrInstSrc *arg_index, bool allow_var) 4555 { 4556 IrInstSrcArgType *instruction = ir_build_instruction<IrInstSrcArgType>(irb, scope, source_node); 4557 instruction->fn_type = fn_type; 4558 instruction->arg_index = arg_index; 4559 instruction->allow_var = allow_var; 4560 4561 ir_ref_instruction(fn_type, irb->current_basic_block); 4562 ir_ref_instruction(arg_index, irb->current_basic_block); 4563 4564 return &instruction->base; 4565 } 4566 4567 static IrInstSrc *ir_build_error_return_trace_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4568 IrInstErrorReturnTraceOptional optional) 4569 { 4570 IrInstSrcErrorReturnTrace *inst = ir_build_instruction<IrInstSrcErrorReturnTrace>(irb, scope, source_node); 4571 inst->optional = optional; 4572 4573 return &inst->base; 4574 } 4575 4576 static IrInstGen *ir_build_error_return_trace_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 4577 IrInstErrorReturnTraceOptional optional, ZigType *result_type) 4578 { 4579 IrInstGenErrorReturnTrace *inst = ir_build_inst_gen<IrInstGenErrorReturnTrace>(&ira->new_irb, scope, source_node); 4580 inst->base.value->type = result_type; 4581 inst->optional = optional; 4582 4583 return &inst->base; 4584 } 4585 4586 static IrInstSrc *ir_build_error_union(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4587 IrInstSrc *err_set, IrInstSrc *payload) 4588 { 4589 IrInstSrcErrorUnion *instruction = ir_build_instruction<IrInstSrcErrorUnion>(irb, scope, source_node); 4590 instruction->err_set = err_set; 4591 instruction->payload = payload; 4592 4593 ir_ref_instruction(err_set, irb->current_basic_block); 4594 ir_ref_instruction(payload, irb->current_basic_block); 4595 4596 return &instruction->base; 4597 } 4598 4599 static IrInstSrc *ir_build_atomic_rmw_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4600 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *op, IrInstSrc *operand, 4601 IrInstSrc *ordering) 4602 { 4603 IrInstSrcAtomicRmw *instruction = ir_build_instruction<IrInstSrcAtomicRmw>(irb, scope, source_node); 4604 instruction->operand_type = operand_type; 4605 instruction->ptr = ptr; 4606 instruction->op = op; 4607 instruction->operand = operand; 4608 instruction->ordering = ordering; 4609 4610 ir_ref_instruction(operand_type, irb->current_basic_block); 4611 ir_ref_instruction(ptr, irb->current_basic_block); 4612 ir_ref_instruction(op, irb->current_basic_block); 4613 ir_ref_instruction(operand, irb->current_basic_block); 4614 ir_ref_instruction(ordering, irb->current_basic_block); 4615 4616 return &instruction->base; 4617 } 4618 4619 static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr, 4620 IrInstGen *ptr, IrInstGen *operand, AtomicRmwOp op, AtomicOrder ordering, ZigType *operand_type) 4621 { 4622 IrInstGenAtomicRmw *instruction = ir_build_inst_gen<IrInstGenAtomicRmw>(&ira->new_irb, source_instr->scope, source_instr->source_node); 4623 instruction->base.value->type = operand_type; 4624 instruction->ptr = ptr; 4625 instruction->op = op; 4626 instruction->operand = operand; 4627 instruction->ordering = ordering; 4628 4629 ir_ref_inst_gen(ptr); 4630 ir_ref_inst_gen(operand); 4631 4632 return &instruction->base; 4633 } 4634 4635 static IrInstSrc *ir_build_atomic_load_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4636 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *ordering) 4637 { 4638 IrInstSrcAtomicLoad *instruction = ir_build_instruction<IrInstSrcAtomicLoad>(irb, scope, source_node); 4639 instruction->operand_type = operand_type; 4640 instruction->ptr = ptr; 4641 instruction->ordering = ordering; 4642 4643 ir_ref_instruction(operand_type, irb->current_basic_block); 4644 ir_ref_instruction(ptr, irb->current_basic_block); 4645 ir_ref_instruction(ordering, irb->current_basic_block); 4646 4647 return &instruction->base; 4648 } 4649 4650 static IrInstGen *ir_build_atomic_load_gen(IrAnalyze *ira, IrInst *source_instr, 4651 IrInstGen *ptr, AtomicOrder ordering, ZigType *operand_type) 4652 { 4653 IrInstGenAtomicLoad *instruction = ir_build_inst_gen<IrInstGenAtomicLoad>(&ira->new_irb, 4654 source_instr->scope, source_instr->source_node); 4655 instruction->base.value->type = operand_type; 4656 instruction->ptr = ptr; 4657 instruction->ordering = ordering; 4658 4659 ir_ref_inst_gen(ptr); 4660 4661 return &instruction->base; 4662 } 4663 4664 static IrInstSrc *ir_build_atomic_store_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4665 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *value, IrInstSrc *ordering) 4666 { 4667 IrInstSrcAtomicStore *instruction = ir_build_instruction<IrInstSrcAtomicStore>(irb, scope, source_node); 4668 instruction->operand_type = operand_type; 4669 instruction->ptr = ptr; 4670 instruction->value = value; 4671 instruction->ordering = ordering; 4672 4673 ir_ref_instruction(operand_type, irb->current_basic_block); 4674 ir_ref_instruction(ptr, irb->current_basic_block); 4675 ir_ref_instruction(value, irb->current_basic_block); 4676 ir_ref_instruction(ordering, irb->current_basic_block); 4677 4678 return &instruction->base; 4679 } 4680 4681 static IrInstGen *ir_build_atomic_store_gen(IrAnalyze *ira, IrInst *source_instr, 4682 IrInstGen *ptr, IrInstGen *value, AtomicOrder ordering) 4683 { 4684 IrInstGenAtomicStore *instruction = ir_build_inst_void<IrInstGenAtomicStore>(&ira->new_irb, 4685 source_instr->scope, source_instr->source_node); 4686 instruction->ptr = ptr; 4687 instruction->value = value; 4688 instruction->ordering = ordering; 4689 4690 ir_ref_inst_gen(ptr); 4691 ir_ref_inst_gen(value); 4692 4693 return &instruction->base; 4694 } 4695 4696 static IrInstSrc *ir_build_save_err_ret_addr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 4697 IrInstSrcSaveErrRetAddr *inst = ir_build_instruction<IrInstSrcSaveErrRetAddr>(irb, scope, source_node); 4698 return &inst->base; 4699 } 4700 4701 static IrInstGen *ir_build_save_err_ret_addr_gen(IrAnalyze *ira, IrInst *source_instr) { 4702 IrInstGenSaveErrRetAddr *inst = ir_build_inst_void<IrInstGenSaveErrRetAddr>(&ira->new_irb, 4703 source_instr->scope, source_instr->source_node); 4704 return &inst->base; 4705 } 4706 4707 static IrInstSrc *ir_build_add_implicit_return_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4708 IrInstSrc *value, ResultLocReturn *result_loc_ret) 4709 { 4710 IrInstSrcAddImplicitReturnType *inst = ir_build_instruction<IrInstSrcAddImplicitReturnType>(irb, scope, source_node); 4711 inst->value = value; 4712 inst->result_loc_ret = result_loc_ret; 4713 4714 ir_ref_instruction(value, irb->current_basic_block); 4715 4716 return &inst->base; 4717 } 4718 4719 static IrInstSrc *ir_build_has_decl(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4720 IrInstSrc *container, IrInstSrc *name) 4721 { 4722 IrInstSrcHasDecl *instruction = ir_build_instruction<IrInstSrcHasDecl>(irb, scope, source_node); 4723 instruction->container = container; 4724 instruction->name = name; 4725 4726 ir_ref_instruction(container, irb->current_basic_block); 4727 ir_ref_instruction(name, irb->current_basic_block); 4728 4729 return &instruction->base; 4730 } 4731 4732 static IrInstSrc *ir_build_undeclared_identifier(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *name) { 4733 IrInstSrcUndeclaredIdent *instruction = ir_build_instruction<IrInstSrcUndeclaredIdent>(irb, scope, source_node); 4734 instruction->name = name; 4735 4736 return &instruction->base; 4737 } 4738 4739 static IrInstSrc *ir_build_check_runtime_scope(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *scope_is_comptime, IrInstSrc *is_comptime) { 4740 IrInstSrcCheckRuntimeScope *instruction = ir_build_instruction<IrInstSrcCheckRuntimeScope>(irb, scope, source_node); 4741 instruction->scope_is_comptime = scope_is_comptime; 4742 instruction->is_comptime = is_comptime; 4743 4744 ir_ref_instruction(scope_is_comptime, irb->current_basic_block); 4745 ir_ref_instruction(is_comptime, irb->current_basic_block); 4746 4747 return &instruction->base; 4748 } 4749 4750 static IrInstSrc *ir_build_union_init_named_field(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4751 IrInstSrc *union_type, IrInstSrc *field_name, IrInstSrc *field_result_loc, IrInstSrc *result_loc) 4752 { 4753 IrInstSrcUnionInitNamedField *instruction = ir_build_instruction<IrInstSrcUnionInitNamedField>(irb, scope, source_node); 4754 instruction->union_type = union_type; 4755 instruction->field_name = field_name; 4756 instruction->field_result_loc = field_result_loc; 4757 instruction->result_loc = result_loc; 4758 4759 ir_ref_instruction(union_type, irb->current_basic_block); 4760 ir_ref_instruction(field_name, irb->current_basic_block); 4761 ir_ref_instruction(field_result_loc, irb->current_basic_block); 4762 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 4763 4764 return &instruction->base; 4765 } 4766 4767 4768 static IrInstGen *ir_build_vector_to_array(IrAnalyze *ira, IrInst *source_instruction, 4769 ZigType *result_type, IrInstGen *vector, IrInstGen *result_loc) 4770 { 4771 IrInstGenVectorToArray *instruction = ir_build_inst_gen<IrInstGenVectorToArray>(&ira->new_irb, 4772 source_instruction->scope, source_instruction->source_node); 4773 instruction->base.value->type = result_type; 4774 instruction->vector = vector; 4775 instruction->result_loc = result_loc; 4776 4777 ir_ref_inst_gen(vector); 4778 ir_ref_inst_gen(result_loc); 4779 4780 return &instruction->base; 4781 } 4782 4783 static IrInstGen *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInst *source_instruction, 4784 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc) 4785 { 4786 IrInstGenPtrOfArrayToSlice *instruction = ir_build_inst_gen<IrInstGenPtrOfArrayToSlice>(&ira->new_irb, 4787 source_instruction->scope, source_instruction->source_node); 4788 instruction->base.value->type = result_type; 4789 instruction->operand = operand; 4790 instruction->result_loc = result_loc; 4791 4792 ir_ref_inst_gen(operand); 4793 ir_ref_inst_gen(result_loc); 4794 4795 return &instruction->base; 4796 } 4797 4798 static IrInstGen *ir_build_array_to_vector(IrAnalyze *ira, IrInst *source_instruction, 4799 IrInstGen *array, ZigType *result_type) 4800 { 4801 IrInstGenArrayToVector *instruction = ir_build_inst_gen<IrInstGenArrayToVector>(&ira->new_irb, 4802 source_instruction->scope, source_instruction->source_node); 4803 instruction->base.value->type = result_type; 4804 instruction->array = array; 4805 4806 ir_ref_inst_gen(array); 4807 4808 return &instruction->base; 4809 } 4810 4811 static IrInstGen *ir_build_assert_zero(IrAnalyze *ira, IrInst *source_instruction, 4812 IrInstGen *target) 4813 { 4814 IrInstGenAssertZero *instruction = ir_build_inst_gen<IrInstGenAssertZero>(&ira->new_irb, 4815 source_instruction->scope, source_instruction->source_node); 4816 instruction->base.value->type = ira->codegen->builtin_types.entry_void; 4817 instruction->target = target; 4818 4819 ir_ref_inst_gen(target); 4820 4821 return &instruction->base; 4822 } 4823 4824 static IrInstGen *ir_build_assert_non_null(IrAnalyze *ira, IrInst *source_instruction, 4825 IrInstGen *target) 4826 { 4827 IrInstGenAssertNonNull *instruction = ir_build_inst_gen<IrInstGenAssertNonNull>(&ira->new_irb, 4828 source_instruction->scope, source_instruction->source_node); 4829 instruction->base.value->type = ira->codegen->builtin_types.entry_void; 4830 instruction->target = target; 4831 4832 ir_ref_inst_gen(target); 4833 4834 return &instruction->base; 4835 } 4836 4837 static IrInstSrc *ir_build_alloca_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4838 IrInstSrc *align, const char *name_hint, IrInstSrc *is_comptime) 4839 { 4840 IrInstSrcAlloca *instruction = ir_build_instruction<IrInstSrcAlloca>(irb, scope, source_node); 4841 instruction->base.is_gen = true; 4842 instruction->align = align; 4843 instruction->name_hint = name_hint; 4844 instruction->is_comptime = is_comptime; 4845 4846 if (align != nullptr) ir_ref_instruction(align, irb->current_basic_block); 4847 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); 4848 4849 return &instruction->base; 4850 } 4851 4852 static IrInstGenAlloca *ir_build_alloca_gen(IrAnalyze *ira, IrInst *source_instruction, 4853 uint32_t align, const char *name_hint) 4854 { 4855 IrInstGenAlloca *instruction = ir_create_inst_gen<IrInstGenAlloca>(&ira->new_irb, 4856 source_instruction->scope, source_instruction->source_node); 4857 instruction->align = align; 4858 instruction->name_hint = name_hint; 4859 4860 return instruction; 4861 } 4862 4863 static IrInstSrc *ir_build_end_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4864 IrInstSrc *value, ResultLoc *result_loc) 4865 { 4866 IrInstSrcEndExpr *instruction = ir_build_instruction<IrInstSrcEndExpr>(irb, scope, source_node); 4867 instruction->base.is_gen = true; 4868 instruction->value = value; 4869 instruction->result_loc = result_loc; 4870 4871 ir_ref_instruction(value, irb->current_basic_block); 4872 4873 return &instruction->base; 4874 } 4875 4876 static IrInstSrcSuspendBegin *ir_build_suspend_begin_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 4877 return ir_build_instruction<IrInstSrcSuspendBegin>(irb, scope, source_node); 4878 } 4879 4880 static IrInstGen *ir_build_suspend_begin_gen(IrAnalyze *ira, IrInst *source_instr) { 4881 IrInstGenSuspendBegin *inst = ir_build_inst_void<IrInstGenSuspendBegin>(&ira->new_irb, 4882 source_instr->scope, source_instr->source_node); 4883 return &inst->base; 4884 } 4885 4886 static IrInstSrc *ir_build_suspend_finish_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4887 IrInstSrcSuspendBegin *begin) 4888 { 4889 IrInstSrcSuspendFinish *inst = ir_build_instruction<IrInstSrcSuspendFinish>(irb, scope, source_node); 4890 inst->begin = begin; 4891 4892 ir_ref_instruction(&begin->base, irb->current_basic_block); 4893 4894 return &inst->base; 4895 } 4896 4897 static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSuspendBegin *begin) { 4898 IrInstGenSuspendFinish *inst = ir_build_inst_void<IrInstGenSuspendFinish>(&ira->new_irb, 4899 source_instr->scope, source_instr->source_node); 4900 inst->begin = begin; 4901 4902 ir_ref_inst_gen(&begin->base); 4903 4904 return &inst->base; 4905 } 4906 4907 static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4908 IrInstSrc *frame, ResultLoc *result_loc, bool is_nosuspend) 4909 { 4910 IrInstSrcAwait *instruction = ir_build_instruction<IrInstSrcAwait>(irb, scope, source_node); 4911 instruction->frame = frame; 4912 instruction->result_loc = result_loc; 4913 instruction->is_nosuspend = is_nosuspend; 4914 4915 ir_ref_instruction(frame, irb->current_basic_block); 4916 4917 return &instruction->base; 4918 } 4919 4920 static IrInstGenAwait *ir_build_await_gen(IrAnalyze *ira, IrInst *source_instruction, 4921 IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc, bool is_nosuspend) 4922 { 4923 IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb, 4924 source_instruction->scope, source_instruction->source_node); 4925 instruction->base.value->type = result_type; 4926 instruction->frame = frame; 4927 instruction->result_loc = result_loc; 4928 instruction->is_nosuspend = is_nosuspend; 4929 4930 ir_ref_inst_gen(frame); 4931 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 4932 4933 return instruction; 4934 } 4935 4936 static IrInstSrc *ir_build_resume_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *frame) { 4937 IrInstSrcResume *instruction = ir_build_instruction<IrInstSrcResume>(irb, scope, source_node); 4938 instruction->frame = frame; 4939 4940 ir_ref_instruction(frame, irb->current_basic_block); 4941 4942 return &instruction->base; 4943 } 4944 4945 static IrInstGen *ir_build_resume_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *frame) { 4946 IrInstGenResume *instruction = ir_build_inst_void<IrInstGenResume>(&ira->new_irb, 4947 source_instr->scope, source_instr->source_node); 4948 instruction->frame = frame; 4949 4950 ir_ref_inst_gen(frame); 4951 4952 return &instruction->base; 4953 } 4954 4955 static IrInstSrcSpillBegin *ir_build_spill_begin_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4956 IrInstSrc *operand, SpillId spill_id) 4957 { 4958 IrInstSrcSpillBegin *instruction = ir_build_instruction<IrInstSrcSpillBegin>(irb, scope, source_node); 4959 instruction->operand = operand; 4960 instruction->spill_id = spill_id; 4961 4962 ir_ref_instruction(operand, irb->current_basic_block); 4963 4964 return instruction; 4965 } 4966 4967 static IrInstGen *ir_build_spill_begin_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, 4968 SpillId spill_id) 4969 { 4970 IrInstGenSpillBegin *instruction = ir_build_inst_void<IrInstGenSpillBegin>(&ira->new_irb, 4971 source_instr->scope, source_instr->source_node); 4972 instruction->operand = operand; 4973 instruction->spill_id = spill_id; 4974 4975 ir_ref_inst_gen(operand); 4976 4977 return &instruction->base; 4978 } 4979 4980 static IrInstSrc *ir_build_spill_end_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4981 IrInstSrcSpillBegin *begin) 4982 { 4983 IrInstSrcSpillEnd *instruction = ir_build_instruction<IrInstSrcSpillEnd>(irb, scope, source_node); 4984 instruction->begin = begin; 4985 4986 ir_ref_instruction(&begin->base, irb->current_basic_block); 4987 4988 return &instruction->base; 4989 } 4990 4991 static IrInstGen *ir_build_spill_end_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSpillBegin *begin, 4992 ZigType *result_type) 4993 { 4994 IrInstGenSpillEnd *instruction = ir_build_inst_gen<IrInstGenSpillEnd>(&ira->new_irb, 4995 source_instr->scope, source_instr->source_node); 4996 instruction->base.value->type = result_type; 4997 instruction->begin = begin; 4998 4999 ir_ref_inst_gen(&begin->base); 5000 5001 return &instruction->base; 5002 } 5003 5004 static IrInstGen *ir_build_vector_extract_elem(IrAnalyze *ira, IrInst *source_instruction, 5005 IrInstGen *vector, IrInstGen *index) 5006 { 5007 IrInstGenVectorExtractElem *instruction = ir_build_inst_gen<IrInstGenVectorExtractElem>( 5008 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 5009 instruction->base.value->type = vector->value->type->data.vector.elem_type; 5010 instruction->vector = vector; 5011 instruction->index = index; 5012 5013 ir_ref_inst_gen(vector); 5014 ir_ref_inst_gen(index); 5015 5016 return &instruction->base; 5017 } 5018 5019 static IrInstSrc *ir_build_wasm_memory_size_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *index) { 5020 IrInstSrcWasmMemorySize *instruction = ir_build_instruction<IrInstSrcWasmMemorySize>(irb, scope, source_node); 5021 instruction->index = index; 5022 5023 ir_ref_instruction(index, irb->current_basic_block); 5024 5025 return &instruction->base; 5026 } 5027 5028 static IrInstGen *ir_build_wasm_memory_size_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *index) { 5029 IrInstGenWasmMemorySize *instruction = ir_build_inst_gen<IrInstGenWasmMemorySize>(&ira->new_irb, 5030 source_instr->scope, source_instr->source_node); 5031 instruction->base.value->type = ira->codegen->builtin_types.entry_u32; 5032 instruction->index = index; 5033 5034 ir_ref_inst_gen(index); 5035 5036 return &instruction->base; 5037 } 5038 5039 static IrInstSrc *ir_build_wasm_memory_grow_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *index, IrInstSrc *delta) { 5040 IrInstSrcWasmMemoryGrow *instruction = ir_build_instruction<IrInstSrcWasmMemoryGrow>(irb, scope, source_node); 5041 instruction->index = index; 5042 instruction->delta = delta; 5043 5044 ir_ref_instruction(index, irb->current_basic_block); 5045 ir_ref_instruction(delta, irb->current_basic_block); 5046 5047 return &instruction->base; 5048 } 5049 5050 static IrInstGen *ir_build_wasm_memory_grow_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *index, IrInstGen *delta) { 5051 IrInstGenWasmMemoryGrow *instruction = ir_build_inst_gen<IrInstGenWasmMemoryGrow>(&ira->new_irb, 5052 source_instr->scope, source_instr->source_node); 5053 instruction->base.value->type = ira->codegen->builtin_types.entry_i32; 5054 instruction->index = index; 5055 instruction->delta = delta; 5056 5057 ir_ref_inst_gen(index); 5058 ir_ref_inst_gen(delta); 5059 5060 return &instruction->base; 5061 } 5062 5063 static IrInstSrc *ir_build_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 5064 IrInstSrcSrc *instruction = ir_build_instruction<IrInstSrcSrc>(irb, scope, source_node); 5065 5066 return &instruction->base; 5067 } 5068 5069 static void ir_count_defers(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { 5070 results[ReturnKindUnconditional] = 0; 5071 results[ReturnKindError] = 0; 5072 5073 Scope *scope = inner_scope; 5074 5075 while (scope != outer_scope) { 5076 assert(scope); 5077 switch (scope->id) { 5078 case ScopeIdDefer: { 5079 AstNode *defer_node = scope->source_node; 5080 assert(defer_node->type == NodeTypeDefer); 5081 ReturnKind defer_kind = defer_node->data.defer.kind; 5082 results[defer_kind] += 1; 5083 scope = scope->parent; 5084 continue; 5085 } 5086 case ScopeIdDecls: 5087 case ScopeIdFnDef: 5088 return; 5089 case ScopeIdBlock: 5090 case ScopeIdVarDecl: 5091 case ScopeIdLoop: 5092 case ScopeIdSuspend: 5093 case ScopeIdCompTime: 5094 case ScopeIdNoSuspend: 5095 case ScopeIdRuntime: 5096 case ScopeIdTypeOf: 5097 case ScopeIdExpr: 5098 scope = scope->parent; 5099 continue; 5100 case ScopeIdDeferExpr: 5101 case ScopeIdCImport: 5102 zig_unreachable(); 5103 } 5104 } 5105 } 5106 5107 static IrInstSrc *ir_mark_gen(IrInstSrc *instruction) { 5108 instruction->is_gen = true; 5109 return instruction; 5110 } 5111 5112 static bool ir_gen_defers_for_block(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_scope, bool *is_noreturn, IrInstSrc *err_value) { 5113 Scope *scope = inner_scope; 5114 if (is_noreturn != nullptr) *is_noreturn = false; 5115 while (scope != outer_scope) { 5116 if (!scope) 5117 return true; 5118 5119 switch (scope->id) { 5120 case ScopeIdDefer: { 5121 AstNode *defer_node = scope->source_node; 5122 assert(defer_node->type == NodeTypeDefer); 5123 ReturnKind defer_kind = defer_node->data.defer.kind; 5124 AstNode *defer_expr_node = defer_node->data.defer.expr; 5125 AstNode *defer_var_node = defer_node->data.defer.err_payload; 5126 5127 if (defer_kind == ReturnKindError && err_value == nullptr) { 5128 // This is an `errdefer` but we're generating code for a 5129 // `return` that doesn't return an error, skip it 5130 scope = scope->parent; 5131 continue; 5132 } 5133 5134 Scope *defer_expr_scope = defer_node->data.defer.expr_scope; 5135 if (defer_var_node != nullptr) { 5136 assert(defer_kind == ReturnKindError); 5137 assert(defer_var_node->type == NodeTypeSymbol); 5138 Buf *var_name = defer_var_node->data.symbol_expr.symbol; 5139 5140 if (defer_expr_node->type == NodeTypeUnreachable) { 5141 add_node_error(irb->codegen, defer_var_node, 5142 buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); 5143 return false; 5144 } 5145 5146 IrInstSrc *is_comptime; 5147 if (ir_should_inline(irb->exec, defer_expr_scope)) { 5148 is_comptime = ir_build_const_bool(irb, defer_expr_scope, 5149 defer_expr_node, true); 5150 } else { 5151 is_comptime = ir_build_test_comptime(irb, defer_expr_scope, 5152 defer_expr_node, err_value); 5153 } 5154 5155 ZigVar *err_var = ir_create_var(irb, defer_var_node, defer_expr_scope, 5156 var_name, true, true, false, is_comptime); 5157 build_decl_var_and_init(irb, defer_expr_scope, defer_var_node, err_var, err_value, 5158 buf_ptr(var_name), is_comptime); 5159 5160 defer_expr_scope = err_var->child_scope; 5161 } 5162 5163 IrInstSrc *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope); 5164 if (defer_expr_value == irb->codegen->invalid_inst_src) 5165 return irb->codegen->invalid_inst_src; 5166 5167 if (defer_expr_value->is_noreturn) { 5168 if (is_noreturn != nullptr) *is_noreturn = true; 5169 } else { 5170 ir_mark_gen(ir_build_check_statement_is_void(irb, defer_expr_scope, defer_expr_node, 5171 defer_expr_value)); 5172 } 5173 scope = scope->parent; 5174 continue; 5175 } 5176 case ScopeIdDecls: 5177 case ScopeIdFnDef: 5178 return true; 5179 case ScopeIdBlock: 5180 case ScopeIdVarDecl: 5181 case ScopeIdLoop: 5182 case ScopeIdSuspend: 5183 case ScopeIdCompTime: 5184 case ScopeIdNoSuspend: 5185 case ScopeIdRuntime: 5186 case ScopeIdTypeOf: 5187 case ScopeIdExpr: 5188 scope = scope->parent; 5189 continue; 5190 case ScopeIdDeferExpr: 5191 case ScopeIdCImport: 5192 zig_unreachable(); 5193 } 5194 } 5195 return true; 5196 } 5197 5198 static void ir_set_cursor_at_end_gen(IrBuilderGen *irb, IrBasicBlockGen *basic_block) { 5199 assert(basic_block); 5200 irb->current_basic_block = basic_block; 5201 } 5202 5203 static void ir_set_cursor_at_end(IrBuilderSrc *irb, IrBasicBlockSrc *basic_block) { 5204 assert(basic_block); 5205 irb->current_basic_block = basic_block; 5206 } 5207 5208 static void ir_append_basic_block_gen(IrBuilderGen *irb, IrBasicBlockGen *bb) { 5209 assert(!bb->already_appended); 5210 bb->already_appended = true; 5211 irb->exec->basic_block_list.append(bb); 5212 } 5213 5214 static void ir_set_cursor_at_end_and_append_block_gen(IrBuilderGen *irb, IrBasicBlockGen *basic_block) { 5215 ir_append_basic_block_gen(irb, basic_block); 5216 ir_set_cursor_at_end_gen(irb, basic_block); 5217 } 5218 5219 static void ir_set_cursor_at_end_and_append_block(IrBuilderSrc *irb, IrBasicBlockSrc *basic_block) { 5220 basic_block->index = irb->exec->basic_block_list.length; 5221 irb->exec->basic_block_list.append(basic_block); 5222 ir_set_cursor_at_end(irb, basic_block); 5223 } 5224 5225 static ScopeSuspend *get_scope_suspend(Scope *scope) { 5226 while (scope) { 5227 if (scope->id == ScopeIdSuspend) 5228 return (ScopeSuspend *)scope; 5229 if (scope->id == ScopeIdFnDef) 5230 return nullptr; 5231 5232 scope = scope->parent; 5233 } 5234 return nullptr; 5235 } 5236 5237 static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { 5238 while (scope) { 5239 if (scope->id == ScopeIdDeferExpr) 5240 return (ScopeDeferExpr *)scope; 5241 if (scope->id == ScopeIdFnDef) 5242 return nullptr; 5243 5244 scope = scope->parent; 5245 } 5246 return nullptr; 5247 } 5248 5249 static IrInstSrc *ir_gen_return(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 5250 assert(node->type == NodeTypeReturnExpr); 5251 5252 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); 5253 if (scope_defer_expr) { 5254 if (!scope_defer_expr->reported_err) { 5255 add_node_error(irb->codegen, node, buf_sprintf("cannot return from defer expression")); 5256 scope_defer_expr->reported_err = true; 5257 } 5258 return irb->codegen->invalid_inst_src; 5259 } 5260 5261 Scope *outer_scope = irb->exec->begin_scope; 5262 5263 AstNode *expr_node = node->data.return_expr.expr; 5264 switch (node->data.return_expr.kind) { 5265 case ReturnKindUnconditional: 5266 { 5267 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>(); 5268 result_loc_ret->base.id = ResultLocIdReturn; 5269 ir_build_reset_result(irb, scope, node, &result_loc_ret->base); 5270 5271 IrInstSrc *return_value; 5272 if (expr_node) { 5273 // Temporarily set this so that if we return a type it gets the name of the function 5274 ZigFn *prev_name_fn = irb->exec->name_fn; 5275 irb->exec->name_fn = exec_fn_entry(irb->exec); 5276 return_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_ret->base); 5277 irb->exec->name_fn = prev_name_fn; 5278 if (return_value == irb->codegen->invalid_inst_src) 5279 return irb->codegen->invalid_inst_src; 5280 } else { 5281 return_value = ir_build_const_void(irb, scope, node); 5282 ir_build_end_expr(irb, scope, node, return_value, &result_loc_ret->base); 5283 } 5284 5285 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value, result_loc_ret)); 5286 5287 size_t defer_counts[2]; 5288 ir_count_defers(irb, scope, outer_scope, defer_counts); 5289 bool have_err_defers = defer_counts[ReturnKindError] > 0; 5290 if (!have_err_defers && !irb->codegen->have_err_ret_tracing) { 5291 // only generate unconditional defers 5292 if (!ir_gen_defers_for_block(irb, scope, outer_scope, nullptr, nullptr)) 5293 return irb->codegen->invalid_inst_src; 5294 IrInstSrc *result = ir_build_return_src(irb, scope, node, nullptr); 5295 result_loc_ret->base.source_instruction = result; 5296 return result; 5297 } 5298 bool should_inline = ir_should_inline(irb->exec, scope); 5299 5300 IrBasicBlockSrc *err_block = ir_create_basic_block(irb, scope, "ErrRetErr"); 5301 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk"); 5302 5303 IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node, return_value, false, true); 5304 5305 IrInstSrc *is_comptime; 5306 if (should_inline) { 5307 is_comptime = ir_build_const_bool(irb, scope, node, should_inline); 5308 } else { 5309 is_comptime = ir_build_test_comptime(irb, scope, node, is_err); 5310 } 5311 5312 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime)); 5313 IrBasicBlockSrc *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt"); 5314 5315 ir_set_cursor_at_end_and_append_block(irb, err_block); 5316 if (!ir_gen_defers_for_block(irb, scope, outer_scope, nullptr, return_value)) 5317 return irb->codegen->invalid_inst_src; 5318 if (irb->codegen->have_err_ret_tracing && !should_inline) { 5319 ir_build_save_err_ret_addr_src(irb, scope, node); 5320 } 5321 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 5322 5323 ir_set_cursor_at_end_and_append_block(irb, ok_block); 5324 if (!ir_gen_defers_for_block(irb, scope, outer_scope, nullptr, nullptr)) 5325 return irb->codegen->invalid_inst_src; 5326 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 5327 5328 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); 5329 IrInstSrc *result = ir_build_return_src(irb, scope, node, nullptr); 5330 result_loc_ret->base.source_instruction = result; 5331 return result; 5332 } 5333 case ReturnKindError: 5334 { 5335 assert(expr_node); 5336 IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 5337 if (err_union_ptr == irb->codegen->invalid_inst_src) 5338 return irb->codegen->invalid_inst_src; 5339 IrInstSrc *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr, true, false); 5340 5341 IrBasicBlockSrc *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); 5342 IrBasicBlockSrc *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); 5343 IrInstSrc *is_comptime; 5344 bool should_inline = ir_should_inline(irb->exec, scope); 5345 if (should_inline) { 5346 is_comptime = ir_build_const_bool(irb, scope, node, true); 5347 } else { 5348 is_comptime = ir_build_test_comptime(irb, scope, node, is_err_val); 5349 } 5350 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime)); 5351 5352 ir_set_cursor_at_end_and_append_block(irb, return_block); 5353 IrInstSrc *err_val_ptr = ir_build_unwrap_err_code_src(irb, scope, node, err_union_ptr); 5354 IrInstSrc *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); 5355 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val, nullptr)); 5356 IrInstSrcSpillBegin *spill_begin = ir_build_spill_begin_src(irb, scope, node, err_val, 5357 SpillIdRetErrCode); 5358 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>(); 5359 result_loc_ret->base.id = ResultLocIdReturn; 5360 ir_build_reset_result(irb, scope, node, &result_loc_ret->base); 5361 ir_build_end_expr(irb, scope, node, err_val, &result_loc_ret->base); 5362 5363 bool is_noreturn = false; 5364 if (!ir_gen_defers_for_block(irb, scope, outer_scope, &is_noreturn, err_val)) { 5365 return irb->codegen->invalid_inst_src; 5366 } 5367 if (!is_noreturn) { 5368 if (irb->codegen->have_err_ret_tracing && !should_inline) { 5369 ir_build_save_err_ret_addr_src(irb, scope, node); 5370 } 5371 err_val = ir_build_spill_end_src(irb, scope, node, spill_begin); 5372 IrInstSrc *ret_inst = ir_build_return_src(irb, scope, node, err_val); 5373 result_loc_ret->base.source_instruction = ret_inst; 5374 } 5375 5376 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5377 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(irb, scope, node, err_union_ptr, false, false); 5378 if (lval == LValPtr) 5379 return unwrapped_ptr; 5380 else 5381 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, unwrapped_ptr), result_loc); 5382 } 5383 } 5384 zig_unreachable(); 5385 } 5386 5387 static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope, 5388 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime, 5389 bool skip_name_check) 5390 { 5391 ZigVar *variable_entry = heap::c_allocator.create<ZigVar>(); 5392 variable_entry->parent_scope = parent_scope; 5393 variable_entry->shadowable = is_shadowable; 5394 variable_entry->is_comptime = is_comptime; 5395 variable_entry->src_arg_index = SIZE_MAX; 5396 variable_entry->const_value = codegen->pass1_arena->create<ZigValue>(); 5397 5398 if (is_comptime != nullptr) { 5399 is_comptime->base.ref_count += 1; 5400 } 5401 5402 if (name) { 5403 variable_entry->name = strdup(buf_ptr(name)); 5404 5405 if (!skip_name_check) { 5406 ZigVar *existing_var = find_variable(codegen, parent_scope, name, nullptr); 5407 if (existing_var && !existing_var->shadowable) { 5408 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) { 5409 ErrorMsg *msg = add_node_error(codegen, node, 5410 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); 5411 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); 5412 } 5413 variable_entry->var_type = codegen->builtin_types.entry_invalid; 5414 } else { 5415 ZigType *type; 5416 if (get_primitive_type(codegen, name, &type) != ErrorPrimitiveTypeNotFound) { 5417 add_node_error(codegen, node, 5418 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name))); 5419 variable_entry->var_type = codegen->builtin_types.entry_invalid; 5420 } else { 5421 Tld *tld = find_decl(codegen, parent_scope, name); 5422 if (tld != nullptr) { 5423 bool want_err_msg = true; 5424 if (tld->id == TldIdVar) { 5425 ZigVar *var = reinterpret_cast<TldVar *>(tld)->var; 5426 if (var != nullptr && var->var_type != nullptr && type_is_invalid(var->var_type)) { 5427 want_err_msg = false; 5428 } 5429 } 5430 if (want_err_msg) { 5431 ErrorMsg *msg = add_node_error(codegen, node, 5432 buf_sprintf("redefinition of '%s'", buf_ptr(name))); 5433 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here")); 5434 } 5435 variable_entry->var_type = codegen->builtin_types.entry_invalid; 5436 } 5437 } 5438 } 5439 } 5440 } else { 5441 assert(is_shadowable); 5442 // TODO make this name not actually be in scope. user should be able to make a variable called "_anon" 5443 // might already be solved, let's just make sure it has test coverage 5444 // maybe we put a prefix on this so the debug info doesn't clobber user debug info for same named variables 5445 variable_entry->name = "_anon"; 5446 } 5447 5448 variable_entry->src_is_const = src_is_const; 5449 variable_entry->gen_is_const = gen_is_const; 5450 variable_entry->decl_node = node; 5451 variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry); 5452 5453 return variable_entry; 5454 } 5455 5456 // Set name to nullptr to make the variable anonymous (not visible to programmer). 5457 // After you call this function var->child_scope has the variable in scope 5458 static ZigVar *ir_create_var(IrBuilderSrc *irb, AstNode *node, Scope *scope, Buf *name, 5459 bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime) 5460 { 5461 bool is_underscored = name ? buf_eql_str(name, "_") : false; 5462 ZigVar *var = create_local_var(irb->codegen, node, scope, 5463 (is_underscored ? nullptr : name), src_is_const, gen_is_const, 5464 (is_underscored ? true : is_shadowable), is_comptime, false); 5465 assert(var->child_scope); 5466 return var; 5467 } 5468 5469 static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) { 5470 ResultLocPeer *result = heap::c_allocator.create<ResultLocPeer>(); 5471 result->base.id = ResultLocIdPeer; 5472 result->base.source_instruction = peer_parent->base.source_instruction; 5473 result->parent = peer_parent; 5474 result->base.allow_write_through_const = peer_parent->parent->allow_write_through_const; 5475 return result; 5476 } 5477 5478 static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *block_node, LVal lval, 5479 ResultLoc *result_loc) 5480 { 5481 assert(block_node->type == NodeTypeBlock); 5482 5483 ZigList<IrInstSrc *> incoming_values = {0}; 5484 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 5485 5486 ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope); 5487 5488 Scope *outer_block_scope = &scope_block->base; 5489 Scope *child_scope = outer_block_scope; 5490 5491 ZigFn *fn_entry = scope_fn_entry(parent_scope); 5492 if (fn_entry && fn_entry->child_scope == parent_scope) { 5493 fn_entry->def_scope = scope_block; 5494 } 5495 5496 if (block_node->data.block.statements.length == 0) { 5497 // {} 5498 return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc); 5499 } 5500 5501 if (block_node->data.block.name != nullptr) { 5502 scope_block->lval = lval; 5503 scope_block->incoming_blocks = &incoming_blocks; 5504 scope_block->incoming_values = &incoming_values; 5505 scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd"); 5506 scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, 5507 ir_should_inline(irb->exec, parent_scope)); 5508 5509 scope_block->peer_parent = heap::c_allocator.create<ResultLocPeerParent>(); 5510 scope_block->peer_parent->base.id = ResultLocIdPeerParent; 5511 scope_block->peer_parent->base.source_instruction = scope_block->is_comptime; 5512 scope_block->peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; 5513 scope_block->peer_parent->end_bb = scope_block->end_block; 5514 scope_block->peer_parent->is_comptime = scope_block->is_comptime; 5515 scope_block->peer_parent->parent = result_loc; 5516 ir_build_reset_result(irb, parent_scope, block_node, &scope_block->peer_parent->base); 5517 } 5518 5519 bool is_continuation_unreachable = false; 5520 bool found_invalid_inst = false; 5521 IrInstSrc *noreturn_return_value = nullptr; 5522 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { 5523 AstNode *statement_node = block_node->data.block.statements.at(i); 5524 5525 IrInstSrc *statement_value = ir_gen_node(irb, statement_node, child_scope); 5526 if (statement_value == irb->codegen->invalid_inst_src) { 5527 // keep generating all the elements of the block in case of error, 5528 // we want to collect other compile errors 5529 found_invalid_inst = true; 5530 continue; 5531 } 5532 5533 is_continuation_unreachable = instr_is_unreachable(statement_value); 5534 if (is_continuation_unreachable) { 5535 // keep the last noreturn statement value around in case we need to return it 5536 noreturn_return_value = statement_value; 5537 } 5538 // This logic must be kept in sync with 5539 // [STMT_EXPR_TEST_THING] <--- (search this token) 5540 if (statement_node->type == NodeTypeDefer) { 5541 // defer starts a new scope 5542 child_scope = statement_node->data.defer.child_scope; 5543 assert(child_scope); 5544 } else if (statement_value->id == IrInstSrcIdDeclVar) { 5545 // variable declarations start a new scope 5546 IrInstSrcDeclVar *decl_var_instruction = (IrInstSrcDeclVar *)statement_value; 5547 child_scope = decl_var_instruction->var->child_scope; 5548 } else if (!is_continuation_unreachable) { 5549 // this statement's value must be void 5550 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value)); 5551 } 5552 } 5553 5554 if (found_invalid_inst) 5555 return irb->codegen->invalid_inst_src; 5556 5557 if (is_continuation_unreachable) { 5558 assert(noreturn_return_value != nullptr); 5559 if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) { 5560 return noreturn_return_value; 5561 } 5562 5563 if (scope_block->peer_parent != nullptr && scope_block->peer_parent->peers.length != 0) { 5564 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; 5565 } 5566 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 5567 IrInstSrc *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, 5568 incoming_blocks.items, incoming_values.items, scope_block->peer_parent); 5569 return ir_expr_wrap(irb, parent_scope, phi, result_loc); 5570 } else { 5571 incoming_blocks.append(irb->current_basic_block); 5572 IrInstSrc *else_expr_result = ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node)); 5573 5574 if (scope_block->peer_parent != nullptr) { 5575 ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent); 5576 scope_block->peer_parent->peers.append(peer_result); 5577 ir_build_end_expr(irb, parent_scope, block_node, else_expr_result, &peer_result->base); 5578 5579 if (scope_block->peer_parent->peers.length != 0) { 5580 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; 5581 } 5582 } 5583 5584 incoming_values.append(else_expr_result); 5585 } 5586 5587 bool is_return_from_fn = block_node == irb->main_block_node; 5588 if (!is_return_from_fn) { 5589 if (!ir_gen_defers_for_block(irb, child_scope, outer_block_scope, nullptr, nullptr)) 5590 return irb->codegen->invalid_inst_src; 5591 } 5592 5593 IrInstSrc *result; 5594 if (block_node->data.block.name != nullptr) { 5595 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); 5596 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 5597 IrInstSrc *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, 5598 incoming_blocks.items, incoming_values.items, scope_block->peer_parent); 5599 result = ir_expr_wrap(irb, parent_scope, phi, result_loc); 5600 } else { 5601 IrInstSrc *void_inst = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)); 5602 result = ir_lval_wrap(irb, parent_scope, void_inst, lval, result_loc); 5603 } 5604 if (!is_return_from_fn) 5605 return result; 5606 5607 // no need for save_err_ret_addr because this cannot return error 5608 // only generate unconditional defers 5609 5610 ir_mark_gen(ir_build_add_implicit_return_type(irb, child_scope, block_node, result, nullptr)); 5611 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>(); 5612 result_loc_ret->base.id = ResultLocIdReturn; 5613 ir_build_reset_result(irb, parent_scope, block_node, &result_loc_ret->base); 5614 ir_mark_gen(ir_build_end_expr(irb, parent_scope, block_node, result, &result_loc_ret->base)); 5615 if (!ir_gen_defers_for_block(irb, child_scope, outer_block_scope, nullptr, nullptr)) 5616 return irb->codegen->invalid_inst_src; 5617 return ir_mark_gen(ir_build_return_src(irb, child_scope, result->base.source_node, result)); 5618 } 5619 5620 static IrInstSrc *ir_gen_bin_op_id(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 5621 Scope *inner_scope = scope; 5622 if (op_id == IrBinOpArrayCat || op_id == IrBinOpArrayMult) { 5623 inner_scope = create_comptime_scope(irb->codegen, node, scope); 5624 } 5625 5626 IrInstSrc *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, inner_scope); 5627 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, inner_scope); 5628 5629 if (op1 == irb->codegen->invalid_inst_src || op2 == irb->codegen->invalid_inst_src) 5630 return irb->codegen->invalid_inst_src; 5631 5632 return ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 5633 } 5634 5635 static IrInstSrc *ir_gen_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5636 IrInstSrc *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 5637 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5638 5639 if (op1 == irb->codegen->invalid_inst_src || op2 == irb->codegen->invalid_inst_src) 5640 return irb->codegen->invalid_inst_src; 5641 5642 // TODO only pass type_name when the || operator is the top level AST node in the var decl expr 5643 Buf bare_name = BUF_INIT; 5644 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error", scope, node, &bare_name); 5645 5646 return ir_build_merge_err_sets(irb, scope, node, op1, op2, type_name); 5647 } 5648 5649 static IrInstSrc *ir_gen_assign(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5650 IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValAssign, nullptr); 5651 if (lvalue == irb->codegen->invalid_inst_src) 5652 return irb->codegen->invalid_inst_src; 5653 5654 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>(); 5655 result_loc_inst->base.id = ResultLocIdInstruction; 5656 result_loc_inst->base.source_instruction = lvalue; 5657 ir_ref_instruction(lvalue, irb->current_basic_block); 5658 ir_build_reset_result(irb, scope, node, &result_loc_inst->base); 5659 5660 IrInstSrc *rvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op2, scope, LValNone, 5661 &result_loc_inst->base); 5662 if (rvalue == irb->codegen->invalid_inst_src) 5663 return irb->codegen->invalid_inst_src; 5664 5665 return ir_build_const_void(irb, scope, node); 5666 } 5667 5668 static IrInstSrc *ir_gen_assign_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5669 IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValAssign, nullptr); 5670 if (lvalue == irb->codegen->invalid_inst_src) 5671 return lvalue; 5672 IrInstSrc *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); 5673 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5674 if (op2 == irb->codegen->invalid_inst_src) 5675 return op2; 5676 IrInstSrc *result = ir_build_merge_err_sets(irb, scope, node, op1, op2, nullptr); 5677 ir_build_store_ptr(irb, scope, node, lvalue, result); 5678 return ir_build_const_void(irb, scope, node); 5679 } 5680 5681 static IrInstSrc *ir_gen_assign_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 5682 IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValAssign, nullptr); 5683 if (lvalue == irb->codegen->invalid_inst_src) 5684 return lvalue; 5685 IrInstSrc *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); 5686 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5687 if (op2 == irb->codegen->invalid_inst_src) 5688 return op2; 5689 IrInstSrc *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 5690 ir_build_store_ptr(irb, scope, node, lvalue, result); 5691 return ir_build_const_void(irb, scope, node); 5692 } 5693 5694 static IrInstSrc *ir_gen_bool_or(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5695 assert(node->type == NodeTypeBinOpExpr); 5696 5697 IrInstSrc *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 5698 if (val1 == irb->codegen->invalid_inst_src) 5699 return irb->codegen->invalid_inst_src; 5700 IrBasicBlockSrc *post_val1_block = irb->current_basic_block; 5701 5702 IrInstSrc *is_comptime; 5703 if (ir_should_inline(irb->exec, scope)) { 5704 is_comptime = ir_build_const_bool(irb, scope, node, true); 5705 } else { 5706 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 5707 } 5708 5709 // block for when val1 == false 5710 IrBasicBlockSrc *false_block = ir_create_basic_block(irb, scope, "BoolOrFalse"); 5711 // block for when val1 == true (don't even evaluate the second part) 5712 IrBasicBlockSrc *true_block = ir_create_basic_block(irb, scope, "BoolOrTrue"); 5713 5714 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 5715 5716 ir_set_cursor_at_end_and_append_block(irb, false_block); 5717 IrInstSrc *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5718 if (val2 == irb->codegen->invalid_inst_src) 5719 return irb->codegen->invalid_inst_src; 5720 IrBasicBlockSrc *post_val2_block = irb->current_basic_block; 5721 5722 ir_build_br(irb, scope, node, true_block, is_comptime); 5723 5724 ir_set_cursor_at_end_and_append_block(irb, true_block); 5725 5726 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 5727 incoming_values[0] = val1; 5728 incoming_values[1] = val2; 5729 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 5730 incoming_blocks[0] = post_val1_block; 5731 incoming_blocks[1] = post_val2_block; 5732 5733 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); 5734 } 5735 5736 static IrInstSrc *ir_gen_bool_and(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5737 assert(node->type == NodeTypeBinOpExpr); 5738 5739 IrInstSrc *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 5740 if (val1 == irb->codegen->invalid_inst_src) 5741 return irb->codegen->invalid_inst_src; 5742 IrBasicBlockSrc *post_val1_block = irb->current_basic_block; 5743 5744 IrInstSrc *is_comptime; 5745 if (ir_should_inline(irb->exec, scope)) { 5746 is_comptime = ir_build_const_bool(irb, scope, node, true); 5747 } else { 5748 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 5749 } 5750 5751 // block for when val1 == true 5752 IrBasicBlockSrc *true_block = ir_create_basic_block(irb, scope, "BoolAndTrue"); 5753 // block for when val1 == false (don't even evaluate the second part) 5754 IrBasicBlockSrc *false_block = ir_create_basic_block(irb, scope, "BoolAndFalse"); 5755 5756 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 5757 5758 ir_set_cursor_at_end_and_append_block(irb, true_block); 5759 IrInstSrc *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5760 if (val2 == irb->codegen->invalid_inst_src) 5761 return irb->codegen->invalid_inst_src; 5762 IrBasicBlockSrc *post_val2_block = irb->current_basic_block; 5763 5764 ir_build_br(irb, scope, node, false_block, is_comptime); 5765 5766 ir_set_cursor_at_end_and_append_block(irb, false_block); 5767 5768 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 5769 incoming_values[0] = val1; 5770 incoming_values[1] = val2; 5771 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 5772 incoming_blocks[0] = post_val1_block; 5773 incoming_blocks[1] = post_val2_block; 5774 5775 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); 5776 } 5777 5778 static ResultLocPeerParent *ir_build_result_peers(IrBuilderSrc *irb, IrInstSrc *cond_br_inst, 5779 IrBasicBlockSrc *end_block, ResultLoc *parent, IrInstSrc *is_comptime) 5780 { 5781 ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>(); 5782 peer_parent->base.id = ResultLocIdPeerParent; 5783 peer_parent->base.source_instruction = cond_br_inst; 5784 peer_parent->base.allow_write_through_const = parent->allow_write_through_const; 5785 peer_parent->end_bb = end_block; 5786 peer_parent->is_comptime = is_comptime; 5787 peer_parent->parent = parent; 5788 5789 IrInstSrc *popped_inst = irb->current_basic_block->instruction_list.pop(); 5790 ir_assert(popped_inst == cond_br_inst, &cond_br_inst->base); 5791 5792 ir_build_reset_result(irb, cond_br_inst->base.scope, cond_br_inst->base.source_node, &peer_parent->base); 5793 irb->current_basic_block->instruction_list.append(popped_inst); 5794 5795 return peer_parent; 5796 } 5797 5798 static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilderSrc *irb, IrInstSrc *cond_br_inst, 5799 IrBasicBlockSrc *else_block, IrBasicBlockSrc *end_block, ResultLoc *parent, IrInstSrc *is_comptime) 5800 { 5801 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, parent, is_comptime); 5802 5803 peer_parent->peers.append(create_peer_result(peer_parent)); 5804 peer_parent->peers.last()->next_bb = else_block; 5805 5806 peer_parent->peers.append(create_peer_result(peer_parent)); 5807 peer_parent->peers.last()->next_bb = end_block; 5808 5809 return peer_parent; 5810 } 5811 5812 static IrInstSrc *ir_gen_orelse(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval, 5813 ResultLoc *result_loc) 5814 { 5815 assert(node->type == NodeTypeBinOpExpr); 5816 5817 AstNode *op1_node = node->data.bin_op_expr.op1; 5818 AstNode *op2_node = node->data.bin_op_expr.op2; 5819 5820 IrInstSrc *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); 5821 if (maybe_ptr == irb->codegen->invalid_inst_src) 5822 return irb->codegen->invalid_inst_src; 5823 5824 IrInstSrc *maybe_val = ir_build_load_ptr(irb, parent_scope, node, maybe_ptr); 5825 IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, parent_scope, node, maybe_val); 5826 5827 IrInstSrc *is_comptime; 5828 if (ir_should_inline(irb->exec, parent_scope)) { 5829 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 5830 } else { 5831 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_non_null); 5832 } 5833 5834 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); 5835 IrBasicBlockSrc *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); 5836 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); 5837 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); 5838 5839 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, 5840 result_loc, is_comptime); 5841 5842 ir_set_cursor_at_end_and_append_block(irb, null_block); 5843 IrInstSrc *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, LValNone, 5844 &peer_parent->peers.at(0)->base); 5845 if (null_result == irb->codegen->invalid_inst_src) 5846 return irb->codegen->invalid_inst_src; 5847 IrBasicBlockSrc *after_null_block = irb->current_basic_block; 5848 if (!instr_is_unreachable(null_result)) 5849 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 5850 5851 ir_set_cursor_at_end_and_append_block(irb, ok_block); 5852 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false); 5853 IrInstSrc *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 5854 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); 5855 IrBasicBlockSrc *after_ok_block = irb->current_basic_block; 5856 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 5857 5858 ir_set_cursor_at_end_and_append_block(irb, end_block); 5859 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 5860 incoming_values[0] = null_result; 5861 incoming_values[1] = unwrapped_payload; 5862 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 5863 incoming_blocks[0] = after_null_block; 5864 incoming_blocks[1] = after_ok_block; 5865 IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); 5866 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 5867 } 5868 5869 static IrInstSrc *ir_gen_error_union(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 5870 assert(node->type == NodeTypeBinOpExpr); 5871 5872 AstNode *op1_node = node->data.bin_op_expr.op1; 5873 AstNode *op2_node = node->data.bin_op_expr.op2; 5874 5875 IrInstSrc *err_set = ir_gen_node(irb, op1_node, parent_scope); 5876 if (err_set == irb->codegen->invalid_inst_src) 5877 return irb->codegen->invalid_inst_src; 5878 5879 IrInstSrc *payload = ir_gen_node(irb, op2_node, parent_scope); 5880 if (payload == irb->codegen->invalid_inst_src) 5881 return irb->codegen->invalid_inst_src; 5882 5883 return ir_build_error_union(irb, parent_scope, node, err_set, payload); 5884 } 5885 5886 static IrInstSrc *ir_gen_bin_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 5887 assert(node->type == NodeTypeBinOpExpr); 5888 5889 BinOpType bin_op_type = node->data.bin_op_expr.bin_op; 5890 switch (bin_op_type) { 5891 case BinOpTypeInvalid: 5892 zig_unreachable(); 5893 case BinOpTypeAssign: 5894 return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc); 5895 case BinOpTypeAssignTimes: 5896 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMult), lval, result_loc); 5897 case BinOpTypeAssignTimesWrap: 5898 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap), lval, result_loc); 5899 case BinOpTypeAssignDiv: 5900 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); 5901 case BinOpTypeAssignMod: 5902 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); 5903 case BinOpTypeAssignPlus: 5904 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAdd), lval, result_loc); 5905 case BinOpTypeAssignPlusWrap: 5906 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap), lval, result_loc); 5907 case BinOpTypeAssignMinus: 5908 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSub), lval, result_loc); 5909 case BinOpTypeAssignMinusWrap: 5910 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap), lval, result_loc); 5911 case BinOpTypeAssignBitShiftLeft: 5912 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); 5913 case BinOpTypeAssignBitShiftRight: 5914 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); 5915 case BinOpTypeAssignBitAnd: 5916 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd), lval, result_loc); 5917 case BinOpTypeAssignBitXor: 5918 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinXor), lval, result_loc); 5919 case BinOpTypeAssignBitOr: 5920 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinOr), lval, result_loc); 5921 case BinOpTypeAssignMergeErrorSets: 5922 return ir_lval_wrap(irb, scope, ir_gen_assign_merge_err_sets(irb, scope, node), lval, result_loc); 5923 case BinOpTypeBoolOr: 5924 return ir_lval_wrap(irb, scope, ir_gen_bool_or(irb, scope, node), lval, result_loc); 5925 case BinOpTypeBoolAnd: 5926 return ir_lval_wrap(irb, scope, ir_gen_bool_and(irb, scope, node), lval, result_loc); 5927 case BinOpTypeCmpEq: 5928 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq), lval, result_loc); 5929 case BinOpTypeCmpNotEq: 5930 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq), lval, result_loc); 5931 case BinOpTypeCmpLessThan: 5932 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan), lval, result_loc); 5933 case BinOpTypeCmpGreaterThan: 5934 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan), lval, result_loc); 5935 case BinOpTypeCmpLessOrEq: 5936 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq), lval, result_loc); 5937 case BinOpTypeCmpGreaterOrEq: 5938 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc); 5939 case BinOpTypeBinOr: 5940 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr), lval, result_loc); 5941 case BinOpTypeBinXor: 5942 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor), lval, result_loc); 5943 case BinOpTypeBinAnd: 5944 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd), lval, result_loc); 5945 case BinOpTypeBitShiftLeft: 5946 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); 5947 case BinOpTypeBitShiftRight: 5948 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); 5949 case BinOpTypeAdd: 5950 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd), lval, result_loc); 5951 case BinOpTypeAddWrap: 5952 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap), lval, result_loc); 5953 case BinOpTypeSub: 5954 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSub), lval, result_loc); 5955 case BinOpTypeSubWrap: 5956 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap), lval, result_loc); 5957 case BinOpTypeMult: 5958 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMult), lval, result_loc); 5959 case BinOpTypeMultWrap: 5960 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap), lval, result_loc); 5961 case BinOpTypeDiv: 5962 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); 5963 case BinOpTypeMod: 5964 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); 5965 case BinOpTypeArrayCat: 5966 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat), lval, result_loc); 5967 case BinOpTypeArrayMult: 5968 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult), lval, result_loc); 5969 case BinOpTypeMergeErrorSets: 5970 return ir_lval_wrap(irb, scope, ir_gen_merge_err_sets(irb, scope, node), lval, result_loc); 5971 case BinOpTypeUnwrapOptional: 5972 return ir_gen_orelse(irb, scope, node, lval, result_loc); 5973 case BinOpTypeErrorUnion: 5974 return ir_lval_wrap(irb, scope, ir_gen_error_union(irb, scope, node), lval, result_loc); 5975 } 5976 zig_unreachable(); 5977 } 5978 5979 static IrInstSrc *ir_gen_int_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5980 assert(node->type == NodeTypeIntLiteral); 5981 5982 return ir_build_const_bigint(irb, scope, node, node->data.int_literal.bigint); 5983 } 5984 5985 static IrInstSrc *ir_gen_float_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5986 assert(node->type == NodeTypeFloatLiteral); 5987 5988 if (node->data.float_literal.overflow) { 5989 add_node_error(irb->codegen, node, buf_sprintf("float literal out of range of any type")); 5990 return irb->codegen->invalid_inst_src; 5991 } 5992 5993 return ir_build_const_bigfloat(irb, scope, node, node->data.float_literal.bigfloat); 5994 } 5995 5996 static IrInstSrc *ir_gen_char_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5997 assert(node->type == NodeTypeCharLiteral); 5998 5999 return ir_build_const_uint(irb, scope, node, node->data.char_literal.value); 6000 } 6001 6002 static IrInstSrc *ir_gen_null_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 6003 assert(node->type == NodeTypeNullLiteral); 6004 6005 return ir_build_const_null(irb, scope, node); 6006 } 6007 6008 static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode *node, Buf *var_name) { 6009 ScopeDecls *scope_decls = nullptr; 6010 while (scope != nullptr) { 6011 if (scope->id == ScopeIdDecls) { 6012 scope_decls = reinterpret_cast<ScopeDecls *>(scope); 6013 } 6014 scope = scope->parent; 6015 } 6016 TldVar *tld_var = heap::c_allocator.create<TldVar>(); 6017 init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); 6018 tld_var->base.resolution = TldResolutionInvalid; 6019 tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, 6020 g->invalid_inst_gen->value, &tld_var->base, g->builtin_types.entry_invalid); 6021 scope_decls->decl_table.put(var_name, &tld_var->base); 6022 } 6023 6024 static IrInstSrc *ir_gen_symbol(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 6025 Error err; 6026 assert(node->type == NodeTypeSymbol); 6027 6028 Buf *variable_name = node->data.symbol_expr.symbol; 6029 6030 if (buf_eql_str(variable_name, "_")) { 6031 if (lval == LValAssign) { 6032 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, node); 6033 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 6034 const_instruction->value->type = get_pointer_to_type(irb->codegen, 6035 irb->codegen->builtin_types.entry_void, false); 6036 const_instruction->value->special = ConstValSpecialStatic; 6037 const_instruction->value->data.x_ptr.special = ConstPtrSpecialDiscard; 6038 return &const_instruction->base; 6039 } else { 6040 add_node_error(irb->codegen, node, buf_sprintf("`_` may only be used to assign things to")); 6041 return irb->codegen->invalid_inst_src; 6042 } 6043 } 6044 6045 ZigType *primitive_type; 6046 if ((err = get_primitive_type(irb->codegen, variable_name, &primitive_type))) { 6047 if (err == ErrorOverflow) { 6048 add_node_error(irb->codegen, node, 6049 buf_sprintf("primitive integer type '%s' exceeds maximum bit width of 65535", 6050 buf_ptr(variable_name))); 6051 return irb->codegen->invalid_inst_src; 6052 } 6053 assert(err == ErrorPrimitiveTypeNotFound); 6054 } else { 6055 IrInstSrc *value = ir_build_const_type(irb, scope, node, primitive_type); 6056 if (lval == LValPtr || lval == LValAssign) { 6057 return ir_build_ref_src(irb, scope, node, value); 6058 } else { 6059 return ir_expr_wrap(irb, scope, value, result_loc); 6060 } 6061 } 6062 6063 ScopeFnDef *crossed_fndef_scope; 6064 ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope); 6065 if (var) { 6066 IrInstSrc *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); 6067 if (lval == LValPtr || lval == LValAssign) { 6068 return var_ptr; 6069 } else { 6070 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, var_ptr), result_loc); 6071 } 6072 } 6073 6074 Tld *tld = find_decl(irb->codegen, scope, variable_name); 6075 if (tld) { 6076 IrInstSrc *decl_ref = ir_build_decl_ref(irb, scope, node, tld, lval); 6077 if (lval == LValPtr || lval == LValAssign) { 6078 return decl_ref; 6079 } else { 6080 return ir_expr_wrap(irb, scope, decl_ref, result_loc); 6081 } 6082 } 6083 6084 if (get_container_scope(node->owner)->any_imports_failed) { 6085 // skip the error message since we had a failing import in this file 6086 // if an import breaks we don't need redundant undeclared identifier errors 6087 return irb->codegen->invalid_inst_src; 6088 } 6089 6090 return ir_build_undeclared_identifier(irb, scope, node, variable_name); 6091 } 6092 6093 static IrInstSrc *ir_gen_array_access(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 6094 ResultLoc *result_loc) 6095 { 6096 assert(node->type == NodeTypeArrayAccessExpr); 6097 6098 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; 6099 IrInstSrc *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr); 6100 if (array_ref_instruction == irb->codegen->invalid_inst_src) 6101 return array_ref_instruction; 6102 6103 // Create an usize-typed result location to hold the subscript value, this 6104 // makes it possible for the compiler to infer the subscript expression type 6105 // if needed 6106 IrInstSrc *usize_type_inst = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 6107 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, usize_type_inst, no_result_loc()); 6108 6109 AstNode *subscript_node = node->data.array_access_expr.subscript; 6110 IrInstSrc *subscript_value = ir_gen_node_extra(irb, subscript_node, scope, LValNone, &result_loc_cast->base); 6111 if (subscript_value == irb->codegen->invalid_inst_src) 6112 return irb->codegen->invalid_inst_src; 6113 6114 IrInstSrc *subscript_instruction = ir_build_implicit_cast(irb, scope, subscript_node, subscript_value, result_loc_cast); 6115 6116 IrInstSrc *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, 6117 subscript_instruction, true, PtrLenSingle, nullptr); 6118 if (lval == LValPtr || lval == LValAssign) 6119 return ptr_instruction; 6120 6121 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 6122 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 6123 } 6124 6125 static IrInstSrc *ir_gen_field_access(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 6126 assert(node->type == NodeTypeFieldAccessExpr); 6127 6128 AstNode *container_ref_node = node->data.field_access_expr.struct_expr; 6129 Buf *field_name = node->data.field_access_expr.field_name; 6130 6131 IrInstSrc *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr); 6132 if (container_ref_instruction == irb->codegen->invalid_inst_src) 6133 return container_ref_instruction; 6134 6135 return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name, false); 6136 } 6137 6138 static IrInstSrc *ir_gen_overflow_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrOverflowOp op) { 6139 assert(node->type == NodeTypeFnCallExpr); 6140 6141 AstNode *type_node = node->data.fn_call_expr.params.at(0); 6142 AstNode *op1_node = node->data.fn_call_expr.params.at(1); 6143 AstNode *op2_node = node->data.fn_call_expr.params.at(2); 6144 AstNode *result_ptr_node = node->data.fn_call_expr.params.at(3); 6145 6146 6147 IrInstSrc *type_value = ir_gen_node(irb, type_node, scope); 6148 if (type_value == irb->codegen->invalid_inst_src) 6149 return irb->codegen->invalid_inst_src; 6150 6151 IrInstSrc *op1 = ir_gen_node(irb, op1_node, scope); 6152 if (op1 == irb->codegen->invalid_inst_src) 6153 return irb->codegen->invalid_inst_src; 6154 6155 IrInstSrc *op2 = ir_gen_node(irb, op2_node, scope); 6156 if (op2 == irb->codegen->invalid_inst_src) 6157 return irb->codegen->invalid_inst_src; 6158 6159 IrInstSrc *result_ptr = ir_gen_node(irb, result_ptr_node, scope); 6160 if (result_ptr == irb->codegen->invalid_inst_src) 6161 return irb->codegen->invalid_inst_src; 6162 6163 return ir_build_overflow_op_src(irb, scope, node, op, type_value, op1, op2, result_ptr); 6164 } 6165 6166 static IrInstSrc *ir_gen_mul_add(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 6167 assert(node->type == NodeTypeFnCallExpr); 6168 6169 AstNode *type_node = node->data.fn_call_expr.params.at(0); 6170 AstNode *op1_node = node->data.fn_call_expr.params.at(1); 6171 AstNode *op2_node = node->data.fn_call_expr.params.at(2); 6172 AstNode *op3_node = node->data.fn_call_expr.params.at(3); 6173 6174 IrInstSrc *type_value = ir_gen_node(irb, type_node, scope); 6175 if (type_value == irb->codegen->invalid_inst_src) 6176 return irb->codegen->invalid_inst_src; 6177 6178 IrInstSrc *op1 = ir_gen_node(irb, op1_node, scope); 6179 if (op1 == irb->codegen->invalid_inst_src) 6180 return irb->codegen->invalid_inst_src; 6181 6182 IrInstSrc *op2 = ir_gen_node(irb, op2_node, scope); 6183 if (op2 == irb->codegen->invalid_inst_src) 6184 return irb->codegen->invalid_inst_src; 6185 6186 IrInstSrc *op3 = ir_gen_node(irb, op3_node, scope); 6187 if (op3 == irb->codegen->invalid_inst_src) 6188 return irb->codegen->invalid_inst_src; 6189 6190 return ir_build_mul_add_src(irb, scope, node, type_value, op1, op2, op3); 6191 } 6192 6193 static IrInstSrc *ir_gen_this(IrBuilderSrc *irb, Scope *orig_scope, AstNode *node) { 6194 for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) { 6195 if (it_scope->id == ScopeIdDecls) { 6196 ScopeDecls *decls_scope = (ScopeDecls *)it_scope; 6197 ZigType *container_type = decls_scope->container_type; 6198 if (container_type != nullptr) { 6199 return ir_build_const_type(irb, orig_scope, node, container_type); 6200 } else { 6201 return ir_build_const_import(irb, orig_scope, node, decls_scope->import); 6202 } 6203 } 6204 } 6205 zig_unreachable(); 6206 } 6207 6208 static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *await_node, AstNode *call_node, 6209 LVal lval, ResultLoc *result_loc) 6210 { 6211 if (call_node->data.fn_call_expr.params.length != 4) { 6212 add_node_error(irb->codegen, call_node, 6213 buf_sprintf("expected 4 arguments, found %" ZIG_PRI_usize, 6214 call_node->data.fn_call_expr.params.length)); 6215 return irb->codegen->invalid_inst_src; 6216 } 6217 6218 AstNode *bytes_node = call_node->data.fn_call_expr.params.at(0); 6219 IrInstSrc *bytes = ir_gen_node(irb, bytes_node, scope); 6220 if (bytes == irb->codegen->invalid_inst_src) 6221 return bytes; 6222 6223 AstNode *ret_ptr_node = call_node->data.fn_call_expr.params.at(1); 6224 IrInstSrc *ret_ptr = ir_gen_node(irb, ret_ptr_node, scope); 6225 if (ret_ptr == irb->codegen->invalid_inst_src) 6226 return ret_ptr; 6227 6228 AstNode *fn_ref_node = call_node->data.fn_call_expr.params.at(2); 6229 IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 6230 if (fn_ref == irb->codegen->invalid_inst_src) 6231 return fn_ref; 6232 6233 CallModifier modifier = (await_node == nullptr) ? CallModifierAsync : CallModifierNone; 6234 bool is_async_call_builtin = true; 6235 AstNode *args_node = call_node->data.fn_call_expr.params.at(3); 6236 if (args_node->type == NodeTypeContainerInitExpr) { 6237 if (args_node->data.container_init_expr.kind == ContainerInitKindArray || 6238 args_node->data.container_init_expr.entries.length == 0) 6239 { 6240 size_t arg_count = args_node->data.container_init_expr.entries.length; 6241 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count); 6242 for (size_t i = 0; i < arg_count; i += 1) { 6243 AstNode *arg_node = args_node->data.container_init_expr.entries.at(i); 6244 IrInstSrc *arg = ir_gen_node(irb, arg_node, scope); 6245 if (arg == irb->codegen->invalid_inst_src) 6246 return arg; 6247 args[i] = arg; 6248 } 6249 6250 IrInstSrc *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args, 6251 ret_ptr, modifier, is_async_call_builtin, bytes, result_loc); 6252 return ir_lval_wrap(irb, scope, call, lval, result_loc); 6253 } else { 6254 exec_add_error_node(irb->codegen, irb->exec, args_node, 6255 buf_sprintf("TODO: @asyncCall with anon struct literal")); 6256 return irb->codegen->invalid_inst_src; 6257 } 6258 } 6259 IrInstSrc *args = ir_gen_node(irb, args_node, scope); 6260 if (args == irb->codegen->invalid_inst_src) 6261 return args; 6262 6263 IrInstSrc *call = ir_build_async_call_extra(irb, scope, call_node, modifier, fn_ref, ret_ptr, bytes, args, result_loc); 6264 return ir_lval_wrap(irb, scope, call, lval, result_loc); 6265 } 6266 6267 static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 6268 AstNode *fn_ref_node, CallModifier modifier, IrInstSrc *options, 6269 AstNode **args_ptr, size_t args_len, LVal lval, ResultLoc *result_loc) 6270 { 6271 IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 6272 if (fn_ref == irb->codegen->invalid_inst_src) 6273 return fn_ref; 6274 6275 IrInstSrc *fn_type = ir_build_typeof_1(irb, scope, source_node, fn_ref); 6276 6277 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len); 6278 for (size_t i = 0; i < args_len; i += 1) { 6279 AstNode *arg_node = args_ptr[i]; 6280 6281 IrInstSrc *arg_index = ir_build_const_usize(irb, scope, arg_node, i); 6282 IrInstSrc *arg_type = ir_build_arg_type(irb, scope, source_node, fn_type, arg_index, true); 6283 ResultLoc *no_result = no_result_loc(); 6284 ir_build_reset_result(irb, scope, source_node, no_result); 6285 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result); 6286 6287 IrInstSrc *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base); 6288 if (arg == irb->codegen->invalid_inst_src) 6289 return arg; 6290 6291 args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast); 6292 } 6293 6294 IrInstSrc *fn_call; 6295 if (options != nullptr) { 6296 fn_call = ir_build_call_args(irb, scope, source_node, options, fn_ref, args, args_len, result_loc); 6297 } else { 6298 fn_call = ir_build_call_src(irb, scope, source_node, nullptr, fn_ref, args_len, args, nullptr, 6299 modifier, false, nullptr, result_loc); 6300 } 6301 return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); 6302 } 6303 6304 static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 6305 ResultLoc *result_loc) 6306 { 6307 assert(node->type == NodeTypeFnCallExpr); 6308 6309 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; 6310 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 6311 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 6312 6313 if (!entry) { 6314 add_node_error(irb->codegen, node, 6315 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name))); 6316 return irb->codegen->invalid_inst_src; 6317 } 6318 6319 BuiltinFnEntry *builtin_fn = entry->value; 6320 size_t actual_param_count = node->data.fn_call_expr.params.length; 6321 6322 if (builtin_fn->param_count != SIZE_MAX && builtin_fn->param_count != actual_param_count) { 6323 add_node_error(irb->codegen, node, 6324 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, 6325 builtin_fn->param_count, actual_param_count)); 6326 return irb->codegen->invalid_inst_src; 6327 } 6328 6329 switch (builtin_fn->id) { 6330 case BuiltinFnIdInvalid: 6331 zig_unreachable(); 6332 case BuiltinFnIdTypeof: 6333 { 6334 Scope *sub_scope = create_typeof_scope(irb->codegen, node, scope); 6335 6336 size_t arg_count = node->data.fn_call_expr.params.length; 6337 6338 IrInstSrc *type_of; 6339 6340 if (arg_count == 0) { 6341 add_node_error(irb->codegen, node, 6342 buf_sprintf("expected at least 1 argument, found 0")); 6343 return irb->codegen->invalid_inst_src; 6344 } else if (arg_count == 1) { 6345 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6346 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, sub_scope); 6347 if (arg0_value == irb->codegen->invalid_inst_src) 6348 return arg0_value; 6349 6350 type_of = ir_build_typeof_1(irb, scope, node, arg0_value); 6351 } else { 6352 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count); 6353 for (size_t i = 0; i < arg_count; i += 1) { 6354 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 6355 IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope); 6356 if (arg == irb->codegen->invalid_inst_src) 6357 return irb->codegen->invalid_inst_src; 6358 args[i] = arg; 6359 } 6360 6361 type_of = ir_build_typeof_n(irb, scope, node, args, arg_count); 6362 } 6363 return ir_lval_wrap(irb, scope, type_of, lval, result_loc); 6364 } 6365 case BuiltinFnIdSetCold: 6366 { 6367 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6368 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6369 if (arg0_value == irb->codegen->invalid_inst_src) 6370 return arg0_value; 6371 6372 IrInstSrc *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); 6373 return ir_lval_wrap(irb, scope, set_cold, lval, result_loc); 6374 } 6375 case BuiltinFnIdSetRuntimeSafety: 6376 { 6377 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6378 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6379 if (arg0_value == irb->codegen->invalid_inst_src) 6380 return arg0_value; 6381 6382 IrInstSrc *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); 6383 return ir_lval_wrap(irb, scope, set_safety, lval, result_loc); 6384 } 6385 case BuiltinFnIdSetFloatMode: 6386 { 6387 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6388 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6389 if (arg0_value == irb->codegen->invalid_inst_src) 6390 return arg0_value; 6391 6392 IrInstSrc *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value); 6393 return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc); 6394 } 6395 case BuiltinFnIdSizeof: 6396 case BuiltinFnIdBitSizeof: 6397 { 6398 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6399 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6400 if (arg0_value == irb->codegen->invalid_inst_src) 6401 return arg0_value; 6402 6403 IrInstSrc *size_of = ir_build_size_of(irb, scope, node, arg0_value, builtin_fn->id == BuiltinFnIdBitSizeof); 6404 return ir_lval_wrap(irb, scope, size_of, lval, result_loc); 6405 } 6406 case BuiltinFnIdImport: 6407 { 6408 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6409 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6410 if (arg0_value == irb->codegen->invalid_inst_src) 6411 return arg0_value; 6412 6413 IrInstSrc *import = ir_build_import(irb, scope, node, arg0_value); 6414 return ir_lval_wrap(irb, scope, import, lval, result_loc); 6415 } 6416 case BuiltinFnIdCImport: 6417 { 6418 IrInstSrc *c_import = ir_build_c_import(irb, scope, node); 6419 return ir_lval_wrap(irb, scope, c_import, lval, result_loc); 6420 } 6421 case BuiltinFnIdCInclude: 6422 { 6423 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6424 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6425 if (arg0_value == irb->codegen->invalid_inst_src) 6426 return arg0_value; 6427 6428 if (!exec_c_import_buf(irb->exec)) { 6429 add_node_error(irb->codegen, node, buf_sprintf("C include valid only inside C import block")); 6430 return irb->codegen->invalid_inst_src; 6431 } 6432 6433 IrInstSrc *c_include = ir_build_c_include(irb, scope, node, arg0_value); 6434 return ir_lval_wrap(irb, scope, c_include, lval, result_loc); 6435 } 6436 case BuiltinFnIdCDefine: 6437 { 6438 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6439 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6440 if (arg0_value == irb->codegen->invalid_inst_src) 6441 return arg0_value; 6442 6443 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6444 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6445 if (arg1_value == irb->codegen->invalid_inst_src) 6446 return arg1_value; 6447 6448 if (!exec_c_import_buf(irb->exec)) { 6449 add_node_error(irb->codegen, node, buf_sprintf("C define valid only inside C import block")); 6450 return irb->codegen->invalid_inst_src; 6451 } 6452 6453 IrInstSrc *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); 6454 return ir_lval_wrap(irb, scope, c_define, lval, result_loc); 6455 } 6456 case BuiltinFnIdCUndef: 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 if (!exec_c_import_buf(irb->exec)) { 6464 add_node_error(irb->codegen, node, buf_sprintf("C undef valid only inside C import block")); 6465 return irb->codegen->invalid_inst_src; 6466 } 6467 6468 IrInstSrc *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); 6469 return ir_lval_wrap(irb, scope, c_undef, lval, result_loc); 6470 } 6471 case BuiltinFnIdCompileErr: 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 IrInstSrc *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); 6479 return ir_lval_wrap(irb, scope, compile_err, lval, result_loc); 6480 } 6481 case BuiltinFnIdCompileLog: 6482 { 6483 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(actual_param_count); 6484 6485 for (size_t i = 0; i < actual_param_count; i += 1) { 6486 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 6487 args[i] = ir_gen_node(irb, arg_node, scope); 6488 if (args[i] == irb->codegen->invalid_inst_src) 6489 return irb->codegen->invalid_inst_src; 6490 } 6491 6492 IrInstSrc *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); 6493 return ir_lval_wrap(irb, scope, compile_log, lval, result_loc); 6494 } 6495 case BuiltinFnIdErrName: 6496 { 6497 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6498 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6499 if (arg0_value == irb->codegen->invalid_inst_src) 6500 return arg0_value; 6501 6502 IrInstSrc *err_name = ir_build_err_name(irb, scope, node, arg0_value); 6503 return ir_lval_wrap(irb, scope, err_name, lval, result_loc); 6504 } 6505 case BuiltinFnIdEmbedFile: 6506 { 6507 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6508 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6509 if (arg0_value == irb->codegen->invalid_inst_src) 6510 return arg0_value; 6511 6512 IrInstSrc *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); 6513 return ir_lval_wrap(irb, scope, embed_file, lval, result_loc); 6514 } 6515 case BuiltinFnIdCmpxchgWeak: 6516 case BuiltinFnIdCmpxchgStrong: 6517 { 6518 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6519 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6520 if (arg0_value == irb->codegen->invalid_inst_src) 6521 return arg0_value; 6522 6523 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6524 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6525 if (arg1_value == irb->codegen->invalid_inst_src) 6526 return arg1_value; 6527 6528 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 6529 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 6530 if (arg2_value == irb->codegen->invalid_inst_src) 6531 return arg2_value; 6532 6533 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 6534 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); 6535 if (arg3_value == irb->codegen->invalid_inst_src) 6536 return arg3_value; 6537 6538 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 6539 IrInstSrc *arg4_value = ir_gen_node(irb, arg4_node, scope); 6540 if (arg4_value == irb->codegen->invalid_inst_src) 6541 return arg4_value; 6542 6543 AstNode *arg5_node = node->data.fn_call_expr.params.at(5); 6544 IrInstSrc *arg5_value = ir_gen_node(irb, arg5_node, scope); 6545 if (arg5_value == irb->codegen->invalid_inst_src) 6546 return arg5_value; 6547 6548 IrInstSrc *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value, 6549 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak), 6550 result_loc); 6551 return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc); 6552 } 6553 case BuiltinFnIdFence: 6554 { 6555 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6556 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6557 if (arg0_value == irb->codegen->invalid_inst_src) 6558 return arg0_value; 6559 6560 IrInstSrc *fence = ir_build_fence(irb, scope, node, arg0_value); 6561 return ir_lval_wrap(irb, scope, fence, lval, result_loc); 6562 } 6563 case BuiltinFnIdDivExact: 6564 { 6565 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6566 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6567 if (arg0_value == irb->codegen->invalid_inst_src) 6568 return arg0_value; 6569 6570 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6571 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6572 if (arg1_value == irb->codegen->invalid_inst_src) 6573 return arg1_value; 6574 6575 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); 6576 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6577 } 6578 case BuiltinFnIdDivTrunc: 6579 { 6580 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6581 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6582 if (arg0_value == irb->codegen->invalid_inst_src) 6583 return arg0_value; 6584 6585 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6586 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6587 if (arg1_value == irb->codegen->invalid_inst_src) 6588 return arg1_value; 6589 6590 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); 6591 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6592 } 6593 case BuiltinFnIdDivFloor: 6594 { 6595 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6596 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6597 if (arg0_value == irb->codegen->invalid_inst_src) 6598 return arg0_value; 6599 6600 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6601 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6602 if (arg1_value == irb->codegen->invalid_inst_src) 6603 return arg1_value; 6604 6605 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); 6606 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6607 } 6608 case BuiltinFnIdRem: 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 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); 6621 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6622 } 6623 case BuiltinFnIdMod: 6624 { 6625 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6626 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6627 if (arg0_value == irb->codegen->invalid_inst_src) 6628 return arg0_value; 6629 6630 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6631 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6632 if (arg1_value == irb->codegen->invalid_inst_src) 6633 return arg1_value; 6634 6635 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); 6636 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6637 } 6638 case BuiltinFnIdSqrt: 6639 case BuiltinFnIdSin: 6640 case BuiltinFnIdCos: 6641 case BuiltinFnIdExp: 6642 case BuiltinFnIdExp2: 6643 case BuiltinFnIdLog: 6644 case BuiltinFnIdLog2: 6645 case BuiltinFnIdLog10: 6646 case BuiltinFnIdFabs: 6647 case BuiltinFnIdFloor: 6648 case BuiltinFnIdCeil: 6649 case BuiltinFnIdTrunc: 6650 case BuiltinFnIdNearbyInt: 6651 case BuiltinFnIdRound: 6652 { 6653 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6654 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6655 if (arg0_value == irb->codegen->invalid_inst_src) 6656 return arg0_value; 6657 6658 IrInstSrc *inst = ir_build_float_op_src(irb, scope, node, arg0_value, builtin_fn->id); 6659 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 6660 } 6661 case BuiltinFnIdTruncate: 6662 { 6663 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6664 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6665 if (arg0_value == irb->codegen->invalid_inst_src) 6666 return arg0_value; 6667 6668 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6669 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6670 if (arg1_value == irb->codegen->invalid_inst_src) 6671 return arg1_value; 6672 6673 IrInstSrc *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); 6674 return ir_lval_wrap(irb, scope, truncate, lval, result_loc); 6675 } 6676 case BuiltinFnIdIntCast: 6677 { 6678 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6679 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6680 if (arg0_value == irb->codegen->invalid_inst_src) 6681 return arg0_value; 6682 6683 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6684 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6685 if (arg1_value == irb->codegen->invalid_inst_src) 6686 return arg1_value; 6687 6688 IrInstSrc *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); 6689 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6690 } 6691 case BuiltinFnIdFloatCast: 6692 { 6693 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6694 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6695 if (arg0_value == irb->codegen->invalid_inst_src) 6696 return arg0_value; 6697 6698 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6699 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6700 if (arg1_value == irb->codegen->invalid_inst_src) 6701 return arg1_value; 6702 6703 IrInstSrc *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); 6704 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6705 } 6706 case BuiltinFnIdErrSetCast: 6707 { 6708 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6709 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6710 if (arg0_value == irb->codegen->invalid_inst_src) 6711 return arg0_value; 6712 6713 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6714 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6715 if (arg1_value == irb->codegen->invalid_inst_src) 6716 return arg1_value; 6717 6718 IrInstSrc *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); 6719 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6720 } 6721 case BuiltinFnIdIntToFloat: 6722 { 6723 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6724 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6725 if (arg0_value == irb->codegen->invalid_inst_src) 6726 return arg0_value; 6727 6728 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6729 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6730 if (arg1_value == irb->codegen->invalid_inst_src) 6731 return arg1_value; 6732 6733 IrInstSrc *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); 6734 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6735 } 6736 case BuiltinFnIdFloatToInt: 6737 { 6738 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6739 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6740 if (arg0_value == irb->codegen->invalid_inst_src) 6741 return arg0_value; 6742 6743 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6744 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6745 if (arg1_value == irb->codegen->invalid_inst_src) 6746 return arg1_value; 6747 6748 IrInstSrc *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); 6749 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6750 } 6751 case BuiltinFnIdErrToInt: 6752 { 6753 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6754 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6755 if (arg0_value == irb->codegen->invalid_inst_src) 6756 return arg0_value; 6757 6758 IrInstSrc *result = ir_build_err_to_int_src(irb, scope, node, arg0_value); 6759 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6760 } 6761 case BuiltinFnIdIntToErr: 6762 { 6763 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6764 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6765 if (arg0_value == irb->codegen->invalid_inst_src) 6766 return arg0_value; 6767 6768 IrInstSrc *result = ir_build_int_to_err_src(irb, scope, node, arg0_value); 6769 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6770 } 6771 case BuiltinFnIdBoolToInt: 6772 { 6773 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6774 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6775 if (arg0_value == irb->codegen->invalid_inst_src) 6776 return arg0_value; 6777 6778 IrInstSrc *result = ir_build_bool_to_int(irb, scope, node, arg0_value); 6779 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6780 } 6781 case BuiltinFnIdVectorType: 6782 { 6783 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6784 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6785 if (arg0_value == irb->codegen->invalid_inst_src) 6786 return arg0_value; 6787 6788 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6789 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6790 if (arg1_value == irb->codegen->invalid_inst_src) 6791 return arg1_value; 6792 6793 IrInstSrc *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value); 6794 return ir_lval_wrap(irb, scope, vector_type, lval, result_loc); 6795 } 6796 case BuiltinFnIdShuffle: 6797 { 6798 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6799 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6800 if (arg0_value == irb->codegen->invalid_inst_src) 6801 return arg0_value; 6802 6803 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6804 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6805 if (arg1_value == irb->codegen->invalid_inst_src) 6806 return arg1_value; 6807 6808 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 6809 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 6810 if (arg2_value == irb->codegen->invalid_inst_src) 6811 return arg2_value; 6812 6813 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 6814 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); 6815 if (arg3_value == irb->codegen->invalid_inst_src) 6816 return arg3_value; 6817 6818 IrInstSrc *shuffle_vector = ir_build_shuffle_vector(irb, scope, node, 6819 arg0_value, arg1_value, arg2_value, arg3_value); 6820 return ir_lval_wrap(irb, scope, shuffle_vector, lval, result_loc); 6821 } 6822 case BuiltinFnIdSplat: 6823 { 6824 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6825 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6826 if (arg0_value == irb->codegen->invalid_inst_src) 6827 return arg0_value; 6828 6829 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6830 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6831 if (arg1_value == irb->codegen->invalid_inst_src) 6832 return arg1_value; 6833 6834 IrInstSrc *splat = ir_build_splat_src(irb, scope, node, 6835 arg0_value, arg1_value); 6836 return ir_lval_wrap(irb, scope, splat, lval, result_loc); 6837 } 6838 case BuiltinFnIdMemcpy: 6839 { 6840 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6841 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6842 if (arg0_value == irb->codegen->invalid_inst_src) 6843 return arg0_value; 6844 6845 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6846 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6847 if (arg1_value == irb->codegen->invalid_inst_src) 6848 return arg1_value; 6849 6850 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 6851 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 6852 if (arg2_value == irb->codegen->invalid_inst_src) 6853 return arg2_value; 6854 6855 IrInstSrc *ir_memcpy = ir_build_memcpy_src(irb, scope, node, arg0_value, arg1_value, arg2_value); 6856 return ir_lval_wrap(irb, scope, ir_memcpy, lval, result_loc); 6857 } 6858 case BuiltinFnIdMemset: 6859 { 6860 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6861 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6862 if (arg0_value == irb->codegen->invalid_inst_src) 6863 return arg0_value; 6864 6865 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6866 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6867 if (arg1_value == irb->codegen->invalid_inst_src) 6868 return arg1_value; 6869 6870 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 6871 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 6872 if (arg2_value == irb->codegen->invalid_inst_src) 6873 return arg2_value; 6874 6875 IrInstSrc *ir_memset = ir_build_memset_src(irb, scope, node, arg0_value, arg1_value, arg2_value); 6876 return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc); 6877 } 6878 case BuiltinFnIdWasmMemorySize: 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 IrInstSrc *ir_wasm_memory_size = ir_build_wasm_memory_size_src(irb, scope, node, arg0_value); 6886 return ir_lval_wrap(irb, scope, ir_wasm_memory_size, lval, result_loc); 6887 } 6888 case BuiltinFnIdWasmMemoryGrow: 6889 { 6890 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6891 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6892 if (arg0_value == irb->codegen->invalid_inst_src) 6893 return arg0_value; 6894 6895 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6896 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6897 if (arg1_value == irb->codegen->invalid_inst_src) 6898 return arg1_value; 6899 6900 IrInstSrc *ir_wasm_memory_grow = ir_build_wasm_memory_grow_src(irb, scope, node, arg0_value, arg1_value); 6901 return ir_lval_wrap(irb, scope, ir_wasm_memory_grow, lval, result_loc); 6902 } 6903 case BuiltinFnIdField: 6904 { 6905 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6906 IrInstSrc *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr); 6907 if (arg0_value == irb->codegen->invalid_inst_src) 6908 return arg0_value; 6909 6910 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6911 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6912 if (arg1_value == irb->codegen->invalid_inst_src) 6913 return arg1_value; 6914 6915 IrInstSrc *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, 6916 arg0_value, arg1_value, false); 6917 6918 if (lval == LValPtr || lval == LValAssign) 6919 return ptr_instruction; 6920 6921 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 6922 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 6923 } 6924 case BuiltinFnIdHasField: 6925 { 6926 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6927 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6928 if (arg0_value == irb->codegen->invalid_inst_src) 6929 return arg0_value; 6930 6931 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6932 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6933 if (arg1_value == irb->codegen->invalid_inst_src) 6934 return arg1_value; 6935 6936 IrInstSrc *type_info = ir_build_has_field(irb, scope, node, arg0_value, arg1_value); 6937 return ir_lval_wrap(irb, scope, type_info, lval, result_loc); 6938 } 6939 case BuiltinFnIdTypeInfo: 6940 { 6941 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6942 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6943 if (arg0_value == irb->codegen->invalid_inst_src) 6944 return arg0_value; 6945 6946 IrInstSrc *type_info = ir_build_type_info(irb, scope, node, arg0_value); 6947 return ir_lval_wrap(irb, scope, type_info, lval, result_loc); 6948 } 6949 case BuiltinFnIdType: 6950 { 6951 AstNode *arg_node = node->data.fn_call_expr.params.at(0); 6952 IrInstSrc *arg = ir_gen_node(irb, arg_node, scope); 6953 if (arg == irb->codegen->invalid_inst_src) 6954 return arg; 6955 6956 IrInstSrc *type = ir_build_type(irb, scope, node, arg); 6957 return ir_lval_wrap(irb, scope, type, lval, result_loc); 6958 } 6959 case BuiltinFnIdBreakpoint: 6960 return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval, result_loc); 6961 case BuiltinFnIdReturnAddress: 6962 return ir_lval_wrap(irb, scope, ir_build_return_address_src(irb, scope, node), lval, result_loc); 6963 case BuiltinFnIdFrameAddress: 6964 return ir_lval_wrap(irb, scope, ir_build_frame_address_src(irb, scope, node), lval, result_loc); 6965 case BuiltinFnIdFrameHandle: 6966 if (!irb->exec->fn_entry) { 6967 add_node_error(irb->codegen, node, buf_sprintf("@frame() called outside of function definition")); 6968 return irb->codegen->invalid_inst_src; 6969 } 6970 return ir_lval_wrap(irb, scope, ir_build_handle_src(irb, scope, node), lval, result_loc); 6971 case BuiltinFnIdFrameType: { 6972 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6973 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6974 if (arg0_value == irb->codegen->invalid_inst_src) 6975 return arg0_value; 6976 6977 IrInstSrc *frame_type = ir_build_frame_type(irb, scope, node, arg0_value); 6978 return ir_lval_wrap(irb, scope, frame_type, lval, result_loc); 6979 } 6980 case BuiltinFnIdFrameSize: { 6981 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6982 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6983 if (arg0_value == irb->codegen->invalid_inst_src) 6984 return arg0_value; 6985 6986 IrInstSrc *frame_size = ir_build_frame_size_src(irb, scope, node, arg0_value); 6987 return ir_lval_wrap(irb, scope, frame_size, lval, result_loc); 6988 } 6989 case BuiltinFnIdAlignOf: 6990 { 6991 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6992 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6993 if (arg0_value == irb->codegen->invalid_inst_src) 6994 return arg0_value; 6995 6996 IrInstSrc *align_of = ir_build_align_of(irb, scope, node, arg0_value); 6997 return ir_lval_wrap(irb, scope, align_of, lval, result_loc); 6998 } 6999 case BuiltinFnIdAddWithOverflow: 7000 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval, result_loc); 7001 case BuiltinFnIdSubWithOverflow: 7002 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval, result_loc); 7003 case BuiltinFnIdMulWithOverflow: 7004 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval, result_loc); 7005 case BuiltinFnIdShlWithOverflow: 7006 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval, result_loc); 7007 case BuiltinFnIdMulAdd: 7008 return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval, result_loc); 7009 case BuiltinFnIdTypeName: 7010 { 7011 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7012 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7013 if (arg0_value == irb->codegen->invalid_inst_src) 7014 return arg0_value; 7015 7016 IrInstSrc *type_name = ir_build_type_name(irb, scope, node, arg0_value); 7017 return ir_lval_wrap(irb, scope, type_name, lval, result_loc); 7018 } 7019 case BuiltinFnIdPanic: 7020 { 7021 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7022 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7023 if (arg0_value == irb->codegen->invalid_inst_src) 7024 return arg0_value; 7025 7026 IrInstSrc *panic = ir_build_panic_src(irb, scope, node, arg0_value); 7027 return ir_lval_wrap(irb, scope, panic, lval, result_loc); 7028 } 7029 case BuiltinFnIdPtrCast: 7030 { 7031 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7032 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7033 if (arg0_value == irb->codegen->invalid_inst_src) 7034 return arg0_value; 7035 7036 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7037 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7038 if (arg1_value == irb->codegen->invalid_inst_src) 7039 return arg1_value; 7040 7041 IrInstSrc *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true); 7042 return ir_lval_wrap(irb, scope, ptr_cast, lval, result_loc); 7043 } 7044 case BuiltinFnIdBitCast: 7045 { 7046 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); 7047 IrInstSrc *dest_type = ir_gen_node(irb, dest_type_node, scope); 7048 if (dest_type == irb->codegen->invalid_inst_src) 7049 return dest_type; 7050 7051 ResultLocBitCast *result_loc_bit_cast = heap::c_allocator.create<ResultLocBitCast>(); 7052 result_loc_bit_cast->base.id = ResultLocIdBitCast; 7053 result_loc_bit_cast->base.source_instruction = dest_type; 7054 result_loc_bit_cast->base.allow_write_through_const = result_loc->allow_write_through_const; 7055 ir_ref_instruction(dest_type, irb->current_basic_block); 7056 result_loc_bit_cast->parent = result_loc; 7057 7058 ir_build_reset_result(irb, scope, node, &result_loc_bit_cast->base); 7059 7060 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7061 IrInstSrc *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, 7062 &result_loc_bit_cast->base); 7063 if (arg1_value == irb->codegen->invalid_inst_src) 7064 return arg1_value; 7065 7066 IrInstSrc *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast); 7067 return ir_lval_wrap(irb, scope, bitcast, lval, result_loc); 7068 } 7069 case BuiltinFnIdAs: 7070 { 7071 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); 7072 IrInstSrc *dest_type = ir_gen_node(irb, dest_type_node, scope); 7073 if (dest_type == irb->codegen->invalid_inst_src) 7074 return dest_type; 7075 7076 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, dest_type, result_loc); 7077 7078 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7079 IrInstSrc *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, 7080 &result_loc_cast->base); 7081 if (arg1_value == irb->codegen->invalid_inst_src) 7082 return arg1_value; 7083 7084 IrInstSrc *result = ir_build_implicit_cast(irb, scope, node, arg1_value, result_loc_cast); 7085 return ir_lval_wrap(irb, scope, result, lval, result_loc); 7086 } 7087 case BuiltinFnIdIntToPtr: 7088 { 7089 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7090 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7091 if (arg0_value == irb->codegen->invalid_inst_src) 7092 return arg0_value; 7093 7094 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7095 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7096 if (arg1_value == irb->codegen->invalid_inst_src) 7097 return arg1_value; 7098 7099 IrInstSrc *int_to_ptr = ir_build_int_to_ptr_src(irb, scope, node, arg0_value, arg1_value); 7100 return ir_lval_wrap(irb, scope, int_to_ptr, lval, result_loc); 7101 } 7102 case BuiltinFnIdPtrToInt: 7103 { 7104 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7105 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7106 if (arg0_value == irb->codegen->invalid_inst_src) 7107 return arg0_value; 7108 7109 IrInstSrc *ptr_to_int = ir_build_ptr_to_int_src(irb, scope, node, arg0_value); 7110 return ir_lval_wrap(irb, scope, ptr_to_int, lval, result_loc); 7111 } 7112 case BuiltinFnIdTagName: 7113 { 7114 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7115 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7116 if (arg0_value == irb->codegen->invalid_inst_src) 7117 return arg0_value; 7118 7119 IrInstSrc *tag_name = ir_build_tag_name_src(irb, scope, node, arg0_value); 7120 return ir_lval_wrap(irb, scope, tag_name, lval, result_loc); 7121 } 7122 case BuiltinFnIdTagType: 7123 { 7124 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7125 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7126 if (arg0_value == irb->codegen->invalid_inst_src) 7127 return arg0_value; 7128 7129 IrInstSrc *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); 7130 return ir_lval_wrap(irb, scope, tag_type, lval, result_loc); 7131 } 7132 case BuiltinFnIdFieldParentPtr: 7133 { 7134 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7135 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7136 if (arg0_value == irb->codegen->invalid_inst_src) 7137 return arg0_value; 7138 7139 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7140 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7141 if (arg1_value == irb->codegen->invalid_inst_src) 7142 return arg1_value; 7143 7144 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 7145 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 7146 if (arg2_value == irb->codegen->invalid_inst_src) 7147 return arg2_value; 7148 7149 IrInstSrc *field_parent_ptr = ir_build_field_parent_ptr_src(irb, scope, node, 7150 arg0_value, arg1_value, arg2_value); 7151 return ir_lval_wrap(irb, scope, field_parent_ptr, lval, result_loc); 7152 } 7153 case BuiltinFnIdByteOffsetOf: 7154 { 7155 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7156 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7157 if (arg0_value == irb->codegen->invalid_inst_src) 7158 return arg0_value; 7159 7160 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7161 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7162 if (arg1_value == irb->codegen->invalid_inst_src) 7163 return arg1_value; 7164 7165 IrInstSrc *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value); 7166 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); 7167 } 7168 case BuiltinFnIdBitOffsetOf: 7169 { 7170 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7171 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7172 if (arg0_value == irb->codegen->invalid_inst_src) 7173 return arg0_value; 7174 7175 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7176 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7177 if (arg1_value == irb->codegen->invalid_inst_src) 7178 return arg1_value; 7179 7180 IrInstSrc *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); 7181 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); 7182 } 7183 case BuiltinFnIdCall: { 7184 // Cast the options parameter to the options type 7185 ZigType *options_type = get_builtin_type(irb->codegen, "CallOptions"); 7186 IrInstSrc *options_type_inst = ir_build_const_type(irb, scope, node, options_type); 7187 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, options_type_inst, no_result_loc()); 7188 7189 AstNode *options_node = node->data.fn_call_expr.params.at(0); 7190 IrInstSrc *options_inner = ir_gen_node_extra(irb, options_node, scope, 7191 LValNone, &result_loc_cast->base); 7192 if (options_inner == irb->codegen->invalid_inst_src) 7193 return options_inner; 7194 IrInstSrc *options = ir_build_implicit_cast(irb, scope, options_node, options_inner, result_loc_cast); 7195 7196 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); 7197 AstNode *args_node = node->data.fn_call_expr.params.at(2); 7198 if (args_node->type == NodeTypeContainerInitExpr) { 7199 if (args_node->data.container_init_expr.kind == ContainerInitKindArray || 7200 args_node->data.container_init_expr.entries.length == 0) 7201 { 7202 return ir_gen_fn_call_with_args(irb, scope, node, 7203 fn_ref_node, CallModifierNone, options, 7204 args_node->data.container_init_expr.entries.items, 7205 args_node->data.container_init_expr.entries.length, 7206 lval, result_loc); 7207 } else { 7208 exec_add_error_node(irb->codegen, irb->exec, args_node, 7209 buf_sprintf("TODO: @call with anon struct literal")); 7210 return irb->codegen->invalid_inst_src; 7211 } 7212 } else { 7213 IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 7214 if (fn_ref == irb->codegen->invalid_inst_src) 7215 return fn_ref; 7216 7217 IrInstSrc *args = ir_gen_node(irb, args_node, scope); 7218 if (args == irb->codegen->invalid_inst_src) 7219 return args; 7220 7221 IrInstSrc *call = ir_build_call_extra(irb, scope, node, options, fn_ref, args, result_loc); 7222 return ir_lval_wrap(irb, scope, call, lval, result_loc); 7223 } 7224 } 7225 case BuiltinFnIdAsyncCall: 7226 return ir_gen_async_call(irb, scope, nullptr, node, lval, result_loc); 7227 case BuiltinFnIdShlExact: 7228 { 7229 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7230 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7231 if (arg0_value == irb->codegen->invalid_inst_src) 7232 return arg0_value; 7233 7234 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7235 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7236 if (arg1_value == irb->codegen->invalid_inst_src) 7237 return arg1_value; 7238 7239 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); 7240 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 7241 } 7242 case BuiltinFnIdShrExact: 7243 { 7244 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7245 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7246 if (arg0_value == irb->codegen->invalid_inst_src) 7247 return arg0_value; 7248 7249 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7250 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7251 if (arg1_value == irb->codegen->invalid_inst_src) 7252 return arg1_value; 7253 7254 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); 7255 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 7256 } 7257 case BuiltinFnIdSetEvalBranchQuota: 7258 { 7259 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7260 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7261 if (arg0_value == irb->codegen->invalid_inst_src) 7262 return arg0_value; 7263 7264 IrInstSrc *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); 7265 return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval, result_loc); 7266 } 7267 case BuiltinFnIdAlignCast: 7268 { 7269 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7270 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7271 if (arg0_value == irb->codegen->invalid_inst_src) 7272 return arg0_value; 7273 7274 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7275 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7276 if (arg1_value == irb->codegen->invalid_inst_src) 7277 return arg1_value; 7278 7279 IrInstSrc *align_cast = ir_build_align_cast_src(irb, scope, node, arg0_value, arg1_value); 7280 return ir_lval_wrap(irb, scope, align_cast, lval, result_loc); 7281 } 7282 case BuiltinFnIdOpaqueType: 7283 { 7284 IrInstSrc *opaque_type = ir_build_opaque_type(irb, scope, node); 7285 return ir_lval_wrap(irb, scope, opaque_type, lval, result_loc); 7286 } 7287 case BuiltinFnIdThis: 7288 { 7289 IrInstSrc *this_inst = ir_gen_this(irb, scope, node); 7290 return ir_lval_wrap(irb, scope, this_inst, lval, result_loc); 7291 } 7292 case BuiltinFnIdSetAlignStack: 7293 { 7294 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7295 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7296 if (arg0_value == irb->codegen->invalid_inst_src) 7297 return arg0_value; 7298 7299 IrInstSrc *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); 7300 return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc); 7301 } 7302 case BuiltinFnIdExport: 7303 { 7304 // Cast the options parameter to the options type 7305 ZigType *options_type = get_builtin_type(irb->codegen, "ExportOptions"); 7306 IrInstSrc *options_type_inst = ir_build_const_type(irb, scope, node, options_type); 7307 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, options_type_inst, no_result_loc()); 7308 7309 AstNode *target_node = node->data.fn_call_expr.params.at(0); 7310 IrInstSrc *target_value = ir_gen_node(irb, target_node, scope); 7311 if (target_value == irb->codegen->invalid_inst_src) 7312 return target_value; 7313 7314 AstNode *options_node = node->data.fn_call_expr.params.at(1); 7315 IrInstSrc *options_value = ir_gen_node_extra(irb, options_node, 7316 scope, LValNone, &result_loc_cast->base); 7317 if (options_value == irb->codegen->invalid_inst_src) 7318 return options_value; 7319 7320 IrInstSrc *casted_options_value = ir_build_implicit_cast( 7321 irb, scope, options_node, options_value, result_loc_cast); 7322 7323 IrInstSrc *ir_export = ir_build_export(irb, scope, node, target_value, casted_options_value); 7324 return ir_lval_wrap(irb, scope, ir_export, lval, result_loc); 7325 } 7326 case BuiltinFnIdErrorReturnTrace: 7327 { 7328 IrInstSrc *error_return_trace = ir_build_error_return_trace_src(irb, scope, node, 7329 IrInstErrorReturnTraceNull); 7330 return ir_lval_wrap(irb, scope, error_return_trace, lval, result_loc); 7331 } 7332 case BuiltinFnIdAtomicRmw: 7333 { 7334 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7335 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7336 if (arg0_value == irb->codegen->invalid_inst_src) 7337 return arg0_value; 7338 7339 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7340 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7341 if (arg1_value == irb->codegen->invalid_inst_src) 7342 return arg1_value; 7343 7344 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 7345 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 7346 if (arg2_value == irb->codegen->invalid_inst_src) 7347 return arg2_value; 7348 7349 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 7350 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); 7351 if (arg3_value == irb->codegen->invalid_inst_src) 7352 return arg3_value; 7353 7354 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 7355 IrInstSrc *arg4_value = ir_gen_node(irb, arg4_node, scope); 7356 if (arg4_value == irb->codegen->invalid_inst_src) 7357 return arg4_value; 7358 7359 IrInstSrc *inst = ir_build_atomic_rmw_src(irb, scope, node, 7360 arg0_value, arg1_value, arg2_value, arg3_value, arg4_value); 7361 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 7362 } 7363 case BuiltinFnIdAtomicLoad: 7364 { 7365 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7366 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7367 if (arg0_value == irb->codegen->invalid_inst_src) 7368 return arg0_value; 7369 7370 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7371 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7372 if (arg1_value == irb->codegen->invalid_inst_src) 7373 return arg1_value; 7374 7375 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 7376 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 7377 if (arg2_value == irb->codegen->invalid_inst_src) 7378 return arg2_value; 7379 7380 IrInstSrc *inst = ir_build_atomic_load_src(irb, scope, node, arg0_value, arg1_value, arg2_value); 7381 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 7382 } 7383 case BuiltinFnIdAtomicStore: 7384 { 7385 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7386 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7387 if (arg0_value == irb->codegen->invalid_inst_src) 7388 return arg0_value; 7389 7390 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7391 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7392 if (arg1_value == irb->codegen->invalid_inst_src) 7393 return arg1_value; 7394 7395 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 7396 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 7397 if (arg2_value == irb->codegen->invalid_inst_src) 7398 return arg2_value; 7399 7400 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 7401 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); 7402 if (arg3_value == irb->codegen->invalid_inst_src) 7403 return arg3_value; 7404 7405 IrInstSrc *inst = ir_build_atomic_store_src(irb, scope, node, arg0_value, arg1_value, 7406 arg2_value, arg3_value); 7407 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 7408 } 7409 case BuiltinFnIdIntToEnum: 7410 { 7411 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7412 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7413 if (arg0_value == irb->codegen->invalid_inst_src) 7414 return arg0_value; 7415 7416 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7417 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7418 if (arg1_value == irb->codegen->invalid_inst_src) 7419 return arg1_value; 7420 7421 IrInstSrc *result = ir_build_int_to_enum_src(irb, scope, node, arg0_value, arg1_value); 7422 return ir_lval_wrap(irb, scope, result, lval, result_loc); 7423 } 7424 case BuiltinFnIdEnumToInt: 7425 { 7426 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7427 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7428 if (arg0_value == irb->codegen->invalid_inst_src) 7429 return arg0_value; 7430 7431 IrInstSrc *result = ir_build_enum_to_int(irb, scope, node, arg0_value); 7432 return ir_lval_wrap(irb, scope, result, lval, result_loc); 7433 } 7434 case BuiltinFnIdCtz: 7435 case BuiltinFnIdPopCount: 7436 case BuiltinFnIdClz: 7437 case BuiltinFnIdBswap: 7438 case BuiltinFnIdBitReverse: 7439 { 7440 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7441 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7442 if (arg0_value == irb->codegen->invalid_inst_src) 7443 return arg0_value; 7444 7445 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7446 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7447 if (arg1_value == irb->codegen->invalid_inst_src) 7448 return arg1_value; 7449 7450 IrInstSrc *result; 7451 switch (builtin_fn->id) { 7452 case BuiltinFnIdCtz: 7453 result = ir_build_ctz(irb, scope, node, arg0_value, arg1_value); 7454 break; 7455 case BuiltinFnIdPopCount: 7456 result = ir_build_pop_count(irb, scope, node, arg0_value, arg1_value); 7457 break; 7458 case BuiltinFnIdClz: 7459 result = ir_build_clz(irb, scope, node, arg0_value, arg1_value); 7460 break; 7461 case BuiltinFnIdBswap: 7462 result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value); 7463 break; 7464 case BuiltinFnIdBitReverse: 7465 result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value); 7466 break; 7467 default: 7468 zig_unreachable(); 7469 } 7470 return ir_lval_wrap(irb, scope, result, lval, result_loc); 7471 } 7472 case BuiltinFnIdHasDecl: 7473 { 7474 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7475 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7476 if (arg0_value == irb->codegen->invalid_inst_src) 7477 return arg0_value; 7478 7479 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7480 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7481 if (arg1_value == irb->codegen->invalid_inst_src) 7482 return arg1_value; 7483 7484 IrInstSrc *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value); 7485 return ir_lval_wrap(irb, scope, has_decl, lval, result_loc); 7486 } 7487 case BuiltinFnIdUnionInit: 7488 { 7489 AstNode *union_type_node = node->data.fn_call_expr.params.at(0); 7490 IrInstSrc *union_type_inst = ir_gen_node(irb, union_type_node, scope); 7491 if (union_type_inst == irb->codegen->invalid_inst_src) 7492 return union_type_inst; 7493 7494 AstNode *name_node = node->data.fn_call_expr.params.at(1); 7495 IrInstSrc *name_inst = ir_gen_node(irb, name_node, scope); 7496 if (name_inst == irb->codegen->invalid_inst_src) 7497 return name_inst; 7498 7499 AstNode *init_node = node->data.fn_call_expr.params.at(2); 7500 7501 return ir_gen_union_init_expr(irb, scope, node, union_type_inst, name_inst, init_node, 7502 lval, result_loc); 7503 } 7504 case BuiltinFnIdSrc: 7505 { 7506 IrInstSrc *src_inst = ir_build_src(irb, scope, node); 7507 return ir_lval_wrap(irb, scope, src_inst, lval, result_loc); 7508 } 7509 } 7510 zig_unreachable(); 7511 } 7512 7513 static ScopeNoSuspend *get_scope_nosuspend(Scope *scope) { 7514 while (scope) { 7515 if (scope->id == ScopeIdNoSuspend) 7516 return (ScopeNoSuspend *)scope; 7517 if (scope->id == ScopeIdFnDef) 7518 return nullptr; 7519 7520 scope = scope->parent; 7521 } 7522 return nullptr; 7523 } 7524 7525 static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 7526 ResultLoc *result_loc) 7527 { 7528 assert(node->type == NodeTypeFnCallExpr); 7529 7530 if (node->data.fn_call_expr.modifier == CallModifierBuiltin) 7531 return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); 7532 7533 bool is_nosuspend = get_scope_nosuspend(scope) != nullptr; 7534 CallModifier modifier = node->data.fn_call_expr.modifier; 7535 if (is_nosuspend) { 7536 if (modifier == CallModifierAsync) { 7537 add_node_error(irb->codegen, node, 7538 buf_sprintf("async call in nosuspend scope")); 7539 return irb->codegen->invalid_inst_src; 7540 } 7541 modifier = CallModifierNoSuspend; 7542 } 7543 7544 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; 7545 return ir_gen_fn_call_with_args(irb, scope, node, fn_ref_node, modifier, 7546 nullptr, node->data.fn_call_expr.params.items, node->data.fn_call_expr.params.length, lval, result_loc); 7547 } 7548 7549 static IrInstSrc *ir_gen_if_bool_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 7550 ResultLoc *result_loc) 7551 { 7552 assert(node->type == NodeTypeIfBoolExpr); 7553 7554 IrInstSrc *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); 7555 if (condition == irb->codegen->invalid_inst_src) 7556 return irb->codegen->invalid_inst_src; 7557 7558 IrInstSrc *is_comptime; 7559 if (ir_should_inline(irb->exec, scope)) { 7560 is_comptime = ir_build_const_bool(irb, scope, node, true); 7561 } else { 7562 is_comptime = ir_build_test_comptime(irb, scope, node, condition); 7563 } 7564 7565 AstNode *then_node = node->data.if_bool_expr.then_block; 7566 AstNode *else_node = node->data.if_bool_expr.else_node; 7567 7568 IrBasicBlockSrc *then_block = ir_create_basic_block(irb, scope, "Then"); 7569 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "Else"); 7570 IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "EndIf"); 7571 7572 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, condition, 7573 then_block, else_block, is_comptime); 7574 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 7575 result_loc, is_comptime); 7576 7577 ir_set_cursor_at_end_and_append_block(irb, then_block); 7578 7579 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 7580 IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval, 7581 &peer_parent->peers.at(0)->base); 7582 if (then_expr_result == irb->codegen->invalid_inst_src) 7583 return irb->codegen->invalid_inst_src; 7584 IrBasicBlockSrc *after_then_block = irb->current_basic_block; 7585 if (!instr_is_unreachable(then_expr_result)) 7586 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 7587 7588 ir_set_cursor_at_end_and_append_block(irb, else_block); 7589 IrInstSrc *else_expr_result; 7590 if (else_node) { 7591 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); 7592 if (else_expr_result == irb->codegen->invalid_inst_src) 7593 return irb->codegen->invalid_inst_src; 7594 } else { 7595 else_expr_result = ir_build_const_void(irb, scope, node); 7596 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 7597 } 7598 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 7599 if (!instr_is_unreachable(else_expr_result)) 7600 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 7601 7602 ir_set_cursor_at_end_and_append_block(irb, endif_block); 7603 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 7604 incoming_values[0] = then_expr_result; 7605 incoming_values[1] = else_expr_result; 7606 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 7607 incoming_blocks[0] = after_then_block; 7608 incoming_blocks[1] = after_else_block; 7609 7610 IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 7611 return ir_expr_wrap(irb, scope, phi, result_loc); 7612 } 7613 7614 static IrInstSrc *ir_gen_prefix_op_id_lval(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { 7615 assert(node->type == NodeTypePrefixOpExpr); 7616 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 7617 7618 IrInstSrc *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); 7619 if (value == irb->codegen->invalid_inst_src) 7620 return value; 7621 7622 return ir_build_un_op(irb, scope, node, op_id, value); 7623 } 7624 7625 static IrInstSrc *ir_gen_prefix_op_id(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrUnOp op_id) { 7626 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone); 7627 } 7628 7629 static IrInstSrc *ir_expr_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *inst, ResultLoc *result_loc) { 7630 if (inst == irb->codegen->invalid_inst_src) return inst; 7631 ir_build_end_expr(irb, scope, inst->base.source_node, inst, result_loc); 7632 return inst; 7633 } 7634 7635 static IrInstSrc *ir_lval_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *value, LVal lval, 7636 ResultLoc *result_loc) 7637 { 7638 // This logic must be kept in sync with 7639 // [STMT_EXPR_TEST_THING] <--- (search this token) 7640 if (value == irb->codegen->invalid_inst_src || 7641 instr_is_unreachable(value) || 7642 value->base.source_node->type == NodeTypeDefer || 7643 value->id == IrInstSrcIdDeclVar) 7644 { 7645 return value; 7646 } 7647 7648 assert(lval != LValAssign); 7649 if (lval == LValPtr) { 7650 // We needed a pointer to a value, but we got a value. So we create 7651 // an instruction which just makes a pointer of it. 7652 return ir_build_ref_src(irb, scope, value->base.source_node, value); 7653 } else if (result_loc != nullptr) { 7654 return ir_expr_wrap(irb, scope, value, result_loc); 7655 } else { 7656 return value; 7657 } 7658 7659 } 7660 7661 static PtrLen star_token_to_ptr_len(TokenId token_id) { 7662 switch (token_id) { 7663 case TokenIdStar: 7664 case TokenIdStarStar: 7665 return PtrLenSingle; 7666 case TokenIdLBracket: 7667 return PtrLenUnknown; 7668 case TokenIdSymbol: 7669 return PtrLenC; 7670 default: 7671 zig_unreachable(); 7672 } 7673 } 7674 7675 static IrInstSrc *ir_gen_pointer_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 7676 assert(node->type == NodeTypePointerType); 7677 7678 PtrLen ptr_len = star_token_to_ptr_len(node->data.pointer_type.star_token->id); 7679 7680 bool is_const = node->data.pointer_type.is_const; 7681 bool is_volatile = node->data.pointer_type.is_volatile; 7682 bool is_allow_zero = node->data.pointer_type.allow_zero_token != nullptr; 7683 AstNode *sentinel_expr = node->data.pointer_type.sentinel; 7684 AstNode *expr_node = node->data.pointer_type.op_expr; 7685 AstNode *align_expr = node->data.pointer_type.align_expr; 7686 7687 IrInstSrc *sentinel; 7688 if (sentinel_expr != nullptr) { 7689 sentinel = ir_gen_node(irb, sentinel_expr, scope); 7690 if (sentinel == irb->codegen->invalid_inst_src) 7691 return sentinel; 7692 } else { 7693 sentinel = nullptr; 7694 } 7695 7696 IrInstSrc *align_value; 7697 if (align_expr != nullptr) { 7698 align_value = ir_gen_node(irb, align_expr, scope); 7699 if (align_value == irb->codegen->invalid_inst_src) 7700 return align_value; 7701 } else { 7702 align_value = nullptr; 7703 } 7704 7705 IrInstSrc *child_type = ir_gen_node(irb, expr_node, scope); 7706 if (child_type == irb->codegen->invalid_inst_src) 7707 return child_type; 7708 7709 uint32_t bit_offset_start = 0; 7710 if (node->data.pointer_type.bit_offset_start != nullptr) { 7711 if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_start, 32, false)) { 7712 Buf *val_buf = buf_alloc(); 7713 bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_start, 10); 7714 exec_add_error_node(irb->codegen, irb->exec, node, 7715 buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf))); 7716 return irb->codegen->invalid_inst_src; 7717 } 7718 bit_offset_start = bigint_as_u32(node->data.pointer_type.bit_offset_start); 7719 } 7720 7721 uint32_t host_int_bytes = 0; 7722 if (node->data.pointer_type.host_int_bytes != nullptr) { 7723 if (!bigint_fits_in_bits(node->data.pointer_type.host_int_bytes, 32, false)) { 7724 Buf *val_buf = buf_alloc(); 7725 bigint_append_buf(val_buf, node->data.pointer_type.host_int_bytes, 10); 7726 exec_add_error_node(irb->codegen, irb->exec, node, 7727 buf_sprintf("value %s too large for u32 byte count", buf_ptr(val_buf))); 7728 return irb->codegen->invalid_inst_src; 7729 } 7730 host_int_bytes = bigint_as_u32(node->data.pointer_type.host_int_bytes); 7731 } 7732 7733 if (host_int_bytes != 0 && bit_offset_start >= host_int_bytes * 8) { 7734 exec_add_error_node(irb->codegen, irb->exec, node, 7735 buf_sprintf("bit offset starts after end of host integer")); 7736 return irb->codegen->invalid_inst_src; 7737 } 7738 7739 return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile, 7740 ptr_len, sentinel, align_value, bit_offset_start, host_int_bytes, is_allow_zero); 7741 } 7742 7743 static IrInstSrc *ir_gen_catch_unreachable(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 7744 AstNode *expr_node, LVal lval, ResultLoc *result_loc) 7745 { 7746 IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 7747 if (err_union_ptr == irb->codegen->invalid_inst_src) 7748 return irb->codegen->invalid_inst_src; 7749 7750 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, scope, source_node, err_union_ptr, true, false); 7751 if (payload_ptr == irb->codegen->invalid_inst_src) 7752 return irb->codegen->invalid_inst_src; 7753 7754 if (lval == LValPtr) 7755 return payload_ptr; 7756 7757 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, source_node, payload_ptr); 7758 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 7759 } 7760 7761 static IrInstSrc *ir_gen_bool_not(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 7762 assert(node->type == NodeTypePrefixOpExpr); 7763 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 7764 7765 IrInstSrc *value = ir_gen_node(irb, expr_node, scope); 7766 if (value == irb->codegen->invalid_inst_src) 7767 return irb->codegen->invalid_inst_src; 7768 7769 return ir_build_bool_not(irb, scope, node, value); 7770 } 7771 7772 static IrInstSrc *ir_gen_prefix_op_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 7773 ResultLoc *result_loc) 7774 { 7775 assert(node->type == NodeTypePrefixOpExpr); 7776 7777 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; 7778 7779 switch (prefix_op) { 7780 case PrefixOpInvalid: 7781 zig_unreachable(); 7782 case PrefixOpBoolNot: 7783 return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval, result_loc); 7784 case PrefixOpBinNot: 7785 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval, result_loc); 7786 case PrefixOpNegation: 7787 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval, result_loc); 7788 case PrefixOpNegationWrap: 7789 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval, result_loc); 7790 case PrefixOpOptional: 7791 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval, result_loc); 7792 case PrefixOpAddrOf: { 7793 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 7794 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr), lval, result_loc); 7795 } 7796 } 7797 zig_unreachable(); 7798 } 7799 7800 static IrInstSrc *ir_gen_union_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 7801 IrInstSrc *union_type, IrInstSrc *field_name, AstNode *expr_node, 7802 LVal lval, ResultLoc *parent_result_loc) 7803 { 7804 IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, source_node, parent_result_loc, union_type); 7805 IrInstSrc *field_ptr = ir_build_field_ptr_instruction(irb, scope, source_node, container_ptr, 7806 field_name, true); 7807 7808 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>(); 7809 result_loc_inst->base.id = ResultLocIdInstruction; 7810 result_loc_inst->base.source_instruction = field_ptr; 7811 ir_ref_instruction(field_ptr, irb->current_basic_block); 7812 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 7813 7814 IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 7815 &result_loc_inst->base); 7816 if (expr_value == irb->codegen->invalid_inst_src) 7817 return expr_value; 7818 7819 IrInstSrc *init_union = ir_build_union_init_named_field(irb, scope, source_node, union_type, 7820 field_name, field_ptr, container_ptr); 7821 7822 return ir_lval_wrap(irb, scope, init_union, lval, parent_result_loc); 7823 } 7824 7825 static IrInstSrc *ir_gen_container_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 7826 ResultLoc *parent_result_loc) 7827 { 7828 assert(node->type == NodeTypeContainerInitExpr); 7829 7830 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; 7831 ContainerInitKind kind = container_init_expr->kind; 7832 7833 ResultLocCast *result_loc_cast = nullptr; 7834 ResultLoc *child_result_loc; 7835 AstNode *init_array_type_source_node; 7836 if (container_init_expr->type != nullptr) { 7837 IrInstSrc *container_type; 7838 if (container_init_expr->type->type == NodeTypeInferredArrayType) { 7839 if (kind == ContainerInitKindStruct) { 7840 add_node_error(irb->codegen, container_init_expr->type, 7841 buf_sprintf("initializing array with struct syntax")); 7842 return irb->codegen->invalid_inst_src; 7843 } 7844 IrInstSrc *sentinel; 7845 if (container_init_expr->type->data.inferred_array_type.sentinel != nullptr) { 7846 sentinel = ir_gen_node(irb, container_init_expr->type->data.inferred_array_type.sentinel, scope); 7847 if (sentinel == irb->codegen->invalid_inst_src) 7848 return sentinel; 7849 } else { 7850 sentinel = nullptr; 7851 } 7852 7853 IrInstSrc *elem_type = ir_gen_node(irb, 7854 container_init_expr->type->data.inferred_array_type.child_type, scope); 7855 if (elem_type == irb->codegen->invalid_inst_src) 7856 return elem_type; 7857 size_t item_count = container_init_expr->entries.length; 7858 IrInstSrc *item_count_inst = ir_build_const_usize(irb, scope, node, item_count); 7859 container_type = ir_build_array_type(irb, scope, node, item_count_inst, sentinel, elem_type); 7860 } else { 7861 container_type = ir_gen_node(irb, container_init_expr->type, scope); 7862 if (container_type == irb->codegen->invalid_inst_src) 7863 return container_type; 7864 } 7865 7866 result_loc_cast = ir_build_cast_result_loc(irb, container_type, parent_result_loc); 7867 child_result_loc = &result_loc_cast->base; 7868 init_array_type_source_node = container_type->base.source_node; 7869 } else { 7870 child_result_loc = parent_result_loc; 7871 if (parent_result_loc->source_instruction != nullptr) { 7872 init_array_type_source_node = parent_result_loc->source_instruction->base.source_node; 7873 } else { 7874 init_array_type_source_node = node; 7875 } 7876 } 7877 7878 switch (kind) { 7879 case ContainerInitKindStruct: { 7880 IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc, 7881 nullptr); 7882 7883 size_t field_count = container_init_expr->entries.length; 7884 IrInstSrcContainerInitFieldsField *fields = heap::c_allocator.allocate<IrInstSrcContainerInitFieldsField>(field_count); 7885 for (size_t i = 0; i < field_count; i += 1) { 7886 AstNode *entry_node = container_init_expr->entries.at(i); 7887 assert(entry_node->type == NodeTypeStructValueField); 7888 7889 Buf *name = entry_node->data.struct_val_field.name; 7890 AstNode *expr_node = entry_node->data.struct_val_field.expr; 7891 7892 IrInstSrc *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true); 7893 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>(); 7894 result_loc_inst->base.id = ResultLocIdInstruction; 7895 result_loc_inst->base.source_instruction = field_ptr; 7896 result_loc_inst->base.allow_write_through_const = true; 7897 ir_ref_instruction(field_ptr, irb->current_basic_block); 7898 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 7899 7900 IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 7901 &result_loc_inst->base); 7902 if (expr_value == irb->codegen->invalid_inst_src) 7903 return expr_value; 7904 7905 fields[i].name = name; 7906 fields[i].source_node = entry_node; 7907 fields[i].result_loc = field_ptr; 7908 } 7909 IrInstSrc *result = ir_build_container_init_fields(irb, scope, node, field_count, 7910 fields, container_ptr); 7911 7912 if (result_loc_cast != nullptr) { 7913 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast); 7914 } 7915 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc); 7916 } 7917 case ContainerInitKindArray: { 7918 size_t item_count = container_init_expr->entries.length; 7919 7920 IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc, 7921 nullptr); 7922 7923 IrInstSrc **result_locs = heap::c_allocator.allocate<IrInstSrc *>(item_count); 7924 for (size_t i = 0; i < item_count; i += 1) { 7925 AstNode *expr_node = container_init_expr->entries.at(i); 7926 7927 IrInstSrc *elem_index = ir_build_const_usize(irb, scope, expr_node, i); 7928 IrInstSrc *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, 7929 elem_index, false, PtrLenSingle, init_array_type_source_node); 7930 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>(); 7931 result_loc_inst->base.id = ResultLocIdInstruction; 7932 result_loc_inst->base.source_instruction = elem_ptr; 7933 result_loc_inst->base.allow_write_through_const = true; 7934 ir_ref_instruction(elem_ptr, irb->current_basic_block); 7935 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 7936 7937 IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 7938 &result_loc_inst->base); 7939 if (expr_value == irb->codegen->invalid_inst_src) 7940 return expr_value; 7941 7942 result_locs[i] = elem_ptr; 7943 } 7944 IrInstSrc *result = ir_build_container_init_list(irb, scope, node, item_count, 7945 result_locs, container_ptr, init_array_type_source_node); 7946 if (result_loc_cast != nullptr) { 7947 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast); 7948 } 7949 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc); 7950 } 7951 } 7952 zig_unreachable(); 7953 } 7954 7955 static ResultLocVar *ir_build_var_result_loc(IrBuilderSrc *irb, IrInstSrc *alloca, ZigVar *var) { 7956 ResultLocVar *result_loc_var = heap::c_allocator.create<ResultLocVar>(); 7957 result_loc_var->base.id = ResultLocIdVar; 7958 result_loc_var->base.source_instruction = alloca; 7959 result_loc_var->base.allow_write_through_const = true; 7960 result_loc_var->var = var; 7961 7962 ir_build_reset_result(irb, alloca->base.scope, alloca->base.source_node, &result_loc_var->base); 7963 7964 return result_loc_var; 7965 } 7966 7967 static ResultLocCast *ir_build_cast_result_loc(IrBuilderSrc *irb, IrInstSrc *dest_type, 7968 ResultLoc *parent_result_loc) 7969 { 7970 ResultLocCast *result_loc_cast = heap::c_allocator.create<ResultLocCast>(); 7971 result_loc_cast->base.id = ResultLocIdCast; 7972 result_loc_cast->base.source_instruction = dest_type; 7973 result_loc_cast->base.allow_write_through_const = parent_result_loc->allow_write_through_const; 7974 ir_ref_instruction(dest_type, irb->current_basic_block); 7975 result_loc_cast->parent = parent_result_loc; 7976 7977 ir_build_reset_result(irb, dest_type->base.scope, dest_type->base.source_node, &result_loc_cast->base); 7978 7979 return result_loc_cast; 7980 } 7981 7982 static void build_decl_var_and_init(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var, 7983 IrInstSrc *init, const char *name_hint, IrInstSrc *is_comptime) 7984 { 7985 IrInstSrc *alloca = ir_build_alloca_src(irb, scope, source_node, nullptr, name_hint, is_comptime); 7986 ResultLocVar *var_result_loc = ir_build_var_result_loc(irb, alloca, var); 7987 ir_build_end_expr(irb, scope, source_node, init, &var_result_loc->base); 7988 ir_build_var_decl_src(irb, scope, source_node, var, nullptr, alloca); 7989 } 7990 7991 static IrInstSrc *ir_gen_var_decl(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 7992 assert(node->type == NodeTypeVariableDeclaration); 7993 7994 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; 7995 7996 if (buf_eql_str(variable_declaration->symbol, "_")) { 7997 add_node_error(irb->codegen, node, buf_sprintf("`_` is not a declarable symbol")); 7998 return irb->codegen->invalid_inst_src; 7999 } 8000 8001 // Used for the type expr and the align expr 8002 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 8003 8004 IrInstSrc *type_instruction; 8005 if (variable_declaration->type != nullptr) { 8006 type_instruction = ir_gen_node(irb, variable_declaration->type, comptime_scope); 8007 if (type_instruction == irb->codegen->invalid_inst_src) 8008 return type_instruction; 8009 } else { 8010 type_instruction = nullptr; 8011 } 8012 8013 bool is_shadowable = false; 8014 bool is_const = variable_declaration->is_const; 8015 bool is_extern = variable_declaration->is_extern; 8016 8017 bool is_comptime_scalar = ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime; 8018 IrInstSrc *is_comptime = ir_build_const_bool(irb, scope, node, is_comptime_scalar); 8019 ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, 8020 is_const, is_const, is_shadowable, is_comptime); 8021 // we detect IrInstSrcDeclVar in gen_block to make sure the next node 8022 // is inside var->child_scope 8023 8024 if (!is_extern && !variable_declaration->expr) { 8025 var->var_type = irb->codegen->builtin_types.entry_invalid; 8026 add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); 8027 return irb->codegen->invalid_inst_src; 8028 } 8029 8030 IrInstSrc *align_value = nullptr; 8031 if (variable_declaration->align_expr != nullptr) { 8032 align_value = ir_gen_node(irb, variable_declaration->align_expr, comptime_scope); 8033 if (align_value == irb->codegen->invalid_inst_src) 8034 return align_value; 8035 } 8036 8037 if (variable_declaration->section_expr != nullptr) { 8038 add_node_error(irb->codegen, variable_declaration->section_expr, 8039 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol))); 8040 } 8041 8042 // Parser should ensure that this never happens 8043 assert(variable_declaration->threadlocal_tok == nullptr); 8044 8045 IrInstSrc *alloca = ir_build_alloca_src(irb, scope, node, align_value, 8046 buf_ptr(variable_declaration->symbol), is_comptime); 8047 8048 // Create a result location for the initialization expression. 8049 ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var); 8050 ResultLoc *init_result_loc; 8051 ResultLocCast *result_loc_cast; 8052 if (type_instruction != nullptr) { 8053 result_loc_cast = ir_build_cast_result_loc(irb, type_instruction, &result_loc_var->base); 8054 init_result_loc = &result_loc_cast->base; 8055 } else { 8056 result_loc_cast = nullptr; 8057 init_result_loc = &result_loc_var->base; 8058 } 8059 8060 Scope *init_scope = is_comptime_scalar ? 8061 create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope; 8062 8063 // Temporarily set the name of the IrExecutableSrc to the VariableDeclaration 8064 // so that the struct or enum from the init expression inherits the name. 8065 Buf *old_exec_name = irb->exec->name; 8066 irb->exec->name = variable_declaration->symbol; 8067 IrInstSrc *init_value = ir_gen_node_extra(irb, variable_declaration->expr, init_scope, 8068 LValNone, init_result_loc); 8069 irb->exec->name = old_exec_name; 8070 8071 if (init_value == irb->codegen->invalid_inst_src) 8072 return irb->codegen->invalid_inst_src; 8073 8074 if (result_loc_cast != nullptr) { 8075 IrInstSrc *implicit_cast = ir_build_implicit_cast(irb, scope, init_value->base.source_node, 8076 init_value, result_loc_cast); 8077 ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base); 8078 } 8079 8080 return ir_build_var_decl_src(irb, scope, node, var, align_value, alloca); 8081 } 8082 8083 static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 8084 ResultLoc *result_loc) 8085 { 8086 assert(node->type == NodeTypeWhileExpr); 8087 8088 AstNode *continue_expr_node = node->data.while_expr.continue_expr; 8089 AstNode *else_node = node->data.while_expr.else_node; 8090 8091 IrBasicBlockSrc *cond_block = ir_create_basic_block(irb, scope, "WhileCond"); 8092 IrBasicBlockSrc *body_block = ir_create_basic_block(irb, scope, "WhileBody"); 8093 IrBasicBlockSrc *continue_block = continue_expr_node ? 8094 ir_create_basic_block(irb, scope, "WhileContinue") : cond_block; 8095 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, scope, "WhileEnd"); 8096 IrBasicBlockSrc *else_block = else_node ? 8097 ir_create_basic_block(irb, scope, "WhileElse") : end_block; 8098 8099 IrInstSrc *is_comptime = ir_build_const_bool(irb, scope, node, 8100 ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline); 8101 ir_build_br(irb, scope, node, cond_block, is_comptime); 8102 8103 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 8104 Buf *var_symbol = node->data.while_expr.var_symbol; 8105 Buf *err_symbol = node->data.while_expr.err_symbol; 8106 if (err_symbol != nullptr) { 8107 ir_set_cursor_at_end_and_append_block(irb, cond_block); 8108 8109 Scope *payload_scope; 8110 AstNode *symbol_node = node; // TODO make more accurate 8111 ZigVar *payload_var; 8112 if (var_symbol) { 8113 // TODO make it an error to write to payload variable 8114 payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 8115 true, false, false, is_comptime); 8116 payload_scope = payload_var->child_scope; 8117 } else { 8118 payload_scope = subexpr_scope; 8119 } 8120 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, payload_scope); 8121 IrInstSrc *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, 8122 LValPtr, nullptr); 8123 if (err_val_ptr == irb->codegen->invalid_inst_src) 8124 return err_val_ptr; 8125 IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr, 8126 true, false); 8127 IrBasicBlockSrc *after_cond_block = irb->current_basic_block; 8128 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 8129 IrInstSrc *cond_br_inst; 8130 if (!instr_is_unreachable(is_err)) { 8131 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, 8132 else_block, body_block, is_comptime); 8133 cond_br_inst->is_gen = true; 8134 } else { 8135 // for the purposes of the source instruction to ir_build_result_peers 8136 cond_br_inst = irb->current_basic_block->instruction_list.last(); 8137 } 8138 8139 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 8140 is_comptime); 8141 8142 ir_set_cursor_at_end_and_append_block(irb, body_block); 8143 if (var_symbol) { 8144 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, &spill_scope->base, symbol_node, 8145 err_val_ptr, false, false); 8146 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ? 8147 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, symbol_node, payload_ptr); 8148 build_decl_var_and_init(irb, payload_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime); 8149 } 8150 8151 ZigList<IrInstSrc *> incoming_values = {0}; 8152 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 8153 8154 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope); 8155 loop_scope->break_block = end_block; 8156 loop_scope->continue_block = continue_block; 8157 loop_scope->is_comptime = is_comptime; 8158 loop_scope->incoming_blocks = &incoming_blocks; 8159 loop_scope->incoming_values = &incoming_values; 8160 loop_scope->lval = lval; 8161 loop_scope->peer_parent = peer_parent; 8162 loop_scope->spill_scope = spill_scope; 8163 8164 // Note the body block of the loop is not the place that lval and result_loc are used - 8165 // it's actually in break statements, handled similarly to return statements. 8166 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 8167 IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 8168 if (body_result == irb->codegen->invalid_inst_src) 8169 return body_result; 8170 8171 if (!instr_is_unreachable(body_result)) { 8172 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result)); 8173 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime)); 8174 } 8175 8176 if (continue_expr_node) { 8177 ir_set_cursor_at_end_and_append_block(irb, continue_block); 8178 IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, payload_scope); 8179 if (expr_result == irb->codegen->invalid_inst_src) 8180 return expr_result; 8181 if (!instr_is_unreachable(expr_result)) { 8182 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, continue_expr_node, expr_result)); 8183 ir_mark_gen(ir_build_br(irb, payload_scope, node, cond_block, is_comptime)); 8184 } 8185 } 8186 8187 ir_set_cursor_at_end_and_append_block(irb, else_block); 8188 assert(else_node != nullptr); 8189 8190 // TODO make it an error to write to error variable 8191 AstNode *err_symbol_node = else_node; // TODO make more accurate 8192 ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol, 8193 true, false, false, is_comptime); 8194 Scope *err_scope = err_var->child_scope; 8195 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, err_symbol_node, err_val_ptr); 8196 IrInstSrc *err_value = ir_build_load_ptr(irb, err_scope, err_symbol_node, err_ptr); 8197 build_decl_var_and_init(irb, err_scope, err_symbol_node, err_var, err_value, buf_ptr(err_symbol), is_comptime); 8198 8199 if (peer_parent->peers.length != 0) { 8200 peer_parent->peers.last()->next_bb = else_block; 8201 } 8202 ResultLocPeer *peer_result = create_peer_result(peer_parent); 8203 peer_parent->peers.append(peer_result); 8204 IrInstSrc *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_result->base); 8205 if (else_result == irb->codegen->invalid_inst_src) 8206 return else_result; 8207 if (!instr_is_unreachable(else_result)) 8208 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 8209 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8210 ir_set_cursor_at_end_and_append_block(irb, end_block); 8211 if (else_result) { 8212 incoming_blocks.append(after_else_block); 8213 incoming_values.append(else_result); 8214 } else { 8215 incoming_blocks.append(after_cond_block); 8216 incoming_values.append(void_else_result); 8217 } 8218 if (peer_parent->peers.length != 0) { 8219 peer_parent->peers.last()->next_bb = end_block; 8220 } 8221 8222 IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 8223 incoming_blocks.items, incoming_values.items, peer_parent); 8224 return ir_expr_wrap(irb, scope, phi, result_loc); 8225 } else if (var_symbol != nullptr) { 8226 ir_set_cursor_at_end_and_append_block(irb, cond_block); 8227 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 8228 // TODO make it an error to write to payload variable 8229 AstNode *symbol_node = node; // TODO make more accurate 8230 8231 ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 8232 true, false, false, is_comptime); 8233 Scope *child_scope = payload_var->child_scope; 8234 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, child_scope); 8235 IrInstSrc *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, 8236 LValPtr, nullptr); 8237 if (maybe_val_ptr == irb->codegen->invalid_inst_src) 8238 return maybe_val_ptr; 8239 IrInstSrc *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); 8240 IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, scope, node->data.while_expr.condition, maybe_val); 8241 IrBasicBlockSrc *after_cond_block = irb->current_basic_block; 8242 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 8243 IrInstSrc *cond_br_inst; 8244 if (!instr_is_unreachable(is_non_null)) { 8245 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, 8246 body_block, else_block, is_comptime); 8247 cond_br_inst->is_gen = true; 8248 } else { 8249 // for the purposes of the source instruction to ir_build_result_peers 8250 cond_br_inst = irb->current_basic_block->instruction_list.last(); 8251 } 8252 8253 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 8254 is_comptime); 8255 8256 ir_set_cursor_at_end_and_append_block(irb, body_block); 8257 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, &spill_scope->base, symbol_node, maybe_val_ptr, false); 8258 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ? 8259 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, symbol_node, payload_ptr); 8260 build_decl_var_and_init(irb, child_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime); 8261 8262 ZigList<IrInstSrc *> incoming_values = {0}; 8263 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 8264 8265 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 8266 loop_scope->break_block = end_block; 8267 loop_scope->continue_block = continue_block; 8268 loop_scope->is_comptime = is_comptime; 8269 loop_scope->incoming_blocks = &incoming_blocks; 8270 loop_scope->incoming_values = &incoming_values; 8271 loop_scope->lval = lval; 8272 loop_scope->peer_parent = peer_parent; 8273 loop_scope->spill_scope = spill_scope; 8274 8275 // Note the body block of the loop is not the place that lval and result_loc are used - 8276 // it's actually in break statements, handled similarly to return statements. 8277 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 8278 IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 8279 if (body_result == irb->codegen->invalid_inst_src) 8280 return body_result; 8281 8282 if (!instr_is_unreachable(body_result)) { 8283 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result)); 8284 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 8285 } 8286 8287 if (continue_expr_node) { 8288 ir_set_cursor_at_end_and_append_block(irb, continue_block); 8289 IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, child_scope); 8290 if (expr_result == irb->codegen->invalid_inst_src) 8291 return expr_result; 8292 if (!instr_is_unreachable(expr_result)) { 8293 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, continue_expr_node, expr_result)); 8294 ir_mark_gen(ir_build_br(irb, child_scope, node, cond_block, is_comptime)); 8295 } 8296 } 8297 8298 IrInstSrc *else_result = nullptr; 8299 if (else_node) { 8300 ir_set_cursor_at_end_and_append_block(irb, else_block); 8301 8302 if (peer_parent->peers.length != 0) { 8303 peer_parent->peers.last()->next_bb = else_block; 8304 } 8305 ResultLocPeer *peer_result = create_peer_result(peer_parent); 8306 peer_parent->peers.append(peer_result); 8307 else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_result->base); 8308 if (else_result == irb->codegen->invalid_inst_src) 8309 return else_result; 8310 if (!instr_is_unreachable(else_result)) 8311 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 8312 } 8313 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8314 ir_set_cursor_at_end_and_append_block(irb, end_block); 8315 if (else_result) { 8316 incoming_blocks.append(after_else_block); 8317 incoming_values.append(else_result); 8318 } else { 8319 incoming_blocks.append(after_cond_block); 8320 incoming_values.append(void_else_result); 8321 } 8322 if (peer_parent->peers.length != 0) { 8323 peer_parent->peers.last()->next_bb = end_block; 8324 } 8325 8326 IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 8327 incoming_blocks.items, incoming_values.items, peer_parent); 8328 return ir_expr_wrap(irb, scope, phi, result_loc); 8329 } else { 8330 ir_set_cursor_at_end_and_append_block(irb, cond_block); 8331 IrInstSrc *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); 8332 if (cond_val == irb->codegen->invalid_inst_src) 8333 return cond_val; 8334 IrBasicBlockSrc *after_cond_block = irb->current_basic_block; 8335 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 8336 IrInstSrc *cond_br_inst; 8337 if (!instr_is_unreachable(cond_val)) { 8338 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, 8339 body_block, else_block, is_comptime); 8340 cond_br_inst->is_gen = true; 8341 } else { 8342 // for the purposes of the source instruction to ir_build_result_peers 8343 cond_br_inst = irb->current_basic_block->instruction_list.last(); 8344 } 8345 8346 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 8347 is_comptime); 8348 ir_set_cursor_at_end_and_append_block(irb, body_block); 8349 8350 ZigList<IrInstSrc *> incoming_values = {0}; 8351 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 8352 8353 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 8354 8355 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope); 8356 loop_scope->break_block = end_block; 8357 loop_scope->continue_block = continue_block; 8358 loop_scope->is_comptime = is_comptime; 8359 loop_scope->incoming_blocks = &incoming_blocks; 8360 loop_scope->incoming_values = &incoming_values; 8361 loop_scope->lval = lval; 8362 loop_scope->peer_parent = peer_parent; 8363 8364 // Note the body block of the loop is not the place that lval and result_loc are used - 8365 // it's actually in break statements, handled similarly to return statements. 8366 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 8367 IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 8368 if (body_result == irb->codegen->invalid_inst_src) 8369 return body_result; 8370 8371 if (!instr_is_unreachable(body_result)) { 8372 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result)); 8373 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime)); 8374 } 8375 8376 if (continue_expr_node) { 8377 ir_set_cursor_at_end_and_append_block(irb, continue_block); 8378 IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, subexpr_scope); 8379 if (expr_result == irb->codegen->invalid_inst_src) 8380 return expr_result; 8381 if (!instr_is_unreachable(expr_result)) { 8382 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, continue_expr_node, expr_result)); 8383 ir_mark_gen(ir_build_br(irb, scope, node, cond_block, is_comptime)); 8384 } 8385 } 8386 8387 IrInstSrc *else_result = nullptr; 8388 if (else_node) { 8389 ir_set_cursor_at_end_and_append_block(irb, else_block); 8390 8391 if (peer_parent->peers.length != 0) { 8392 peer_parent->peers.last()->next_bb = else_block; 8393 } 8394 ResultLocPeer *peer_result = create_peer_result(peer_parent); 8395 peer_parent->peers.append(peer_result); 8396 8397 else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_result->base); 8398 if (else_result == irb->codegen->invalid_inst_src) 8399 return else_result; 8400 if (!instr_is_unreachable(else_result)) 8401 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 8402 } 8403 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8404 ir_set_cursor_at_end_and_append_block(irb, end_block); 8405 if (else_result) { 8406 incoming_blocks.append(after_else_block); 8407 incoming_values.append(else_result); 8408 } else { 8409 incoming_blocks.append(after_cond_block); 8410 incoming_values.append(void_else_result); 8411 } 8412 if (peer_parent->peers.length != 0) { 8413 peer_parent->peers.last()->next_bb = end_block; 8414 } 8415 8416 IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 8417 incoming_blocks.items, incoming_values.items, peer_parent); 8418 return ir_expr_wrap(irb, scope, phi, result_loc); 8419 } 8420 } 8421 8422 static IrInstSrc *ir_gen_for_expr(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval, 8423 ResultLoc *result_loc) 8424 { 8425 assert(node->type == NodeTypeForExpr); 8426 8427 AstNode *array_node = node->data.for_expr.array_expr; 8428 AstNode *elem_node = node->data.for_expr.elem_node; 8429 AstNode *index_node = node->data.for_expr.index_node; 8430 AstNode *body_node = node->data.for_expr.body; 8431 AstNode *else_node = node->data.for_expr.else_node; 8432 8433 if (!elem_node) { 8434 add_node_error(irb->codegen, node, buf_sprintf("for loop expression missing element parameter")); 8435 return irb->codegen->invalid_inst_src; 8436 } 8437 assert(elem_node->type == NodeTypeSymbol); 8438 8439 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, parent_scope); 8440 8441 IrInstSrc *array_val_ptr = ir_gen_node_extra(irb, array_node, &spill_scope->base, LValPtr, nullptr); 8442 if (array_val_ptr == irb->codegen->invalid_inst_src) 8443 return array_val_ptr; 8444 8445 IrInstSrc *is_comptime = ir_build_const_bool(irb, parent_scope, node, 8446 ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); 8447 8448 AstNode *index_var_source_node; 8449 ZigVar *index_var; 8450 const char *index_var_name; 8451 if (index_node) { 8452 index_var_source_node = index_node; 8453 Buf *index_var_name_buf = index_node->data.symbol_expr.symbol; 8454 index_var = ir_create_var(irb, index_node, parent_scope, index_var_name_buf, true, false, false, is_comptime); 8455 index_var_name = buf_ptr(index_var_name_buf); 8456 } else { 8457 index_var_source_node = node; 8458 index_var = ir_create_var(irb, node, parent_scope, nullptr, true, false, true, is_comptime); 8459 index_var_name = "i"; 8460 } 8461 8462 IrInstSrc *zero = ir_build_const_usize(irb, parent_scope, node, 0); 8463 build_decl_var_and_init(irb, parent_scope, index_var_source_node, index_var, zero, index_var_name, is_comptime); 8464 parent_scope = index_var->child_scope; 8465 8466 IrInstSrc *one = ir_build_const_usize(irb, parent_scope, node, 1); 8467 IrInstSrc *index_ptr = ir_build_var_ptr(irb, parent_scope, node, index_var); 8468 8469 8470 IrBasicBlockSrc *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond"); 8471 IrBasicBlockSrc *body_block = ir_create_basic_block(irb, parent_scope, "ForBody"); 8472 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd"); 8473 IrBasicBlockSrc *else_block = else_node ? ir_create_basic_block(irb, parent_scope, "ForElse") : end_block; 8474 IrBasicBlockSrc *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue"); 8475 8476 Buf *len_field_name = buf_create_from_str("len"); 8477 IrInstSrc *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name, false); 8478 IrInstSrc *len_val = ir_build_load_ptr(irb, &spill_scope->base, node, len_ref); 8479 ir_build_br(irb, parent_scope, node, cond_block, is_comptime); 8480 8481 ir_set_cursor_at_end_and_append_block(irb, cond_block); 8482 IrInstSrc *index_val = ir_build_load_ptr(irb, &spill_scope->base, node, index_ptr); 8483 IrInstSrc *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); 8484 IrBasicBlockSrc *after_cond_block = irb->current_basic_block; 8485 IrInstSrc *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); 8486 IrInstSrc *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, 8487 body_block, else_block, is_comptime)); 8488 8489 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, is_comptime); 8490 8491 ir_set_cursor_at_end_and_append_block(irb, body_block); 8492 IrInstSrc *elem_ptr = ir_build_elem_ptr(irb, &spill_scope->base, node, array_val_ptr, index_val, 8493 false, PtrLenSingle, nullptr); 8494 // TODO make it an error to write to element variable or i variable. 8495 Buf *elem_var_name = elem_node->data.symbol_expr.symbol; 8496 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); 8497 Scope *child_scope = elem_var->child_scope; 8498 8499 IrInstSrc *elem_value = node->data.for_expr.elem_is_ptr ? 8500 elem_ptr : ir_build_load_ptr(irb, &spill_scope->base, elem_node, elem_ptr); 8501 build_decl_var_and_init(irb, parent_scope, elem_node, elem_var, elem_value, buf_ptr(elem_var_name), is_comptime); 8502 8503 ZigList<IrInstSrc *> incoming_values = {0}; 8504 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 8505 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 8506 loop_scope->break_block = end_block; 8507 loop_scope->continue_block = continue_block; 8508 loop_scope->is_comptime = is_comptime; 8509 loop_scope->incoming_blocks = &incoming_blocks; 8510 loop_scope->incoming_values = &incoming_values; 8511 loop_scope->lval = LValNone; 8512 loop_scope->peer_parent = peer_parent; 8513 loop_scope->spill_scope = spill_scope; 8514 8515 // Note the body block of the loop is not the place that lval and result_loc are used - 8516 // it's actually in break statements, handled similarly to return statements. 8517 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 8518 IrInstSrc *body_result = ir_gen_node(irb, body_node, &loop_scope->base); 8519 if (body_result == irb->codegen->invalid_inst_src) 8520 return irb->codegen->invalid_inst_src; 8521 8522 if (!instr_is_unreachable(body_result)) { 8523 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result)); 8524 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 8525 } 8526 8527 ir_set_cursor_at_end_and_append_block(irb, continue_block); 8528 IrInstSrc *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false); 8529 ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)->allow_write_through_const = true; 8530 ir_build_br(irb, child_scope, node, cond_block, is_comptime); 8531 8532 IrInstSrc *else_result = nullptr; 8533 if (else_node) { 8534 ir_set_cursor_at_end_and_append_block(irb, else_block); 8535 8536 if (peer_parent->peers.length != 0) { 8537 peer_parent->peers.last()->next_bb = else_block; 8538 } 8539 ResultLocPeer *peer_result = create_peer_result(peer_parent); 8540 peer_parent->peers.append(peer_result); 8541 else_result = ir_gen_node_extra(irb, else_node, parent_scope, LValNone, &peer_result->base); 8542 if (else_result == irb->codegen->invalid_inst_src) 8543 return else_result; 8544 if (!instr_is_unreachable(else_result)) 8545 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 8546 } 8547 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8548 ir_set_cursor_at_end_and_append_block(irb, end_block); 8549 8550 if (else_result) { 8551 incoming_blocks.append(after_else_block); 8552 incoming_values.append(else_result); 8553 } else { 8554 incoming_blocks.append(after_cond_block); 8555 incoming_values.append(void_else_value); 8556 } 8557 if (peer_parent->peers.length != 0) { 8558 peer_parent->peers.last()->next_bb = end_block; 8559 } 8560 8561 IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, 8562 incoming_blocks.items, incoming_values.items, peer_parent); 8563 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 8564 } 8565 8566 static IrInstSrc *ir_gen_bool_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8567 assert(node->type == NodeTypeBoolLiteral); 8568 return ir_build_const_bool(irb, scope, node, node->data.bool_literal.value); 8569 } 8570 8571 static IrInstSrc *ir_gen_enum_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8572 assert(node->type == NodeTypeEnumLiteral); 8573 Buf *name = &node->data.enum_literal.identifier->data.str_lit.str; 8574 return ir_build_const_enum_literal(irb, scope, node, name); 8575 } 8576 8577 static IrInstSrc *ir_gen_string_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8578 assert(node->type == NodeTypeStringLiteral); 8579 8580 return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf); 8581 } 8582 8583 static IrInstSrc *ir_gen_array_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8584 assert(node->type == NodeTypeArrayType); 8585 8586 AstNode *size_node = node->data.array_type.size; 8587 AstNode *child_type_node = node->data.array_type.child_type; 8588 bool is_const = node->data.array_type.is_const; 8589 bool is_volatile = node->data.array_type.is_volatile; 8590 bool is_allow_zero = node->data.array_type.allow_zero_token != nullptr; 8591 AstNode *sentinel_expr = node->data.array_type.sentinel; 8592 AstNode *align_expr = node->data.array_type.align_expr; 8593 8594 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 8595 8596 IrInstSrc *sentinel; 8597 if (sentinel_expr != nullptr) { 8598 sentinel = ir_gen_node(irb, sentinel_expr, comptime_scope); 8599 if (sentinel == irb->codegen->invalid_inst_src) 8600 return sentinel; 8601 } else { 8602 sentinel = nullptr; 8603 } 8604 8605 if (size_node) { 8606 if (is_const) { 8607 add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type")); 8608 return irb->codegen->invalid_inst_src; 8609 } 8610 if (is_volatile) { 8611 add_node_error(irb->codegen, node, buf_create_from_str("volatile qualifier invalid on array type")); 8612 return irb->codegen->invalid_inst_src; 8613 } 8614 if (is_allow_zero) { 8615 add_node_error(irb->codegen, node, buf_create_from_str("allowzero qualifier invalid on array type")); 8616 return irb->codegen->invalid_inst_src; 8617 } 8618 if (align_expr != nullptr) { 8619 add_node_error(irb->codegen, node, buf_create_from_str("align qualifier invalid on array type")); 8620 return irb->codegen->invalid_inst_src; 8621 } 8622 8623 IrInstSrc *size_value = ir_gen_node(irb, size_node, comptime_scope); 8624 if (size_value == irb->codegen->invalid_inst_src) 8625 return size_value; 8626 8627 IrInstSrc *child_type = ir_gen_node(irb, child_type_node, comptime_scope); 8628 if (child_type == irb->codegen->invalid_inst_src) 8629 return child_type; 8630 8631 return ir_build_array_type(irb, scope, node, size_value, sentinel, child_type); 8632 } else { 8633 IrInstSrc *align_value; 8634 if (align_expr != nullptr) { 8635 align_value = ir_gen_node(irb, align_expr, comptime_scope); 8636 if (align_value == irb->codegen->invalid_inst_src) 8637 return align_value; 8638 } else { 8639 align_value = nullptr; 8640 } 8641 8642 IrInstSrc *child_type = ir_gen_node(irb, child_type_node, comptime_scope); 8643 if (child_type == irb->codegen->invalid_inst_src) 8644 return child_type; 8645 8646 return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, sentinel, 8647 align_value, is_allow_zero); 8648 } 8649 } 8650 8651 static IrInstSrc *ir_gen_anyframe_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8652 assert(node->type == NodeTypeAnyFrameType); 8653 8654 AstNode *payload_type_node = node->data.anyframe_type.payload_type; 8655 IrInstSrc *payload_type_value = nullptr; 8656 8657 if (payload_type_node != nullptr) { 8658 payload_type_value = ir_gen_node(irb, payload_type_node, scope); 8659 if (payload_type_value == irb->codegen->invalid_inst_src) 8660 return payload_type_value; 8661 8662 } 8663 8664 return ir_build_anyframe_type(irb, scope, node, payload_type_value); 8665 } 8666 8667 static IrInstSrc *ir_gen_undefined_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8668 assert(node->type == NodeTypeUndefinedLiteral); 8669 return ir_build_const_undefined(irb, scope, node); 8670 } 8671 8672 static Error parse_asm_template(IrAnalyze *ira, AstNode *source_node, Buf *asm_template, 8673 ZigList<AsmToken> *tok_list) 8674 { 8675 // TODO Connect the errors in this function back up to the actual source location 8676 // rather than just the token. https://github.com/ziglang/zig/issues/2080 8677 enum State { 8678 StateStart, 8679 StatePercent, 8680 StateTemplate, 8681 StateVar, 8682 }; 8683 8684 assert(tok_list->length == 0); 8685 8686 AsmToken *cur_tok = nullptr; 8687 8688 enum State state = StateStart; 8689 8690 for (size_t i = 0; i < buf_len(asm_template); i += 1) { 8691 uint8_t c = *((uint8_t*)buf_ptr(asm_template) + i); 8692 switch (state) { 8693 case StateStart: 8694 if (c == '%') { 8695 tok_list->add_one(); 8696 cur_tok = &tok_list->last(); 8697 cur_tok->id = AsmTokenIdPercent; 8698 cur_tok->start = i; 8699 state = StatePercent; 8700 } else { 8701 tok_list->add_one(); 8702 cur_tok = &tok_list->last(); 8703 cur_tok->id = AsmTokenIdTemplate; 8704 cur_tok->start = i; 8705 state = StateTemplate; 8706 } 8707 break; 8708 case StatePercent: 8709 if (c == '%') { 8710 cur_tok->end = i; 8711 state = StateStart; 8712 } else if (c == '[') { 8713 cur_tok->id = AsmTokenIdVar; 8714 state = StateVar; 8715 } else if (c == '=') { 8716 cur_tok->id = AsmTokenIdUniqueId; 8717 cur_tok->end = i; 8718 state = StateStart; 8719 } else { 8720 add_node_error(ira->codegen, source_node, 8721 buf_create_from_str("expected a '%' or '['")); 8722 return ErrorSemanticAnalyzeFail; 8723 } 8724 break; 8725 case StateTemplate: 8726 if (c == '%') { 8727 cur_tok->end = i; 8728 i -= 1; 8729 cur_tok = nullptr; 8730 state = StateStart; 8731 } 8732 break; 8733 case StateVar: 8734 if (c == ']') { 8735 cur_tok->end = i; 8736 state = StateStart; 8737 } else if ((c >= 'a' && c <= 'z') || 8738 (c >= '0' && c <= '9') || 8739 (c == '_')) 8740 { 8741 // do nothing 8742 } else { 8743 add_node_error(ira->codegen, source_node, 8744 buf_sprintf("invalid substitution character: '%c'", c)); 8745 return ErrorSemanticAnalyzeFail; 8746 } 8747 break; 8748 } 8749 } 8750 8751 switch (state) { 8752 case StateStart: 8753 break; 8754 case StatePercent: 8755 case StateVar: 8756 add_node_error(ira->codegen, source_node, buf_sprintf("unexpected end of assembly template")); 8757 return ErrorSemanticAnalyzeFail; 8758 case StateTemplate: 8759 cur_tok->end = buf_len(asm_template); 8760 break; 8761 } 8762 return ErrorNone; 8763 } 8764 8765 static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_template) { 8766 const char *ptr = buf_ptr(src_template) + tok->start + 2; 8767 size_t len = tok->end - tok->start - 2; 8768 size_t result = 0; 8769 for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1, result += 1) { 8770 AsmOutput *asm_output = node->data.asm_expr.output_list.at(i); 8771 if (buf_eql_mem(asm_output->asm_symbolic_name, ptr, len)) { 8772 return result; 8773 } 8774 } 8775 for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1, result += 1) { 8776 AsmInput *asm_input = node->data.asm_expr.input_list.at(i); 8777 if (buf_eql_mem(asm_input->asm_symbolic_name, ptr, len)) { 8778 return result; 8779 } 8780 } 8781 return SIZE_MAX; 8782 } 8783 8784 static IrInstSrc *ir_gen_asm_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8785 assert(node->type == NodeTypeAsmExpr); 8786 AstNodeAsmExpr *asm_expr = &node->data.asm_expr; 8787 8788 IrInstSrc *asm_template = ir_gen_node(irb, asm_expr->asm_template, scope); 8789 if (asm_template == irb->codegen->invalid_inst_src) 8790 return irb->codegen->invalid_inst_src; 8791 8792 bool is_volatile = asm_expr->volatile_token != nullptr; 8793 bool in_fn_scope = (scope_fn_entry(scope) != nullptr); 8794 8795 if (!in_fn_scope) { 8796 if (is_volatile) { 8797 add_token_error(irb->codegen, node->owner, asm_expr->volatile_token, 8798 buf_sprintf("volatile is meaningless on global assembly")); 8799 return irb->codegen->invalid_inst_src; 8800 } 8801 8802 if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 || 8803 asm_expr->clobber_list.length != 0) 8804 { 8805 add_node_error(irb->codegen, node, 8806 buf_sprintf("global assembly cannot have inputs, outputs, or clobbers")); 8807 return irb->codegen->invalid_inst_src; 8808 } 8809 8810 return ir_build_asm_src(irb, scope, node, asm_template, nullptr, nullptr, 8811 nullptr, 0, is_volatile, true); 8812 } 8813 8814 IrInstSrc **input_list = heap::c_allocator.allocate<IrInstSrc *>(asm_expr->input_list.length); 8815 IrInstSrc **output_types = heap::c_allocator.allocate<IrInstSrc *>(asm_expr->output_list.length); 8816 ZigVar **output_vars = heap::c_allocator.allocate<ZigVar *>(asm_expr->output_list.length); 8817 size_t return_count = 0; 8818 if (!is_volatile && asm_expr->output_list.length == 0) { 8819 add_node_error(irb->codegen, node, 8820 buf_sprintf("assembly expression with no output must be marked volatile")); 8821 return irb->codegen->invalid_inst_src; 8822 } 8823 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 8824 AsmOutput *asm_output = asm_expr->output_list.at(i); 8825 if (asm_output->return_type) { 8826 return_count += 1; 8827 8828 IrInstSrc *return_type = ir_gen_node(irb, asm_output->return_type, scope); 8829 if (return_type == irb->codegen->invalid_inst_src) 8830 return irb->codegen->invalid_inst_src; 8831 if (return_count > 1) { 8832 add_node_error(irb->codegen, node, 8833 buf_sprintf("inline assembly allows up to one output value")); 8834 return irb->codegen->invalid_inst_src; 8835 } 8836 output_types[i] = return_type; 8837 } else { 8838 Buf *variable_name = asm_output->variable_name; 8839 // TODO there is some duplication here with ir_gen_symbol. I need to do a full audit of how 8840 // inline assembly works. https://github.com/ziglang/zig/issues/215 8841 ZigVar *var = find_variable(irb->codegen, scope, variable_name, nullptr); 8842 if (var) { 8843 output_vars[i] = var; 8844 } else { 8845 add_node_error(irb->codegen, node, 8846 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); 8847 return irb->codegen->invalid_inst_src; 8848 } 8849 } 8850 8851 const char modifier = *buf_ptr(asm_output->constraint); 8852 if (modifier != '=') { 8853 add_node_error(irb->codegen, node, 8854 buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported." 8855 " Compiler TODO: see https://github.com/ziglang/zig/issues/215", 8856 buf_ptr(asm_output->asm_symbolic_name), modifier)); 8857 return irb->codegen->invalid_inst_src; 8858 } 8859 } 8860 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 8861 AsmInput *asm_input = asm_expr->input_list.at(i); 8862 IrInstSrc *input_value = ir_gen_node(irb, asm_input->expr, scope); 8863 if (input_value == irb->codegen->invalid_inst_src) 8864 return irb->codegen->invalid_inst_src; 8865 8866 input_list[i] = input_value; 8867 } 8868 8869 return ir_build_asm_src(irb, scope, node, asm_template, input_list, output_types, 8870 output_vars, return_count, is_volatile, false); 8871 } 8872 8873 static IrInstSrc *ir_gen_if_optional_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 8874 ResultLoc *result_loc) 8875 { 8876 assert(node->type == NodeTypeIfOptional); 8877 8878 Buf *var_symbol = node->data.test_expr.var_symbol; 8879 AstNode *expr_node = node->data.test_expr.target_node; 8880 AstNode *then_node = node->data.test_expr.then_node; 8881 AstNode *else_node = node->data.test_expr.else_node; 8882 bool var_is_ptr = node->data.test_expr.var_is_ptr; 8883 8884 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, expr_node, scope); 8885 spill_scope->spill_harder = true; 8886 8887 IrInstSrc *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, &spill_scope->base, LValPtr, nullptr); 8888 if (maybe_val_ptr == irb->codegen->invalid_inst_src) 8889 return maybe_val_ptr; 8890 8891 IrInstSrc *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr); 8892 IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, scope, node, maybe_val); 8893 8894 IrBasicBlockSrc *then_block = ir_create_basic_block(irb, scope, "OptionalThen"); 8895 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "OptionalElse"); 8896 IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "OptionalEndIf"); 8897 8898 IrInstSrc *is_comptime; 8899 if (ir_should_inline(irb->exec, scope)) { 8900 is_comptime = ir_build_const_bool(irb, scope, node, true); 8901 } else { 8902 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); 8903 } 8904 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null, 8905 then_block, else_block, is_comptime); 8906 8907 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 8908 result_loc, is_comptime); 8909 8910 ir_set_cursor_at_end_and_append_block(irb, then_block); 8911 8912 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, &spill_scope->base, is_comptime); 8913 Scope *var_scope; 8914 if (var_symbol) { 8915 bool is_shadowable = false; 8916 bool is_const = true; 8917 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 8918 var_symbol, is_const, is_const, is_shadowable, is_comptime); 8919 8920 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false); 8921 IrInstSrc *var_value = var_is_ptr ? 8922 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, node, payload_ptr); 8923 build_decl_var_and_init(irb, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), is_comptime); 8924 var_scope = var->child_scope; 8925 } else { 8926 var_scope = subexpr_scope; 8927 } 8928 IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, 8929 &peer_parent->peers.at(0)->base); 8930 if (then_expr_result == irb->codegen->invalid_inst_src) 8931 return then_expr_result; 8932 IrBasicBlockSrc *after_then_block = irb->current_basic_block; 8933 if (!instr_is_unreachable(then_expr_result)) 8934 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 8935 8936 ir_set_cursor_at_end_and_append_block(irb, else_block); 8937 IrInstSrc *else_expr_result; 8938 if (else_node) { 8939 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); 8940 if (else_expr_result == irb->codegen->invalid_inst_src) 8941 return else_expr_result; 8942 } else { 8943 else_expr_result = ir_build_const_void(irb, scope, node); 8944 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 8945 } 8946 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8947 if (!instr_is_unreachable(else_expr_result)) 8948 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 8949 8950 ir_set_cursor_at_end_and_append_block(irb, endif_block); 8951 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 8952 incoming_values[0] = then_expr_result; 8953 incoming_values[1] = else_expr_result; 8954 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 8955 incoming_blocks[0] = after_then_block; 8956 incoming_blocks[1] = after_else_block; 8957 8958 IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 8959 return ir_expr_wrap(irb, scope, phi, result_loc); 8960 } 8961 8962 static IrInstSrc *ir_gen_if_err_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 8963 ResultLoc *result_loc) 8964 { 8965 assert(node->type == NodeTypeIfErrorExpr); 8966 8967 AstNode *target_node = node->data.if_err_expr.target_node; 8968 AstNode *then_node = node->data.if_err_expr.then_node; 8969 AstNode *else_node = node->data.if_err_expr.else_node; 8970 bool var_is_ptr = node->data.if_err_expr.var_is_ptr; 8971 bool var_is_const = true; 8972 Buf *var_symbol = node->data.if_err_expr.var_symbol; 8973 Buf *err_symbol = node->data.if_err_expr.err_symbol; 8974 8975 IrInstSrc *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); 8976 if (err_val_ptr == irb->codegen->invalid_inst_src) 8977 return err_val_ptr; 8978 8979 IrInstSrc *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); 8980 IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr, true, false); 8981 8982 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, scope, "TryOk"); 8983 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "TryElse"); 8984 IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "TryEnd"); 8985 8986 bool force_comptime = ir_should_inline(irb->exec, scope); 8987 IrInstSrc *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); 8988 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); 8989 8990 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 8991 result_loc, is_comptime); 8992 8993 ir_set_cursor_at_end_and_append_block(irb, ok_block); 8994 8995 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 8996 Scope *var_scope; 8997 if (var_symbol) { 8998 bool is_shadowable = false; 8999 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); 9000 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 9001 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); 9002 9003 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, subexpr_scope, node, err_val_ptr, false, false); 9004 IrInstSrc *var_value = var_is_ptr ? 9005 payload_ptr : ir_build_load_ptr(irb, subexpr_scope, node, payload_ptr); 9006 build_decl_var_and_init(irb, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), var_is_comptime); 9007 var_scope = var->child_scope; 9008 } else { 9009 var_scope = subexpr_scope; 9010 } 9011 IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, 9012 &peer_parent->peers.at(0)->base); 9013 if (then_expr_result == irb->codegen->invalid_inst_src) 9014 return then_expr_result; 9015 IrBasicBlockSrc *after_then_block = irb->current_basic_block; 9016 if (!instr_is_unreachable(then_expr_result)) 9017 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 9018 9019 ir_set_cursor_at_end_and_append_block(irb, else_block); 9020 9021 IrInstSrc *else_expr_result; 9022 if (else_node) { 9023 Scope *err_var_scope; 9024 if (err_symbol) { 9025 bool is_shadowable = false; 9026 bool is_const = true; 9027 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 9028 err_symbol, is_const, is_const, is_shadowable, is_comptime); 9029 9030 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, subexpr_scope, node, err_val_ptr); 9031 IrInstSrc *err_value = ir_build_load_ptr(irb, subexpr_scope, node, err_ptr); 9032 build_decl_var_and_init(irb, subexpr_scope, node, var, err_value, buf_ptr(err_symbol), is_comptime); 9033 err_var_scope = var->child_scope; 9034 } else { 9035 err_var_scope = subexpr_scope; 9036 } 9037 else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base); 9038 if (else_expr_result == irb->codegen->invalid_inst_src) 9039 return else_expr_result; 9040 } else { 9041 else_expr_result = ir_build_const_void(irb, scope, node); 9042 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 9043 } 9044 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 9045 if (!instr_is_unreachable(else_expr_result)) 9046 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 9047 9048 ir_set_cursor_at_end_and_append_block(irb, endif_block); 9049 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 9050 incoming_values[0] = then_expr_result; 9051 incoming_values[1] = else_expr_result; 9052 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 9053 incoming_blocks[0] = after_then_block; 9054 incoming_blocks[1] = after_else_block; 9055 9056 IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 9057 return ir_expr_wrap(irb, scope, phi, result_loc); 9058 } 9059 9060 static bool ir_gen_switch_prong_expr(IrBuilderSrc *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, 9061 IrBasicBlockSrc *end_block, IrInstSrc *is_comptime, IrInstSrc *var_is_comptime, 9062 IrInstSrc *target_value_ptr, IrInstSrc **prong_values, size_t prong_values_len, 9063 ZigList<IrBasicBlockSrc *> *incoming_blocks, ZigList<IrInstSrc *> *incoming_values, 9064 IrInstSrcSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc) 9065 { 9066 assert(switch_node->type == NodeTypeSwitchExpr); 9067 assert(prong_node->type == NodeTypeSwitchProng); 9068 9069 AstNode *expr_node = prong_node->data.switch_prong.expr; 9070 AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol; 9071 Scope *child_scope; 9072 if (var_symbol_node) { 9073 assert(var_symbol_node->type == NodeTypeSymbol); 9074 Buf *var_name = var_symbol_node->data.symbol_expr.symbol; 9075 bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr; 9076 9077 bool is_shadowable = false; 9078 bool is_const = true; 9079 ZigVar *var = ir_create_var(irb, var_symbol_node, scope, 9080 var_name, is_const, is_const, is_shadowable, var_is_comptime); 9081 child_scope = var->child_scope; 9082 IrInstSrc *var_value; 9083 if (out_switch_else_var != nullptr) { 9084 IrInstSrcSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node, 9085 target_value_ptr); 9086 *out_switch_else_var = switch_else_var; 9087 IrInstSrc *payload_ptr = &switch_else_var->base; 9088 var_value = var_is_ptr ? 9089 payload_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, payload_ptr); 9090 } else if (prong_values != nullptr) { 9091 IrInstSrc *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, 9092 prong_values, prong_values_len); 9093 var_value = var_is_ptr ? 9094 payload_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, payload_ptr); 9095 } else { 9096 var_value = var_is_ptr ? 9097 target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr); 9098 } 9099 build_decl_var_and_init(irb, scope, var_symbol_node, var, var_value, buf_ptr(var_name), var_is_comptime); 9100 } else { 9101 child_scope = scope; 9102 } 9103 9104 IrInstSrc *expr_result = ir_gen_node_extra(irb, expr_node, child_scope, lval, result_loc); 9105 if (expr_result == irb->codegen->invalid_inst_src) 9106 return false; 9107 if (!instr_is_unreachable(expr_result)) 9108 ir_mark_gen(ir_build_br(irb, scope, switch_node, end_block, is_comptime)); 9109 incoming_blocks->append(irb->current_basic_block); 9110 incoming_values->append(expr_result); 9111 return true; 9112 } 9113 9114 static IrInstSrc *ir_gen_switch_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 9115 ResultLoc *result_loc) 9116 { 9117 assert(node->type == NodeTypeSwitchExpr); 9118 9119 AstNode *target_node = node->data.switch_expr.expr; 9120 IrInstSrc *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); 9121 if (target_value_ptr == irb->codegen->invalid_inst_src) 9122 return target_value_ptr; 9123 IrInstSrc *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); 9124 9125 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "SwitchElse"); 9126 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, scope, "SwitchEnd"); 9127 9128 size_t prong_count = node->data.switch_expr.prongs.length; 9129 ZigList<IrInstSrcSwitchBrCase> cases = {0}; 9130 9131 IrInstSrc *is_comptime; 9132 IrInstSrc *var_is_comptime; 9133 if (ir_should_inline(irb->exec, scope)) { 9134 is_comptime = ir_build_const_bool(irb, scope, node, true); 9135 var_is_comptime = is_comptime; 9136 } else { 9137 is_comptime = ir_build_test_comptime(irb, scope, node, target_value); 9138 var_is_comptime = ir_build_test_comptime(irb, scope, node, target_value_ptr); 9139 } 9140 9141 ZigList<IrInstSrc *> incoming_values = {0}; 9142 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 9143 ZigList<IrInstSrcCheckSwitchProngsRange> check_ranges = {0}; 9144 9145 IrInstSrcSwitchElseVar *switch_else_var = nullptr; 9146 9147 ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>(); 9148 peer_parent->base.id = ResultLocIdPeerParent; 9149 peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; 9150 peer_parent->end_bb = end_block; 9151 peer_parent->is_comptime = is_comptime; 9152 peer_parent->parent = result_loc; 9153 9154 ir_build_reset_result(irb, scope, node, &peer_parent->base); 9155 9156 // First do the else and the ranges 9157 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 9158 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 9159 AstNode *else_prong = nullptr; 9160 AstNode *underscore_prong = nullptr; 9161 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 9162 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 9163 size_t prong_item_count = prong_node->data.switch_prong.items.length; 9164 if (prong_node->data.switch_prong.any_items_are_range) { 9165 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 9166 9167 IrInstSrc *ok_bit = nullptr; 9168 AstNode *last_item_node = nullptr; 9169 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 9170 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 9171 last_item_node = item_node; 9172 if (item_node->type == NodeTypeSwitchRange) { 9173 AstNode *start_node = item_node->data.switch_range.start; 9174 AstNode *end_node = item_node->data.switch_range.end; 9175 9176 IrInstSrc *start_value = ir_gen_node(irb, start_node, comptime_scope); 9177 if (start_value == irb->codegen->invalid_inst_src) 9178 return irb->codegen->invalid_inst_src; 9179 9180 IrInstSrc *end_value = ir_gen_node(irb, end_node, comptime_scope); 9181 if (end_value == irb->codegen->invalid_inst_src) 9182 return irb->codegen->invalid_inst_src; 9183 9184 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one(); 9185 check_range->start = start_value; 9186 check_range->end = end_value; 9187 9188 IrInstSrc *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq, 9189 target_value, start_value, false); 9190 IrInstSrc *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq, 9191 target_value, end_value, false); 9192 IrInstSrc *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd, 9193 lower_range_ok, upper_range_ok, false); 9194 if (ok_bit) { 9195 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false); 9196 } else { 9197 ok_bit = both_ok; 9198 } 9199 } else { 9200 IrInstSrc *item_value = ir_gen_node(irb, item_node, comptime_scope); 9201 if (item_value == irb->codegen->invalid_inst_src) 9202 return irb->codegen->invalid_inst_src; 9203 9204 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one(); 9205 check_range->start = item_value; 9206 check_range->end = item_value; 9207 9208 IrInstSrc *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq, 9209 item_value, target_value, false); 9210 if (ok_bit) { 9211 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false); 9212 } else { 9213 ok_bit = cmp_ok; 9214 } 9215 } 9216 } 9217 9218 IrBasicBlockSrc *range_block_yes = ir_create_basic_block(irb, scope, "SwitchRangeYes"); 9219 IrBasicBlockSrc *range_block_no = ir_create_basic_block(irb, scope, "SwitchRangeNo"); 9220 9221 assert(ok_bit); 9222 assert(last_item_node); 9223 IrInstSrc *br_inst = ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, 9224 range_block_yes, range_block_no, is_comptime)); 9225 if (peer_parent->base.source_instruction == nullptr) { 9226 peer_parent->base.source_instruction = br_inst; 9227 } 9228 9229 if (peer_parent->peers.length > 0) { 9230 peer_parent->peers.last()->next_bb = range_block_yes; 9231 } 9232 peer_parent->peers.append(this_peer_result_loc); 9233 ir_set_cursor_at_end_and_append_block(irb, range_block_yes); 9234 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 9235 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, 9236 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) 9237 { 9238 return irb->codegen->invalid_inst_src; 9239 } 9240 9241 ir_set_cursor_at_end_and_append_block(irb, range_block_no); 9242 } else { 9243 if (prong_item_count == 0) { 9244 if (else_prong) { 9245 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 9246 buf_sprintf("multiple else prongs in switch expression")); 9247 add_error_note(irb->codegen, msg, else_prong, 9248 buf_sprintf("previous else prong is here")); 9249 return irb->codegen->invalid_inst_src; 9250 } 9251 else_prong = prong_node; 9252 } else if (prong_item_count == 1 && 9253 prong_node->data.switch_prong.items.at(0)->type == NodeTypeSymbol && 9254 buf_eql_str(prong_node->data.switch_prong.items.at(0)->data.symbol_expr.symbol, "_")) { 9255 if (underscore_prong) { 9256 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 9257 buf_sprintf("multiple '_' prongs in switch expression")); 9258 add_error_note(irb->codegen, msg, underscore_prong, 9259 buf_sprintf("previous '_' prong is here")); 9260 return irb->codegen->invalid_inst_src; 9261 } 9262 underscore_prong = prong_node; 9263 } else { 9264 continue; 9265 } 9266 if (underscore_prong && else_prong) { 9267 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 9268 buf_sprintf("else and '_' prong in switch expression")); 9269 if (underscore_prong == prong_node) 9270 add_error_note(irb->codegen, msg, else_prong, 9271 buf_sprintf("else prong is here")); 9272 else 9273 add_error_note(irb->codegen, msg, underscore_prong, 9274 buf_sprintf("'_' prong is here")); 9275 return irb->codegen->invalid_inst_src; 9276 } 9277 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 9278 9279 IrBasicBlockSrc *prev_block = irb->current_basic_block; 9280 if (peer_parent->peers.length > 0) { 9281 peer_parent->peers.last()->next_bb = else_block; 9282 } 9283 peer_parent->peers.append(this_peer_result_loc); 9284 ir_set_cursor_at_end_and_append_block(irb, else_block); 9285 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 9286 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, 9287 &switch_else_var, LValNone, &this_peer_result_loc->base)) 9288 { 9289 return irb->codegen->invalid_inst_src; 9290 } 9291 ir_set_cursor_at_end(irb, prev_block); 9292 } 9293 } 9294 9295 // next do the non-else non-ranges 9296 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 9297 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 9298 size_t prong_item_count = prong_node->data.switch_prong.items.length; 9299 if (prong_item_count == 0) 9300 continue; 9301 if (prong_node->data.switch_prong.any_items_are_range) 9302 continue; 9303 if (underscore_prong == prong_node) 9304 continue; 9305 9306 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 9307 9308 IrBasicBlockSrc *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); 9309 IrInstSrc **items = heap::c_allocator.allocate<IrInstSrc *>(prong_item_count); 9310 9311 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 9312 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 9313 assert(item_node->type != NodeTypeSwitchRange); 9314 9315 IrInstSrc *item_value = ir_gen_node(irb, item_node, comptime_scope); 9316 if (item_value == irb->codegen->invalid_inst_src) 9317 return irb->codegen->invalid_inst_src; 9318 9319 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one(); 9320 check_range->start = item_value; 9321 check_range->end = item_value; 9322 9323 IrInstSrcSwitchBrCase *this_case = cases.add_one(); 9324 this_case->value = item_value; 9325 this_case->block = prong_block; 9326 9327 items[item_i] = item_value; 9328 } 9329 9330 IrBasicBlockSrc *prev_block = irb->current_basic_block; 9331 if (peer_parent->peers.length > 0) { 9332 peer_parent->peers.last()->next_bb = prong_block; 9333 } 9334 peer_parent->peers.append(this_peer_result_loc); 9335 ir_set_cursor_at_end_and_append_block(irb, prong_block); 9336 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 9337 is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, 9338 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) 9339 { 9340 return irb->codegen->invalid_inst_src; 9341 } 9342 9343 ir_set_cursor_at_end(irb, prev_block); 9344 9345 } 9346 9347 IrInstSrc *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, 9348 check_ranges.items, check_ranges.length, else_prong != nullptr, underscore_prong != nullptr); 9349 9350 IrInstSrc *br_instruction; 9351 if (cases.length == 0) { 9352 br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime); 9353 } else { 9354 IrInstSrcSwitchBr *switch_br = ir_build_switch_br_src(irb, scope, node, target_value, else_block, 9355 cases.length, cases.items, is_comptime, switch_prongs_void); 9356 if (switch_else_var != nullptr) { 9357 switch_else_var->switch_br = switch_br; 9358 } 9359 br_instruction = &switch_br->base; 9360 } 9361 if (peer_parent->base.source_instruction == nullptr) { 9362 peer_parent->base.source_instruction = br_instruction; 9363 } 9364 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 9365 peer_parent->peers.at(i)->base.source_instruction = peer_parent->base.source_instruction; 9366 } 9367 9368 if (!else_prong && !underscore_prong) { 9369 if (peer_parent->peers.length != 0) { 9370 peer_parent->peers.last()->next_bb = else_block; 9371 } 9372 ir_set_cursor_at_end_and_append_block(irb, else_block); 9373 ir_build_unreachable(irb, scope, node); 9374 } else { 9375 if (peer_parent->peers.length != 0) { 9376 peer_parent->peers.last()->next_bb = end_block; 9377 } 9378 } 9379 9380 ir_set_cursor_at_end_and_append_block(irb, end_block); 9381 assert(incoming_blocks.length == incoming_values.length); 9382 IrInstSrc *result_instruction; 9383 if (incoming_blocks.length == 0) { 9384 result_instruction = ir_build_const_void(irb, scope, node); 9385 } else { 9386 result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length, 9387 incoming_blocks.items, incoming_values.items, peer_parent); 9388 } 9389 return ir_lval_wrap(irb, scope, result_instruction, lval, result_loc); 9390 } 9391 9392 static IrInstSrc *ir_gen_comptime(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) { 9393 assert(node->type == NodeTypeCompTime); 9394 9395 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); 9396 // purposefully pass null for result_loc and let EndExpr handle it 9397 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); 9398 } 9399 9400 static IrInstSrc *ir_gen_nosuspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) { 9401 assert(node->type == NodeTypeNoSuspend); 9402 9403 Scope *child_scope = create_nosuspend_scope(irb->codegen, node, parent_scope); 9404 // purposefully pass null for result_loc and let EndExpr handle it 9405 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); 9406 } 9407 9408 static IrInstSrc *ir_gen_return_from_block(IrBuilderSrc *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { 9409 IrInstSrc *is_comptime; 9410 if (ir_should_inline(irb->exec, break_scope)) { 9411 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 9412 } else { 9413 is_comptime = block_scope->is_comptime; 9414 } 9415 9416 IrInstSrc *result_value; 9417 if (node->data.break_expr.expr) { 9418 ResultLocPeer *peer_result = create_peer_result(block_scope->peer_parent); 9419 block_scope->peer_parent->peers.append(peer_result); 9420 9421 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, block_scope->lval, 9422 &peer_result->base); 9423 if (result_value == irb->codegen->invalid_inst_src) 9424 return irb->codegen->invalid_inst_src; 9425 } else { 9426 result_value = ir_build_const_void(irb, break_scope, node); 9427 } 9428 9429 IrBasicBlockSrc *dest_block = block_scope->end_block; 9430 if (!ir_gen_defers_for_block(irb, break_scope, dest_block->scope, nullptr, nullptr)) 9431 return irb->codegen->invalid_inst_src; 9432 9433 block_scope->incoming_blocks->append(irb->current_basic_block); 9434 block_scope->incoming_values->append(result_value); 9435 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 9436 } 9437 9438 static IrInstSrc *ir_gen_break(IrBuilderSrc *irb, Scope *break_scope, AstNode *node) { 9439 assert(node->type == NodeTypeBreak); 9440 9441 // Search up the scope. We'll find one of these things first: 9442 // * function definition scope or global scope => error, break outside loop 9443 // * defer expression scope => error, cannot break out of defer expression 9444 // * loop scope => OK 9445 // * (if it's a labeled break) labeled block => OK 9446 9447 Scope *search_scope = break_scope; 9448 ScopeLoop *loop_scope; 9449 for (;;) { 9450 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 9451 if (node->data.break_expr.name != nullptr) { 9452 add_node_error(irb->codegen, node, buf_sprintf("label not found: '%s'", buf_ptr(node->data.break_expr.name))); 9453 return irb->codegen->invalid_inst_src; 9454 } else { 9455 add_node_error(irb->codegen, node, buf_sprintf("break expression outside loop")); 9456 return irb->codegen->invalid_inst_src; 9457 } 9458 } else if (search_scope->id == ScopeIdDeferExpr) { 9459 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of defer expression")); 9460 return irb->codegen->invalid_inst_src; 9461 } else if (search_scope->id == ScopeIdLoop) { 9462 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 9463 if (node->data.break_expr.name == nullptr || 9464 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name))) 9465 { 9466 loop_scope = this_loop_scope; 9467 break; 9468 } 9469 } else if (search_scope->id == ScopeIdBlock) { 9470 ScopeBlock *this_block_scope = (ScopeBlock *)search_scope; 9471 if (node->data.break_expr.name != nullptr && 9472 (this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name))) 9473 { 9474 assert(this_block_scope->end_block != nullptr); 9475 return ir_gen_return_from_block(irb, break_scope, node, this_block_scope); 9476 } 9477 } else if (search_scope->id == ScopeIdSuspend) { 9478 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of suspend block")); 9479 return irb->codegen->invalid_inst_src; 9480 } 9481 search_scope = search_scope->parent; 9482 } 9483 9484 IrInstSrc *is_comptime; 9485 if (ir_should_inline(irb->exec, break_scope)) { 9486 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 9487 } else { 9488 is_comptime = loop_scope->is_comptime; 9489 } 9490 9491 IrInstSrc *result_value; 9492 if (node->data.break_expr.expr) { 9493 ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent); 9494 loop_scope->peer_parent->peers.append(peer_result); 9495 9496 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, 9497 loop_scope->lval, &peer_result->base); 9498 if (result_value == irb->codegen->invalid_inst_src) 9499 return irb->codegen->invalid_inst_src; 9500 } else { 9501 result_value = ir_build_const_void(irb, break_scope, node); 9502 } 9503 9504 IrBasicBlockSrc *dest_block = loop_scope->break_block; 9505 if (!ir_gen_defers_for_block(irb, break_scope, dest_block->scope, nullptr, nullptr)) 9506 return irb->codegen->invalid_inst_src; 9507 9508 loop_scope->incoming_blocks->append(irb->current_basic_block); 9509 loop_scope->incoming_values->append(result_value); 9510 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 9511 } 9512 9513 static IrInstSrc *ir_gen_continue(IrBuilderSrc *irb, Scope *continue_scope, AstNode *node) { 9514 assert(node->type == NodeTypeContinue); 9515 9516 // Search up the scope. We'll find one of these things first: 9517 // * function definition scope or global scope => error, break outside loop 9518 // * defer expression scope => error, cannot break out of defer expression 9519 // * loop scope => OK 9520 9521 ZigList<ScopeRuntime *> runtime_scopes = {}; 9522 9523 Scope *search_scope = continue_scope; 9524 ScopeLoop *loop_scope; 9525 for (;;) { 9526 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 9527 if (node->data.continue_expr.name != nullptr) { 9528 add_node_error(irb->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.continue_expr.name))); 9529 return irb->codegen->invalid_inst_src; 9530 } else { 9531 add_node_error(irb->codegen, node, buf_sprintf("continue expression outside loop")); 9532 return irb->codegen->invalid_inst_src; 9533 } 9534 } else if (search_scope->id == ScopeIdDeferExpr) { 9535 add_node_error(irb->codegen, node, buf_sprintf("cannot continue out of defer expression")); 9536 return irb->codegen->invalid_inst_src; 9537 } else if (search_scope->id == ScopeIdLoop) { 9538 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 9539 if (node->data.continue_expr.name == nullptr || 9540 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name))) 9541 { 9542 loop_scope = this_loop_scope; 9543 break; 9544 } 9545 } else if (search_scope->id == ScopeIdRuntime) { 9546 ScopeRuntime *scope_runtime = (ScopeRuntime *)search_scope; 9547 runtime_scopes.append(scope_runtime); 9548 } 9549 search_scope = search_scope->parent; 9550 } 9551 9552 IrInstSrc *is_comptime; 9553 if (ir_should_inline(irb->exec, continue_scope)) { 9554 is_comptime = ir_build_const_bool(irb, continue_scope, node, true); 9555 } else { 9556 is_comptime = loop_scope->is_comptime; 9557 } 9558 9559 for (size_t i = 0; i < runtime_scopes.length; i += 1) { 9560 ScopeRuntime *scope_runtime = runtime_scopes.at(i); 9561 ir_mark_gen(ir_build_check_runtime_scope(irb, continue_scope, node, scope_runtime->is_comptime, is_comptime)); 9562 } 9563 9564 IrBasicBlockSrc *dest_block = loop_scope->continue_block; 9565 if (!ir_gen_defers_for_block(irb, continue_scope, dest_block->scope, nullptr, nullptr)) 9566 return irb->codegen->invalid_inst_src; 9567 return ir_mark_gen(ir_build_br(irb, continue_scope, node, dest_block, is_comptime)); 9568 } 9569 9570 static IrInstSrc *ir_gen_error_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 9571 assert(node->type == NodeTypeErrorType); 9572 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_global_error_set); 9573 } 9574 9575 static IrInstSrc *ir_gen_defer(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 9576 assert(node->type == NodeTypeDefer); 9577 9578 ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope); 9579 node->data.defer.child_scope = &defer_child_scope->base; 9580 9581 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(irb->codegen, node, parent_scope); 9582 node->data.defer.expr_scope = &defer_expr_scope->base; 9583 9584 return ir_build_const_void(irb, parent_scope, node); 9585 } 9586 9587 static IrInstSrc *ir_gen_slice(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 9588 assert(node->type == NodeTypeSliceExpr); 9589 9590 AstNodeSliceExpr *slice_expr = &node->data.slice_expr; 9591 AstNode *array_node = slice_expr->array_ref_expr; 9592 AstNode *start_node = slice_expr->start; 9593 AstNode *end_node = slice_expr->end; 9594 AstNode *sentinel_node = slice_expr->sentinel; 9595 9596 IrInstSrc *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr); 9597 if (ptr_value == irb->codegen->invalid_inst_src) 9598 return irb->codegen->invalid_inst_src; 9599 9600 IrInstSrc *start_value = ir_gen_node(irb, start_node, scope); 9601 if (start_value == irb->codegen->invalid_inst_src) 9602 return irb->codegen->invalid_inst_src; 9603 9604 IrInstSrc *end_value; 9605 if (end_node) { 9606 end_value = ir_gen_node(irb, end_node, scope); 9607 if (end_value == irb->codegen->invalid_inst_src) 9608 return irb->codegen->invalid_inst_src; 9609 } else { 9610 end_value = nullptr; 9611 } 9612 9613 IrInstSrc *sentinel_value; 9614 if (sentinel_node) { 9615 sentinel_value = ir_gen_node(irb, sentinel_node, scope); 9616 if (sentinel_value == irb->codegen->invalid_inst_src) 9617 return irb->codegen->invalid_inst_src; 9618 } else { 9619 sentinel_value = nullptr; 9620 } 9621 9622 IrInstSrc *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value, 9623 sentinel_value, true, result_loc); 9624 return ir_lval_wrap(irb, scope, slice, lval, result_loc); 9625 } 9626 9627 static IrInstSrc *ir_gen_catch(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval, 9628 ResultLoc *result_loc) 9629 { 9630 assert(node->type == NodeTypeCatchExpr); 9631 9632 AstNode *op1_node = node->data.unwrap_err_expr.op1; 9633 AstNode *op2_node = node->data.unwrap_err_expr.op2; 9634 AstNode *var_node = node->data.unwrap_err_expr.symbol; 9635 9636 if (op2_node->type == NodeTypeUnreachable) { 9637 if (var_node != nullptr) { 9638 assert(var_node->type == NodeTypeSymbol); 9639 Buf *var_name = var_node->data.symbol_expr.symbol; 9640 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); 9641 return irb->codegen->invalid_inst_src; 9642 } 9643 return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, lval, result_loc); 9644 } 9645 9646 9647 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, op1_node, parent_scope); 9648 spill_scope->spill_harder = true; 9649 9650 IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, op1_node, &spill_scope->base, LValPtr, nullptr); 9651 if (err_union_ptr == irb->codegen->invalid_inst_src) 9652 return irb->codegen->invalid_inst_src; 9653 9654 IrInstSrc *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr, true, false); 9655 9656 IrInstSrc *is_comptime; 9657 if (ir_should_inline(irb->exec, parent_scope)) { 9658 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 9659 } else { 9660 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_err); 9661 } 9662 9663 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); 9664 IrBasicBlockSrc *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); 9665 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); 9666 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); 9667 9668 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, result_loc, 9669 is_comptime); 9670 9671 ir_set_cursor_at_end_and_append_block(irb, err_block); 9672 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, &spill_scope->base, is_comptime); 9673 Scope *err_scope; 9674 if (var_node) { 9675 assert(var_node->type == NodeTypeSymbol); 9676 Buf *var_name = var_node->data.symbol_expr.symbol; 9677 bool is_const = true; 9678 bool is_shadowable = false; 9679 ZigVar *var = ir_create_var(irb, node, subexpr_scope, var_name, 9680 is_const, is_const, is_shadowable, is_comptime); 9681 err_scope = var->child_scope; 9682 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, node, err_union_ptr); 9683 IrInstSrc *err_value = ir_build_load_ptr(irb, err_scope, var_node, err_ptr); 9684 build_decl_var_and_init(irb, err_scope, var_node, var, err_value, buf_ptr(var_name), is_comptime); 9685 } else { 9686 err_scope = subexpr_scope; 9687 } 9688 IrInstSrc *err_result = ir_gen_node_extra(irb, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base); 9689 if (err_result == irb->codegen->invalid_inst_src) 9690 return irb->codegen->invalid_inst_src; 9691 IrBasicBlockSrc *after_err_block = irb->current_basic_block; 9692 if (!instr_is_unreachable(err_result)) 9693 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 9694 9695 ir_set_cursor_at_end_and_append_block(irb, ok_block); 9696 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(irb, parent_scope, node, err_union_ptr, false, false); 9697 IrInstSrc *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 9698 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); 9699 IrBasicBlockSrc *after_ok_block = irb->current_basic_block; 9700 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 9701 9702 ir_set_cursor_at_end_and_append_block(irb, end_block); 9703 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 9704 incoming_values[0] = err_result; 9705 incoming_values[1] = unwrapped_payload; 9706 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 9707 incoming_blocks[0] = after_err_block; 9708 incoming_blocks[1] = after_ok_block; 9709 IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); 9710 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 9711 } 9712 9713 static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) { 9714 if (inner_scope == nullptr || inner_scope == outer_scope) return false; 9715 bool need_comma = render_instance_name_recursive(codegen, name, outer_scope, inner_scope->parent); 9716 if (inner_scope->id != ScopeIdVarDecl) 9717 return need_comma; 9718 9719 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; 9720 if (need_comma) 9721 buf_append_char(name, ','); 9722 // TODO: const ptr reinterpret here to make the var type agree with the value? 9723 render_const_value(codegen, name, var_scope->var->const_value); 9724 return true; 9725 } 9726 9727 static Buf *get_anon_type_name(CodeGen *codegen, IrExecutableSrc *exec, const char *kind_name, 9728 Scope *scope, AstNode *source_node, Buf *out_bare_name) 9729 { 9730 if (exec != nullptr && exec->name) { 9731 ZigType *import = get_scope_import(scope); 9732 Buf *namespace_name = buf_alloc(); 9733 append_namespace_qualification(codegen, namespace_name, import); 9734 buf_append_buf(namespace_name, exec->name); 9735 buf_init_from_buf(out_bare_name, exec->name); 9736 return namespace_name; 9737 } else if (exec != nullptr && exec->name_fn != nullptr) { 9738 Buf *name = buf_alloc(); 9739 buf_append_buf(name, &exec->name_fn->symbol_name); 9740 buf_appendf(name, "("); 9741 render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope); 9742 buf_appendf(name, ")"); 9743 buf_init_from_buf(out_bare_name, name); 9744 return name; 9745 } else { 9746 ZigType *import = get_scope_import(scope); 9747 Buf *namespace_name = buf_alloc(); 9748 append_namespace_qualification(codegen, namespace_name, import); 9749 buf_appendf(namespace_name, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, kind_name, 9750 source_node->line + 1, source_node->column + 1); 9751 buf_init_from_buf(out_bare_name, namespace_name); 9752 return namespace_name; 9753 } 9754 } 9755 9756 static IrInstSrc *ir_gen_container_decl(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 9757 assert(node->type == NodeTypeContainerDecl); 9758 9759 ContainerKind kind = node->data.container_decl.kind; 9760 Buf *bare_name = buf_alloc(); 9761 Buf *name = get_anon_type_name(irb->codegen, irb->exec, container_string(kind), parent_scope, node, bare_name); 9762 9763 ContainerLayout layout = node->data.container_decl.layout; 9764 ZigType *container_type = get_partial_container_type(irb->codegen, parent_scope, 9765 kind, node, buf_ptr(name), bare_name, layout); 9766 ScopeDecls *child_scope = get_container_scope(container_type); 9767 9768 for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) { 9769 AstNode *child_node = node->data.container_decl.decls.at(i); 9770 scan_decls(irb->codegen, child_scope, child_node); 9771 } 9772 9773 TldContainer *tld_container = heap::c_allocator.create<TldContainer>(); 9774 init_tld(&tld_container->base, TldIdContainer, bare_name, VisibModPub, node, parent_scope); 9775 tld_container->type_entry = container_type; 9776 tld_container->decls_scope = child_scope; 9777 irb->codegen->resolve_queue.append(&tld_container->base); 9778 9779 // Add this to the list to mark as invalid if analyzing this exec fails. 9780 irb->exec->tld_list.append(&tld_container->base); 9781 9782 return ir_build_const_type(irb, parent_scope, node, container_type); 9783 } 9784 9785 // errors should be populated with set1's values 9786 static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigType *set1, ZigType *set2, 9787 Buf *type_name) 9788 { 9789 assert(set1->id == ZigTypeIdErrorSet); 9790 assert(set2->id == ZigTypeIdErrorSet); 9791 9792 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 9793 err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits; 9794 err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align; 9795 err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size; 9796 if (type_name == nullptr) { 9797 buf_resize(&err_set_type->name, 0); 9798 buf_appendf(&err_set_type->name, "error{"); 9799 } else { 9800 buf_init_from_buf(&err_set_type->name, type_name); 9801 } 9802 9803 for (uint32_t i = 0, count = set1->data.error_set.err_count; i < count; i += 1) { 9804 assert(errors[set1->data.error_set.errors[i]->value] == set1->data.error_set.errors[i]); 9805 } 9806 9807 uint32_t count = set1->data.error_set.err_count; 9808 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 9809 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 9810 if (errors[error_entry->value] == nullptr) { 9811 count += 1; 9812 } 9813 } 9814 9815 err_set_type->data.error_set.err_count = count; 9816 err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(count); 9817 9818 bool need_comma = false; 9819 for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { 9820 ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; 9821 if (type_name == nullptr) { 9822 const char *comma = need_comma ? "," : ""; 9823 need_comma = true; 9824 buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&error_entry->name)); 9825 } 9826 err_set_type->data.error_set.errors[i] = error_entry; 9827 } 9828 9829 uint32_t index = set1->data.error_set.err_count; 9830 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 9831 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 9832 if (errors[error_entry->value] == nullptr) { 9833 errors[error_entry->value] = error_entry; 9834 if (type_name == nullptr) { 9835 const char *comma = need_comma ? "," : ""; 9836 need_comma = true; 9837 buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&error_entry->name)); 9838 } 9839 err_set_type->data.error_set.errors[index] = error_entry; 9840 index += 1; 9841 } 9842 } 9843 assert(index == count); 9844 9845 if (type_name == nullptr) { 9846 buf_appendf(&err_set_type->name, "}"); 9847 } 9848 9849 return err_set_type; 9850 9851 } 9852 9853 static ZigType *make_err_set_with_one_item(CodeGen *g, Scope *parent_scope, AstNode *node, 9854 ErrorTableEntry *err_entry) 9855 { 9856 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 9857 buf_resize(&err_set_type->name, 0); 9858 buf_appendf(&err_set_type->name, "error{%s}", buf_ptr(&err_entry->name)); 9859 err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits; 9860 err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align; 9861 err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size; 9862 err_set_type->data.error_set.err_count = 1; 9863 err_set_type->data.error_set.errors = heap::c_allocator.create<ErrorTableEntry *>(); 9864 9865 err_set_type->data.error_set.errors[0] = err_entry; 9866 9867 return err_set_type; 9868 } 9869 9870 static AstNode *ast_field_to_symbol_node(AstNode *err_set_field_node) { 9871 if (err_set_field_node->type == NodeTypeSymbol) { 9872 return err_set_field_node; 9873 } else if (err_set_field_node->type == NodeTypeErrorSetField) { 9874 assert(err_set_field_node->data.err_set_field.field_name->type == NodeTypeSymbol); 9875 return err_set_field_node->data.err_set_field.field_name; 9876 } else { 9877 return err_set_field_node; 9878 } 9879 } 9880 9881 static IrInstSrc *ir_gen_err_set_decl(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 9882 assert(node->type == NodeTypeErrorSetDecl); 9883 9884 uint32_t err_count = node->data.err_set_decl.decls.length; 9885 9886 Buf bare_name = BUF_INIT; 9887 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error", parent_scope, node, &bare_name); 9888 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 9889 buf_init_from_buf(&err_set_type->name, type_name); 9890 err_set_type->data.error_set.err_count = err_count; 9891 err_set_type->size_in_bits = irb->codegen->builtin_types.entry_global_error_set->size_in_bits; 9892 err_set_type->abi_align = irb->codegen->builtin_types.entry_global_error_set->abi_align; 9893 err_set_type->abi_size = irb->codegen->builtin_types.entry_global_error_set->abi_size; 9894 err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(err_count); 9895 9896 size_t errors_count = irb->codegen->errors_by_index.length + err_count; 9897 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count); 9898 9899 for (uint32_t i = 0; i < err_count; i += 1) { 9900 AstNode *field_node = node->data.err_set_decl.decls.at(i); 9901 AstNode *symbol_node = ast_field_to_symbol_node(field_node); 9902 Buf *err_name = symbol_node->data.symbol_expr.symbol; 9903 ErrorTableEntry *err = heap::c_allocator.create<ErrorTableEntry>(); 9904 err->decl_node = field_node; 9905 buf_init_from_buf(&err->name, err_name); 9906 9907 auto existing_entry = irb->codegen->error_table.put_unique(err_name, err); 9908 if (existing_entry) { 9909 err->value = existing_entry->value->value; 9910 } else { 9911 size_t error_value_count = irb->codegen->errors_by_index.length; 9912 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)irb->codegen->err_tag_type->data.integral.bit_count)); 9913 err->value = error_value_count; 9914 irb->codegen->errors_by_index.append(err); 9915 } 9916 err_set_type->data.error_set.errors[i] = err; 9917 9918 ErrorTableEntry *prev_err = errors[err->value]; 9919 if (prev_err != nullptr) { 9920 ErrorMsg *msg = add_node_error(irb->codegen, ast_field_to_symbol_node(err->decl_node), 9921 buf_sprintf("duplicate error: '%s'", buf_ptr(&err->name))); 9922 add_error_note(irb->codegen, msg, ast_field_to_symbol_node(prev_err->decl_node), 9923 buf_sprintf("other error here")); 9924 return irb->codegen->invalid_inst_src; 9925 } 9926 errors[err->value] = err; 9927 } 9928 heap::c_allocator.deallocate(errors, errors_count); 9929 return ir_build_const_type(irb, parent_scope, node, err_set_type); 9930 } 9931 9932 static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 9933 assert(node->type == NodeTypeFnProto); 9934 9935 size_t param_count = node->data.fn_proto.params.length; 9936 IrInstSrc **param_types = heap::c_allocator.allocate<IrInstSrc*>(param_count); 9937 9938 bool is_var_args = false; 9939 for (size_t i = 0; i < param_count; i += 1) { 9940 AstNode *param_node = node->data.fn_proto.params.at(i); 9941 if (param_node->data.param_decl.is_var_args) { 9942 is_var_args = true; 9943 break; 9944 } 9945 if (param_node->data.param_decl.anytype_token == nullptr) { 9946 AstNode *type_node = param_node->data.param_decl.type; 9947 IrInstSrc *type_value = ir_gen_node(irb, type_node, parent_scope); 9948 if (type_value == irb->codegen->invalid_inst_src) 9949 return irb->codegen->invalid_inst_src; 9950 param_types[i] = type_value; 9951 } else { 9952 param_types[i] = nullptr; 9953 } 9954 } 9955 9956 IrInstSrc *align_value = nullptr; 9957 if (node->data.fn_proto.align_expr != nullptr) { 9958 align_value = ir_gen_node(irb, node->data.fn_proto.align_expr, parent_scope); 9959 if (align_value == irb->codegen->invalid_inst_src) 9960 return irb->codegen->invalid_inst_src; 9961 } 9962 9963 IrInstSrc *callconv_value = nullptr; 9964 if (node->data.fn_proto.callconv_expr != nullptr) { 9965 callconv_value = ir_gen_node(irb, node->data.fn_proto.callconv_expr, parent_scope); 9966 if (callconv_value == irb->codegen->invalid_inst_src) 9967 return irb->codegen->invalid_inst_src; 9968 } 9969 9970 IrInstSrc *return_type; 9971 if (node->data.fn_proto.return_anytype_token == nullptr) { 9972 if (node->data.fn_proto.return_type == nullptr) { 9973 return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void); 9974 } else { 9975 return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope); 9976 if (return_type == irb->codegen->invalid_inst_src) 9977 return irb->codegen->invalid_inst_src; 9978 } 9979 } else { 9980 add_node_error(irb->codegen, node, 9981 buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447")); 9982 return irb->codegen->invalid_inst_src; 9983 //return_type = nullptr; 9984 } 9985 9986 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, callconv_value, return_type, is_var_args); 9987 } 9988 9989 static IrInstSrc *ir_gen_resume(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 9990 assert(node->type == NodeTypeResume); 9991 if (get_scope_nosuspend(scope) != nullptr) { 9992 add_node_error(irb->codegen, node, buf_sprintf("resume in nosuspend scope")); 9993 return irb->codegen->invalid_inst_src; 9994 } 9995 9996 IrInstSrc *target_inst = ir_gen_node_extra(irb, node->data.resume_expr.expr, scope, LValPtr, nullptr); 9997 if (target_inst == irb->codegen->invalid_inst_src) 9998 return irb->codegen->invalid_inst_src; 9999 10000 return ir_build_resume_src(irb, scope, node, target_inst); 10001 } 10002 10003 static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 10004 ResultLoc *result_loc) 10005 { 10006 assert(node->type == NodeTypeAwaitExpr); 10007 10008 bool is_nosuspend = get_scope_nosuspend(scope) != nullptr; 10009 10010 AstNode *expr_node = node->data.await_expr.expr; 10011 if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) { 10012 AstNode *fn_ref_expr = expr_node->data.fn_call_expr.fn_ref_expr; 10013 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 10014 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 10015 if (entry != nullptr) { 10016 BuiltinFnEntry *builtin_fn = entry->value; 10017 if (builtin_fn->id == BuiltinFnIdAsyncCall) { 10018 return ir_gen_async_call(irb, scope, node, expr_node, lval, result_loc); 10019 } 10020 } 10021 } 10022 10023 ZigFn *fn_entry = exec_fn_entry(irb->exec); 10024 if (!fn_entry) { 10025 add_node_error(irb->codegen, node, buf_sprintf("await outside function definition")); 10026 return irb->codegen->invalid_inst_src; 10027 } 10028 ScopeSuspend *existing_suspend_scope = get_scope_suspend(scope); 10029 if (existing_suspend_scope) { 10030 if (!existing_suspend_scope->reported_err) { 10031 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot await inside suspend block")); 10032 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("suspend block here")); 10033 existing_suspend_scope->reported_err = true; 10034 } 10035 return irb->codegen->invalid_inst_src; 10036 } 10037 10038 IrInstSrc *target_inst = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 10039 if (target_inst == irb->codegen->invalid_inst_src) 10040 return irb->codegen->invalid_inst_src; 10041 10042 IrInstSrc *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc, is_nosuspend); 10043 return ir_lval_wrap(irb, scope, await_inst, lval, result_loc); 10044 } 10045 10046 static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 10047 assert(node->type == NodeTypeSuspend); 10048 10049 ZigFn *fn_entry = exec_fn_entry(irb->exec); 10050 if (!fn_entry) { 10051 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition")); 10052 return irb->codegen->invalid_inst_src; 10053 } 10054 if (get_scope_nosuspend(parent_scope) != nullptr) { 10055 add_node_error(irb->codegen, node, buf_sprintf("suspend in nosuspend scope")); 10056 return irb->codegen->invalid_inst_src; 10057 } 10058 10059 ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope); 10060 if (existing_suspend_scope) { 10061 if (!existing_suspend_scope->reported_err) { 10062 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside suspend block")); 10063 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here")); 10064 existing_suspend_scope->reported_err = true; 10065 } 10066 return irb->codegen->invalid_inst_src; 10067 } 10068 10069 IrInstSrcSuspendBegin *begin = ir_build_suspend_begin_src(irb, parent_scope, node); 10070 if (node->data.suspend.block != nullptr) { 10071 ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); 10072 Scope *child_scope = &suspend_scope->base; 10073 IrInstSrc *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope); 10074 if (susp_res == irb->codegen->invalid_inst_src) 10075 return irb->codegen->invalid_inst_src; 10076 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res)); 10077 } 10078 10079 return ir_mark_gen(ir_build_suspend_finish_src(irb, parent_scope, node, begin)); 10080 } 10081 10082 static IrInstSrc *ir_gen_node_raw(IrBuilderSrc *irb, AstNode *node, Scope *scope, 10083 LVal lval, ResultLoc *result_loc) 10084 { 10085 assert(scope); 10086 switch (node->type) { 10087 case NodeTypeStructValueField: 10088 case NodeTypeParamDecl: 10089 case NodeTypeUsingNamespace: 10090 case NodeTypeSwitchProng: 10091 case NodeTypeSwitchRange: 10092 case NodeTypeStructField: 10093 case NodeTypeErrorSetField: 10094 case NodeTypeFnDef: 10095 case NodeTypeTestDecl: 10096 zig_unreachable(); 10097 case NodeTypeBlock: 10098 return ir_gen_block(irb, scope, node, lval, result_loc); 10099 case NodeTypeGroupedExpr: 10100 return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc); 10101 case NodeTypeBinOpExpr: 10102 return ir_gen_bin_op(irb, scope, node, lval, result_loc); 10103 case NodeTypeIntLiteral: 10104 return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval, result_loc); 10105 case NodeTypeFloatLiteral: 10106 return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval, result_loc); 10107 case NodeTypeCharLiteral: 10108 return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval, result_loc); 10109 case NodeTypeSymbol: 10110 return ir_gen_symbol(irb, scope, node, lval, result_loc); 10111 case NodeTypeFnCallExpr: 10112 return ir_gen_fn_call(irb, scope, node, lval, result_loc); 10113 case NodeTypeIfBoolExpr: 10114 return ir_gen_if_bool_expr(irb, scope, node, lval, result_loc); 10115 case NodeTypePrefixOpExpr: 10116 return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc); 10117 case NodeTypeContainerInitExpr: 10118 return ir_gen_container_init_expr(irb, scope, node, lval, result_loc); 10119 case NodeTypeVariableDeclaration: 10120 return ir_gen_var_decl(irb, scope, node); 10121 case NodeTypeWhileExpr: 10122 return ir_gen_while_expr(irb, scope, node, lval, result_loc); 10123 case NodeTypeForExpr: 10124 return ir_gen_for_expr(irb, scope, node, lval, result_loc); 10125 case NodeTypeArrayAccessExpr: 10126 return ir_gen_array_access(irb, scope, node, lval, result_loc); 10127 case NodeTypeReturnExpr: 10128 return ir_gen_return(irb, scope, node, lval, result_loc); 10129 case NodeTypeFieldAccessExpr: 10130 { 10131 IrInstSrc *ptr_instruction = ir_gen_field_access(irb, scope, node); 10132 if (ptr_instruction == irb->codegen->invalid_inst_src) 10133 return ptr_instruction; 10134 if (lval == LValPtr || lval == LValAssign) 10135 return ptr_instruction; 10136 10137 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 10138 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 10139 } 10140 case NodeTypePtrDeref: { 10141 AstNode *expr_node = node->data.ptr_deref_expr.target; 10142 10143 LVal child_lval = lval; 10144 if (child_lval == LValAssign) 10145 child_lval = LValPtr; 10146 10147 IrInstSrc *value = ir_gen_node_extra(irb, expr_node, scope, child_lval, nullptr); 10148 if (value == irb->codegen->invalid_inst_src) 10149 return value; 10150 10151 // We essentially just converted any lvalue from &(x.*) to (&x).*; 10152 // this inhibits checking that x is a pointer later, so we directly 10153 // record whether the pointer check is needed 10154 IrInstSrc *un_op = ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval, result_loc); 10155 return ir_expr_wrap(irb, scope, un_op, result_loc); 10156 } 10157 case NodeTypeUnwrapOptional: { 10158 AstNode *expr_node = node->data.unwrap_optional.expr; 10159 10160 IrInstSrc *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 10161 if (maybe_ptr == irb->codegen->invalid_inst_src) 10162 return irb->codegen->invalid_inst_src; 10163 10164 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true ); 10165 if (lval == LValPtr || lval == LValAssign) 10166 return unwrapped_ptr; 10167 10168 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, unwrapped_ptr); 10169 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 10170 } 10171 case NodeTypeBoolLiteral: 10172 return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval, result_loc); 10173 case NodeTypeArrayType: 10174 return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc); 10175 case NodeTypePointerType: 10176 return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc); 10177 case NodeTypeAnyFrameType: 10178 return ir_lval_wrap(irb, scope, ir_gen_anyframe_type(irb, scope, node), lval, result_loc); 10179 case NodeTypeStringLiteral: 10180 return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc); 10181 case NodeTypeUndefinedLiteral: 10182 return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval, result_loc); 10183 case NodeTypeAsmExpr: 10184 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval, result_loc); 10185 case NodeTypeNullLiteral: 10186 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval, result_loc); 10187 case NodeTypeIfErrorExpr: 10188 return ir_gen_if_err_expr(irb, scope, node, lval, result_loc); 10189 case NodeTypeIfOptional: 10190 return ir_gen_if_optional_expr(irb, scope, node, lval, result_loc); 10191 case NodeTypeSwitchExpr: 10192 return ir_gen_switch_expr(irb, scope, node, lval, result_loc); 10193 case NodeTypeCompTime: 10194 return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc); 10195 case NodeTypeNoSuspend: 10196 return ir_expr_wrap(irb, scope, ir_gen_nosuspend(irb, scope, node, lval), result_loc); 10197 case NodeTypeErrorType: 10198 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc); 10199 case NodeTypeBreak: 10200 return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval, result_loc); 10201 case NodeTypeContinue: 10202 return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc); 10203 case NodeTypeUnreachable: 10204 return ir_build_unreachable(irb, scope, node); 10205 case NodeTypeDefer: 10206 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc); 10207 case NodeTypeSliceExpr: 10208 return ir_gen_slice(irb, scope, node, lval, result_loc); 10209 case NodeTypeCatchExpr: 10210 return ir_gen_catch(irb, scope, node, lval, result_loc); 10211 case NodeTypeContainerDecl: 10212 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval, result_loc); 10213 case NodeTypeFnProto: 10214 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval, result_loc); 10215 case NodeTypeErrorSetDecl: 10216 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval, result_loc); 10217 case NodeTypeResume: 10218 return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval, result_loc); 10219 case NodeTypeAwaitExpr: 10220 return ir_gen_await_expr(irb, scope, node, lval, result_loc); 10221 case NodeTypeSuspend: 10222 return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval, result_loc); 10223 case NodeTypeEnumLiteral: 10224 return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval, result_loc); 10225 case NodeTypeInferredArrayType: 10226 add_node_error(irb->codegen, node, 10227 buf_sprintf("inferred array size invalid here")); 10228 return irb->codegen->invalid_inst_src; 10229 case NodeTypeAnyTypeField: 10230 return ir_lval_wrap(irb, scope, 10231 ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_anytype), lval, result_loc); 10232 } 10233 zig_unreachable(); 10234 } 10235 10236 static ResultLoc *no_result_loc(void) { 10237 ResultLocNone *result_loc_none = heap::c_allocator.create<ResultLocNone>(); 10238 result_loc_none->base.id = ResultLocIdNone; 10239 return &result_loc_none->base; 10240 } 10241 10242 static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *scope, LVal lval, 10243 ResultLoc *result_loc) 10244 { 10245 if (lval == LValAssign) { 10246 switch (node->type) { 10247 case NodeTypeStructValueField: 10248 case NodeTypeParamDecl: 10249 case NodeTypeUsingNamespace: 10250 case NodeTypeSwitchProng: 10251 case NodeTypeSwitchRange: 10252 case NodeTypeStructField: 10253 case NodeTypeErrorSetField: 10254 case NodeTypeFnDef: 10255 case NodeTypeTestDecl: 10256 zig_unreachable(); 10257 10258 // cannot be assigned to 10259 case NodeTypeBlock: 10260 case NodeTypeGroupedExpr: 10261 case NodeTypeBinOpExpr: 10262 case NodeTypeIntLiteral: 10263 case NodeTypeFloatLiteral: 10264 case NodeTypeCharLiteral: 10265 case NodeTypeIfBoolExpr: 10266 case NodeTypeContainerInitExpr: 10267 case NodeTypeVariableDeclaration: 10268 case NodeTypeWhileExpr: 10269 case NodeTypeForExpr: 10270 case NodeTypeReturnExpr: 10271 case NodeTypeBoolLiteral: 10272 case NodeTypeArrayType: 10273 case NodeTypePointerType: 10274 case NodeTypeAnyFrameType: 10275 case NodeTypeStringLiteral: 10276 case NodeTypeUndefinedLiteral: 10277 case NodeTypeAsmExpr: 10278 case NodeTypeNullLiteral: 10279 case NodeTypeIfErrorExpr: 10280 case NodeTypeIfOptional: 10281 case NodeTypeSwitchExpr: 10282 case NodeTypeCompTime: 10283 case NodeTypeNoSuspend: 10284 case NodeTypeErrorType: 10285 case NodeTypeBreak: 10286 case NodeTypeContinue: 10287 case NodeTypeUnreachable: 10288 case NodeTypeDefer: 10289 case NodeTypeSliceExpr: 10290 case NodeTypeCatchExpr: 10291 case NodeTypeContainerDecl: 10292 case NodeTypeFnProto: 10293 case NodeTypeErrorSetDecl: 10294 case NodeTypeResume: 10295 case NodeTypeAwaitExpr: 10296 case NodeTypeSuspend: 10297 case NodeTypeEnumLiteral: 10298 case NodeTypeInferredArrayType: 10299 case NodeTypeAnyTypeField: 10300 case NodeTypePrefixOpExpr: 10301 add_node_error(irb->codegen, node, 10302 buf_sprintf("invalid left-hand side to assignment")); 10303 return irb->codegen->invalid_inst_src; 10304 10305 // @field can be assigned to 10306 case NodeTypeFnCallExpr: 10307 if (node->data.fn_call_expr.modifier == CallModifierBuiltin) { 10308 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; 10309 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 10310 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 10311 10312 if (!entry) { 10313 add_node_error(irb->codegen, node, 10314 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name))); 10315 return irb->codegen->invalid_inst_src; 10316 } 10317 10318 if (entry->value->id == BuiltinFnIdField) { 10319 break; 10320 } 10321 } 10322 add_node_error(irb->codegen, node, 10323 buf_sprintf("invalid left-hand side to assignment")); 10324 return irb->codegen->invalid_inst_src; 10325 10326 10327 // can be assigned to 10328 case NodeTypeUnwrapOptional: 10329 case NodeTypePtrDeref: 10330 case NodeTypeFieldAccessExpr: 10331 case NodeTypeArrayAccessExpr: 10332 case NodeTypeSymbol: 10333 break; 10334 } 10335 } 10336 if (result_loc == nullptr) { 10337 // Create a result location indicating there is none - but if one gets created 10338 // it will be properly distributed. 10339 result_loc = no_result_loc(); 10340 ir_build_reset_result(irb, scope, node, result_loc); 10341 } 10342 Scope *child_scope; 10343 if (irb->exec->is_inline || 10344 (irb->exec->fn_entry != nullptr && irb->exec->fn_entry->child_scope == scope)) 10345 { 10346 child_scope = scope; 10347 } else { 10348 child_scope = &create_expr_scope(irb->codegen, node, scope)->base; 10349 } 10350 IrInstSrc *result = ir_gen_node_raw(irb, node, child_scope, lval, result_loc); 10351 if (result == irb->codegen->invalid_inst_src) { 10352 if (irb->exec->first_err_trace_msg == nullptr) { 10353 irb->exec->first_err_trace_msg = irb->codegen->trace_err; 10354 } 10355 } 10356 return result; 10357 } 10358 10359 static IrInstSrc *ir_gen_node(IrBuilderSrc *irb, AstNode *node, Scope *scope) { 10360 return ir_gen_node_extra(irb, node, scope, LValNone, nullptr); 10361 } 10362 10363 static void invalidate_exec(IrExecutableSrc *exec, ErrorMsg *msg) { 10364 if (exec->first_err_trace_msg != nullptr) 10365 return; 10366 10367 exec->first_err_trace_msg = msg; 10368 10369 for (size_t i = 0; i < exec->tld_list.length; i += 1) { 10370 exec->tld_list.items[i]->resolution = TldResolutionInvalid; 10371 } 10372 } 10373 10374 static void invalidate_exec_gen(IrExecutableGen *exec, ErrorMsg *msg) { 10375 if (exec->first_err_trace_msg != nullptr) 10376 return; 10377 10378 exec->first_err_trace_msg = msg; 10379 10380 for (size_t i = 0; i < exec->tld_list.length; i += 1) { 10381 exec->tld_list.items[i]->resolution = TldResolutionInvalid; 10382 } 10383 10384 if (exec->source_exec != nullptr) 10385 invalidate_exec(exec->source_exec, msg); 10386 } 10387 10388 10389 bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutableSrc *ir_executable) { 10390 assert(node->owner); 10391 10392 IrBuilderSrc ir_builder = {0}; 10393 IrBuilderSrc *irb = &ir_builder; 10394 10395 irb->codegen = codegen; 10396 irb->exec = ir_executable; 10397 irb->main_block_node = node; 10398 10399 IrBasicBlockSrc *entry_block = ir_create_basic_block(irb, scope, "Entry"); 10400 ir_set_cursor_at_end_and_append_block(irb, entry_block); 10401 // Entry block gets a reference because we enter it to begin. 10402 ir_ref_bb(irb->current_basic_block); 10403 10404 IrInstSrc *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); 10405 10406 if (result == irb->codegen->invalid_inst_src) 10407 return false; 10408 10409 if (irb->exec->first_err_trace_msg != nullptr) { 10410 codegen->trace_err = irb->exec->first_err_trace_msg; 10411 return false; 10412 } 10413 10414 if (!instr_is_unreachable(result)) { 10415 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->base.source_node, result, nullptr)); 10416 // no need for save_err_ret_addr because this cannot return error 10417 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>(); 10418 result_loc_ret->base.id = ResultLocIdReturn; 10419 ir_build_reset_result(irb, scope, node, &result_loc_ret->base); 10420 ir_mark_gen(ir_build_end_expr(irb, scope, node, result, &result_loc_ret->base)); 10421 ir_mark_gen(ir_build_return_src(irb, scope, result->base.source_node, result)); 10422 } 10423 10424 return true; 10425 } 10426 10427 bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) { 10428 assert(fn_entry); 10429 10430 IrExecutableSrc *ir_executable = fn_entry->ir_executable; 10431 AstNode *body_node = fn_entry->body_node; 10432 10433 assert(fn_entry->child_scope); 10434 10435 return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable); 10436 } 10437 10438 static void ir_add_call_stack_errors_gen(CodeGen *codegen, IrExecutableGen *exec, ErrorMsg *err_msg, int limit) { 10439 if (!exec || !exec->source_node || limit < 0) return; 10440 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); 10441 10442 ir_add_call_stack_errors_gen(codegen, exec->parent_exec, err_msg, limit - 1); 10443 } 10444 10445 static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutableSrc *exec, ErrorMsg *err_msg, int limit) { 10446 if (!exec || !exec->source_node || limit < 0) return; 10447 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); 10448 10449 ir_add_call_stack_errors_gen(codegen, exec->parent_exec, err_msg, limit - 1); 10450 } 10451 10452 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutableSrc *exec, AstNode *source_node, Buf *msg) { 10453 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); 10454 invalidate_exec(exec, err_msg); 10455 if (exec->parent_exec) { 10456 ir_add_call_stack_errors(codegen, exec, err_msg, 10); 10457 } 10458 return err_msg; 10459 } 10460 10461 static ErrorMsg *exec_add_error_node_gen(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, Buf *msg) { 10462 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); 10463 invalidate_exec_gen(exec, err_msg); 10464 if (exec->parent_exec) { 10465 ir_add_call_stack_errors_gen(codegen, exec, err_msg, 10); 10466 } 10467 return err_msg; 10468 } 10469 10470 static ErrorMsg *ir_add_error_node(IrAnalyze *ira, AstNode *source_node, Buf *msg) { 10471 return exec_add_error_node_gen(ira->codegen, ira->new_irb.exec, source_node, msg); 10472 } 10473 10474 static ErrorMsg *opt_ir_add_error_node(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, Buf *msg) { 10475 if (ira != nullptr) 10476 return exec_add_error_node_gen(codegen, ira->new_irb.exec, source_node, msg); 10477 else 10478 return add_node_error(codegen, source_node, msg); 10479 } 10480 10481 static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInst *source_instruction, Buf *msg) { 10482 return ir_add_error_node(ira, source_instruction->source_node, msg); 10483 } 10484 10485 static void ir_assert_impl(bool ok, IrInst *source_instruction, char const *file, unsigned int line) { 10486 if (ok) return; 10487 src_assert_impl(ok, source_instruction->source_node, file, line); 10488 } 10489 10490 static void ir_assert_gen_impl(bool ok, IrInstGen *source_instruction, char const *file, unsigned int line) { 10491 if (ok) return; 10492 src_assert_impl(ok, source_instruction->base.source_node, file, line); 10493 } 10494 10495 // This function takes a comptime ptr and makes the child const value conform to the type 10496 // described by the pointer. 10497 static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 10498 ZigValue *ptr_val) 10499 { 10500 Error err; 10501 assert(ptr_val->type->id == ZigTypeIdPointer); 10502 assert(ptr_val->special == ConstValSpecialStatic); 10503 ZigValue tmp = {}; 10504 tmp.special = ConstValSpecialStatic; 10505 tmp.type = ptr_val->type->data.pointer.child_type; 10506 if ((err = ir_read_const_ptr(ira, codegen, source_node, &tmp, ptr_val))) 10507 return err; 10508 ZigValue *child_val = const_ptr_pointee_unchecked(codegen, ptr_val); 10509 copy_const_val(codegen, child_val, &tmp); 10510 return ErrorNone; 10511 } 10512 10513 ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val, 10514 AstNode *source_node) 10515 { 10516 Error err; 10517 ZigValue *val = const_ptr_pointee_unchecked(codegen, const_val); 10518 if (val == nullptr) return nullptr; 10519 assert(const_val->type->id == ZigTypeIdPointer); 10520 ZigType *expected_type = const_val->type->data.pointer.child_type; 10521 if (expected_type == codegen->builtin_types.entry_anytype) { 10522 return val; 10523 } 10524 switch (type_has_one_possible_value(codegen, expected_type)) { 10525 case OnePossibleValueInvalid: 10526 return nullptr; 10527 case OnePossibleValueNo: 10528 break; 10529 case OnePossibleValueYes: 10530 return get_the_one_possible_value(codegen, expected_type); 10531 } 10532 if (!types_have_same_zig_comptime_repr(codegen, expected_type, val->type)) { 10533 if ((err = eval_comptime_ptr_reinterpret(ira, codegen, source_node, const_val))) 10534 return nullptr; 10535 return const_ptr_pointee_unchecked(codegen, const_val); 10536 } 10537 return val; 10538 } 10539 10540 static Error ir_exec_scan_for_side_effects(CodeGen *codegen, IrExecutableGen *exec) { 10541 IrBasicBlockGen *bb = exec->basic_block_list.at(0); 10542 for (size_t i = 0; i < bb->instruction_list.length; i += 1) { 10543 IrInstGen *instruction = bb->instruction_list.at(i); 10544 if (instruction->id == IrInstGenIdReturn) { 10545 return ErrorNone; 10546 } else if (ir_inst_gen_has_side_effects(instruction)) { 10547 if (instr_is_comptime(instruction)) { 10548 switch (instruction->id) { 10549 case IrInstGenIdUnwrapErrPayload: 10550 case IrInstGenIdOptionalUnwrapPtr: 10551 case IrInstGenIdUnionFieldPtr: 10552 continue; 10553 default: 10554 break; 10555 } 10556 } 10557 if (get_scope_typeof(instruction->base.scope) != nullptr) { 10558 // doesn't count, it's inside a @TypeOf() 10559 continue; 10560 } 10561 exec_add_error_node_gen(codegen, exec, instruction->base.source_node, 10562 buf_sprintf("unable to evaluate constant expression")); 10563 return ErrorSemanticAnalyzeFail; 10564 } 10565 } 10566 zig_unreachable(); 10567 } 10568 10569 static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInst* source_instruction) { 10570 if (ir_should_inline(ira->old_irb.exec, source_instruction->scope)) { 10571 ir_add_error(ira, source_instruction, buf_sprintf("unable to evaluate constant expression")); 10572 return false; 10573 } 10574 return true; 10575 } 10576 10577 static bool const_val_fits_in_num_lit(ZigValue *const_val, ZigType *num_lit_type) { 10578 return ((num_lit_type->id == ZigTypeIdComptimeFloat && 10579 (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat)) || 10580 (num_lit_type->id == ZigTypeIdComptimeInt && 10581 (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt))); 10582 } 10583 10584 static bool float_has_fraction(ZigValue *const_val) { 10585 if (const_val->type->id == ZigTypeIdComptimeFloat) { 10586 return bigfloat_has_fraction(&const_val->data.x_bigfloat); 10587 } else if (const_val->type->id == ZigTypeIdFloat) { 10588 switch (const_val->type->data.floating.bit_count) { 10589 case 16: 10590 { 10591 float16_t floored = f16_roundToInt(const_val->data.x_f16, softfloat_round_minMag, false); 10592 return !f16_eq(floored, const_val->data.x_f16); 10593 } 10594 case 32: 10595 return floorf(const_val->data.x_f32) != const_val->data.x_f32; 10596 case 64: 10597 return floor(const_val->data.x_f64) != const_val->data.x_f64; 10598 case 128: 10599 { 10600 float128_t floored; 10601 f128M_roundToInt(&const_val->data.x_f128, softfloat_round_minMag, false, &floored); 10602 return !f128M_eq(&floored, &const_val->data.x_f128); 10603 } 10604 default: 10605 zig_unreachable(); 10606 } 10607 } else { 10608 zig_unreachable(); 10609 } 10610 } 10611 10612 static void float_append_buf(Buf *buf, ZigValue *const_val) { 10613 if (const_val->type->id == ZigTypeIdComptimeFloat) { 10614 bigfloat_append_buf(buf, &const_val->data.x_bigfloat); 10615 } else if (const_val->type->id == ZigTypeIdFloat) { 10616 switch (const_val->type->data.floating.bit_count) { 10617 case 16: 10618 buf_appendf(buf, "%f", zig_f16_to_double(const_val->data.x_f16)); 10619 break; 10620 case 32: 10621 buf_appendf(buf, "%f", const_val->data.x_f32); 10622 break; 10623 case 64: 10624 buf_appendf(buf, "%f", const_val->data.x_f64); 10625 break; 10626 case 128: 10627 { 10628 // TODO actual implementation 10629 const size_t extra_len = 100; 10630 size_t old_len = buf_len(buf); 10631 buf_resize(buf, old_len + extra_len); 10632 10633 float64_t f64_value = f128M_to_f64(&const_val->data.x_f128); 10634 double double_value; 10635 memcpy(&double_value, &f64_value, sizeof(double)); 10636 10637 int len = snprintf(buf_ptr(buf) + old_len, extra_len, "%f", double_value); 10638 assert(len > 0); 10639 buf_resize(buf, old_len + len); 10640 break; 10641 } 10642 default: 10643 zig_unreachable(); 10644 } 10645 } else { 10646 zig_unreachable(); 10647 } 10648 } 10649 10650 static void float_init_bigint(BigInt *bigint, ZigValue *const_val) { 10651 if (const_val->type->id == ZigTypeIdComptimeFloat) { 10652 bigint_init_bigfloat(bigint, &const_val->data.x_bigfloat); 10653 } else if (const_val->type->id == ZigTypeIdFloat) { 10654 switch (const_val->type->data.floating.bit_count) { 10655 case 16: 10656 { 10657 double x = zig_f16_to_double(const_val->data.x_f16); 10658 if (x >= 0) { 10659 bigint_init_unsigned(bigint, (uint64_t)x); 10660 } else { 10661 bigint_init_unsigned(bigint, (uint64_t)-x); 10662 bigint->is_negative = true; 10663 } 10664 break; 10665 } 10666 case 32: 10667 if (const_val->data.x_f32 >= 0) { 10668 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f32)); 10669 } else { 10670 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f32)); 10671 bigint->is_negative = true; 10672 } 10673 break; 10674 case 64: 10675 if (const_val->data.x_f64 >= 0) { 10676 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f64)); 10677 } else { 10678 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f64)); 10679 bigint->is_negative = true; 10680 } 10681 break; 10682 case 128: 10683 { 10684 BigFloat tmp_float; 10685 bigfloat_init_128(&tmp_float, const_val->data.x_f128); 10686 bigint_init_bigfloat(bigint, &tmp_float); 10687 } 10688 break; 10689 default: 10690 zig_unreachable(); 10691 } 10692 } else { 10693 zig_unreachable(); 10694 } 10695 } 10696 10697 static void float_init_bigfloat(ZigValue *dest_val, BigFloat *bigfloat) { 10698 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10699 bigfloat_init_bigfloat(&dest_val->data.x_bigfloat, bigfloat); 10700 } else if (dest_val->type->id == ZigTypeIdFloat) { 10701 switch (dest_val->type->data.floating.bit_count) { 10702 case 16: 10703 dest_val->data.x_f16 = bigfloat_to_f16(bigfloat); 10704 break; 10705 case 32: 10706 dest_val->data.x_f32 = bigfloat_to_f32(bigfloat); 10707 break; 10708 case 64: 10709 dest_val->data.x_f64 = bigfloat_to_f64(bigfloat); 10710 break; 10711 case 80: 10712 zig_panic("TODO"); 10713 case 128: 10714 dest_val->data.x_f128 = bigfloat_to_f128(bigfloat); 10715 break; 10716 default: 10717 zig_unreachable(); 10718 } 10719 } else { 10720 zig_unreachable(); 10721 } 10722 } 10723 10724 static void float_init_f16(ZigValue *dest_val, float16_t x) { 10725 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10726 bigfloat_init_16(&dest_val->data.x_bigfloat, x); 10727 } else if (dest_val->type->id == ZigTypeIdFloat) { 10728 switch (dest_val->type->data.floating.bit_count) { 10729 case 16: 10730 dest_val->data.x_f16 = x; 10731 break; 10732 case 32: 10733 dest_val->data.x_f32 = zig_f16_to_double(x); 10734 break; 10735 case 64: 10736 dest_val->data.x_f64 = zig_f16_to_double(x); 10737 break; 10738 case 128: 10739 f16_to_f128M(x, &dest_val->data.x_f128); 10740 break; 10741 default: 10742 zig_unreachable(); 10743 } 10744 } else { 10745 zig_unreachable(); 10746 } 10747 } 10748 10749 static void float_init_f32(ZigValue *dest_val, float x) { 10750 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10751 bigfloat_init_32(&dest_val->data.x_bigfloat, x); 10752 } else if (dest_val->type->id == ZigTypeIdFloat) { 10753 switch (dest_val->type->data.floating.bit_count) { 10754 case 16: 10755 dest_val->data.x_f16 = zig_double_to_f16(x); 10756 break; 10757 case 32: 10758 dest_val->data.x_f32 = x; 10759 break; 10760 case 64: 10761 dest_val->data.x_f64 = x; 10762 break; 10763 case 128: 10764 { 10765 float32_t x_f32; 10766 memcpy(&x_f32, &x, sizeof(float)); 10767 f32_to_f128M(x_f32, &dest_val->data.x_f128); 10768 break; 10769 } 10770 default: 10771 zig_unreachable(); 10772 } 10773 } else { 10774 zig_unreachable(); 10775 } 10776 } 10777 10778 static void float_init_f64(ZigValue *dest_val, double x) { 10779 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10780 bigfloat_init_64(&dest_val->data.x_bigfloat, x); 10781 } else if (dest_val->type->id == ZigTypeIdFloat) { 10782 switch (dest_val->type->data.floating.bit_count) { 10783 case 16: 10784 dest_val->data.x_f16 = zig_double_to_f16(x); 10785 break; 10786 case 32: 10787 dest_val->data.x_f32 = x; 10788 break; 10789 case 64: 10790 dest_val->data.x_f64 = x; 10791 break; 10792 case 128: 10793 { 10794 float64_t x_f64; 10795 memcpy(&x_f64, &x, sizeof(double)); 10796 f64_to_f128M(x_f64, &dest_val->data.x_f128); 10797 break; 10798 } 10799 default: 10800 zig_unreachable(); 10801 } 10802 } else { 10803 zig_unreachable(); 10804 } 10805 } 10806 10807 static void float_init_f128(ZigValue *dest_val, float128_t x) { 10808 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10809 bigfloat_init_128(&dest_val->data.x_bigfloat, x); 10810 } else if (dest_val->type->id == ZigTypeIdFloat) { 10811 switch (dest_val->type->data.floating.bit_count) { 10812 case 16: 10813 dest_val->data.x_f16 = f128M_to_f16(&x); 10814 break; 10815 case 32: 10816 { 10817 float32_t f32_val = f128M_to_f32(&x); 10818 memcpy(&dest_val->data.x_f32, &f32_val, sizeof(float)); 10819 break; 10820 } 10821 case 64: 10822 { 10823 float64_t f64_val = f128M_to_f64(&x); 10824 memcpy(&dest_val->data.x_f64, &f64_val, sizeof(double)); 10825 break; 10826 } 10827 case 128: 10828 { 10829 memcpy(&dest_val->data.x_f128, &x, sizeof(float128_t)); 10830 break; 10831 } 10832 default: 10833 zig_unreachable(); 10834 } 10835 } else { 10836 zig_unreachable(); 10837 } 10838 } 10839 10840 static void float_init_float(ZigValue *dest_val, ZigValue *src_val) { 10841 if (src_val->type->id == ZigTypeIdComptimeFloat) { 10842 float_init_bigfloat(dest_val, &src_val->data.x_bigfloat); 10843 } else if (src_val->type->id == ZigTypeIdFloat) { 10844 switch (src_val->type->data.floating.bit_count) { 10845 case 16: 10846 float_init_f16(dest_val, src_val->data.x_f16); 10847 break; 10848 case 32: 10849 float_init_f32(dest_val, src_val->data.x_f32); 10850 break; 10851 case 64: 10852 float_init_f64(dest_val, src_val->data.x_f64); 10853 break; 10854 case 128: 10855 float_init_f128(dest_val, src_val->data.x_f128); 10856 break; 10857 default: 10858 zig_unreachable(); 10859 } 10860 } else { 10861 zig_unreachable(); 10862 } 10863 } 10864 10865 static bool float_is_nan(ZigValue *op) { 10866 if (op->type->id == ZigTypeIdComptimeFloat) { 10867 return bigfloat_is_nan(&op->data.x_bigfloat); 10868 } else if (op->type->id == ZigTypeIdFloat) { 10869 switch (op->type->data.floating.bit_count) { 10870 case 16: 10871 return f16_isSignalingNaN(op->data.x_f16); 10872 case 32: 10873 return op->data.x_f32 != op->data.x_f32; 10874 case 64: 10875 return op->data.x_f64 != op->data.x_f64; 10876 case 128: 10877 return f128M_isSignalingNaN(&op->data.x_f128); 10878 default: 10879 zig_unreachable(); 10880 } 10881 } else { 10882 zig_unreachable(); 10883 } 10884 } 10885 10886 static Cmp float_cmp(ZigValue *op1, ZigValue *op2) { 10887 if (op1->type == op2->type) { 10888 if (op1->type->id == ZigTypeIdComptimeFloat) { 10889 return bigfloat_cmp(&op1->data.x_bigfloat, &op2->data.x_bigfloat); 10890 } else if (op1->type->id == ZigTypeIdFloat) { 10891 switch (op1->type->data.floating.bit_count) { 10892 case 16: 10893 if (f16_lt(op1->data.x_f16, op2->data.x_f16)) { 10894 return CmpLT; 10895 } else if (f16_lt(op2->data.x_f16, op1->data.x_f16)) { 10896 return CmpGT; 10897 } else { 10898 return CmpEQ; 10899 } 10900 case 32: 10901 if (op1->data.x_f32 > op2->data.x_f32) { 10902 return CmpGT; 10903 } else if (op1->data.x_f32 < op2->data.x_f32) { 10904 return CmpLT; 10905 } else { 10906 return CmpEQ; 10907 } 10908 case 64: 10909 if (op1->data.x_f64 > op2->data.x_f64) { 10910 return CmpGT; 10911 } else if (op1->data.x_f64 < op2->data.x_f64) { 10912 return CmpLT; 10913 } else { 10914 return CmpEQ; 10915 } 10916 case 128: 10917 if (f128M_lt(&op1->data.x_f128, &op2->data.x_f128)) { 10918 return CmpLT; 10919 } else if (f128M_eq(&op1->data.x_f128, &op2->data.x_f128)) { 10920 return CmpEQ; 10921 } else { 10922 return CmpGT; 10923 } 10924 default: 10925 zig_unreachable(); 10926 } 10927 } else { 10928 zig_unreachable(); 10929 } 10930 } 10931 BigFloat op1_big; 10932 BigFloat op2_big; 10933 float_init_bigfloat(op1, &op1_big); 10934 float_init_bigfloat(op2, &op2_big); 10935 return bigfloat_cmp(&op1_big, &op2_big); 10936 } 10937 10938 // This function cannot handle NaN 10939 static Cmp float_cmp_zero(ZigValue *op) { 10940 if (op->type->id == ZigTypeIdComptimeFloat) { 10941 return bigfloat_cmp_zero(&op->data.x_bigfloat); 10942 } else if (op->type->id == ZigTypeIdFloat) { 10943 switch (op->type->data.floating.bit_count) { 10944 case 16: 10945 { 10946 const float16_t zero = zig_double_to_f16(0); 10947 if (f16_lt(op->data.x_f16, zero)) { 10948 return CmpLT; 10949 } else if (f16_lt(zero, op->data.x_f16)) { 10950 return CmpGT; 10951 } else { 10952 return CmpEQ; 10953 } 10954 } 10955 case 32: 10956 if (op->data.x_f32 < 0.0) { 10957 return CmpLT; 10958 } else if (op->data.x_f32 > 0.0) { 10959 return CmpGT; 10960 } else { 10961 return CmpEQ; 10962 } 10963 case 64: 10964 if (op->data.x_f64 < 0.0) { 10965 return CmpLT; 10966 } else if (op->data.x_f64 > 0.0) { 10967 return CmpGT; 10968 } else { 10969 return CmpEQ; 10970 } 10971 case 128: 10972 float128_t zero_float; 10973 ui32_to_f128M(0, &zero_float); 10974 if (f128M_lt(&op->data.x_f128, &zero_float)) { 10975 return CmpLT; 10976 } else if (f128M_eq(&op->data.x_f128, &zero_float)) { 10977 return CmpEQ; 10978 } else { 10979 return CmpGT; 10980 } 10981 default: 10982 zig_unreachable(); 10983 } 10984 } else { 10985 zig_unreachable(); 10986 } 10987 } 10988 10989 static void float_add(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 10990 assert(op1->type == op2->type); 10991 out_val->type = op1->type; 10992 if (op1->type->id == ZigTypeIdComptimeFloat) { 10993 bigfloat_add(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 10994 } else if (op1->type->id == ZigTypeIdFloat) { 10995 switch (op1->type->data.floating.bit_count) { 10996 case 16: 10997 out_val->data.x_f16 = f16_add(op1->data.x_f16, op2->data.x_f16); 10998 return; 10999 case 32: 11000 out_val->data.x_f32 = op1->data.x_f32 + op2->data.x_f32; 11001 return; 11002 case 64: 11003 out_val->data.x_f64 = op1->data.x_f64 + op2->data.x_f64; 11004 return; 11005 case 128: 11006 f128M_add(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11007 return; 11008 default: 11009 zig_unreachable(); 11010 } 11011 } else { 11012 zig_unreachable(); 11013 } 11014 } 11015 11016 static void float_sub(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 11017 assert(op1->type == op2->type); 11018 out_val->type = op1->type; 11019 if (op1->type->id == ZigTypeIdComptimeFloat) { 11020 bigfloat_sub(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 11021 } else if (op1->type->id == ZigTypeIdFloat) { 11022 switch (op1->type->data.floating.bit_count) { 11023 case 16: 11024 out_val->data.x_f16 = f16_sub(op1->data.x_f16, op2->data.x_f16); 11025 return; 11026 case 32: 11027 out_val->data.x_f32 = op1->data.x_f32 - op2->data.x_f32; 11028 return; 11029 case 64: 11030 out_val->data.x_f64 = op1->data.x_f64 - op2->data.x_f64; 11031 return; 11032 case 128: 11033 f128M_sub(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11034 return; 11035 default: 11036 zig_unreachable(); 11037 } 11038 } else { 11039 zig_unreachable(); 11040 } 11041 } 11042 11043 static void float_mul(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 11044 assert(op1->type == op2->type); 11045 out_val->type = op1->type; 11046 if (op1->type->id == ZigTypeIdComptimeFloat) { 11047 bigfloat_mul(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 11048 } else if (op1->type->id == ZigTypeIdFloat) { 11049 switch (op1->type->data.floating.bit_count) { 11050 case 16: 11051 out_val->data.x_f16 = f16_mul(op1->data.x_f16, op2->data.x_f16); 11052 return; 11053 case 32: 11054 out_val->data.x_f32 = op1->data.x_f32 * op2->data.x_f32; 11055 return; 11056 case 64: 11057 out_val->data.x_f64 = op1->data.x_f64 * op2->data.x_f64; 11058 return; 11059 case 128: 11060 f128M_mul(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11061 return; 11062 default: 11063 zig_unreachable(); 11064 } 11065 } else { 11066 zig_unreachable(); 11067 } 11068 } 11069 11070 static void float_div(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 11071 assert(op1->type == op2->type); 11072 out_val->type = op1->type; 11073 if (op1->type->id == ZigTypeIdComptimeFloat) { 11074 bigfloat_div(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 11075 } else if (op1->type->id == ZigTypeIdFloat) { 11076 switch (op1->type->data.floating.bit_count) { 11077 case 16: 11078 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 11079 return; 11080 case 32: 11081 out_val->data.x_f32 = op1->data.x_f32 / op2->data.x_f32; 11082 return; 11083 case 64: 11084 out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64; 11085 return; 11086 case 128: 11087 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11088 return; 11089 default: 11090 zig_unreachable(); 11091 } 11092 } else { 11093 zig_unreachable(); 11094 } 11095 } 11096 11097 static void float_div_trunc(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 11098 assert(op1->type == op2->type); 11099 out_val->type = op1->type; 11100 if (op1->type->id == ZigTypeIdComptimeFloat) { 11101 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 11102 } else if (op1->type->id == ZigTypeIdFloat) { 11103 switch (op1->type->data.floating.bit_count) { 11104 case 16: 11105 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 11106 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_minMag, false); 11107 return; 11108 case 32: 11109 out_val->data.x_f32 = truncf(op1->data.x_f32 / op2->data.x_f32); 11110 return; 11111 case 64: 11112 out_val->data.x_f64 = trunc(op1->data.x_f64 / op2->data.x_f64); 11113 return; 11114 case 128: 11115 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11116 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_minMag, false, &out_val->data.x_f128); 11117 return; 11118 default: 11119 zig_unreachable(); 11120 } 11121 } else { 11122 zig_unreachable(); 11123 } 11124 } 11125 11126 static void float_div_floor(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 11127 assert(op1->type == op2->type); 11128 out_val->type = op1->type; 11129 if (op1->type->id == ZigTypeIdComptimeFloat) { 11130 bigfloat_div_floor(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 11131 } else if (op1->type->id == ZigTypeIdFloat) { 11132 switch (op1->type->data.floating.bit_count) { 11133 case 16: 11134 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 11135 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_min, false); 11136 return; 11137 case 32: 11138 out_val->data.x_f32 = floorf(op1->data.x_f32 / op2->data.x_f32); 11139 return; 11140 case 64: 11141 out_val->data.x_f64 = floor(op1->data.x_f64 / op2->data.x_f64); 11142 return; 11143 case 128: 11144 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11145 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_min, false, &out_val->data.x_f128); 11146 return; 11147 default: 11148 zig_unreachable(); 11149 } 11150 } else { 11151 zig_unreachable(); 11152 } 11153 } 11154 11155 static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 11156 assert(op1->type == op2->type); 11157 out_val->type = op1->type; 11158 if (op1->type->id == ZigTypeIdComptimeFloat) { 11159 bigfloat_rem(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 11160 } else if (op1->type->id == ZigTypeIdFloat) { 11161 switch (op1->type->data.floating.bit_count) { 11162 case 16: 11163 out_val->data.x_f16 = f16_rem(op1->data.x_f16, op2->data.x_f16); 11164 return; 11165 case 32: 11166 out_val->data.x_f32 = fmodf(op1->data.x_f32, op2->data.x_f32); 11167 return; 11168 case 64: 11169 out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64); 11170 return; 11171 case 128: 11172 f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11173 return; 11174 default: 11175 zig_unreachable(); 11176 } 11177 } else { 11178 zig_unreachable(); 11179 } 11180 } 11181 11182 // c = a - b * trunc(a / b) 11183 static float16_t zig_f16_mod(float16_t a, float16_t b) { 11184 float16_t c; 11185 c = f16_div(a, b); 11186 c = f16_roundToInt(c, softfloat_round_min, true); 11187 c = f16_mul(b, c); 11188 c = f16_sub(a, c); 11189 return c; 11190 } 11191 11192 // c = a - b * trunc(a / b) 11193 static void zig_f128M_mod(const float128_t* a, const float128_t* b, float128_t* c) { 11194 f128M_div(a, b, c); 11195 f128M_roundToInt(c, softfloat_round_min, true, c); 11196 f128M_mul(b, c, c); 11197 f128M_sub(a, c, c); 11198 } 11199 11200 static void float_mod(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 11201 assert(op1->type == op2->type); 11202 out_val->type = op1->type; 11203 if (op1->type->id == ZigTypeIdComptimeFloat) { 11204 bigfloat_mod(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 11205 } else if (op1->type->id == ZigTypeIdFloat) { 11206 switch (op1->type->data.floating.bit_count) { 11207 case 16: 11208 out_val->data.x_f16 = zig_f16_mod(op1->data.x_f16, op2->data.x_f16); 11209 return; 11210 case 32: 11211 out_val->data.x_f32 = fmodf(fmodf(op1->data.x_f32, op2->data.x_f32) + op2->data.x_f32, op2->data.x_f32); 11212 return; 11213 case 64: 11214 out_val->data.x_f64 = fmod(fmod(op1->data.x_f64, op2->data.x_f64) + op2->data.x_f64, op2->data.x_f64); 11215 return; 11216 case 128: 11217 zig_f128M_mod(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11218 return; 11219 default: 11220 zig_unreachable(); 11221 } 11222 } else { 11223 zig_unreachable(); 11224 } 11225 } 11226 11227 static void float_negate(ZigValue *out_val, ZigValue *op) { 11228 out_val->type = op->type; 11229 if (op->type->id == ZigTypeIdComptimeFloat) { 11230 bigfloat_negate(&out_val->data.x_bigfloat, &op->data.x_bigfloat); 11231 } else if (op->type->id == ZigTypeIdFloat) { 11232 switch (op->type->data.floating.bit_count) { 11233 case 16: 11234 { 11235 const float16_t zero = zig_double_to_f16(0); 11236 out_val->data.x_f16 = f16_sub(zero, op->data.x_f16); 11237 return; 11238 } 11239 case 32: 11240 out_val->data.x_f32 = -op->data.x_f32; 11241 return; 11242 case 64: 11243 out_val->data.x_f64 = -op->data.x_f64; 11244 return; 11245 case 128: 11246 float128_t zero_f128; 11247 ui32_to_f128M(0, &zero_f128); 11248 f128M_sub(&zero_f128, &op->data.x_f128, &out_val->data.x_f128); 11249 return; 11250 default: 11251 zig_unreachable(); 11252 } 11253 } else { 11254 zig_unreachable(); 11255 } 11256 } 11257 11258 void float_write_ieee597(ZigValue *op, uint8_t *buf, bool is_big_endian) { 11259 if (op->type->id != ZigTypeIdFloat) 11260 zig_unreachable(); 11261 11262 const unsigned n = op->type->data.floating.bit_count / 8; 11263 assert(n <= 16); 11264 11265 switch (op->type->data.floating.bit_count) { 11266 case 16: 11267 memcpy(buf, &op->data.x_f16, 2); 11268 break; 11269 case 32: 11270 memcpy(buf, &op->data.x_f32, 4); 11271 break; 11272 case 64: 11273 memcpy(buf, &op->data.x_f64, 8); 11274 break; 11275 case 128: 11276 memcpy(buf, &op->data.x_f128, 16); 11277 break; 11278 default: 11279 zig_unreachable(); 11280 } 11281 11282 if (is_big_endian) { 11283 // Byteswap in place if needed 11284 for (size_t i = 0; i < n / 2; i++) { 11285 uint8_t u = buf[i]; 11286 buf[i] = buf[n - 1 - i]; 11287 buf[n - 1 - i] = u; 11288 } 11289 } 11290 } 11291 11292 void float_read_ieee597(ZigValue *val, uint8_t *buf, bool is_big_endian) { 11293 if (val->type->id != ZigTypeIdFloat) 11294 zig_unreachable(); 11295 11296 const unsigned n = val->type->data.floating.bit_count / 8; 11297 assert(n <= 16); 11298 11299 uint8_t tmp[16]; 11300 uint8_t *ptr = buf; 11301 11302 if (is_big_endian) { 11303 memcpy(tmp, buf, n); 11304 11305 // Byteswap if needed 11306 for (size_t i = 0; i < n / 2; i++) { 11307 uint8_t u = tmp[i]; 11308 tmp[i] = tmp[n - 1 - i]; 11309 tmp[n - 1 - i] = u; 11310 } 11311 11312 ptr = tmp; 11313 } 11314 11315 switch (val->type->data.floating.bit_count) { 11316 case 16: 11317 memcpy(&val->data.x_f16, ptr, 2); 11318 return; 11319 case 32: 11320 memcpy(&val->data.x_f32, ptr, 4); 11321 return; 11322 case 64: 11323 memcpy(&val->data.x_f64, ptr, 8); 11324 return; 11325 case 128: 11326 memcpy(&val->data.x_f128, ptr, 16); 11327 return; 11328 default: 11329 zig_unreachable(); 11330 } 11331 } 11332 11333 static void value_to_bigfloat(BigFloat *out, ZigValue *val) { 11334 switch (val->type->id) { 11335 case ZigTypeIdInt: 11336 case ZigTypeIdComptimeInt: 11337 bigfloat_init_bigint(out, &val->data.x_bigint); 11338 return; 11339 case ZigTypeIdComptimeFloat: 11340 *out = val->data.x_bigfloat; 11341 return; 11342 case ZigTypeIdFloat: switch (val->type->data.floating.bit_count) { 11343 case 16: 11344 bigfloat_init_16(out, val->data.x_f16); 11345 return; 11346 case 32: 11347 bigfloat_init_32(out, val->data.x_f32); 11348 return; 11349 case 64: 11350 bigfloat_init_64(out, val->data.x_f64); 11351 return; 11352 case 80: 11353 zig_panic("TODO"); 11354 case 128: 11355 bigfloat_init_128(out, val->data.x_f128); 11356 return; 11357 default: 11358 zig_unreachable(); 11359 } 11360 default: 11361 zig_unreachable(); 11362 } 11363 } 11364 11365 static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstGen *instruction, ZigType *other_type, 11366 bool explicit_cast) 11367 { 11368 if (type_is_invalid(other_type)) { 11369 return false; 11370 } 11371 11372 ZigValue *const_val = ir_resolve_const(ira, instruction, LazyOkNoUndef); 11373 if (const_val == nullptr) 11374 return false; 11375 11376 if (const_val->special == ConstValSpecialLazy) { 11377 switch (const_val->data.x_lazy->id) { 11378 case LazyValueIdAlignOf: { 11379 // This is guaranteed to fit into a u29 11380 if (other_type->id == ZigTypeIdComptimeInt) 11381 return true; 11382 size_t align_bits = get_align_amt_type(ira->codegen)->data.integral.bit_count; 11383 if (other_type->id == ZigTypeIdInt && !other_type->data.integral.is_signed && 11384 other_type->data.integral.bit_count >= align_bits) 11385 { 11386 return true; 11387 } 11388 break; 11389 } 11390 case LazyValueIdSizeOf: { 11391 // This is guaranteed to fit into a usize 11392 if (other_type->id == ZigTypeIdComptimeInt) 11393 return true; 11394 size_t usize_bits = ira->codegen->builtin_types.entry_usize->data.integral.bit_count; 11395 if (other_type->id == ZigTypeIdInt && !other_type->data.integral.is_signed && 11396 other_type->data.integral.bit_count >= usize_bits) 11397 { 11398 return true; 11399 } 11400 break; 11401 } 11402 default: 11403 break; 11404 } 11405 } 11406 11407 const_val = ir_resolve_const(ira, instruction, UndefBad); 11408 if (const_val == nullptr) 11409 return false; 11410 11411 bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt); 11412 bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat); 11413 assert(const_val_is_int || const_val_is_float); 11414 11415 if (const_val_is_int && other_type->id == ZigTypeIdComptimeFloat) { 11416 return true; 11417 } 11418 if (other_type->id == ZigTypeIdFloat) { 11419 if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) { 11420 return true; 11421 } 11422 if (const_val->type->id == ZigTypeIdInt) { 11423 BigFloat tmp_bf; 11424 bigfloat_init_bigint(&tmp_bf, &const_val->data.x_bigint); 11425 BigFloat orig_bf; 11426 switch (other_type->data.floating.bit_count) { 11427 case 16: { 11428 float16_t tmp = bigfloat_to_f16(&tmp_bf); 11429 bigfloat_init_16(&orig_bf, tmp); 11430 break; 11431 } 11432 case 32: { 11433 float tmp = bigfloat_to_f32(&tmp_bf); 11434 bigfloat_init_32(&orig_bf, tmp); 11435 break; 11436 } 11437 case 64: { 11438 double tmp = bigfloat_to_f64(&tmp_bf); 11439 bigfloat_init_64(&orig_bf, tmp); 11440 break; 11441 } 11442 case 80: 11443 zig_panic("TODO"); 11444 case 128: { 11445 float128_t tmp = bigfloat_to_f128(&tmp_bf); 11446 bigfloat_init_128(&orig_bf, tmp); 11447 break; 11448 } 11449 default: 11450 zig_unreachable(); 11451 } 11452 BigInt orig_bi; 11453 bigint_init_bigfloat(&orig_bi, &orig_bf); 11454 if (bigint_cmp(&orig_bi, &const_val->data.x_bigint) == CmpEQ) { 11455 return true; 11456 } 11457 Buf *val_buf = buf_alloc(); 11458 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 11459 ir_add_error_node(ira, instruction->base.source_node, 11460 buf_sprintf("type %s cannot represent integer value %s", 11461 buf_ptr(&other_type->name), 11462 buf_ptr(val_buf))); 11463 return false; 11464 } 11465 if (other_type->data.floating.bit_count >= const_val->type->data.floating.bit_count) { 11466 return true; 11467 } 11468 switch (other_type->data.floating.bit_count) { 11469 case 16: 11470 switch (const_val->type->data.floating.bit_count) { 11471 case 32: { 11472 float16_t tmp = zig_double_to_f16(const_val->data.x_f32); 11473 float orig = zig_f16_to_double(tmp); 11474 if (const_val->data.x_f32 == orig) { 11475 return true; 11476 } 11477 break; 11478 } 11479 case 64: { 11480 float16_t tmp = zig_double_to_f16(const_val->data.x_f64); 11481 double orig = zig_f16_to_double(tmp); 11482 if (const_val->data.x_f64 == orig) { 11483 return true; 11484 } 11485 break; 11486 } 11487 case 80: 11488 zig_panic("TODO"); 11489 case 128: { 11490 float16_t tmp = f128M_to_f16(&const_val->data.x_f128); 11491 float128_t orig; 11492 f16_to_f128M(tmp, &orig); 11493 if (f128M_eq(&orig, &const_val->data.x_f128)) { 11494 return true; 11495 } 11496 break; 11497 } 11498 default: 11499 zig_unreachable(); 11500 } 11501 break; 11502 case 32: 11503 switch (const_val->type->data.floating.bit_count) { 11504 case 64: { 11505 float tmp = const_val->data.x_f64; 11506 double orig = tmp; 11507 if (const_val->data.x_f64 == orig) { 11508 return true; 11509 } 11510 break; 11511 } 11512 case 80: 11513 zig_panic("TODO"); 11514 case 128: { 11515 float32_t tmp = f128M_to_f32(&const_val->data.x_f128); 11516 float128_t orig; 11517 f32_to_f128M(tmp, &orig); 11518 if (f128M_eq(&orig, &const_val->data.x_f128)) { 11519 return true; 11520 } 11521 break; 11522 } 11523 default: 11524 zig_unreachable(); 11525 } 11526 break; 11527 case 64: 11528 switch (const_val->type->data.floating.bit_count) { 11529 case 80: 11530 zig_panic("TODO"); 11531 case 128: { 11532 float64_t tmp = f128M_to_f64(&const_val->data.x_f128); 11533 float128_t orig; 11534 f64_to_f128M(tmp, &orig); 11535 if (f128M_eq(&orig, &const_val->data.x_f128)) { 11536 return true; 11537 } 11538 break; 11539 } 11540 default: 11541 zig_unreachable(); 11542 } 11543 break; 11544 case 80: 11545 assert(const_val->type->data.floating.bit_count == 128); 11546 zig_panic("TODO"); 11547 case 128: 11548 return true; 11549 default: 11550 zig_unreachable(); 11551 } 11552 Buf *val_buf = buf_alloc(); 11553 float_append_buf(val_buf, const_val); 11554 ir_add_error_node(ira, instruction->base.source_node, 11555 buf_sprintf("cast of value %s to type '%s' loses information", 11556 buf_ptr(val_buf), 11557 buf_ptr(&other_type->name))); 11558 return false; 11559 } else if (other_type->id == ZigTypeIdInt && const_val_is_int) { 11560 if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 11561 Buf *val_buf = buf_alloc(); 11562 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 11563 ir_add_error_node(ira, instruction->base.source_node, 11564 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 11565 buf_ptr(val_buf), 11566 buf_ptr(&other_type->name))); 11567 return false; 11568 } 11569 if (bigint_fits_in_bits(&const_val->data.x_bigint, other_type->data.integral.bit_count, 11570 other_type->data.integral.is_signed)) 11571 { 11572 return true; 11573 } 11574 } else if (const_val_fits_in_num_lit(const_val, other_type)) { 11575 return true; 11576 } else if (other_type->id == ZigTypeIdOptional) { 11577 ZigType *child_type = other_type->data.maybe.child_type; 11578 if (const_val_fits_in_num_lit(const_val, child_type)) { 11579 return true; 11580 } else if (child_type->id == ZigTypeIdInt && const_val_is_int) { 11581 if (!child_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 11582 Buf *val_buf = buf_alloc(); 11583 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 11584 ir_add_error_node(ira, instruction->base.source_node, 11585 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 11586 buf_ptr(val_buf), 11587 buf_ptr(&child_type->name))); 11588 return false; 11589 } 11590 if (bigint_fits_in_bits(&const_val->data.x_bigint, 11591 child_type->data.integral.bit_count, 11592 child_type->data.integral.is_signed)) 11593 { 11594 return true; 11595 } 11596 } else if (child_type->id == ZigTypeIdFloat && const_val_is_float) { 11597 return true; 11598 } 11599 } 11600 if (explicit_cast && (other_type->id == ZigTypeIdInt || other_type->id == ZigTypeIdComptimeInt) && 11601 const_val_is_float) 11602 { 11603 if (float_has_fraction(const_val)) { 11604 Buf *val_buf = buf_alloc(); 11605 float_append_buf(val_buf, const_val); 11606 11607 ir_add_error_node(ira, instruction->base.source_node, 11608 buf_sprintf("fractional component prevents float value %s from being casted to type '%s'", 11609 buf_ptr(val_buf), 11610 buf_ptr(&other_type->name))); 11611 return false; 11612 } else { 11613 if (other_type->id == ZigTypeIdComptimeInt) { 11614 return true; 11615 } else { 11616 BigInt bigint; 11617 float_init_bigint(&bigint, const_val); 11618 if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count, 11619 other_type->data.integral.is_signed)) 11620 { 11621 return true; 11622 } 11623 } 11624 } 11625 } 11626 11627 const char *num_lit_str; 11628 Buf *val_buf = buf_alloc(); 11629 if (const_val_is_float) { 11630 num_lit_str = "float"; 11631 float_append_buf(val_buf, const_val); 11632 } else { 11633 num_lit_str = "integer"; 11634 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 11635 } 11636 11637 ir_add_error_node(ira, instruction->base.source_node, 11638 buf_sprintf("%s value %s cannot be coerced to type '%s'", 11639 num_lit_str, 11640 buf_ptr(val_buf), 11641 buf_ptr(&other_type->name))); 11642 return false; 11643 } 11644 11645 static bool is_tagged_union(ZigType *type) { 11646 if (type->id != ZigTypeIdUnion) 11647 return false; 11648 return (type->data.unionation.decl_node->data.container_decl.auto_enum || 11649 type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr); 11650 } 11651 11652 static void populate_error_set_table(ErrorTableEntry **errors, ZigType *set) { 11653 assert(set->id == ZigTypeIdErrorSet); 11654 for (uint32_t i = 0; i < set->data.error_set.err_count; i += 1) { 11655 ErrorTableEntry *error_entry = set->data.error_set.errors[i]; 11656 assert(errors[error_entry->value] == nullptr); 11657 errors[error_entry->value] = error_entry; 11658 } 11659 } 11660 11661 static ErrorTableEntry *better_documented_error(ErrorTableEntry *preferred, ErrorTableEntry *other) { 11662 if (preferred->decl_node->type == NodeTypeErrorSetField) 11663 return preferred; 11664 if (other->decl_node->type == NodeTypeErrorSetField) 11665 return other; 11666 return preferred; 11667 } 11668 11669 static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigType *set2, 11670 AstNode *source_node) 11671 { 11672 assert(set1->id == ZigTypeIdErrorSet); 11673 assert(set2->id == ZigTypeIdErrorSet); 11674 11675 if (!resolve_inferred_error_set(ira->codegen, set1, source_node)) { 11676 return ira->codegen->builtin_types.entry_invalid; 11677 } 11678 if (!resolve_inferred_error_set(ira->codegen, set2, source_node)) { 11679 return ira->codegen->builtin_types.entry_invalid; 11680 } 11681 if (type_is_global_error_set(set1)) { 11682 return set2; 11683 } 11684 if (type_is_global_error_set(set2)) { 11685 return set1; 11686 } 11687 size_t errors_count = ira->codegen->errors_by_index.length; 11688 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count); 11689 populate_error_set_table(errors, set1); 11690 ZigList<ErrorTableEntry *> intersection_list = {}; 11691 11692 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 11693 buf_resize(&err_set_type->name, 0); 11694 buf_appendf(&err_set_type->name, "error{"); 11695 11696 bool need_comma = false; 11697 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 11698 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 11699 ErrorTableEntry *existing_entry = errors[error_entry->value]; 11700 if (existing_entry != nullptr) { 11701 // prefer the one with docs 11702 const char *comma = need_comma ? "," : ""; 11703 need_comma = true; 11704 ErrorTableEntry *existing_entry_with_docs = better_documented_error(existing_entry, error_entry); 11705 intersection_list.append(existing_entry_with_docs); 11706 buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&existing_entry_with_docs->name)); 11707 } 11708 } 11709 heap::c_allocator.deallocate(errors, errors_count); 11710 11711 err_set_type->data.error_set.err_count = intersection_list.length; 11712 err_set_type->data.error_set.errors = intersection_list.items; 11713 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 11714 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 11715 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 11716 11717 buf_appendf(&err_set_type->name, "}"); 11718 11719 return err_set_type; 11720 } 11721 11722 static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted_type, 11723 ZigType *actual_type, AstNode *source_node, bool wanted_is_mutable) 11724 { 11725 CodeGen *g = ira->codegen; 11726 ConstCastOnly result = {}; 11727 result.id = ConstCastResultIdOk; 11728 11729 Error err; 11730 11731 if (wanted_type == actual_type) 11732 return result; 11733 11734 // If pointers have the same representation in memory, they can be "const-casted". 11735 // `const` attribute can be gained 11736 // `volatile` attribute can be gained 11737 // `allowzero` attribute can be gained (whether from explicit attribute, C pointer, or optional pointer) 11738 // but only if !wanted_is_mutable 11739 // alignment can be decreased 11740 // bit offset attributes must match exactly 11741 // PtrLenSingle/PtrLenUnknown must match exactly, but PtrLenC matches either one 11742 // sentinel-terminated pointers can coerce into PtrLenUnknown 11743 ZigType *wanted_ptr_type = get_src_ptr_type(wanted_type); 11744 ZigType *actual_ptr_type = get_src_ptr_type(actual_type); 11745 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); 11746 bool actual_allows_zero = ptr_allows_addr_zero(actual_type); 11747 bool wanted_is_c_ptr = wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC; 11748 bool actual_is_c_ptr = actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenC; 11749 bool wanted_opt_or_ptr = wanted_ptr_type != nullptr && wanted_ptr_type->id == ZigTypeIdPointer; 11750 bool actual_opt_or_ptr = actual_ptr_type != nullptr && actual_ptr_type->id == ZigTypeIdPointer; 11751 if (wanted_opt_or_ptr && actual_opt_or_ptr) { 11752 bool ok_null_term_ptrs = 11753 wanted_ptr_type->data.pointer.sentinel == nullptr || 11754 (actual_ptr_type->data.pointer.sentinel != nullptr && 11755 const_values_equal(ira->codegen, wanted_ptr_type->data.pointer.sentinel, 11756 actual_ptr_type->data.pointer.sentinel)) || 11757 actual_ptr_type->data.pointer.ptr_len == PtrLenC; 11758 if (!ok_null_term_ptrs) { 11759 result.id = ConstCastResultIdPtrSentinel; 11760 result.data.bad_ptr_sentinel = heap::c_allocator.allocate_nonzero<ConstCastPtrSentinel>(1); 11761 result.data.bad_ptr_sentinel->wanted_type = wanted_ptr_type; 11762 result.data.bad_ptr_sentinel->actual_type = actual_ptr_type; 11763 return result; 11764 } 11765 bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len; 11766 if (!(ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr)) { 11767 result.id = ConstCastResultIdPtrLens; 11768 return result; 11769 } 11770 11771 bool ok_cv_qualifiers = 11772 (!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 11773 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile); 11774 if (!ok_cv_qualifiers) { 11775 result.id = ConstCastResultIdCV; 11776 result.data.bad_cv = heap::c_allocator.allocate_nonzero<ConstCastBadCV>(1); 11777 result.data.bad_cv->wanted_type = wanted_ptr_type; 11778 result.data.bad_cv->actual_type = actual_ptr_type; 11779 return result; 11780 } 11781 11782 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 11783 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 11784 if (child.id == ConstCastResultIdInvalid) 11785 return child; 11786 if (child.id != ConstCastResultIdOk) { 11787 result.id = ConstCastResultIdPointerChild; 11788 result.data.pointer_mismatch = heap::c_allocator.allocate_nonzero<ConstCastPointerMismatch>(1); 11789 result.data.pointer_mismatch->child = child; 11790 result.data.pointer_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 11791 result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 11792 return result; 11793 } 11794 bool ok_allows_zero = (wanted_allows_zero && 11795 (actual_allows_zero || !wanted_is_mutable)) || 11796 (!wanted_allows_zero && !actual_allows_zero); 11797 if (!ok_allows_zero) { 11798 result.id = ConstCastResultIdBadAllowsZero; 11799 result.data.bad_allows_zero = heap::c_allocator.allocate_nonzero<ConstCastBadAllowsZero>(1); 11800 result.data.bad_allows_zero->wanted_type = wanted_type; 11801 result.data.bad_allows_zero->actual_type = actual_type; 11802 return result; 11803 } 11804 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 11805 result.id = ConstCastResultIdInvalid; 11806 return result; 11807 } 11808 if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 11809 result.id = ConstCastResultIdInvalid; 11810 return result; 11811 } 11812 if ((err = type_resolve(g, wanted_type, ResolveStatusZeroBitsKnown))) { 11813 result.id = ConstCastResultIdInvalid; 11814 return result; 11815 } 11816 if ((err = type_resolve(g, actual_type, ResolveStatusZeroBitsKnown))) { 11817 result.id = ConstCastResultIdInvalid; 11818 return result; 11819 } 11820 if (type_has_bits(g, wanted_type) == type_has_bits(g, actual_type) && 11821 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && 11822 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && 11823 get_ptr_align(ira->codegen, actual_ptr_type) >= get_ptr_align(ira->codegen, wanted_ptr_type)) 11824 { 11825 return result; 11826 } 11827 } 11828 11829 // arrays 11830 if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdArray && 11831 wanted_type->data.array.len == actual_type->data.array.len) 11832 { 11833 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.array.child_type, 11834 actual_type->data.array.child_type, source_node, wanted_is_mutable); 11835 if (child.id == ConstCastResultIdInvalid) 11836 return child; 11837 if (child.id != ConstCastResultIdOk) { 11838 result.id = ConstCastResultIdArrayChild; 11839 result.data.array_mismatch = heap::c_allocator.allocate_nonzero<ConstCastArrayMismatch>(1); 11840 result.data.array_mismatch->child = child; 11841 result.data.array_mismatch->wanted_child = wanted_type->data.array.child_type; 11842 result.data.array_mismatch->actual_child = actual_type->data.array.child_type; 11843 return result; 11844 } 11845 bool ok_null_terminated = (wanted_type->data.array.sentinel == nullptr) || 11846 (actual_type->data.array.sentinel != nullptr && 11847 const_values_equal(ira->codegen, wanted_type->data.array.sentinel, actual_type->data.array.sentinel)); 11848 if (!ok_null_terminated) { 11849 result.id = ConstCastResultIdSentinelArrays; 11850 result.data.sentinel_arrays = heap::c_allocator.allocate_nonzero<ConstCastBadNullTermArrays>(1); 11851 result.data.sentinel_arrays->child = child; 11852 result.data.sentinel_arrays->wanted_type = wanted_type; 11853 result.data.sentinel_arrays->actual_type = actual_type; 11854 return result; 11855 } 11856 return result; 11857 } 11858 11859 // slice const 11860 if (is_slice(wanted_type) && is_slice(actual_type)) { 11861 ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index]->type_entry; 11862 ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry; 11863 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 11864 result.id = ConstCastResultIdInvalid; 11865 return result; 11866 } 11867 if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 11868 result.id = ConstCastResultIdInvalid; 11869 return result; 11870 } 11871 bool ok_sentinels = 11872 wanted_ptr_type->data.pointer.sentinel == nullptr || 11873 (actual_ptr_type->data.pointer.sentinel != nullptr && 11874 const_values_equal(ira->codegen, wanted_ptr_type->data.pointer.sentinel, 11875 actual_ptr_type->data.pointer.sentinel)); 11876 if (!ok_sentinels) { 11877 result.id = ConstCastResultIdPtrSentinel; 11878 result.data.bad_ptr_sentinel = heap::c_allocator.allocate_nonzero<ConstCastPtrSentinel>(1); 11879 result.data.bad_ptr_sentinel->wanted_type = wanted_ptr_type; 11880 result.data.bad_ptr_sentinel->actual_type = actual_ptr_type; 11881 return result; 11882 } 11883 if ((!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 11884 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) && 11885 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && 11886 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && 11887 get_ptr_align(g, actual_ptr_type) >= get_ptr_align(g, wanted_ptr_type)) 11888 { 11889 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 11890 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 11891 if (child.id == ConstCastResultIdInvalid) 11892 return child; 11893 if (child.id != ConstCastResultIdOk) { 11894 result.id = ConstCastResultIdSliceChild; 11895 result.data.slice_mismatch = heap::c_allocator.allocate_nonzero<ConstCastSliceMismatch>(1); 11896 result.data.slice_mismatch->child = child; 11897 result.data.slice_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 11898 result.data.slice_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 11899 } 11900 return result; 11901 } 11902 } 11903 11904 // maybe 11905 if (wanted_type->id == ZigTypeIdOptional && actual_type->id == ZigTypeIdOptional) { 11906 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.maybe.child_type, 11907 actual_type->data.maybe.child_type, source_node, wanted_is_mutable); 11908 if (child.id == ConstCastResultIdInvalid) 11909 return child; 11910 if (child.id != ConstCastResultIdOk) { 11911 result.id = ConstCastResultIdOptionalChild; 11912 result.data.optional = heap::c_allocator.allocate_nonzero<ConstCastOptionalMismatch>(1); 11913 result.data.optional->child = child; 11914 result.data.optional->wanted_child = wanted_type->data.maybe.child_type; 11915 result.data.optional->actual_child = actual_type->data.maybe.child_type; 11916 } 11917 return result; 11918 } 11919 11920 // error union 11921 if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id == ZigTypeIdErrorUnion) { 11922 ConstCastOnly payload_child = types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, 11923 actual_type->data.error_union.payload_type, source_node, wanted_is_mutable); 11924 if (payload_child.id == ConstCastResultIdInvalid) 11925 return payload_child; 11926 if (payload_child.id != ConstCastResultIdOk) { 11927 result.id = ConstCastResultIdErrorUnionPayload; 11928 result.data.error_union_payload = heap::c_allocator.allocate_nonzero<ConstCastErrUnionPayloadMismatch>(1); 11929 result.data.error_union_payload->child = payload_child; 11930 result.data.error_union_payload->wanted_payload = wanted_type->data.error_union.payload_type; 11931 result.data.error_union_payload->actual_payload = actual_type->data.error_union.payload_type; 11932 return result; 11933 } 11934 ConstCastOnly error_set_child = types_match_const_cast_only(ira, wanted_type->data.error_union.err_set_type, 11935 actual_type->data.error_union.err_set_type, source_node, wanted_is_mutable); 11936 if (error_set_child.id == ConstCastResultIdInvalid) 11937 return error_set_child; 11938 if (error_set_child.id != ConstCastResultIdOk) { 11939 result.id = ConstCastResultIdErrorUnionErrorSet; 11940 result.data.error_union_error_set = heap::c_allocator.allocate_nonzero<ConstCastErrUnionErrSetMismatch>(1); 11941 result.data.error_union_error_set->child = error_set_child; 11942 result.data.error_union_error_set->wanted_err_set = wanted_type->data.error_union.err_set_type; 11943 result.data.error_union_error_set->actual_err_set = actual_type->data.error_union.err_set_type; 11944 return result; 11945 } 11946 return result; 11947 } 11948 11949 // error set 11950 if (wanted_type->id == ZigTypeIdErrorSet && actual_type->id == ZigTypeIdErrorSet) { 11951 ZigType *contained_set = actual_type; 11952 ZigType *container_set = wanted_type; 11953 11954 // if the container set is inferred, then this will always work. 11955 if (container_set->data.error_set.infer_fn != nullptr && container_set->data.error_set.incomplete) { 11956 return result; 11957 } 11958 // if the container set is the global one, it will always work. 11959 if (type_is_global_error_set(container_set)) { 11960 return result; 11961 } 11962 11963 if (!resolve_inferred_error_set(ira->codegen, contained_set, source_node)) { 11964 result.id = ConstCastResultIdUnresolvedInferredErrSet; 11965 return result; 11966 } 11967 11968 if (type_is_global_error_set(contained_set)) { 11969 result.id = ConstCastResultIdErrSetGlobal; 11970 return result; 11971 } 11972 11973 size_t errors_count = g->errors_by_index.length; 11974 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count); 11975 for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) { 11976 ErrorTableEntry *error_entry = container_set->data.error_set.errors[i]; 11977 assert(errors[error_entry->value] == nullptr); 11978 errors[error_entry->value] = error_entry; 11979 } 11980 for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) { 11981 ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i]; 11982 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 11983 if (error_entry == nullptr) { 11984 if (result.id == ConstCastResultIdOk) { 11985 result.id = ConstCastResultIdErrSet; 11986 result.data.error_set_mismatch = heap::c_allocator.create<ConstCastErrSetMismatch>(); 11987 } 11988 result.data.error_set_mismatch->missing_errors.append(contained_error_entry); 11989 } 11990 } 11991 heap::c_allocator.deallocate(errors, errors_count); 11992 return result; 11993 } 11994 11995 // fn 11996 if (wanted_type->id == ZigTypeIdFn && 11997 actual_type->id == ZigTypeIdFn) 11998 { 11999 if (wanted_type->data.fn.fn_type_id.alignment > actual_type->data.fn.fn_type_id.alignment) { 12000 result.id = ConstCastResultIdFnAlign; 12001 return result; 12002 } 12003 if (wanted_type->data.fn.fn_type_id.is_var_args != actual_type->data.fn.fn_type_id.is_var_args) { 12004 result.id = ConstCastResultIdFnVarArgs; 12005 return result; 12006 } 12007 if (wanted_type->data.fn.is_generic != actual_type->data.fn.is_generic) { 12008 result.id = ConstCastResultIdFnIsGeneric; 12009 return result; 12010 } 12011 if (!wanted_type->data.fn.is_generic && 12012 actual_type->data.fn.fn_type_id.return_type->id != ZigTypeIdUnreachable) 12013 { 12014 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.fn.fn_type_id.return_type, 12015 actual_type->data.fn.fn_type_id.return_type, source_node, false); 12016 if (child.id == ConstCastResultIdInvalid) 12017 return child; 12018 if (child.id != ConstCastResultIdOk) { 12019 result.id = ConstCastResultIdFnReturnType; 12020 result.data.return_type = heap::c_allocator.allocate_nonzero<ConstCastOnly>(1); 12021 *result.data.return_type = child; 12022 return result; 12023 } 12024 } 12025 if (wanted_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { 12026 result.id = ConstCastResultIdFnArgCount; 12027 return result; 12028 } 12029 if (wanted_type->data.fn.fn_type_id.next_param_index != actual_type->data.fn.fn_type_id.next_param_index) { 12030 result.id = ConstCastResultIdFnGenericArgCount; 12031 return result; 12032 } 12033 assert(wanted_type->data.fn.is_generic || 12034 wanted_type->data.fn.fn_type_id.next_param_index == wanted_type->data.fn.fn_type_id.param_count); 12035 for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.param_count; i += 1) { 12036 // note it's reversed for parameters 12037 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i]; 12038 FnTypeParamInfo *expected_param_info = &wanted_type->data.fn.fn_type_id.param_info[i]; 12039 12040 ConstCastOnly arg_child = types_match_const_cast_only(ira, actual_param_info->type, 12041 expected_param_info->type, source_node, false); 12042 if (arg_child.id == ConstCastResultIdInvalid) 12043 return arg_child; 12044 if (arg_child.id != ConstCastResultIdOk) { 12045 result.id = ConstCastResultIdFnArg; 12046 result.data.fn_arg.arg_index = i; 12047 result.data.fn_arg.actual_param_type = actual_param_info->type; 12048 result.data.fn_arg.expected_param_type = expected_param_info->type; 12049 result.data.fn_arg.child = heap::c_allocator.allocate_nonzero<ConstCastOnly>(1); 12050 *result.data.fn_arg.child = arg_child; 12051 return result; 12052 } 12053 12054 if (expected_param_info->is_noalias != actual_param_info->is_noalias) { 12055 result.id = ConstCastResultIdFnArgNoAlias; 12056 result.data.arg_no_alias.arg_index = i; 12057 return result; 12058 } 12059 } 12060 if (wanted_type->data.fn.fn_type_id.cc != actual_type->data.fn.fn_type_id.cc) { 12061 // ConstCastResultIdFnCC is guaranteed to be the last one reported, meaning everything else is ok. 12062 result.id = ConstCastResultIdFnCC; 12063 return result; 12064 } 12065 return result; 12066 } 12067 12068 if (wanted_type->id == ZigTypeIdInt && actual_type->id == ZigTypeIdInt) { 12069 if (wanted_type->data.integral.is_signed != actual_type->data.integral.is_signed || 12070 wanted_type->data.integral.bit_count != actual_type->data.integral.bit_count) 12071 { 12072 result.id = ConstCastResultIdIntShorten; 12073 result.data.int_shorten = heap::c_allocator.allocate_nonzero<ConstCastIntShorten>(1); 12074 result.data.int_shorten->wanted_type = wanted_type; 12075 result.data.int_shorten->actual_type = actual_type; 12076 return result; 12077 } 12078 return result; 12079 } 12080 12081 result.id = ConstCastResultIdType; 12082 result.data.type_mismatch = heap::c_allocator.allocate_nonzero<ConstCastTypeMismatch>(1); 12083 result.data.type_mismatch->wanted_type = wanted_type; 12084 result.data.type_mismatch->actual_type = actual_type; 12085 return result; 12086 } 12087 12088 static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) { 12089 size_t old_errors_count = *errors_count; 12090 *errors_count = g->errors_by_index.length; 12091 *errors = heap::c_allocator.reallocate(*errors, old_errors_count, *errors_count); 12092 } 12093 12094 static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigType *expected_type, 12095 IrInstGen **instructions, size_t instruction_count) 12096 { 12097 Error err; 12098 assert(instruction_count >= 1); 12099 IrInstGen *prev_inst; 12100 size_t i = 0; 12101 for (;;) { 12102 prev_inst = instructions[i]; 12103 if (type_is_invalid(prev_inst->value->type)) { 12104 return ira->codegen->builtin_types.entry_invalid; 12105 } 12106 if (prev_inst->value->type->id == ZigTypeIdUnreachable) { 12107 i += 1; 12108 if (i == instruction_count) { 12109 return prev_inst->value->type; 12110 } 12111 continue; 12112 } 12113 break; 12114 } 12115 ErrorTableEntry **errors = nullptr; 12116 size_t errors_count = 0; 12117 ZigType *err_set_type = nullptr; 12118 if (prev_inst->value->type->id == ZigTypeIdErrorSet) { 12119 if (!resolve_inferred_error_set(ira->codegen, prev_inst->value->type, prev_inst->base.source_node)) { 12120 return ira->codegen->builtin_types.entry_invalid; 12121 } 12122 if (type_is_global_error_set(prev_inst->value->type)) { 12123 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12124 } else { 12125 err_set_type = prev_inst->value->type; 12126 update_errors_helper(ira->codegen, &errors, &errors_count); 12127 12128 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12129 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 12130 assert(errors[error_entry->value] == nullptr); 12131 errors[error_entry->value] = error_entry; 12132 } 12133 } 12134 } 12135 12136 bool any_are_null = (prev_inst->value->type->id == ZigTypeIdNull); 12137 bool convert_to_const_slice = false; 12138 bool make_the_slice_const = false; 12139 bool make_the_pointer_const = false; 12140 for (; i < instruction_count; i += 1) { 12141 IrInstGen *cur_inst = instructions[i]; 12142 ZigType *cur_type = cur_inst->value->type; 12143 ZigType *prev_type = prev_inst->value->type; 12144 12145 if (type_is_invalid(cur_type)) { 12146 return cur_type; 12147 } 12148 12149 if (prev_type == cur_type) { 12150 continue; 12151 } 12152 12153 if (prev_type->id == ZigTypeIdUnreachable) { 12154 prev_inst = cur_inst; 12155 continue; 12156 } 12157 12158 if (cur_type->id == ZigTypeIdUnreachable) { 12159 continue; 12160 } 12161 12162 if (prev_type->id == ZigTypeIdErrorSet) { 12163 ir_assert_gen(err_set_type != nullptr, prev_inst); 12164 if (cur_type->id == ZigTypeIdErrorSet) { 12165 if (type_is_global_error_set(err_set_type)) { 12166 continue; 12167 } 12168 bool allow_infer = cur_type->data.error_set.infer_fn != nullptr && 12169 cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12170 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) { 12171 return ira->codegen->builtin_types.entry_invalid; 12172 } 12173 if (!allow_infer && type_is_global_error_set(cur_type)) { 12174 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12175 prev_inst = cur_inst; 12176 continue; 12177 } 12178 12179 // number of declared errors might have increased now 12180 update_errors_helper(ira->codegen, &errors, &errors_count); 12181 12182 // if err_set_type is a superset of cur_type, keep err_set_type. 12183 // if cur_type is a superset of err_set_type, switch err_set_type to cur_type 12184 bool prev_is_superset = true; 12185 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 12186 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 12187 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 12188 if (error_entry == nullptr) { 12189 prev_is_superset = false; 12190 break; 12191 } 12192 } 12193 if (prev_is_superset) { 12194 continue; 12195 } 12196 12197 // unset everything in errors 12198 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12199 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 12200 errors[error_entry->value] = nullptr; 12201 } 12202 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 12203 assert(errors[i] == nullptr); 12204 } 12205 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 12206 ErrorTableEntry *error_entry = cur_type->data.error_set.errors[i]; 12207 assert(errors[error_entry->value] == nullptr); 12208 errors[error_entry->value] = error_entry; 12209 } 12210 bool cur_is_superset = true; 12211 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12212 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 12213 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 12214 if (error_entry == nullptr) { 12215 cur_is_superset = false; 12216 break; 12217 } 12218 } 12219 if (cur_is_superset) { 12220 err_set_type = cur_type; 12221 prev_inst = cur_inst; 12222 assert(errors != nullptr); 12223 continue; 12224 } 12225 12226 // neither of them are supersets. so we invent a new error set type that is a union of both of them 12227 err_set_type = get_error_set_union(ira->codegen, errors, cur_type, err_set_type, nullptr); 12228 assert(errors != nullptr); 12229 continue; 12230 } else if (cur_type->id == ZigTypeIdErrorUnion) { 12231 if (type_is_global_error_set(err_set_type)) { 12232 prev_inst = cur_inst; 12233 continue; 12234 } 12235 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 12236 bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr && 12237 cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12238 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) { 12239 return ira->codegen->builtin_types.entry_invalid; 12240 } 12241 if (!allow_infer && type_is_global_error_set(cur_err_set_type)) { 12242 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12243 prev_inst = cur_inst; 12244 continue; 12245 } 12246 12247 update_errors_helper(ira->codegen, &errors, &errors_count); 12248 12249 // test if err_set_type is a subset of cur_type's error set 12250 // unset everything in errors 12251 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12252 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 12253 errors[error_entry->value] = nullptr; 12254 } 12255 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 12256 assert(errors[i] == nullptr); 12257 } 12258 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 12259 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 12260 assert(errors[error_entry->value] == nullptr); 12261 errors[error_entry->value] = error_entry; 12262 } 12263 bool cur_is_superset = true; 12264 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12265 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 12266 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 12267 if (error_entry == nullptr) { 12268 cur_is_superset = false; 12269 break; 12270 } 12271 } 12272 if (cur_is_superset) { 12273 err_set_type = cur_err_set_type; 12274 prev_inst = cur_inst; 12275 assert(errors != nullptr); 12276 continue; 12277 } 12278 12279 // not a subset. invent new error set type, union of both of them 12280 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, err_set_type, nullptr); 12281 prev_inst = cur_inst; 12282 assert(errors != nullptr); 12283 continue; 12284 } else { 12285 prev_inst = cur_inst; 12286 continue; 12287 } 12288 } 12289 12290 if (cur_type->id == ZigTypeIdErrorSet) { 12291 bool allow_infer = cur_type->data.error_set.infer_fn != nullptr && 12292 cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12293 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) { 12294 return ira->codegen->builtin_types.entry_invalid; 12295 } 12296 if (!allow_infer && type_is_global_error_set(cur_type)) { 12297 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12298 continue; 12299 } 12300 if (err_set_type != nullptr && type_is_global_error_set(err_set_type)) { 12301 continue; 12302 } 12303 12304 update_errors_helper(ira->codegen, &errors, &errors_count); 12305 12306 if (err_set_type == nullptr) { 12307 bool allow_infer = false; 12308 if (prev_type->id == ZigTypeIdErrorUnion) { 12309 err_set_type = prev_type->data.error_union.err_set_type; 12310 allow_infer = err_set_type->data.error_set.infer_fn != nullptr && 12311 err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12312 } else { 12313 err_set_type = cur_type; 12314 } 12315 12316 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, err_set_type, cur_inst->base.source_node)) { 12317 return ira->codegen->builtin_types.entry_invalid; 12318 } 12319 12320 if (!allow_infer && type_is_global_error_set(err_set_type)) { 12321 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12322 continue; 12323 } 12324 12325 update_errors_helper(ira->codegen, &errors, &errors_count); 12326 12327 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12328 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 12329 assert(errors[error_entry->value] == nullptr); 12330 errors[error_entry->value] = error_entry; 12331 } 12332 if (err_set_type == cur_type) { 12333 continue; 12334 } 12335 } 12336 // check if the cur type error set is a subset 12337 bool prev_is_superset = true; 12338 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 12339 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 12340 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 12341 if (error_entry == nullptr) { 12342 prev_is_superset = false; 12343 break; 12344 } 12345 } 12346 if (prev_is_superset) { 12347 continue; 12348 } 12349 // not a subset. invent new error set type, union of both of them 12350 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_type, nullptr); 12351 assert(errors != nullptr); 12352 continue; 12353 } 12354 12355 if (prev_type->id == ZigTypeIdErrorUnion && cur_type->id == ZigTypeIdErrorUnion) { 12356 ZigType *prev_payload_type = prev_type->data.error_union.payload_type; 12357 ZigType *cur_payload_type = cur_type->data.error_union.payload_type; 12358 12359 bool const_cast_prev = types_match_const_cast_only(ira, prev_payload_type, cur_payload_type, 12360 source_node, false).id == ConstCastResultIdOk; 12361 bool const_cast_cur = types_match_const_cast_only(ira, cur_payload_type, prev_payload_type, 12362 source_node, false).id == ConstCastResultIdOk; 12363 12364 if (const_cast_prev || const_cast_cur) { 12365 if (const_cast_cur) { 12366 prev_inst = cur_inst; 12367 } 12368 12369 ZigType *prev_err_set_type = (err_set_type == nullptr) ? prev_type->data.error_union.err_set_type : err_set_type; 12370 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 12371 if (prev_err_set_type == cur_err_set_type) 12372 continue; 12373 12374 bool allow_infer_prev = prev_err_set_type->data.error_set.infer_fn != nullptr && 12375 prev_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12376 bool allow_infer_cur = cur_err_set_type->data.error_set.infer_fn != nullptr && 12377 cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12378 12379 if (!allow_infer_prev && !resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->base.source_node)) { 12380 return ira->codegen->builtin_types.entry_invalid; 12381 } 12382 12383 if (!allow_infer_cur && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) { 12384 return ira->codegen->builtin_types.entry_invalid; 12385 } 12386 12387 if ((!allow_infer_prev && type_is_global_error_set(prev_err_set_type)) || 12388 (!allow_infer_cur && type_is_global_error_set(cur_err_set_type))) 12389 { 12390 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12391 continue; 12392 } 12393 12394 update_errors_helper(ira->codegen, &errors, &errors_count); 12395 12396 if (err_set_type == nullptr) { 12397 err_set_type = prev_err_set_type; 12398 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 12399 ErrorTableEntry *error_entry = prev_err_set_type->data.error_set.errors[i]; 12400 assert(errors[error_entry->value] == nullptr); 12401 errors[error_entry->value] = error_entry; 12402 } 12403 } 12404 bool prev_is_superset = true; 12405 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 12406 ErrorTableEntry *contained_error_entry = cur_err_set_type->data.error_set.errors[i]; 12407 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 12408 if (error_entry == nullptr) { 12409 prev_is_superset = false; 12410 break; 12411 } 12412 } 12413 if (prev_is_superset) { 12414 continue; 12415 } 12416 // unset all the errors 12417 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12418 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 12419 errors[error_entry->value] = nullptr; 12420 } 12421 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 12422 assert(errors[i] == nullptr); 12423 } 12424 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 12425 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 12426 assert(errors[error_entry->value] == nullptr); 12427 errors[error_entry->value] = error_entry; 12428 } 12429 bool cur_is_superset = true; 12430 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 12431 ErrorTableEntry *contained_error_entry = prev_err_set_type->data.error_set.errors[i]; 12432 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 12433 if (error_entry == nullptr) { 12434 cur_is_superset = false; 12435 break; 12436 } 12437 } 12438 if (cur_is_superset) { 12439 err_set_type = cur_err_set_type; 12440 continue; 12441 } 12442 12443 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, prev_err_set_type, nullptr); 12444 continue; 12445 } 12446 } 12447 12448 if (prev_type->id == ZigTypeIdNull) { 12449 prev_inst = cur_inst; 12450 any_are_null = true; 12451 continue; 12452 } 12453 12454 if (cur_type->id == ZigTypeIdNull) { 12455 any_are_null = true; 12456 continue; 12457 } 12458 12459 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdEnumLiteral) { 12460 TypeEnumField *field = find_enum_type_field(prev_type, cur_inst->value->data.x_enum_literal); 12461 if (field != nullptr) { 12462 continue; 12463 } 12464 } 12465 if (is_tagged_union(prev_type) && cur_type->id == ZigTypeIdEnumLiteral) { 12466 TypeUnionField *field = find_union_type_field(prev_type, cur_inst->value->data.x_enum_literal); 12467 if (field != nullptr) { 12468 continue; 12469 } 12470 } 12471 12472 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdEnumLiteral) { 12473 TypeEnumField *field = find_enum_type_field(cur_type, prev_inst->value->data.x_enum_literal); 12474 if (field != nullptr) { 12475 prev_inst = cur_inst; 12476 continue; 12477 } 12478 } 12479 12480 if (is_tagged_union(cur_type) && prev_type->id == ZigTypeIdEnumLiteral) { 12481 TypeUnionField *field = find_union_type_field(cur_type, prev_inst->value->data.x_enum_literal); 12482 if (field != nullptr) { 12483 prev_inst = cur_inst; 12484 continue; 12485 } 12486 } 12487 12488 if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenC && 12489 (cur_type->id == ZigTypeIdComptimeInt || cur_type->id == ZigTypeIdInt)) 12490 { 12491 continue; 12492 } 12493 12494 if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenC && 12495 (prev_type->id == ZigTypeIdComptimeInt || prev_type->id == ZigTypeIdInt)) 12496 { 12497 prev_inst = cur_inst; 12498 continue; 12499 } 12500 12501 if (prev_type->id == ZigTypeIdPointer && cur_type->id == ZigTypeIdPointer) { 12502 if (prev_type->data.pointer.ptr_len == PtrLenC && 12503 types_match_const_cast_only(ira, prev_type->data.pointer.child_type, 12504 cur_type->data.pointer.child_type, source_node, 12505 !prev_type->data.pointer.is_const).id == ConstCastResultIdOk) 12506 { 12507 continue; 12508 } 12509 if (cur_type->data.pointer.ptr_len == PtrLenC && 12510 types_match_const_cast_only(ira, cur_type->data.pointer.child_type, 12511 prev_type->data.pointer.child_type, source_node, 12512 !cur_type->data.pointer.is_const).id == ConstCastResultIdOk) 12513 { 12514 prev_inst = cur_inst; 12515 continue; 12516 } 12517 } 12518 12519 if (types_match_const_cast_only(ira, prev_type, cur_type, source_node, false).id == ConstCastResultIdOk) { 12520 continue; 12521 } 12522 12523 if (types_match_const_cast_only(ira, cur_type, prev_type, source_node, false).id == ConstCastResultIdOk) { 12524 prev_inst = cur_inst; 12525 continue; 12526 } 12527 12528 if (prev_type->id == ZigTypeIdInt && 12529 cur_type->id == ZigTypeIdInt && 12530 prev_type->data.integral.is_signed == cur_type->data.integral.is_signed) 12531 { 12532 if (cur_type->data.integral.bit_count > prev_type->data.integral.bit_count) { 12533 prev_inst = cur_inst; 12534 } 12535 continue; 12536 } 12537 12538 if (prev_type->id == ZigTypeIdFloat && cur_type->id == ZigTypeIdFloat) { 12539 if (cur_type->data.floating.bit_count > prev_type->data.floating.bit_count) { 12540 prev_inst = cur_inst; 12541 } 12542 continue; 12543 } 12544 12545 if (prev_type->id == ZigTypeIdErrorUnion && 12546 types_match_const_cast_only(ira, prev_type->data.error_union.payload_type, cur_type, 12547 source_node, false).id == ConstCastResultIdOk) 12548 { 12549 continue; 12550 } 12551 12552 if (cur_type->id == ZigTypeIdErrorUnion && 12553 types_match_const_cast_only(ira, cur_type->data.error_union.payload_type, prev_type, 12554 source_node, false).id == ConstCastResultIdOk) 12555 { 12556 if (err_set_type != nullptr) { 12557 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 12558 bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr && 12559 cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12560 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) { 12561 return ira->codegen->builtin_types.entry_invalid; 12562 } 12563 if ((!allow_infer && type_is_global_error_set(cur_err_set_type)) || 12564 type_is_global_error_set(err_set_type)) 12565 { 12566 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12567 prev_inst = cur_inst; 12568 continue; 12569 } 12570 12571 update_errors_helper(ira->codegen, &errors, &errors_count); 12572 12573 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_err_set_type, nullptr); 12574 } 12575 prev_inst = cur_inst; 12576 continue; 12577 } 12578 12579 if (prev_type->id == ZigTypeIdOptional && 12580 types_match_const_cast_only(ira, prev_type->data.maybe.child_type, cur_type, 12581 source_node, false).id == ConstCastResultIdOk) 12582 { 12583 continue; 12584 } 12585 12586 if (cur_type->id == ZigTypeIdOptional && 12587 types_match_const_cast_only(ira, cur_type->data.maybe.child_type, prev_type, 12588 source_node, false).id == ConstCastResultIdOk) 12589 { 12590 prev_inst = cur_inst; 12591 continue; 12592 } 12593 12594 if (prev_type->id == ZigTypeIdOptional && 12595 types_match_const_cast_only(ira, cur_type, prev_type->data.maybe.child_type, 12596 source_node, false).id == ConstCastResultIdOk) 12597 { 12598 prev_inst = cur_inst; 12599 any_are_null = true; 12600 continue; 12601 } 12602 12603 if (cur_type->id == ZigTypeIdOptional && 12604 types_match_const_cast_only(ira, prev_type, cur_type->data.maybe.child_type, 12605 source_node, false).id == ConstCastResultIdOk) 12606 { 12607 any_are_null = true; 12608 continue; 12609 } 12610 12611 if (cur_type->id == ZigTypeIdUndefined) { 12612 continue; 12613 } 12614 12615 if (prev_type->id == ZigTypeIdUndefined) { 12616 prev_inst = cur_inst; 12617 continue; 12618 } 12619 12620 if (prev_type->id == ZigTypeIdComptimeInt || 12621 prev_type->id == ZigTypeIdComptimeFloat) 12622 { 12623 if (ir_num_lit_fits_in_other_type(ira, prev_inst, cur_type, false)) { 12624 prev_inst = cur_inst; 12625 continue; 12626 } else { 12627 return ira->codegen->builtin_types.entry_invalid; 12628 } 12629 } 12630 12631 if (cur_type->id == ZigTypeIdComptimeInt || 12632 cur_type->id == ZigTypeIdComptimeFloat) 12633 { 12634 if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type, false)) { 12635 continue; 12636 } else { 12637 return ira->codegen->builtin_types.entry_invalid; 12638 } 12639 } 12640 12641 // *[N]T to [*]T 12642 if (prev_type->id == ZigTypeIdPointer && 12643 prev_type->data.pointer.ptr_len == PtrLenSingle && 12644 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 12645 ((cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenUnknown))) 12646 { 12647 convert_to_const_slice = false; 12648 prev_inst = cur_inst; 12649 12650 if (prev_type->data.pointer.is_const && !cur_type->data.pointer.is_const) { 12651 // const array pointer and non-const unknown pointer 12652 make_the_pointer_const = true; 12653 } 12654 continue; 12655 } 12656 12657 // *[N]T to [*]T 12658 if (cur_type->id == ZigTypeIdPointer && 12659 cur_type->data.pointer.ptr_len == PtrLenSingle && 12660 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 12661 ((prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenUnknown))) 12662 { 12663 if (cur_type->data.pointer.is_const && !prev_type->data.pointer.is_const) { 12664 // const array pointer and non-const unknown pointer 12665 make_the_pointer_const = true; 12666 } 12667 continue; 12668 } 12669 12670 // *[N]T to []T 12671 // *[N]T to E![]T 12672 if (cur_type->id == ZigTypeIdPointer && 12673 cur_type->data.pointer.ptr_len == PtrLenSingle && 12674 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 12675 ((prev_type->id == ZigTypeIdErrorUnion && is_slice(prev_type->data.error_union.payload_type)) || 12676 is_slice(prev_type))) 12677 { 12678 ZigType *array_type = cur_type->data.pointer.child_type; 12679 ZigType *slice_type = (prev_type->id == ZigTypeIdErrorUnion) ? 12680 prev_type->data.error_union.payload_type : prev_type; 12681 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 12682 if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 12683 array_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 12684 { 12685 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 || 12686 !cur_type->data.pointer.is_const); 12687 if (!const_ok) make_the_slice_const = true; 12688 convert_to_const_slice = false; 12689 continue; 12690 } 12691 } 12692 12693 // *[N]T to []T 12694 // *[N]T to E![]T 12695 if (prev_type->id == ZigTypeIdPointer && 12696 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 12697 prev_type->data.pointer.ptr_len == PtrLenSingle && 12698 ((cur_type->id == ZigTypeIdErrorUnion && is_slice(cur_type->data.error_union.payload_type)) || 12699 (cur_type->id == ZigTypeIdOptional && is_slice(cur_type->data.maybe.child_type)) || 12700 is_slice(cur_type))) 12701 { 12702 ZigType *array_type = prev_type->data.pointer.child_type; 12703 ZigType *slice_type; 12704 switch (cur_type->id) { 12705 case ZigTypeIdErrorUnion: 12706 slice_type = cur_type->data.error_union.payload_type; 12707 break; 12708 case ZigTypeIdOptional: 12709 slice_type = cur_type->data.maybe.child_type; 12710 break; 12711 default: 12712 slice_type = cur_type; 12713 break; 12714 } 12715 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 12716 if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 12717 array_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 12718 { 12719 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 || 12720 !prev_type->data.pointer.is_const); 12721 if (!const_ok) make_the_slice_const = true; 12722 prev_inst = cur_inst; 12723 convert_to_const_slice = false; 12724 continue; 12725 } 12726 } 12727 12728 // *[N]T and *[M]T 12729 if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle && 12730 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 12731 prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenSingle && 12732 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 12733 ( 12734 prev_type->data.pointer.child_type->data.array.sentinel == nullptr || 12735 (cur_type->data.pointer.child_type->data.array.sentinel != nullptr && 12736 const_values_equal(ira->codegen, prev_type->data.pointer.child_type->data.array.sentinel, 12737 cur_type->data.pointer.child_type->data.array.sentinel)) 12738 ) && 12739 types_match_const_cast_only(ira, 12740 cur_type->data.pointer.child_type->data.array.child_type, 12741 prev_type->data.pointer.child_type->data.array.child_type, 12742 source_node, !cur_type->data.pointer.is_const).id == ConstCastResultIdOk) 12743 { 12744 bool const_ok = (cur_type->data.pointer.is_const || !prev_type->data.pointer.is_const || 12745 prev_type->data.pointer.child_type->data.array.len == 0); 12746 if (!const_ok) make_the_slice_const = true; 12747 prev_inst = cur_inst; 12748 convert_to_const_slice = true; 12749 continue; 12750 } 12751 if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenSingle && 12752 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 12753 cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle && 12754 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 12755 ( 12756 cur_type->data.pointer.child_type->data.array.sentinel == nullptr || 12757 (prev_type->data.pointer.child_type->data.array.sentinel != nullptr && 12758 const_values_equal(ira->codegen, cur_type->data.pointer.child_type->data.array.sentinel, 12759 prev_type->data.pointer.child_type->data.array.sentinel)) 12760 ) && 12761 types_match_const_cast_only(ira, 12762 prev_type->data.pointer.child_type->data.array.child_type, 12763 cur_type->data.pointer.child_type->data.array.child_type, 12764 source_node, !prev_type->data.pointer.is_const).id == ConstCastResultIdOk) 12765 { 12766 bool const_ok = (prev_type->data.pointer.is_const || !cur_type->data.pointer.is_const || 12767 cur_type->data.pointer.child_type->data.array.len == 0); 12768 if (!const_ok) make_the_slice_const = true; 12769 convert_to_const_slice = true; 12770 continue; 12771 } 12772 12773 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdUnion && 12774 (cur_type->data.unionation.decl_node->data.container_decl.auto_enum || cur_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 12775 { 12776 if ((err = type_resolve(ira->codegen, cur_type, ResolveStatusZeroBitsKnown))) 12777 return ira->codegen->builtin_types.entry_invalid; 12778 if (cur_type->data.unionation.tag_type == prev_type) { 12779 continue; 12780 } 12781 } 12782 12783 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdUnion && 12784 (prev_type->data.unionation.decl_node->data.container_decl.auto_enum || prev_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 12785 { 12786 if ((err = type_resolve(ira->codegen, prev_type, ResolveStatusZeroBitsKnown))) 12787 return ira->codegen->builtin_types.entry_invalid; 12788 if (prev_type->data.unionation.tag_type == cur_type) { 12789 prev_inst = cur_inst; 12790 continue; 12791 } 12792 } 12793 12794 ErrorMsg *msg = ir_add_error_node(ira, source_node, 12795 buf_sprintf("incompatible types: '%s' and '%s'", 12796 buf_ptr(&prev_type->name), buf_ptr(&cur_type->name))); 12797 add_error_note(ira->codegen, msg, prev_inst->base.source_node, 12798 buf_sprintf("type '%s' here", buf_ptr(&prev_type->name))); 12799 add_error_note(ira->codegen, msg, cur_inst->base.source_node, 12800 buf_sprintf("type '%s' here", buf_ptr(&cur_type->name))); 12801 12802 return ira->codegen->builtin_types.entry_invalid; 12803 } 12804 12805 heap::c_allocator.deallocate(errors, errors_count); 12806 12807 if (convert_to_const_slice) { 12808 if (prev_inst->value->type->id == ZigTypeIdPointer) { 12809 ZigType *array_type = prev_inst->value->type->data.pointer.child_type; 12810 src_assert(array_type->id == ZigTypeIdArray, source_node); 12811 ZigType *ptr_type = get_pointer_to_type_extra2( 12812 ira->codegen, array_type->data.array.child_type, 12813 prev_inst->value->type->data.pointer.is_const || make_the_slice_const, false, 12814 PtrLenUnknown, 12815 0, 0, 0, false, 12816 VECTOR_INDEX_NONE, nullptr, array_type->data.array.sentinel); 12817 ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); 12818 if (err_set_type != nullptr) { 12819 return get_error_union_type(ira->codegen, err_set_type, slice_type); 12820 } else { 12821 return slice_type; 12822 } 12823 } else { 12824 zig_unreachable(); 12825 } 12826 } else if (err_set_type != nullptr) { 12827 if (prev_inst->value->type->id == ZigTypeIdErrorSet) { 12828 return err_set_type; 12829 } else if (prev_inst->value->type->id == ZigTypeIdErrorUnion) { 12830 ZigType *payload_type = prev_inst->value->type->data.error_union.payload_type; 12831 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 12832 return ira->codegen->builtin_types.entry_invalid; 12833 return get_error_union_type(ira->codegen, err_set_type, payload_type); 12834 } else if (expected_type != nullptr && expected_type->id == ZigTypeIdErrorUnion) { 12835 ZigType *payload_type = expected_type->data.error_union.payload_type; 12836 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 12837 return ira->codegen->builtin_types.entry_invalid; 12838 return get_error_union_type(ira->codegen, err_set_type, payload_type); 12839 } else { 12840 if (prev_inst->value->type->id == ZigTypeIdComptimeInt || 12841 prev_inst->value->type->id == ZigTypeIdComptimeFloat) 12842 { 12843 ir_add_error_node(ira, source_node, 12844 buf_sprintf("unable to make error union out of number literal")); 12845 return ira->codegen->builtin_types.entry_invalid; 12846 } else if (prev_inst->value->type->id == ZigTypeIdNull) { 12847 ir_add_error_node(ira, source_node, 12848 buf_sprintf("unable to make error union out of null literal")); 12849 return ira->codegen->builtin_types.entry_invalid; 12850 } else { 12851 if ((err = type_resolve(ira->codegen, prev_inst->value->type, ResolveStatusSizeKnown))) 12852 return ira->codegen->builtin_types.entry_invalid; 12853 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value->type); 12854 } 12855 } 12856 } else if (any_are_null && prev_inst->value->type->id != ZigTypeIdNull) { 12857 if (prev_inst->value->type->id == ZigTypeIdOptional) { 12858 return prev_inst->value->type; 12859 } else { 12860 if ((err = type_resolve(ira->codegen, prev_inst->value->type, ResolveStatusSizeKnown))) 12861 return ira->codegen->builtin_types.entry_invalid; 12862 return get_optional_type(ira->codegen, prev_inst->value->type); 12863 } 12864 } else if (make_the_slice_const) { 12865 ZigType *slice_type; 12866 if (prev_inst->value->type->id == ZigTypeIdErrorUnion) { 12867 slice_type = prev_inst->value->type->data.error_union.payload_type; 12868 } else if (is_slice(prev_inst->value->type)) { 12869 slice_type = prev_inst->value->type; 12870 } else { 12871 zig_unreachable(); 12872 } 12873 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 12874 ZigType *adjusted_ptr_type = adjust_ptr_const(ira->codegen, slice_ptr_type, make_the_slice_const); 12875 ZigType *adjusted_slice_type = get_slice_type(ira->codegen, adjusted_ptr_type); 12876 if (prev_inst->value->type->id == ZigTypeIdErrorUnion) { 12877 return get_error_union_type(ira->codegen, prev_inst->value->type->data.error_union.err_set_type, 12878 adjusted_slice_type); 12879 } else if (is_slice(prev_inst->value->type)) { 12880 return adjusted_slice_type; 12881 } else { 12882 zig_unreachable(); 12883 } 12884 } else if (make_the_pointer_const) { 12885 return adjust_ptr_const(ira->codegen, prev_inst->value->type, make_the_pointer_const); 12886 } else { 12887 return prev_inst->value->type; 12888 } 12889 } 12890 12891 static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInst *source_instr, 12892 CastOp cast_op, 12893 ZigValue *other_val, ZigType *other_type, 12894 ZigValue *const_val, ZigType *new_type) 12895 { 12896 const_val->special = other_val->special; 12897 12898 assert(other_val != const_val); 12899 switch (cast_op) { 12900 case CastOpNoCast: 12901 zig_unreachable(); 12902 case CastOpErrSet: 12903 case CastOpBitCast: 12904 zig_panic("TODO"); 12905 case CastOpNoop: { 12906 copy_const_val(ira->codegen, const_val, other_val); 12907 const_val->type = new_type; 12908 break; 12909 } 12910 case CastOpNumLitToConcrete: 12911 if (other_val->type->id == ZigTypeIdComptimeFloat) { 12912 assert(new_type->id == ZigTypeIdFloat); 12913 switch (new_type->data.floating.bit_count) { 12914 case 16: 12915 const_val->data.x_f16 = bigfloat_to_f16(&other_val->data.x_bigfloat); 12916 break; 12917 case 32: 12918 const_val->data.x_f32 = bigfloat_to_f32(&other_val->data.x_bigfloat); 12919 break; 12920 case 64: 12921 const_val->data.x_f64 = bigfloat_to_f64(&other_val->data.x_bigfloat); 12922 break; 12923 case 80: 12924 zig_panic("TODO"); 12925 case 128: 12926 const_val->data.x_f128 = bigfloat_to_f128(&other_val->data.x_bigfloat); 12927 break; 12928 default: 12929 zig_unreachable(); 12930 } 12931 } else if (other_val->type->id == ZigTypeIdComptimeInt) { 12932 bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint); 12933 } else { 12934 zig_unreachable(); 12935 } 12936 const_val->type = new_type; 12937 break; 12938 case CastOpIntToFloat: 12939 if (new_type->id == ZigTypeIdFloat) { 12940 BigFloat bigfloat; 12941 bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint); 12942 switch (new_type->data.floating.bit_count) { 12943 case 16: 12944 const_val->data.x_f16 = bigfloat_to_f16(&bigfloat); 12945 break; 12946 case 32: 12947 const_val->data.x_f32 = bigfloat_to_f32(&bigfloat); 12948 break; 12949 case 64: 12950 const_val->data.x_f64 = bigfloat_to_f64(&bigfloat); 12951 break; 12952 case 80: 12953 zig_panic("TODO"); 12954 case 128: 12955 const_val->data.x_f128 = bigfloat_to_f128(&bigfloat); 12956 break; 12957 default: 12958 zig_unreachable(); 12959 } 12960 } else if (new_type->id == ZigTypeIdComptimeFloat) { 12961 bigfloat_init_bigint(&const_val->data.x_bigfloat, &other_val->data.x_bigint); 12962 } else { 12963 zig_unreachable(); 12964 } 12965 const_val->special = ConstValSpecialStatic; 12966 break; 12967 case CastOpFloatToInt: 12968 float_init_bigint(&const_val->data.x_bigint, other_val); 12969 if (new_type->id == ZigTypeIdInt) { 12970 if (!bigint_fits_in_bits(&const_val->data.x_bigint, new_type->data.integral.bit_count, 12971 new_type->data.integral.is_signed)) 12972 { 12973 Buf *int_buf = buf_alloc(); 12974 bigint_append_buf(int_buf, &const_val->data.x_bigint, 10); 12975 12976 ir_add_error(ira, source_instr, 12977 buf_sprintf("integer value '%s' cannot be stored in type '%s'", 12978 buf_ptr(int_buf), buf_ptr(&new_type->name))); 12979 return false; 12980 } 12981 } 12982 12983 const_val->special = ConstValSpecialStatic; 12984 break; 12985 case CastOpBoolToInt: 12986 bigint_init_unsigned(&const_val->data.x_bigint, other_val->data.x_bool ? 1 : 0); 12987 const_val->special = ConstValSpecialStatic; 12988 break; 12989 } 12990 return true; 12991 } 12992 12993 static IrInstGen *ir_const(IrAnalyze *ira, IrInst *inst, ZigType *ty) { 12994 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 12995 inst->scope, inst->source_node); 12996 IrInstGen *new_instruction = &const_instruction->base; 12997 new_instruction->value->type = ty; 12998 new_instruction->value->special = ConstValSpecialStatic; 12999 ira->new_irb.constants.append(&heap::c_allocator, const_instruction); 13000 return new_instruction; 13001 } 13002 13003 static IrInstGen *ir_const_noval(IrAnalyze *ira, IrInst *old_instruction) { 13004 IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb, 13005 old_instruction->scope, old_instruction->source_node); 13006 ira->new_irb.constants.append(&heap::c_allocator, const_instruction); 13007 return &const_instruction->base; 13008 } 13009 13010 // This function initializes the new IrInstGen with the provided ZigValue, 13011 // rather than creating a new one. 13012 static IrInstGen *ir_const_move(IrAnalyze *ira, IrInst *old_instruction, ZigValue *val) { 13013 IrInstGen *result = ir_const_noval(ira, old_instruction); 13014 result->value = val; 13015 return result; 13016 } 13017 13018 static IrInstGen *ir_resolve_cast(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, 13019 ZigType *wanted_type, CastOp cast_op) 13020 { 13021 if (instr_is_comptime(value) || !type_has_bits(ira->codegen, wanted_type)) { 13022 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13023 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 13024 if (val == nullptr) 13025 return ira->codegen->invalid_inst_gen; 13026 13027 if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, val, val->type, 13028 result->value, wanted_type)) 13029 { 13030 return ira->codegen->invalid_inst_gen; 13031 } 13032 return result; 13033 } else { 13034 return ir_build_cast(ira, source_instr, wanted_type, value, cast_op); 13035 } 13036 } 13037 13038 static IrInstGen *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, IrInst* source_instr, 13039 IrInstGen *value, ZigType *wanted_type) 13040 { 13041 ir_assert(value->value->type->id == ZigTypeIdPointer, source_instr); 13042 13043 Error err; 13044 13045 if ((err = type_resolve(ira->codegen, value->value->type->data.pointer.child_type, 13046 ResolveStatusAlignmentKnown))) 13047 { 13048 return ira->codegen->invalid_inst_gen; 13049 } 13050 13051 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value->type)); 13052 13053 if (instr_is_comptime(value)) { 13054 ZigValue *val = ir_resolve_const(ira, value, UndefOk); 13055 if (val == nullptr) 13056 return ira->codegen->invalid_inst_gen; 13057 if (val->special == ConstValSpecialUndef) 13058 return ir_const_undef(ira, source_instr, wanted_type); 13059 13060 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 13061 if (pointee == nullptr) 13062 return ira->codegen->invalid_inst_gen; 13063 if (pointee->special != ConstValSpecialRuntime) { 13064 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13065 result->value->data.x_ptr.special = ConstPtrSpecialBaseArray; 13066 result->value->data.x_ptr.mut = val->data.x_ptr.mut; 13067 result->value->data.x_ptr.data.base_array.array_val = pointee; 13068 result->value->data.x_ptr.data.base_array.elem_index = 0; 13069 return result; 13070 } 13071 } 13072 13073 return ir_build_cast(ira, source_instr, wanted_type, value, CastOpBitCast); 13074 } 13075 13076 static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* source_instr, 13077 IrInstGen *array_ptr, ZigType *wanted_type, ResultLoc *result_loc) 13078 { 13079 Error err; 13080 13081 assert(array_ptr->value->type->id == ZigTypeIdPointer); 13082 assert(array_ptr->value->type->data.pointer.child_type->id == ZigTypeIdArray); 13083 13084 ZigType *array_type = array_ptr->value->type->data.pointer.child_type; 13085 size_t array_len = array_type->data.array.len; 13086 13087 // A zero-sized array can be casted regardless of the destination alignment, or 13088 // whether the pointer is undefined, and the result is always comptime known. 13089 // TODO However, this is exposing a result location bug that I failed to solve on the first try. 13090 // If you want to try to fix the bug, uncomment this block and get the tests passing. 13091 //if (array_len == 0 && array_type->data.array.sentinel == nullptr) { 13092 // ZigValue *undef_array = ira->codegen->pass1_arena->create<ZigValue>(); 13093 // undef_array->special = ConstValSpecialUndef; 13094 // undef_array->type = array_type; 13095 13096 // IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13097 // init_const_slice(ira->codegen, result->value, undef_array, 0, 0, false); 13098 // result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutComptimeConst; 13099 // result->value->type = wanted_type; 13100 // return result; 13101 //} 13102 13103 if ((err = type_resolve(ira->codegen, array_ptr->value->type, ResolveStatusAlignmentKnown))) { 13104 return ira->codegen->invalid_inst_gen; 13105 } 13106 13107 if (array_len != 0) { 13108 wanted_type = adjust_slice_align(ira->codegen, wanted_type, 13109 get_ptr_align(ira->codegen, array_ptr->value->type)); 13110 } 13111 13112 if (instr_is_comptime(array_ptr)) { 13113 UndefAllowed undef_allowed = (array_len == 0) ? UndefOk : UndefBad; 13114 ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, undef_allowed); 13115 if (array_ptr_val == nullptr) 13116 return ira->codegen->invalid_inst_gen; 13117 ir_assert(is_slice(wanted_type), source_instr); 13118 if (array_ptr_val->special == ConstValSpecialUndef) { 13119 ZigValue *undef_array = ira->codegen->pass1_arena->create<ZigValue>(); 13120 undef_array->special = ConstValSpecialUndef; 13121 undef_array->type = array_type; 13122 13123 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13124 init_const_slice(ira->codegen, result->value, undef_array, 0, 0, false); 13125 result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutComptimeConst; 13126 result->value->type = wanted_type; 13127 return result; 13128 } 13129 bool wanted_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const; 13130 // Optimization to avoid creating unnecessary ZigValue in const_ptr_pointee 13131 if (array_ptr_val->data.x_ptr.special == ConstPtrSpecialSubArray) { 13132 ZigValue *array_val = array_ptr_val->data.x_ptr.data.base_array.array_val; 13133 if (array_val->special != ConstValSpecialRuntime) { 13134 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13135 init_const_slice(ira->codegen, result->value, array_val, 13136 array_ptr_val->data.x_ptr.data.base_array.elem_index, 13137 array_type->data.array.len, wanted_const); 13138 result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; 13139 result->value->type = wanted_type; 13140 return result; 13141 } 13142 } else if (array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 13143 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, array_ptr_val, source_instr->source_node); 13144 if (pointee == nullptr) 13145 return ira->codegen->invalid_inst_gen; 13146 if (pointee->special != ConstValSpecialRuntime) { 13147 assert(array_ptr_val->type->id == ZigTypeIdPointer); 13148 13149 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13150 init_const_slice(ira->codegen, result->value, pointee, 0, array_type->data.array.len, wanted_const); 13151 result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; 13152 result->value->type = wanted_type; 13153 return result; 13154 } 13155 } 13156 } 13157 13158 if (result_loc == nullptr) result_loc = no_result_loc(); 13159 IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); 13160 if (type_is_invalid(result_loc_inst->value->type) || 13161 result_loc_inst->value->type->id == ZigTypeIdUnreachable) 13162 { 13163 return result_loc_inst; 13164 } 13165 return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, array_ptr, result_loc_inst); 13166 } 13167 13168 static IrBasicBlockGen *ir_get_new_bb(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrInst *ref_old_instruction) { 13169 assert(old_bb); 13170 13171 if (old_bb->child) { 13172 if (ref_old_instruction == nullptr || old_bb->child->ref_instruction != ref_old_instruction) { 13173 return old_bb->child; 13174 } 13175 } 13176 13177 IrBasicBlockGen *new_bb = ir_build_bb_from(ira, old_bb); 13178 new_bb->ref_instruction = ref_old_instruction; 13179 13180 return new_bb; 13181 } 13182 13183 static IrBasicBlockGen *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrInst *ref_old_instruction) { 13184 assert(ref_old_instruction != nullptr); 13185 IrBasicBlockGen *new_bb = ir_get_new_bb(ira, old_bb, ref_old_instruction); 13186 if (new_bb->must_be_comptime_source_instr) { 13187 ErrorMsg *msg = ir_add_error(ira, ref_old_instruction, 13188 buf_sprintf("control flow attempts to use compile-time variable at runtime")); 13189 add_error_note(ira->codegen, msg, new_bb->must_be_comptime_source_instr->source_node, 13190 buf_sprintf("compile-time variable assigned here")); 13191 return nullptr; 13192 } 13193 return new_bb; 13194 } 13195 13196 static void ir_start_bb(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrBasicBlockSrc *const_predecessor_bb) { 13197 ir_assert(!old_bb->suspended, (old_bb->instruction_list.length != 0) ? &old_bb->instruction_list.at(0)->base : nullptr); 13198 ira->instruction_index = 0; 13199 ira->old_irb.current_basic_block = old_bb; 13200 ira->const_predecessor_bb = const_predecessor_bb; 13201 ira->old_bb_index = old_bb->index; 13202 } 13203 13204 static IrInstGen *ira_suspend(IrAnalyze *ira, IrInst *old_instruction, IrBasicBlockSrc *next_bb, 13205 IrSuspendPosition *suspend_pos) 13206 { 13207 if (ira->codegen->verbose_ir) { 13208 fprintf(stderr, "suspend %s_%" PRIu32 " %s_%" PRIu32 " #%" PRIu32 " (%zu,%zu)\n", 13209 ira->old_irb.current_basic_block->name_hint, 13210 ira->old_irb.current_basic_block->debug_id, 13211 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint, 13212 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id, 13213 ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->base.debug_id, 13214 ira->old_bb_index, ira->instruction_index); 13215 } 13216 suspend_pos->basic_block_index = ira->old_bb_index; 13217 suspend_pos->instruction_index = ira->instruction_index; 13218 13219 ira->old_irb.current_basic_block->suspended = true; 13220 13221 // null next_bb means that the caller plans to call ira_resume before returning 13222 if (next_bb != nullptr) { 13223 ira->old_bb_index = next_bb->index; 13224 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 13225 assert(ira->old_irb.current_basic_block == next_bb); 13226 ira->instruction_index = 0; 13227 ira->const_predecessor_bb = nullptr; 13228 next_bb->child = ir_get_new_bb_runtime(ira, next_bb, old_instruction); 13229 ira->new_irb.current_basic_block = next_bb->child; 13230 } 13231 return ira->codegen->unreach_instruction; 13232 } 13233 13234 static IrInstGen *ira_resume(IrAnalyze *ira) { 13235 IrSuspendPosition pos = ira->resume_stack.pop(); 13236 if (ira->codegen->verbose_ir) { 13237 fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index); 13238 } 13239 ira->old_bb_index = pos.basic_block_index; 13240 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 13241 assert(ira->old_irb.current_basic_block->in_resume_stack); 13242 ira->old_irb.current_basic_block->in_resume_stack = false; 13243 ira->old_irb.current_basic_block->suspended = false; 13244 ira->instruction_index = pos.instruction_index; 13245 assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length); 13246 if (ira->codegen->verbose_ir) { 13247 fprintf(stderr, "%s_%" PRIu32 " #%" PRIu32 "\n", ira->old_irb.current_basic_block->name_hint, 13248 ira->old_irb.current_basic_block->debug_id, 13249 ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->base.debug_id); 13250 } 13251 ira->const_predecessor_bb = nullptr; 13252 ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->child; 13253 assert(ira->new_irb.current_basic_block != nullptr); 13254 return ira->codegen->unreach_instruction; 13255 } 13256 13257 static void ir_start_next_bb(IrAnalyze *ira) { 13258 ira->old_bb_index += 1; 13259 13260 bool need_repeat = true; 13261 for (;;) { 13262 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 13263 IrBasicBlockSrc *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 13264 if (old_bb->child == nullptr && old_bb->suspend_instruction_ref == nullptr) { 13265 ira->old_bb_index += 1; 13266 continue; 13267 } 13268 // if it's already started, or 13269 // if it's a suspended block, 13270 // then skip it 13271 if (old_bb->suspended || 13272 (old_bb->child != nullptr && old_bb->child->instruction_list.length != 0) || 13273 (old_bb->child != nullptr && old_bb->child->already_appended)) 13274 { 13275 ira->old_bb_index += 1; 13276 continue; 13277 } 13278 13279 // if there is a resume_stack, pop one from there rather than moving on. 13280 // the last item of the resume stack will be a basic block that will 13281 // move on to the next one below 13282 if (ira->resume_stack.length != 0) { 13283 ira_resume(ira); 13284 return; 13285 } 13286 13287 if (old_bb->child == nullptr) { 13288 old_bb->child = ir_get_new_bb_runtime(ira, old_bb, old_bb->suspend_instruction_ref); 13289 } 13290 ira->new_irb.current_basic_block = old_bb->child; 13291 ir_start_bb(ira, old_bb, nullptr); 13292 return; 13293 } 13294 if (!need_repeat) { 13295 if (ira->resume_stack.length != 0) { 13296 ira_resume(ira); 13297 } 13298 return; 13299 } 13300 need_repeat = false; 13301 ira->old_bb_index = 0; 13302 continue; 13303 } 13304 } 13305 13306 static void ir_finish_bb(IrAnalyze *ira) { 13307 if (!ira->new_irb.current_basic_block->already_appended) { 13308 ir_append_basic_block_gen(&ira->new_irb, ira->new_irb.current_basic_block); 13309 if (ira->codegen->verbose_ir) { 13310 fprintf(stderr, "append new bb %s_%" PRIu32 "\n", ira->new_irb.current_basic_block->name_hint, 13311 ira->new_irb.current_basic_block->debug_id); 13312 } 13313 } 13314 ira->instruction_index += 1; 13315 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { 13316 IrInstSrc *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 13317 if (!next_instruction->is_gen) { 13318 ir_add_error(ira, &next_instruction->base, buf_sprintf("unreachable code")); 13319 break; 13320 } 13321 ira->instruction_index += 1; 13322 } 13323 13324 ir_start_next_bb(ira); 13325 } 13326 13327 static IrInstGen *ir_unreach_error(IrAnalyze *ira) { 13328 ira->old_bb_index = SIZE_MAX; 13329 if (ira->new_irb.exec->first_err_trace_msg == nullptr) { 13330 ira->new_irb.exec->first_err_trace_msg = ira->codegen->trace_err; 13331 } 13332 return ira->codegen->unreach_instruction; 13333 } 13334 13335 static bool ir_emit_backward_branch(IrAnalyze *ira, IrInst* source_instruction) { 13336 size_t *bbc = ira->new_irb.exec->backward_branch_count; 13337 size_t *quota = ira->new_irb.exec->backward_branch_quota; 13338 13339 // If we're already over quota, we've already given an error message for this. 13340 if (*bbc > *quota) { 13341 assert(ira->codegen->errors.length > 0); 13342 return false; 13343 } 13344 13345 *bbc += 1; 13346 if (*bbc > *quota) { 13347 ir_add_error(ira, source_instruction, 13348 buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", *quota)); 13349 return false; 13350 } 13351 return true; 13352 } 13353 13354 static IrInstGen *ir_inline_bb(IrAnalyze *ira, IrInst* source_instruction, IrBasicBlockSrc *old_bb) { 13355 if (old_bb->debug_id <= ira->old_irb.current_basic_block->debug_id) { 13356 if (!ir_emit_backward_branch(ira, source_instruction)) 13357 return ir_unreach_error(ira); 13358 } 13359 13360 old_bb->child = ira->old_irb.current_basic_block->child; 13361 ir_start_bb(ira, old_bb, ira->old_irb.current_basic_block); 13362 return ira->codegen->unreach_instruction; 13363 } 13364 13365 static IrInstGen *ir_finish_anal(IrAnalyze *ira, IrInstGen *instruction) { 13366 if (instruction->value->type->id == ZigTypeIdUnreachable) 13367 ir_finish_bb(ira); 13368 return instruction; 13369 } 13370 13371 static IrInstGen *ir_const_fn(IrAnalyze *ira, IrInst *source_instr, ZigFn *fn_entry) { 13372 IrInstGen *result = ir_const(ira, source_instr, fn_entry->type_entry); 13373 result->value->special = ConstValSpecialStatic; 13374 result->value->data.x_ptr.data.fn.fn_entry = fn_entry; 13375 result->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 13376 result->value->data.x_ptr.special = ConstPtrSpecialFunction; 13377 return result; 13378 } 13379 13380 static IrInstGen *ir_const_bound_fn(IrAnalyze *ira, IrInst *src_inst, ZigFn *fn_entry, IrInstGen *first_arg, 13381 IrInst *first_arg_src) 13382 { 13383 // This is unfortunately required to avoid improperly freeing first_arg_src 13384 ira_ref(ira); 13385 13386 IrInstGen *result = ir_const(ira, src_inst, get_bound_fn_type(ira->codegen, fn_entry)); 13387 result->value->data.x_bound_fn.fn = fn_entry; 13388 result->value->data.x_bound_fn.first_arg = first_arg; 13389 result->value->data.x_bound_fn.first_arg_src = first_arg_src; 13390 return result; 13391 } 13392 13393 static IrInstGen *ir_const_type(IrAnalyze *ira, IrInst *source_instruction, ZigType *ty) { 13394 IrInstGen *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_type); 13395 result->value->data.x_type = ty; 13396 return result; 13397 } 13398 13399 static IrInstGen *ir_const_bool(IrAnalyze *ira, IrInst *source_instruction, bool value) { 13400 IrInstGen *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_bool); 13401 result->value->data.x_bool = value; 13402 return result; 13403 } 13404 13405 static IrInstGen *ir_const_undef(IrAnalyze *ira, IrInst *source_instruction, ZigType *ty) { 13406 IrInstGen *result = ir_const(ira, source_instruction, ty); 13407 result->value->special = ConstValSpecialUndef; 13408 return result; 13409 } 13410 13411 static IrInstGen *ir_const_unreachable(IrAnalyze *ira, IrInst *source_instruction) { 13412 IrInstGen *result = ir_const_noval(ira, source_instruction); 13413 result->value = ira->codegen->intern.for_unreachable(); 13414 return result; 13415 } 13416 13417 static IrInstGen *ir_const_void(IrAnalyze *ira, IrInst *source_instruction) { 13418 IrInstGen *result = ir_const_noval(ira, source_instruction); 13419 result->value = ira->codegen->intern.for_void(); 13420 return result; 13421 } 13422 13423 static IrInstGen *ir_const_unsigned(IrAnalyze *ira, IrInst *source_instruction, uint64_t value) { 13424 IrInstGen *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_num_lit_int); 13425 bigint_init_unsigned(&result->value->data.x_bigint, value); 13426 return result; 13427 } 13428 13429 static IrInstGen *ir_get_const_ptr(IrAnalyze *ira, IrInst *instruction, 13430 ZigValue *pointee, ZigType *pointee_type, 13431 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align) 13432 { 13433 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type, 13434 ptr_is_const, ptr_is_volatile, PtrLenSingle, ptr_align, 0, 0, false); 13435 IrInstGen *const_instr = ir_const(ira, instruction, ptr_type); 13436 ZigValue *const_val = const_instr->value; 13437 const_val->data.x_ptr.special = ConstPtrSpecialRef; 13438 const_val->data.x_ptr.mut = ptr_mut; 13439 const_val->data.x_ptr.data.ref.pointee = pointee; 13440 return const_instr; 13441 } 13442 13443 static Error ir_resolve_const_val(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, 13444 ZigValue *val, UndefAllowed undef_allowed) 13445 { 13446 Error err; 13447 for (;;) { 13448 switch (val->special) { 13449 case ConstValSpecialStatic: 13450 return ErrorNone; 13451 case ConstValSpecialRuntime: 13452 if (!type_has_bits(codegen, val->type)) 13453 return ErrorNone; 13454 13455 exec_add_error_node_gen(codegen, exec, source_node, 13456 buf_sprintf("unable to evaluate constant expression")); 13457 return ErrorSemanticAnalyzeFail; 13458 case ConstValSpecialUndef: 13459 if (undef_allowed == UndefOk || undef_allowed == LazyOk) 13460 return ErrorNone; 13461 13462 exec_add_error_node_gen(codegen, exec, source_node, 13463 buf_sprintf("use of undefined value here causes undefined behavior")); 13464 return ErrorSemanticAnalyzeFail; 13465 case ConstValSpecialLazy: 13466 if (undef_allowed == LazyOk || undef_allowed == LazyOkNoUndef) 13467 return ErrorNone; 13468 13469 if ((err = ir_resolve_lazy(codegen, source_node, val))) 13470 return err; 13471 13472 continue; 13473 } 13474 } 13475 } 13476 13477 static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed undef_allowed) { 13478 Error err; 13479 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, value->base.source_node, 13480 value->value, undef_allowed))) 13481 { 13482 return nullptr; 13483 } 13484 return value->value; 13485 } 13486 13487 Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, 13488 ZigValue *return_ptr, size_t *backward_branch_count, size_t *backward_branch_quota, 13489 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, 13490 IrExecutableGen *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef_allowed) 13491 { 13492 Error err; 13493 13494 src_assert(return_ptr->type->id == ZigTypeIdPointer, source_node); 13495 13496 if (type_is_invalid(return_ptr->type)) 13497 return ErrorSemanticAnalyzeFail; 13498 13499 IrExecutableSrc *ir_executable = heap::c_allocator.create<IrExecutableSrc>(); 13500 ir_executable->source_node = source_node; 13501 ir_executable->parent_exec = parent_exec; 13502 ir_executable->name = exec_name; 13503 ir_executable->is_inline = true; 13504 ir_executable->fn_entry = fn_entry; 13505 ir_executable->c_import_buf = c_import_buf; 13506 ir_executable->begin_scope = scope; 13507 13508 if (!ir_gen(codegen, node, scope, ir_executable)) 13509 return ErrorSemanticAnalyzeFail; 13510 13511 if (ir_executable->first_err_trace_msg != nullptr) { 13512 codegen->trace_err = ir_executable->first_err_trace_msg; 13513 return ErrorSemanticAnalyzeFail; 13514 } 13515 13516 if (codegen->verbose_ir) { 13517 fprintf(stderr, "\nSource: "); 13518 ast_render(stderr, node, 4); 13519 fprintf(stderr, "\n{ // (IR)\n"); 13520 ir_print_src(codegen, stderr, ir_executable, 2); 13521 fprintf(stderr, "}\n"); 13522 } 13523 IrExecutableGen *analyzed_executable = heap::c_allocator.create<IrExecutableGen>(); 13524 analyzed_executable->source_node = source_node; 13525 analyzed_executable->parent_exec = parent_exec; 13526 analyzed_executable->source_exec = ir_executable; 13527 analyzed_executable->name = exec_name; 13528 analyzed_executable->is_inline = true; 13529 analyzed_executable->fn_entry = fn_entry; 13530 analyzed_executable->c_import_buf = c_import_buf; 13531 analyzed_executable->backward_branch_count = backward_branch_count; 13532 analyzed_executable->backward_branch_quota = backward_branch_quota; 13533 analyzed_executable->begin_scope = scope; 13534 ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, 13535 return_ptr->type->data.pointer.child_type, expected_type_source_node, return_ptr); 13536 if (type_is_invalid(result_type)) { 13537 return ErrorSemanticAnalyzeFail; 13538 } 13539 13540 if (codegen->verbose_ir) { 13541 fprintf(stderr, "{ // (analyzed)\n"); 13542 ir_print_gen(codegen, stderr, analyzed_executable, 2); 13543 fprintf(stderr, "}\n"); 13544 } 13545 13546 if ((err = ir_exec_scan_for_side_effects(codegen, analyzed_executable))) 13547 return err; 13548 13549 ZigValue *result = const_ptr_pointee(nullptr, codegen, return_ptr, source_node); 13550 if (result == nullptr) 13551 return ErrorSemanticAnalyzeFail; 13552 if ((err = ir_resolve_const_val(codegen, analyzed_executable, node, result, undef_allowed))) 13553 return err; 13554 13555 return ErrorNone; 13556 } 13557 13558 static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstGen *err_value) { 13559 if (type_is_invalid(err_value->value->type)) 13560 return nullptr; 13561 13562 if (err_value->value->type->id != ZigTypeIdErrorSet) { 13563 ir_add_error_node(ira, err_value->base.source_node, 13564 buf_sprintf("expected error, found '%s'", buf_ptr(&err_value->value->type->name))); 13565 return nullptr; 13566 } 13567 13568 ZigValue *const_val = ir_resolve_const(ira, err_value, UndefBad); 13569 if (!const_val) 13570 return nullptr; 13571 13572 assert(const_val->data.x_err_set != nullptr); 13573 return const_val->data.x_err_set; 13574 } 13575 13576 static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, 13577 ZigValue *val) 13578 { 13579 Error err; 13580 if ((err = ir_resolve_const_val(codegen, exec, source_node, val, UndefBad))) 13581 return codegen->builtin_types.entry_invalid; 13582 13583 assert(val->data.x_type != nullptr); 13584 return val->data.x_type; 13585 } 13586 13587 static ZigValue *ir_resolve_type_lazy(IrAnalyze *ira, IrInstGen *type_value) { 13588 if (type_is_invalid(type_value->value->type)) 13589 return nullptr; 13590 13591 if (type_value->value->type->id != ZigTypeIdMetaType) { 13592 ir_add_error_node(ira, type_value->base.source_node, 13593 buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->value->type->name))); 13594 return nullptr; 13595 } 13596 13597 Error err; 13598 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, type_value->base.source_node, 13599 type_value->value, LazyOk))) 13600 { 13601 return nullptr; 13602 } 13603 13604 return type_value->value; 13605 } 13606 13607 static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstGen *type_value) { 13608 ZigValue *val = ir_resolve_type_lazy(ira, type_value); 13609 if (val == nullptr) 13610 return ira->codegen->builtin_types.entry_invalid; 13611 13612 return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->base.source_node, val); 13613 } 13614 13615 static Error ir_validate_vector_elem_type(IrAnalyze *ira, AstNode *source_node, ZigType *elem_type) { 13616 Error err; 13617 bool is_valid; 13618 if ((err = is_valid_vector_elem_type(ira->codegen, elem_type, &is_valid))) 13619 return err; 13620 if (!is_valid) { 13621 ir_add_error_node(ira, source_node, 13622 buf_sprintf("vector element type must be integer, float, bool, or pointer; '%s' is invalid", 13623 buf_ptr(&elem_type->name))); 13624 return ErrorSemanticAnalyzeFail; 13625 } 13626 return ErrorNone; 13627 } 13628 13629 static ZigType *ir_resolve_vector_elem_type(IrAnalyze *ira, IrInstGen *elem_type_value) { 13630 Error err; 13631 ZigType *elem_type = ir_resolve_type(ira, elem_type_value); 13632 if (type_is_invalid(elem_type)) 13633 return ira->codegen->builtin_types.entry_invalid; 13634 if ((err = ir_validate_vector_elem_type(ira, elem_type_value->base.source_node, elem_type))) 13635 return ira->codegen->builtin_types.entry_invalid; 13636 return elem_type; 13637 } 13638 13639 static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstGen *type_value) { 13640 ZigType *ty = ir_resolve_type(ira, type_value); 13641 if (type_is_invalid(ty)) 13642 return ira->codegen->builtin_types.entry_invalid; 13643 13644 if (ty->id != ZigTypeIdInt) { 13645 ErrorMsg *msg = ir_add_error_node(ira, type_value->base.source_node, 13646 buf_sprintf("expected integer type, found '%s'", buf_ptr(&ty->name))); 13647 if (ty->id == ZigTypeIdVector && 13648 ty->data.vector.elem_type->id == ZigTypeIdInt) 13649 { 13650 add_error_note(ira->codegen, msg, type_value->base.source_node, 13651 buf_sprintf("represent vectors with their element types, i.e. '%s'", 13652 buf_ptr(&ty->data.vector.elem_type->name))); 13653 } 13654 return ira->codegen->builtin_types.entry_invalid; 13655 } 13656 13657 return ty; 13658 } 13659 13660 static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInst *op_source, IrInstGen *type_value) { 13661 if (type_is_invalid(type_value->value->type)) 13662 return ira->codegen->builtin_types.entry_invalid; 13663 13664 if (type_value->value->type->id != ZigTypeIdMetaType) { 13665 ErrorMsg *msg = ir_add_error_node(ira, type_value->base.source_node, 13666 buf_sprintf("expected error set type, found '%s'", buf_ptr(&type_value->value->type->name))); 13667 add_error_note(ira->codegen, msg, op_source->source_node, 13668 buf_sprintf("`||` merges error sets; `or` performs boolean OR")); 13669 return ira->codegen->builtin_types.entry_invalid; 13670 } 13671 13672 ZigValue *const_val = ir_resolve_const(ira, type_value, UndefBad); 13673 if (!const_val) 13674 return ira->codegen->builtin_types.entry_invalid; 13675 13676 assert(const_val->data.x_type != nullptr); 13677 ZigType *result_type = const_val->data.x_type; 13678 if (result_type->id != ZigTypeIdErrorSet) { 13679 ErrorMsg *msg = ir_add_error_node(ira, type_value->base.source_node, 13680 buf_sprintf("expected error set type, found type '%s'", buf_ptr(&result_type->name))); 13681 add_error_note(ira->codegen, msg, op_source->source_node, 13682 buf_sprintf("`||` merges error sets; `or` performs boolean OR")); 13683 return ira->codegen->builtin_types.entry_invalid; 13684 } 13685 return result_type; 13686 } 13687 13688 static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstGen *fn_value) { 13689 if (type_is_invalid(fn_value->value->type)) 13690 return nullptr; 13691 13692 if (fn_value->value->type->id != ZigTypeIdFn) { 13693 ir_add_error_node(ira, fn_value->base.source_node, 13694 buf_sprintf("expected function type, found '%s'", buf_ptr(&fn_value->value->type->name))); 13695 return nullptr; 13696 } 13697 13698 ZigValue *const_val = ir_resolve_const(ira, fn_value, UndefBad); 13699 if (!const_val) 13700 return nullptr; 13701 13702 // May be a ConstPtrSpecialHardCodedAddr 13703 if (const_val->data.x_ptr.special != ConstPtrSpecialFunction) 13704 return nullptr; 13705 13706 return const_val->data.x_ptr.data.fn.fn_entry; 13707 } 13708 13709 static IrInstGen *ir_analyze_optional_wrap(IrAnalyze *ira, IrInst* source_instr, 13710 IrInstGen *value, ZigType *wanted_type, ResultLoc *result_loc) 13711 { 13712 assert(wanted_type->id == ZigTypeIdOptional); 13713 13714 if (instr_is_comptime(value)) { 13715 ZigType *payload_type = wanted_type->data.maybe.child_type; 13716 IrInstGen *casted_payload = ir_implicit_cast(ira, value, payload_type); 13717 if (type_is_invalid(casted_payload->value->type)) 13718 return ira->codegen->invalid_inst_gen; 13719 13720 ZigValue *val = ir_resolve_const(ira, casted_payload, UndefOk); 13721 if (!val) 13722 return ira->codegen->invalid_inst_gen; 13723 13724 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 13725 source_instr->scope, source_instr->source_node); 13726 const_instruction->base.value->special = ConstValSpecialStatic; 13727 if (types_have_same_zig_comptime_repr(ira->codegen, wanted_type, payload_type)) { 13728 copy_const_val(ira->codegen, const_instruction->base.value, val); 13729 } else { 13730 const_instruction->base.value->data.x_optional = val; 13731 } 13732 const_instruction->base.value->type = wanted_type; 13733 return &const_instruction->base; 13734 } 13735 13736 if (result_loc == nullptr && handle_is_ptr(ira->codegen, wanted_type)) { 13737 result_loc = no_result_loc(); 13738 } 13739 IrInstGen *result_loc_inst = nullptr; 13740 if (result_loc != nullptr) { 13741 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); 13742 if (type_is_invalid(result_loc_inst->value->type) || 13743 result_loc_inst->value->type->id == ZigTypeIdUnreachable) 13744 { 13745 return result_loc_inst; 13746 } 13747 } 13748 IrInstGen *result = ir_build_optional_wrap(ira, source_instr, wanted_type, value, result_loc_inst); 13749 result->value->data.rh_maybe = RuntimeHintOptionalNonNull; 13750 return result; 13751 } 13752 13753 static IrInstGen *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInst* source_instr, 13754 IrInstGen *value, ZigType *wanted_type, ResultLoc *result_loc) 13755 { 13756 assert(wanted_type->id == ZigTypeIdErrorUnion); 13757 13758 ZigType *payload_type = wanted_type->data.error_union.payload_type; 13759 ZigType *err_set_type = wanted_type->data.error_union.err_set_type; 13760 if (instr_is_comptime(value)) { 13761 IrInstGen *casted_payload = ir_implicit_cast(ira, value, payload_type); 13762 if (type_is_invalid(casted_payload->value->type)) 13763 return ira->codegen->invalid_inst_gen; 13764 13765 ZigValue *val = ir_resolve_const(ira, casted_payload, UndefOk); 13766 if (val == nullptr) 13767 return ira->codegen->invalid_inst_gen; 13768 13769 ZigValue *err_set_val = ira->codegen->pass1_arena->create<ZigValue>(); 13770 err_set_val->type = err_set_type; 13771 err_set_val->special = ConstValSpecialStatic; 13772 err_set_val->data.x_err_set = nullptr; 13773 13774 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 13775 source_instr->scope, source_instr->source_node); 13776 const_instruction->base.value->type = wanted_type; 13777 const_instruction->base.value->special = ConstValSpecialStatic; 13778 const_instruction->base.value->data.x_err_union.error_set = err_set_val; 13779 const_instruction->base.value->data.x_err_union.payload = val; 13780 return &const_instruction->base; 13781 } 13782 13783 IrInstGen *result_loc_inst; 13784 if (handle_is_ptr(ira->codegen, wanted_type)) { 13785 if (result_loc == nullptr) result_loc = no_result_loc(); 13786 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); 13787 if (type_is_invalid(result_loc_inst->value->type) || 13788 result_loc_inst->value->type->id == ZigTypeIdUnreachable) { 13789 return result_loc_inst; 13790 } 13791 } else { 13792 result_loc_inst = nullptr; 13793 } 13794 13795 IrInstGen *result = ir_build_err_wrap_payload(ira, source_instr, wanted_type, value, result_loc_inst); 13796 result->value->data.rh_error_union = RuntimeHintErrorUnionNonError; 13797 return result; 13798 } 13799 13800 static IrInstGen *ir_analyze_err_set_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 13801 ZigType *wanted_type) 13802 { 13803 assert(value->value->type->id == ZigTypeIdErrorSet); 13804 assert(wanted_type->id == ZigTypeIdErrorSet); 13805 13806 if (instr_is_comptime(value)) { 13807 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 13808 if (!val) 13809 return ira->codegen->invalid_inst_gen; 13810 13811 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 13812 return ira->codegen->invalid_inst_gen; 13813 } 13814 if (!type_is_global_error_set(wanted_type)) { 13815 bool subset = false; 13816 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 13817 if (wanted_type->data.error_set.errors[i]->value == val->data.x_err_set->value) { 13818 subset = true; 13819 break; 13820 } 13821 } 13822 if (!subset) { 13823 ir_add_error(ira, source_instr, 13824 buf_sprintf("error.%s not a member of error set '%s'", 13825 buf_ptr(&val->data.x_err_set->name), buf_ptr(&wanted_type->name))); 13826 return ira->codegen->invalid_inst_gen; 13827 } 13828 } 13829 13830 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 13831 source_instr->scope, source_instr->source_node); 13832 const_instruction->base.value->type = wanted_type; 13833 const_instruction->base.value->special = ConstValSpecialStatic; 13834 const_instruction->base.value->data.x_err_set = val->data.x_err_set; 13835 return &const_instruction->base; 13836 } 13837 13838 return ir_build_cast(ira, source_instr, wanted_type, value, CastOpErrSet); 13839 } 13840 13841 static IrInstGen *ir_analyze_frame_ptr_to_anyframe(IrAnalyze *ira, IrInst* source_instr, 13842 IrInstGen *frame_ptr, ZigType *wanted_type) 13843 { 13844 if (instr_is_comptime(frame_ptr)) { 13845 ZigValue *ptr_val = ir_resolve_const(ira, frame_ptr, UndefBad); 13846 if (ptr_val == nullptr) 13847 return ira->codegen->invalid_inst_gen; 13848 13849 ir_assert(ptr_val->type->id == ZigTypeIdPointer, source_instr); 13850 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 13851 zig_panic("TODO comptime frame pointer"); 13852 } 13853 } 13854 13855 return ir_build_cast(ira, source_instr, wanted_type, frame_ptr, CastOpBitCast); 13856 } 13857 13858 static IrInstGen *ir_analyze_anyframe_to_anyframe(IrAnalyze *ira, IrInst* source_instr, 13859 IrInstGen *value, ZigType *wanted_type) 13860 { 13861 if (instr_is_comptime(value)) { 13862 zig_panic("TODO comptime anyframe->T to anyframe"); 13863 } 13864 13865 return ir_build_cast(ira, source_instr, wanted_type, value, CastOpBitCast); 13866 } 13867 13868 13869 static IrInstGen *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 13870 ZigType *wanted_type, ResultLoc *result_loc) 13871 { 13872 assert(wanted_type->id == ZigTypeIdErrorUnion); 13873 13874 IrInstGen *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); 13875 13876 if (instr_is_comptime(casted_value)) { 13877 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); 13878 if (!val) 13879 return ira->codegen->invalid_inst_gen; 13880 13881 ZigValue *err_set_val = ira->codegen->pass1_arena->create<ZigValue>(); 13882 err_set_val->special = ConstValSpecialStatic; 13883 err_set_val->type = wanted_type->data.error_union.err_set_type; 13884 err_set_val->data.x_err_set = val->data.x_err_set; 13885 13886 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 13887 source_instr->scope, source_instr->source_node); 13888 const_instruction->base.value->type = wanted_type; 13889 const_instruction->base.value->special = ConstValSpecialStatic; 13890 const_instruction->base.value->data.x_err_union.error_set = err_set_val; 13891 const_instruction->base.value->data.x_err_union.payload = nullptr; 13892 return &const_instruction->base; 13893 } 13894 13895 IrInstGen *result_loc_inst; 13896 if (handle_is_ptr(ira->codegen, wanted_type)) { 13897 if (result_loc == nullptr) result_loc = no_result_loc(); 13898 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); 13899 if (type_is_invalid(result_loc_inst->value->type) || 13900 result_loc_inst->value->type->id == ZigTypeIdUnreachable) 13901 { 13902 return result_loc_inst; 13903 } 13904 } else { 13905 result_loc_inst = nullptr; 13906 } 13907 13908 13909 IrInstGen *result = ir_build_err_wrap_code(ira, source_instr, wanted_type, value, result_loc_inst); 13910 result->value->data.rh_error_union = RuntimeHintErrorUnionError; 13911 return result; 13912 } 13913 13914 static IrInstGen *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, ZigType *wanted_type) { 13915 assert(wanted_type->id == ZigTypeIdOptional); 13916 assert(instr_is_comptime(value)); 13917 13918 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 13919 assert(val != nullptr); 13920 13921 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13922 result->value->special = ConstValSpecialStatic; 13923 13924 if (get_src_ptr_type(wanted_type) != nullptr) { 13925 result->value->data.x_ptr.special = ConstPtrSpecialNull; 13926 } else if (is_opt_err_set(wanted_type)) { 13927 result->value->data.x_err_set = nullptr; 13928 } else { 13929 result->value->data.x_optional = nullptr; 13930 } 13931 return result; 13932 } 13933 13934 static IrInstGen *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInst *source_instr, 13935 IrInstGen *value, ZigType *wanted_type) 13936 { 13937 assert(wanted_type->id == ZigTypeIdPointer); 13938 assert(wanted_type->data.pointer.ptr_len == PtrLenC); 13939 assert(instr_is_comptime(value)); 13940 13941 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 13942 assert(val != nullptr); 13943 13944 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13945 result->value->data.x_ptr.special = ConstPtrSpecialNull; 13946 result->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 13947 return result; 13948 } 13949 13950 static IrInstGen *ir_get_ref2(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value, 13951 ZigType *elem_type, bool is_const, bool is_volatile) 13952 { 13953 Error err; 13954 13955 if (type_is_invalid(elem_type)) 13956 return ira->codegen->invalid_inst_gen; 13957 13958 if (instr_is_comptime(value)) { 13959 ZigValue *val = ir_resolve_const(ira, value, LazyOk); 13960 if (!val) 13961 return ira->codegen->invalid_inst_gen; 13962 return ir_get_const_ptr(ira, source_instruction, val, elem_type, 13963 ConstPtrMutComptimeConst, is_const, is_volatile, 0); 13964 } 13965 13966 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, elem_type, 13967 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 13968 13969 if ((err = type_resolve(ira->codegen, ptr_type, ResolveStatusZeroBitsKnown))) 13970 return ira->codegen->invalid_inst_gen; 13971 13972 IrInstGen *result_loc; 13973 if (type_has_bits(ira->codegen, ptr_type) && !handle_is_ptr(ira->codegen, elem_type)) { 13974 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), elem_type, nullptr, true, true); 13975 } else { 13976 result_loc = nullptr; 13977 } 13978 13979 IrInstGen *new_instruction = ir_build_ref_gen(ira, source_instruction, ptr_type, value, result_loc); 13980 new_instruction->value->data.rh_ptr = RuntimeHintPtrStack; 13981 return new_instruction; 13982 } 13983 13984 static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value, 13985 bool is_const, bool is_volatile) 13986 { 13987 return ir_get_ref2(ira, source_instruction, value, value->value->type, is_const, is_volatile); 13988 } 13989 13990 static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, AstNode *source_node, ZigType *union_type) { 13991 assert(union_type->id == ZigTypeIdUnion); 13992 13993 Error err; 13994 if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) 13995 return ira->codegen->builtin_types.entry_invalid; 13996 13997 AstNode *decl_node = union_type->data.unionation.decl_node; 13998 if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) { 13999 assert(union_type->data.unionation.tag_type != nullptr); 14000 return union_type->data.unionation.tag_type; 14001 } else { 14002 ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("union '%s' has no tag", 14003 buf_ptr(&union_type->name))); 14004 add_error_note(ira->codegen, msg, decl_node, buf_sprintf("consider 'union(enum)' here")); 14005 return ira->codegen->builtin_types.entry_invalid; 14006 } 14007 } 14008 14009 static IrInstGen *ir_analyze_enum_to_int(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target) { 14010 Error err; 14011 14012 IrInstGen *enum_target; 14013 ZigType *enum_type; 14014 if (target->value->type->id == ZigTypeIdUnion) { 14015 enum_type = ir_resolve_union_tag_type(ira, target->base.source_node, target->value->type); 14016 if (type_is_invalid(enum_type)) 14017 return ira->codegen->invalid_inst_gen; 14018 enum_target = ir_implicit_cast(ira, target, enum_type); 14019 if (type_is_invalid(enum_target->value->type)) 14020 return ira->codegen->invalid_inst_gen; 14021 } else if (target->value->type->id == ZigTypeIdEnum) { 14022 enum_target = target; 14023 enum_type = target->value->type; 14024 } else { 14025 ir_add_error_node(ira, target->base.source_node, 14026 buf_sprintf("expected enum, found type '%s'", buf_ptr(&target->value->type->name))); 14027 return ira->codegen->invalid_inst_gen; 14028 } 14029 14030 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown))) 14031 return ira->codegen->invalid_inst_gen; 14032 14033 ZigType *tag_type = enum_type->data.enumeration.tag_int_type; 14034 assert(tag_type->id == ZigTypeIdInt || tag_type->id == ZigTypeIdComptimeInt); 14035 14036 // If there is only one possible tag, then we know at comptime what it is. 14037 if (enum_type->data.enumeration.layout == ContainerLayoutAuto && 14038 enum_type->data.enumeration.src_field_count == 1) 14039 { 14040 IrInstGen *result = ir_const(ira, source_instr, tag_type); 14041 init_const_bigint(result->value, tag_type, 14042 &enum_type->data.enumeration.fields[0].value); 14043 return result; 14044 } 14045 14046 if (instr_is_comptime(enum_target)) { 14047 ZigValue *val = ir_resolve_const(ira, enum_target, UndefBad); 14048 if (!val) 14049 return ira->codegen->invalid_inst_gen; 14050 IrInstGen *result = ir_const(ira, source_instr, tag_type); 14051 init_const_bigint(result->value, tag_type, &val->data.x_enum_tag); 14052 return result; 14053 } 14054 14055 return ir_build_widen_or_shorten(ira, source_instr->scope, source_instr->source_node, enum_target, tag_type); 14056 } 14057 14058 static IrInstGen *ir_analyze_union_to_tag(IrAnalyze *ira, IrInst* source_instr, 14059 IrInstGen *target, ZigType *wanted_type) 14060 { 14061 assert(target->value->type->id == ZigTypeIdUnion); 14062 assert(wanted_type->id == ZigTypeIdEnum); 14063 assert(wanted_type == target->value->type->data.unionation.tag_type); 14064 14065 if (instr_is_comptime(target)) { 14066 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14067 if (!val) 14068 return ira->codegen->invalid_inst_gen; 14069 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14070 result->value->special = ConstValSpecialStatic; 14071 result->value->type = wanted_type; 14072 bigint_init_bigint(&result->value->data.x_enum_tag, &val->data.x_union.tag); 14073 return result; 14074 } 14075 14076 // If there is only 1 possible tag, then we know at comptime what it is. 14077 if (wanted_type->data.enumeration.layout == ContainerLayoutAuto && 14078 wanted_type->data.enumeration.src_field_count == 1) 14079 { 14080 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14081 result->value->special = ConstValSpecialStatic; 14082 result->value->type = wanted_type; 14083 TypeEnumField *enum_field = target->value->type->data.unionation.fields[0].enum_field; 14084 bigint_init_bigint(&result->value->data.x_enum_tag, &enum_field->value); 14085 return result; 14086 } 14087 14088 return ir_build_union_tag(ira, source_instr, target, wanted_type); 14089 } 14090 14091 static IrInstGen *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInst* source_instr, 14092 IrInstGen *target, ZigType *wanted_type) 14093 { 14094 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14095 result->value->special = ConstValSpecialUndef; 14096 return result; 14097 } 14098 14099 static IrInstGen *ir_analyze_enum_to_union(IrAnalyze *ira, IrInst* source_instr, 14100 IrInstGen *uncasted_target, ZigType *wanted_type) 14101 { 14102 Error err; 14103 assert(wanted_type->id == ZigTypeIdUnion); 14104 14105 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown))) 14106 return ira->codegen->invalid_inst_gen; 14107 14108 IrInstGen *target = ir_implicit_cast(ira, uncasted_target, wanted_type->data.unionation.tag_type); 14109 if (type_is_invalid(target->value->type)) 14110 return ira->codegen->invalid_inst_gen; 14111 14112 if (instr_is_comptime(target)) { 14113 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14114 if (!val) 14115 return ira->codegen->invalid_inst_gen; 14116 TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); 14117 assert(union_field != nullptr); 14118 ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); 14119 if (field_type == nullptr) 14120 return ira->codegen->invalid_inst_gen; 14121 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) 14122 return ira->codegen->invalid_inst_gen; 14123 14124 switch (type_has_one_possible_value(ira->codegen, field_type)) { 14125 case OnePossibleValueInvalid: 14126 return ira->codegen->invalid_inst_gen; 14127 case OnePossibleValueNo: { 14128 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at( 14129 union_field->enum_field->decl_index); 14130 ErrorMsg *msg = ir_add_error(ira, source_instr, 14131 buf_sprintf("cast to union '%s' must initialize '%s' field '%s'", 14132 buf_ptr(&wanted_type->name), 14133 buf_ptr(&field_type->name), 14134 buf_ptr(union_field->name))); 14135 add_error_note(ira->codegen, msg, field_node, 14136 buf_sprintf("field '%s' declared here", buf_ptr(union_field->name))); 14137 return ira->codegen->invalid_inst_gen; 14138 } 14139 case OnePossibleValueYes: 14140 break; 14141 } 14142 14143 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14144 result->value->special = ConstValSpecialStatic; 14145 result->value->type = wanted_type; 14146 bigint_init_bigint(&result->value->data.x_union.tag, &val->data.x_enum_tag); 14147 result->value->data.x_union.payload = ira->codegen->pass1_arena->create<ZigValue>(); 14148 result->value->data.x_union.payload->special = ConstValSpecialStatic; 14149 result->value->data.x_union.payload->type = field_type; 14150 return result; 14151 } 14152 14153 // if the union has all fields 0 bits, we can do it 14154 // and in fact it's a noop cast because the union value is just the enum value 14155 if (wanted_type->data.unionation.gen_field_count == 0) { 14156 return ir_build_cast(ira, &target->base, wanted_type, target, CastOpNoop); 14157 } 14158 14159 ErrorMsg *msg = ir_add_error(ira, source_instr, 14160 buf_sprintf("runtime cast to union '%s' which has non-void fields", 14161 buf_ptr(&wanted_type->name))); 14162 for (uint32_t i = 0; i < wanted_type->data.unionation.src_field_count; i += 1) { 14163 TypeUnionField *union_field = &wanted_type->data.unionation.fields[i]; 14164 ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); 14165 if (field_type == nullptr) 14166 return ira->codegen->invalid_inst_gen; 14167 bool has_bits; 14168 if ((err = type_has_bits2(ira->codegen, field_type, &has_bits))) 14169 return ira->codegen->invalid_inst_gen; 14170 if (has_bits) { 14171 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i); 14172 add_error_note(ira->codegen, msg, field_node, 14173 buf_sprintf("field '%s' has type '%s'", 14174 buf_ptr(union_field->name), 14175 buf_ptr(&field_type->name))); 14176 } 14177 } 14178 return ira->codegen->invalid_inst_gen; 14179 } 14180 14181 static IrInstGen *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInst* source_instr, 14182 IrInstGen *target, ZigType *wanted_type) 14183 { 14184 assert(wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdFloat); 14185 14186 if (instr_is_comptime(target)) { 14187 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14188 if (!val) 14189 return ira->codegen->invalid_inst_gen; 14190 if (wanted_type->id == ZigTypeIdInt) { 14191 if (bigint_cmp_zero(&val->data.x_bigint) == CmpLT && !wanted_type->data.integral.is_signed) { 14192 ir_add_error(ira, source_instr, 14193 buf_sprintf("attempt to cast negative value to unsigned integer")); 14194 return ira->codegen->invalid_inst_gen; 14195 } 14196 if (!bigint_fits_in_bits(&val->data.x_bigint, wanted_type->data.integral.bit_count, 14197 wanted_type->data.integral.is_signed)) 14198 { 14199 ir_add_error(ira, source_instr, 14200 buf_sprintf("cast from '%s' to '%s' truncates bits", 14201 buf_ptr(&target->value->type->name), buf_ptr(&wanted_type->name))); 14202 return ira->codegen->invalid_inst_gen; 14203 } 14204 } 14205 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14206 result->value->type = wanted_type; 14207 if (wanted_type->id == ZigTypeIdInt) { 14208 bigint_init_bigint(&result->value->data.x_bigint, &val->data.x_bigint); 14209 } else { 14210 float_init_float(result->value, val); 14211 } 14212 return result; 14213 } 14214 14215 // If the destination integer type has no bits, then we can emit a comptime 14216 // zero. However, we still want to emit a runtime safety check to make sure 14217 // the target is zero. 14218 if (!type_has_bits(ira->codegen, wanted_type)) { 14219 assert(wanted_type->id == ZigTypeIdInt); 14220 assert(type_has_bits(ira->codegen, target->value->type)); 14221 ir_build_assert_zero(ira, source_instr, target); 14222 IrInstGen *result = ir_const_unsigned(ira, source_instr, 0); 14223 result->value->type = wanted_type; 14224 return result; 14225 } 14226 14227 return ir_build_widen_or_shorten(ira, source_instr->scope, source_instr->source_node, target, wanted_type); 14228 } 14229 14230 static IrInstGen *ir_analyze_int_to_enum(IrAnalyze *ira, IrInst* source_instr, 14231 IrInstGen *target, ZigType *wanted_type) 14232 { 14233 Error err; 14234 assert(wanted_type->id == ZigTypeIdEnum); 14235 14236 ZigType *actual_type = target->value->type; 14237 14238 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusSizeKnown))) 14239 return ira->codegen->invalid_inst_gen; 14240 14241 if (actual_type != wanted_type->data.enumeration.tag_int_type) { 14242 ir_add_error(ira, source_instr, 14243 buf_sprintf("integer to enum cast from '%s' instead of its tag type, '%s'", 14244 buf_ptr(&actual_type->name), 14245 buf_ptr(&wanted_type->data.enumeration.tag_int_type->name))); 14246 return ira->codegen->invalid_inst_gen; 14247 } 14248 14249 assert(actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt); 14250 14251 if (instr_is_comptime(target)) { 14252 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14253 if (!val) 14254 return ira->codegen->invalid_inst_gen; 14255 14256 TypeEnumField *field = find_enum_field_by_tag(wanted_type, &val->data.x_bigint); 14257 if (field == nullptr && !wanted_type->data.enumeration.non_exhaustive) { 14258 Buf *val_buf = buf_alloc(); 14259 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 14260 ErrorMsg *msg = ir_add_error(ira, source_instr, 14261 buf_sprintf("enum '%s' has no tag matching integer value %s", 14262 buf_ptr(&wanted_type->name), buf_ptr(val_buf))); 14263 add_error_note(ira->codegen, msg, wanted_type->data.enumeration.decl_node, 14264 buf_sprintf("'%s' declared here", buf_ptr(&wanted_type->name))); 14265 return ira->codegen->invalid_inst_gen; 14266 } 14267 14268 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14269 bigint_init_bigint(&result->value->data.x_enum_tag, &val->data.x_bigint); 14270 return result; 14271 } 14272 14273 return ir_build_int_to_enum_gen(ira, source_instr->scope, source_instr->source_node, wanted_type, target); 14274 } 14275 14276 static IrInstGen *ir_analyze_number_to_literal(IrAnalyze *ira, IrInst* source_instr, 14277 IrInstGen *target, ZigType *wanted_type) 14278 { 14279 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14280 if (!val) 14281 return ira->codegen->invalid_inst_gen; 14282 14283 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14284 if (wanted_type->id == ZigTypeIdComptimeFloat) { 14285 float_init_float(result->value, val); 14286 } else if (wanted_type->id == ZigTypeIdComptimeInt) { 14287 bigint_init_bigint(&result->value->data.x_bigint, &val->data.x_bigint); 14288 } else { 14289 zig_unreachable(); 14290 } 14291 return result; 14292 } 14293 14294 static IrInstGen *ir_analyze_int_to_err(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 14295 ZigType *wanted_type) 14296 { 14297 assert(target->value->type->id == ZigTypeIdInt); 14298 assert(!target->value->type->data.integral.is_signed); 14299 assert(wanted_type->id == ZigTypeIdErrorSet); 14300 14301 if (instr_is_comptime(target)) { 14302 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14303 if (!val) 14304 return ira->codegen->invalid_inst_gen; 14305 14306 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14307 14308 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 14309 return ira->codegen->invalid_inst_gen; 14310 } 14311 14312 if (type_is_global_error_set(wanted_type)) { 14313 BigInt err_count; 14314 bigint_init_unsigned(&err_count, ira->codegen->errors_by_index.length); 14315 14316 if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) { 14317 Buf *val_buf = buf_alloc(); 14318 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 14319 ir_add_error(ira, source_instr, 14320 buf_sprintf("integer value %s represents no error", buf_ptr(val_buf))); 14321 return ira->codegen->invalid_inst_gen; 14322 } 14323 14324 size_t index = bigint_as_usize(&val->data.x_bigint); 14325 result->value->data.x_err_set = ira->codegen->errors_by_index.at(index); 14326 return result; 14327 } else { 14328 ErrorTableEntry *err = nullptr; 14329 BigInt err_int; 14330 14331 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 14332 ErrorTableEntry *this_err = wanted_type->data.error_set.errors[i]; 14333 bigint_init_unsigned(&err_int, this_err->value); 14334 if (bigint_cmp(&val->data.x_bigint, &err_int) == CmpEQ) { 14335 err = this_err; 14336 break; 14337 } 14338 } 14339 14340 if (err == nullptr) { 14341 Buf *val_buf = buf_alloc(); 14342 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 14343 ir_add_error(ira, source_instr, 14344 buf_sprintf("integer value %s represents no error in '%s'", buf_ptr(val_buf), buf_ptr(&wanted_type->name))); 14345 return ira->codegen->invalid_inst_gen; 14346 } 14347 14348 result->value->data.x_err_set = err; 14349 return result; 14350 } 14351 } 14352 14353 return ir_build_int_to_err_gen(ira, source_instr->scope, source_instr->source_node, target, wanted_type); 14354 } 14355 14356 static IrInstGen *ir_analyze_err_to_int(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 14357 ZigType *wanted_type) 14358 { 14359 assert(wanted_type->id == ZigTypeIdInt); 14360 14361 ZigType *err_type = target->value->type; 14362 14363 if (instr_is_comptime(target)) { 14364 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14365 if (!val) 14366 return ira->codegen->invalid_inst_gen; 14367 14368 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14369 14370 ErrorTableEntry *err; 14371 if (err_type->id == ZigTypeIdErrorUnion) { 14372 err = val->data.x_err_union.error_set->data.x_err_set; 14373 } else if (err_type->id == ZigTypeIdErrorSet) { 14374 err = val->data.x_err_set; 14375 } else { 14376 zig_unreachable(); 14377 } 14378 result->value->type = wanted_type; 14379 uint64_t err_value = err ? err->value : 0; 14380 bigint_init_unsigned(&result->value->data.x_bigint, err_value); 14381 14382 if (!bigint_fits_in_bits(&result->value->data.x_bigint, 14383 wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) 14384 { 14385 ir_add_error_node(ira, source_instr->source_node, 14386 buf_sprintf("error code '%s' does not fit in '%s'", 14387 buf_ptr(&err->name), buf_ptr(&wanted_type->name))); 14388 return ira->codegen->invalid_inst_gen; 14389 } 14390 14391 return result; 14392 } 14393 14394 ZigType *err_set_type; 14395 if (err_type->id == ZigTypeIdErrorUnion) { 14396 err_set_type = err_type->data.error_union.err_set_type; 14397 } else if (err_type->id == ZigTypeIdErrorSet) { 14398 err_set_type = err_type; 14399 } else { 14400 zig_unreachable(); 14401 } 14402 if (!type_is_global_error_set(err_set_type)) { 14403 if (!resolve_inferred_error_set(ira->codegen, err_set_type, source_instr->source_node)) { 14404 return ira->codegen->invalid_inst_gen; 14405 } 14406 if (err_set_type->data.error_set.err_count == 0) { 14407 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14408 bigint_init_unsigned(&result->value->data.x_bigint, 0); 14409 return result; 14410 } else if (err_set_type->data.error_set.err_count == 1) { 14411 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14412 ErrorTableEntry *err = err_set_type->data.error_set.errors[0]; 14413 bigint_init_unsigned(&result->value->data.x_bigint, err->value); 14414 return result; 14415 } 14416 } 14417 14418 BigInt bn; 14419 bigint_init_unsigned(&bn, ira->codegen->errors_by_index.length); 14420 if (!bigint_fits_in_bits(&bn, wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) { 14421 ir_add_error_node(ira, source_instr->source_node, 14422 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name))); 14423 return ira->codegen->invalid_inst_gen; 14424 } 14425 14426 return ir_build_err_to_int_gen(ira, source_instr->scope, source_instr->source_node, target, wanted_type); 14427 } 14428 14429 static IrInstGen *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 14430 ZigType *wanted_type) 14431 { 14432 assert(wanted_type->id == ZigTypeIdPointer); 14433 Error err; 14434 if ((err = type_resolve(ira->codegen, target->value->type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 14435 return ira->codegen->invalid_inst_gen; 14436 assert((wanted_type->data.pointer.is_const && target->value->type->data.pointer.is_const) || !target->value->type->data.pointer.is_const); 14437 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, target->value->type)); 14438 ZigType *array_type = wanted_type->data.pointer.child_type; 14439 assert(array_type->id == ZigTypeIdArray); 14440 assert(array_type->data.array.len == 1); 14441 14442 if (instr_is_comptime(target)) { 14443 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14444 if (!val) 14445 return ira->codegen->invalid_inst_gen; 14446 14447 assert(val->type->id == ZigTypeIdPointer); 14448 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 14449 if (pointee == nullptr) 14450 return ira->codegen->invalid_inst_gen; 14451 if (pointee->special != ConstValSpecialRuntime) { 14452 ZigValue *array_val = ira->codegen->pass1_arena->create<ZigValue>(); 14453 array_val->special = ConstValSpecialStatic; 14454 array_val->type = array_type; 14455 array_val->data.x_array.special = ConstArraySpecialNone; 14456 array_val->data.x_array.data.s_none.elements = pointee; 14457 array_val->parent.id = ConstParentIdScalar; 14458 array_val->parent.data.p_scalar.scalar_val = pointee; 14459 14460 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 14461 source_instr->scope, source_instr->source_node); 14462 const_instruction->base.value->type = wanted_type; 14463 const_instruction->base.value->special = ConstValSpecialStatic; 14464 const_instruction->base.value->data.x_ptr.special = ConstPtrSpecialRef; 14465 const_instruction->base.value->data.x_ptr.data.ref.pointee = array_val; 14466 const_instruction->base.value->data.x_ptr.mut = val->data.x_ptr.mut; 14467 return &const_instruction->base; 14468 } 14469 } 14470 14471 // pointer to array and pointer to single item are represented the same way at runtime 14472 return ir_build_cast(ira, &target->base, wanted_type, target, CastOpBitCast); 14473 } 14474 14475 static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCastOnly *cast_result, 14476 ErrorMsg *parent_msg) 14477 { 14478 switch (cast_result->id) { 14479 case ConstCastResultIdOk: 14480 zig_unreachable(); 14481 case ConstCastResultIdInvalid: 14482 zig_unreachable(); 14483 case ConstCastResultIdOptionalChild: { 14484 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 14485 buf_sprintf("optional type child '%s' cannot cast into optional type child '%s'", 14486 buf_ptr(&cast_result->data.optional->actual_child->name), 14487 buf_ptr(&cast_result->data.optional->wanted_child->name))); 14488 report_recursive_error(ira, source_node, &cast_result->data.optional->child, msg); 14489 break; 14490 } 14491 case ConstCastResultIdErrorUnionErrorSet: { 14492 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 14493 buf_sprintf("error set '%s' cannot cast into error set '%s'", 14494 buf_ptr(&cast_result->data.error_union_error_set->actual_err_set->name), 14495 buf_ptr(&cast_result->data.error_union_error_set->wanted_err_set->name))); 14496 report_recursive_error(ira, source_node, &cast_result->data.error_union_error_set->child, msg); 14497 break; 14498 } 14499 case ConstCastResultIdErrSet: { 14500 ZigList<ErrorTableEntry *> *missing_errors = &cast_result->data.error_set_mismatch->missing_errors; 14501 for (size_t i = 0; i < missing_errors->length; i += 1) { 14502 ErrorTableEntry *error_entry = missing_errors->at(i); 14503 add_error_note(ira->codegen, parent_msg, ast_field_to_symbol_node(error_entry->decl_node), 14504 buf_sprintf("'error.%s' not a member of destination error set", buf_ptr(&error_entry->name))); 14505 } 14506 break; 14507 } 14508 case ConstCastResultIdErrSetGlobal: { 14509 add_error_note(ira->codegen, parent_msg, source_node, 14510 buf_sprintf("cannot cast global error set into smaller set")); 14511 break; 14512 } 14513 case ConstCastResultIdPointerChild: { 14514 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 14515 buf_sprintf("pointer type child '%s' cannot cast into pointer type child '%s'", 14516 buf_ptr(&cast_result->data.pointer_mismatch->actual_child->name), 14517 buf_ptr(&cast_result->data.pointer_mismatch->wanted_child->name))); 14518 report_recursive_error(ira, source_node, &cast_result->data.pointer_mismatch->child, msg); 14519 break; 14520 } 14521 case ConstCastResultIdSliceChild: { 14522 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 14523 buf_sprintf("slice type child '%s' cannot cast into slice type child '%s'", 14524 buf_ptr(&cast_result->data.slice_mismatch->actual_child->name), 14525 buf_ptr(&cast_result->data.slice_mismatch->wanted_child->name))); 14526 report_recursive_error(ira, source_node, &cast_result->data.slice_mismatch->child, msg); 14527 break; 14528 } 14529 case ConstCastResultIdErrorUnionPayload: { 14530 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 14531 buf_sprintf("error union payload '%s' cannot cast into error union payload '%s'", 14532 buf_ptr(&cast_result->data.error_union_payload->actual_payload->name), 14533 buf_ptr(&cast_result->data.error_union_payload->wanted_payload->name))); 14534 report_recursive_error(ira, source_node, &cast_result->data.error_union_payload->child, msg); 14535 break; 14536 } 14537 case ConstCastResultIdType: { 14538 AstNode *wanted_decl_node = type_decl_node(cast_result->data.type_mismatch->wanted_type); 14539 AstNode *actual_decl_node = type_decl_node(cast_result->data.type_mismatch->actual_type); 14540 if (wanted_decl_node != nullptr) { 14541 add_error_note(ira->codegen, parent_msg, wanted_decl_node, 14542 buf_sprintf("%s declared here", 14543 buf_ptr(&cast_result->data.type_mismatch->wanted_type->name))); 14544 } 14545 if (actual_decl_node != nullptr) { 14546 add_error_note(ira->codegen, parent_msg, actual_decl_node, 14547 buf_sprintf("%s declared here", 14548 buf_ptr(&cast_result->data.type_mismatch->actual_type->name))); 14549 } 14550 break; 14551 } 14552 case ConstCastResultIdFnArg: { 14553 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 14554 buf_sprintf("parameter %" ZIG_PRI_usize ": '%s' cannot cast into '%s'", 14555 cast_result->data.fn_arg.arg_index, 14556 buf_ptr(&cast_result->data.fn_arg.actual_param_type->name), 14557 buf_ptr(&cast_result->data.fn_arg.expected_param_type->name))); 14558 report_recursive_error(ira, source_node, cast_result->data.fn_arg.child, msg); 14559 break; 14560 } 14561 case ConstCastResultIdBadAllowsZero: { 14562 ZigType *wanted_type = cast_result->data.bad_allows_zero->wanted_type; 14563 ZigType *actual_type = cast_result->data.bad_allows_zero->actual_type; 14564 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); 14565 bool actual_allows_zero = ptr_allows_addr_zero(actual_type); 14566 if (actual_allows_zero && !wanted_allows_zero) { 14567 add_error_note(ira->codegen, parent_msg, source_node, 14568 buf_sprintf("'%s' could have null values which are illegal in type '%s'", 14569 buf_ptr(&actual_type->name), 14570 buf_ptr(&wanted_type->name))); 14571 } else { 14572 add_error_note(ira->codegen, parent_msg, source_node, 14573 buf_sprintf("mutable '%s' allows illegal null values stored to type '%s'", 14574 buf_ptr(&wanted_type->name), 14575 buf_ptr(&actual_type->name))); 14576 } 14577 break; 14578 } 14579 case ConstCastResultIdPtrLens: { 14580 add_error_note(ira->codegen, parent_msg, source_node, 14581 buf_sprintf("pointer length mismatch")); 14582 break; 14583 } 14584 case ConstCastResultIdPtrSentinel: { 14585 ZigType *actual_type = cast_result->data.bad_ptr_sentinel->actual_type; 14586 ZigType *wanted_type = cast_result->data.bad_ptr_sentinel->wanted_type; 14587 { 14588 Buf *txt_msg = buf_sprintf("destination pointer requires a terminating '"); 14589 render_const_value(ira->codegen, txt_msg, wanted_type->data.pointer.sentinel); 14590 buf_appendf(txt_msg, "' sentinel"); 14591 if (actual_type->data.pointer.sentinel != nullptr) { 14592 buf_appendf(txt_msg, ", but source pointer has a terminating '"); 14593 render_const_value(ira->codegen, txt_msg, actual_type->data.pointer.sentinel); 14594 buf_appendf(txt_msg, "' sentinel"); 14595 } 14596 add_error_note(ira->codegen, parent_msg, source_node, txt_msg); 14597 } 14598 break; 14599 } 14600 case ConstCastResultIdSentinelArrays: { 14601 ZigType *actual_type = cast_result->data.sentinel_arrays->actual_type; 14602 ZigType *wanted_type = cast_result->data.sentinel_arrays->wanted_type; 14603 Buf *txt_msg = buf_sprintf("destination array requires a terminating '"); 14604 render_const_value(ira->codegen, txt_msg, wanted_type->data.array.sentinel); 14605 buf_appendf(txt_msg, "' sentinel"); 14606 if (actual_type->data.array.sentinel != nullptr) { 14607 buf_appendf(txt_msg, ", but source array has a terminating '"); 14608 render_const_value(ira->codegen, txt_msg, actual_type->data.array.sentinel); 14609 buf_appendf(txt_msg, "' sentinel"); 14610 } 14611 add_error_note(ira->codegen, parent_msg, source_node, txt_msg); 14612 break; 14613 } 14614 case ConstCastResultIdCV: { 14615 ZigType *wanted_type = cast_result->data.bad_cv->wanted_type; 14616 ZigType *actual_type = cast_result->data.bad_cv->actual_type; 14617 bool ok_const = !actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const; 14618 bool ok_volatile = !actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile; 14619 if (!ok_const) { 14620 add_error_note(ira->codegen, parent_msg, source_node, buf_sprintf("cast discards const qualifier")); 14621 } else if (!ok_volatile) { 14622 add_error_note(ira->codegen, parent_msg, source_node, buf_sprintf("cast discards volatile qualifier")); 14623 } else { 14624 zig_unreachable(); 14625 } 14626 break; 14627 } 14628 case ConstCastResultIdFnIsGeneric: 14629 add_error_note(ira->codegen, parent_msg, source_node, 14630 buf_sprintf("only one of the functions is generic")); 14631 break; 14632 case ConstCastResultIdFnCC: 14633 add_error_note(ira->codegen, parent_msg, source_node, 14634 buf_sprintf("calling convention mismatch")); 14635 break; 14636 case ConstCastResultIdIntShorten: { 14637 ZigType *wanted_type = cast_result->data.int_shorten->wanted_type; 14638 ZigType *actual_type = cast_result->data.int_shorten->actual_type; 14639 const char *wanted_signed = wanted_type->data.integral.is_signed ? "signed" : "unsigned"; 14640 const char *actual_signed = actual_type->data.integral.is_signed ? "signed" : "unsigned"; 14641 add_error_note(ira->codegen, parent_msg, source_node, 14642 buf_sprintf("%s %" PRIu32 "-bit int cannot represent all possible %s %" PRIu32 "-bit values", 14643 wanted_signed, wanted_type->data.integral.bit_count, 14644 actual_signed, actual_type->data.integral.bit_count)); 14645 break; 14646 } 14647 case ConstCastResultIdFnAlign: // TODO 14648 case ConstCastResultIdFnVarArgs: // TODO 14649 case ConstCastResultIdFnReturnType: // TODO 14650 case ConstCastResultIdFnArgCount: // TODO 14651 case ConstCastResultIdFnGenericArgCount: // TODO 14652 case ConstCastResultIdFnArgNoAlias: // TODO 14653 case ConstCastResultIdUnresolvedInferredErrSet: // TODO 14654 case ConstCastResultIdAsyncAllocatorType: // TODO 14655 case ConstCastResultIdArrayChild: // TODO 14656 break; 14657 } 14658 } 14659 14660 static IrInstGen *ir_analyze_array_to_vector(IrAnalyze *ira, IrInst* source_instr, 14661 IrInstGen *array, ZigType *vector_type) 14662 { 14663 if (instr_is_comptime(array)) { 14664 // arrays and vectors have the same ZigValue representation 14665 IrInstGen *result = ir_const(ira, source_instr, vector_type); 14666 copy_const_val(ira->codegen, result->value, array->value); 14667 result->value->type = vector_type; 14668 return result; 14669 } 14670 return ir_build_array_to_vector(ira, source_instr, array, vector_type); 14671 } 14672 14673 static IrInstGen *ir_analyze_vector_to_array(IrAnalyze *ira, IrInst* source_instr, 14674 IrInstGen *vector, ZigType *array_type, ResultLoc *result_loc) 14675 { 14676 if (instr_is_comptime(vector)) { 14677 // arrays and vectors have the same ZigValue representation 14678 IrInstGen *result = ir_const(ira, source_instr, array_type); 14679 copy_const_val(ira->codegen, result->value, vector->value); 14680 result->value->type = array_type; 14681 return result; 14682 } 14683 if (result_loc == nullptr) { 14684 result_loc = no_result_loc(); 14685 } 14686 IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, true, true); 14687 if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { 14688 return result_loc_inst; 14689 } 14690 return ir_build_vector_to_array(ira, source_instr, array_type, vector, result_loc_inst); 14691 } 14692 14693 static IrInstGen *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInst* source_instr, 14694 IrInstGen *integer, ZigType *dest_type) 14695 { 14696 IrInstGen *unsigned_integer; 14697 if (instr_is_comptime(integer)) { 14698 unsigned_integer = integer; 14699 } else { 14700 assert(integer->value->type->id == ZigTypeIdInt); 14701 14702 if (integer->value->type->data.integral.bit_count > 14703 ira->codegen->builtin_types.entry_usize->data.integral.bit_count) 14704 { 14705 ir_add_error(ira, source_instr, 14706 buf_sprintf("integer type '%s' too big for implicit @intToPtr to type '%s'", 14707 buf_ptr(&integer->value->type->name), 14708 buf_ptr(&dest_type->name))); 14709 return ira->codegen->invalid_inst_gen; 14710 } 14711 14712 if (integer->value->type->data.integral.is_signed) { 14713 ZigType *unsigned_int_type = get_int_type(ira->codegen, false, 14714 integer->value->type->data.integral.bit_count); 14715 unsigned_integer = ir_analyze_bit_cast(ira, source_instr, integer, unsigned_int_type); 14716 if (type_is_invalid(unsigned_integer->value->type)) 14717 return ira->codegen->invalid_inst_gen; 14718 } else { 14719 unsigned_integer = integer; 14720 } 14721 } 14722 14723 return ir_analyze_int_to_ptr(ira, source_instr, unsigned_integer, dest_type); 14724 } 14725 14726 static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { 14727 if (ty->id == ZigTypeIdPointer) return ty->data.pointer.child_type->id != ZigTypeIdPointer; 14728 if (ty->id == ZigTypeIdFn) return true; 14729 if (ty->id == ZigTypeIdOptional) { 14730 ZigType *ptr_ty = ty->data.maybe.child_type; 14731 if (ptr_ty->id == ZigTypeIdPointer) return ptr_ty->data.pointer.child_type->id != ZigTypeIdPointer; 14732 if (ptr_ty->id == ZigTypeIdFn) return true; 14733 } 14734 return false; 14735 } 14736 14737 static IrInstGen *ir_analyze_enum_literal(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 14738 ZigType *enum_type) 14739 { 14740 assert(enum_type->id == ZigTypeIdEnum); 14741 14742 Error err; 14743 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusZeroBitsKnown))) 14744 return ira->codegen->invalid_inst_gen; 14745 14746 TypeEnumField *field = find_enum_type_field(enum_type, value->value->data.x_enum_literal); 14747 if (field == nullptr) { 14748 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("enum '%s' has no field named '%s'", 14749 buf_ptr(&enum_type->name), buf_ptr(value->value->data.x_enum_literal))); 14750 add_error_note(ira->codegen, msg, enum_type->data.enumeration.decl_node, 14751 buf_sprintf("'%s' declared here", buf_ptr(&enum_type->name))); 14752 return ira->codegen->invalid_inst_gen; 14753 } 14754 IrInstGen *result = ir_const(ira, source_instr, enum_type); 14755 bigint_init_bigint(&result->value->data.x_enum_tag, &field->value); 14756 14757 return result; 14758 } 14759 14760 static IrInstGen *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInst* source_instr, 14761 IrInstGen *value, ZigType *wanted_type) 14762 { 14763 ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon list literal to array")); 14764 return ira->codegen->invalid_inst_gen; 14765 } 14766 14767 static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* source_instr, 14768 IrInstGen *struct_operand, ZigType *wanted_type) 14769 { 14770 Error err; 14771 14772 IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, struct_operand, true, false); 14773 if (type_is_invalid(struct_ptr->value->type)) 14774 return ira->codegen->invalid_inst_gen; 14775 14776 if (wanted_type->data.structure.resolve_status == ResolveStatusBeingInferred) { 14777 ir_add_error(ira, source_instr, buf_sprintf("type coercion of anon struct literal to inferred struct")); 14778 return ira->codegen->invalid_inst_gen; 14779 } 14780 14781 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusSizeKnown))) 14782 return ira->codegen->invalid_inst_gen; 14783 14784 size_t actual_field_count = wanted_type->data.structure.src_field_count; 14785 size_t instr_field_count = struct_operand->value->type->data.structure.src_field_count; 14786 14787 bool need_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope) 14788 || type_requires_comptime(ira->codegen, wanted_type) == ReqCompTimeYes; 14789 bool is_comptime = true; 14790 14791 // Determine if the struct_operand will be comptime. 14792 // Also emit compile errors for missing fields and duplicate fields. 14793 AstNode **field_assign_nodes = heap::c_allocator.allocate<AstNode *>(actual_field_count); 14794 ZigValue **field_values = heap::c_allocator.allocate<ZigValue *>(actual_field_count); 14795 IrInstGen **casted_fields = heap::c_allocator.allocate<IrInstGen *>(actual_field_count); 14796 IrInstGen *const_result = ir_const(ira, source_instr, wanted_type); 14797 14798 for (size_t i = 0; i < instr_field_count; i += 1) { 14799 TypeStructField *src_field = struct_operand->value->type->data.structure.fields[i]; 14800 TypeStructField *dst_field = find_struct_type_field(wanted_type, src_field->name); 14801 if (dst_field == nullptr) { 14802 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("no field named '%s' in struct '%s'", 14803 buf_ptr(src_field->name), buf_ptr(&wanted_type->name))); 14804 if (wanted_type->data.structure.decl_node) { 14805 add_error_note(ira->codegen, msg, wanted_type->data.structure.decl_node, 14806 buf_sprintf("struct '%s' declared here", buf_ptr(&wanted_type->name))); 14807 } 14808 add_error_note(ira->codegen, msg, src_field->decl_node, 14809 buf_sprintf("field '%s' declared here", buf_ptr(src_field->name))); 14810 return ira->codegen->invalid_inst_gen; 14811 } 14812 14813 ir_assert(src_field->decl_node != nullptr, source_instr); 14814 AstNode *existing_assign_node = field_assign_nodes[dst_field->src_index]; 14815 if (existing_assign_node != nullptr) { 14816 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("duplicate field")); 14817 add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here")); 14818 return ira->codegen->invalid_inst_gen; 14819 } 14820 field_assign_nodes[dst_field->src_index] = src_field->decl_node; 14821 14822 IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, src_field, struct_ptr, 14823 struct_operand->value->type, false); 14824 if (type_is_invalid(field_ptr->value->type)) 14825 return ira->codegen->invalid_inst_gen; 14826 IrInstGen *field_value = ir_get_deref(ira, source_instr, field_ptr, nullptr); 14827 if (type_is_invalid(field_value->value->type)) 14828 return ira->codegen->invalid_inst_gen; 14829 IrInstGen *casted_value = ir_implicit_cast(ira, field_value, dst_field->type_entry); 14830 if (type_is_invalid(casted_value->value->type)) 14831 return ira->codegen->invalid_inst_gen; 14832 14833 casted_fields[dst_field->src_index] = casted_value; 14834 if (need_comptime || instr_is_comptime(casted_value)) { 14835 ZigValue *field_val = ir_resolve_const(ira, casted_value, UndefOk); 14836 if (field_val == nullptr) 14837 return ira->codegen->invalid_inst_gen; 14838 field_val->parent.id = ConstParentIdStruct; 14839 field_val->parent.data.p_struct.struct_val = const_result->value; 14840 field_val->parent.data.p_struct.field_index = dst_field->src_index; 14841 field_values[dst_field->src_index] = field_val; 14842 } else { 14843 is_comptime = false; 14844 } 14845 } 14846 14847 bool any_missing = false; 14848 for (size_t i = 0; i < actual_field_count; i += 1) { 14849 if (field_assign_nodes[i] != nullptr) continue; 14850 14851 // look for a default field value 14852 TypeStructField *field = wanted_type->data.structure.fields[i]; 14853 memoize_field_init_val(ira->codegen, wanted_type, field); 14854 if (field->init_val == nullptr) { 14855 ir_add_error(ira, source_instr, 14856 buf_sprintf("missing field: '%s'", buf_ptr(field->name))); 14857 any_missing = true; 14858 continue; 14859 } 14860 if (type_is_invalid(field->init_val->type)) 14861 return ira->codegen->invalid_inst_gen; 14862 ZigValue *init_val_copy = ira->codegen->pass1_arena->create<ZigValue>(); 14863 copy_const_val(ira->codegen, init_val_copy, field->init_val); 14864 init_val_copy->parent.id = ConstParentIdStruct; 14865 init_val_copy->parent.data.p_struct.struct_val = const_result->value; 14866 init_val_copy->parent.data.p_struct.field_index = i; 14867 field_values[i] = init_val_copy; 14868 casted_fields[i] = ir_const_move(ira, source_instr, init_val_copy); 14869 } 14870 if (any_missing) 14871 return ira->codegen->invalid_inst_gen; 14872 14873 if (is_comptime) { 14874 heap::c_allocator.deallocate(field_assign_nodes, actual_field_count); 14875 IrInstGen *const_result = ir_const(ira, source_instr, wanted_type); 14876 const_result->value->data.x_struct.fields = field_values; 14877 return const_result; 14878 } 14879 14880 IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, no_result_loc(), 14881 wanted_type, nullptr, true, true); 14882 if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { 14883 return ira->codegen->invalid_inst_gen; 14884 } 14885 14886 for (size_t i = 0; i < actual_field_count; i += 1) { 14887 TypeStructField *field = wanted_type->data.structure.fields[i]; 14888 IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, result_loc_inst, wanted_type, true); 14889 if (type_is_invalid(field_ptr->value->type)) 14890 return ira->codegen->invalid_inst_gen; 14891 IrInstGen *store_ptr_inst = ir_analyze_store_ptr(ira, source_instr, field_ptr, casted_fields[i], true); 14892 if (type_is_invalid(store_ptr_inst->value->type)) 14893 return ira->codegen->invalid_inst_gen; 14894 } 14895 14896 heap::c_allocator.deallocate(field_assign_nodes, actual_field_count); 14897 heap::c_allocator.deallocate(field_values, actual_field_count); 14898 heap::c_allocator.deallocate(casted_fields, actual_field_count); 14899 14900 return ir_get_deref(ira, source_instr, result_loc_inst, nullptr); 14901 } 14902 14903 static IrInstGen *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInst* source_instr, 14904 IrInstGen *value, ZigType *union_type) 14905 { 14906 Error err; 14907 ZigType *struct_type = value->value->type; 14908 14909 assert(struct_type->id == ZigTypeIdStruct); 14910 assert(union_type->id == ZigTypeIdUnion); 14911 assert(struct_type->data.structure.src_field_count == 1); 14912 14913 TypeStructField *only_field = struct_type->data.structure.fields[0]; 14914 14915 if ((err = type_resolve(ira->codegen, union_type, ResolveStatusZeroBitsKnown))) 14916 return ira->codegen->invalid_inst_gen; 14917 14918 TypeUnionField *union_field = find_union_type_field(union_type, only_field->name); 14919 if (union_field == nullptr) { 14920 ir_add_error_node(ira, only_field->decl_node, 14921 buf_sprintf("no field named '%s' in union '%s'", 14922 buf_ptr(only_field->name), buf_ptr(&union_type->name))); 14923 return ira->codegen->invalid_inst_gen; 14924 } 14925 14926 ZigType *payload_type = resolve_union_field_type(ira->codegen, union_field); 14927 if (payload_type == nullptr) 14928 return ira->codegen->invalid_inst_gen; 14929 14930 IrInstGen *field_value = ir_analyze_struct_value_field_value(ira, source_instr, value, only_field); 14931 if (type_is_invalid(field_value->value->type)) 14932 return ira->codegen->invalid_inst_gen; 14933 14934 IrInstGen *casted_value = ir_implicit_cast(ira, field_value, payload_type); 14935 if (type_is_invalid(casted_value->value->type)) 14936 return ira->codegen->invalid_inst_gen; 14937 14938 if (instr_is_comptime(casted_value)) { 14939 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); 14940 if (val == nullptr) 14941 return ira->codegen->invalid_inst_gen; 14942 14943 IrInstGen *result = ir_const(ira, source_instr, union_type); 14944 bigint_init_bigint(&result->value->data.x_union.tag, &union_field->enum_field->value); 14945 result->value->data.x_union.payload = val; 14946 14947 val->parent.id = ConstParentIdUnion; 14948 val->parent.data.p_union.union_val = result->value; 14949 14950 return result; 14951 } 14952 14953 IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, no_result_loc(), 14954 union_type, nullptr, true, true); 14955 if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { 14956 return ira->codegen->invalid_inst_gen; 14957 } 14958 14959 IrInstGen *payload_ptr = ir_analyze_container_field_ptr(ira, only_field->name, source_instr, 14960 result_loc_inst, source_instr, union_type, true); 14961 if (type_is_invalid(payload_ptr->value->type)) 14962 return ira->codegen->invalid_inst_gen; 14963 14964 IrInstGen *store_ptr_inst = ir_analyze_store_ptr(ira, source_instr, payload_ptr, casted_value, false); 14965 if (type_is_invalid(store_ptr_inst->value->type)) 14966 return ira->codegen->invalid_inst_gen; 14967 14968 return ir_get_deref(ira, source_instr, result_loc_inst, nullptr); 14969 } 14970 14971 // Add a compile error and return ErrorSemanticAnalyzeFail if the pointer alignment does not work, 14972 // otherwise return ErrorNone. Does not emit any instructions. 14973 // Assumes that the pointer types have element types with the same ABI alignment. Avoids resolving the 14974 // pointer types' alignments if both of the pointer types are ABI aligned. 14975 static Error ir_cast_ptr_align(IrAnalyze *ira, IrInst* source_instr, ZigType *dest_ptr_type, 14976 ZigType *src_ptr_type, AstNode *src_source_node) 14977 { 14978 Error err; 14979 14980 ir_assert(dest_ptr_type->id == ZigTypeIdPointer, source_instr); 14981 ir_assert(src_ptr_type->id == ZigTypeIdPointer, source_instr); 14982 14983 if (dest_ptr_type->data.pointer.explicit_alignment == 0 && 14984 src_ptr_type->data.pointer.explicit_alignment == 0) 14985 { 14986 return ErrorNone; 14987 } 14988 14989 if ((err = type_resolve(ira->codegen, dest_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 14990 return ErrorSemanticAnalyzeFail; 14991 14992 if ((err = type_resolve(ira->codegen, src_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 14993 return ErrorSemanticAnalyzeFail; 14994 14995 uint32_t wanted_align = get_ptr_align(ira->codegen, dest_ptr_type); 14996 uint32_t actual_align = get_ptr_align(ira->codegen, src_ptr_type); 14997 if (wanted_align > actual_align) { 14998 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 14999 add_error_note(ira->codegen, msg, src_source_node, 15000 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_ptr_type->name), actual_align)); 15001 add_error_note(ira->codegen, msg, source_instr->source_node, 15002 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&dest_ptr_type->name), wanted_align)); 15003 return ErrorSemanticAnalyzeFail; 15004 } 15005 15006 return ErrorNone; 15007 } 15008 15009 static IrInstGen *ir_analyze_struct_value_field_value(IrAnalyze *ira, IrInst* source_instr, 15010 IrInstGen *struct_operand, TypeStructField *field) 15011 { 15012 IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, struct_operand, true, false); 15013 if (type_is_invalid(struct_ptr->value->type)) 15014 return ira->codegen->invalid_inst_gen; 15015 IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, struct_ptr, 15016 struct_operand->value->type, false); 15017 if (type_is_invalid(field_ptr->value->type)) 15018 return ira->codegen->invalid_inst_gen; 15019 return ir_get_deref(ira, source_instr, field_ptr, nullptr); 15020 } 15021 15022 static IrInstGen *ir_analyze_optional_value_payload_value(IrAnalyze *ira, IrInst* source_instr, 15023 IrInstGen *optional_operand, bool safety_check_on) 15024 { 15025 IrInstGen *opt_ptr = ir_get_ref(ira, source_instr, optional_operand, true, false); 15026 IrInstGen *payload_ptr = ir_analyze_unwrap_optional_payload(ira, source_instr, opt_ptr, 15027 safety_check_on, false); 15028 return ir_get_deref(ira, source_instr, payload_ptr, nullptr); 15029 } 15030 15031 static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr, 15032 ZigType *wanted_type, IrInstGen *value) 15033 { 15034 Error err; 15035 ZigType *actual_type = value->value->type; 15036 AstNode *source_node = source_instr->source_node; 15037 15038 if (type_is_invalid(wanted_type) || type_is_invalid(actual_type)) { 15039 return ira->codegen->invalid_inst_gen; 15040 } 15041 15042 // This means the wanted type is anything. 15043 if (wanted_type == ira->codegen->builtin_types.entry_anytype) { 15044 return value; 15045 } 15046 15047 // perfect match or non-const to const 15048 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type, 15049 source_node, false); 15050 if (const_cast_result.id == ConstCastResultIdInvalid) 15051 return ira->codegen->invalid_inst_gen; 15052 if (const_cast_result.id == ConstCastResultIdOk) { 15053 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); 15054 } 15055 15056 if (const_cast_result.id == ConstCastResultIdFnCC) { 15057 ir_assert(value->value->type->id == ZigTypeIdFn, source_instr); 15058 // ConstCastResultIdFnCC is guaranteed to be the last one reported, meaning everything else is ok. 15059 if (wanted_type->data.fn.fn_type_id.cc == CallingConventionAsync && 15060 actual_type->data.fn.fn_type_id.cc == CallingConventionUnspecified) 15061 { 15062 ir_assert(value->value->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); 15063 ZigFn *fn = value->value->data.x_ptr.data.fn.fn_entry; 15064 if (fn->inferred_async_node == nullptr) { 15065 fn->inferred_async_node = source_instr->source_node; 15066 } 15067 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); 15068 } 15069 } 15070 15071 // cast from T to ?T 15072 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism 15073 if (wanted_type->id == ZigTypeIdOptional) { 15074 ZigType *wanted_child_type = wanted_type->data.maybe.child_type; 15075 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, 15076 false).id == ConstCastResultIdOk) 15077 { 15078 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, nullptr); 15079 } else if (actual_type->id == ZigTypeIdComptimeInt || 15080 actual_type->id == ZigTypeIdComptimeFloat) 15081 { 15082 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { 15083 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, nullptr); 15084 } else { 15085 return ira->codegen->invalid_inst_gen; 15086 } 15087 } else if ( 15088 wanted_child_type->id == ZigTypeIdPointer && 15089 wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && 15090 actual_type->id == ZigTypeIdPointer && 15091 actual_type->data.pointer.ptr_len == PtrLenSingle && 15092 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 15093 { 15094 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 15095 return ira->codegen->invalid_inst_gen; 15096 if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 15097 return ira->codegen->invalid_inst_gen; 15098 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && 15099 types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, 15100 actual_type->data.pointer.child_type->data.array.child_type, source_node, 15101 !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) 15102 { 15103 IrInstGen *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, 15104 wanted_child_type); 15105 if (type_is_invalid(cast1->value->type)) 15106 return ira->codegen->invalid_inst_gen; 15107 return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type, nullptr); 15108 } 15109 } 15110 } 15111 15112 // T to E!T 15113 if (wanted_type->id == ZigTypeIdErrorUnion) { 15114 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, 15115 source_node, false).id == ConstCastResultIdOk) 15116 { 15117 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, nullptr); 15118 } else if (actual_type->id == ZigTypeIdComptimeInt || 15119 actual_type->id == ZigTypeIdComptimeFloat) 15120 { 15121 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { 15122 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, nullptr); 15123 } else { 15124 return ira->codegen->invalid_inst_gen; 15125 } 15126 } 15127 } 15128 15129 // cast from T to E!?T 15130 if (wanted_type->id == ZigTypeIdErrorUnion && 15131 wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && 15132 actual_type->id != ZigTypeIdOptional) 15133 { 15134 ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; 15135 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || 15136 actual_type->id == ZigTypeIdNull || 15137 actual_type->id == ZigTypeIdComptimeInt || 15138 actual_type->id == ZigTypeIdComptimeFloat) 15139 { 15140 IrInstGen *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); 15141 if (type_is_invalid(cast1->value->type)) 15142 return ira->codegen->invalid_inst_gen; 15143 15144 IrInstGen *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 15145 if (type_is_invalid(cast2->value->type)) 15146 return ira->codegen->invalid_inst_gen; 15147 15148 return cast2; 15149 } 15150 } 15151 15152 15153 // cast from comptime-known number to another number type 15154 if (instr_is_comptime(value) && 15155 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt || 15156 actual_type->id == ZigTypeIdFloat || actual_type->id == ZigTypeIdComptimeFloat) && 15157 (wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdComptimeInt || 15158 wanted_type->id == ZigTypeIdFloat || wanted_type->id == ZigTypeIdComptimeFloat)) 15159 { 15160 if (value->value->special == ConstValSpecialUndef) { 15161 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 15162 result->value->special = ConstValSpecialUndef; 15163 return result; 15164 } 15165 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { 15166 if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) { 15167 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 15168 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { 15169 copy_const_val(ira->codegen, result->value, value->value); 15170 result->value->type = wanted_type; 15171 } else { 15172 float_init_bigint(&result->value->data.x_bigint, value->value); 15173 } 15174 return result; 15175 } else if (wanted_type->id == ZigTypeIdComptimeFloat || wanted_type->id == ZigTypeIdFloat) { 15176 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 15177 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { 15178 BigFloat bf; 15179 bigfloat_init_bigint(&bf, &value->value->data.x_bigint); 15180 float_init_bigfloat(result->value, &bf); 15181 } else { 15182 float_init_float(result->value, value->value); 15183 } 15184 return result; 15185 } 15186 zig_unreachable(); 15187 } else { 15188 return ira->codegen->invalid_inst_gen; 15189 } 15190 } 15191 15192 // widening conversion 15193 if (wanted_type->id == ZigTypeIdInt && 15194 actual_type->id == ZigTypeIdInt && 15195 wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed && 15196 wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count) 15197 { 15198 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 15199 } 15200 15201 // small enough unsigned ints can get casted to large enough signed ints 15202 if (wanted_type->id == ZigTypeIdInt && wanted_type->data.integral.is_signed && 15203 actual_type->id == ZigTypeIdInt && !actual_type->data.integral.is_signed && 15204 wanted_type->data.integral.bit_count > actual_type->data.integral.bit_count) 15205 { 15206 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 15207 } 15208 15209 // float widening conversion 15210 if (wanted_type->id == ZigTypeIdFloat && 15211 actual_type->id == ZigTypeIdFloat && 15212 wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count) 15213 { 15214 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 15215 } 15216 15217 // *[N]T to ?[]T 15218 if (wanted_type->id == ZigTypeIdOptional && 15219 is_slice(wanted_type->data.maybe.child_type) && 15220 actual_type->id == ZigTypeIdPointer && 15221 actual_type->data.pointer.ptr_len == PtrLenSingle && 15222 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 15223 { 15224 IrInstGen *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); 15225 if (type_is_invalid(cast1->value->type)) 15226 return ira->codegen->invalid_inst_gen; 15227 15228 IrInstGen *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 15229 if (type_is_invalid(cast2->value->type)) 15230 return ira->codegen->invalid_inst_gen; 15231 15232 return cast2; 15233 } 15234 15235 // *[N]T to [*]T and [*c]T 15236 if (wanted_type->id == ZigTypeIdPointer && 15237 (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC) && 15238 actual_type->id == ZigTypeIdPointer && 15239 actual_type->data.pointer.ptr_len == PtrLenSingle && 15240 actual_type->data.pointer.child_type->id == ZigTypeIdArray && 15241 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && 15242 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) 15243 { 15244 ZigType *actual_array_type = actual_type->data.pointer.child_type; 15245 if (wanted_type->data.pointer.sentinel == nullptr || 15246 (actual_array_type->data.array.sentinel != nullptr && 15247 const_values_equal(ira->codegen, wanted_type->data.pointer.sentinel, 15248 actual_array_type->data.array.sentinel))) 15249 { 15250 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 15251 return ira->codegen->invalid_inst_gen; 15252 if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 15253 return ira->codegen->invalid_inst_gen; 15254 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type) && 15255 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 15256 actual_type->data.pointer.child_type->data.array.child_type, source_node, 15257 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 15258 { 15259 return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type); 15260 } 15261 } 15262 } 15263 15264 // *[N]T to []T 15265 // *[N]T to E![]T 15266 if ((is_slice(wanted_type) || 15267 (wanted_type->id == ZigTypeIdErrorUnion && 15268 is_slice(wanted_type->data.error_union.payload_type))) && 15269 actual_type->id == ZigTypeIdPointer && 15270 actual_type->data.pointer.ptr_len == PtrLenSingle && 15271 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 15272 { 15273 ZigType *slice_type = (wanted_type->id == ZigTypeIdErrorUnion) ? 15274 wanted_type->data.error_union.payload_type : wanted_type; 15275 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 15276 assert(slice_ptr_type->id == ZigTypeIdPointer); 15277 ZigType *array_type = actual_type->data.pointer.child_type; 15278 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 15279 || !actual_type->data.pointer.is_const); 15280 if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 15281 array_type->data.array.child_type, source_node, 15282 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) 15283 { 15284 // If the pointers both have ABI align, it works. 15285 // Or if the array length is 0, alignment doesn't matter. 15286 bool ok_align = array_type->data.array.len == 0 || 15287 (slice_ptr_type->data.pointer.explicit_alignment == 0 && 15288 actual_type->data.pointer.explicit_alignment == 0); 15289 if (!ok_align) { 15290 // If either one has non ABI align, we have to resolve them both 15291 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, 15292 ResolveStatusAlignmentKnown))) 15293 { 15294 return ira->codegen->invalid_inst_gen; 15295 } 15296 if ((err = type_resolve(ira->codegen, slice_ptr_type->data.pointer.child_type, 15297 ResolveStatusAlignmentKnown))) 15298 { 15299 return ira->codegen->invalid_inst_gen; 15300 } 15301 ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type); 15302 } 15303 if (ok_align) { 15304 if (wanted_type->id == ZigTypeIdErrorUnion) { 15305 IrInstGen *cast1 = ir_analyze_cast(ira, source_instr, slice_type, value); 15306 if (type_is_invalid(cast1->value->type)) 15307 return ira->codegen->invalid_inst_gen; 15308 15309 IrInstGen *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 15310 if (type_is_invalid(cast2->value->type)) 15311 return ira->codegen->invalid_inst_gen; 15312 15313 return cast2; 15314 } else { 15315 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, slice_type, nullptr); 15316 } 15317 } 15318 } 15319 } 15320 15321 // @Vector(N,T1) to @Vector(N,T2) 15322 if (actual_type->id == ZigTypeIdVector && wanted_type->id == ZigTypeIdVector) { 15323 if (actual_type->data.vector.len == wanted_type->data.vector.len && 15324 types_match_const_cast_only(ira, wanted_type->data.vector.elem_type, 15325 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 15326 { 15327 return ir_analyze_bit_cast(ira, source_instr, value, wanted_type); 15328 } 15329 } 15330 15331 // *@Frame(func) to anyframe->T or anyframe 15332 // *@Frame(func) to ?anyframe->T or ?anyframe 15333 // *@Frame(func) to E!anyframe->T or E!anyframe 15334 if (actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle && 15335 !actual_type->data.pointer.is_const && 15336 actual_type->data.pointer.child_type->id == ZigTypeIdFnFrame) 15337 { 15338 ZigType *anyframe_type; 15339 if (wanted_type->id == ZigTypeIdAnyFrame) { 15340 anyframe_type = wanted_type; 15341 } else if (wanted_type->id == ZigTypeIdOptional && 15342 wanted_type->data.maybe.child_type->id == ZigTypeIdAnyFrame) 15343 { 15344 anyframe_type = wanted_type->data.maybe.child_type; 15345 } else if (wanted_type->id == ZigTypeIdErrorUnion && 15346 wanted_type->data.error_union.payload_type->id == ZigTypeIdAnyFrame) 15347 { 15348 anyframe_type = wanted_type->data.error_union.payload_type; 15349 } else { 15350 anyframe_type = nullptr; 15351 } 15352 if (anyframe_type != nullptr) { 15353 bool ok = true; 15354 if (anyframe_type->data.any_frame.result_type != nullptr) { 15355 ZigFn *fn = actual_type->data.pointer.child_type->data.frame.fn; 15356 ZigType *fn_return_type = fn->type_entry->data.fn.fn_type_id.return_type; 15357 if (anyframe_type->data.any_frame.result_type != fn_return_type) { 15358 ok = false; 15359 } 15360 } 15361 if (ok) { 15362 IrInstGen *cast1 = ir_analyze_frame_ptr_to_anyframe(ira, source_instr, value, anyframe_type); 15363 if (anyframe_type == wanted_type) 15364 return cast1; 15365 return ir_analyze_cast(ira, source_instr, wanted_type, cast1); 15366 } 15367 } 15368 } 15369 15370 // anyframe->T to anyframe 15371 if (actual_type->id == ZigTypeIdAnyFrame && actual_type->data.any_frame.result_type != nullptr && 15372 wanted_type->id == ZigTypeIdAnyFrame && wanted_type->data.any_frame.result_type == nullptr) 15373 { 15374 return ir_analyze_anyframe_to_anyframe(ira, source_instr, value, wanted_type); 15375 } 15376 15377 // cast from null literal to maybe type 15378 if (wanted_type->id == ZigTypeIdOptional && 15379 actual_type->id == ZigTypeIdNull) 15380 { 15381 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type); 15382 } 15383 15384 // cast from null literal to C pointer 15385 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC && 15386 actual_type->id == ZigTypeIdNull) 15387 { 15388 return ir_analyze_null_to_c_pointer(ira, source_instr, value, wanted_type); 15389 } 15390 15391 // cast from E to E!T 15392 if (wanted_type->id == ZigTypeIdErrorUnion && 15393 actual_type->id == ZigTypeIdErrorSet) 15394 { 15395 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type, nullptr); 15396 } 15397 15398 // cast from typed number to integer or float literal. 15399 // works when the number is known at compile time 15400 if (instr_is_comptime(value) && 15401 ((actual_type->id == ZigTypeIdInt && wanted_type->id == ZigTypeIdComptimeInt) || 15402 (actual_type->id == ZigTypeIdFloat && wanted_type->id == ZigTypeIdComptimeFloat))) 15403 { 15404 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type); 15405 } 15406 15407 // cast from enum literal to enum with matching field name 15408 if (actual_type->id == ZigTypeIdEnumLiteral && wanted_type->id == ZigTypeIdEnum) 15409 { 15410 return ir_analyze_enum_literal(ira, source_instr, value, wanted_type); 15411 } 15412 15413 // cast from enum literal to optional enum 15414 if (actual_type->id == ZigTypeIdEnumLiteral && 15415 (wanted_type->id == ZigTypeIdOptional && wanted_type->data.maybe.child_type->id == ZigTypeIdEnum)) 15416 { 15417 IrInstGen *result = ir_analyze_enum_literal(ira, source_instr, value, wanted_type->data.maybe.child_type); 15418 if (type_is_invalid(result->value->type)) 15419 return result; 15420 15421 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, nullptr); 15422 } 15423 15424 // cast from enum literal to error union when payload is an enum 15425 if (actual_type->id == ZigTypeIdEnumLiteral && 15426 (wanted_type->id == ZigTypeIdErrorUnion && wanted_type->data.error_union.payload_type->id == ZigTypeIdEnum)) 15427 { 15428 IrInstGen *result = ir_analyze_enum_literal(ira, source_instr, value, wanted_type->data.error_union.payload_type); 15429 if (type_is_invalid(result->value->type)) 15430 return result; 15431 15432 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, nullptr); 15433 } 15434 15435 // cast from union to the enum type of the union 15436 if (actual_type->id == ZigTypeIdUnion && wanted_type->id == ZigTypeIdEnum) { 15437 if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) 15438 return ira->codegen->invalid_inst_gen; 15439 15440 if (actual_type->data.unionation.tag_type == wanted_type) { 15441 return ir_analyze_union_to_tag(ira, source_instr, value, wanted_type); 15442 } 15443 } 15444 15445 // enum to union which has the enum as the tag type, or 15446 // enum literal to union which has a matching enum as the tag type 15447 if (is_tagged_union(wanted_type) && (actual_type->id == ZigTypeIdEnum || 15448 actual_type->id == ZigTypeIdEnumLiteral)) 15449 { 15450 return ir_analyze_enum_to_union(ira, source_instr, value, wanted_type); 15451 } 15452 15453 // cast from *T to *[1]T 15454 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 15455 actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle) 15456 { 15457 ZigType *array_type = wanted_type->data.pointer.child_type; 15458 if (array_type->id == ZigTypeIdArray && array_type->data.array.len == 1 && 15459 types_match_const_cast_only(ira, array_type->data.array.child_type, 15460 actual_type->data.pointer.child_type, source_node, 15461 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk && 15462 // `types_match_const_cast_only` only gets info for child_types 15463 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && 15464 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) 15465 { 15466 if ((err = ir_cast_ptr_align(ira, source_instr, wanted_type, actual_type, value->base.source_node))) 15467 return ira->codegen->invalid_inst_gen; 15468 15469 return ir_analyze_ptr_to_array(ira, source_instr, value, wanted_type); 15470 } 15471 } 15472 15473 // [:x]T to [*:x]T 15474 // [:x]T to [*c]T 15475 if (wanted_type->id == ZigTypeIdPointer && is_slice(actual_type) && 15476 ((wanted_type->data.pointer.ptr_len == PtrLenUnknown && wanted_type->data.pointer.sentinel != nullptr) || 15477 wanted_type->data.pointer.ptr_len == PtrLenC)) 15478 { 15479 ZigType *slice_ptr_type = resolve_struct_field_type(ira->codegen, 15480 actual_type->data.structure.fields[slice_ptr_index]); 15481 if (types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 15482 slice_ptr_type->data.pointer.child_type, source_node, 15483 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk && 15484 (slice_ptr_type->data.pointer.sentinel != nullptr && 15485 (wanted_type->data.pointer.ptr_len == PtrLenC || 15486 const_values_equal(ira->codegen, wanted_type->data.pointer.sentinel, 15487 slice_ptr_type->data.pointer.sentinel)))) 15488 { 15489 TypeStructField *ptr_field = actual_type->data.structure.fields[slice_ptr_index]; 15490 IrInstGen *slice_ptr = ir_analyze_struct_value_field_value(ira, source_instr, value, ptr_field); 15491 return ir_implicit_cast2(ira, source_instr, slice_ptr, wanted_type); 15492 } 15493 } 15494 15495 // cast from *T and [*]T to *c_void and ?*c_void 15496 // but don't do it if the actual type is a double pointer 15497 if (is_pointery_and_elem_is_not_pointery(actual_type)) { 15498 ZigType *dest_ptr_type = nullptr; 15499 if (wanted_type->id == ZigTypeIdPointer && 15500 actual_type->id != ZigTypeIdOptional && 15501 wanted_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 15502 { 15503 dest_ptr_type = wanted_type; 15504 } else if (wanted_type->id == ZigTypeIdOptional && 15505 wanted_type->data.maybe.child_type->id == ZigTypeIdPointer && 15506 wanted_type->data.maybe.child_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 15507 { 15508 dest_ptr_type = wanted_type->data.maybe.child_type; 15509 } 15510 if (dest_ptr_type != nullptr) { 15511 return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true, 15512 false); 15513 } 15514 } 15515 15516 // cast from T to *T where T is zero bits 15517 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 15518 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 15519 actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 15520 { 15521 bool has_bits; 15522 if ((err = type_has_bits2(ira->codegen, actual_type, &has_bits))) 15523 return ira->codegen->invalid_inst_gen; 15524 if (!has_bits) { 15525 return ir_get_ref(ira, source_instr, value, false, false); 15526 } 15527 } 15528 15529 // cast from @Vector(N, T) to [N]T 15530 if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdVector && 15531 wanted_type->data.array.len == actual_type->data.vector.len && 15532 types_match_const_cast_only(ira, wanted_type->data.array.child_type, 15533 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 15534 { 15535 return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type, nullptr); 15536 } 15537 15538 // cast from [N]T to @Vector(N, T) 15539 if (actual_type->id == ZigTypeIdArray && wanted_type->id == ZigTypeIdVector && 15540 actual_type->data.array.len == wanted_type->data.vector.len && 15541 types_match_const_cast_only(ira, actual_type->data.array.child_type, 15542 wanted_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 15543 { 15544 return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type); 15545 } 15546 15547 // casting between C pointers and normal pointers 15548 if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer && 15549 (wanted_type->data.pointer.ptr_len == PtrLenC || actual_type->data.pointer.ptr_len == PtrLenC) && 15550 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 15551 actual_type->data.pointer.child_type, source_node, 15552 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 15553 { 15554 return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true, false); 15555 } 15556 15557 // cast from integer to C pointer 15558 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC && 15559 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt)) 15560 { 15561 return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type); 15562 } 15563 15564 // cast from inferred struct type to array, union, or struct 15565 if (is_anon_container(actual_type)) { 15566 const bool is_array_init = 15567 actual_type->data.structure.special == StructSpecialInferredTuple; 15568 const uint32_t field_count = actual_type->data.structure.src_field_count; 15569 15570 if (wanted_type->id == ZigTypeIdArray && (is_array_init || field_count == 0) && 15571 wanted_type->data.array.len == field_count) 15572 { 15573 return ir_analyze_struct_literal_to_array(ira, source_instr, value, wanted_type); 15574 } else if (wanted_type->id == ZigTypeIdStruct && 15575 (!is_array_init || field_count == 0)) 15576 { 15577 return ir_analyze_struct_literal_to_struct(ira, source_instr, value, wanted_type); 15578 } else if (wanted_type->id == ZigTypeIdUnion && !is_array_init && field_count == 1) { 15579 return ir_analyze_struct_literal_to_union(ira, source_instr, value, wanted_type); 15580 } 15581 } 15582 15583 // cast from undefined to anything 15584 if (actual_type->id == ZigTypeIdUndefined) { 15585 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); 15586 } 15587 15588 // T to ?U, where T implicitly casts to U 15589 if (wanted_type->id == ZigTypeIdOptional && actual_type->id != ZigTypeIdOptional) { 15590 IrInstGen *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type); 15591 if (type_is_invalid(cast1->value->type)) 15592 return ira->codegen->invalid_inst_gen; 15593 return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); 15594 } 15595 15596 // T to E!U, where T implicitly casts to U 15597 if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id != ZigTypeIdErrorUnion && 15598 actual_type->id != ZigTypeIdErrorSet) 15599 { 15600 IrInstGen *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.error_union.payload_type); 15601 if (type_is_invalid(cast1->value->type)) 15602 return ira->codegen->invalid_inst_gen; 15603 return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); 15604 } 15605 15606 ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, 15607 buf_sprintf("expected type '%s', found '%s'", 15608 buf_ptr(&wanted_type->name), 15609 buf_ptr(&actual_type->name))); 15610 report_recursive_error(ira, source_instr->source_node, &const_cast_result, parent_msg); 15611 return ira->codegen->invalid_inst_gen; 15612 } 15613 15614 static IrInstGen *ir_implicit_cast2(IrAnalyze *ira, IrInst *value_source_instr, 15615 IrInstGen *value, ZigType *expected_type) 15616 { 15617 assert(value); 15618 assert(!expected_type || !type_is_invalid(expected_type)); 15619 assert(value->value->type); 15620 assert(!type_is_invalid(value->value->type)); 15621 if (expected_type == nullptr) 15622 return value; // anything will do 15623 if (expected_type == value->value->type) 15624 return value; // match 15625 if (value->value->type->id == ZigTypeIdUnreachable) 15626 return value; 15627 15628 return ir_analyze_cast(ira, value_source_instr, expected_type, value); 15629 } 15630 15631 static IrInstGen *ir_implicit_cast(IrAnalyze *ira, IrInstGen *value, ZigType *expected_type) { 15632 return ir_implicit_cast2(ira, &value->base, value, expected_type); 15633 } 15634 15635 static ZigType *get_ptr_elem_type(CodeGen *g, IrInstGen *ptr) { 15636 ir_assert_gen(ptr->value->type->id == ZigTypeIdPointer, ptr); 15637 ZigType *elem_type = ptr->value->type->data.pointer.child_type; 15638 if (elem_type != g->builtin_types.entry_anytype) 15639 return elem_type; 15640 15641 if (ir_resolve_lazy(g, ptr->base.source_node, ptr->value)) 15642 return g->builtin_types.entry_invalid; 15643 15644 assert(value_is_comptime(ptr->value)); 15645 ZigValue *pointee = const_ptr_pointee_unchecked(g, ptr->value); 15646 return pointee->type; 15647 } 15648 15649 static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *ptr, 15650 ResultLoc *result_loc) 15651 { 15652 Error err; 15653 ZigType *ptr_type = ptr->value->type; 15654 if (type_is_invalid(ptr_type)) 15655 return ira->codegen->invalid_inst_gen; 15656 15657 if (ptr_type->id != ZigTypeIdPointer) { 15658 ir_add_error_node(ira, source_instruction->source_node, 15659 buf_sprintf("attempt to dereference non-pointer type '%s'", 15660 buf_ptr(&ptr_type->name))); 15661 return ira->codegen->invalid_inst_gen; 15662 } 15663 15664 ZigType *child_type = ptr_type->data.pointer.child_type; 15665 if (type_is_invalid(child_type)) 15666 return ira->codegen->invalid_inst_gen; 15667 // if the child type has one possible value, the deref is comptime 15668 switch (type_has_one_possible_value(ira->codegen, child_type)) { 15669 case OnePossibleValueInvalid: 15670 return ira->codegen->invalid_inst_gen; 15671 case OnePossibleValueYes: 15672 return ir_const_move(ira, source_instruction, 15673 get_the_one_possible_value(ira->codegen, child_type)); 15674 case OnePossibleValueNo: 15675 break; 15676 } 15677 if (instr_is_comptime(ptr)) { 15678 if (ptr->value->special == ConstValSpecialUndef) { 15679 // If we are in a TypeOf call, we return an undefined value instead of erroring 15680 // since we know the type. 15681 if (get_scope_typeof(source_instruction->scope)) { 15682 return ir_const_undef(ira, source_instruction, child_type); 15683 } 15684 15685 ir_add_error(ira, &ptr->base, buf_sprintf("attempt to dereference undefined value")); 15686 return ira->codegen->invalid_inst_gen; 15687 } 15688 if (ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 15689 ZigValue *pointee = const_ptr_pointee_unchecked(ira->codegen, ptr->value); 15690 if (child_type == ira->codegen->builtin_types.entry_anytype) { 15691 child_type = pointee->type; 15692 } 15693 if (pointee->special != ConstValSpecialRuntime) { 15694 IrInstGen *result = ir_const(ira, source_instruction, child_type); 15695 15696 if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, result->value, 15697 ptr->value))) 15698 { 15699 return ira->codegen->invalid_inst_gen; 15700 } 15701 result->value->type = child_type; 15702 return result; 15703 } 15704 } 15705 } 15706 15707 // if the instruction is a const ref instruction we can skip it 15708 if (ptr->id == IrInstGenIdRef) { 15709 IrInstGenRef *ref_inst = reinterpret_cast<IrInstGenRef *>(ptr); 15710 return ref_inst->operand; 15711 } 15712 15713 // If the instruction is a element pointer instruction to a vector, we emit 15714 // vector element extract instruction rather than load pointer. If the 15715 // pointer type has non-VECTOR_INDEX_RUNTIME value, it would have been 15716 // possible to implement this in the codegen for IrInstGenLoadPtr. 15717 // However if it has VECTOR_INDEX_RUNTIME then we must emit a compile error 15718 // if the vector index cannot be determined right here, right now, because 15719 // the type information does not contain enough information to actually 15720 // perform a dereference. 15721 if (ptr_type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) { 15722 if (ptr->id == IrInstGenIdElemPtr) { 15723 IrInstGenElemPtr *elem_ptr = (IrInstGenElemPtr *)ptr; 15724 IrInstGen *vector_loaded = ir_get_deref(ira, &elem_ptr->array_ptr->base, 15725 elem_ptr->array_ptr, nullptr); 15726 IrInstGen *elem_index = elem_ptr->elem_index; 15727 return ir_build_vector_extract_elem(ira, source_instruction, vector_loaded, elem_index); 15728 } 15729 ir_add_error(ira, &ptr->base, 15730 buf_sprintf("unable to determine vector element index of type '%s'", buf_ptr(&ptr_type->name))); 15731 return ira->codegen->invalid_inst_gen; 15732 } 15733 15734 IrInstGen *result_loc_inst; 15735 if (ptr_type->data.pointer.host_int_bytes != 0 && handle_is_ptr(ira->codegen, child_type)) { 15736 if (result_loc == nullptr) result_loc = no_result_loc(); 15737 result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, true, true); 15738 if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { 15739 return result_loc_inst; 15740 } 15741 } else { 15742 result_loc_inst = nullptr; 15743 } 15744 15745 return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst); 15746 } 15747 15748 static bool ir_resolve_const_align(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, 15749 ZigValue *const_val, uint32_t *out) 15750 { 15751 Error err; 15752 if ((err = ir_resolve_const_val(codegen, exec, source_node, const_val, UndefBad))) 15753 return false; 15754 15755 uint32_t align_bytes = bigint_as_u32(&const_val->data.x_bigint); 15756 if (align_bytes == 0) { 15757 exec_add_error_node_gen(codegen, exec, source_node, buf_sprintf("alignment must be >= 1")); 15758 return false; 15759 } 15760 15761 if (!is_power_of_2(align_bytes)) { 15762 exec_add_error_node_gen(codegen, exec, source_node, 15763 buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); 15764 return false; 15765 } 15766 15767 *out = align_bytes; 15768 return true; 15769 } 15770 15771 static bool ir_resolve_align(IrAnalyze *ira, IrInstGen *value, ZigType *elem_type, uint32_t *out) { 15772 if (type_is_invalid(value->value->type)) 15773 return false; 15774 15775 // Look for this pattern: `*align(@alignOf(T)) T`. 15776 // This can be resolved to be `*out = 0` without resolving any alignment. 15777 if (elem_type != nullptr && value->value->special == ConstValSpecialLazy && 15778 value->value->data.x_lazy->id == LazyValueIdAlignOf) 15779 { 15780 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(value->value->data.x_lazy); 15781 15782 ZigType *lazy_elem_type = ir_resolve_type(lazy_align_of->ira, lazy_align_of->target_type); 15783 if (type_is_invalid(lazy_elem_type)) 15784 return false; 15785 15786 if (elem_type == lazy_elem_type) { 15787 *out = 0; 15788 return true; 15789 } 15790 } 15791 15792 IrInstGen *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); 15793 if (type_is_invalid(casted_value->value->type)) 15794 return false; 15795 15796 return ir_resolve_const_align(ira->codegen, ira->new_irb.exec, value->base.source_node, 15797 casted_value->value, out); 15798 } 15799 15800 static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstGen *value, ZigType *int_type, uint64_t *out) { 15801 if (type_is_invalid(value->value->type)) 15802 return false; 15803 15804 IrInstGen *casted_value = ir_implicit_cast(ira, value, int_type); 15805 if (type_is_invalid(casted_value->value->type)) 15806 return false; 15807 15808 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15809 if (!const_val) 15810 return false; 15811 15812 *out = bigint_as_u64(&const_val->data.x_bigint); 15813 return true; 15814 } 15815 15816 static bool ir_resolve_usize(IrAnalyze *ira, IrInstGen *value, uint64_t *out) { 15817 return ir_resolve_unsigned(ira, value, ira->codegen->builtin_types.entry_usize, out); 15818 } 15819 15820 static bool ir_resolve_bool(IrAnalyze *ira, IrInstGen *value, bool *out) { 15821 if (type_is_invalid(value->value->type)) 15822 return false; 15823 15824 IrInstGen *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_bool); 15825 if (type_is_invalid(casted_value->value->type)) 15826 return false; 15827 15828 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15829 if (!const_val) 15830 return false; 15831 15832 *out = const_val->data.x_bool; 15833 return true; 15834 } 15835 15836 static bool ir_resolve_comptime(IrAnalyze *ira, IrInstGen *value, bool *out) { 15837 if (!value) { 15838 *out = false; 15839 return true; 15840 } 15841 return ir_resolve_bool(ira, value, out); 15842 } 15843 15844 static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstGen *value, AtomicOrder *out) { 15845 if (type_is_invalid(value->value->type)) 15846 return false; 15847 15848 ZigType *atomic_order_type = get_builtin_type(ira->codegen, "AtomicOrder"); 15849 15850 IrInstGen *casted_value = ir_implicit_cast(ira, value, atomic_order_type); 15851 if (type_is_invalid(casted_value->value->type)) 15852 return false; 15853 15854 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15855 if (!const_val) 15856 return false; 15857 15858 *out = (AtomicOrder)bigint_as_u32(&const_val->data.x_enum_tag); 15859 return true; 15860 } 15861 15862 static bool ir_resolve_atomic_rmw_op(IrAnalyze *ira, IrInstGen *value, AtomicRmwOp *out) { 15863 if (type_is_invalid(value->value->type)) 15864 return false; 15865 15866 ZigType *atomic_rmw_op_type = get_builtin_type(ira->codegen, "AtomicRmwOp"); 15867 15868 IrInstGen *casted_value = ir_implicit_cast(ira, value, atomic_rmw_op_type); 15869 if (type_is_invalid(casted_value->value->type)) 15870 return false; 15871 15872 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15873 if (!const_val) 15874 return false; 15875 15876 *out = (AtomicRmwOp)bigint_as_u32(&const_val->data.x_enum_tag); 15877 return true; 15878 } 15879 15880 static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstGen *value, GlobalLinkageId *out) { 15881 if (type_is_invalid(value->value->type)) 15882 return false; 15883 15884 ZigType *global_linkage_type = get_builtin_type(ira->codegen, "GlobalLinkage"); 15885 15886 IrInstGen *casted_value = ir_implicit_cast(ira, value, global_linkage_type); 15887 if (type_is_invalid(casted_value->value->type)) 15888 return false; 15889 15890 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15891 if (!const_val) 15892 return false; 15893 15894 *out = (GlobalLinkageId)bigint_as_u32(&const_val->data.x_enum_tag); 15895 return true; 15896 } 15897 15898 static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstGen *value, FloatMode *out) { 15899 if (type_is_invalid(value->value->type)) 15900 return false; 15901 15902 ZigType *float_mode_type = get_builtin_type(ira->codegen, "FloatMode"); 15903 15904 IrInstGen *casted_value = ir_implicit_cast(ira, value, float_mode_type); 15905 if (type_is_invalid(casted_value->value->type)) 15906 return false; 15907 15908 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15909 if (!const_val) 15910 return false; 15911 15912 *out = (FloatMode)bigint_as_u32(&const_val->data.x_enum_tag); 15913 return true; 15914 } 15915 15916 static Buf *ir_resolve_str(IrAnalyze *ira, IrInstGen *value) { 15917 if (type_is_invalid(value->value->type)) 15918 return nullptr; 15919 15920 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 15921 true, false, PtrLenUnknown, 0, 0, 0, false); 15922 ZigType *str_type = get_slice_type(ira->codegen, ptr_type); 15923 IrInstGen *casted_value = ir_implicit_cast(ira, value, str_type); 15924 if (type_is_invalid(casted_value->value->type)) 15925 return nullptr; 15926 15927 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15928 if (!const_val) 15929 return nullptr; 15930 15931 ZigValue *ptr_field = const_val->data.x_struct.fields[slice_ptr_index]; 15932 ZigValue *len_field = const_val->data.x_struct.fields[slice_len_index]; 15933 15934 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); 15935 ZigValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; 15936 expand_undef_array(ira->codegen, array_val); 15937 size_t len = bigint_as_usize(&len_field->data.x_bigint); 15938 if (array_val->data.x_array.special == ConstArraySpecialBuf && len == buf_len(array_val->data.x_array.data.s_buf)) { 15939 return array_val->data.x_array.data.s_buf; 15940 } 15941 Buf *result = buf_alloc(); 15942 buf_resize(result, len); 15943 for (size_t i = 0; i < len; i += 1) { 15944 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; 15945 ZigValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index]; 15946 if (char_val->special == ConstValSpecialUndef) { 15947 ir_add_error(ira, &casted_value->base, buf_sprintf("use of undefined value")); 15948 return nullptr; 15949 } 15950 uint64_t big_c = bigint_as_u64(&char_val->data.x_bigint); 15951 assert(big_c <= UINT8_MAX); 15952 uint8_t c = (uint8_t)big_c; 15953 buf_ptr(result)[i] = c; 15954 } 15955 return result; 15956 } 15957 15958 static IrInstGen *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, 15959 IrInstSrcAddImplicitReturnType *instruction) 15960 { 15961 IrInstGen *value = instruction->value->child; 15962 if (type_is_invalid(value->value->type)) 15963 return ir_unreach_error(ira); 15964 15965 if (instruction->result_loc_ret == nullptr || !instruction->result_loc_ret->implicit_return_type_done) { 15966 ira->src_implicit_return_type_list.append(value); 15967 } 15968 15969 return ir_const_void(ira, &instruction->base.base); 15970 } 15971 15972 static IrInstGen *ir_analyze_instruction_return(IrAnalyze *ira, IrInstSrcReturn *instruction) { 15973 if (instruction->operand == nullptr) { 15974 // result location mechanism took care of it. 15975 IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, nullptr); 15976 return ir_finish_anal(ira, result); 15977 } 15978 15979 IrInstGen *operand = instruction->operand->child; 15980 if (type_is_invalid(operand->value->type)) 15981 return ir_unreach_error(ira); 15982 15983 IrInstGen *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type); 15984 if (type_is_invalid(casted_operand->value->type)) { 15985 AstNode *source_node = ira->explicit_return_type_source_node; 15986 if (source_node != nullptr) { 15987 ErrorMsg *msg = ira->codegen->errors.last(); 15988 add_error_note(ira->codegen, msg, source_node, 15989 buf_sprintf("return type declared here")); 15990 } 15991 return ir_unreach_error(ira); 15992 } 15993 15994 if (!instr_is_comptime(operand) && ira->explicit_return_type != nullptr && 15995 handle_is_ptr(ira->codegen, ira->explicit_return_type)) 15996 { 15997 // result location mechanism took care of it. 15998 IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, nullptr); 15999 return ir_finish_anal(ira, result); 16000 } 16001 16002 if (casted_operand->value->special == ConstValSpecialRuntime && 16003 casted_operand->value->type->id == ZigTypeIdPointer && 16004 casted_operand->value->data.rh_ptr == RuntimeHintPtrStack) 16005 { 16006 ir_add_error(ira, &instruction->operand->base, buf_sprintf("function returns address of local variable")); 16007 return ir_unreach_error(ira); 16008 } 16009 16010 IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, casted_operand); 16011 return ir_finish_anal(ira, result); 16012 } 16013 16014 static IrInstGen *ir_analyze_instruction_const(IrAnalyze *ira, IrInstSrcConst *instruction) { 16015 return ir_const_move(ira, &instruction->base.base, instruction->value); 16016 } 16017 16018 static IrInstGen *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { 16019 IrInstGen *op1 = bin_op_instruction->op1->child; 16020 if (type_is_invalid(op1->value->type)) 16021 return ira->codegen->invalid_inst_gen; 16022 16023 IrInstGen *op2 = bin_op_instruction->op2->child; 16024 if (type_is_invalid(op2->value->type)) 16025 return ira->codegen->invalid_inst_gen; 16026 16027 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 16028 16029 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, bool_type); 16030 if (type_is_invalid(casted_op1->value->type)) 16031 return ira->codegen->invalid_inst_gen; 16032 16033 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, bool_type); 16034 if (type_is_invalid(casted_op2->value->type)) 16035 return ira->codegen->invalid_inst_gen; 16036 16037 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 16038 ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 16039 if (op1_val == nullptr) 16040 return ira->codegen->invalid_inst_gen; 16041 16042 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 16043 if (op2_val == nullptr) 16044 return ira->codegen->invalid_inst_gen; 16045 16046 assert(casted_op1->value->type->id == ZigTypeIdBool); 16047 assert(casted_op2->value->type->id == ZigTypeIdBool); 16048 bool result_bool; 16049 if (bin_op_instruction->op_id == IrBinOpBoolOr) { 16050 result_bool = op1_val->data.x_bool || op2_val->data.x_bool; 16051 } else if (bin_op_instruction->op_id == IrBinOpBoolAnd) { 16052 result_bool = op1_val->data.x_bool && op2_val->data.x_bool; 16053 } else { 16054 zig_unreachable(); 16055 } 16056 return ir_const_bool(ira, &bin_op_instruction->base.base, result_bool); 16057 } 16058 16059 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, bool_type, 16060 bin_op_instruction->op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 16061 } 16062 16063 static bool resolve_cmp_op_id(IrBinOp op_id, Cmp cmp) { 16064 switch (op_id) { 16065 case IrBinOpCmpEq: 16066 return cmp == CmpEQ; 16067 case IrBinOpCmpNotEq: 16068 return cmp != CmpEQ; 16069 case IrBinOpCmpLessThan: 16070 return cmp == CmpLT; 16071 case IrBinOpCmpGreaterThan: 16072 return cmp == CmpGT; 16073 case IrBinOpCmpLessOrEq: 16074 return cmp != CmpGT; 16075 case IrBinOpCmpGreaterOrEq: 16076 return cmp != CmpLT; 16077 default: 16078 zig_unreachable(); 16079 } 16080 } 16081 16082 static void set_optional_value_to_null(ZigValue *val) { 16083 assert(val->special == ConstValSpecialStatic); 16084 if (val->type->id == ZigTypeIdNull) return; // nothing to do 16085 assert(val->type->id == ZigTypeIdOptional); 16086 if (get_src_ptr_type(val->type) != nullptr) { 16087 val->data.x_ptr.special = ConstPtrSpecialNull; 16088 } else if (is_opt_err_set(val->type)) { 16089 val->data.x_err_set = nullptr; 16090 } else { 16091 val->data.x_optional = nullptr; 16092 } 16093 } 16094 16095 static void set_optional_payload(ZigValue *opt_val, ZigValue *payload) { 16096 assert(opt_val->special == ConstValSpecialStatic); 16097 assert(opt_val->type->id == ZigTypeIdOptional); 16098 if (payload == nullptr) { 16099 set_optional_value_to_null(opt_val); 16100 } else if (is_opt_err_set(opt_val->type)) { 16101 assert(payload->type->id == ZigTypeIdErrorSet); 16102 opt_val->data.x_err_set = payload->data.x_err_set; 16103 } else { 16104 opt_val->data.x_optional = payload; 16105 } 16106 } 16107 16108 static IrInstGen *ir_evaluate_bin_op_cmp(IrAnalyze *ira, ZigType *resolved_type, 16109 ZigValue *op1_val, ZigValue *op2_val, IrInst *source_instr, IrBinOp op_id, 16110 bool one_possible_value) 16111 { 16112 if (op1_val->special == ConstValSpecialUndef || 16113 op2_val->special == ConstValSpecialUndef) 16114 return ir_const_undef(ira, source_instr, resolved_type); 16115 if (resolved_type->id == ZigTypeIdPointer && op_id != IrBinOpCmpEq && op_id != IrBinOpCmpNotEq) { 16116 if ((op1_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 16117 op1_val->data.x_ptr.special == ConstPtrSpecialNull) && 16118 (op2_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 16119 op2_val->data.x_ptr.special == ConstPtrSpecialNull)) 16120 { 16121 uint64_t op1_addr = op1_val->data.x_ptr.special == ConstPtrSpecialNull ? 16122 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr; 16123 uint64_t op2_addr = op2_val->data.x_ptr.special == ConstPtrSpecialNull ? 16124 0 : op2_val->data.x_ptr.data.hard_coded_addr.addr; 16125 Cmp cmp_result; 16126 if (op1_addr > op2_addr) { 16127 cmp_result = CmpGT; 16128 } else if (op1_addr < op2_addr) { 16129 cmp_result = CmpLT; 16130 } else { 16131 cmp_result = CmpEQ; 16132 } 16133 bool answer = resolve_cmp_op_id(op_id, cmp_result); 16134 return ir_const_bool(ira, source_instr, answer); 16135 } 16136 } else { 16137 bool are_equal = one_possible_value || const_values_equal(ira->codegen, op1_val, op2_val); 16138 bool answer; 16139 if (op_id == IrBinOpCmpEq) { 16140 answer = are_equal; 16141 } else if (op_id == IrBinOpCmpNotEq) { 16142 answer = !are_equal; 16143 } else { 16144 zig_unreachable(); 16145 } 16146 return ir_const_bool(ira, source_instr, answer); 16147 } 16148 zig_unreachable(); 16149 } 16150 16151 static IrInstGen *ir_try_evaluate_bin_op_cmp_const(IrAnalyze *ira, IrInst *source_instr, IrInstGen *op1, IrInstGen *op2, 16152 ZigType *resolved_type, IrBinOp op_id) 16153 { 16154 assert(op1->value->type == resolved_type && op2->value->type == resolved_type); 16155 bool one_possible_value; 16156 switch (type_has_one_possible_value(ira->codegen, resolved_type)) { 16157 case OnePossibleValueInvalid: 16158 return ira->codegen->invalid_inst_gen; 16159 case OnePossibleValueYes: 16160 one_possible_value = true; 16161 break; 16162 case OnePossibleValueNo: 16163 one_possible_value = false; 16164 break; 16165 } 16166 16167 if (one_possible_value || (instr_is_comptime(op1) && instr_is_comptime(op2))) { 16168 ZigValue *op1_val = one_possible_value ? op1->value : ir_resolve_const(ira, op1, UndefBad); 16169 if (op1_val == nullptr) 16170 return ira->codegen->invalid_inst_gen; 16171 ZigValue *op2_val = one_possible_value ? op2->value : ir_resolve_const(ira, op2, UndefBad); 16172 if (op2_val == nullptr) 16173 return ira->codegen->invalid_inst_gen; 16174 if (resolved_type->id != ZigTypeIdVector) 16175 return ir_evaluate_bin_op_cmp(ira, resolved_type, op1_val, op2_val, source_instr, op_id, one_possible_value); 16176 IrInstGen *result = ir_const(ira, source_instr, 16177 get_vector_type(ira->codegen, resolved_type->data.vector.len, ira->codegen->builtin_types.entry_bool)); 16178 result->value->data.x_array.data.s_none.elements = 16179 ira->codegen->pass1_arena->allocate<ZigValue>(resolved_type->data.vector.len); 16180 16181 expand_undef_array(ira->codegen, result->value); 16182 for (size_t i = 0;i < resolved_type->data.vector.len;i++) { 16183 IrInstGen *cur_res = ir_evaluate_bin_op_cmp(ira, resolved_type->data.vector.elem_type, 16184 &op1_val->data.x_array.data.s_none.elements[i], 16185 &op2_val->data.x_array.data.s_none.elements[i], 16186 source_instr, op_id, one_possible_value); 16187 copy_const_val(ira->codegen, &result->value->data.x_array.data.s_none.elements[i], cur_res->value); 16188 } 16189 return result; 16190 } else { 16191 return nullptr; 16192 } 16193 } 16194 16195 // Returns ErrorNotLazy when the value cannot be determined 16196 static Error lazy_cmp_zero(CodeGen *codegen, AstNode *source_node, ZigValue *val, Cmp *result) { 16197 Error err; 16198 16199 switch (type_has_one_possible_value(codegen, val->type)) { 16200 case OnePossibleValueInvalid: 16201 return ErrorSemanticAnalyzeFail; 16202 case OnePossibleValueNo: 16203 break; 16204 case OnePossibleValueYes: 16205 switch (val->type->id) { 16206 case ZigTypeIdInt: 16207 src_assert(val->type->data.integral.bit_count == 0, source_node); 16208 *result = CmpEQ; 16209 return ErrorNone; 16210 case ZigTypeIdUndefined: 16211 return ErrorNotLazy; 16212 default: 16213 zig_unreachable(); 16214 } 16215 } 16216 16217 switch (val->special) { 16218 case ConstValSpecialRuntime: 16219 case ConstValSpecialUndef: 16220 return ErrorNotLazy; 16221 case ConstValSpecialStatic: 16222 switch (val->type->id) { 16223 case ZigTypeIdComptimeInt: 16224 case ZigTypeIdInt: 16225 *result = bigint_cmp_zero(&val->data.x_bigint); 16226 return ErrorNone; 16227 case ZigTypeIdComptimeFloat: 16228 case ZigTypeIdFloat: 16229 if (float_is_nan(val)) 16230 return ErrorNotLazy; 16231 *result = float_cmp_zero(val); 16232 return ErrorNone; 16233 default: 16234 return ErrorNotLazy; 16235 } 16236 case ConstValSpecialLazy: 16237 switch (val->data.x_lazy->id) { 16238 case LazyValueIdInvalid: 16239 zig_unreachable(); 16240 case LazyValueIdAlignOf: { 16241 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy); 16242 IrAnalyze *ira = lazy_align_of->ira; 16243 16244 bool is_zero_bits; 16245 if ((err = type_val_resolve_zero_bits(ira->codegen, lazy_align_of->target_type->value, 16246 nullptr, nullptr, &is_zero_bits))) 16247 { 16248 return err; 16249 } 16250 16251 *result = is_zero_bits ? CmpEQ : CmpGT; 16252 return ErrorNone; 16253 } 16254 case LazyValueIdSizeOf: { 16255 LazyValueSizeOf *lazy_size_of = reinterpret_cast<LazyValueSizeOf *>(val->data.x_lazy); 16256 IrAnalyze *ira = lazy_size_of->ira; 16257 bool is_zero_bits; 16258 if ((err = type_val_resolve_zero_bits(ira->codegen, lazy_size_of->target_type->value, 16259 nullptr, nullptr, &is_zero_bits))) 16260 { 16261 return err; 16262 } 16263 *result = is_zero_bits ? CmpEQ : CmpGT; 16264 return ErrorNone; 16265 } 16266 default: 16267 return ErrorNotLazy; 16268 } 16269 } 16270 zig_unreachable(); 16271 } 16272 16273 static ErrorMsg *ir_eval_bin_op_cmp_scalar(IrAnalyze *ira, IrInst* source_instr, 16274 ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val, ZigValue *out_val) 16275 { 16276 Error err; 16277 { 16278 // Before resolving the values, we special case comparisons against zero. These can often 16279 // be done without resolving lazy values, preventing potential dependency loops. 16280 Cmp op1_cmp_zero; 16281 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op1_val, &op1_cmp_zero))) { 16282 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally; 16283 return ira->codegen->trace_err; 16284 } 16285 Cmp op2_cmp_zero; 16286 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op2_val, &op2_cmp_zero))) { 16287 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally; 16288 return ira->codegen->trace_err; 16289 } 16290 bool can_cmp_zero = false; 16291 Cmp cmp_result; 16292 if (op1_cmp_zero == CmpEQ && op2_cmp_zero == CmpEQ) { 16293 can_cmp_zero = true; 16294 cmp_result = CmpEQ; 16295 } else if (op1_cmp_zero == CmpGT && op2_cmp_zero == CmpEQ) { 16296 can_cmp_zero = true; 16297 cmp_result = CmpGT; 16298 } else if (op1_cmp_zero == CmpEQ && op2_cmp_zero == CmpGT) { 16299 can_cmp_zero = true; 16300 cmp_result = CmpLT; 16301 } else if (op1_cmp_zero == CmpLT && op2_cmp_zero == CmpEQ) { 16302 can_cmp_zero = true; 16303 cmp_result = CmpLT; 16304 } else if (op1_cmp_zero == CmpEQ && op2_cmp_zero == CmpLT) { 16305 can_cmp_zero = true; 16306 cmp_result = CmpGT; 16307 } else if (op1_cmp_zero == CmpLT && op2_cmp_zero == CmpGT) { 16308 can_cmp_zero = true; 16309 cmp_result = CmpLT; 16310 } else if (op1_cmp_zero == CmpGT && op2_cmp_zero == CmpLT) { 16311 can_cmp_zero = true; 16312 cmp_result = CmpGT; 16313 } 16314 if (can_cmp_zero) { 16315 bool answer = resolve_cmp_op_id(op_id, cmp_result); 16316 out_val->special = ConstValSpecialStatic; 16317 out_val->data.x_bool = answer; 16318 return nullptr; 16319 } 16320 } 16321 never_mind_just_calculate_it_normally: 16322 16323 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_instr->source_node, 16324 op1_val, UndefOk))) 16325 { 16326 return ira->codegen->trace_err; 16327 } 16328 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_instr->source_node, 16329 op2_val, UndefOk))) 16330 { 16331 return ira->codegen->trace_err; 16332 } 16333 16334 16335 if (op1_val->special == ConstValSpecialUndef || op2_val->special == ConstValSpecialUndef || 16336 op1_val->type->id == ZigTypeIdUndefined || op2_val->type->id == ZigTypeIdUndefined) 16337 { 16338 out_val->special = ConstValSpecialUndef; 16339 return nullptr; 16340 } 16341 16342 bool op1_is_float = op1_val->type->id == ZigTypeIdFloat || op1_val->type->id == ZigTypeIdComptimeFloat; 16343 bool op2_is_float = op2_val->type->id == ZigTypeIdFloat || op2_val->type->id == ZigTypeIdComptimeFloat; 16344 if (op1_is_float && op2_is_float) { 16345 if (float_is_nan(op1_val) || float_is_nan(op2_val)) { 16346 out_val->special = ConstValSpecialStatic; 16347 out_val->data.x_bool = op_id == IrBinOpCmpNotEq; 16348 return nullptr; 16349 } 16350 if (op1_val->type->id == ZigTypeIdComptimeFloat) { 16351 IrInstGen *tmp = ir_const_noval(ira, source_instr); 16352 tmp->value = op1_val; 16353 IrInstGen *casted = ir_implicit_cast(ira, tmp, op2_val->type); 16354 op1_val = casted->value; 16355 } else if (op2_val->type->id == ZigTypeIdComptimeFloat) { 16356 IrInstGen *tmp = ir_const_noval(ira, source_instr); 16357 tmp->value = op2_val; 16358 IrInstGen *casted = ir_implicit_cast(ira, tmp, op1_val->type); 16359 op2_val = casted->value; 16360 } 16361 Cmp cmp_result = float_cmp(op1_val, op2_val); 16362 out_val->special = ConstValSpecialStatic; 16363 out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result); 16364 return nullptr; 16365 } 16366 16367 bool op1_is_int = op1_val->type->id == ZigTypeIdInt || op1_val->type->id == ZigTypeIdComptimeInt; 16368 bool op2_is_int = op2_val->type->id == ZigTypeIdInt || op2_val->type->id == ZigTypeIdComptimeInt; 16369 16370 if (op1_is_int && op2_is_int) { 16371 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); 16372 out_val->special = ConstValSpecialStatic; 16373 out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result); 16374 16375 return nullptr; 16376 } 16377 16378 // Handle the case where one of the two operands is a fp value and the other 16379 // is an integer value 16380 ZigValue *float_val; 16381 if (op1_is_int && op2_is_float) { 16382 float_val = op2_val; 16383 } else if (op1_is_float && op2_is_int) { 16384 float_val = op1_val; 16385 } else { 16386 zig_unreachable(); 16387 } 16388 16389 // They can never be equal if the fp value has a non-zero decimal part 16390 if (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq) { 16391 if (float_has_fraction(float_val)) { 16392 out_val->special = ConstValSpecialStatic; 16393 out_val->data.x_bool = op_id == IrBinOpCmpNotEq; 16394 return nullptr; 16395 } 16396 } 16397 16398 // Cast the integer operand into a fp value to perform the comparison 16399 BigFloat op1_bigfloat; 16400 BigFloat op2_bigfloat; 16401 value_to_bigfloat(&op1_bigfloat, op1_val); 16402 value_to_bigfloat(&op2_bigfloat, op2_val); 16403 16404 Cmp cmp_result = bigfloat_cmp(&op1_bigfloat, &op2_bigfloat); 16405 out_val->special = ConstValSpecialStatic; 16406 out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result); 16407 16408 return nullptr; 16409 } 16410 16411 static IrInstGen *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInst *source_instr, 16412 IrInstGen *op1, IrInstGen *op2, IrBinOp op_id) 16413 { 16414 Error err; 16415 16416 ZigType *scalar_result_type = ira->codegen->builtin_types.entry_bool; 16417 ZigType *result_type = scalar_result_type; 16418 ZigType *op1_scalar_type = op1->value->type; 16419 ZigType *op2_scalar_type = op2->value->type; 16420 if (op1->value->type->id == ZigTypeIdVector && op2->value->type->id == ZigTypeIdVector) { 16421 if (op1->value->type->data.vector.len != op2->value->type->data.vector.len) { 16422 ir_add_error(ira, source_instr, 16423 buf_sprintf("vector length mismatch: %" PRIu64 " and %" PRIu64, 16424 op1->value->type->data.vector.len, op2->value->type->data.vector.len)); 16425 return ira->codegen->invalid_inst_gen; 16426 } 16427 result_type = get_vector_type(ira->codegen, op1->value->type->data.vector.len, scalar_result_type); 16428 op1_scalar_type = op1->value->type->data.vector.elem_type; 16429 op2_scalar_type = op2->value->type->data.vector.elem_type; 16430 } else if (op1->value->type->id == ZigTypeIdVector || op2->value->type->id == ZigTypeIdVector) { 16431 ir_add_error(ira, source_instr, 16432 buf_sprintf("mixed scalar and vector operands to comparison operator: '%s' and '%s'", 16433 buf_ptr(&op1->value->type->name), buf_ptr(&op2->value->type->name))); 16434 return ira->codegen->invalid_inst_gen; 16435 } 16436 16437 bool opv_op1; 16438 switch (type_has_one_possible_value(ira->codegen, op1->value->type)) { 16439 case OnePossibleValueInvalid: 16440 return ira->codegen->invalid_inst_gen; 16441 case OnePossibleValueYes: 16442 opv_op1 = true; 16443 break; 16444 case OnePossibleValueNo: 16445 opv_op1 = false; 16446 break; 16447 } 16448 bool opv_op2; 16449 switch (type_has_one_possible_value(ira->codegen, op2->value->type)) { 16450 case OnePossibleValueInvalid: 16451 return ira->codegen->invalid_inst_gen; 16452 case OnePossibleValueYes: 16453 opv_op2 = true; 16454 break; 16455 case OnePossibleValueNo: 16456 opv_op2 = false; 16457 break; 16458 } 16459 Cmp op1_cmp_zero; 16460 bool have_op1_cmp_zero = false; 16461 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op1->value, &op1_cmp_zero))) { 16462 if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen; 16463 } else { 16464 have_op1_cmp_zero = true; 16465 } 16466 Cmp op2_cmp_zero; 16467 bool have_op2_cmp_zero = false; 16468 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op2->value, &op2_cmp_zero))) { 16469 if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen; 16470 } else { 16471 have_op2_cmp_zero = true; 16472 } 16473 if (((opv_op1 || instr_is_comptime(op1)) && (opv_op2 || instr_is_comptime(op2))) || 16474 (have_op1_cmp_zero && have_op2_cmp_zero)) 16475 { 16476 IrInstGen *result_instruction = ir_const(ira, source_instr, result_type); 16477 ZigValue *out_val = result_instruction->value; 16478 if (result_type->id == ZigTypeIdVector) { 16479 size_t len = result_type->data.vector.len; 16480 expand_undef_array(ira->codegen, op1->value); 16481 expand_undef_array(ira->codegen, op2->value); 16482 out_val->special = ConstValSpecialUndef; 16483 expand_undef_array(ira->codegen, out_val); 16484 for (size_t i = 0; i < len; i += 1) { 16485 ZigValue *scalar_op1_val = &op1->value->data.x_array.data.s_none.elements[i]; 16486 ZigValue *scalar_op2_val = &op2->value->data.x_array.data.s_none.elements[i]; 16487 ZigValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 16488 assert(scalar_out_val->type == scalar_result_type); 16489 ErrorMsg *msg = ir_eval_bin_op_cmp_scalar(ira, source_instr, 16490 scalar_op1_val, op_id, scalar_op2_val, scalar_out_val); 16491 if (msg != nullptr) { 16492 add_error_note(ira->codegen, msg, source_instr->source_node, 16493 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 16494 return ira->codegen->invalid_inst_gen; 16495 } 16496 } 16497 out_val->type = result_type; 16498 out_val->special = ConstValSpecialStatic; 16499 } else { 16500 if (ir_eval_bin_op_cmp_scalar(ira, source_instr, op1->value, op_id, 16501 op2->value, out_val) != nullptr) 16502 { 16503 return ira->codegen->invalid_inst_gen; 16504 } 16505 } 16506 return result_instruction; 16507 } 16508 16509 // If one operand has a comptime-known comparison with 0, and the other operand is unsigned, we might 16510 // know the answer, depending on the operator. 16511 // TODO make this work with vectors 16512 if (have_op1_cmp_zero && op2_scalar_type->id == ZigTypeIdInt && !op2_scalar_type->data.integral.is_signed) { 16513 if (op1_cmp_zero == CmpEQ) { 16514 // 0 <= unsigned_x // true 16515 // 0 > unsigned_x // false 16516 switch (op_id) { 16517 case IrBinOpCmpLessOrEq: 16518 return ir_const_bool(ira, source_instr, true); 16519 case IrBinOpCmpGreaterThan: 16520 return ir_const_bool(ira, source_instr, false); 16521 default: 16522 break; 16523 } 16524 } else if (op1_cmp_zero == CmpLT) { 16525 // -1 != unsigned_x // true 16526 // -1 <= unsigned_x // true 16527 // -1 < unsigned_x // true 16528 // -1 == unsigned_x // false 16529 // -1 >= unsigned_x // false 16530 // -1 > unsigned_x // false 16531 switch (op_id) { 16532 case IrBinOpCmpNotEq: 16533 case IrBinOpCmpLessOrEq: 16534 case IrBinOpCmpLessThan: 16535 return ir_const_bool(ira, source_instr, true); 16536 case IrBinOpCmpEq: 16537 case IrBinOpCmpGreaterOrEq: 16538 case IrBinOpCmpGreaterThan: 16539 return ir_const_bool(ira, source_instr, false); 16540 default: 16541 break; 16542 } 16543 } 16544 } 16545 if (have_op2_cmp_zero && op1_scalar_type->id == ZigTypeIdInt && !op1_scalar_type->data.integral.is_signed) { 16546 if (op2_cmp_zero == CmpEQ) { 16547 // unsigned_x < 0 // false 16548 // unsigned_x >= 0 // true 16549 switch (op_id) { 16550 case IrBinOpCmpLessThan: 16551 return ir_const_bool(ira, source_instr, false); 16552 case IrBinOpCmpGreaterOrEq: 16553 return ir_const_bool(ira, source_instr, true); 16554 default: 16555 break; 16556 } 16557 } else if (op2_cmp_zero == CmpLT) { 16558 // unsigned_x != -1 // true 16559 // unsigned_x >= -1 // true 16560 // unsigned_x > -1 // true 16561 // unsigned_x == -1 // false 16562 // unsigned_x < -1 // false 16563 // unsigned_x <= -1 // false 16564 switch (op_id) { 16565 case IrBinOpCmpNotEq: 16566 case IrBinOpCmpGreaterOrEq: 16567 case IrBinOpCmpGreaterThan: 16568 return ir_const_bool(ira, source_instr, true); 16569 case IrBinOpCmpEq: 16570 case IrBinOpCmpLessThan: 16571 case IrBinOpCmpLessOrEq: 16572 return ir_const_bool(ira, source_instr, false); 16573 default: 16574 break; 16575 } 16576 } 16577 } 16578 16579 // It must be a runtime comparison. 16580 // For floats, emit a float comparison instruction. 16581 bool op1_is_float = op1_scalar_type->id == ZigTypeIdFloat || op1_scalar_type->id == ZigTypeIdComptimeFloat; 16582 bool op2_is_float = op2_scalar_type->id == ZigTypeIdFloat || op2_scalar_type->id == ZigTypeIdComptimeFloat; 16583 if (op1_is_float && op2_is_float) { 16584 // Implicit cast the smaller one to the larger one. 16585 ZigType *dest_scalar_type; 16586 if (op1_scalar_type->id == ZigTypeIdComptimeFloat) { 16587 dest_scalar_type = op2_scalar_type; 16588 } else if (op2_scalar_type->id == ZigTypeIdComptimeFloat) { 16589 dest_scalar_type = op1_scalar_type; 16590 } else if (op1_scalar_type->data.floating.bit_count >= op2_scalar_type->data.floating.bit_count) { 16591 dest_scalar_type = op1_scalar_type; 16592 } else { 16593 dest_scalar_type = op2_scalar_type; 16594 } 16595 ZigType *dest_type = (result_type->id == ZigTypeIdVector) ? 16596 get_vector_type(ira->codegen, result_type->data.vector.len, dest_scalar_type) : dest_scalar_type; 16597 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 16598 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, dest_type); 16599 if (type_is_invalid(casted_op1->value->type) || type_is_invalid(casted_op2->value->type)) 16600 return ira->codegen->invalid_inst_gen; 16601 return ir_build_bin_op_gen(ira, source_instr, result_type, op_id, casted_op1, casted_op2, true); 16602 } 16603 16604 // For mixed unsigned integer sizes, implicit cast both operands to the larger integer. 16605 // For mixed signed and unsigned integers, implicit cast both operands to a signed 16606 // integer with + 1 bit. 16607 // For mixed floats and integers, extract the integer part from the float, cast that to 16608 // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float, 16609 // add/subtract 1. 16610 bool dest_int_is_signed = false; 16611 if (have_op1_cmp_zero) { 16612 if (op1_cmp_zero == CmpLT) dest_int_is_signed = true; 16613 } else if (op1_is_float) { 16614 dest_int_is_signed = true; 16615 } else if (op1_scalar_type->id == ZigTypeIdInt && op1_scalar_type->data.integral.is_signed) { 16616 dest_int_is_signed = true; 16617 } 16618 if (have_op2_cmp_zero) { 16619 if (op2_cmp_zero == CmpLT) dest_int_is_signed = true; 16620 } else if (op2_is_float) { 16621 dest_int_is_signed = true; 16622 } else if (op2->value->type->id == ZigTypeIdInt && op2->value->type->data.integral.is_signed) { 16623 dest_int_is_signed = true; 16624 } 16625 ZigType *dest_float_type = nullptr; 16626 uint32_t op1_bits; 16627 if (instr_is_comptime(op1)) { 16628 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefOk); 16629 if (op1_val == nullptr) 16630 return ira->codegen->invalid_inst_gen; 16631 if (op1_val->special == ConstValSpecialUndef) 16632 return ir_const_undef(ira, source_instr, ira->codegen->builtin_types.entry_bool); 16633 if (result_type->id == ZigTypeIdVector) { 16634 ir_add_error(ira, &op1->base, buf_sprintf("compiler bug: TODO: support comptime vector here")); 16635 return ira->codegen->invalid_inst_gen; 16636 } 16637 bool is_unsigned; 16638 if (op1_is_float) { 16639 BigInt bigint = {}; 16640 float_init_bigint(&bigint, op1_val); 16641 Cmp zcmp = float_cmp_zero(op1_val); 16642 if (float_has_fraction(op1_val)) { 16643 if (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq) { 16644 return ir_const_bool(ira, source_instr, op_id == IrBinOpCmpNotEq); 16645 } 16646 if (zcmp == CmpLT) { 16647 bigint_decr(&bigint); 16648 } else { 16649 bigint_incr(&bigint); 16650 } 16651 } 16652 op1_bits = bigint_bits_needed(&bigint); 16653 is_unsigned = zcmp != CmpLT; 16654 } else { 16655 op1_bits = bigint_bits_needed(&op1_val->data.x_bigint); 16656 is_unsigned = bigint_cmp_zero(&op1_val->data.x_bigint) != CmpLT; 16657 } 16658 if (is_unsigned && dest_int_is_signed) { 16659 op1_bits += 1; 16660 } 16661 } else if (op1_is_float) { 16662 dest_float_type = op1_scalar_type; 16663 } else { 16664 ir_assert(op1_scalar_type->id == ZigTypeIdInt, source_instr); 16665 op1_bits = op1_scalar_type->data.integral.bit_count; 16666 if (!op1_scalar_type->data.integral.is_signed && dest_int_is_signed) { 16667 op1_bits += 1; 16668 } 16669 } 16670 uint32_t op2_bits; 16671 if (instr_is_comptime(op2)) { 16672 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefOk); 16673 if (op2_val == nullptr) 16674 return ira->codegen->invalid_inst_gen; 16675 if (op2_val->special == ConstValSpecialUndef) 16676 return ir_const_undef(ira, source_instr, ira->codegen->builtin_types.entry_bool); 16677 if (result_type->id == ZigTypeIdVector) { 16678 ir_add_error(ira, &op2->base, buf_sprintf("compiler bug: TODO: support comptime vector here")); 16679 return ira->codegen->invalid_inst_gen; 16680 } 16681 bool is_unsigned; 16682 if (op2_is_float) { 16683 BigInt bigint = {}; 16684 float_init_bigint(&bigint, op2_val); 16685 Cmp zcmp = float_cmp_zero(op2_val); 16686 if (float_has_fraction(op2_val)) { 16687 if (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq) { 16688 return ir_const_bool(ira, source_instr, op_id == IrBinOpCmpNotEq); 16689 } 16690 if (zcmp == CmpLT) { 16691 bigint_decr(&bigint); 16692 } else { 16693 bigint_incr(&bigint); 16694 } 16695 } 16696 op2_bits = bigint_bits_needed(&bigint); 16697 is_unsigned = zcmp != CmpLT; 16698 } else { 16699 op2_bits = bigint_bits_needed(&op2_val->data.x_bigint); 16700 is_unsigned = bigint_cmp_zero(&op2_val->data.x_bigint) != CmpLT; 16701 } 16702 if (is_unsigned && dest_int_is_signed) { 16703 op2_bits += 1; 16704 } 16705 } else if (op2_is_float) { 16706 dest_float_type = op2_scalar_type; 16707 } else { 16708 ir_assert(op2_scalar_type->id == ZigTypeIdInt, source_instr); 16709 op2_bits = op2_scalar_type->data.integral.bit_count; 16710 if (!op2_scalar_type->data.integral.is_signed && dest_int_is_signed) { 16711 op2_bits += 1; 16712 } 16713 } 16714 ZigType *dest_scalar_type = (dest_float_type == nullptr) ? 16715 get_int_type(ira->codegen, dest_int_is_signed, (op1_bits > op2_bits) ? op1_bits : op2_bits) : 16716 dest_float_type; 16717 ZigType *dest_type = (result_type->id == ZigTypeIdVector) ? 16718 get_vector_type(ira->codegen, result_type->data.vector.len, dest_scalar_type) : dest_scalar_type; 16719 16720 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 16721 if (type_is_invalid(casted_op1->value->type)) 16722 return ira->codegen->invalid_inst_gen; 16723 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, dest_type); 16724 if (type_is_invalid(casted_op2->value->type)) 16725 return ira->codegen->invalid_inst_gen; 16726 return ir_build_bin_op_gen(ira, source_instr, result_type, op_id, casted_op1, casted_op2, true); 16727 } 16728 16729 static bool type_is_self_comparable(ZigType *ty, bool is_equality_cmp) { 16730 if (type_is_numeric(ty)) { 16731 return true; 16732 } 16733 switch (ty->id) { 16734 case ZigTypeIdInvalid: 16735 zig_unreachable(); 16736 16737 case ZigTypeIdComptimeFloat: 16738 case ZigTypeIdComptimeInt: 16739 case ZigTypeIdInt: 16740 case ZigTypeIdFloat: 16741 zig_unreachable(); // handled with the type_is_numeric check above 16742 16743 case ZigTypeIdVector: 16744 // Not every case is handled by the type_is_numeric check above, 16745 // vectors of bool trigger this code path 16746 case ZigTypeIdBool: 16747 case ZigTypeIdMetaType: 16748 case ZigTypeIdVoid: 16749 case ZigTypeIdErrorSet: 16750 case ZigTypeIdFn: 16751 case ZigTypeIdOpaque: 16752 case ZigTypeIdBoundFn: 16753 case ZigTypeIdEnum: 16754 case ZigTypeIdEnumLiteral: 16755 case ZigTypeIdAnyFrame: 16756 return is_equality_cmp; 16757 16758 case ZigTypeIdPointer: 16759 return is_equality_cmp || (ty->data.pointer.ptr_len == PtrLenC); 16760 16761 case ZigTypeIdUnreachable: 16762 case ZigTypeIdArray: 16763 case ZigTypeIdStruct: 16764 case ZigTypeIdUndefined: 16765 case ZigTypeIdNull: 16766 case ZigTypeIdErrorUnion: 16767 case ZigTypeIdUnion: 16768 case ZigTypeIdFnFrame: 16769 return false; 16770 16771 case ZigTypeIdOptional: 16772 return is_equality_cmp && get_src_ptr_type(ty) != nullptr; 16773 } 16774 zig_unreachable(); 16775 } 16776 16777 static IrInstGen *ir_try_evaluate_cmp_optional_non_optional_const(IrAnalyze *ira, IrInst *source_instr, ZigType *child_type, 16778 IrInstGen *optional, IrInstGen *non_optional, IrBinOp op_id) 16779 { 16780 assert(optional->value->type->id == ZigTypeIdOptional); 16781 assert(optional->value->type->data.maybe.child_type == non_optional->value->type); 16782 assert(non_optional->value->type == child_type); 16783 assert(op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 16784 16785 if (instr_is_comptime(optional) && instr_is_comptime(non_optional)) { 16786 ZigValue *optional_val = ir_resolve_const(ira, optional, UndefBad); 16787 if (!optional_val) { 16788 return ira->codegen->invalid_inst_gen; 16789 } 16790 16791 ZigValue *non_optional_val = ir_resolve_const(ira, non_optional, UndefBad); 16792 if (!non_optional_val) { 16793 return ira->codegen->invalid_inst_gen; 16794 } 16795 16796 if (!optional_value_is_null(optional_val)) { 16797 IrInstGen *optional_unwrapped = ir_analyze_optional_value_payload_value(ira, source_instr, optional, false); 16798 if (type_is_invalid(optional_unwrapped->value->type)) { 16799 return ira->codegen->invalid_inst_gen; 16800 } 16801 16802 IrInstGen *ret = ir_try_evaluate_bin_op_cmp_const(ira, source_instr, optional_unwrapped, non_optional, child_type, op_id); 16803 assert(ret != nullptr); 16804 return ret; 16805 } 16806 return ir_const_bool(ira, source_instr, (op_id != IrBinOpCmpEq)); 16807 } else { 16808 return nullptr; 16809 } 16810 } 16811 16812 static IrInstGen *ir_evaluate_cmp_optional_non_optional(IrAnalyze *ira, IrInst *source_instr, ZigType *child_type, 16813 IrInstGen *optional, IrInstGen *non_optional, IrBinOp op_id) 16814 { 16815 assert(optional->value->type->id == ZigTypeIdOptional); 16816 assert(optional->value->type->data.maybe.child_type == non_optional->value->type); 16817 assert(non_optional->value->type == child_type); 16818 assert(op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 16819 16820 ZigType *result_type = ira->codegen->builtin_types.entry_bool; 16821 ir_append_basic_block_gen(&ira->new_irb, ira->new_irb.current_basic_block); 16822 16823 IrBasicBlockGen *null_block = ir_create_basic_block_gen(ira, source_instr->scope, "CmpOptionalNonOptionalOptionalNull"); 16824 IrBasicBlockGen *non_null_block = ir_create_basic_block_gen(ira, source_instr->scope, "CmpOptionalNonOptionalOptionalNotNull"); 16825 IrBasicBlockGen *end_block = ir_create_basic_block_gen(ira, source_instr->scope, "CmpOptionalNonOptionalEnd"); 16826 16827 IrInstGen *is_non_null = ir_build_test_non_null_gen(ira, source_instr, optional); 16828 ir_build_cond_br_gen(ira, source_instr, is_non_null, non_null_block, null_block); 16829 16830 ir_set_cursor_at_end_and_append_block_gen(&ira->new_irb, non_null_block); 16831 IrInstGen *optional_unwrapped = ir_analyze_optional_value_payload_value(ira, source_instr, optional, false); 16832 if (type_is_invalid(optional_unwrapped->value->type)) { 16833 return ira->codegen->invalid_inst_gen; 16834 } 16835 IrInstGen *non_null_cmp_result = ir_build_bin_op_gen(ira, source_instr, result_type, op_id, 16836 optional_unwrapped, non_optional, false); // safety check unnecessary for comparison operators 16837 ir_build_br_gen(ira, source_instr, end_block); 16838 16839 16840 ir_set_cursor_at_end_and_append_block_gen(&ira->new_irb, null_block); 16841 IrInstGen *null_result = ir_const_bool(ira, source_instr, (op_id != IrBinOpCmpEq)); 16842 ir_build_br_gen(ira, source_instr, end_block); 16843 16844 ir_set_cursor_at_end_gen(&ira->new_irb, end_block); 16845 int incoming_count = 2; 16846 IrBasicBlockGen **incoming_blocks = heap::c_allocator.allocate_nonzero<IrBasicBlockGen *>(incoming_count); 16847 incoming_blocks[0] = null_block; 16848 incoming_blocks[1] = non_null_block; 16849 IrInstGen **incoming_values = heap::c_allocator.allocate_nonzero<IrInstGen *>(incoming_count); 16850 incoming_values[0] = null_result; 16851 incoming_values[1] = non_null_cmp_result; 16852 16853 return ir_build_phi_gen(ira, source_instr, incoming_count, incoming_blocks, incoming_values, result_type); 16854 } 16855 16856 static IrInstGen *ir_analyze_cmp_optional_non_optional(IrAnalyze *ira, IrInst *source_instr, 16857 IrInstGen *op1, IrInstGen *op2, IrInstGen *optional, IrBinOp op_id) 16858 { 16859 assert(op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 16860 assert(optional->value->type->id == ZigTypeIdOptional); 16861 assert(get_src_ptr_type(optional->value->type) == nullptr); 16862 16863 IrInstGen *non_optional; 16864 if (op1 == optional) { 16865 non_optional = op2; 16866 } else if (op2 == optional) { 16867 non_optional = op1; 16868 } else { 16869 zig_unreachable(); 16870 } 16871 16872 ZigType *child_type = optional->value->type->data.maybe.child_type; 16873 bool child_type_matches = (child_type == non_optional->value->type); 16874 if (!child_type_matches || !type_is_self_comparable(child_type, true)) { 16875 ErrorMsg *msg = ir_add_error_node(ira, source_instr->source_node, buf_sprintf("cannot compare types '%s' and '%s'", 16876 buf_ptr(&op1->value->type->name), 16877 buf_ptr(&op2->value->type->name))); 16878 16879 if (!child_type_matches) { 16880 if (non_optional->value->type->id == ZigTypeIdOptional) { 16881 add_error_note(ira->codegen, msg, source_instr->source_node, buf_sprintf( 16882 "optional to optional comparison is only supported for optional pointer types")); 16883 } else { 16884 add_error_note(ira->codegen, msg, source_instr->source_node, 16885 buf_sprintf("optional child type '%s' must be the same as non-optional type '%s'", 16886 buf_ptr(&child_type->name), 16887 buf_ptr(&non_optional->value->type->name))); 16888 } 16889 } else { 16890 add_error_note(ira->codegen, msg, source_instr->source_node, 16891 buf_sprintf("operator not supported for type '%s'", 16892 buf_ptr(&child_type->name))); 16893 } 16894 return ira->codegen->invalid_inst_gen; 16895 } 16896 16897 if (child_type->id == ZigTypeIdVector) { 16898 ir_add_error_node(ira, source_instr->source_node, buf_sprintf("TODO add comparison of optional vector")); 16899 return ira->codegen->invalid_inst_gen; 16900 } 16901 16902 if (IrInstGen *const_result = ir_try_evaluate_cmp_optional_non_optional_const(ira, source_instr, child_type, 16903 optional, non_optional, op_id)) 16904 { 16905 return const_result; 16906 } 16907 16908 return ir_evaluate_cmp_optional_non_optional(ira, source_instr, child_type, optional, non_optional, op_id); 16909 } 16910 16911 static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { 16912 IrInstGen *op1 = bin_op_instruction->op1->child; 16913 if (type_is_invalid(op1->value->type)) 16914 return ira->codegen->invalid_inst_gen; 16915 16916 IrInstGen *op2 = bin_op_instruction->op2->child; 16917 if (type_is_invalid(op2->value->type)) 16918 return ira->codegen->invalid_inst_gen; 16919 16920 AstNode *source_node = bin_op_instruction->base.base.source_node; 16921 16922 IrBinOp op_id = bin_op_instruction->op_id; 16923 bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 16924 if (is_equality_cmp && op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdNull) { 16925 return ir_const_bool(ira, &bin_op_instruction->base.base, (op_id == IrBinOpCmpEq)); 16926 } else if (is_equality_cmp && 16927 ((op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdOptional) || 16928 (op2->value->type->id == ZigTypeIdNull && op1->value->type->id == ZigTypeIdOptional))) 16929 { 16930 IrInstGen *maybe_op; 16931 if (op1->value->type->id == ZigTypeIdNull) { 16932 maybe_op = op2; 16933 } else if (op2->value->type->id == ZigTypeIdNull) { 16934 maybe_op = op1; 16935 } else { 16936 zig_unreachable(); 16937 } 16938 if (instr_is_comptime(maybe_op)) { 16939 ZigValue *maybe_val = ir_resolve_const(ira, maybe_op, UndefBad); 16940 if (!maybe_val) 16941 return ira->codegen->invalid_inst_gen; 16942 bool is_null = optional_value_is_null(maybe_val); 16943 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 16944 return ir_const_bool(ira, &bin_op_instruction->base.base, bool_result); 16945 } 16946 16947 IrInstGen *is_non_null = ir_build_test_non_null_gen(ira, &bin_op_instruction->base.base, maybe_op); 16948 16949 if (op_id == IrBinOpCmpEq) { 16950 return ir_build_bool_not_gen(ira, &bin_op_instruction->base.base, is_non_null); 16951 } else { 16952 return is_non_null; 16953 } 16954 } else if (is_equality_cmp && 16955 ((op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdPointer && 16956 op2->value->type->data.pointer.ptr_len == PtrLenC) || 16957 (op2->value->type->id == ZigTypeIdNull && op1->value->type->id == ZigTypeIdPointer && 16958 op1->value->type->data.pointer.ptr_len == PtrLenC))) 16959 { 16960 IrInstGen *c_ptr_op; 16961 if (op1->value->type->id == ZigTypeIdNull) { 16962 c_ptr_op = op2; 16963 } else if (op2->value->type->id == ZigTypeIdNull) { 16964 c_ptr_op = op1; 16965 } else { 16966 zig_unreachable(); 16967 } 16968 if (instr_is_comptime(c_ptr_op)) { 16969 ZigValue *c_ptr_val = ir_resolve_const(ira, c_ptr_op, UndefOk); 16970 if (!c_ptr_val) 16971 return ira->codegen->invalid_inst_gen; 16972 if (c_ptr_val->special == ConstValSpecialUndef) 16973 return ir_const_undef(ira, &bin_op_instruction->base.base, ira->codegen->builtin_types.entry_bool); 16974 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 16975 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 16976 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 16977 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 16978 return ir_const_bool(ira, &bin_op_instruction->base.base, bool_result); 16979 } 16980 IrInstGen *is_non_null = ir_build_test_non_null_gen(ira, &bin_op_instruction->base.base, c_ptr_op); 16981 16982 if (op_id == IrBinOpCmpEq) { 16983 return ir_build_bool_not_gen(ira, &bin_op_instruction->base.base, is_non_null); 16984 } else { 16985 return is_non_null; 16986 } 16987 } else if (is_equality_cmp && 16988 (op1->value->type->id == ZigTypeIdOptional && get_src_ptr_type(op1->value->type) == nullptr)) 16989 { 16990 return ir_analyze_cmp_optional_non_optional(ira, &bin_op_instruction->base.base, op1, op2, op1, op_id); 16991 } else if(is_equality_cmp && 16992 (op2->value->type->id == ZigTypeIdOptional && get_src_ptr_type(op2->value->type) == nullptr)) 16993 { 16994 return ir_analyze_cmp_optional_non_optional(ira, &bin_op_instruction->base.base, op1, op2, op2, op_id); 16995 } else if (op1->value->type->id == ZigTypeIdNull || op2->value->type->id == ZigTypeIdNull) { 16996 ZigType *non_null_type = (op1->value->type->id == ZigTypeIdNull) ? op2->value->type : op1->value->type; 16997 ir_add_error_node(ira, source_node, buf_sprintf("comparison of '%s' with null", 16998 buf_ptr(&non_null_type->name))); 16999 return ira->codegen->invalid_inst_gen; 17000 } else if (is_equality_cmp && ( 17001 (op1->value->type->id == ZigTypeIdEnumLiteral && op2->value->type->id == ZigTypeIdUnion) || 17002 (op2->value->type->id == ZigTypeIdEnumLiteral && op1->value->type->id == ZigTypeIdUnion))) 17003 { 17004 // Support equality comparison between a union's tag value and a enum literal 17005 IrInstGen *union_val = op1->value->type->id == ZigTypeIdUnion ? op1 : op2; 17006 IrInstGen *enum_val = op1->value->type->id == ZigTypeIdUnion ? op2 : op1; 17007 17008 if (!is_tagged_union(union_val->value->type)) { 17009 ErrorMsg *msg = ir_add_error_node(ira, source_node, 17010 buf_sprintf("comparison of union and enum literal is only valid for tagged union types")); 17011 add_error_note(ira->codegen, msg, union_val->value->type->data.unionation.decl_node, 17012 buf_sprintf("type %s is not a tagged union", 17013 buf_ptr(&union_val->value->type->name))); 17014 return ira->codegen->invalid_inst_gen; 17015 } 17016 17017 ZigType *tag_type = union_val->value->type->data.unionation.tag_type; 17018 assert(tag_type != nullptr); 17019 17020 IrInstGen *casted_union = ir_implicit_cast(ira, union_val, tag_type); 17021 if (type_is_invalid(casted_union->value->type)) 17022 return ira->codegen->invalid_inst_gen; 17023 17024 IrInstGen *casted_val = ir_implicit_cast(ira, enum_val, tag_type); 17025 if (type_is_invalid(casted_val->value->type)) 17026 return ira->codegen->invalid_inst_gen; 17027 17028 if (instr_is_comptime(casted_union)) { 17029 ZigValue *const_union_val = ir_resolve_const(ira, casted_union, UndefBad); 17030 if (!const_union_val) 17031 return ira->codegen->invalid_inst_gen; 17032 17033 ZigValue *const_enum_val = ir_resolve_const(ira, casted_val, UndefBad); 17034 if (!const_enum_val) 17035 return ira->codegen->invalid_inst_gen; 17036 17037 Cmp cmp_result = bigint_cmp(&const_union_val->data.x_union.tag, &const_enum_val->data.x_enum_tag); 17038 bool bool_result = (op_id == IrBinOpCmpEq) ? cmp_result == CmpEQ : cmp_result != CmpEQ; 17039 17040 return ir_const_bool(ira, &bin_op_instruction->base.base, bool_result); 17041 } 17042 17043 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, ira->codegen->builtin_types.entry_bool, 17044 op_id, casted_union, casted_val, bin_op_instruction->safety_check_on); 17045 } 17046 17047 if (op1->value->type->id == ZigTypeIdErrorSet && op2->value->type->id == ZigTypeIdErrorSet) { 17048 if (!is_equality_cmp) { 17049 ir_add_error_node(ira, source_node, buf_sprintf("operator not allowed for errors")); 17050 return ira->codegen->invalid_inst_gen; 17051 } 17052 ZigType *intersect_type = get_error_set_intersection(ira, op1->value->type, op2->value->type, source_node); 17053 if (type_is_invalid(intersect_type)) { 17054 return ira->codegen->invalid_inst_gen; 17055 } 17056 17057 if (!resolve_inferred_error_set(ira->codegen, intersect_type, source_node)) { 17058 return ira->codegen->invalid_inst_gen; 17059 } 17060 17061 // exception if one of the operators has the type of the empty error set, we allow the comparison 17062 // (and make it comptime known) 17063 // this is a function which is evaluated at comptime and returns an inferred error set will have an empty 17064 // error set. 17065 if (op1->value->type->data.error_set.err_count == 0 || op2->value->type->data.error_set.err_count == 0) { 17066 bool are_equal = false; 17067 bool answer; 17068 if (op_id == IrBinOpCmpEq) { 17069 answer = are_equal; 17070 } else if (op_id == IrBinOpCmpNotEq) { 17071 answer = !are_equal; 17072 } else { 17073 zig_unreachable(); 17074 } 17075 return ir_const_bool(ira, &bin_op_instruction->base.base, answer); 17076 } 17077 17078 if (!type_is_global_error_set(intersect_type)) { 17079 if (intersect_type->data.error_set.err_count == 0) { 17080 ir_add_error_node(ira, source_node, 17081 buf_sprintf("error sets '%s' and '%s' have no common errors", 17082 buf_ptr(&op1->value->type->name), buf_ptr(&op2->value->type->name))); 17083 return ira->codegen->invalid_inst_gen; 17084 } 17085 if (op1->value->type->data.error_set.err_count == 1 && op2->value->type->data.error_set.err_count == 1) { 17086 bool are_equal = true; 17087 bool answer; 17088 if (op_id == IrBinOpCmpEq) { 17089 answer = are_equal; 17090 } else if (op_id == IrBinOpCmpNotEq) { 17091 answer = !are_equal; 17092 } else { 17093 zig_unreachable(); 17094 } 17095 return ir_const_bool(ira, &bin_op_instruction->base.base, answer); 17096 } 17097 } 17098 17099 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 17100 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 17101 if (op1_val == nullptr) 17102 return ira->codegen->invalid_inst_gen; 17103 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 17104 if (op2_val == nullptr) 17105 return ira->codegen->invalid_inst_gen; 17106 17107 bool answer; 17108 bool are_equal = op1_val->data.x_err_set->value == op2_val->data.x_err_set->value; 17109 if (op_id == IrBinOpCmpEq) { 17110 answer = are_equal; 17111 } else if (op_id == IrBinOpCmpNotEq) { 17112 answer = !are_equal; 17113 } else { 17114 zig_unreachable(); 17115 } 17116 17117 return ir_const_bool(ira, &bin_op_instruction->base.base, answer); 17118 } 17119 17120 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, ira->codegen->builtin_types.entry_bool, 17121 op_id, op1, op2, bin_op_instruction->safety_check_on); 17122 } 17123 17124 if (type_is_numeric(op1->value->type) && type_is_numeric(op2->value->type)) { 17125 // This operation allows any combination of integer and float types, regardless of the 17126 // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for 17127 // numeric types. 17128 return ir_analyze_bin_op_cmp_numeric(ira, &bin_op_instruction->base.base, op1, op2, op_id); 17129 } 17130 17131 IrInstGen *instructions[] = {op1, op2}; 17132 ZigType *resolved_type = ir_resolve_peer_types(ira, source_node, nullptr, instructions, 2); 17133 if (type_is_invalid(resolved_type)) 17134 return ira->codegen->invalid_inst_gen; 17135 17136 bool operator_allowed = type_is_self_comparable(resolved_type, is_equality_cmp); 17137 17138 if (!operator_allowed) { 17139 ir_add_error_node(ira, source_node, 17140 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name))); 17141 return ira->codegen->invalid_inst_gen; 17142 } 17143 17144 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 17145 if (type_is_invalid(casted_op1->value->type)) 17146 return ira->codegen->invalid_inst_gen; 17147 17148 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 17149 if (type_is_invalid(casted_op2->value->type)) 17150 return ira->codegen->invalid_inst_gen; 17151 17152 IrInstGen *resolve_const_result = ir_try_evaluate_bin_op_cmp_const(ira, &bin_op_instruction->base.base, casted_op1, 17153 casted_op2, resolved_type, op_id); 17154 if (resolve_const_result != nullptr) { 17155 return resolve_const_result; 17156 } 17157 17158 ZigType *res_type = (resolved_type->id == ZigTypeIdVector) ? 17159 get_vector_type(ira->codegen, resolved_type->data.vector.len, ira->codegen->builtin_types.entry_bool) : 17160 ira->codegen->builtin_types.entry_bool; 17161 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, res_type, 17162 op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 17163 } 17164 17165 static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInst* source_instr, ZigType *type_entry, 17166 ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val, ZigValue *out_val) 17167 { 17168 bool is_int; 17169 bool is_float; 17170 Cmp op2_zcmp; 17171 if (type_entry->id == ZigTypeIdInt || type_entry->id == ZigTypeIdComptimeInt) { 17172 is_int = true; 17173 is_float = false; 17174 op2_zcmp = bigint_cmp_zero(&op2_val->data.x_bigint); 17175 } else if (type_entry->id == ZigTypeIdFloat || 17176 type_entry->id == ZigTypeIdComptimeFloat) 17177 { 17178 is_int = false; 17179 is_float = true; 17180 op2_zcmp = float_cmp_zero(op2_val); 17181 } else { 17182 zig_unreachable(); 17183 } 17184 17185 if ((op_id == IrBinOpDivUnspecified || op_id == IrBinOpRemRem || op_id == IrBinOpRemMod || 17186 op_id == IrBinOpDivTrunc || op_id == IrBinOpDivFloor) && op2_zcmp == CmpEQ) 17187 { 17188 return ir_add_error(ira, source_instr, buf_sprintf("division by zero")); 17189 } 17190 if ((op_id == IrBinOpRemRem || op_id == IrBinOpRemMod) && op2_zcmp == CmpLT) { 17191 return ir_add_error(ira, source_instr, buf_sprintf("negative denominator")); 17192 } 17193 17194 switch (op_id) { 17195 case IrBinOpInvalid: 17196 case IrBinOpBoolOr: 17197 case IrBinOpBoolAnd: 17198 case IrBinOpCmpEq: 17199 case IrBinOpCmpNotEq: 17200 case IrBinOpCmpLessThan: 17201 case IrBinOpCmpGreaterThan: 17202 case IrBinOpCmpLessOrEq: 17203 case IrBinOpCmpGreaterOrEq: 17204 case IrBinOpArrayCat: 17205 case IrBinOpArrayMult: 17206 case IrBinOpRemUnspecified: 17207 zig_unreachable(); 17208 case IrBinOpBinOr: 17209 assert(is_int); 17210 bigint_or(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17211 break; 17212 case IrBinOpBinXor: 17213 assert(is_int); 17214 bigint_xor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17215 break; 17216 case IrBinOpBinAnd: 17217 assert(is_int); 17218 bigint_and(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17219 break; 17220 case IrBinOpBitShiftLeftExact: 17221 assert(is_int); 17222 bigint_shl(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17223 break; 17224 case IrBinOpBitShiftLeftLossy: 17225 assert(type_entry->id == ZigTypeIdInt); 17226 bigint_shl_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 17227 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 17228 break; 17229 case IrBinOpBitShiftRightExact: 17230 { 17231 assert(is_int); 17232 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17233 BigInt orig_bigint; 17234 bigint_shl(&orig_bigint, &out_val->data.x_bigint, &op2_val->data.x_bigint); 17235 if (bigint_cmp(&op1_val->data.x_bigint, &orig_bigint) != CmpEQ) { 17236 return ir_add_error(ira, source_instr, buf_sprintf("exact shift shifted out 1 bits")); 17237 } 17238 break; 17239 } 17240 case IrBinOpBitShiftRightLossy: 17241 assert(is_int); 17242 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17243 break; 17244 case IrBinOpAdd: 17245 if (is_int) { 17246 bigint_add(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17247 } else { 17248 float_add(out_val, op1_val, op2_val); 17249 } 17250 break; 17251 case IrBinOpAddWrap: 17252 assert(type_entry->id == ZigTypeIdInt); 17253 bigint_add_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 17254 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 17255 break; 17256 case IrBinOpSub: 17257 if (is_int) { 17258 bigint_sub(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17259 } else { 17260 float_sub(out_val, op1_val, op2_val); 17261 } 17262 break; 17263 case IrBinOpSubWrap: 17264 assert(type_entry->id == ZigTypeIdInt); 17265 bigint_sub_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 17266 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 17267 break; 17268 case IrBinOpMult: 17269 if (is_int) { 17270 bigint_mul(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17271 } else { 17272 float_mul(out_val, op1_val, op2_val); 17273 } 17274 break; 17275 case IrBinOpMultWrap: 17276 assert(type_entry->id == ZigTypeIdInt); 17277 bigint_mul_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 17278 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 17279 break; 17280 case IrBinOpDivUnspecified: 17281 assert(is_float); 17282 float_div(out_val, op1_val, op2_val); 17283 break; 17284 case IrBinOpDivTrunc: 17285 if (is_int) { 17286 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17287 } else { 17288 float_div_trunc(out_val, op1_val, op2_val); 17289 } 17290 break; 17291 case IrBinOpDivFloor: 17292 if (is_int) { 17293 bigint_div_floor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17294 } else { 17295 float_div_floor(out_val, op1_val, op2_val); 17296 } 17297 break; 17298 case IrBinOpDivExact: 17299 if (is_int) { 17300 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17301 BigInt remainder; 17302 bigint_rem(&remainder, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17303 if (bigint_cmp_zero(&remainder) != CmpEQ) { 17304 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); 17305 } 17306 } else { 17307 float_div_trunc(out_val, op1_val, op2_val); 17308 ZigValue remainder = {}; 17309 float_rem(&remainder, op1_val, op2_val); 17310 if (float_cmp_zero(&remainder) != CmpEQ) { 17311 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); 17312 } 17313 } 17314 break; 17315 case IrBinOpRemRem: 17316 if (is_int) { 17317 bigint_rem(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17318 } else { 17319 float_rem(out_val, op1_val, op2_val); 17320 } 17321 break; 17322 case IrBinOpRemMod: 17323 if (is_int) { 17324 bigint_mod(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17325 } else { 17326 float_mod(out_val, op1_val, op2_val); 17327 } 17328 break; 17329 } 17330 17331 if (type_entry->id == ZigTypeIdInt) { 17332 if (!bigint_fits_in_bits(&out_val->data.x_bigint, type_entry->data.integral.bit_count, 17333 type_entry->data.integral.is_signed)) 17334 { 17335 return ir_add_error(ira, source_instr, buf_sprintf("operation caused overflow")); 17336 } 17337 } 17338 17339 out_val->type = type_entry; 17340 out_val->special = ConstValSpecialStatic; 17341 return nullptr; 17342 } 17343 17344 // This works on operands that have already been checked to be comptime known. 17345 static IrInstGen *ir_analyze_math_op(IrAnalyze *ira, IrInst* source_instr, 17346 ZigType *type_entry, ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val) 17347 { 17348 IrInstGen *result_instruction = ir_const(ira, source_instr, type_entry); 17349 ZigValue *out_val = result_instruction->value; 17350 if (type_entry->id == ZigTypeIdVector) { 17351 expand_undef_array(ira->codegen, op1_val); 17352 expand_undef_array(ira->codegen, op2_val); 17353 out_val->special = ConstValSpecialUndef; 17354 expand_undef_array(ira->codegen, out_val); 17355 size_t len = type_entry->data.vector.len; 17356 ZigType *scalar_type = type_entry->data.vector.elem_type; 17357 for (size_t i = 0; i < len; i += 1) { 17358 ZigValue *scalar_op1_val = &op1_val->data.x_array.data.s_none.elements[i]; 17359 ZigValue *scalar_op2_val = &op2_val->data.x_array.data.s_none.elements[i]; 17360 ZigValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 17361 assert(scalar_op1_val->type == scalar_type); 17362 assert(scalar_out_val->type == scalar_type); 17363 ErrorMsg *msg = ir_eval_math_op_scalar(ira, source_instr, scalar_type, 17364 scalar_op1_val, op_id, scalar_op2_val, scalar_out_val); 17365 if (msg != nullptr) { 17366 add_error_note(ira->codegen, msg, source_instr->source_node, 17367 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 17368 return ira->codegen->invalid_inst_gen; 17369 } 17370 } 17371 out_val->type = type_entry; 17372 out_val->special = ConstValSpecialStatic; 17373 } else { 17374 if (ir_eval_math_op_scalar(ira, source_instr, type_entry, op1_val, op_id, op2_val, out_val) != nullptr) { 17375 return ira->codegen->invalid_inst_gen; 17376 } 17377 } 17378 return ir_implicit_cast(ira, result_instruction, type_entry); 17379 } 17380 17381 static IrInstGen *ir_analyze_bit_shift(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { 17382 IrInstGen *op1 = bin_op_instruction->op1->child; 17383 if (type_is_invalid(op1->value->type)) 17384 return ira->codegen->invalid_inst_gen; 17385 17386 IrInstGen *op2 = bin_op_instruction->op2->child; 17387 if (type_is_invalid(op2->value->type)) 17388 return ira->codegen->invalid_inst_gen; 17389 17390 ZigType *op1_type = op1->value->type; 17391 ZigType *op2_type = op2->value->type; 17392 17393 if (op1_type->id == ZigTypeIdVector && op2_type->id != ZigTypeIdVector) { 17394 ir_add_error(ira, &bin_op_instruction->op1->base, 17395 buf_sprintf("bit shifting operation expected vector type, found '%s'", 17396 buf_ptr(&op2_type->name))); 17397 return ira->codegen->invalid_inst_gen; 17398 } 17399 17400 if (op1_type->id != ZigTypeIdVector && op2_type->id == ZigTypeIdVector) { 17401 ir_add_error(ira, &bin_op_instruction->op1->base, 17402 buf_sprintf("bit shifting operation expected vector type, found '%s'", 17403 buf_ptr(&op1_type->name))); 17404 return ira->codegen->invalid_inst_gen; 17405 } 17406 17407 ZigType *op1_scalar_type = (op1_type->id == ZigTypeIdVector) ? 17408 op1_type->data.vector.elem_type : op1_type; 17409 ZigType *op2_scalar_type = (op2_type->id == ZigTypeIdVector) ? 17410 op2_type->data.vector.elem_type : op2_type; 17411 17412 if (op1_scalar_type->id != ZigTypeIdInt && op1_scalar_type->id != ZigTypeIdComptimeInt) { 17413 ir_add_error(ira, &bin_op_instruction->op1->base, 17414 buf_sprintf("bit shifting operation expected integer type, found '%s'", 17415 buf_ptr(&op1_scalar_type->name))); 17416 return ira->codegen->invalid_inst_gen; 17417 } 17418 17419 if (op2_scalar_type->id != ZigTypeIdInt && op2_scalar_type->id != ZigTypeIdComptimeInt) { 17420 ir_add_error(ira, &bin_op_instruction->op2->base, 17421 buf_sprintf("shift amount has to be an integer type, but found '%s'", 17422 buf_ptr(&op2_scalar_type->name))); 17423 return ira->codegen->invalid_inst_gen; 17424 } 17425 17426 IrInstGen *casted_op2; 17427 IrBinOp op_id = bin_op_instruction->op_id; 17428 if (op1_scalar_type->id == ZigTypeIdComptimeInt) { 17429 // comptime_int has no finite bit width 17430 casted_op2 = op2; 17431 17432 if (op_id == IrBinOpBitShiftLeftLossy) { 17433 op_id = IrBinOpBitShiftLeftExact; 17434 } 17435 17436 if (!instr_is_comptime(op2)) { 17437 ir_add_error(ira, &bin_op_instruction->base.base, 17438 buf_sprintf("LHS of shift must be a fixed-width integer type, or RHS must be compile-time known")); 17439 return ira->codegen->invalid_inst_gen; 17440 } 17441 17442 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 17443 if (op2_val == nullptr) 17444 return ira->codegen->invalid_inst_gen; 17445 17446 if (op2_val->data.x_bigint.is_negative) { 17447 Buf *val_buf = buf_alloc(); 17448 bigint_append_buf(val_buf, &op2_val->data.x_bigint, 10); 17449 ir_add_error(ira, &casted_op2->base, 17450 buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); 17451 return ira->codegen->invalid_inst_gen; 17452 } 17453 } else { 17454 const unsigned bit_count = op1_scalar_type->data.integral.bit_count; 17455 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 17456 bit_count > 0 ? bit_count - 1 : 0); 17457 17458 if (op1_type->id == ZigTypeIdVector) { 17459 shift_amt_type = get_vector_type(ira->codegen, op1_type->data.vector.len, 17460 shift_amt_type); 17461 } 17462 17463 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 17464 if (type_is_invalid(casted_op2->value->type)) 17465 return ira->codegen->invalid_inst_gen; 17466 17467 // This check is only valid iff op1 has at least one bit 17468 if (bit_count > 0 && instr_is_comptime(casted_op2)) { 17469 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 17470 if (op2_val == nullptr) 17471 return ira->codegen->invalid_inst_gen; 17472 17473 ZigValue bit_count_value = {}; 17474 init_const_usize(ira->codegen, &bit_count_value, bit_count); 17475 17476 if (!value_cmp_numeric_val_all(op2_val, CmpLT, &bit_count_value)) { 17477 ErrorMsg* msg = ir_add_error(ira, 17478 &bin_op_instruction->base.base, 17479 buf_sprintf("RHS of shift is too large for LHS type")); 17480 add_error_note(ira->codegen, msg, op1->base.source_node, 17481 buf_sprintf("type %s has only %u bits", 17482 buf_ptr(&op1->value->type->name), bit_count)); 17483 17484 return ira->codegen->invalid_inst_gen; 17485 } 17486 } 17487 } 17488 17489 // Fast path for zero RHS 17490 if (instr_is_comptime(casted_op2)) { 17491 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 17492 if (op2_val == nullptr) 17493 return ira->codegen->invalid_inst_gen; 17494 17495 if (value_cmp_numeric_val_all(op2_val, CmpEQ, nullptr)) 17496 return ir_analyze_cast(ira, &bin_op_instruction->base.base, op1->value->type, op1); 17497 } 17498 17499 if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) { 17500 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 17501 if (op1_val == nullptr) 17502 return ira->codegen->invalid_inst_gen; 17503 17504 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 17505 if (op2_val == nullptr) 17506 return ira->codegen->invalid_inst_gen; 17507 17508 return ir_analyze_math_op(ira, &bin_op_instruction->base.base, op1_type, op1_val, op_id, op2_val); 17509 } 17510 17511 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, op1->value->type, 17512 op_id, op1, casted_op2, bin_op_instruction->safety_check_on); 17513 } 17514 17515 static bool ok_float_op(IrBinOp op) { 17516 switch (op) { 17517 case IrBinOpInvalid: 17518 zig_unreachable(); 17519 case IrBinOpAdd: 17520 case IrBinOpSub: 17521 case IrBinOpMult: 17522 case IrBinOpDivUnspecified: 17523 case IrBinOpDivTrunc: 17524 case IrBinOpDivFloor: 17525 case IrBinOpDivExact: 17526 case IrBinOpRemRem: 17527 case IrBinOpRemMod: 17528 case IrBinOpRemUnspecified: 17529 return true; 17530 17531 case IrBinOpBoolOr: 17532 case IrBinOpBoolAnd: 17533 case IrBinOpCmpEq: 17534 case IrBinOpCmpNotEq: 17535 case IrBinOpCmpLessThan: 17536 case IrBinOpCmpGreaterThan: 17537 case IrBinOpCmpLessOrEq: 17538 case IrBinOpCmpGreaterOrEq: 17539 case IrBinOpBinOr: 17540 case IrBinOpBinXor: 17541 case IrBinOpBinAnd: 17542 case IrBinOpBitShiftLeftLossy: 17543 case IrBinOpBitShiftLeftExact: 17544 case IrBinOpBitShiftRightLossy: 17545 case IrBinOpBitShiftRightExact: 17546 case IrBinOpAddWrap: 17547 case IrBinOpSubWrap: 17548 case IrBinOpMultWrap: 17549 case IrBinOpArrayCat: 17550 case IrBinOpArrayMult: 17551 return false; 17552 } 17553 zig_unreachable(); 17554 } 17555 17556 static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) { 17557 switch (op) { 17558 case IrBinOpAdd: 17559 case IrBinOpSub: 17560 break; 17561 default: 17562 return false; 17563 } 17564 if (lhs_type->id != ZigTypeIdPointer) 17565 return false; 17566 switch (lhs_type->data.pointer.ptr_len) { 17567 case PtrLenSingle: 17568 return lhs_type->data.pointer.child_type->id == ZigTypeIdArray; 17569 case PtrLenUnknown: 17570 case PtrLenC: 17571 return true; 17572 } 17573 zig_unreachable(); 17574 } 17575 17576 static bool value_cmp_numeric_val(ZigValue *left, Cmp predicate, ZigValue *right, bool any) { 17577 assert(left->special == ConstValSpecialStatic); 17578 assert(right == nullptr || right->special == ConstValSpecialStatic); 17579 17580 switch (left->type->id) { 17581 case ZigTypeIdComptimeInt: 17582 case ZigTypeIdInt: { 17583 const Cmp result = right ? 17584 bigint_cmp(&left->data.x_bigint, &right->data.x_bigint) : 17585 bigint_cmp_zero(&left->data.x_bigint); 17586 return result == predicate; 17587 } 17588 case ZigTypeIdComptimeFloat: 17589 case ZigTypeIdFloat: { 17590 if (float_is_nan(left)) 17591 return false; 17592 if (right != nullptr && float_is_nan(right)) 17593 return false; 17594 17595 const Cmp result = right ? float_cmp(left, right) : float_cmp_zero(left); 17596 return result == predicate; 17597 } 17598 case ZigTypeIdVector: { 17599 for (size_t i = 0; i < left->type->data.vector.len; i++) { 17600 ZigValue *scalar_val = &left->data.x_array.data.s_none.elements[i]; 17601 const bool result = value_cmp_numeric_val(scalar_val, predicate, right, any); 17602 17603 if (any && result) 17604 return true; // This element satisfies the predicate 17605 else if (!any && !result) 17606 return false; // This element doesn't satisfy the predicate 17607 } 17608 return any ? false : true; 17609 } 17610 default: 17611 zig_unreachable(); 17612 } 17613 } 17614 17615 static bool value_cmp_numeric_val_any(ZigValue *left, Cmp predicate, ZigValue *right) { 17616 return value_cmp_numeric_val(left, predicate, right, true); 17617 } 17618 17619 static bool value_cmp_numeric_val_all(ZigValue *left, Cmp predicate, ZigValue *right) { 17620 return value_cmp_numeric_val(left, predicate, right, false); 17621 } 17622 17623 static IrInstGen *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstSrcBinOp *instruction) { 17624 Error err; 17625 17626 IrInstGen *op1 = instruction->op1->child; 17627 if (type_is_invalid(op1->value->type)) 17628 return ira->codegen->invalid_inst_gen; 17629 17630 IrInstGen *op2 = instruction->op2->child; 17631 if (type_is_invalid(op2->value->type)) 17632 return ira->codegen->invalid_inst_gen; 17633 17634 IrBinOp op_id = instruction->op_id; 17635 17636 // look for pointer math 17637 if (is_pointer_arithmetic_allowed(op1->value->type, op_id)) { 17638 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, ira->codegen->builtin_types.entry_usize); 17639 if (type_is_invalid(casted_op2->value->type)) 17640 return ira->codegen->invalid_inst_gen; 17641 17642 // If either operand is undef, result is undef. 17643 ZigValue *op1_val = nullptr; 17644 ZigValue *op2_val = nullptr; 17645 if (instr_is_comptime(op1)) { 17646 op1_val = ir_resolve_const(ira, op1, UndefOk); 17647 if (op1_val == nullptr) 17648 return ira->codegen->invalid_inst_gen; 17649 if (op1_val->special == ConstValSpecialUndef) 17650 return ir_const_undef(ira, &instruction->base.base, op1->value->type); 17651 } 17652 if (instr_is_comptime(casted_op2)) { 17653 op2_val = ir_resolve_const(ira, casted_op2, UndefOk); 17654 if (op2_val == nullptr) 17655 return ira->codegen->invalid_inst_gen; 17656 if (op2_val->special == ConstValSpecialUndef) 17657 return ir_const_undef(ira, &instruction->base.base, op1->value->type); 17658 } 17659 17660 ZigType *elem_type = op1->value->type->data.pointer.child_type; 17661 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) 17662 return ira->codegen->invalid_inst_gen; 17663 17664 // NOTE: this variable is meaningful iff op2_val is not null! 17665 uint64_t byte_offset; 17666 if (op2_val != nullptr) { 17667 uint64_t elem_offset; 17668 if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) 17669 return ira->codegen->invalid_inst_gen; 17670 17671 byte_offset = type_size(ira->codegen, elem_type) * elem_offset; 17672 } 17673 17674 // Fast path for cases where the RHS is zero 17675 if (op2_val != nullptr && byte_offset == 0) { 17676 return op1; 17677 } 17678 17679 ZigType *result_type = op1->value->type; 17680 // Calculate the new alignment of the pointer 17681 { 17682 uint32_t align_bytes; 17683 if ((err = resolve_ptr_align(ira, op1->value->type, &align_bytes))) 17684 return ira->codegen->invalid_inst_gen; 17685 17686 // If the addend is not a comptime-known value we can still count on 17687 // it being a multiple of the type size 17688 uint32_t addend = op2_val ? byte_offset : type_size(ira->codegen, elem_type); 17689 17690 // The resulting pointer is aligned to the lcd between the 17691 // offset (an arbitrary number) and the alignment factor (always 17692 // a power of two, non zero) 17693 uint32_t new_align = 1 << ctzll(addend | align_bytes); 17694 // Rough guard to prevent overflows 17695 assert(new_align); 17696 result_type = adjust_ptr_align(ira->codegen, result_type, new_align); 17697 } 17698 17699 if (op2_val != nullptr && op1_val != nullptr && 17700 (op1->value->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 17701 op1->value->data.x_ptr.special == ConstPtrSpecialNull)) 17702 { 17703 uint64_t start_addr = (op1_val->data.x_ptr.special == ConstPtrSpecialNull) ? 17704 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr; 17705 uint64_t new_addr; 17706 if (op_id == IrBinOpAdd) { 17707 new_addr = start_addr + byte_offset; 17708 } else if (op_id == IrBinOpSub) { 17709 new_addr = start_addr - byte_offset; 17710 } else { 17711 zig_unreachable(); 17712 } 17713 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 17714 result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 17715 result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; 17716 result->value->data.x_ptr.data.hard_coded_addr.addr = new_addr; 17717 return result; 17718 } 17719 17720 return ir_build_bin_op_gen(ira, &instruction->base.base, result_type, op_id, op1, casted_op2, true); 17721 } 17722 17723 IrInstGen *instructions[] = {op1, op2}; 17724 ZigType *resolved_type = ir_resolve_peer_types(ira, instruction->base.base.source_node, nullptr, instructions, 2); 17725 if (type_is_invalid(resolved_type)) 17726 return ira->codegen->invalid_inst_gen; 17727 17728 ZigType *scalar_type = (resolved_type->id == ZigTypeIdVector) ? 17729 resolved_type->data.vector.elem_type : resolved_type; 17730 17731 bool is_int = scalar_type->id == ZigTypeIdInt || scalar_type->id == ZigTypeIdComptimeInt; 17732 bool is_float = scalar_type->id == ZigTypeIdFloat || scalar_type->id == ZigTypeIdComptimeFloat; 17733 17734 if (!is_int && !(is_float && ok_float_op(op_id))) { 17735 AstNode *source_node = instruction->base.base.source_node; 17736 ir_add_error_node(ira, source_node, 17737 buf_sprintf("invalid operands to binary expression: '%s' and '%s'", 17738 buf_ptr(&op1->value->type->name), 17739 buf_ptr(&op2->value->type->name))); 17740 return ira->codegen->invalid_inst_gen; 17741 } 17742 17743 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 17744 if (type_is_invalid(casted_op1->value->type)) 17745 return ira->codegen->invalid_inst_gen; 17746 17747 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 17748 if (type_is_invalid(casted_op2->value->type)) 17749 return ira->codegen->invalid_inst_gen; 17750 17751 // Comptime integers have no fixed size 17752 if (scalar_type->id == ZigTypeIdComptimeInt) { 17753 if (op_id == IrBinOpAddWrap) { 17754 op_id = IrBinOpAdd; 17755 } else if (op_id == IrBinOpSubWrap) { 17756 op_id = IrBinOpSub; 17757 } else if (op_id == IrBinOpMultWrap) { 17758 op_id = IrBinOpMult; 17759 } 17760 } 17761 17762 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 17763 ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 17764 if (op1_val == nullptr) 17765 return ira->codegen->invalid_inst_gen; 17766 17767 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 17768 if (op2_val == nullptr) 17769 return ira->codegen->invalid_inst_gen; 17770 17771 // Promote division with negative numbers to signed 17772 bool is_signed_div = value_cmp_numeric_val_any(op1_val, CmpLT, nullptr) || 17773 value_cmp_numeric_val_any(op2_val, CmpLT, nullptr); 17774 17775 if (op_id == IrBinOpDivUnspecified && is_int) { 17776 // Default to truncating division and check if it's valid for the 17777 // given operands if signed 17778 op_id = IrBinOpDivTrunc; 17779 17780 if (is_signed_div) { 17781 bool ok = false; 17782 17783 if (value_cmp_numeric_val_any(op2_val, CmpEQ, nullptr)) { 17784 // the division by zero error will be caught later, but we don't have a 17785 // division function ambiguity problem. 17786 ok = true; 17787 } else { 17788 IrInstGen *trunc_val = ir_analyze_math_op(ira, &instruction->base.base, resolved_type, 17789 op1_val, IrBinOpDivTrunc, op2_val); 17790 if (type_is_invalid(trunc_val->value->type)) 17791 return ira->codegen->invalid_inst_gen; 17792 17793 IrInstGen *floor_val = ir_analyze_math_op(ira, &instruction->base.base, resolved_type, 17794 op1_val, IrBinOpDivFloor, op2_val); 17795 if (type_is_invalid(floor_val->value->type)) 17796 return ira->codegen->invalid_inst_gen; 17797 17798 IrInstGen *cmp_val = ir_analyze_bin_op_cmp_numeric(ira, &instruction->base.base, 17799 trunc_val, floor_val, IrBinOpCmpEq); 17800 if (type_is_invalid(cmp_val->value->type)) 17801 return ira->codegen->invalid_inst_gen; 17802 17803 // We can "upgrade" the operator only if trunc(a/b) == floor(a/b) 17804 if (!ir_resolve_bool(ira, cmp_val, &ok)) 17805 return ira->codegen->invalid_inst_gen; 17806 } 17807 17808 if (!ok) { 17809 ir_add_error(ira, &instruction->base.base, 17810 buf_sprintf("division with '%s' and '%s': signed integers must use @divTrunc, @divFloor, or @divExact", 17811 buf_ptr(&op1->value->type->name), 17812 buf_ptr(&op2->value->type->name))); 17813 return ira->codegen->invalid_inst_gen; 17814 } 17815 } 17816 } else if (op_id == IrBinOpRemUnspecified) { 17817 op_id = IrBinOpRemRem; 17818 17819 if (is_signed_div) { 17820 bool ok = false; 17821 17822 if (value_cmp_numeric_val_any(op2_val, CmpEQ, nullptr)) { 17823 // the division by zero error will be caught later, but we don't have a 17824 // division function ambiguity problem. 17825 ok = true; 17826 } else { 17827 IrInstGen *rem_val = ir_analyze_math_op(ira, &instruction->base.base, resolved_type, 17828 op1_val, IrBinOpRemRem, op2_val); 17829 if (type_is_invalid(rem_val->value->type)) 17830 return ira->codegen->invalid_inst_gen; 17831 17832 IrInstGen *mod_val = ir_analyze_math_op(ira, &instruction->base.base, resolved_type, 17833 op1_val, IrBinOpRemMod, op2_val); 17834 if (type_is_invalid(mod_val->value->type)) 17835 return ira->codegen->invalid_inst_gen; 17836 17837 IrInstGen *cmp_val = ir_analyze_bin_op_cmp_numeric(ira, &instruction->base.base, 17838 rem_val, mod_val, IrBinOpCmpEq); 17839 if (type_is_invalid(cmp_val->value->type)) 17840 return ira->codegen->invalid_inst_gen; 17841 17842 // We can "upgrade" the operator only if mod(a,b) == rem(a,b) 17843 if (!ir_resolve_bool(ira, cmp_val, &ok)) 17844 return ira->codegen->invalid_inst_gen; 17845 } 17846 17847 if (!ok) { 17848 ir_add_error(ira, &instruction->base.base, 17849 buf_sprintf("remainder division with '%s' and '%s': signed integers and floats must use @rem or @mod", 17850 buf_ptr(&op1->value->type->name), 17851 buf_ptr(&op2->value->type->name))); 17852 return ira->codegen->invalid_inst_gen; 17853 } 17854 } 17855 } 17856 17857 return ir_analyze_math_op(ira, &instruction->base.base, resolved_type, op1_val, op_id, op2_val); 17858 } 17859 17860 const bool is_signed_div = 17861 (scalar_type->id == ZigTypeIdInt && scalar_type->data.integral.is_signed) || 17862 scalar_type->id == ZigTypeIdFloat; 17863 17864 // Warn the user to use the proper operators here 17865 if (op_id == IrBinOpDivUnspecified && is_int) { 17866 op_id = IrBinOpDivTrunc; 17867 17868 if (is_signed_div) { 17869 ir_add_error(ira, &instruction->base.base, 17870 buf_sprintf("division with '%s' and '%s': signed integers must use @divTrunc, @divFloor, or @divExact", 17871 buf_ptr(&op1->value->type->name), 17872 buf_ptr(&op2->value->type->name))); 17873 return ira->codegen->invalid_inst_gen; 17874 } 17875 } else if (op_id == IrBinOpRemUnspecified) { 17876 op_id = IrBinOpRemRem; 17877 17878 if (is_signed_div) { 17879 ir_add_error(ira, &instruction->base.base, 17880 buf_sprintf("remainder division with '%s' and '%s': signed integers and floats must use @rem or @mod", 17881 buf_ptr(&op1->value->type->name), 17882 buf_ptr(&op2->value->type->name))); 17883 return ira->codegen->invalid_inst_gen; 17884 } 17885 } 17886 17887 return ir_build_bin_op_gen(ira, &instruction->base.base, resolved_type, 17888 op_id, casted_op1, casted_op2, instruction->safety_check_on); 17889 } 17890 17891 static IrInstGen *ir_analyze_tuple_cat(IrAnalyze *ira, IrInst* source_instr, 17892 IrInstGen *op1, IrInstGen *op2) 17893 { 17894 Error err; 17895 ZigType *op1_type = op1->value->type; 17896 ZigType *op2_type = op2->value->type; 17897 17898 uint32_t op1_field_count = op1_type->data.structure.src_field_count; 17899 uint32_t op2_field_count = op2_type->data.structure.src_field_count; 17900 17901 Buf *bare_name = buf_alloc(); 17902 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), 17903 source_instr->scope, source_instr->source_node, bare_name); 17904 ZigType *new_type = get_partial_container_type(ira->codegen, source_instr->scope, 17905 ContainerKindStruct, source_instr->source_node, buf_ptr(name), bare_name, ContainerLayoutAuto); 17906 new_type->data.structure.special = StructSpecialInferredTuple; 17907 new_type->data.structure.resolve_status = ResolveStatusBeingInferred; 17908 uint32_t new_field_count = op1_field_count + op2_field_count; 17909 17910 new_type->data.structure.src_field_count = new_field_count; 17911 new_type->data.structure.fields = realloc_type_struct_fields(new_type->data.structure.fields, 17912 0, new_field_count); 17913 17914 IrInstGen *new_struct_ptr = ir_resolve_result(ira, source_instr, no_result_loc(), 17915 new_type, nullptr, false, true); 17916 17917 for (uint32_t i = 0; i < new_field_count; i += 1) { 17918 TypeStructField *src_field; 17919 if (i < op1_field_count) { 17920 src_field = op1_type->data.structure.fields[i]; 17921 } else { 17922 src_field = op2_type->data.structure.fields[i - op1_field_count]; 17923 } 17924 TypeStructField *new_field = new_type->data.structure.fields[i]; 17925 new_field->name = buf_sprintf("%" PRIu32, i); 17926 new_field->type_entry = src_field->type_entry; 17927 new_field->type_val = src_field->type_val; 17928 new_field->src_index = i; 17929 new_field->decl_node = src_field->decl_node; 17930 new_field->init_val = src_field->init_val; 17931 new_field->is_comptime = src_field->is_comptime; 17932 } 17933 if ((err = type_resolve(ira->codegen, new_type, ResolveStatusZeroBitsKnown))) 17934 return ira->codegen->invalid_inst_gen; 17935 17936 ZigList<IrInstGen *> const_ptrs = {}; 17937 for (uint32_t i = 0; i < new_field_count; i += 1) { 17938 TypeStructField *dst_field = new_type->data.structure.fields[i]; 17939 IrInstGen *src_struct_op; 17940 TypeStructField *src_field; 17941 if (i < op1_field_count) { 17942 src_field = op1_type->data.structure.fields[i]; 17943 src_struct_op = op1; 17944 } else { 17945 src_field = op2_type->data.structure.fields[i - op1_field_count]; 17946 src_struct_op = op2; 17947 } 17948 IrInstGen *field_value = ir_analyze_struct_value_field_value(ira, source_instr, 17949 src_struct_op, src_field); 17950 if (type_is_invalid(field_value->value->type)) 17951 return ira->codegen->invalid_inst_gen; 17952 IrInstGen *dest_ptr = ir_analyze_struct_field_ptr(ira, source_instr, dst_field, 17953 new_struct_ptr, new_type, true); 17954 if (type_is_invalid(dest_ptr->value->type)) 17955 return ira->codegen->invalid_inst_gen; 17956 if (instr_is_comptime(field_value)) { 17957 const_ptrs.append(dest_ptr); 17958 } 17959 IrInstGen *store_ptr_inst = ir_analyze_store_ptr(ira, source_instr, dest_ptr, field_value, 17960 true); 17961 if (type_is_invalid(store_ptr_inst->value->type)) 17962 return ira->codegen->invalid_inst_gen; 17963 } 17964 if (const_ptrs.length != new_field_count) { 17965 new_struct_ptr->value->special = ConstValSpecialRuntime; 17966 for (size_t i = 0; i < const_ptrs.length; i += 1) { 17967 IrInstGen *elem_result_loc = const_ptrs.at(i); 17968 assert(elem_result_loc->value->special == ConstValSpecialStatic); 17969 if (elem_result_loc->value->type->data.pointer.inferred_struct_field != nullptr) { 17970 // This field will be generated comptime; no need to do this. 17971 continue; 17972 } 17973 IrInstGen *deref = ir_get_deref(ira, &elem_result_loc->base, elem_result_loc, nullptr); 17974 if (!type_requires_comptime(ira->codegen, elem_result_loc->value->type->data.pointer.child_type)) { 17975 elem_result_loc->value->special = ConstValSpecialRuntime; 17976 } 17977 ir_analyze_store_ptr(ira, &elem_result_loc->base, elem_result_loc, deref, true); 17978 } 17979 } 17980 17981 const_ptrs.deinit(); 17982 17983 return ir_get_deref(ira, source_instr, new_struct_ptr, nullptr); 17984 } 17985 17986 static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instruction) { 17987 IrInstGen *op1 = instruction->op1->child; 17988 ZigType *op1_type = op1->value->type; 17989 if (type_is_invalid(op1_type)) 17990 return ira->codegen->invalid_inst_gen; 17991 17992 IrInstGen *op2 = instruction->op2->child; 17993 ZigType *op2_type = op2->value->type; 17994 if (type_is_invalid(op2_type)) 17995 return ira->codegen->invalid_inst_gen; 17996 17997 if (is_tuple(op1_type) && is_tuple(op2_type)) { 17998 return ir_analyze_tuple_cat(ira, &instruction->base.base, op1, op2); 17999 } 18000 18001 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 18002 if (!op1_val) 18003 return ira->codegen->invalid_inst_gen; 18004 18005 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 18006 if (!op2_val) 18007 return ira->codegen->invalid_inst_gen; 18008 18009 ZigValue *sentinel1 = nullptr; 18010 ZigValue *op1_array_val; 18011 size_t op1_array_index; 18012 size_t op1_array_end; 18013 ZigType *child_type; 18014 if (op1_type->id == ZigTypeIdArray) { 18015 child_type = op1_type->data.array.child_type; 18016 op1_array_val = op1_val; 18017 op1_array_index = 0; 18018 op1_array_end = op1_type->data.array.len; 18019 sentinel1 = op1_type->data.array.sentinel; 18020 } else if (op1_type->id == ZigTypeIdPointer && 18021 op1_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && 18022 op1_type->data.pointer.sentinel != nullptr && 18023 op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray) 18024 { 18025 child_type = op1_type->data.pointer.child_type; 18026 op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; 18027 op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; 18028 op1_array_end = op1_array_val->type->data.array.len; 18029 sentinel1 = op1_type->data.pointer.sentinel; 18030 } else if (is_slice(op1_type)) { 18031 ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index]->type_entry; 18032 child_type = ptr_type->data.pointer.child_type; 18033 ZigValue *ptr_val = op1_val->data.x_struct.fields[slice_ptr_index]; 18034 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 18035 op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 18036 op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 18037 ZigValue *len_val = op1_val->data.x_struct.fields[slice_len_index]; 18038 op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint); 18039 sentinel1 = ptr_type->data.pointer.sentinel; 18040 } else if (op1_type->id == ZigTypeIdPointer && 18041 op1_type->data.pointer.ptr_len == PtrLenSingle && 18042 op1_type->data.pointer.child_type->id == ZigTypeIdArray) 18043 { 18044 ZigType *array_type = op1_type->data.pointer.child_type; 18045 child_type = array_type->data.array.child_type; 18046 op1_array_val = const_ptr_pointee(ira, ira->codegen, op1_val, op1->base.source_node); 18047 if (op1_array_val == nullptr) 18048 return ira->codegen->invalid_inst_gen; 18049 op1_array_index = 0; 18050 op1_array_end = array_type->data.array.len; 18051 sentinel1 = array_type->data.array.sentinel; 18052 } else { 18053 ir_add_error(ira, &op1->base, buf_sprintf("expected array, found '%s'", buf_ptr(&op1->value->type->name))); 18054 return ira->codegen->invalid_inst_gen; 18055 } 18056 18057 ZigValue *sentinel2 = nullptr; 18058 ZigValue *op2_array_val; 18059 size_t op2_array_index; 18060 size_t op2_array_end; 18061 bool op2_type_valid; 18062 if (op2_type->id == ZigTypeIdArray) { 18063 op2_type_valid = op2_type->data.array.child_type == child_type; 18064 op2_array_val = op2_val; 18065 op2_array_index = 0; 18066 op2_array_end = op2_array_val->type->data.array.len; 18067 sentinel2 = op2_type->data.array.sentinel; 18068 } else if (op2_type->id == ZigTypeIdPointer && 18069 op2_type->data.pointer.sentinel != nullptr && 18070 op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray) 18071 { 18072 op2_type_valid = op2_type->data.pointer.child_type == child_type; 18073 op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; 18074 op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; 18075 op2_array_end = op2_array_val->type->data.array.len; 18076 18077 sentinel2 = op2_type->data.pointer.sentinel; 18078 } else if (is_slice(op2_type)) { 18079 ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index]->type_entry; 18080 op2_type_valid = ptr_type->data.pointer.child_type == child_type; 18081 ZigValue *ptr_val = op2_val->data.x_struct.fields[slice_ptr_index]; 18082 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 18083 op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 18084 op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 18085 ZigValue *len_val = op2_val->data.x_struct.fields[slice_len_index]; 18086 op2_array_end = op2_array_index + bigint_as_usize(&len_val->data.x_bigint); 18087 18088 sentinel2 = ptr_type->data.pointer.sentinel; 18089 } else if (op2_type->id == ZigTypeIdPointer && op2_type->data.pointer.ptr_len == PtrLenSingle && 18090 op2_type->data.pointer.child_type->id == ZigTypeIdArray) 18091 { 18092 ZigType *array_type = op2_type->data.pointer.child_type; 18093 op2_type_valid = array_type->data.array.child_type == child_type; 18094 op2_array_val = const_ptr_pointee(ira, ira->codegen, op2_val, op2->base.source_node); 18095 if (op2_array_val == nullptr) 18096 return ira->codegen->invalid_inst_gen; 18097 op2_array_index = 0; 18098 op2_array_end = array_type->data.array.len; 18099 18100 sentinel2 = array_type->data.array.sentinel; 18101 } else { 18102 ir_add_error(ira, &op2->base, 18103 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value->type->name))); 18104 return ira->codegen->invalid_inst_gen; 18105 } 18106 if (!op2_type_valid) { 18107 ir_add_error(ira, &op2->base, buf_sprintf("expected array of type '%s', found '%s'", 18108 buf_ptr(&child_type->name), 18109 buf_ptr(&op2->value->type->name))); 18110 return ira->codegen->invalid_inst_gen; 18111 } 18112 18113 ZigValue *sentinel; 18114 if (sentinel1 != nullptr && sentinel2 != nullptr) { 18115 // When there is a sentinel mismatch, no sentinel on the result. The type system 18116 // will catch this if it is a problem. 18117 sentinel = const_values_equal(ira->codegen, sentinel1, sentinel2) ? sentinel1 : nullptr; 18118 } else if (sentinel1 != nullptr) { 18119 sentinel = sentinel1; 18120 } else if (sentinel2 != nullptr) { 18121 sentinel = sentinel2; 18122 } else { 18123 sentinel = nullptr; 18124 } 18125 18126 // The type of result is populated in the following if blocks 18127 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 18128 ZigValue *out_val = result->value; 18129 18130 ZigValue *out_array_val; 18131 size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); 18132 if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) { 18133 out_array_val = ira->codegen->pass1_arena->create<ZigValue>(); 18134 out_array_val->special = ConstValSpecialStatic; 18135 out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 18136 18137 out_val->data.x_ptr.special = ConstPtrSpecialRef; 18138 out_val->data.x_ptr.data.ref.pointee = out_array_val; 18139 out_val->type = get_pointer_to_type(ira->codegen, out_array_val->type, true); 18140 } else if (is_slice(op1_type) || is_slice(op2_type)) { 18141 ZigType *ptr_type = get_pointer_to_type_extra2(ira->codegen, child_type, 18142 true, false, PtrLenUnknown, 0, 0, 0, false, 18143 VECTOR_INDEX_NONE, nullptr, sentinel); 18144 result->value->type = get_slice_type(ira->codegen, ptr_type); 18145 out_array_val = ira->codegen->pass1_arena->create<ZigValue>(); 18146 out_array_val->special = ConstValSpecialStatic; 18147 out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 18148 18149 out_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, 2); 18150 18151 out_val->data.x_struct.fields[slice_ptr_index]->type = ptr_type; 18152 out_val->data.x_struct.fields[slice_ptr_index]->special = ConstValSpecialStatic; 18153 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.special = ConstPtrSpecialBaseArray; 18154 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.array_val = out_array_val; 18155 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.elem_index = 0; 18156 18157 out_val->data.x_struct.fields[slice_len_index]->type = ira->codegen->builtin_types.entry_usize; 18158 out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic; 18159 bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len); 18160 } else if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { 18161 result->value->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 18162 out_array_val = out_val; 18163 } else { 18164 result->value->type = get_pointer_to_type_extra2(ira->codegen, child_type, true, false, PtrLenUnknown, 18165 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr, sentinel); 18166 out_array_val = ira->codegen->pass1_arena->create<ZigValue>(); 18167 out_array_val->special = ConstValSpecialStatic; 18168 out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 18169 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 18170 out_val->data.x_ptr.data.base_array.array_val = out_array_val; 18171 out_val->data.x_ptr.data.base_array.elem_index = 0; 18172 } 18173 18174 if (op1_array_val->data.x_array.special == ConstArraySpecialUndef && 18175 op2_array_val->data.x_array.special == ConstArraySpecialUndef) 18176 { 18177 out_array_val->data.x_array.special = ConstArraySpecialUndef; 18178 return result; 18179 } 18180 18181 uint64_t full_len = new_len + ((sentinel != nullptr) ? 1 : 0); 18182 out_array_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(full_len); 18183 // TODO handle the buf case here for an optimization 18184 expand_undef_array(ira->codegen, op1_array_val); 18185 expand_undef_array(ira->codegen, op2_array_val); 18186 18187 size_t next_index = 0; 18188 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { 18189 ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; 18190 copy_const_val(ira->codegen, elem_dest_val, &op1_array_val->data.x_array.data.s_none.elements[i]); 18191 elem_dest_val->parent.id = ConstParentIdArray; 18192 elem_dest_val->parent.data.p_array.array_val = out_array_val; 18193 elem_dest_val->parent.data.p_array.elem_index = next_index; 18194 } 18195 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { 18196 ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; 18197 copy_const_val(ira->codegen, elem_dest_val, &op2_array_val->data.x_array.data.s_none.elements[i]); 18198 elem_dest_val->parent.id = ConstParentIdArray; 18199 elem_dest_val->parent.data.p_array.array_val = out_array_val; 18200 elem_dest_val->parent.data.p_array.elem_index = next_index; 18201 } 18202 if (next_index < full_len) { 18203 ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; 18204 copy_const_val(ira->codegen, elem_dest_val, sentinel); 18205 elem_dest_val->parent.id = ConstParentIdArray; 18206 elem_dest_val->parent.data.p_array.array_val = out_array_val; 18207 elem_dest_val->parent.data.p_array.elem_index = next_index; 18208 next_index += 1; 18209 } 18210 assert(next_index == full_len); 18211 18212 return result; 18213 } 18214 18215 static IrInstGen *ir_analyze_tuple_mult(IrAnalyze *ira, IrInst* source_instr, 18216 IrInstGen *op1, IrInstGen *op2) 18217 { 18218 Error err; 18219 ZigType *op1_type = op1->value->type; 18220 uint64_t op1_field_count = op1_type->data.structure.src_field_count; 18221 18222 uint64_t mult_amt; 18223 if (!ir_resolve_usize(ira, op2, &mult_amt)) 18224 return ira->codegen->invalid_inst_gen; 18225 18226 uint64_t new_field_count; 18227 if (mul_u64_overflow(op1_field_count, mult_amt, &new_field_count)) { 18228 ir_add_error(ira, source_instr, buf_sprintf("operation results in overflow")); 18229 return ira->codegen->invalid_inst_gen; 18230 } 18231 18232 Buf *bare_name = buf_alloc(); 18233 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), 18234 source_instr->scope, source_instr->source_node, bare_name); 18235 ZigType *new_type = get_partial_container_type(ira->codegen, source_instr->scope, 18236 ContainerKindStruct, source_instr->source_node, buf_ptr(name), bare_name, ContainerLayoutAuto); 18237 new_type->data.structure.special = StructSpecialInferredTuple; 18238 new_type->data.structure.resolve_status = ResolveStatusBeingInferred; 18239 new_type->data.structure.src_field_count = new_field_count; 18240 new_type->data.structure.fields = realloc_type_struct_fields( 18241 new_type->data.structure.fields, 0, new_field_count); 18242 18243 IrInstGen *new_struct_ptr = ir_resolve_result(ira, source_instr, no_result_loc(), 18244 new_type, nullptr, false, true); 18245 18246 for (uint64_t i = 0; i < new_field_count; i += 1) { 18247 TypeStructField *src_field = op1_type->data.structure.fields[i % op1_field_count]; 18248 TypeStructField *new_field = new_type->data.structure.fields[i]; 18249 18250 new_field->name = buf_sprintf("%" ZIG_PRI_u64, i); 18251 new_field->type_entry = src_field->type_entry; 18252 new_field->type_val = src_field->type_val; 18253 new_field->src_index = i; 18254 new_field->decl_node = src_field->decl_node; 18255 new_field->init_val = src_field->init_val; 18256 new_field->is_comptime = src_field->is_comptime; 18257 } 18258 18259 if ((err = type_resolve(ira->codegen, new_type, ResolveStatusZeroBitsKnown))) 18260 return ira->codegen->invalid_inst_gen; 18261 18262 ZigList<IrInstGen *> const_ptrs = {}; 18263 for (uint64_t i = 0; i < new_field_count; i += 1) { 18264 TypeStructField *src_field = op1_type->data.structure.fields[i % op1_field_count]; 18265 TypeStructField *dst_field = new_type->data.structure.fields[i]; 18266 18267 IrInstGen *field_value = ir_analyze_struct_value_field_value( 18268 ira, source_instr, op1, src_field); 18269 if (type_is_invalid(field_value->value->type)) 18270 return ira->codegen->invalid_inst_gen; 18271 18272 IrInstGen *dest_ptr = ir_analyze_struct_field_ptr( 18273 ira, source_instr, dst_field, new_struct_ptr, new_type, true); 18274 if (type_is_invalid(dest_ptr->value->type)) 18275 return ira->codegen->invalid_inst_gen; 18276 18277 if (instr_is_comptime(field_value)) { 18278 const_ptrs.append(dest_ptr); 18279 } 18280 18281 IrInstGen *store_ptr_inst = ir_analyze_store_ptr( 18282 ira, source_instr, dest_ptr, field_value, true); 18283 if (type_is_invalid(store_ptr_inst->value->type)) 18284 return ira->codegen->invalid_inst_gen; 18285 } 18286 18287 if (const_ptrs.length != new_field_count) { 18288 new_struct_ptr->value->special = ConstValSpecialRuntime; 18289 for (size_t i = 0; i < const_ptrs.length; i += 1) { 18290 IrInstGen *elem_result_loc = const_ptrs.at(i); 18291 assert(elem_result_loc->value->special == ConstValSpecialStatic); 18292 if (elem_result_loc->value->type->data.pointer.inferred_struct_field != nullptr) { 18293 // This field will be generated comptime; no need to do this. 18294 continue; 18295 } 18296 IrInstGen *deref = ir_get_deref(ira, &elem_result_loc->base, elem_result_loc, nullptr); 18297 if (!type_requires_comptime(ira->codegen, elem_result_loc->value->type->data.pointer.child_type)) { 18298 elem_result_loc->value->special = ConstValSpecialRuntime; 18299 } 18300 IrInstGen *store_ptr_inst = ir_analyze_store_ptr( 18301 ira, &elem_result_loc->base, elem_result_loc, deref, true); 18302 if (type_is_invalid(store_ptr_inst->value->type)) 18303 return ira->codegen->invalid_inst_gen; 18304 } 18305 } 18306 18307 const_ptrs.deinit(); 18308 18309 return ir_get_deref(ira, source_instr, new_struct_ptr, nullptr); 18310 } 18311 18312 static IrInstGen *ir_analyze_array_mult(IrAnalyze *ira, IrInstSrcBinOp *instruction) { 18313 IrInstGen *op1 = instruction->op1->child; 18314 if (type_is_invalid(op1->value->type)) 18315 return ira->codegen->invalid_inst_gen; 18316 18317 IrInstGen *op2 = instruction->op2->child; 18318 if (type_is_invalid(op2->value->type)) 18319 return ira->codegen->invalid_inst_gen; 18320 18321 bool want_ptr_to_array = false; 18322 ZigType *array_type; 18323 ZigValue *array_val; 18324 if (op1->value->type->id == ZigTypeIdArray) { 18325 array_type = op1->value->type; 18326 array_val = ir_resolve_const(ira, op1, UndefOk); 18327 if (array_val == nullptr) 18328 return ira->codegen->invalid_inst_gen; 18329 } else if (op1->value->type->id == ZigTypeIdPointer && 18330 op1->value->type->data.pointer.ptr_len == PtrLenSingle && 18331 op1->value->type->data.pointer.child_type->id == ZigTypeIdArray) 18332 { 18333 array_type = op1->value->type->data.pointer.child_type; 18334 IrInstGen *array_inst = ir_get_deref(ira, &op1->base, op1, nullptr); 18335 if (type_is_invalid(array_inst->value->type)) 18336 return ira->codegen->invalid_inst_gen; 18337 array_val = ir_resolve_const(ira, array_inst, UndefOk); 18338 if (array_val == nullptr) 18339 return ira->codegen->invalid_inst_gen; 18340 want_ptr_to_array = true; 18341 } else if (is_tuple(op1->value->type)) { 18342 return ir_analyze_tuple_mult(ira, &instruction->base.base, op1, op2); 18343 } else { 18344 ir_add_error(ira, &op1->base, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value->type->name))); 18345 return ira->codegen->invalid_inst_gen; 18346 } 18347 18348 uint64_t mult_amt; 18349 if (!ir_resolve_usize(ira, op2, &mult_amt)) 18350 return ira->codegen->invalid_inst_gen; 18351 18352 uint64_t old_array_len = array_type->data.array.len; 18353 uint64_t new_array_len; 18354 18355 if (mul_u64_overflow(old_array_len, mult_amt, &new_array_len)) { 18356 ir_add_error(ira, &instruction->base.base, buf_sprintf("operation results in overflow")); 18357 return ira->codegen->invalid_inst_gen; 18358 } 18359 18360 ZigType *child_type = array_type->data.array.child_type; 18361 ZigType *result_array_type = get_array_type(ira->codegen, child_type, new_array_len, 18362 array_type->data.array.sentinel); 18363 18364 IrInstGen *array_result; 18365 if (array_val->special == ConstValSpecialUndef || array_val->data.x_array.special == ConstArraySpecialUndef) { 18366 array_result = ir_const_undef(ira, &instruction->base.base, result_array_type); 18367 } else { 18368 array_result = ir_const(ira, &instruction->base.base, result_array_type); 18369 ZigValue *out_val = array_result->value; 18370 18371 switch (type_has_one_possible_value(ira->codegen, result_array_type)) { 18372 case OnePossibleValueInvalid: 18373 return ira->codegen->invalid_inst_gen; 18374 case OnePossibleValueYes: 18375 goto skip_computation; 18376 case OnePossibleValueNo: 18377 break; 18378 } 18379 18380 // TODO optimize the buf case 18381 expand_undef_array(ira->codegen, array_val); 18382 size_t extra_null_term = (array_type->data.array.sentinel != nullptr) ? 1 : 0; 18383 out_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(new_array_len + extra_null_term); 18384 18385 uint64_t i = 0; 18386 for (uint64_t x = 0; x < mult_amt; x += 1) { 18387 for (uint64_t y = 0; y < old_array_len; y += 1) { 18388 ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; 18389 copy_const_val(ira->codegen, elem_dest_val, &array_val->data.x_array.data.s_none.elements[y]); 18390 elem_dest_val->parent.id = ConstParentIdArray; 18391 elem_dest_val->parent.data.p_array.array_val = out_val; 18392 elem_dest_val->parent.data.p_array.elem_index = i; 18393 i += 1; 18394 } 18395 } 18396 assert(i == new_array_len); 18397 18398 if (array_type->data.array.sentinel != nullptr) { 18399 ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; 18400 copy_const_val(ira->codegen, elem_dest_val, array_type->data.array.sentinel); 18401 elem_dest_val->parent.id = ConstParentIdArray; 18402 elem_dest_val->parent.data.p_array.array_val = out_val; 18403 elem_dest_val->parent.data.p_array.elem_index = i; 18404 i += 1; 18405 } 18406 } 18407 skip_computation: 18408 if (want_ptr_to_array) { 18409 return ir_get_ref(ira, &instruction->base.base, array_result, true, false); 18410 } else { 18411 return array_result; 18412 } 18413 } 18414 18415 static IrInstGen *ir_analyze_instruction_merge_err_sets(IrAnalyze *ira, 18416 IrInstSrcMergeErrSets *instruction) 18417 { 18418 ZigType *op1_type = ir_resolve_error_set_type(ira, &instruction->base.base, instruction->op1->child); 18419 if (type_is_invalid(op1_type)) 18420 return ira->codegen->invalid_inst_gen; 18421 18422 ZigType *op2_type = ir_resolve_error_set_type(ira, &instruction->base.base, instruction->op2->child); 18423 if (type_is_invalid(op2_type)) 18424 return ira->codegen->invalid_inst_gen; 18425 18426 if (!resolve_inferred_error_set(ira->codegen, op1_type, instruction->op1->child->base.source_node)) { 18427 return ira->codegen->invalid_inst_gen; 18428 } 18429 18430 if (!resolve_inferred_error_set(ira->codegen, op2_type, instruction->op2->child->base.source_node)) { 18431 return ira->codegen->invalid_inst_gen; 18432 } 18433 18434 if (type_is_global_error_set(op1_type) || 18435 type_is_global_error_set(op2_type)) 18436 { 18437 return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_global_error_set); 18438 } 18439 18440 size_t errors_count = ira->codegen->errors_by_index.length; 18441 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count); 18442 for (uint32_t i = 0, count = op1_type->data.error_set.err_count; i < count; i += 1) { 18443 ErrorTableEntry *error_entry = op1_type->data.error_set.errors[i]; 18444 assert(errors[error_entry->value] == nullptr); 18445 errors[error_entry->value] = error_entry; 18446 } 18447 ZigType *result_type = get_error_set_union(ira->codegen, errors, op1_type, op2_type, instruction->type_name); 18448 heap::c_allocator.deallocate(errors, errors_count); 18449 18450 return ir_const_type(ira, &instruction->base.base, result_type); 18451 } 18452 18453 18454 static IrInstGen *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { 18455 IrBinOp op_id = bin_op_instruction->op_id; 18456 switch (op_id) { 18457 case IrBinOpInvalid: 18458 zig_unreachable(); 18459 case IrBinOpBoolOr: 18460 case IrBinOpBoolAnd: 18461 return ir_analyze_bin_op_bool(ira, bin_op_instruction); 18462 case IrBinOpCmpEq: 18463 case IrBinOpCmpNotEq: 18464 case IrBinOpCmpLessThan: 18465 case IrBinOpCmpGreaterThan: 18466 case IrBinOpCmpLessOrEq: 18467 case IrBinOpCmpGreaterOrEq: 18468 return ir_analyze_bin_op_cmp(ira, bin_op_instruction); 18469 case IrBinOpBitShiftLeftLossy: 18470 case IrBinOpBitShiftLeftExact: 18471 case IrBinOpBitShiftRightLossy: 18472 case IrBinOpBitShiftRightExact: 18473 return ir_analyze_bit_shift(ira, bin_op_instruction); 18474 case IrBinOpBinOr: 18475 case IrBinOpBinXor: 18476 case IrBinOpBinAnd: 18477 case IrBinOpAdd: 18478 case IrBinOpAddWrap: 18479 case IrBinOpSub: 18480 case IrBinOpSubWrap: 18481 case IrBinOpMult: 18482 case IrBinOpMultWrap: 18483 case IrBinOpDivUnspecified: 18484 case IrBinOpDivTrunc: 18485 case IrBinOpDivFloor: 18486 case IrBinOpDivExact: 18487 case IrBinOpRemUnspecified: 18488 case IrBinOpRemRem: 18489 case IrBinOpRemMod: 18490 return ir_analyze_bin_op_math(ira, bin_op_instruction); 18491 case IrBinOpArrayCat: 18492 return ir_analyze_array_cat(ira, bin_op_instruction); 18493 case IrBinOpArrayMult: 18494 return ir_analyze_array_mult(ira, bin_op_instruction); 18495 } 18496 zig_unreachable(); 18497 } 18498 18499 static IrInstGen *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstSrcDeclVar *decl_var_instruction) { 18500 Error err; 18501 ZigVar *var = decl_var_instruction->var; 18502 18503 ZigType *explicit_type = nullptr; 18504 IrInstGen *var_type = nullptr; 18505 if (decl_var_instruction->var_type != nullptr) { 18506 var_type = decl_var_instruction->var_type->child; 18507 ZigType *proposed_type = ir_resolve_type(ira, var_type); 18508 explicit_type = validate_var_type(ira->codegen, var_type->base.source_node, proposed_type); 18509 if (type_is_invalid(explicit_type)) { 18510 var->var_type = ira->codegen->builtin_types.entry_invalid; 18511 return ira->codegen->invalid_inst_gen; 18512 } 18513 } 18514 18515 AstNode *source_node = decl_var_instruction->base.base.source_node; 18516 18517 bool is_comptime_var = ir_get_var_is_comptime(var); 18518 18519 bool var_class_requires_const = false; 18520 18521 IrInstGen *var_ptr = decl_var_instruction->ptr->child; 18522 // if this is null, a compiler error happened and did not initialize the variable. 18523 // if there are no compile errors there may be a missing ir_expr_wrap in pass1 IR generation. 18524 if (var_ptr == nullptr || type_is_invalid(var_ptr->value->type)) { 18525 ir_assert(var_ptr != nullptr || ira->codegen->errors.length != 0, &decl_var_instruction->base.base); 18526 var->var_type = ira->codegen->builtin_types.entry_invalid; 18527 return ira->codegen->invalid_inst_gen; 18528 } 18529 18530 // The ir_build_var_decl_src call is supposed to pass a pointer to the allocation, not an initialization value. 18531 ir_assert(var_ptr->value->type->id == ZigTypeIdPointer, &decl_var_instruction->base.base); 18532 18533 ZigType *result_type = var_ptr->value->type->data.pointer.child_type; 18534 if (type_is_invalid(result_type)) { 18535 result_type = ira->codegen->builtin_types.entry_invalid; 18536 } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) { 18537 zig_unreachable(); 18538 } 18539 18540 ZigValue *init_val = nullptr; 18541 if (instr_is_comptime(var_ptr) && var_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 18542 ZigValue *ptr_val = ir_resolve_const(ira, var_ptr, UndefBad); 18543 if (ptr_val == nullptr) 18544 return ira->codegen->invalid_inst_gen; 18545 18546 init_val = const_ptr_pointee(ira, ira->codegen, ptr_val, decl_var_instruction->base.base.source_node); 18547 if (init_val == nullptr) 18548 return ira->codegen->invalid_inst_gen; 18549 18550 if (is_comptime_var) { 18551 if (var->gen_is_const) { 18552 var->const_value = init_val; 18553 } else { 18554 var->const_value = ira->codegen->pass1_arena->create<ZigValue>(); 18555 copy_const_val(ira->codegen, var->const_value, init_val); 18556 } 18557 } 18558 } 18559 18560 switch (type_requires_comptime(ira->codegen, result_type)) { 18561 case ReqCompTimeInvalid: 18562 result_type = ira->codegen->builtin_types.entry_invalid; 18563 break; 18564 case ReqCompTimeYes: 18565 var_class_requires_const = true; 18566 if (!var->gen_is_const && !is_comptime_var) { 18567 ir_add_error_node(ira, source_node, 18568 buf_sprintf("variable of type '%s' must be const or comptime", 18569 buf_ptr(&result_type->name))); 18570 result_type = ira->codegen->builtin_types.entry_invalid; 18571 } 18572 break; 18573 case ReqCompTimeNo: 18574 if (init_val != nullptr && value_is_comptime(init_val)) { 18575 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 18576 decl_var_instruction->base.base.source_node, init_val, UndefOk))) 18577 { 18578 result_type = ira->codegen->builtin_types.entry_invalid; 18579 } else if (init_val->type->id == ZigTypeIdFn && 18580 init_val->special != ConstValSpecialUndef && 18581 init_val->data.x_ptr.special == ConstPtrSpecialFunction && 18582 init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) 18583 { 18584 var_class_requires_const = true; 18585 if (!var->src_is_const && !is_comptime_var) { 18586 ErrorMsg *msg = ir_add_error_node(ira, source_node, 18587 buf_sprintf("functions marked inline must be stored in const or comptime var")); 18588 AstNode *proto_node = init_val->data.x_ptr.data.fn.fn_entry->proto_node; 18589 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); 18590 result_type = ira->codegen->builtin_types.entry_invalid; 18591 } 18592 } 18593 } 18594 break; 18595 } 18596 18597 while (var->next_var != nullptr) { 18598 var = var->next_var; 18599 } 18600 18601 // This must be done after possibly creating a new variable above 18602 var->ref_count = 0; 18603 18604 var->ptr_instruction = var_ptr; 18605 var->var_type = result_type; 18606 assert(var->var_type); 18607 18608 if (type_is_invalid(result_type)) { 18609 return ir_const_void(ira, &decl_var_instruction->base.base); 18610 } 18611 18612 if (decl_var_instruction->align_value == nullptr) { 18613 if ((err = type_resolve(ira->codegen, result_type, ResolveStatusAlignmentKnown))) { 18614 var->var_type = ira->codegen->builtin_types.entry_invalid; 18615 return ir_const_void(ira, &decl_var_instruction->base.base); 18616 } 18617 var->align_bytes = get_ptr_align(ira->codegen, var_ptr->value->type); 18618 } else { 18619 if (!ir_resolve_align(ira, decl_var_instruction->align_value->child, nullptr, &var->align_bytes)) { 18620 var->var_type = ira->codegen->builtin_types.entry_invalid; 18621 } 18622 } 18623 18624 if (init_val != nullptr && value_is_comptime(init_val)) { 18625 // Resolve ConstPtrMutInfer 18626 if (var->gen_is_const) { 18627 var_ptr->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 18628 } else if (is_comptime_var) { 18629 var_ptr->value->data.x_ptr.mut = ConstPtrMutComptimeVar; 18630 } else { 18631 // we need a runtime ptr but we have a comptime val. 18632 // since it's a comptime val there are no instructions for it. 18633 // we memcpy the init value here 18634 IrInstGen *deref = ir_get_deref(ira, &var_ptr->base, var_ptr, nullptr); 18635 if (type_is_invalid(deref->value->type)) { 18636 var->var_type = ira->codegen->builtin_types.entry_invalid; 18637 return ira->codegen->invalid_inst_gen; 18638 } 18639 // If this assertion trips, something is wrong with the IR instructions, because 18640 // we expected the above deref to return a constant value, but it created a runtime 18641 // instruction. 18642 assert(deref->value->special != ConstValSpecialRuntime); 18643 var_ptr->value->special = ConstValSpecialRuntime; 18644 ir_analyze_store_ptr(ira, &var_ptr->base, var_ptr, deref, false); 18645 } 18646 if (instr_is_comptime(var_ptr) && (is_comptime_var || (var_class_requires_const && var->gen_is_const))) { 18647 return ir_const_void(ira, &decl_var_instruction->base.base); 18648 } 18649 } else if (is_comptime_var) { 18650 ir_add_error(ira, &decl_var_instruction->base.base, 18651 buf_sprintf("cannot store runtime value in compile time variable")); 18652 var->var_type = ira->codegen->builtin_types.entry_invalid; 18653 return ira->codegen->invalid_inst_gen; 18654 } 18655 18656 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 18657 if (fn_entry) 18658 fn_entry->variable_list.append(var); 18659 18660 return ir_build_var_decl_gen(ira, &decl_var_instruction->base.base, var, var_ptr); 18661 } 18662 18663 static IrInstGen *ir_analyze_instruction_export(IrAnalyze *ira, IrInstSrcExport *instruction) { 18664 IrInstGen *target = instruction->target->child; 18665 if (type_is_invalid(target->value->type)) 18666 return ira->codegen->invalid_inst_gen; 18667 18668 IrInstGen *options = instruction->options->child; 18669 if (type_is_invalid(options->value->type)) 18670 return ira->codegen->invalid_inst_gen; 18671 18672 ZigType *options_type = options->value->type; 18673 assert(options_type->id == ZigTypeIdStruct); 18674 18675 TypeStructField *name_field = find_struct_type_field(options_type, buf_create_from_str("name")); 18676 ir_assert(name_field != nullptr, &instruction->base.base); 18677 IrInstGen *name_inst = ir_analyze_struct_value_field_value(ira, &instruction->base.base, options, name_field); 18678 if (type_is_invalid(name_inst->value->type)) 18679 return ira->codegen->invalid_inst_gen; 18680 18681 TypeStructField *linkage_field = find_struct_type_field(options_type, buf_create_from_str("linkage")); 18682 ir_assert(linkage_field != nullptr, &instruction->base.base); 18683 IrInstGen *linkage_inst = ir_analyze_struct_value_field_value(ira, &instruction->base.base, options, linkage_field); 18684 if (type_is_invalid(linkage_inst->value->type)) 18685 return ira->codegen->invalid_inst_gen; 18686 18687 TypeStructField *section_field = find_struct_type_field(options_type, buf_create_from_str("section")); 18688 ir_assert(section_field != nullptr, &instruction->base.base); 18689 IrInstGen *section_inst = ir_analyze_struct_value_field_value(ira, &instruction->base.base, options, section_field); 18690 if (type_is_invalid(section_inst->value->type)) 18691 return ira->codegen->invalid_inst_gen; 18692 18693 // The `section` field is optional, we have to unwrap it first 18694 IrInstGen *non_null_check = ir_analyze_test_non_null(ira, &instruction->base.base, section_inst); 18695 bool is_non_null; 18696 if (!ir_resolve_bool(ira, non_null_check, &is_non_null)) 18697 return ira->codegen->invalid_inst_gen; 18698 18699 IrInstGen *section_str_inst = nullptr; 18700 if (is_non_null) { 18701 section_str_inst = ir_analyze_optional_value_payload_value(ira, &instruction->base.base, section_inst, false); 18702 if (type_is_invalid(section_str_inst->value->type)) 18703 return ira->codegen->invalid_inst_gen; 18704 } 18705 18706 // Resolve all the comptime values 18707 Buf *symbol_name = ir_resolve_str(ira, name_inst); 18708 if (!symbol_name) 18709 return ira->codegen->invalid_inst_gen; 18710 18711 if (buf_len(symbol_name) < 1) { 18712 ir_add_error(ira, &name_inst->base, 18713 buf_sprintf("exported symbol name cannot be empty")); 18714 return ira->codegen->invalid_inst_gen; 18715 } 18716 18717 GlobalLinkageId global_linkage_id; 18718 if (!ir_resolve_global_linkage(ira, linkage_inst, &global_linkage_id)) 18719 return ira->codegen->invalid_inst_gen; 18720 18721 Buf *section_name = nullptr; 18722 if (section_str_inst != nullptr && !(section_name = ir_resolve_str(ira, section_str_inst))) 18723 return ira->codegen->invalid_inst_gen; 18724 18725 // TODO: This function needs to be audited. 18726 // It's not clear how all the different types are supposed to be handled. 18727 // Need comprehensive tests for exporting one thing in one file and declaring an extern var 18728 // in another file. 18729 TldFn *tld_fn = heap::c_allocator.create<TldFn>(); 18730 tld_fn->base.id = TldIdFn; 18731 tld_fn->base.source_node = instruction->base.base.source_node; 18732 18733 auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, &tld_fn->base); 18734 if (entry) { 18735 AstNode *other_export_node = entry->value->source_node; 18736 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 18737 buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name))); 18738 add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here")); 18739 return ira->codegen->invalid_inst_gen; 18740 } 18741 18742 Error err; 18743 bool want_var_export = false; 18744 switch (target->value->type->id) { 18745 case ZigTypeIdInvalid: 18746 case ZigTypeIdUnreachable: 18747 zig_unreachable(); 18748 case ZigTypeIdFn: { 18749 assert(target->value->data.x_ptr.special == ConstPtrSpecialFunction); 18750 ZigFn *fn_entry = target->value->data.x_ptr.data.fn.fn_entry; 18751 tld_fn->fn_entry = fn_entry; 18752 CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc; 18753 switch (cc) { 18754 case CallingConventionUnspecified: { 18755 ErrorMsg *msg = ir_add_error(ira, &target->base, 18756 buf_sprintf("exported function must specify calling convention")); 18757 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 18758 } break; 18759 case CallingConventionAsync: { 18760 ErrorMsg *msg = ir_add_error(ira, &target->base, 18761 buf_sprintf("exported function cannot be async")); 18762 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 18763 } break; 18764 case CallingConventionC: 18765 case CallingConventionCold: 18766 case CallingConventionNaked: 18767 case CallingConventionInterrupt: 18768 case CallingConventionSignal: 18769 case CallingConventionStdcall: 18770 case CallingConventionFastcall: 18771 case CallingConventionVectorcall: 18772 case CallingConventionThiscall: 18773 case CallingConventionAPCS: 18774 case CallingConventionAAPCS: 18775 case CallingConventionAAPCSVFP: 18776 add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc); 18777 fn_entry->section_name = section_name; 18778 break; 18779 } 18780 } break; 18781 case ZigTypeIdStruct: 18782 if (is_slice(target->value->type)) { 18783 ir_add_error(ira, &target->base, 18784 buf_sprintf("unable to export value of type '%s'", buf_ptr(&target->value->type->name))); 18785 } else if (target->value->type->data.structure.layout != ContainerLayoutExtern) { 18786 ErrorMsg *msg = ir_add_error(ira, &target->base, 18787 buf_sprintf("exported struct value must be declared extern")); 18788 add_error_note(ira->codegen, msg, target->value->type->data.structure.decl_node, buf_sprintf("declared here")); 18789 } else { 18790 want_var_export = true; 18791 } 18792 break; 18793 case ZigTypeIdUnion: 18794 if (target->value->type->data.unionation.layout != ContainerLayoutExtern) { 18795 ErrorMsg *msg = ir_add_error(ira, &target->base, 18796 buf_sprintf("exported union value must be declared extern")); 18797 add_error_note(ira->codegen, msg, target->value->type->data.unionation.decl_node, buf_sprintf("declared here")); 18798 } else { 18799 want_var_export = true; 18800 } 18801 break; 18802 case ZigTypeIdEnum: 18803 if (target->value->type->data.enumeration.layout != ContainerLayoutExtern) { 18804 ErrorMsg *msg = ir_add_error(ira, &target->base, 18805 buf_sprintf("exported enum value must be declared extern")); 18806 add_error_note(ira->codegen, msg, target->value->type->data.enumeration.decl_node, buf_sprintf("declared here")); 18807 } else { 18808 want_var_export = true; 18809 } 18810 break; 18811 case ZigTypeIdArray: { 18812 bool ok_type; 18813 if ((err = type_allowed_in_extern(ira->codegen, target->value->type->data.array.child_type, &ok_type))) 18814 return ira->codegen->invalid_inst_gen; 18815 18816 if (!ok_type) { 18817 ir_add_error(ira, &target->base, 18818 buf_sprintf("array element type '%s' not extern-compatible", 18819 buf_ptr(&target->value->type->data.array.child_type->name))); 18820 } else { 18821 want_var_export = true; 18822 } 18823 break; 18824 } 18825 case ZigTypeIdMetaType: { 18826 ZigType *type_value = target->value->data.x_type; 18827 switch (type_value->id) { 18828 case ZigTypeIdInvalid: 18829 zig_unreachable(); 18830 case ZigTypeIdStruct: 18831 if (is_slice(type_value)) { 18832 ir_add_error(ira, &target->base, 18833 buf_sprintf("unable to export type '%s'", buf_ptr(&type_value->name))); 18834 } else if (type_value->data.structure.layout != ContainerLayoutExtern) { 18835 ErrorMsg *msg = ir_add_error(ira, &target->base, 18836 buf_sprintf("exported struct must be declared extern")); 18837 add_error_note(ira->codegen, msg, type_value->data.structure.decl_node, buf_sprintf("declared here")); 18838 } 18839 break; 18840 case ZigTypeIdUnion: 18841 if (type_value->data.unionation.layout != ContainerLayoutExtern) { 18842 ErrorMsg *msg = ir_add_error(ira, &target->base, 18843 buf_sprintf("exported union must be declared extern")); 18844 add_error_note(ira->codegen, msg, type_value->data.unionation.decl_node, buf_sprintf("declared here")); 18845 } 18846 break; 18847 case ZigTypeIdEnum: 18848 if (type_value->data.enumeration.layout != ContainerLayoutExtern) { 18849 ErrorMsg *msg = ir_add_error(ira, &target->base, 18850 buf_sprintf("exported enum must be declared extern")); 18851 add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here")); 18852 } 18853 break; 18854 case ZigTypeIdFn: { 18855 if (type_value->data.fn.fn_type_id.cc == CallingConventionUnspecified) { 18856 ir_add_error(ira, &target->base, 18857 buf_sprintf("exported function type must specify calling convention")); 18858 } 18859 } break; 18860 case ZigTypeIdInt: 18861 case ZigTypeIdFloat: 18862 case ZigTypeIdPointer: 18863 case ZigTypeIdArray: 18864 case ZigTypeIdBool: 18865 case ZigTypeIdVector: 18866 break; 18867 case ZigTypeIdMetaType: 18868 case ZigTypeIdVoid: 18869 case ZigTypeIdUnreachable: 18870 case ZigTypeIdComptimeFloat: 18871 case ZigTypeIdComptimeInt: 18872 case ZigTypeIdEnumLiteral: 18873 case ZigTypeIdUndefined: 18874 case ZigTypeIdNull: 18875 case ZigTypeIdOptional: 18876 case ZigTypeIdErrorUnion: 18877 case ZigTypeIdErrorSet: 18878 case ZigTypeIdBoundFn: 18879 case ZigTypeIdOpaque: 18880 case ZigTypeIdFnFrame: 18881 case ZigTypeIdAnyFrame: 18882 ir_add_error(ira, &target->base, 18883 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name))); 18884 break; 18885 } 18886 } break; 18887 case ZigTypeIdInt: 18888 want_var_export = true; 18889 break; 18890 case ZigTypeIdVoid: 18891 case ZigTypeIdBool: 18892 case ZigTypeIdFloat: 18893 case ZigTypeIdPointer: 18894 case ZigTypeIdComptimeFloat: 18895 case ZigTypeIdComptimeInt: 18896 case ZigTypeIdUndefined: 18897 case ZigTypeIdNull: 18898 case ZigTypeIdOptional: 18899 case ZigTypeIdErrorUnion: 18900 case ZigTypeIdErrorSet: 18901 case ZigTypeIdVector: 18902 zig_panic("TODO export const value of type %s", buf_ptr(&target->value->type->name)); 18903 case ZigTypeIdBoundFn: 18904 case ZigTypeIdOpaque: 18905 case ZigTypeIdEnumLiteral: 18906 case ZigTypeIdFnFrame: 18907 case ZigTypeIdAnyFrame: 18908 ir_add_error(ira, &target->base, 18909 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value->type->name))); 18910 break; 18911 } 18912 18913 // TODO audit the various ways to use @export 18914 if (want_var_export && target->id == IrInstGenIdLoadPtr) { 18915 IrInstGenLoadPtr *load_ptr = reinterpret_cast<IrInstGenLoadPtr *>(target); 18916 if (load_ptr->ptr->id == IrInstGenIdVarPtr) { 18917 IrInstGenVarPtr *var_ptr = reinterpret_cast<IrInstGenVarPtr *>(load_ptr->ptr); 18918 ZigVar *var = var_ptr->var; 18919 add_var_export(ira->codegen, var, buf_ptr(symbol_name), global_linkage_id); 18920 var->section_name = section_name; 18921 } 18922 } 18923 18924 return ir_const_void(ira, &instruction->base.base); 18925 } 18926 18927 static bool exec_has_err_ret_trace(CodeGen *g, IrExecutableSrc *exec) { 18928 ZigFn *fn_entry = exec_fn_entry(exec); 18929 return fn_entry != nullptr && fn_entry->calls_or_awaits_errorable_fn && g->have_err_ret_tracing; 18930 } 18931 18932 static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira, 18933 IrInstSrcErrorReturnTrace *instruction) 18934 { 18935 ZigType *ptr_to_stack_trace_type = get_pointer_to_type(ira->codegen, get_stack_trace_type(ira->codegen), false); 18936 if (instruction->optional == IrInstErrorReturnTraceNull) { 18937 ZigType *optional_type = get_optional_type(ira->codegen, ptr_to_stack_trace_type); 18938 if (!exec_has_err_ret_trace(ira->codegen, ira->old_irb.exec)) { 18939 IrInstGen *result = ir_const(ira, &instruction->base.base, optional_type); 18940 ZigValue *out_val = result->value; 18941 assert(get_src_ptr_type(optional_type) != nullptr); 18942 out_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 18943 out_val->data.x_ptr.data.hard_coded_addr.addr = 0; 18944 return result; 18945 } 18946 return ir_build_error_return_trace_gen(ira, instruction->base.base.scope, 18947 instruction->base.base.source_node, instruction->optional, optional_type); 18948 } else { 18949 assert(ira->codegen->have_err_ret_tracing); 18950 return ir_build_error_return_trace_gen(ira, instruction->base.base.scope, 18951 instruction->base.base.source_node, instruction->optional, ptr_to_stack_trace_type); 18952 } 18953 } 18954 18955 static IrInstGen *ir_analyze_instruction_error_union(IrAnalyze *ira, IrInstSrcErrorUnion *instruction) { 18956 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); 18957 result->value->special = ConstValSpecialLazy; 18958 18959 LazyValueErrUnionType *lazy_err_union_type = heap::c_allocator.create<LazyValueErrUnionType>(); 18960 lazy_err_union_type->ira = ira; ira_ref(ira); 18961 result->value->data.x_lazy = &lazy_err_union_type->base; 18962 lazy_err_union_type->base.id = LazyValueIdErrUnionType; 18963 18964 lazy_err_union_type->err_set_type = instruction->err_set->child; 18965 if (ir_resolve_type_lazy(ira, lazy_err_union_type->err_set_type) == nullptr) 18966 return ira->codegen->invalid_inst_gen; 18967 18968 lazy_err_union_type->payload_type = instruction->payload->child; 18969 if (ir_resolve_type_lazy(ira, lazy_err_union_type->payload_type) == nullptr) 18970 return ira->codegen->invalid_inst_gen; 18971 18972 return result; 18973 } 18974 18975 static IrInstGen *ir_analyze_alloca(IrAnalyze *ira, IrInst *source_inst, ZigType *var_type, 18976 uint32_t align, const char *name_hint, bool force_comptime) 18977 { 18978 Error err; 18979 18980 ZigValue *pointee = ira->codegen->pass1_arena->create<ZigValue>(); 18981 pointee->special = ConstValSpecialUndef; 18982 pointee->llvm_align = align; 18983 18984 IrInstGenAlloca *result = ir_build_alloca_gen(ira, source_inst, align, name_hint); 18985 result->base.value->special = ConstValSpecialStatic; 18986 result->base.value->data.x_ptr.special = ConstPtrSpecialRef; 18987 result->base.value->data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer; 18988 result->base.value->data.x_ptr.data.ref.pointee = pointee; 18989 18990 bool var_type_has_bits; 18991 if ((err = type_has_bits2(ira->codegen, var_type, &var_type_has_bits))) 18992 return ira->codegen->invalid_inst_gen; 18993 if (align != 0) { 18994 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown))) 18995 return ira->codegen->invalid_inst_gen; 18996 if (!var_type_has_bits) { 18997 ir_add_error(ira, source_inst, 18998 buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned", 18999 name_hint, buf_ptr(&var_type->name))); 19000 return ira->codegen->invalid_inst_gen; 19001 } 19002 } 19003 assert(result->base.value->data.x_ptr.special != ConstPtrSpecialInvalid); 19004 19005 pointee->type = var_type; 19006 result->base.value->type = get_pointer_to_type_extra(ira->codegen, var_type, false, false, 19007 PtrLenSingle, align, 0, 0, false); 19008 19009 if (!force_comptime) { 19010 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 19011 if (fn_entry != nullptr) { 19012 fn_entry->alloca_gen_list.append(result); 19013 } 19014 } 19015 return &result->base; 19016 } 19017 19018 static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInst *suspend_source_instr, 19019 ResultLoc *result_loc) 19020 { 19021 switch (result_loc->id) { 19022 case ResultLocIdInvalid: 19023 case ResultLocIdPeerParent: 19024 zig_unreachable(); 19025 case ResultLocIdNone: 19026 case ResultLocIdVar: 19027 case ResultLocIdBitCast: 19028 case ResultLocIdCast: 19029 return nullptr; 19030 case ResultLocIdInstruction: 19031 return result_loc->source_instruction->child->value->type; 19032 case ResultLocIdReturn: 19033 return ira->explicit_return_type; 19034 case ResultLocIdPeer: 19035 return reinterpret_cast<ResultLocPeer*>(result_loc)->parent->resolved_type; 19036 } 19037 zig_unreachable(); 19038 } 19039 19040 static bool type_can_bit_cast(ZigType *t) { 19041 switch (t->id) { 19042 case ZigTypeIdInvalid: 19043 zig_unreachable(); 19044 case ZigTypeIdMetaType: 19045 case ZigTypeIdOpaque: 19046 case ZigTypeIdBoundFn: 19047 case ZigTypeIdUnreachable: 19048 case ZigTypeIdComptimeFloat: 19049 case ZigTypeIdComptimeInt: 19050 case ZigTypeIdEnumLiteral: 19051 case ZigTypeIdUndefined: 19052 case ZigTypeIdNull: 19053 case ZigTypeIdPointer: 19054 return false; 19055 default: 19056 // TODO list these types out explicitly, there are probably some other invalid ones here 19057 return true; 19058 } 19059 } 19060 19061 static void set_up_result_loc_for_inferred_comptime(IrAnalyze *ira, IrInstGen *ptr) { 19062 ZigValue *undef_child = ira->codegen->pass1_arena->create<ZigValue>(); 19063 undef_child->type = ptr->value->type->data.pointer.child_type; 19064 undef_child->special = ConstValSpecialUndef; 19065 ptr->value->special = ConstValSpecialStatic; 19066 ptr->value->data.x_ptr.mut = ConstPtrMutInfer; 19067 ptr->value->data.x_ptr.special = ConstPtrSpecialRef; 19068 ptr->value->data.x_ptr.data.ref.pointee = undef_child; 19069 } 19070 19071 static Error ir_result_has_type(IrAnalyze *ira, ResultLoc *result_loc, bool *out) { 19072 switch (result_loc->id) { 19073 case ResultLocIdInvalid: 19074 case ResultLocIdPeerParent: 19075 zig_unreachable(); 19076 case ResultLocIdNone: 19077 case ResultLocIdPeer: 19078 *out = false; 19079 return ErrorNone; 19080 case ResultLocIdReturn: 19081 case ResultLocIdInstruction: 19082 case ResultLocIdBitCast: 19083 *out = true; 19084 return ErrorNone; 19085 case ResultLocIdCast: { 19086 ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); 19087 ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); 19088 if (type_is_invalid(dest_type)) 19089 return ErrorSemanticAnalyzeFail; 19090 *out = (dest_type != ira->codegen->builtin_types.entry_anytype); 19091 return ErrorNone; 19092 } 19093 case ResultLocIdVar: 19094 *out = reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; 19095 return ErrorNone; 19096 } 19097 zig_unreachable(); 19098 } 19099 19100 static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_source_instr, 19101 ResultLoc *result_loc, ZigType *value_type) 19102 { 19103 if (type_is_invalid(value_type)) 19104 return ira->codegen->invalid_inst_gen; 19105 IrInstGenAlloca *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, ""); 19106 alloca_gen->base.value->type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, 19107 PtrLenSingle, 0, 0, 0, false); 19108 set_up_result_loc_for_inferred_comptime(ira, &alloca_gen->base); 19109 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 19110 if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) { 19111 fn_entry->alloca_gen_list.append(alloca_gen); 19112 } 19113 result_loc->written = true; 19114 result_loc->resolved_loc = &alloca_gen->base; 19115 return result_loc->resolved_loc; 19116 } 19117 19118 static bool result_loc_is_discard(ResultLoc *result_loc_pass1) { 19119 if (result_loc_pass1->id == ResultLocIdInstruction && 19120 result_loc_pass1->source_instruction->id == IrInstSrcIdConst) 19121 { 19122 IrInstSrcConst *const_inst = reinterpret_cast<IrInstSrcConst *>(result_loc_pass1->source_instruction); 19123 if (value_is_comptime(const_inst->value) && 19124 const_inst->value->type->id == ZigTypeIdPointer && 19125 const_inst->value->data.x_ptr.special == ConstPtrSpecialDiscard) 19126 { 19127 return true; 19128 } 19129 } 19130 return false; 19131 } 19132 19133 // when calling this function, at the callsite must check for result type noreturn and propagate it up 19134 static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_instr, 19135 ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime, 19136 bool allow_discard) 19137 { 19138 Error err; 19139 if (result_loc->resolved_loc != nullptr) { 19140 // allow to redo the result location if the value is known and comptime and the previous one isn't 19141 if (value == nullptr || !instr_is_comptime(value) || instr_is_comptime(result_loc->resolved_loc)) { 19142 return result_loc->resolved_loc; 19143 } 19144 } 19145 result_loc->gen_instruction = value; 19146 result_loc->implicit_elem_type = value_type; 19147 switch (result_loc->id) { 19148 case ResultLocIdInvalid: 19149 case ResultLocIdPeerParent: 19150 zig_unreachable(); 19151 case ResultLocIdNone: { 19152 if (value != nullptr) { 19153 return nullptr; 19154 } 19155 // need to return a result location and don't have one. use a stack allocation 19156 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type); 19157 } 19158 case ResultLocIdVar: { 19159 ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc); 19160 assert(result_loc->source_instruction->id == IrInstSrcIdAlloca); 19161 IrInstSrcAlloca *alloca_src = reinterpret_cast<IrInstSrcAlloca *>(result_loc->source_instruction); 19162 19163 ZigVar *var = result_loc_var->var; 19164 if (var->var_type != nullptr && !ir_get_var_is_comptime(var)) { 19165 // This is at least the second time we've seen this variable declaration during analysis. 19166 // This means that this is actually a different variable due to, e.g. an inline while loop. 19167 // We make a new variable so that it can hold a different type, and so the debug info can 19168 // be distinct. 19169 ZigVar *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope, 19170 buf_create_from_str(var->name), var->src_is_const, var->gen_is_const, 19171 var->shadowable, var->is_comptime, true); 19172 new_var->align_bytes = var->align_bytes; 19173 19174 var->next_var = new_var; 19175 var = new_var; 19176 } 19177 if (value_type->id == ZigTypeIdUnreachable || value_type->id == ZigTypeIdOpaque) { 19178 ir_add_error(ira, &result_loc->source_instruction->base, 19179 buf_sprintf("variable of type '%s' not allowed", buf_ptr(&value_type->name))); 19180 return ira->codegen->invalid_inst_gen; 19181 } 19182 if (alloca_src->base.child == nullptr || var->ptr_instruction == nullptr) { 19183 bool force_comptime; 19184 if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) 19185 return ira->codegen->invalid_inst_gen; 19186 uint32_t align = 0; 19187 if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, nullptr, &align)) { 19188 return ira->codegen->invalid_inst_gen; 19189 } 19190 IrInstGen *alloca_gen = ir_analyze_alloca(ira, &result_loc->source_instruction->base, value_type, 19191 align, alloca_src->name_hint, force_comptime); 19192 if (force_runtime) { 19193 alloca_gen->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; 19194 alloca_gen->value->special = ConstValSpecialRuntime; 19195 } 19196 if (alloca_src->base.child != nullptr && !result_loc->written) { 19197 alloca_src->base.child->base.ref_count = 0; 19198 } 19199 alloca_src->base.child = alloca_gen; 19200 var->ptr_instruction = alloca_gen; 19201 } 19202 result_loc->written = true; 19203 result_loc->resolved_loc = alloca_src->base.child; 19204 return alloca_src->base.child; 19205 } 19206 case ResultLocIdInstruction: { 19207 result_loc->written = true; 19208 result_loc->resolved_loc = result_loc->source_instruction->child; 19209 return result_loc->resolved_loc; 19210 } 19211 case ResultLocIdReturn: { 19212 if (value != nullptr) { 19213 reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = true; 19214 ira->src_implicit_return_type_list.append(value); 19215 } 19216 result_loc->written = true; 19217 result_loc->resolved_loc = ira->return_ptr; 19218 return result_loc->resolved_loc; 19219 } 19220 case ResultLocIdPeer: { 19221 ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(result_loc); 19222 ResultLocPeerParent *peer_parent = result_peer->parent; 19223 19224 if (peer_parent->peers.length == 1) { 19225 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 19226 value_type, value, force_runtime, true); 19227 result_peer->suspend_pos.basic_block_index = SIZE_MAX; 19228 result_peer->suspend_pos.instruction_index = SIZE_MAX; 19229 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 19230 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 19231 { 19232 return parent_result_loc; 19233 } 19234 result_loc->written = true; 19235 result_loc->resolved_loc = parent_result_loc; 19236 return result_loc->resolved_loc; 19237 } 19238 19239 bool is_condition_comptime; 19240 if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_condition_comptime)) 19241 return ira->codegen->invalid_inst_gen; 19242 if (is_condition_comptime) { 19243 peer_parent->skipped = true; 19244 return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 19245 value_type, value, force_runtime, true); 19246 } 19247 bool peer_parent_has_type; 19248 if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) 19249 return ira->codegen->invalid_inst_gen; 19250 if (peer_parent_has_type) { 19251 peer_parent->skipped = true; 19252 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 19253 value_type, value, force_runtime || !is_condition_comptime, true); 19254 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 19255 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 19256 { 19257 return parent_result_loc; 19258 } 19259 peer_parent->parent->written = true; 19260 result_loc->written = true; 19261 result_loc->resolved_loc = parent_result_loc; 19262 return result_loc->resolved_loc; 19263 } 19264 19265 if (peer_parent->resolved_type == nullptr) { 19266 if (peer_parent->end_bb->suspend_instruction_ref == nullptr) { 19267 peer_parent->end_bb->suspend_instruction_ref = suspend_source_instr; 19268 } 19269 IrInstGen *unreach_inst = ira_suspend(ira, suspend_source_instr, result_peer->next_bb, 19270 &result_peer->suspend_pos); 19271 if (result_peer->next_bb == nullptr) { 19272 ir_start_next_bb(ira); 19273 } 19274 return unreach_inst; 19275 } 19276 19277 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 19278 peer_parent->resolved_type, nullptr, force_runtime, true); 19279 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 19280 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 19281 { 19282 return parent_result_loc; 19283 } 19284 // because is_condition_comptime is false, we mark this a runtime pointer 19285 parent_result_loc->value->special = ConstValSpecialRuntime; 19286 result_loc->written = true; 19287 result_loc->resolved_loc = parent_result_loc; 19288 return result_loc->resolved_loc; 19289 } 19290 case ResultLocIdCast: { 19291 ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); 19292 ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); 19293 if (type_is_invalid(dest_type)) 19294 return ira->codegen->invalid_inst_gen; 19295 19296 if (dest_type == ira->codegen->builtin_types.entry_anytype) { 19297 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type); 19298 } 19299 19300 IrInstGen *casted_value; 19301 if (value != nullptr) { 19302 casted_value = ir_implicit_cast2(ira, suspend_source_instr, value, dest_type); 19303 if (type_is_invalid(casted_value->value->type)) 19304 return ira->codegen->invalid_inst_gen; 19305 dest_type = casted_value->value->type; 19306 } else { 19307 casted_value = nullptr; 19308 } 19309 19310 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent, 19311 dest_type, casted_value, force_runtime, true); 19312 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 19313 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 19314 { 19315 return parent_result_loc; 19316 } 19317 19318 ZigType *parent_ptr_type = parent_result_loc->value->type; 19319 assert(parent_ptr_type->id == ZigTypeIdPointer); 19320 19321 if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, 19322 ResolveStatusAlignmentKnown))) 19323 { 19324 return ira->codegen->invalid_inst_gen; 19325 } 19326 uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); 19327 if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { 19328 return ira->codegen->invalid_inst_gen; 19329 } 19330 if (!type_has_bits(ira->codegen, value_type)) { 19331 parent_ptr_align = 0; 19332 } 19333 // If we're casting from a sentinel-terminated array to a non-sentinel-terminated array, 19334 // we actually need the result location pointer to *not* have a sentinel. Otherwise the generated 19335 // memcpy will write an extra byte to the destination, and THAT'S NO GOOD. 19336 ZigType *ptr_elem_type; 19337 if (value_type->id == ZigTypeIdArray && value_type->data.array.sentinel != nullptr && 19338 dest_type->id == ZigTypeIdArray && dest_type->data.array.sentinel == nullptr) 19339 { 19340 ptr_elem_type = get_array_type(ira->codegen, value_type->data.array.child_type, 19341 value_type->data.array.len, nullptr); 19342 } else { 19343 ptr_elem_type = value_type; 19344 } 19345 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ptr_elem_type, 19346 parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, 19347 parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); 19348 19349 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, 19350 parent_result_loc->value->type, ptr_type, 19351 result_cast->base.source_instruction->base.source_node, false); 19352 if (const_cast_result.id == ConstCastResultIdInvalid) 19353 return ira->codegen->invalid_inst_gen; 19354 if (const_cast_result.id != ConstCastResultIdOk) { 19355 if (allow_discard) { 19356 return parent_result_loc; 19357 } 19358 // We will not be able to provide a result location for this value. Create 19359 // a new result location. 19360 result_cast->parent->written = false; 19361 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type); 19362 } 19363 19364 result_loc->written = true; 19365 result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, 19366 &parent_result_loc->base, ptr_type, &result_cast->base.source_instruction->base, false, false); 19367 return result_loc->resolved_loc; 19368 } 19369 case ResultLocIdBitCast: { 19370 ResultLocBitCast *result_bit_cast = reinterpret_cast<ResultLocBitCast *>(result_loc); 19371 ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child); 19372 if (type_is_invalid(dest_type)) 19373 return ira->codegen->invalid_inst_gen; 19374 19375 ZigType *dest_cg_ptr_type; 19376 if ((err = get_codegen_ptr_type(ira->codegen, dest_type, &dest_cg_ptr_type))) 19377 return ira->codegen->invalid_inst_gen; 19378 if (dest_cg_ptr_type != nullptr) { 19379 ir_add_error(ira, &result_loc->source_instruction->base, 19380 buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); 19381 return ira->codegen->invalid_inst_gen; 19382 } 19383 19384 if (!type_can_bit_cast(dest_type)) { 19385 ir_add_error(ira, &result_loc->source_instruction->base, 19386 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); 19387 return ira->codegen->invalid_inst_gen; 19388 } 19389 19390 ZigType *value_cg_ptr_type; 19391 if ((err = get_codegen_ptr_type(ira->codegen, value_type, &value_cg_ptr_type))) 19392 return ira->codegen->invalid_inst_gen; 19393 if (value_cg_ptr_type != nullptr) { 19394 ir_add_error(ira, suspend_source_instr, 19395 buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&value_type->name))); 19396 return ira->codegen->invalid_inst_gen; 19397 } 19398 19399 if (!type_can_bit_cast(value_type)) { 19400 ir_add_error(ira, suspend_source_instr, 19401 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&value_type->name))); 19402 return ira->codegen->invalid_inst_gen; 19403 } 19404 19405 IrInstGen *bitcasted_value; 19406 if (value != nullptr) { 19407 bitcasted_value = ir_analyze_bit_cast(ira, &result_loc->source_instruction->base, value, dest_type); 19408 dest_type = bitcasted_value->value->type; 19409 } else { 19410 bitcasted_value = nullptr; 19411 } 19412 19413 if (bitcasted_value != nullptr && type_is_invalid(bitcasted_value->value->type)) { 19414 return bitcasted_value; 19415 } 19416 19417 bool parent_was_written = result_bit_cast->parent->written; 19418 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent, 19419 dest_type, bitcasted_value, force_runtime, true); 19420 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 19421 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 19422 { 19423 return parent_result_loc; 19424 } 19425 ZigType *parent_ptr_type = parent_result_loc->value->type; 19426 assert(parent_ptr_type->id == ZigTypeIdPointer); 19427 ZigType *child_type = parent_ptr_type->data.pointer.child_type; 19428 19429 if (result_loc_is_discard(result_bit_cast->parent)) { 19430 assert(allow_discard); 19431 return parent_result_loc; 19432 } 19433 19434 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) { 19435 return ira->codegen->invalid_inst_gen; 19436 } 19437 19438 if ((err = type_resolve(ira->codegen, value_type, ResolveStatusSizeKnown))) { 19439 return ira->codegen->invalid_inst_gen; 19440 } 19441 19442 if (child_type != ira->codegen->builtin_types.entry_anytype) { 19443 if (type_size(ira->codegen, child_type) != type_size(ira->codegen, value_type)) { 19444 // pointer cast won't work; we need a temporary location. 19445 result_bit_cast->parent->written = parent_was_written; 19446 result_loc->written = true; 19447 result_loc->resolved_loc = ir_resolve_result(ira, suspend_source_instr, no_result_loc(), 19448 value_type, bitcasted_value, force_runtime, true); 19449 return result_loc->resolved_loc; 19450 } 19451 } 19452 uint64_t parent_ptr_align = 0; 19453 if (type_has_bits(ira->codegen, value_type)) parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); 19454 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, 19455 parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, 19456 parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); 19457 19458 result_loc->written = true; 19459 result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, 19460 &parent_result_loc->base, ptr_type, &result_bit_cast->base.source_instruction->base, false, false); 19461 return result_loc->resolved_loc; 19462 } 19463 } 19464 zig_unreachable(); 19465 } 19466 19467 static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr, 19468 ResultLoc *result_loc_pass1, ZigType *value_type, IrInstGen *value, bool force_runtime, 19469 bool allow_discard) 19470 { 19471 if (!allow_discard && result_loc_is_discard(result_loc_pass1)) { 19472 result_loc_pass1 = no_result_loc(); 19473 } 19474 bool was_written = result_loc_pass1->written; 19475 IrInstGen *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, 19476 value, force_runtime, allow_discard); 19477 if (result_loc == nullptr || result_loc->value->type->id == ZigTypeIdUnreachable || 19478 type_is_invalid(result_loc->value->type)) 19479 { 19480 return result_loc; 19481 } 19482 19483 if ((force_runtime || (value != nullptr && !instr_is_comptime(value))) && 19484 result_loc_pass1->written && result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) 19485 { 19486 result_loc->value->special = ConstValSpecialRuntime; 19487 } 19488 19489 InferredStructField *isf = result_loc->value->type->data.pointer.inferred_struct_field; 19490 if (isf != nullptr) { 19491 TypeStructField *field; 19492 IrInstGen *casted_ptr; 19493 if (isf->already_resolved) { 19494 field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); 19495 casted_ptr = result_loc; 19496 } else { 19497 isf->already_resolved = true; 19498 // Now it's time to add the field to the struct type. 19499 uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count; 19500 uint32_t new_field_count = old_field_count + 1; 19501 isf->inferred_struct_type->data.structure.src_field_count = new_field_count; 19502 isf->inferred_struct_type->data.structure.fields = realloc_type_struct_fields( 19503 isf->inferred_struct_type->data.structure.fields, old_field_count, new_field_count); 19504 19505 field = isf->inferred_struct_type->data.structure.fields[old_field_count]; 19506 field->name = isf->field_name; 19507 field->type_entry = value_type; 19508 field->type_val = create_const_type(ira->codegen, field->type_entry); 19509 field->src_index = old_field_count; 19510 field->decl_node = value ? value->base.source_node : suspend_source_instr->source_node; 19511 if (value && instr_is_comptime(value)) { 19512 ZigValue *val = ir_resolve_const(ira, value, UndefOk); 19513 if (!val) 19514 return ira->codegen->invalid_inst_gen; 19515 field->is_comptime = true; 19516 field->init_val = ira->codegen->pass1_arena->create<ZigValue>(); 19517 copy_const_val(ira->codegen, field->init_val, val); 19518 return result_loc; 19519 } 19520 19521 ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false); 19522 if (instr_is_comptime(result_loc)) { 19523 casted_ptr = ir_const(ira, suspend_source_instr, struct_ptr_type); 19524 copy_const_val(ira->codegen, casted_ptr->value, result_loc->value); 19525 casted_ptr->value->type = struct_ptr_type; 19526 } else { 19527 casted_ptr = result_loc; 19528 } 19529 if (instr_is_comptime(casted_ptr)) { 19530 ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad); 19531 if (!ptr_val) 19532 return ira->codegen->invalid_inst_gen; 19533 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 19534 ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, 19535 suspend_source_instr->source_node); 19536 struct_val->special = ConstValSpecialStatic; 19537 struct_val->data.x_struct.fields = realloc_const_vals_ptrs(ira->codegen, 19538 struct_val->data.x_struct.fields, old_field_count, new_field_count); 19539 19540 ZigValue *field_val = struct_val->data.x_struct.fields[old_field_count]; 19541 field_val->special = ConstValSpecialUndef; 19542 field_val->type = field->type_entry; 19543 field_val->parent.id = ConstParentIdStruct; 19544 field_val->parent.data.p_struct.struct_val = struct_val; 19545 field_val->parent.data.p_struct.field_index = old_field_count; 19546 } 19547 } 19548 } 19549 19550 result_loc = ir_analyze_struct_field_ptr(ira, suspend_source_instr, field, casted_ptr, 19551 isf->inferred_struct_type, true); 19552 result_loc_pass1->resolved_loc = result_loc; 19553 } 19554 19555 if (was_written) { 19556 return result_loc; 19557 } 19558 19559 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, suspend_source_instr); 19560 ZigType *actual_elem_type = result_loc->value->type->data.pointer.child_type; 19561 if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && 19562 value_type->id != ZigTypeIdNull && value_type->id != ZigTypeIdUndefined) 19563 { 19564 bool same_comptime_repr = types_have_same_zig_comptime_repr(ira->codegen, actual_elem_type, value_type); 19565 if (!same_comptime_repr) { 19566 result_loc_pass1->written = was_written; 19567 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); 19568 } 19569 } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion && 19570 value_type->id != ZigTypeIdUndefined) 19571 { 19572 if (value_type->id == ZigTypeIdErrorSet) { 19573 return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); 19574 } else { 19575 IrInstGen *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, 19576 result_loc, false, true); 19577 ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; 19578 if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && 19579 value_type->id != ZigTypeIdNull && value_type->id != ZigTypeIdUndefined) 19580 { 19581 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); 19582 } else { 19583 return unwrapped_err_ptr; 19584 } 19585 } 19586 } 19587 return result_loc; 19588 } 19589 19590 static IrInstGen *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstSrcResolveResult *instruction) { 19591 ZigType *implicit_elem_type; 19592 if (instruction->ty == nullptr) { 19593 if (instruction->result_loc->id == ResultLocIdCast) { 19594 implicit_elem_type = ir_resolve_type(ira, 19595 instruction->result_loc->source_instruction->child); 19596 if (type_is_invalid(implicit_elem_type)) 19597 return ira->codegen->invalid_inst_gen; 19598 } else if (instruction->result_loc->id == ResultLocIdReturn) { 19599 implicit_elem_type = ira->explicit_return_type; 19600 if (type_is_invalid(implicit_elem_type)) 19601 return ira->codegen->invalid_inst_gen; 19602 } else { 19603 implicit_elem_type = ira->codegen->builtin_types.entry_anytype; 19604 } 19605 if (implicit_elem_type == ira->codegen->builtin_types.entry_anytype) { 19606 Buf *bare_name = buf_alloc(); 19607 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), 19608 instruction->base.base.scope, instruction->base.base.source_node, bare_name); 19609 19610 StructSpecial struct_special = StructSpecialInferredStruct; 19611 if (instruction->base.base.source_node->type == NodeTypeContainerInitExpr && 19612 instruction->base.base.source_node->data.container_init_expr.kind == ContainerInitKindArray) 19613 { 19614 struct_special = StructSpecialInferredTuple; 19615 } 19616 19617 ZigType *inferred_struct_type = get_partial_container_type(ira->codegen, 19618 instruction->base.base.scope, ContainerKindStruct, instruction->base.base.source_node, 19619 buf_ptr(name), bare_name, ContainerLayoutAuto); 19620 inferred_struct_type->data.structure.special = struct_special; 19621 inferred_struct_type->data.structure.resolve_status = ResolveStatusBeingInferred; 19622 implicit_elem_type = inferred_struct_type; 19623 } 19624 } else { 19625 implicit_elem_type = ir_resolve_type(ira, instruction->ty->child); 19626 if (type_is_invalid(implicit_elem_type)) 19627 return ira->codegen->invalid_inst_gen; 19628 } 19629 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 19630 implicit_elem_type, nullptr, false, true); 19631 if (result_loc != nullptr) 19632 return result_loc; 19633 19634 ZigFn *fn = ira->new_irb.exec->fn_entry; 19635 if (fn != nullptr && fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync && 19636 instruction->result_loc->id == ResultLocIdReturn) 19637 { 19638 result_loc = ir_resolve_result(ira, &instruction->base.base, no_result_loc(), 19639 implicit_elem_type, nullptr, false, true); 19640 if (result_loc != nullptr && 19641 (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) 19642 { 19643 return result_loc; 19644 } 19645 result_loc->value->special = ConstValSpecialRuntime; 19646 return result_loc; 19647 } 19648 19649 IrInstGen *result = ir_const(ira, &instruction->base.base, implicit_elem_type); 19650 result->value->special = ConstValSpecialUndef; 19651 IrInstGen *ptr = ir_get_ref(ira, &instruction->base.base, result, false, false); 19652 ptr->value->data.x_ptr.mut = ConstPtrMutComptimeVar; 19653 return ptr; 19654 } 19655 19656 static void ir_reset_result(ResultLoc *result_loc) { 19657 result_loc->written = false; 19658 result_loc->resolved_loc = nullptr; 19659 result_loc->gen_instruction = nullptr; 19660 result_loc->implicit_elem_type = nullptr; 19661 switch (result_loc->id) { 19662 case ResultLocIdInvalid: 19663 zig_unreachable(); 19664 case ResultLocIdPeerParent: { 19665 ResultLocPeerParent *peer_parent = reinterpret_cast<ResultLocPeerParent *>(result_loc); 19666 peer_parent->skipped = false; 19667 peer_parent->done_resuming = false; 19668 peer_parent->resolved_type = nullptr; 19669 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 19670 ir_reset_result(&peer_parent->peers.at(i)->base); 19671 } 19672 break; 19673 } 19674 case ResultLocIdVar: { 19675 IrInstSrcAlloca *alloca_src = reinterpret_cast<IrInstSrcAlloca *>(result_loc->source_instruction); 19676 alloca_src->base.child = nullptr; 19677 break; 19678 } 19679 case ResultLocIdReturn: 19680 reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = false; 19681 break; 19682 case ResultLocIdPeer: 19683 case ResultLocIdNone: 19684 case ResultLocIdInstruction: 19685 case ResultLocIdBitCast: 19686 case ResultLocIdCast: 19687 break; 19688 } 19689 } 19690 19691 static IrInstGen *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInstSrcResetResult *instruction) { 19692 ir_reset_result(instruction->result_loc); 19693 return ir_const_void(ira, &instruction->base.base); 19694 } 19695 19696 static IrInstGen *get_async_call_result_loc(IrAnalyze *ira, IrInst* source_instr, 19697 ZigType *fn_ret_type, bool is_async_call_builtin, IrInstGen **args_ptr, size_t args_len, 19698 IrInstGen *ret_ptr_uncasted) 19699 { 19700 ir_assert(is_async_call_builtin, source_instr); 19701 if (type_is_invalid(ret_ptr_uncasted->value->type)) 19702 return ira->codegen->invalid_inst_gen; 19703 if (ret_ptr_uncasted->value->type->id == ZigTypeIdVoid) { 19704 // Result location will be inside the async frame. 19705 return nullptr; 19706 } 19707 return ir_implicit_cast(ira, ret_ptr_uncasted, get_pointer_to_type(ira->codegen, fn_ret_type, false)); 19708 } 19709 19710 static IrInstGen *ir_analyze_async_call(IrAnalyze *ira, IrInst* source_instr, ZigFn *fn_entry, 19711 ZigType *fn_type, IrInstGen *fn_ref, IrInstGen **casted_args, size_t arg_count, 19712 IrInstGen *casted_new_stack, bool is_async_call_builtin, IrInstGen *ret_ptr_uncasted, 19713 ResultLoc *call_result_loc) 19714 { 19715 if (fn_entry == nullptr) { 19716 if (fn_type->data.fn.fn_type_id.cc != CallingConventionAsync) { 19717 ir_add_error(ira, &fn_ref->base, 19718 buf_sprintf("expected async function, found '%s'", buf_ptr(&fn_type->name))); 19719 return ira->codegen->invalid_inst_gen; 19720 } 19721 if (casted_new_stack == nullptr) { 19722 ir_add_error(ira, &fn_ref->base, buf_sprintf("function is not comptime-known; @asyncCall required")); 19723 return ira->codegen->invalid_inst_gen; 19724 } 19725 } 19726 if (casted_new_stack != nullptr) { 19727 ZigType *fn_ret_type = fn_type->data.fn.fn_type_id.return_type; 19728 IrInstGen *ret_ptr = get_async_call_result_loc(ira, source_instr, fn_ret_type, is_async_call_builtin, 19729 casted_args, arg_count, ret_ptr_uncasted); 19730 if (ret_ptr != nullptr && type_is_invalid(ret_ptr->value->type)) 19731 return ira->codegen->invalid_inst_gen; 19732 19733 ZigType *anyframe_type = get_any_frame_type(ira->codegen, fn_ret_type); 19734 19735 IrInstGenCall *call_gen = ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, 19736 arg_count, casted_args, CallModifierAsync, casted_new_stack, 19737 is_async_call_builtin, ret_ptr, anyframe_type); 19738 return &call_gen->base; 19739 } else { 19740 ZigType *frame_type = get_fn_frame_type(ira->codegen, fn_entry); 19741 IrInstGen *result_loc = ir_resolve_result(ira, source_instr, call_result_loc, 19742 frame_type, nullptr, true, false); 19743 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 19744 return result_loc; 19745 } 19746 result_loc = ir_implicit_cast2(ira, source_instr, result_loc, 19747 get_pointer_to_type(ira->codegen, frame_type, false)); 19748 if (type_is_invalid(result_loc->value->type)) 19749 return ira->codegen->invalid_inst_gen; 19750 return &ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, arg_count, 19751 casted_args, CallModifierAsync, casted_new_stack, 19752 is_async_call_builtin, result_loc, frame_type)->base; 19753 } 19754 } 19755 static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, 19756 IrInstGen *arg, Scope **exec_scope, size_t *next_proto_i) 19757 { 19758 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 19759 assert(param_decl_node->type == NodeTypeParamDecl); 19760 19761 IrInstGen *casted_arg; 19762 if (param_decl_node->data.param_decl.anytype_token == nullptr) { 19763 AstNode *param_type_node = param_decl_node->data.param_decl.type; 19764 ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node); 19765 if (type_is_invalid(param_type)) 19766 return false; 19767 19768 casted_arg = ir_implicit_cast(ira, arg, param_type); 19769 if (type_is_invalid(casted_arg->value->type)) 19770 return false; 19771 } else { 19772 casted_arg = arg; 19773 } 19774 19775 ZigValue *arg_val = ir_resolve_const(ira, casted_arg, UndefOk); 19776 if (!arg_val) 19777 return false; 19778 19779 Buf *param_name = param_decl_node->data.param_decl.name; 19780 ZigVar *var = add_variable(ira->codegen, param_decl_node, 19781 *exec_scope, param_name, true, arg_val, nullptr, arg_val->type); 19782 *exec_scope = var->child_scope; 19783 *next_proto_i += 1; 19784 19785 return true; 19786 } 19787 19788 static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node, 19789 IrInstGen *arg, IrInst *arg_src, Scope **child_scope, size_t *next_proto_i, 19790 GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstGen **casted_args, 19791 ZigFn *impl_fn) 19792 { 19793 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 19794 assert(param_decl_node->type == NodeTypeParamDecl); 19795 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 19796 bool arg_part_of_generic_id = false; 19797 IrInstGen *casted_arg; 19798 if (is_var_args) { 19799 arg_part_of_generic_id = true; 19800 casted_arg = arg; 19801 } else { 19802 if (param_decl_node->data.param_decl.anytype_token == nullptr) { 19803 AstNode *param_type_node = param_decl_node->data.param_decl.type; 19804 ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node); 19805 if (type_is_invalid(param_type)) 19806 return false; 19807 19808 casted_arg = ir_implicit_cast2(ira, arg_src, arg, param_type); 19809 if (type_is_invalid(casted_arg->value->type)) 19810 return false; 19811 } else { 19812 arg_part_of_generic_id = true; 19813 casted_arg = arg; 19814 } 19815 } 19816 19817 bool comptime_arg = param_decl_node->data.param_decl.is_comptime; 19818 if (!comptime_arg) { 19819 switch (type_requires_comptime(ira->codegen, casted_arg->value->type)) { 19820 case ReqCompTimeInvalid: 19821 return false; 19822 case ReqCompTimeYes: 19823 comptime_arg = true; 19824 break; 19825 case ReqCompTimeNo: 19826 break; 19827 } 19828 } 19829 19830 ZigValue *arg_val; 19831 19832 if (comptime_arg) { 19833 arg_part_of_generic_id = true; 19834 arg_val = ir_resolve_const(ira, casted_arg, UndefBad); 19835 if (!arg_val) 19836 return false; 19837 } else { 19838 arg_val = create_const_runtime(ira->codegen, casted_arg->value->type); 19839 } 19840 if (arg_part_of_generic_id) { 19841 copy_const_val(ira->codegen, &generic_id->params[generic_id->param_count], arg_val); 19842 generic_id->param_count += 1; 19843 } 19844 19845 Buf *param_name = param_decl_node->data.param_decl.name; 19846 if (!param_name) return false; 19847 if (!is_var_args) { 19848 ZigVar *var = add_variable(ira->codegen, param_decl_node, 19849 *child_scope, param_name, true, arg_val, nullptr, arg_val->type); 19850 *child_scope = var->child_scope; 19851 var->shadowable = !comptime_arg; 19852 19853 *next_proto_i += 1; 19854 } else if (casted_arg->value->type->id == ZigTypeIdComptimeInt || 19855 casted_arg->value->type->id == ZigTypeIdComptimeFloat) 19856 { 19857 ir_add_error(ira, &casted_arg->base, 19858 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/ziglang/zig/issues/557")); 19859 return false; 19860 } 19861 19862 if (!comptime_arg) { 19863 casted_args[fn_type_id->param_count] = casted_arg; 19864 FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count]; 19865 param_info->type = casted_arg->value->type; 19866 param_info->is_noalias = param_decl_node->data.param_decl.is_noalias; 19867 impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node; 19868 fn_type_id->param_count += 1; 19869 } 19870 19871 return true; 19872 } 19873 19874 static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *var) { 19875 while (var->next_var != nullptr) { 19876 var = var->next_var; 19877 } 19878 19879 if (var->var_type == nullptr || type_is_invalid(var->var_type)) 19880 return ira->codegen->invalid_inst_gen; 19881 19882 bool is_volatile = false; 19883 ZigType *var_ptr_type = get_pointer_to_type_extra(ira->codegen, var->var_type, 19884 var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0, false); 19885 19886 if (var->ptr_instruction != nullptr) { 19887 return ir_implicit_cast(ira, var->ptr_instruction, var_ptr_type); 19888 } 19889 19890 bool comptime_var_mem = ir_get_var_is_comptime(var); 19891 bool linkage_makes_it_runtime = var->decl_node->data.variable_declaration.is_extern; 19892 19893 IrInstGen *result = ir_build_var_ptr_gen(ira, source_instr, var); 19894 result->value->type = var_ptr_type; 19895 19896 if (!linkage_makes_it_runtime && !var->is_thread_local && value_is_comptime(var->const_value)) { 19897 ZigValue *val = var->const_value; 19898 switch (val->special) { 19899 case ConstValSpecialRuntime: 19900 break; 19901 case ConstValSpecialStatic: // fallthrough 19902 case ConstValSpecialLazy: // fallthrough 19903 case ConstValSpecialUndef: { 19904 ConstPtrMut ptr_mut; 19905 if (comptime_var_mem) { 19906 ptr_mut = ConstPtrMutComptimeVar; 19907 } else if (var->gen_is_const) { 19908 ptr_mut = ConstPtrMutComptimeConst; 19909 } else { 19910 assert(!comptime_var_mem); 19911 ptr_mut = ConstPtrMutRuntimeVar; 19912 } 19913 result->value->special = ConstValSpecialStatic; 19914 result->value->data.x_ptr.mut = ptr_mut; 19915 result->value->data.x_ptr.special = ConstPtrSpecialRef; 19916 result->value->data.x_ptr.data.ref.pointee = val; 19917 return result; 19918 } 19919 } 19920 } 19921 19922 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr); 19923 result->value->data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack; 19924 19925 return result; 19926 } 19927 19928 // This function is called when a comptime value becomes accessible at runtime. 19929 static void mark_comptime_value_escape(IrAnalyze *ira, IrInst* source_instr, ZigValue *val) { 19930 ir_assert(value_is_comptime(val), source_instr); 19931 if (val->special == ConstValSpecialUndef) 19932 return; 19933 19934 if (val->type->id == ZigTypeIdFn && val->type->data.fn.fn_type_id.cc == CallingConventionUnspecified) { 19935 ir_assert(val->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); 19936 if (val->data.x_ptr.data.fn.fn_entry->non_async_node == nullptr) { 19937 val->data.x_ptr.data.fn.fn_entry->non_async_node = source_instr->source_node; 19938 } 19939 } 19940 } 19941 19942 static IrInstGen *ir_analyze_store_ptr(IrAnalyze *ira, IrInst* source_instr, 19943 IrInstGen *ptr, IrInstGen *uncasted_value, bool allow_write_through_const) 19944 { 19945 assert(ptr->value->type->id == ZigTypeIdPointer); 19946 19947 if (ptr->value->data.x_ptr.special == ConstPtrSpecialDiscard) { 19948 if (uncasted_value->value->type->id == ZigTypeIdErrorUnion || 19949 uncasted_value->value->type->id == ZigTypeIdErrorSet) 19950 { 19951 ir_add_error(ira, source_instr, buf_sprintf("error is discarded")); 19952 return ira->codegen->invalid_inst_gen; 19953 } 19954 return ir_const_void(ira, source_instr); 19955 } 19956 19957 if (ptr->value->type->data.pointer.is_const && !allow_write_through_const) { 19958 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 19959 return ira->codegen->invalid_inst_gen; 19960 } 19961 19962 ZigType *child_type = ptr->value->type->data.pointer.child_type; 19963 IrInstGen *value = ir_implicit_cast(ira, uncasted_value, child_type); 19964 if (type_is_invalid(value->value->type)) 19965 return ira->codegen->invalid_inst_gen; 19966 19967 switch (type_has_one_possible_value(ira->codegen, child_type)) { 19968 case OnePossibleValueInvalid: 19969 return ira->codegen->invalid_inst_gen; 19970 case OnePossibleValueYes: 19971 return ir_const_void(ira, source_instr); 19972 case OnePossibleValueNo: 19973 break; 19974 } 19975 19976 if (instr_is_comptime(ptr) && ptr->value->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 19977 if (!allow_write_through_const && ptr->value->data.x_ptr.mut == ConstPtrMutComptimeConst) { 19978 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 19979 return ira->codegen->invalid_inst_gen; 19980 } 19981 if ((allow_write_through_const && ptr->value->data.x_ptr.mut == ConstPtrMutComptimeConst) || 19982 ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar || 19983 ptr->value->data.x_ptr.mut == ConstPtrMutInfer) 19984 { 19985 if (instr_is_comptime(value)) { 19986 ZigValue *dest_val = const_ptr_pointee(ira, ira->codegen, ptr->value, source_instr->source_node); 19987 if (dest_val == nullptr) 19988 return ira->codegen->invalid_inst_gen; 19989 if (dest_val->special != ConstValSpecialRuntime) { 19990 copy_const_val(ira->codegen, dest_val, value->value); 19991 19992 if (ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar && 19993 !ira->new_irb.current_basic_block->must_be_comptime_source_instr) 19994 { 19995 ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; 19996 } 19997 return ir_const_void(ira, source_instr); 19998 } 19999 } 20000 if (ptr->value->data.x_ptr.mut == ConstPtrMutInfer) { 20001 ptr->value->special = ConstValSpecialRuntime; 20002 } else { 20003 ir_add_error(ira, source_instr, 20004 buf_sprintf("cannot store runtime value in compile time variable")); 20005 ZigValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, ptr->value); 20006 dest_val->type = ira->codegen->builtin_types.entry_invalid; 20007 20008 return ira->codegen->invalid_inst_gen; 20009 } 20010 } 20011 } 20012 20013 if (ptr->value->type->data.pointer.inferred_struct_field != nullptr && 20014 child_type == ira->codegen->builtin_types.entry_anytype) 20015 { 20016 child_type = ptr->value->type->data.pointer.inferred_struct_field->inferred_struct_type; 20017 } 20018 20019 switch (type_requires_comptime(ira->codegen, child_type)) { 20020 case ReqCompTimeInvalid: 20021 return ira->codegen->invalid_inst_gen; 20022 case ReqCompTimeYes: 20023 switch (type_has_one_possible_value(ira->codegen, ptr->value->type)) { 20024 case OnePossibleValueInvalid: 20025 return ira->codegen->invalid_inst_gen; 20026 case OnePossibleValueNo: 20027 ir_add_error(ira, source_instr, 20028 buf_sprintf("cannot store runtime value in type '%s'", buf_ptr(&child_type->name))); 20029 return ira->codegen->invalid_inst_gen; 20030 case OnePossibleValueYes: 20031 return ir_const_void(ira, source_instr); 20032 } 20033 zig_unreachable(); 20034 case ReqCompTimeNo: 20035 break; 20036 } 20037 20038 if (instr_is_comptime(value)) { 20039 mark_comptime_value_escape(ira, source_instr, value->value); 20040 } 20041 20042 // If this is a store to a pointer with a runtime-known vector index, 20043 // we have to figure out the IrInstGen which represents the index and 20044 // emit a IrInstGenVectorStoreElem, or emit a compile error 20045 // explaining why it is impossible for this store to work. Which is that 20046 // the pointer address is of the vector; without the element index being known 20047 // we cannot properly perform the insertion. 20048 if (ptr->value->type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) { 20049 if (ptr->id == IrInstGenIdElemPtr) { 20050 IrInstGenElemPtr *elem_ptr = (IrInstGenElemPtr *)ptr; 20051 return ir_build_vector_store_elem(ira, source_instr, elem_ptr->array_ptr, 20052 elem_ptr->elem_index, value); 20053 } 20054 ir_add_error(ira, &ptr->base, 20055 buf_sprintf("unable to determine vector element index of type '%s'", 20056 buf_ptr(&ptr->value->type->name))); 20057 return ira->codegen->invalid_inst_gen; 20058 } 20059 20060 return ir_build_store_ptr_gen(ira, source_instr, ptr, value); 20061 } 20062 20063 static IrInstGen *analyze_casted_new_stack(IrAnalyze *ira, IrInst* source_instr, 20064 IrInstGen *new_stack, IrInst *new_stack_src, bool is_async_call_builtin, ZigFn *fn_entry) 20065 { 20066 if (new_stack == nullptr) 20067 return nullptr; 20068 20069 if (!is_async_call_builtin && 20070 arch_stack_pointer_register_name(ira->codegen->zig_target->arch) == nullptr) 20071 { 20072 ir_add_error(ira, source_instr, 20073 buf_sprintf("target arch '%s' does not support calling with a new stack", 20074 target_arch_name(ira->codegen->zig_target->arch))); 20075 } 20076 20077 if (is_async_call_builtin && 20078 fn_entry != nullptr && new_stack->value->type->id == ZigTypeIdPointer && 20079 new_stack->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 20080 { 20081 ZigType *needed_frame_type = get_pointer_to_type(ira->codegen, 20082 get_fn_frame_type(ira->codegen, fn_entry), false); 20083 return ir_implicit_cast(ira, new_stack, needed_frame_type); 20084 } else { 20085 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 20086 false, false, PtrLenUnknown, target_fn_align(ira->codegen->zig_target), 0, 0, false); 20087 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 20088 ira->codegen->need_frame_size_prefix_data = true; 20089 return ir_implicit_cast2(ira, new_stack_src, new_stack, u8_slice); 20090 } 20091 } 20092 20093 static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, 20094 ZigFn *fn_entry, ZigType *fn_type, IrInstGen *fn_ref, 20095 IrInstGen *first_arg_ptr, IrInst *first_arg_ptr_src, CallModifier modifier, 20096 IrInstGen *new_stack, IrInst *new_stack_src, bool is_async_call_builtin, 20097 IrInstGen **args_ptr, size_t args_len, IrInstGen *ret_ptr, ResultLoc *call_result_loc) 20098 { 20099 Error err; 20100 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 20101 size_t first_arg_1_or_0 = first_arg_ptr ? 1 : 0; 20102 20103 // for extern functions, the var args argument is not counted. 20104 // for zig functions, it is. 20105 size_t var_args_1_or_0; 20106 if (fn_type_id->cc == CallingConventionC) { 20107 var_args_1_or_0 = 0; 20108 } else { 20109 var_args_1_or_0 = fn_type_id->is_var_args ? 1 : 0; 20110 } 20111 size_t src_param_count = fn_type_id->param_count - var_args_1_or_0; 20112 size_t call_param_count = args_len + first_arg_1_or_0; 20113 AstNode *source_node = source_instr->source_node; 20114 20115 AstNode *fn_proto_node = fn_entry ? fn_entry->proto_node : nullptr;; 20116 20117 if (fn_type_id->cc == CallingConventionNaked) { 20118 ErrorMsg *msg = ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to call function with naked calling convention")); 20119 if (fn_proto_node) { 20120 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 20121 } 20122 return ira->codegen->invalid_inst_gen; 20123 } 20124 20125 if (fn_type_id->is_var_args) { 20126 if (call_param_count < src_param_count) { 20127 ErrorMsg *msg = ir_add_error_node(ira, source_node, 20128 buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 20129 if (fn_proto_node) { 20130 add_error_note(ira->codegen, msg, fn_proto_node, 20131 buf_sprintf("declared here")); 20132 } 20133 return ira->codegen->invalid_inst_gen; 20134 } 20135 } else if (src_param_count != call_param_count) { 20136 ErrorMsg *msg = ir_add_error_node(ira, source_node, 20137 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 20138 if (fn_proto_node) { 20139 add_error_note(ira->codegen, msg, fn_proto_node, 20140 buf_sprintf("declared here")); 20141 } 20142 return ira->codegen->invalid_inst_gen; 20143 } 20144 20145 if (modifier == CallModifierCompileTime) { 20146 // If we are evaluating an extern function in a TypeOf call, we can return an undefined value 20147 // of its return type. 20148 if (fn_entry != nullptr && get_scope_typeof(source_instr->scope) != nullptr && 20149 fn_proto_node->data.fn_proto.is_extern) { 20150 20151 assert(fn_entry->body_node == nullptr); 20152 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 20153 ZigType *return_type = ir_analyze_type_expr(ira, source_instr->scope, return_type_node); 20154 if (type_is_invalid(return_type)) 20155 return ira->codegen->invalid_inst_gen; 20156 20157 return ir_const_undef(ira, source_instr, return_type); 20158 } 20159 20160 // No special handling is needed for compile time evaluation of generic functions. 20161 if (!fn_entry || fn_entry->body_node == nullptr) { 20162 ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression")); 20163 return ira->codegen->invalid_inst_gen; 20164 } 20165 20166 if (!ir_emit_backward_branch(ira, source_instr)) 20167 return ira->codegen->invalid_inst_gen; 20168 20169 // Fork a scope of the function with known values for the parameters. 20170 Scope *exec_scope = &fn_entry->fndef_scope->base; 20171 20172 size_t next_proto_i = 0; 20173 if (first_arg_ptr) { 20174 assert(first_arg_ptr->value->type->id == ZigTypeIdPointer); 20175 20176 bool first_arg_known_bare = false; 20177 if (fn_type_id->next_param_index >= 1) { 20178 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 20179 if (type_is_invalid(param_type)) 20180 return ira->codegen->invalid_inst_gen; 20181 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 20182 } 20183 20184 IrInstGen *first_arg; 20185 if (!first_arg_known_bare) { 20186 first_arg = first_arg_ptr; 20187 } else { 20188 first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); 20189 if (type_is_invalid(first_arg->value->type)) 20190 return ira->codegen->invalid_inst_gen; 20191 } 20192 20193 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, first_arg, &exec_scope, &next_proto_i)) 20194 return ira->codegen->invalid_inst_gen; 20195 } 20196 20197 for (size_t call_i = 0; call_i < args_len; call_i += 1) { 20198 IrInstGen *old_arg = args_ptr[call_i]; 20199 20200 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_proto_i)) 20201 return ira->codegen->invalid_inst_gen; 20202 } 20203 20204 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 20205 if (return_type_node == nullptr) { 20206 ir_add_error(ira, &fn_ref->base, 20207 buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447")); 20208 return ira->codegen->invalid_inst_gen; 20209 } 20210 ZigType *specified_return_type = ir_analyze_type_expr(ira, exec_scope, return_type_node); 20211 if (type_is_invalid(specified_return_type)) 20212 return ira->codegen->invalid_inst_gen; 20213 ZigType *return_type; 20214 ZigType *inferred_err_set_type = nullptr; 20215 if (fn_proto_node->data.fn_proto.auto_err_set) { 20216 inferred_err_set_type = get_auto_err_set_type(ira->codegen, fn_entry); 20217 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 20218 return ira->codegen->invalid_inst_gen; 20219 return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 20220 } else { 20221 return_type = specified_return_type; 20222 } 20223 20224 bool cacheable = fn_eval_cacheable(exec_scope, return_type); 20225 ZigValue *result = nullptr; 20226 if (cacheable) { 20227 auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope); 20228 if (entry) 20229 result = entry->value; 20230 } 20231 20232 if (result == nullptr) { 20233 // Analyze the fn body block like any other constant expression. 20234 AstNode *body_node = fn_entry->body_node; 20235 ZigValue *result_ptr; 20236 create_result_ptr(ira->codegen, return_type, &result, &result_ptr); 20237 20238 if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr, 20239 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 20240 fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node, 20241 UndefOk))) 20242 { 20243 return ira->codegen->invalid_inst_gen; 20244 } 20245 20246 if (inferred_err_set_type != nullptr) { 20247 inferred_err_set_type->data.error_set.incomplete = false; 20248 if (result->type->id == ZigTypeIdErrorUnion) { 20249 ErrorTableEntry *err = result->data.x_err_union.error_set->data.x_err_set; 20250 if (err != nullptr) { 20251 inferred_err_set_type->data.error_set.err_count = 1; 20252 inferred_err_set_type->data.error_set.errors = heap::c_allocator.create<ErrorTableEntry *>(); 20253 inferred_err_set_type->data.error_set.errors[0] = err; 20254 } 20255 ZigType *fn_inferred_err_set_type = result->type->data.error_union.err_set_type; 20256 inferred_err_set_type->data.error_set.err_count = fn_inferred_err_set_type->data.error_set.err_count; 20257 inferred_err_set_type->data.error_set.errors = fn_inferred_err_set_type->data.error_set.errors; 20258 } else if (result->type->id == ZigTypeIdErrorSet) { 20259 inferred_err_set_type->data.error_set.err_count = result->type->data.error_set.err_count; 20260 inferred_err_set_type->data.error_set.errors = result->type->data.error_set.errors; 20261 } 20262 } 20263 20264 if (cacheable) { 20265 ira->codegen->memoized_fn_eval_table.put(exec_scope, result); 20266 } 20267 20268 if (type_is_invalid(result->type)) { 20269 return ira->codegen->invalid_inst_gen; 20270 } 20271 } 20272 20273 IrInstGen *new_instruction = ir_const_move(ira, source_instr, result); 20274 return ir_finish_anal(ira, new_instruction); 20275 } 20276 20277 if (fn_type->data.fn.is_generic) { 20278 if (!fn_entry) { 20279 ir_add_error(ira, &fn_ref->base, 20280 buf_sprintf("calling a generic function requires compile-time known function value")); 20281 return ira->codegen->invalid_inst_gen; 20282 } 20283 20284 size_t new_fn_arg_count = first_arg_1_or_0 + args_len; 20285 20286 IrInstGen **casted_args = heap::c_allocator.allocate<IrInstGen *>(new_fn_arg_count); 20287 20288 // Fork a scope of the function with known values for the parameters. 20289 Scope *parent_scope = fn_entry->fndef_scope->base.parent; 20290 ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node); 20291 impl_fn->param_source_nodes = heap::c_allocator.allocate<AstNode *>(new_fn_arg_count); 20292 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); 20293 impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn); 20294 impl_fn->child_scope = &impl_fn->fndef_scope->base; 20295 FnTypeId inst_fn_type_id = {0}; 20296 init_fn_type_id(&inst_fn_type_id, fn_proto_node, fn_type_id->cc, new_fn_arg_count); 20297 inst_fn_type_id.param_count = 0; 20298 inst_fn_type_id.is_var_args = false; 20299 20300 // TODO maybe GenericFnTypeId can be replaced with using the child_scope directly 20301 // as the key in generic_table 20302 GenericFnTypeId *generic_id = heap::c_allocator.create<GenericFnTypeId>(); 20303 generic_id->fn_entry = fn_entry; 20304 generic_id->param_count = 0; 20305 generic_id->params = ira->codegen->pass1_arena->allocate<ZigValue>(new_fn_arg_count); 20306 size_t next_proto_i = 0; 20307 20308 if (first_arg_ptr) { 20309 assert(first_arg_ptr->value->type->id == ZigTypeIdPointer); 20310 20311 bool first_arg_known_bare = false; 20312 if (fn_type_id->next_param_index >= 1) { 20313 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 20314 if (type_is_invalid(param_type)) 20315 return ira->codegen->invalid_inst_gen; 20316 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 20317 } 20318 20319 IrInstGen *first_arg; 20320 if (!first_arg_known_bare) { 20321 first_arg = first_arg_ptr; 20322 } else { 20323 first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); 20324 if (type_is_invalid(first_arg->value->type)) 20325 return ira->codegen->invalid_inst_gen; 20326 } 20327 20328 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, first_arg, first_arg_ptr_src, 20329 &impl_fn->child_scope, &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 20330 { 20331 return ira->codegen->invalid_inst_gen; 20332 } 20333 } 20334 20335 ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry; 20336 assert(parent_fn_entry); 20337 for (size_t call_i = 0; call_i < args_len; call_i += 1) { 20338 IrInstGen *arg = args_ptr[call_i]; 20339 20340 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 20341 assert(param_decl_node->type == NodeTypeParamDecl); 20342 20343 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &arg->base, &impl_fn->child_scope, 20344 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 20345 { 20346 return ira->codegen->invalid_inst_gen; 20347 } 20348 } 20349 20350 if (fn_proto_node->data.fn_proto.align_expr != nullptr) { 20351 ZigValue *align_result; 20352 ZigValue *result_ptr; 20353 create_result_ptr(ira->codegen, get_align_amt_type(ira->codegen), &align_result, &result_ptr); 20354 if ((err = ir_eval_const_value(ira->codegen, impl_fn->child_scope, 20355 fn_proto_node->data.fn_proto.align_expr, result_ptr, 20356 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 20357 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, 20358 nullptr, UndefBad))) 20359 { 20360 return ira->codegen->invalid_inst_gen; 20361 } 20362 IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb, 20363 impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); 20364 const_instruction->base.value = align_result; 20365 20366 uint32_t align_bytes = 0; 20367 ir_resolve_align(ira, &const_instruction->base, nullptr, &align_bytes); 20368 impl_fn->align_bytes = align_bytes; 20369 inst_fn_type_id.alignment = align_bytes; 20370 } 20371 20372 if (fn_proto_node->data.fn_proto.return_anytype_token == nullptr) { 20373 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 20374 ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node); 20375 if (type_is_invalid(specified_return_type)) 20376 return ira->codegen->invalid_inst_gen; 20377 20378 if(!is_valid_return_type(specified_return_type)){ 20379 ErrorMsg *msg = ir_add_error(ira, source_instr, 20380 buf_sprintf("call to generic function with %s return type '%s' not allowed", type_id_name(specified_return_type->id), buf_ptr(&specified_return_type->name))); 20381 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("function declared here")); 20382 20383 Tld *tld = find_decl(ira->codegen, &fn_entry->fndef_scope->base, &specified_return_type->name); 20384 if (tld != nullptr) { 20385 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("type declared here")); 20386 } 20387 return ira->codegen->invalid_inst_gen; 20388 } 20389 20390 if (fn_proto_node->data.fn_proto.auto_err_set) { 20391 ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn); 20392 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 20393 return ira->codegen->invalid_inst_gen; 20394 inst_fn_type_id.return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 20395 } else { 20396 inst_fn_type_id.return_type = specified_return_type; 20397 } 20398 20399 switch (type_requires_comptime(ira->codegen, specified_return_type)) { 20400 case ReqCompTimeYes: 20401 // Throw out our work and call the function as if it were comptime. 20402 return ir_analyze_fn_call(ira, source_instr, fn_entry, fn_type, fn_ref, first_arg_ptr, 20403 first_arg_ptr_src, CallModifierCompileTime, new_stack, new_stack_src, is_async_call_builtin, 20404 args_ptr, args_len, ret_ptr, call_result_loc); 20405 case ReqCompTimeInvalid: 20406 return ira->codegen->invalid_inst_gen; 20407 case ReqCompTimeNo: 20408 break; 20409 } 20410 } 20411 20412 auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn); 20413 if (existing_entry) { 20414 // throw away all our work and use the existing function 20415 impl_fn = existing_entry->value; 20416 } else { 20417 // finish instantiating the function 20418 impl_fn->type_entry = get_fn_type(ira->codegen, &inst_fn_type_id); 20419 if (type_is_invalid(impl_fn->type_entry)) 20420 return ira->codegen->invalid_inst_gen; 20421 20422 impl_fn->ir_executable->source_node = source_instr->source_node; 20423 impl_fn->ir_executable->parent_exec = ira->new_irb.exec; 20424 impl_fn->analyzed_executable.source_node = source_instr->source_node; 20425 impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec; 20426 impl_fn->analyzed_executable.backward_branch_quota = ira->new_irb.exec->backward_branch_quota; 20427 impl_fn->analyzed_executable.is_generic_instantiation = true; 20428 20429 ira->codegen->fn_defs.append(impl_fn); 20430 } 20431 20432 FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id; 20433 20434 if (fn_type_can_fail(impl_fn_type_id)) { 20435 parent_fn_entry->calls_or_awaits_errorable_fn = true; 20436 } 20437 20438 IrInstGen *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack, 20439 new_stack_src, is_async_call_builtin, impl_fn); 20440 if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) 20441 return ira->codegen->invalid_inst_gen; 20442 20443 size_t impl_param_count = impl_fn_type_id->param_count; 20444 if (modifier == CallModifierAsync) { 20445 IrInstGen *result = ir_analyze_async_call(ira, source_instr, impl_fn, impl_fn->type_entry, 20446 nullptr, casted_args, impl_param_count, casted_new_stack, is_async_call_builtin, ret_ptr, 20447 call_result_loc); 20448 return ir_finish_anal(ira, result); 20449 } 20450 20451 IrInstGen *result_loc; 20452 if (handle_is_ptr(ira->codegen, impl_fn_type_id->return_type)) { 20453 result_loc = ir_resolve_result(ira, source_instr, call_result_loc, 20454 impl_fn_type_id->return_type, nullptr, true, false); 20455 if (result_loc != nullptr) { 20456 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 20457 return result_loc; 20458 } 20459 if (result_loc->value->type->data.pointer.is_const) { 20460 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 20461 return ira->codegen->invalid_inst_gen; 20462 } 20463 20464 IrInstGen *dummy_value = ir_const(ira, source_instr, impl_fn_type_id->return_type); 20465 dummy_value->value->special = ConstValSpecialRuntime; 20466 IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr, 20467 dummy_value, result_loc->value->type->data.pointer.child_type); 20468 if (type_is_invalid(dummy_result->value->type)) 20469 return ira->codegen->invalid_inst_gen; 20470 ZigType *res_child_type = result_loc->value->type->data.pointer.child_type; 20471 if (res_child_type == ira->codegen->builtin_types.entry_anytype) { 20472 res_child_type = impl_fn_type_id->return_type; 20473 } 20474 if (!handle_is_ptr(ira->codegen, res_child_type)) { 20475 ir_reset_result(call_result_loc); 20476 result_loc = nullptr; 20477 } 20478 } 20479 } else if (is_async_call_builtin) { 20480 result_loc = get_async_call_result_loc(ira, source_instr, impl_fn_type_id->return_type, 20481 is_async_call_builtin, args_ptr, args_len, ret_ptr); 20482 if (result_loc != nullptr && type_is_invalid(result_loc->value->type)) 20483 return ira->codegen->invalid_inst_gen; 20484 } else { 20485 result_loc = nullptr; 20486 } 20487 20488 if (impl_fn_type_id->cc == CallingConventionAsync && 20489 parent_fn_entry->inferred_async_node == nullptr && 20490 modifier != CallModifierNoSuspend) 20491 { 20492 parent_fn_entry->inferred_async_node = fn_ref->base.source_node; 20493 parent_fn_entry->inferred_async_fn = impl_fn; 20494 } 20495 20496 IrInstGenCall *new_call_instruction = ir_build_call_gen(ira, source_instr, 20497 impl_fn, nullptr, impl_param_count, casted_args, modifier, casted_new_stack, 20498 is_async_call_builtin, result_loc, impl_fn_type_id->return_type); 20499 20500 if (get_scope_typeof(source_instr->scope) == nullptr) { 20501 parent_fn_entry->call_list.append(new_call_instruction); 20502 } 20503 20504 return ir_finish_anal(ira, &new_call_instruction->base); 20505 } 20506 20507 ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry; 20508 assert(fn_type_id->return_type != nullptr); 20509 assert(parent_fn_entry != nullptr); 20510 if (fn_type_can_fail(fn_type_id)) { 20511 parent_fn_entry->calls_or_awaits_errorable_fn = true; 20512 } 20513 20514 20515 IrInstGen **casted_args = heap::c_allocator.allocate<IrInstGen *>(call_param_count); 20516 size_t next_arg_index = 0; 20517 if (first_arg_ptr) { 20518 assert(first_arg_ptr->value->type->id == ZigTypeIdPointer); 20519 20520 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 20521 if (type_is_invalid(param_type)) 20522 return ira->codegen->invalid_inst_gen; 20523 20524 IrInstGen *first_arg; 20525 if (param_type->id == ZigTypeIdPointer) { 20526 first_arg = first_arg_ptr; 20527 } else { 20528 first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); 20529 if (type_is_invalid(first_arg->value->type)) 20530 return ira->codegen->invalid_inst_gen; 20531 } 20532 20533 IrInstGen *casted_arg = ir_implicit_cast2(ira, first_arg_ptr_src, first_arg, param_type); 20534 if (type_is_invalid(casted_arg->value->type)) 20535 return ira->codegen->invalid_inst_gen; 20536 20537 casted_args[next_arg_index] = casted_arg; 20538 next_arg_index += 1; 20539 } 20540 for (size_t call_i = 0; call_i < args_len; call_i += 1) { 20541 IrInstGen *old_arg = args_ptr[call_i]; 20542 if (type_is_invalid(old_arg->value->type)) 20543 return ira->codegen->invalid_inst_gen; 20544 20545 IrInstGen *casted_arg; 20546 if (next_arg_index < src_param_count) { 20547 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 20548 if (type_is_invalid(param_type)) 20549 return ira->codegen->invalid_inst_gen; 20550 casted_arg = ir_implicit_cast(ira, old_arg, param_type); 20551 if (type_is_invalid(casted_arg->value->type)) 20552 return ira->codegen->invalid_inst_gen; 20553 } else { 20554 casted_arg = old_arg; 20555 } 20556 20557 casted_args[next_arg_index] = casted_arg; 20558 next_arg_index += 1; 20559 } 20560 20561 assert(next_arg_index == call_param_count); 20562 20563 ZigType *return_type = fn_type_id->return_type; 20564 if (type_is_invalid(return_type)) 20565 return ira->codegen->invalid_inst_gen; 20566 20567 if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && modifier == CallModifierNeverInline) { 20568 ir_add_error(ira, source_instr, 20569 buf_sprintf("no-inline call of inline function")); 20570 return ira->codegen->invalid_inst_gen; 20571 } 20572 20573 IrInstGen *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack, new_stack_src, 20574 is_async_call_builtin, fn_entry); 20575 if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) 20576 return ira->codegen->invalid_inst_gen; 20577 20578 if (modifier == CallModifierAsync) { 20579 IrInstGen *result = ir_analyze_async_call(ira, source_instr, fn_entry, fn_type, fn_ref, 20580 casted_args, call_param_count, casted_new_stack, is_async_call_builtin, ret_ptr, call_result_loc); 20581 return ir_finish_anal(ira, result); 20582 } 20583 20584 if (fn_type_id->cc == CallingConventionAsync && 20585 parent_fn_entry->inferred_async_node == nullptr && 20586 modifier != CallModifierNoSuspend) 20587 { 20588 parent_fn_entry->inferred_async_node = fn_ref->base.source_node; 20589 parent_fn_entry->inferred_async_fn = fn_entry; 20590 } 20591 20592 IrInstGen *result_loc; 20593 if (handle_is_ptr(ira->codegen, return_type)) { 20594 result_loc = ir_resolve_result(ira, source_instr, call_result_loc, 20595 return_type, nullptr, true, false); 20596 if (result_loc != nullptr) { 20597 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 20598 return result_loc; 20599 } 20600 if (result_loc->value->type->data.pointer.is_const) { 20601 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 20602 return ira->codegen->invalid_inst_gen; 20603 } 20604 20605 IrInstGen *dummy_value = ir_const(ira, source_instr, return_type); 20606 dummy_value->value->special = ConstValSpecialRuntime; 20607 IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr, 20608 dummy_value, result_loc->value->type->data.pointer.child_type); 20609 if (type_is_invalid(dummy_result->value->type)) 20610 return ira->codegen->invalid_inst_gen; 20611 ZigType *res_child_type = result_loc->value->type->data.pointer.child_type; 20612 if (res_child_type == ira->codegen->builtin_types.entry_anytype) { 20613 res_child_type = return_type; 20614 } 20615 if (!handle_is_ptr(ira->codegen, res_child_type)) { 20616 ir_reset_result(call_result_loc); 20617 result_loc = nullptr; 20618 } 20619 } 20620 } else if (is_async_call_builtin) { 20621 result_loc = get_async_call_result_loc(ira, source_instr, return_type, is_async_call_builtin, 20622 args_ptr, args_len, ret_ptr); 20623 if (result_loc != nullptr && type_is_invalid(result_loc->value->type)) 20624 return ira->codegen->invalid_inst_gen; 20625 } else { 20626 result_loc = nullptr; 20627 } 20628 20629 IrInstGenCall *new_call_instruction = ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, 20630 call_param_count, casted_args, modifier, casted_new_stack, 20631 is_async_call_builtin, result_loc, return_type); 20632 if (get_scope_typeof(source_instr->scope) == nullptr) { 20633 parent_fn_entry->call_list.append(new_call_instruction); 20634 } 20635 return ir_finish_anal(ira, &new_call_instruction->base); 20636 } 20637 20638 static IrInstGen *ir_analyze_fn_call_src(IrAnalyze *ira, IrInstSrcCall *call_instruction, 20639 ZigFn *fn_entry, ZigType *fn_type, IrInstGen *fn_ref, 20640 IrInstGen *first_arg_ptr, IrInst *first_arg_ptr_src, CallModifier modifier) 20641 { 20642 IrInstGen *new_stack = nullptr; 20643 IrInst *new_stack_src = nullptr; 20644 if (call_instruction->new_stack) { 20645 new_stack = call_instruction->new_stack->child; 20646 if (type_is_invalid(new_stack->value->type)) 20647 return ira->codegen->invalid_inst_gen; 20648 new_stack_src = &call_instruction->new_stack->base; 20649 } 20650 IrInstGen **args_ptr = heap::c_allocator.allocate<IrInstGen *>(call_instruction->arg_count); 20651 for (size_t i = 0; i < call_instruction->arg_count; i += 1) { 20652 args_ptr[i] = call_instruction->args[i]->child; 20653 if (type_is_invalid(args_ptr[i]->value->type)) 20654 return ira->codegen->invalid_inst_gen; 20655 } 20656 IrInstGen *ret_ptr = nullptr; 20657 if (call_instruction->ret_ptr != nullptr) { 20658 ret_ptr = call_instruction->ret_ptr->child; 20659 if (type_is_invalid(ret_ptr->value->type)) 20660 return ira->codegen->invalid_inst_gen; 20661 } 20662 IrInstGen *result = ir_analyze_fn_call(ira, &call_instruction->base.base, fn_entry, fn_type, fn_ref, 20663 first_arg_ptr, first_arg_ptr_src, modifier, new_stack, new_stack_src, 20664 call_instruction->is_async_call_builtin, args_ptr, call_instruction->arg_count, ret_ptr, 20665 call_instruction->result_loc); 20666 heap::c_allocator.deallocate(args_ptr, call_instruction->arg_count); 20667 return result; 20668 } 20669 20670 static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr, 20671 IrInstSrc *pass1_options, IrInstSrc *pass1_fn_ref, IrInstGen **args_ptr, size_t args_len, 20672 ResultLoc *result_loc) 20673 { 20674 IrInstGen *options = pass1_options->child; 20675 if (type_is_invalid(options->value->type)) 20676 return ira->codegen->invalid_inst_gen; 20677 20678 IrInstGen *fn_ref = pass1_fn_ref->child; 20679 if (type_is_invalid(fn_ref->value->type)) 20680 return ira->codegen->invalid_inst_gen; 20681 20682 TypeStructField *modifier_field = find_struct_type_field(options->value->type, buf_create_from_str("modifier")); 20683 ir_assert(modifier_field != nullptr, source_instr); 20684 IrInstGen *modifier_inst = ir_analyze_struct_value_field_value(ira, source_instr, options, modifier_field); 20685 ZigValue *modifier_val = ir_resolve_const(ira, modifier_inst, UndefBad); 20686 if (modifier_val == nullptr) 20687 return ira->codegen->invalid_inst_gen; 20688 CallModifier modifier = (CallModifier)bigint_as_u32(&modifier_val->data.x_enum_tag); 20689 20690 if (ir_should_inline(ira->old_irb.exec, source_instr->scope)) { 20691 switch (modifier) { 20692 case CallModifierBuiltin: 20693 zig_unreachable(); 20694 case CallModifierAsync: 20695 ir_add_error(ira, source_instr, buf_sprintf("TODO: comptime @call with async modifier")); 20696 return ira->codegen->invalid_inst_gen; 20697 case CallModifierCompileTime: 20698 case CallModifierNone: 20699 case CallModifierAlwaysInline: 20700 case CallModifierAlwaysTail: 20701 case CallModifierNoSuspend: 20702 modifier = CallModifierCompileTime; 20703 break; 20704 case CallModifierNeverInline: 20705 ir_add_error(ira, source_instr, 20706 buf_sprintf("unable to perform 'never_inline' call at compile-time")); 20707 return ira->codegen->invalid_inst_gen; 20708 case CallModifierNeverTail: 20709 ir_add_error(ira, source_instr, 20710 buf_sprintf("unable to perform 'never_tail' call at compile-time")); 20711 return ira->codegen->invalid_inst_gen; 20712 } 20713 } 20714 20715 IrInstGen *first_arg_ptr = nullptr; 20716 IrInst *first_arg_ptr_src = nullptr; 20717 ZigFn *fn = nullptr; 20718 if (instr_is_comptime(fn_ref)) { 20719 if (fn_ref->value->type->id == ZigTypeIdBoundFn) { 20720 assert(fn_ref->value->special == ConstValSpecialStatic); 20721 fn = fn_ref->value->data.x_bound_fn.fn; 20722 first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg; 20723 first_arg_ptr_src = fn_ref->value->data.x_bound_fn.first_arg_src; 20724 if (type_is_invalid(first_arg_ptr->value->type)) 20725 return ira->codegen->invalid_inst_gen; 20726 } else { 20727 fn = ir_resolve_fn(ira, fn_ref); 20728 } 20729 } 20730 20731 // Some modifiers require the callee to be comptime-known 20732 switch (modifier) { 20733 case CallModifierCompileTime: 20734 case CallModifierAlwaysInline: 20735 case CallModifierAsync: 20736 if (fn == nullptr) { 20737 ir_add_error(ira, &modifier_inst->base, 20738 buf_sprintf("the specified modifier requires a comptime-known function")); 20739 return ira->codegen->invalid_inst_gen; 20740 } 20741 ZIG_FALLTHROUGH; 20742 default: 20743 break; 20744 } 20745 20746 ZigType *fn_type = (fn != nullptr) ? fn->type_entry : fn_ref->value->type; 20747 20748 TypeStructField *stack_field = find_struct_type_field(options->value->type, buf_create_from_str("stack")); 20749 ir_assert(stack_field != nullptr, source_instr); 20750 IrInstGen *opt_stack = ir_analyze_struct_value_field_value(ira, source_instr, options, stack_field); 20751 if (type_is_invalid(opt_stack->value->type)) 20752 return ira->codegen->invalid_inst_gen; 20753 20754 IrInstGen *stack_is_non_null_inst = ir_analyze_test_non_null(ira, source_instr, opt_stack); 20755 bool stack_is_non_null; 20756 if (!ir_resolve_bool(ira, stack_is_non_null_inst, &stack_is_non_null)) 20757 return ira->codegen->invalid_inst_gen; 20758 20759 IrInstGen *stack = nullptr; 20760 IrInst *stack_src = nullptr; 20761 if (stack_is_non_null) { 20762 stack = ir_analyze_optional_value_payload_value(ira, source_instr, opt_stack, false); 20763 if (type_is_invalid(stack->value->type)) 20764 return ira->codegen->invalid_inst_gen; 20765 stack_src = &stack->base; 20766 } 20767 20768 return ir_analyze_fn_call(ira, source_instr, fn, fn_type, fn_ref, first_arg_ptr, first_arg_ptr_src, 20769 modifier, stack, stack_src, false, args_ptr, args_len, nullptr, result_loc); 20770 } 20771 20772 static IrInstGen *ir_analyze_async_call_extra(IrAnalyze *ira, IrInst* source_instr, CallModifier modifier, 20773 IrInstSrc *pass1_fn_ref, IrInstSrc *ret_ptr, IrInstSrc *new_stack, IrInstGen **args_ptr, size_t args_len, ResultLoc *result_loc) 20774 { 20775 IrInstGen *fn_ref = pass1_fn_ref->child; 20776 if (type_is_invalid(fn_ref->value->type)) 20777 return ira->codegen->invalid_inst_gen; 20778 20779 if (ir_should_inline(ira->old_irb.exec, source_instr->scope)) { 20780 ir_add_error(ira, source_instr, buf_sprintf("TODO: comptime @asyncCall")); 20781 return ira->codegen->invalid_inst_gen; 20782 } 20783 20784 IrInstGen *first_arg_ptr = nullptr; 20785 IrInst *first_arg_ptr_src = nullptr; 20786 ZigFn *fn = nullptr; 20787 if (instr_is_comptime(fn_ref)) { 20788 if (fn_ref->value->type->id == ZigTypeIdBoundFn) { 20789 assert(fn_ref->value->special == ConstValSpecialStatic); 20790 fn = fn_ref->value->data.x_bound_fn.fn; 20791 first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg; 20792 first_arg_ptr_src = fn_ref->value->data.x_bound_fn.first_arg_src; 20793 if (type_is_invalid(first_arg_ptr->value->type)) 20794 return ira->codegen->invalid_inst_gen; 20795 } else { 20796 fn = ir_resolve_fn(ira, fn_ref); 20797 } 20798 } 20799 20800 IrInstGen *ret_ptr_uncasted = nullptr; 20801 if (ret_ptr != nullptr) { 20802 ret_ptr_uncasted = ret_ptr->child; 20803 if (type_is_invalid(ret_ptr_uncasted->value->type)) 20804 return ira->codegen->invalid_inst_gen; 20805 } 20806 20807 ZigType *fn_type = (fn != nullptr) ? fn->type_entry : fn_ref->value->type; 20808 IrInstGen *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack->child, 20809 &new_stack->base, true, fn); 20810 if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) 20811 return ira->codegen->invalid_inst_gen; 20812 20813 return ir_analyze_fn_call(ira, source_instr, fn, fn_type, fn_ref, first_arg_ptr, first_arg_ptr_src, 20814 modifier, casted_new_stack, &new_stack->base, true, args_ptr, args_len, ret_ptr_uncasted, result_loc); 20815 } 20816 20817 static bool ir_extract_tuple_call_args(IrAnalyze *ira, IrInst *source_instr, IrInstGen *args, IrInstGen ***args_ptr, size_t *args_len) { 20818 ZigType *args_type = args->value->type; 20819 if (type_is_invalid(args_type)) 20820 return false; 20821 20822 if (args_type->id != ZigTypeIdStruct) { 20823 ir_add_error(ira, &args->base, 20824 buf_sprintf("expected tuple or struct, found '%s'", buf_ptr(&args_type->name))); 20825 return false; 20826 } 20827 20828 if (is_tuple(args_type)) { 20829 *args_len = args_type->data.structure.src_field_count; 20830 *args_ptr = heap::c_allocator.allocate<IrInstGen *>(*args_len); 20831 for (size_t i = 0; i < *args_len; i += 1) { 20832 TypeStructField *arg_field = args_type->data.structure.fields[i]; 20833 (*args_ptr)[i] = ir_analyze_struct_value_field_value(ira, source_instr, args, arg_field); 20834 if (type_is_invalid((*args_ptr)[i]->value->type)) 20835 return false; 20836 } 20837 } else { 20838 ir_add_error(ira, &args->base, buf_sprintf("TODO: struct args")); 20839 return false; 20840 } 20841 return true; 20842 } 20843 20844 static IrInstGen *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstSrcCallExtra *instruction) { 20845 IrInstGen *args = instruction->args->child; 20846 IrInstGen **args_ptr = nullptr; 20847 size_t args_len = 0; 20848 if (!ir_extract_tuple_call_args(ira, &instruction->base.base, args, &args_ptr, &args_len)) { 20849 return ira->codegen->invalid_inst_gen; 20850 } 20851 20852 IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options, 20853 instruction->fn_ref, args_ptr, args_len, instruction->result_loc); 20854 heap::c_allocator.deallocate(args_ptr, args_len); 20855 return result; 20856 } 20857 20858 static IrInstGen *ir_analyze_instruction_async_call_extra(IrAnalyze *ira, IrInstSrcAsyncCallExtra *instruction) { 20859 IrInstGen *args = instruction->args->child; 20860 IrInstGen **args_ptr = nullptr; 20861 size_t args_len = 0; 20862 if (!ir_extract_tuple_call_args(ira, &instruction->base.base, args, &args_ptr, &args_len)) { 20863 return ira->codegen->invalid_inst_gen; 20864 } 20865 20866 IrInstGen *result = ir_analyze_async_call_extra(ira, &instruction->base.base, instruction->modifier, 20867 instruction->fn_ref, instruction->ret_ptr, instruction->new_stack, args_ptr, args_len, instruction->result_loc); 20868 heap::c_allocator.deallocate(args_ptr, args_len); 20869 return result; 20870 } 20871 20872 static IrInstGen *ir_analyze_instruction_call_args(IrAnalyze *ira, IrInstSrcCallArgs *instruction) { 20873 IrInstGen **args_ptr = heap::c_allocator.allocate<IrInstGen *>(instruction->args_len); 20874 for (size_t i = 0; i < instruction->args_len; i += 1) { 20875 args_ptr[i] = instruction->args_ptr[i]->child; 20876 if (type_is_invalid(args_ptr[i]->value->type)) 20877 return ira->codegen->invalid_inst_gen; 20878 } 20879 20880 IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options, 20881 instruction->fn_ref, args_ptr, instruction->args_len, instruction->result_loc); 20882 heap::c_allocator.deallocate(args_ptr, instruction->args_len); 20883 return result; 20884 } 20885 20886 static IrInstGen *ir_analyze_instruction_call(IrAnalyze *ira, IrInstSrcCall *call_instruction) { 20887 IrInstGen *fn_ref = call_instruction->fn_ref->child; 20888 if (type_is_invalid(fn_ref->value->type)) 20889 return ira->codegen->invalid_inst_gen; 20890 20891 bool is_comptime = (call_instruction->modifier == CallModifierCompileTime) || 20892 ir_should_inline(ira->old_irb.exec, call_instruction->base.base.scope); 20893 CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; 20894 20895 if (is_comptime || instr_is_comptime(fn_ref)) { 20896 if (fn_ref->value->type->id == ZigTypeIdMetaType) { 20897 ZigType *ty = ir_resolve_type(ira, fn_ref); 20898 if (ty == nullptr) 20899 return ira->codegen->invalid_inst_gen; 20900 ErrorMsg *msg = ir_add_error(ira, &fn_ref->base, 20901 buf_sprintf("type '%s' not a function", buf_ptr(&ty->name))); 20902 add_error_note(ira->codegen, msg, call_instruction->base.base.source_node, 20903 buf_sprintf("use @as builtin for type coercion")); 20904 return ira->codegen->invalid_inst_gen; 20905 } else if (fn_ref->value->type->id == ZigTypeIdFn) { 20906 ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref); 20907 ZigType *fn_type = fn_table_entry ? fn_table_entry->type_entry : fn_ref->value->type; 20908 CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; 20909 return ir_analyze_fn_call_src(ira, call_instruction, fn_table_entry, fn_type, 20910 fn_ref, nullptr, nullptr, modifier); 20911 } else if (fn_ref->value->type->id == ZigTypeIdBoundFn) { 20912 assert(fn_ref->value->special == ConstValSpecialStatic); 20913 ZigFn *fn_table_entry = fn_ref->value->data.x_bound_fn.fn; 20914 IrInstGen *first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg; 20915 IrInst *first_arg_ptr_src = fn_ref->value->data.x_bound_fn.first_arg_src; 20916 CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; 20917 return ir_analyze_fn_call_src(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, 20918 fn_ref, first_arg_ptr, first_arg_ptr_src, modifier); 20919 } else { 20920 ir_add_error(ira, &fn_ref->base, 20921 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value->type->name))); 20922 return ira->codegen->invalid_inst_gen; 20923 } 20924 } 20925 20926 if (fn_ref->value->type->id == ZigTypeIdFn) { 20927 return ir_analyze_fn_call_src(ira, call_instruction, nullptr, fn_ref->value->type, 20928 fn_ref, nullptr, nullptr, modifier); 20929 } else { 20930 ir_add_error(ira, &fn_ref->base, 20931 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value->type->name))); 20932 return ira->codegen->invalid_inst_gen; 20933 } 20934 } 20935 20936 // out_val->type must be the type to read the pointer as 20937 // if the type is different than the actual type then it does a comptime byte reinterpretation 20938 static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 20939 ZigValue *out_val, ZigValue *ptr_val) 20940 { 20941 Error err; 20942 assert(out_val->type != nullptr); 20943 20944 ZigValue *pointee = const_ptr_pointee_unchecked(codegen, ptr_val); 20945 src_assert(pointee->type != nullptr, source_node); 20946 20947 if ((err = type_resolve(codegen, pointee->type, ResolveStatusSizeKnown))) 20948 return ErrorSemanticAnalyzeFail; 20949 if ((err = type_resolve(codegen, out_val->type, ResolveStatusSizeKnown))) 20950 return ErrorSemanticAnalyzeFail; 20951 20952 size_t src_size = type_size(codegen, pointee->type); 20953 size_t dst_size = type_size(codegen, out_val->type); 20954 20955 if (dst_size <= src_size) { 20956 if (src_size == dst_size && types_have_same_zig_comptime_repr(codegen, out_val->type, pointee->type)) { 20957 copy_const_val(codegen, out_val, pointee); 20958 return ErrorNone; 20959 } 20960 Buf buf = BUF_INIT; 20961 buf_resize(&buf, src_size); 20962 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf), pointee); 20963 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 20964 return err; 20965 buf_deinit(&buf); 20966 return ErrorNone; 20967 } 20968 20969 switch (ptr_val->data.x_ptr.special) { 20970 case ConstPtrSpecialInvalid: 20971 zig_unreachable(); 20972 case ConstPtrSpecialNull: 20973 if (dst_size == 0) 20974 return ErrorNone; 20975 opt_ir_add_error_node(ira, codegen, source_node, 20976 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from null pointer", 20977 dst_size)); 20978 return ErrorSemanticAnalyzeFail; 20979 case ConstPtrSpecialRef: { 20980 opt_ir_add_error_node(ira, codegen, source_node, 20981 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from pointer to %s which is %" ZIG_PRI_usize " bytes", 20982 dst_size, buf_ptr(&pointee->type->name), src_size)); 20983 return ErrorSemanticAnalyzeFail; 20984 } 20985 case ConstPtrSpecialSubArray: { 20986 ZigValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val; 20987 assert(array_val->type->id == ZigTypeIdArray); 20988 if (array_val->data.x_array.special != ConstArraySpecialNone) 20989 zig_panic("TODO"); 20990 if (dst_size > src_size) { 20991 size_t elem_index = ptr_val->data.x_ptr.data.base_array.elem_index; 20992 opt_ir_add_error_node(ira, codegen, source_node, 20993 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from %s at index %" ZIG_PRI_usize " which is %" ZIG_PRI_usize " bytes", 20994 dst_size, buf_ptr(&array_val->type->name), elem_index, src_size)); 20995 return ErrorSemanticAnalyzeFail; 20996 } 20997 size_t elem_size = src_size; 20998 size_t elem_count = (dst_size % elem_size == 0) ? (dst_size / elem_size) : (dst_size / elem_size + 1); 20999 Buf buf = BUF_INIT; 21000 buf_resize(&buf, elem_count * elem_size); 21001 for (size_t i = 0; i < elem_count; i += 1) { 21002 ZigValue *elem_val = &array_val->data.x_array.data.s_none.elements[i]; 21003 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val); 21004 } 21005 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 21006 return err; 21007 buf_deinit(&buf); 21008 return ErrorNone; 21009 } 21010 case ConstPtrSpecialBaseArray: { 21011 ZigValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val; 21012 assert(array_val->type->id == ZigTypeIdArray); 21013 if (array_val->data.x_array.special != ConstArraySpecialNone) 21014 zig_panic("TODO"); 21015 size_t elem_size = src_size; 21016 size_t elem_index = ptr_val->data.x_ptr.data.base_array.elem_index; 21017 src_size = elem_size * (array_val->type->data.array.len - elem_index); 21018 if (dst_size > src_size) { 21019 opt_ir_add_error_node(ira, codegen, source_node, 21020 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from %s at index %" ZIG_PRI_usize " which is %" ZIG_PRI_usize " bytes", 21021 dst_size, buf_ptr(&array_val->type->name), elem_index, src_size)); 21022 return ErrorSemanticAnalyzeFail; 21023 } 21024 size_t elem_count = (dst_size % elem_size == 0) ? (dst_size / elem_size) : (dst_size / elem_size + 1); 21025 Buf buf = BUF_INIT; 21026 buf_resize(&buf, elem_count * elem_size); 21027 for (size_t i = 0; i < elem_count; i += 1) { 21028 ZigValue *elem_val = &array_val->data.x_array.data.s_none.elements[elem_index + i]; 21029 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val); 21030 } 21031 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 21032 return err; 21033 buf_deinit(&buf); 21034 return ErrorNone; 21035 } 21036 case ConstPtrSpecialBaseStruct: 21037 case ConstPtrSpecialBaseErrorUnionCode: 21038 case ConstPtrSpecialBaseErrorUnionPayload: 21039 case ConstPtrSpecialBaseOptionalPayload: 21040 case ConstPtrSpecialDiscard: 21041 case ConstPtrSpecialHardCodedAddr: 21042 case ConstPtrSpecialFunction: 21043 zig_panic("TODO"); 21044 } 21045 zig_unreachable(); 21046 } 21047 21048 static IrInstGen *ir_analyze_optional_type(IrAnalyze *ira, IrInstSrcUnOp *instruction) { 21049 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); 21050 result->value->special = ConstValSpecialLazy; 21051 21052 LazyValueOptType *lazy_opt_type = heap::c_allocator.create<LazyValueOptType>(); 21053 lazy_opt_type->ira = ira; ira_ref(ira); 21054 result->value->data.x_lazy = &lazy_opt_type->base; 21055 lazy_opt_type->base.id = LazyValueIdOptType; 21056 21057 lazy_opt_type->payload_type = instruction->value->child; 21058 if (ir_resolve_type_lazy(ira, lazy_opt_type->payload_type) == nullptr) 21059 return ira->codegen->invalid_inst_gen; 21060 21061 return result; 21062 } 21063 21064 static ErrorMsg *ir_eval_negation_scalar(IrAnalyze *ira, IrInst* source_instr, ZigType *scalar_type, 21065 ZigValue *operand_val, ZigValue *scalar_out_val, bool is_wrap_op) 21066 { 21067 bool is_float = (scalar_type->id == ZigTypeIdFloat || scalar_type->id == ZigTypeIdComptimeFloat); 21068 21069 bool ok_type = ((scalar_type->id == ZigTypeIdInt && scalar_type->data.integral.is_signed) || 21070 scalar_type->id == ZigTypeIdComptimeInt || (is_float && !is_wrap_op)); 21071 21072 if (!ok_type) { 21073 const char *fmt = is_wrap_op ? "invalid wrapping negation type: '%s'" : "invalid negation type: '%s'"; 21074 return ir_add_error(ira, source_instr, buf_sprintf(fmt, buf_ptr(&scalar_type->name))); 21075 } 21076 21077 if (is_float) { 21078 float_negate(scalar_out_val, operand_val); 21079 } else if (is_wrap_op) { 21080 bigint_negate_wrap(&scalar_out_val->data.x_bigint, &operand_val->data.x_bigint, 21081 scalar_type->data.integral.bit_count); 21082 } else { 21083 bigint_negate(&scalar_out_val->data.x_bigint, &operand_val->data.x_bigint); 21084 } 21085 21086 scalar_out_val->type = scalar_type; 21087 scalar_out_val->special = ConstValSpecialStatic; 21088 21089 if (is_wrap_op || is_float || scalar_type->id == ZigTypeIdComptimeInt) { 21090 return nullptr; 21091 } 21092 21093 if (!bigint_fits_in_bits(&scalar_out_val->data.x_bigint, scalar_type->data.integral.bit_count, true)) { 21094 return ir_add_error(ira, source_instr, buf_sprintf("negation caused overflow")); 21095 } 21096 return nullptr; 21097 } 21098 21099 static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction) { 21100 IrInstGen *value = instruction->value->child; 21101 ZigType *expr_type = value->value->type; 21102 if (type_is_invalid(expr_type)) 21103 return ira->codegen->invalid_inst_gen; 21104 21105 bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap); 21106 21107 switch (expr_type->id) { 21108 case ZigTypeIdComptimeInt: 21109 case ZigTypeIdFloat: 21110 case ZigTypeIdComptimeFloat: 21111 case ZigTypeIdVector: 21112 break; 21113 case ZigTypeIdInt: 21114 if (is_wrap_op || expr_type->data.integral.is_signed) 21115 break; 21116 ZIG_FALLTHROUGH; 21117 default: 21118 ir_add_error(ira, &instruction->base.base, 21119 buf_sprintf("negation of type '%s'", buf_ptr(&expr_type->name))); 21120 return ira->codegen->invalid_inst_gen; 21121 } 21122 21123 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; 21124 21125 if (instr_is_comptime(value)) { 21126 ZigValue *operand_val = ir_resolve_const(ira, value, UndefBad); 21127 if (!operand_val) 21128 return ira->codegen->invalid_inst_gen; 21129 21130 IrInstGen *result_instruction = ir_const(ira, &instruction->base.base, expr_type); 21131 ZigValue *out_val = result_instruction->value; 21132 if (expr_type->id == ZigTypeIdVector) { 21133 expand_undef_array(ira->codegen, operand_val); 21134 out_val->special = ConstValSpecialUndef; 21135 expand_undef_array(ira->codegen, out_val); 21136 size_t len = expr_type->data.vector.len; 21137 for (size_t i = 0; i < len; i += 1) { 21138 ZigValue *scalar_operand_val = &operand_val->data.x_array.data.s_none.elements[i]; 21139 ZigValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 21140 assert(scalar_operand_val->type == scalar_type); 21141 assert(scalar_out_val->type == scalar_type); 21142 ErrorMsg *msg = ir_eval_negation_scalar(ira, &instruction->base.base, scalar_type, 21143 scalar_operand_val, scalar_out_val, is_wrap_op); 21144 if (msg != nullptr) { 21145 add_error_note(ira->codegen, msg, instruction->base.base.source_node, 21146 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 21147 return ira->codegen->invalid_inst_gen; 21148 } 21149 } 21150 out_val->type = expr_type; 21151 out_val->special = ConstValSpecialStatic; 21152 } else { 21153 if (ir_eval_negation_scalar(ira, &instruction->base.base, scalar_type, operand_val, out_val, 21154 is_wrap_op) != nullptr) 21155 { 21156 return ira->codegen->invalid_inst_gen; 21157 } 21158 } 21159 return result_instruction; 21160 } 21161 21162 if (is_wrap_op) { 21163 return ir_build_negation_wrapping(ira, &instruction->base.base, value, expr_type); 21164 } else { 21165 return ir_build_negation(ira, &instruction->base.base, value, expr_type); 21166 } 21167 } 21168 21169 static IrInstGen *ir_analyze_bin_not(IrAnalyze *ira, IrInstSrcUnOp *instruction) { 21170 IrInstGen *value = instruction->value->child; 21171 ZigType *expr_type = value->value->type; 21172 if (type_is_invalid(expr_type)) 21173 return ira->codegen->invalid_inst_gen; 21174 21175 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? 21176 expr_type->data.vector.elem_type : expr_type; 21177 21178 if (scalar_type->id != ZigTypeIdInt) { 21179 ir_add_error(ira, &instruction->base.base, 21180 buf_sprintf("unable to perform binary not operation on type '%s'", buf_ptr(&expr_type->name))); 21181 return ira->codegen->invalid_inst_gen; 21182 } 21183 21184 if (instr_is_comptime(value)) { 21185 ZigValue *expr_val = ir_resolve_const(ira, value, UndefBad); 21186 if (expr_val == nullptr) 21187 return ira->codegen->invalid_inst_gen; 21188 21189 IrInstGen *result = ir_const(ira, &instruction->base.base, expr_type); 21190 21191 if (expr_type->id == ZigTypeIdVector) { 21192 expand_undef_array(ira->codegen, expr_val); 21193 result->value->special = ConstValSpecialUndef; 21194 expand_undef_array(ira->codegen, result->value); 21195 21196 for (size_t i = 0; i < expr_type->data.vector.len; i++) { 21197 ZigValue *src_val = &expr_val->data.x_array.data.s_none.elements[i]; 21198 ZigValue *dst_val = &result->value->data.x_array.data.s_none.elements[i]; 21199 21200 dst_val->type = scalar_type; 21201 dst_val->special = ConstValSpecialStatic; 21202 bigint_not(&dst_val->data.x_bigint, &src_val->data.x_bigint, 21203 scalar_type->data.integral.bit_count, scalar_type->data.integral.is_signed); 21204 } 21205 } else { 21206 bigint_not(&result->value->data.x_bigint, &expr_val->data.x_bigint, 21207 scalar_type->data.integral.bit_count, scalar_type->data.integral.is_signed); 21208 } 21209 21210 return result; 21211 } 21212 21213 return ir_build_binary_not(ira, &instruction->base.base, value, expr_type); 21214 } 21215 21216 static IrInstGen *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstSrcUnOp *instruction) { 21217 IrUnOp op_id = instruction->op_id; 21218 switch (op_id) { 21219 case IrUnOpInvalid: 21220 zig_unreachable(); 21221 case IrUnOpBinNot: 21222 return ir_analyze_bin_not(ira, instruction); 21223 case IrUnOpNegation: 21224 case IrUnOpNegationWrap: 21225 return ir_analyze_negation(ira, instruction); 21226 case IrUnOpDereference: { 21227 IrInstGen *ptr = instruction->value->child; 21228 if (type_is_invalid(ptr->value->type)) 21229 return ira->codegen->invalid_inst_gen; 21230 ZigType *ptr_type = ptr->value->type; 21231 if (ptr_type->id == ZigTypeIdPointer && ptr_type->data.pointer.ptr_len == PtrLenUnknown) { 21232 ir_add_error_node(ira, instruction->base.base.source_node, 21233 buf_sprintf("index syntax required for unknown-length pointer type '%s'", 21234 buf_ptr(&ptr_type->name))); 21235 return ira->codegen->invalid_inst_gen; 21236 } 21237 21238 IrInstGen *result = ir_get_deref(ira, &instruction->base.base, ptr, instruction->result_loc); 21239 if (type_is_invalid(result->value->type)) 21240 return ira->codegen->invalid_inst_gen; 21241 21242 // If the result needs to be an lvalue, type check it 21243 if (instruction->lval != LValNone && result->value->type->id != ZigTypeIdPointer) { 21244 ir_add_error(ira, &instruction->base.base, 21245 buf_sprintf("attempt to dereference non-pointer type '%s'", buf_ptr(&result->value->type->name))); 21246 return ira->codegen->invalid_inst_gen; 21247 } 21248 21249 return result; 21250 } 21251 case IrUnOpOptional: 21252 return ir_analyze_optional_type(ira, instruction); 21253 } 21254 zig_unreachable(); 21255 } 21256 21257 static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) { 21258 IrBasicBlockSrc *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index); 21259 if (old_bb->in_resume_stack) return; 21260 ira->resume_stack.append(pos); 21261 old_bb->in_resume_stack = true; 21262 } 21263 21264 static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlockSrc *old_bb) { 21265 if (ira->resume_stack.length != 0) { 21266 ir_push_resume(ira, {old_bb->index, 0}); 21267 } 21268 } 21269 21270 static IrInstGen *ir_analyze_instruction_br(IrAnalyze *ira, IrInstSrcBr *br_instruction) { 21271 IrBasicBlockSrc *old_dest_block = br_instruction->dest_block; 21272 21273 bool is_comptime; 21274 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) 21275 return ir_unreach_error(ira); 21276 21277 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) 21278 return ir_inline_bb(ira, &br_instruction->base.base, old_dest_block); 21279 21280 IrBasicBlockGen *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base.base); 21281 if (new_bb == nullptr) 21282 return ir_unreach_error(ira); 21283 21284 ir_push_resume_block(ira, old_dest_block); 21285 21286 IrInstGen *result = ir_build_br_gen(ira, &br_instruction->base.base, new_bb); 21287 return ir_finish_anal(ira, result); 21288 } 21289 21290 static IrInstGen *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstSrcCondBr *cond_br_instruction) { 21291 IrInstGen *condition = cond_br_instruction->condition->child; 21292 if (type_is_invalid(condition->value->type)) 21293 return ir_unreach_error(ira); 21294 21295 bool is_comptime; 21296 if (!ir_resolve_comptime(ira, cond_br_instruction->is_comptime->child, &is_comptime)) 21297 return ir_unreach_error(ira); 21298 21299 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 21300 IrInstGen *casted_condition = ir_implicit_cast(ira, condition, bool_type); 21301 if (type_is_invalid(casted_condition->value->type)) 21302 return ir_unreach_error(ira); 21303 21304 if (is_comptime || instr_is_comptime(casted_condition)) { 21305 bool cond_is_true; 21306 if (!ir_resolve_bool(ira, casted_condition, &cond_is_true)) 21307 return ir_unreach_error(ira); 21308 21309 IrBasicBlockSrc *old_dest_block = cond_is_true ? 21310 cond_br_instruction->then_block : cond_br_instruction->else_block; 21311 21312 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) 21313 return ir_inline_bb(ira, &cond_br_instruction->base.base, old_dest_block); 21314 21315 IrBasicBlockGen *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base.base); 21316 if (new_dest_block == nullptr) 21317 return ir_unreach_error(ira); 21318 21319 ir_push_resume_block(ira, old_dest_block); 21320 21321 IrInstGen *result = ir_build_br_gen(ira, &cond_br_instruction->base.base, new_dest_block); 21322 return ir_finish_anal(ira, result); 21323 } 21324 21325 assert(cond_br_instruction->then_block != cond_br_instruction->else_block); 21326 IrBasicBlockGen *new_then_block = ir_get_new_bb_runtime(ira, cond_br_instruction->then_block, &cond_br_instruction->base.base); 21327 if (new_then_block == nullptr) 21328 return ir_unreach_error(ira); 21329 21330 IrBasicBlockGen *new_else_block = ir_get_new_bb_runtime(ira, cond_br_instruction->else_block, &cond_br_instruction->base.base); 21331 if (new_else_block == nullptr) 21332 return ir_unreach_error(ira); 21333 21334 ir_push_resume_block(ira, cond_br_instruction->else_block); 21335 ir_push_resume_block(ira, cond_br_instruction->then_block); 21336 21337 IrInstGen *result = ir_build_cond_br_gen(ira, &cond_br_instruction->base.base, 21338 casted_condition, new_then_block, new_else_block); 21339 return ir_finish_anal(ira, result); 21340 } 21341 21342 static IrInstGen *ir_analyze_instruction_unreachable(IrAnalyze *ira, 21343 IrInstSrcUnreachable *unreachable_instruction) 21344 { 21345 IrInstGen *result = ir_build_unreachable_gen(ira, &unreachable_instruction->base.base); 21346 return ir_finish_anal(ira, result); 21347 } 21348 21349 static IrInstGen *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstSrcPhi *phi_instruction) { 21350 Error err; 21351 21352 if (ira->const_predecessor_bb) { 21353 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 21354 IrBasicBlockSrc *predecessor = phi_instruction->incoming_blocks[i]; 21355 if (predecessor != ira->const_predecessor_bb) 21356 continue; 21357 IrInstGen *value = phi_instruction->incoming_values[i]->child; 21358 assert(value->value->type); 21359 if (type_is_invalid(value->value->type)) 21360 return ira->codegen->invalid_inst_gen; 21361 21362 if (value->value->special != ConstValSpecialRuntime) { 21363 IrInstGen *result = ir_const(ira, &phi_instruction->base.base, nullptr); 21364 copy_const_val(ira->codegen, result->value, value->value); 21365 return result; 21366 } else { 21367 return value; 21368 } 21369 } 21370 zig_unreachable(); 21371 } 21372 21373 ResultLocPeerParent *peer_parent = phi_instruction->peer_parent; 21374 if (peer_parent != nullptr && !peer_parent->skipped && !peer_parent->done_resuming && 21375 peer_parent->peers.length >= 2) 21376 { 21377 if (peer_parent->resolved_type == nullptr) { 21378 IrInstGen **instructions = heap::c_allocator.allocate<IrInstGen *>(peer_parent->peers.length); 21379 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 21380 ResultLocPeer *this_peer = peer_parent->peers.at(i); 21381 21382 IrInstGen *gen_instruction = this_peer->base.gen_instruction; 21383 if (gen_instruction == nullptr) { 21384 // unreachable instructions will cause implicit_elem_type to be null 21385 if (this_peer->base.implicit_elem_type == nullptr) { 21386 instructions[i] = ir_const_unreachable(ira, &this_peer->base.source_instruction->base); 21387 } else { 21388 instructions[i] = ir_const(ira, &this_peer->base.source_instruction->base, 21389 this_peer->base.implicit_elem_type); 21390 instructions[i]->value->special = ConstValSpecialRuntime; 21391 } 21392 } else { 21393 instructions[i] = gen_instruction; 21394 } 21395 21396 } 21397 ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base.base, peer_parent->parent); 21398 peer_parent->resolved_type = ir_resolve_peer_types(ira, 21399 peer_parent->base.source_instruction->base.source_node, expected_type, instructions, 21400 peer_parent->peers.length); 21401 if (type_is_invalid(peer_parent->resolved_type)) 21402 return ira->codegen->invalid_inst_gen; 21403 21404 // the logic below assumes there are no instructions in the new current basic block yet 21405 ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base.base); 21406 21407 // In case resolving the parent activates a suspend, do it now 21408 IrInstGen *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base.base, peer_parent->parent, 21409 peer_parent->resolved_type, nullptr, false, true); 21410 if (parent_result_loc != nullptr && 21411 (type_is_invalid(parent_result_loc->value->type) || parent_result_loc->value->type->id == ZigTypeIdUnreachable)) 21412 { 21413 return parent_result_loc; 21414 } 21415 // If the above code generated any instructions in the current basic block, we need 21416 // to move them to the peer parent predecessor. 21417 ZigList<IrInstGen *> instrs_to_move = {}; 21418 while (ira->new_irb.current_basic_block->instruction_list.length != 0) { 21419 instrs_to_move.append(ira->new_irb.current_basic_block->instruction_list.pop()); 21420 } 21421 if (instrs_to_move.length != 0) { 21422 IrBasicBlockGen *predecessor = peer_parent->base.source_instruction->child->owner_bb; 21423 IrInstGen *branch_instruction = predecessor->instruction_list.pop(); 21424 ir_assert(branch_instruction->value->type->id == ZigTypeIdUnreachable, &phi_instruction->base.base); 21425 while (instrs_to_move.length != 0) { 21426 predecessor->instruction_list.append(instrs_to_move.pop()); 21427 } 21428 predecessor->instruction_list.append(branch_instruction); 21429 } 21430 } 21431 21432 IrSuspendPosition suspend_pos; 21433 ira_suspend(ira, &phi_instruction->base.base, nullptr, &suspend_pos); 21434 ir_push_resume(ira, suspend_pos); 21435 21436 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 21437 ResultLocPeer *opposite_peer = peer_parent->peers.at(peer_parent->peers.length - i - 1); 21438 if (opposite_peer->base.implicit_elem_type != nullptr && 21439 opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) 21440 { 21441 ir_push_resume(ira, opposite_peer->suspend_pos); 21442 } 21443 } 21444 21445 peer_parent->done_resuming = true; 21446 return ira_resume(ira); 21447 } 21448 21449 ZigList<IrBasicBlockGen*> new_incoming_blocks = {0}; 21450 ZigList<IrInstGen*> new_incoming_values = {0}; 21451 21452 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 21453 IrBasicBlockSrc *predecessor = phi_instruction->incoming_blocks[i]; 21454 if (predecessor->ref_count == 0) 21455 continue; 21456 21457 21458 IrInstSrc *old_value = phi_instruction->incoming_values[i]; 21459 assert(old_value); 21460 IrInstGen *new_value = old_value->child; 21461 if (!new_value || new_value->value->type->id == ZigTypeIdUnreachable || predecessor->child == nullptr) 21462 continue; 21463 21464 if (type_is_invalid(new_value->value->type)) 21465 return ira->codegen->invalid_inst_gen; 21466 21467 21468 assert(predecessor->child); 21469 new_incoming_blocks.append(predecessor->child); 21470 new_incoming_values.append(new_value); 21471 } 21472 21473 if (new_incoming_blocks.length == 0) { 21474 IrInstGen *result = ir_build_unreachable_gen(ira, &phi_instruction->base.base); 21475 return ir_finish_anal(ira, result); 21476 } 21477 21478 if (new_incoming_blocks.length == 1) { 21479 return new_incoming_values.at(0); 21480 } 21481 21482 ZigType *resolved_type = nullptr; 21483 if (peer_parent != nullptr) { 21484 bool peer_parent_has_type; 21485 if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) 21486 return ira->codegen->invalid_inst_gen; 21487 if (peer_parent_has_type) { 21488 if (peer_parent->parent->id == ResultLocIdReturn) { 21489 resolved_type = ira->explicit_return_type; 21490 } else if (peer_parent->parent->id == ResultLocIdCast) { 21491 resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child); 21492 } else if (peer_parent->parent->resolved_loc) { 21493 ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value->type; 21494 ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base.base); 21495 resolved_type = resolved_loc_ptr_type->data.pointer.child_type; 21496 } 21497 21498 if (resolved_type != nullptr && type_is_invalid(resolved_type)) 21499 return ira->codegen->invalid_inst_gen; 21500 } 21501 } 21502 21503 if (resolved_type == nullptr) { 21504 resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.base.source_node, nullptr, 21505 new_incoming_values.items, new_incoming_values.length); 21506 if (type_is_invalid(resolved_type)) 21507 return ira->codegen->invalid_inst_gen; 21508 } 21509 21510 switch (type_has_one_possible_value(ira->codegen, resolved_type)) { 21511 case OnePossibleValueInvalid: 21512 return ira->codegen->invalid_inst_gen; 21513 case OnePossibleValueYes: 21514 return ir_const_move(ira, &phi_instruction->base.base, 21515 get_the_one_possible_value(ira->codegen, resolved_type)); 21516 case OnePossibleValueNo: 21517 break; 21518 } 21519 21520 switch (type_requires_comptime(ira->codegen, resolved_type)) { 21521 case ReqCompTimeInvalid: 21522 return ira->codegen->invalid_inst_gen; 21523 case ReqCompTimeYes: 21524 ir_add_error(ira, &phi_instruction->base.base, 21525 buf_sprintf("values of type '%s' must be comptime known", buf_ptr(&resolved_type->name))); 21526 return ira->codegen->invalid_inst_gen; 21527 case ReqCompTimeNo: 21528 break; 21529 } 21530 21531 bool all_stack_ptrs = (resolved_type->id == ZigTypeIdPointer); 21532 21533 // cast all values to the resolved type. however we can't put cast instructions in front of the phi instruction. 21534 // so we go back and insert the casts as the last instruction in the corresponding predecessor blocks, and 21535 // then make sure the branch instruction is preserved. 21536 IrBasicBlockGen *cur_bb = ira->new_irb.current_basic_block; 21537 for (size_t i = 0; i < new_incoming_values.length; i += 1) { 21538 IrInstGen *new_value = new_incoming_values.at(i); 21539 IrBasicBlockGen *predecessor = new_incoming_blocks.at(i); 21540 ir_assert(predecessor->instruction_list.length != 0, &phi_instruction->base.base); 21541 IrInstGen *branch_instruction = predecessor->instruction_list.pop(); 21542 ir_set_cursor_at_end_gen(&ira->new_irb, predecessor); 21543 IrInstGen *casted_value = ir_implicit_cast(ira, new_value, resolved_type); 21544 if (type_is_invalid(casted_value->value->type)) { 21545 return ira->codegen->invalid_inst_gen; 21546 } 21547 new_incoming_values.items[i] = casted_value; 21548 predecessor->instruction_list.append(branch_instruction); 21549 21550 if (all_stack_ptrs && (casted_value->value->special != ConstValSpecialRuntime || 21551 casted_value->value->data.rh_ptr != RuntimeHintPtrStack)) 21552 { 21553 all_stack_ptrs = false; 21554 } 21555 } 21556 ir_set_cursor_at_end_gen(&ira->new_irb, cur_bb); 21557 21558 IrInstGen *result = ir_build_phi_gen(ira, &phi_instruction->base.base, 21559 new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items, resolved_type); 21560 21561 if (all_stack_ptrs) { 21562 assert(result->value->special == ConstValSpecialRuntime); 21563 result->value->data.rh_ptr = RuntimeHintPtrStack; 21564 } 21565 21566 return result; 21567 } 21568 21569 static IrInstGen *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstSrcVarPtr *instruction) { 21570 ZigVar *var = instruction->var; 21571 IrInstGen *result = ir_get_var_ptr(ira, &instruction->base.base, var); 21572 if (instruction->crossed_fndef_scope != nullptr && !instr_is_comptime(result)) { 21573 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 21574 buf_sprintf("'%s' not accessible from inner function", var->name)); 21575 add_error_note(ira->codegen, msg, instruction->crossed_fndef_scope->base.source_node, 21576 buf_sprintf("crossed function definition here")); 21577 add_error_note(ira->codegen, msg, var->decl_node, 21578 buf_sprintf("declared here")); 21579 return ira->codegen->invalid_inst_gen; 21580 } 21581 return result; 21582 } 21583 21584 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align) { 21585 assert(ptr_type->id == ZigTypeIdPointer); 21586 return get_pointer_to_type_extra2(g, 21587 ptr_type->data.pointer.child_type, 21588 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21589 ptr_type->data.pointer.ptr_len, 21590 new_align, 21591 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 21592 ptr_type->data.pointer.allow_zero, 21593 ptr_type->data.pointer.vector_index, 21594 ptr_type->data.pointer.inferred_struct_field, 21595 ptr_type->data.pointer.sentinel); 21596 } 21597 21598 static ZigType *adjust_ptr_sentinel(CodeGen *g, ZigType *ptr_type, ZigValue *new_sentinel) { 21599 assert(ptr_type->id == ZigTypeIdPointer); 21600 return get_pointer_to_type_extra2(g, 21601 ptr_type->data.pointer.child_type, 21602 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21603 ptr_type->data.pointer.ptr_len, 21604 ptr_type->data.pointer.explicit_alignment, 21605 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 21606 ptr_type->data.pointer.allow_zero, 21607 ptr_type->data.pointer.vector_index, 21608 ptr_type->data.pointer.inferred_struct_field, 21609 new_sentinel); 21610 } 21611 21612 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) { 21613 assert(is_slice(slice_type)); 21614 ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index]->type_entry, 21615 new_align); 21616 return get_slice_type(g, ptr_type); 21617 } 21618 21619 static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) { 21620 assert(ptr_type->id == ZigTypeIdPointer); 21621 return get_pointer_to_type_extra2(g, 21622 ptr_type->data.pointer.child_type, 21623 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21624 ptr_len, 21625 ptr_type->data.pointer.explicit_alignment, 21626 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 21627 ptr_type->data.pointer.allow_zero, 21628 ptr_type->data.pointer.vector_index, 21629 ptr_type->data.pointer.inferred_struct_field, 21630 (ptr_len != PtrLenUnknown) ? nullptr : ptr_type->data.pointer.sentinel); 21631 } 21632 21633 static ZigType *adjust_ptr_allow_zero(CodeGen *g, ZigType *ptr_type, bool allow_zero) { 21634 assert(ptr_type->id == ZigTypeIdPointer); 21635 return get_pointer_to_type_extra2(g, 21636 ptr_type->data.pointer.child_type, 21637 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21638 ptr_type->data.pointer.ptr_len, 21639 ptr_type->data.pointer.explicit_alignment, 21640 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 21641 allow_zero, 21642 ptr_type->data.pointer.vector_index, 21643 ptr_type->data.pointer.inferred_struct_field, 21644 ptr_type->data.pointer.sentinel); 21645 } 21646 21647 static ZigType *adjust_ptr_const(CodeGen *g, ZigType *ptr_type, bool is_const) { 21648 assert(ptr_type->id == ZigTypeIdPointer); 21649 return get_pointer_to_type_extra2(g, 21650 ptr_type->data.pointer.child_type, 21651 is_const, ptr_type->data.pointer.is_volatile, 21652 ptr_type->data.pointer.ptr_len, 21653 ptr_type->data.pointer.explicit_alignment, 21654 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 21655 ptr_type->data.pointer.allow_zero, 21656 ptr_type->data.pointer.vector_index, 21657 ptr_type->data.pointer.inferred_struct_field, 21658 ptr_type->data.pointer.sentinel); 21659 } 21660 21661 static Error compute_elem_align(IrAnalyze *ira, ZigType *elem_type, uint32_t base_ptr_align, 21662 uint64_t elem_index, uint32_t *result) 21663 { 21664 Error err; 21665 21666 if (base_ptr_align == 0) { 21667 *result = 0; 21668 return ErrorNone; 21669 } 21670 21671 // figure out the largest alignment possible 21672 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) 21673 return err; 21674 21675 uint64_t elem_size = type_size(ira->codegen, elem_type); 21676 uint64_t abi_align = get_abi_alignment(ira->codegen, elem_type); 21677 uint64_t ptr_align = base_ptr_align; 21678 21679 uint64_t chosen_align = abi_align; 21680 if (ptr_align >= abi_align) { 21681 while (ptr_align > abi_align) { 21682 if ((elem_index * elem_size) % ptr_align == 0) { 21683 chosen_align = ptr_align; 21684 break; 21685 } 21686 ptr_align >>= 1; 21687 } 21688 } else if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 21689 chosen_align = ptr_align; 21690 } else { 21691 // can't get here because guaranteed elem_size >= abi_align 21692 zig_unreachable(); 21693 } 21694 21695 *result = chosen_align; 21696 return ErrorNone; 21697 } 21698 21699 static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemPtr *elem_ptr_instruction) { 21700 Error err; 21701 IrInstGen *array_ptr = elem_ptr_instruction->array_ptr->child; 21702 if (type_is_invalid(array_ptr->value->type)) 21703 return ira->codegen->invalid_inst_gen; 21704 21705 IrInstGen *elem_index = elem_ptr_instruction->elem_index->child; 21706 if (type_is_invalid(elem_index->value->type)) 21707 return ira->codegen->invalid_inst_gen; 21708 21709 ZigValue *orig_array_ptr_val = array_ptr->value; 21710 21711 ZigType *ptr_type = orig_array_ptr_val->type; 21712 assert(ptr_type->id == ZigTypeIdPointer); 21713 21714 ZigType *array_type = ptr_type->data.pointer.child_type; 21715 21716 // At first return_type will be the pointer type we want to return, except with an optimistic alignment. 21717 // We will adjust return_type's alignment before returning it. 21718 ZigType *return_type; 21719 21720 if (type_is_invalid(array_type)) 21721 return ira->codegen->invalid_inst_gen; 21722 21723 if (array_type->id == ZigTypeIdPointer && 21724 array_type->data.pointer.ptr_len == PtrLenSingle && 21725 array_type->data.pointer.child_type->id == ZigTypeIdArray) 21726 { 21727 IrInstGen *ptr_value = ir_get_deref(ira, &elem_ptr_instruction->base.base, 21728 array_ptr, nullptr); 21729 if (type_is_invalid(ptr_value->value->type)) 21730 return ira->codegen->invalid_inst_gen; 21731 21732 array_type = array_type->data.pointer.child_type; 21733 ptr_type = ptr_type->data.pointer.child_type; 21734 21735 orig_array_ptr_val = ptr_value->value; 21736 } 21737 21738 if (array_type->id == ZigTypeIdArray) { 21739 if(array_type->data.array.len == 0 && array_type->data.array.sentinel == nullptr){ 21740 ir_add_error(ira, &elem_ptr_instruction->base.base, buf_sprintf("accessing a zero length array is not allowed")); 21741 return ira->codegen->invalid_inst_gen; 21742 } 21743 21744 ZigType *child_type = array_type->data.array.child_type; 21745 if (ptr_type->data.pointer.host_int_bytes == 0) { 21746 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 21747 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21748 elem_ptr_instruction->ptr_len, 21749 ptr_type->data.pointer.explicit_alignment, 0, 0, false); 21750 } else { 21751 uint64_t elem_val_scalar; 21752 if (!ir_resolve_usize(ira, elem_index, &elem_val_scalar)) 21753 return ira->codegen->invalid_inst_gen; 21754 21755 size_t bit_width = type_size_bits(ira->codegen, child_type); 21756 size_t bit_offset = bit_width * elem_val_scalar; 21757 21758 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 21759 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21760 elem_ptr_instruction->ptr_len, 21761 1, (uint32_t)bit_offset, ptr_type->data.pointer.host_int_bytes, false); 21762 } 21763 } else if (array_type->id == ZigTypeIdPointer) { 21764 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 21765 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 21766 buf_sprintf("index of single-item pointer")); 21767 return ira->codegen->invalid_inst_gen; 21768 } 21769 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len); 21770 } else if (is_slice(array_type)) { 21771 return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index]->type_entry, 21772 elem_ptr_instruction->ptr_len); 21773 } else if (array_type->id == ZigTypeIdVector) { 21774 // This depends on whether the element index is comptime, so it is computed later. 21775 return_type = nullptr; 21776 } else if (elem_ptr_instruction->init_array_type_source_node != nullptr && 21777 array_type->id == ZigTypeIdStruct && 21778 array_type->data.structure.resolve_status == ResolveStatusBeingInferred) 21779 { 21780 ZigType *usize = ira->codegen->builtin_types.entry_usize; 21781 IrInstGen *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); 21782 if (type_is_invalid(casted_elem_index->value->type)) 21783 return ira->codegen->invalid_inst_gen; 21784 ir_assert(instr_is_comptime(casted_elem_index), &elem_ptr_instruction->base.base); 21785 Buf *field_name = buf_alloc(); 21786 bigint_append_buf(field_name, &casted_elem_index->value->data.x_bigint, 10); 21787 return ir_analyze_inferred_field_ptr(ira, field_name, &elem_ptr_instruction->base.base, 21788 array_ptr, array_type); 21789 } else if (is_tuple(array_type)) { 21790 uint64_t elem_index_scalar; 21791 if (!ir_resolve_usize(ira, elem_index, &elem_index_scalar)) 21792 return ira->codegen->invalid_inst_gen; 21793 if (elem_index_scalar >= array_type->data.structure.src_field_count) { 21794 ir_add_error(ira, &elem_ptr_instruction->base.base, buf_sprintf( 21795 "field index %" ZIG_PRI_u64 " outside tuple '%s' which has %" PRIu32 " fields", 21796 elem_index_scalar, buf_ptr(&array_type->name), 21797 array_type->data.structure.src_field_count)); 21798 return ira->codegen->invalid_inst_gen; 21799 } 21800 TypeStructField *field = array_type->data.structure.fields[elem_index_scalar]; 21801 return ir_analyze_struct_field_ptr(ira, &elem_ptr_instruction->base.base, field, array_ptr, 21802 array_type, false); 21803 } else { 21804 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 21805 buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name))); 21806 return ira->codegen->invalid_inst_gen; 21807 } 21808 21809 ZigType *usize = ira->codegen->builtin_types.entry_usize; 21810 IrInstGen *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); 21811 if (type_is_invalid(casted_elem_index->value->type)) 21812 return ira->codegen->invalid_inst_gen; 21813 21814 bool safety_check_on = elem_ptr_instruction->safety_check_on; 21815 if (instr_is_comptime(casted_elem_index)) { 21816 ZigValue *index_val = ir_resolve_const(ira, casted_elem_index, UndefBad); 21817 if (index_val == nullptr) 21818 return ira->codegen->invalid_inst_gen; 21819 uint64_t index = bigint_as_u64(&index_val->data.x_bigint); 21820 21821 if (array_type->id == ZigTypeIdArray) { 21822 uint64_t array_len = array_type->data.array.len + 21823 (array_type->data.array.sentinel != nullptr); 21824 if (index >= array_len) { 21825 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 21826 buf_sprintf("index %" ZIG_PRI_u64 " outside array of size %" ZIG_PRI_u64, 21827 index, array_len)); 21828 return ira->codegen->invalid_inst_gen; 21829 } 21830 safety_check_on = false; 21831 } 21832 if (array_type->id == ZigTypeIdVector) { 21833 ZigType *elem_type = array_type->data.vector.elem_type; 21834 uint32_t host_vec_len = array_type->data.vector.len; 21835 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 21836 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21837 elem_ptr_instruction->ptr_len, 21838 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, (uint32_t)index, 21839 nullptr, nullptr); 21840 } else if (return_type->data.pointer.explicit_alignment != 0) { 21841 uint32_t chosen_align; 21842 if ((err = compute_elem_align(ira, return_type->data.pointer.child_type, 21843 return_type->data.pointer.explicit_alignment, index, &chosen_align))) 21844 { 21845 return ira->codegen->invalid_inst_gen; 21846 } 21847 return_type = adjust_ptr_align(ira->codegen, return_type, chosen_align); 21848 } 21849 21850 // TODO The `array_type->id == ZigTypeIdArray` exception here should not be an exception; 21851 // the `orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar` clause should be omitted completely. 21852 // However there are bugs to fix before this improvement can be made. 21853 if (orig_array_ptr_val->special != ConstValSpecialRuntime && 21854 orig_array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && 21855 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == ZigTypeIdArray)) 21856 { 21857 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 21858 elem_ptr_instruction->base.base.source_node, orig_array_ptr_val, UndefBad))) 21859 { 21860 return ira->codegen->invalid_inst_gen; 21861 } 21862 21863 ZigValue *array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val, 21864 elem_ptr_instruction->base.base.source_node); 21865 if (array_ptr_val == nullptr) 21866 return ira->codegen->invalid_inst_gen; 21867 21868 if (array_ptr_val->special == ConstValSpecialUndef && 21869 elem_ptr_instruction->init_array_type_source_node != nullptr) 21870 { 21871 if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) { 21872 array_ptr_val->data.x_array.special = ConstArraySpecialNone; 21873 array_ptr_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(array_type->data.array.len); 21874 array_ptr_val->special = ConstValSpecialStatic; 21875 for (size_t i = 0; i < array_type->data.array.len; i += 1) { 21876 ZigValue *elem_val = &array_ptr_val->data.x_array.data.s_none.elements[i]; 21877 elem_val->special = ConstValSpecialUndef; 21878 elem_val->type = array_type->data.array.child_type; 21879 elem_val->parent.id = ConstParentIdArray; 21880 elem_val->parent.data.p_array.array_val = array_ptr_val; 21881 elem_val->parent.data.p_array.elem_index = i; 21882 } 21883 } else if (is_slice(array_type)) { 21884 ir_assert(array_ptr->value->type->id == ZigTypeIdPointer, &elem_ptr_instruction->base.base); 21885 ZigType *actual_array_type = array_ptr->value->type->data.pointer.child_type; 21886 21887 if (type_is_invalid(actual_array_type)) 21888 return ira->codegen->invalid_inst_gen; 21889 if (actual_array_type->id != ZigTypeIdArray) { 21890 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, 21891 buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", 21892 buf_ptr(&actual_array_type->name))); 21893 return ira->codegen->invalid_inst_gen; 21894 } 21895 21896 ZigValue *array_init_val = ira->codegen->pass1_arena->create<ZigValue>(); 21897 array_init_val->special = ConstValSpecialStatic; 21898 array_init_val->type = actual_array_type; 21899 array_init_val->data.x_array.special = ConstArraySpecialNone; 21900 array_init_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(actual_array_type->data.array.len); 21901 array_init_val->special = ConstValSpecialStatic; 21902 for (size_t i = 0; i < actual_array_type->data.array.len; i += 1) { 21903 ZigValue *elem_val = &array_init_val->data.x_array.data.s_none.elements[i]; 21904 elem_val->special = ConstValSpecialUndef; 21905 elem_val->type = actual_array_type->data.array.child_type; 21906 elem_val->parent.id = ConstParentIdArray; 21907 elem_val->parent.data.p_array.array_val = array_init_val; 21908 elem_val->parent.data.p_array.elem_index = i; 21909 } 21910 21911 init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len, 21912 false); 21913 array_ptr_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutInfer; 21914 } else { 21915 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, 21916 buf_sprintf("expected array type or [_], found '%s'", 21917 buf_ptr(&array_type->name))); 21918 return ira->codegen->invalid_inst_gen; 21919 } 21920 } 21921 21922 if (array_ptr_val->special != ConstValSpecialRuntime && 21923 (array_type->id != ZigTypeIdPointer || 21924 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) 21925 { 21926 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 21927 elem_ptr_instruction->base.base.source_node, array_ptr_val, UndefOk))) 21928 { 21929 return ira->codegen->invalid_inst_gen; 21930 } 21931 if (array_type->id == ZigTypeIdPointer) { 21932 IrInstGen *result = ir_const(ira, &elem_ptr_instruction->base.base, return_type); 21933 ZigValue *out_val = result->value; 21934 out_val->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; 21935 size_t new_index; 21936 size_t mem_size; 21937 size_t old_size; 21938 switch (array_ptr_val->data.x_ptr.special) { 21939 case ConstPtrSpecialInvalid: 21940 case ConstPtrSpecialDiscard: 21941 zig_unreachable(); 21942 case ConstPtrSpecialRef: 21943 if (array_ptr_val->data.x_ptr.data.ref.pointee->type->id == ZigTypeIdArray) { 21944 ZigValue *array_val = array_ptr_val->data.x_ptr.data.ref.pointee; 21945 new_index = index; 21946 ZigType *array_type = array_val->type; 21947 mem_size = array_type->data.array.len; 21948 if (array_type->data.array.sentinel != nullptr) { 21949 mem_size += 1; 21950 } 21951 old_size = mem_size; 21952 21953 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 21954 out_val->data.x_ptr.data.base_array.array_val = array_val; 21955 out_val->data.x_ptr.data.base_array.elem_index = new_index; 21956 } else { 21957 mem_size = 1; 21958 old_size = 1; 21959 new_index = index; 21960 21961 out_val->data.x_ptr.special = ConstPtrSpecialRef; 21962 out_val->data.x_ptr.data.ref.pointee = array_ptr_val->data.x_ptr.data.ref.pointee; 21963 } 21964 break; 21965 case ConstPtrSpecialBaseArray: 21966 case ConstPtrSpecialSubArray: 21967 { 21968 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index; 21969 new_index = offset + index; 21970 ZigType *array_type = array_ptr_val->data.x_ptr.data.base_array.array_val->type; 21971 mem_size = array_type->data.array.len; 21972 if (array_type->data.array.sentinel != nullptr) { 21973 mem_size += 1; 21974 } 21975 old_size = mem_size - offset; 21976 21977 assert(array_ptr_val->data.x_ptr.data.base_array.array_val); 21978 21979 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 21980 out_val->data.x_ptr.data.base_array.array_val = 21981 array_ptr_val->data.x_ptr.data.base_array.array_val; 21982 out_val->data.x_ptr.data.base_array.elem_index = new_index; 21983 21984 break; 21985 } 21986 case ConstPtrSpecialBaseStruct: 21987 zig_panic("TODO elem ptr on a const inner struct"); 21988 case ConstPtrSpecialBaseErrorUnionCode: 21989 zig_panic("TODO elem ptr on a const inner error union code"); 21990 case ConstPtrSpecialBaseErrorUnionPayload: 21991 zig_panic("TODO elem ptr on a const inner error union payload"); 21992 case ConstPtrSpecialBaseOptionalPayload: 21993 zig_panic("TODO elem ptr on a const inner optional payload"); 21994 case ConstPtrSpecialHardCodedAddr: 21995 zig_unreachable(); 21996 case ConstPtrSpecialFunction: 21997 zig_panic("TODO element ptr of a function casted to a ptr"); 21998 case ConstPtrSpecialNull: 21999 zig_panic("TODO elem ptr on a null pointer"); 22000 } 22001 if (new_index >= mem_size) { 22002 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 22003 buf_sprintf("index %" ZIG_PRI_u64 " outside pointer of size %" ZIG_PRI_usize "", index, old_size)); 22004 return ira->codegen->invalid_inst_gen; 22005 } 22006 return result; 22007 } else if (is_slice(array_type)) { 22008 ZigValue *ptr_field = array_ptr_val->data.x_struct.fields[slice_ptr_index]; 22009 ir_assert(ptr_field != nullptr, &elem_ptr_instruction->base.base); 22010 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 22011 return ir_build_elem_ptr_gen(ira, elem_ptr_instruction->base.base.scope, 22012 elem_ptr_instruction->base.base.source_node, array_ptr, casted_elem_index, false, 22013 return_type); 22014 } 22015 ZigValue *len_field = array_ptr_val->data.x_struct.fields[slice_len_index]; 22016 IrInstGen *result = ir_const(ira, &elem_ptr_instruction->base.base, return_type); 22017 ZigValue *out_val = result->value; 22018 ZigType *slice_ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; 22019 uint64_t slice_len = bigint_as_u64(&len_field->data.x_bigint); 22020 uint64_t full_slice_len = slice_len + 22021 ((slice_ptr_type->data.pointer.sentinel != nullptr) ? 1 : 0); 22022 if (index >= full_slice_len) { 22023 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 22024 buf_sprintf("index %" ZIG_PRI_u64 " outside slice of size %" ZIG_PRI_u64, 22025 index, slice_len)); 22026 return ira->codegen->invalid_inst_gen; 22027 } 22028 out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut; 22029 switch (ptr_field->data.x_ptr.special) { 22030 case ConstPtrSpecialInvalid: 22031 case ConstPtrSpecialDiscard: 22032 zig_unreachable(); 22033 case ConstPtrSpecialRef: 22034 out_val->data.x_ptr.special = ConstPtrSpecialRef; 22035 out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee; 22036 break; 22037 case ConstPtrSpecialSubArray: 22038 case ConstPtrSpecialBaseArray: 22039 { 22040 size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index; 22041 uint64_t new_index = offset + index; 22042 if (ptr_field->data.x_ptr.data.base_array.array_val->data.x_array.special != 22043 ConstArraySpecialBuf) 22044 { 22045 ir_assert(new_index < 22046 ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len, 22047 &elem_ptr_instruction->base.base); 22048 } 22049 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 22050 out_val->data.x_ptr.data.base_array.array_val = 22051 ptr_field->data.x_ptr.data.base_array.array_val; 22052 out_val->data.x_ptr.data.base_array.elem_index = new_index; 22053 break; 22054 } 22055 case ConstPtrSpecialBaseStruct: 22056 zig_panic("TODO elem ptr on a slice backed by const inner struct"); 22057 case ConstPtrSpecialBaseErrorUnionCode: 22058 zig_panic("TODO elem ptr on a slice backed by const inner error union code"); 22059 case ConstPtrSpecialBaseErrorUnionPayload: 22060 zig_panic("TODO elem ptr on a slice backed by const inner error union payload"); 22061 case ConstPtrSpecialBaseOptionalPayload: 22062 zig_panic("TODO elem ptr on a slice backed by const optional payload"); 22063 case ConstPtrSpecialHardCodedAddr: 22064 zig_unreachable(); 22065 case ConstPtrSpecialFunction: 22066 zig_panic("TODO elem ptr on a slice that was ptrcast from a function"); 22067 case ConstPtrSpecialNull: 22068 zig_panic("TODO elem ptr on a slice has a null pointer"); 22069 } 22070 return result; 22071 } else if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) { 22072 IrInstGen *result; 22073 if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 22074 result = ir_build_elem_ptr_gen(ira, elem_ptr_instruction->base.base.scope, 22075 elem_ptr_instruction->base.base.source_node, array_ptr, casted_elem_index, 22076 false, return_type); 22077 result->value->special = ConstValSpecialStatic; 22078 } else { 22079 result = ir_const(ira, &elem_ptr_instruction->base.base, return_type); 22080 } 22081 ZigValue *out_val = result->value; 22082 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 22083 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; 22084 out_val->data.x_ptr.data.base_array.array_val = array_ptr_val; 22085 out_val->data.x_ptr.data.base_array.elem_index = index; 22086 return result; 22087 } else { 22088 zig_unreachable(); 22089 } 22090 } 22091 } 22092 } else if (array_type->id == ZigTypeIdVector) { 22093 // runtime known element index 22094 ZigType *elem_type = array_type->data.vector.elem_type; 22095 uint32_t host_vec_len = array_type->data.vector.len; 22096 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 22097 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 22098 elem_ptr_instruction->ptr_len, 22099 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, VECTOR_INDEX_RUNTIME, 22100 nullptr, nullptr); 22101 } else { 22102 // runtime known element index 22103 switch (type_requires_comptime(ira->codegen, return_type)) { 22104 case ReqCompTimeYes: 22105 ir_add_error(ira, &elem_index->base, 22106 buf_sprintf("values of type '%s' must be comptime known, but index value is runtime known", 22107 buf_ptr(&return_type->data.pointer.child_type->name))); 22108 return ira->codegen->invalid_inst_gen; 22109 case ReqCompTimeInvalid: 22110 return ira->codegen->invalid_inst_gen; 22111 case ReqCompTimeNo: 22112 break; 22113 } 22114 22115 if (return_type->data.pointer.explicit_alignment != 0) { 22116 if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown))) 22117 return ira->codegen->invalid_inst_gen; 22118 22119 uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); 22120 uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); 22121 uint64_t ptr_align = get_ptr_align(ira->codegen, return_type); 22122 if (ptr_align < abi_align) { 22123 if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 22124 return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align); 22125 } else { 22126 // can't get here because guaranteed elem_size >= abi_align 22127 zig_unreachable(); 22128 } 22129 } else { 22130 return_type = adjust_ptr_align(ira->codegen, return_type, abi_align); 22131 } 22132 } 22133 } 22134 22135 return ir_build_elem_ptr_gen(ira, elem_ptr_instruction->base.base.scope, 22136 elem_ptr_instruction->base.base.source_node, array_ptr, casted_elem_index, safety_check_on, return_type); 22137 } 22138 22139 static IrInstGen *ir_analyze_container_member_access_inner(IrAnalyze *ira, 22140 ZigType *bare_struct_type, Buf *field_name, IrInst* source_instr, 22141 IrInstGen *container_ptr, IrInst *container_ptr_src, ZigType *container_type) 22142 { 22143 if (!is_slice(bare_struct_type)) { 22144 ScopeDecls *container_scope = get_container_scope(bare_struct_type); 22145 assert(container_scope != nullptr); 22146 auto tld = find_container_decl(ira->codegen, container_scope, field_name); 22147 if (tld) { 22148 if (tld->id == TldIdFn) { 22149 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); 22150 if (tld->resolution == TldResolutionInvalid) 22151 return ira->codegen->invalid_inst_gen; 22152 if (tld->resolution == TldResolutionResolving) 22153 return ir_error_dependency_loop(ira, source_instr); 22154 22155 if (tld->visib_mod == VisibModPrivate && 22156 tld->import != get_scope_import(source_instr->scope)) 22157 { 22158 ErrorMsg *msg = ir_add_error(ira, source_instr, 22159 buf_sprintf("'%s' is private", buf_ptr(field_name))); 22160 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); 22161 return ira->codegen->invalid_inst_gen; 22162 } 22163 22164 TldFn *tld_fn = (TldFn *)tld; 22165 ZigFn *fn_entry = tld_fn->fn_entry; 22166 assert(fn_entry != nullptr); 22167 22168 if (type_is_invalid(fn_entry->type_entry)) 22169 return ira->codegen->invalid_inst_gen; 22170 22171 IrInstGen *bound_fn_value = ir_const_bound_fn(ira, source_instr, fn_entry, container_ptr, 22172 container_ptr_src); 22173 return ir_get_ref(ira, source_instr, bound_fn_value, true, false); 22174 } else if (tld->id == TldIdVar) { 22175 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); 22176 if (tld->resolution == TldResolutionInvalid) 22177 return ira->codegen->invalid_inst_gen; 22178 if (tld->resolution == TldResolutionResolving) 22179 return ir_error_dependency_loop(ira, source_instr); 22180 22181 TldVar *tld_var = (TldVar *)tld; 22182 ZigVar *var = tld_var->var; 22183 assert(var != nullptr); 22184 22185 if (type_is_invalid(var->var_type)) 22186 return ira->codegen->invalid_inst_gen; 22187 22188 if (var->const_value->type->id == ZigTypeIdFn) { 22189 ir_assert(var->const_value->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); 22190 ZigFn *fn = var->const_value->data.x_ptr.data.fn.fn_entry; 22191 IrInstGen *bound_fn_value = ir_const_bound_fn(ira, source_instr, fn, container_ptr, 22192 container_ptr_src); 22193 return ir_get_ref(ira, source_instr, bound_fn_value, true, false); 22194 } 22195 } 22196 } 22197 } 22198 const char *prefix_name; 22199 if (is_slice(bare_struct_type)) { 22200 prefix_name = ""; 22201 } else if (bare_struct_type->id == ZigTypeIdStruct) { 22202 prefix_name = "struct "; 22203 } else if (bare_struct_type->id == ZigTypeIdEnum) { 22204 prefix_name = "enum "; 22205 } else if (bare_struct_type->id == ZigTypeIdUnion) { 22206 prefix_name = "union "; 22207 } else { 22208 prefix_name = ""; 22209 } 22210 ir_add_error_node(ira, source_instr->source_node, 22211 buf_sprintf("no member named '%s' in %s'%s'", buf_ptr(field_name), prefix_name, buf_ptr(&bare_struct_type->name))); 22212 return ira->codegen->invalid_inst_gen; 22213 } 22214 22215 static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field) { 22216 if (field->init_val != nullptr) return; 22217 if (field->decl_node->type != NodeTypeStructField) return; 22218 AstNode *init_node = field->decl_node->data.struct_field.value; 22219 if (init_node == nullptr) return; 22220 // scope is not the scope of the struct init, it's the scope of the struct type decl 22221 Scope *analyze_scope = &get_container_scope(container_type)->base; 22222 // memoize it 22223 field->init_val = analyze_const_value(codegen, analyze_scope, init_node, 22224 field->type_entry, nullptr, UndefOk); 22225 } 22226 22227 static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_instr, 22228 TypeStructField *field, IrInstGen *struct_ptr, ZigType *struct_type, bool initializing) 22229 { 22230 Error err; 22231 ZigType *field_type = resolve_struct_field_type(ira->codegen, field); 22232 if (field_type == nullptr) 22233 return ira->codegen->invalid_inst_gen; 22234 if (field->is_comptime) { 22235 IrInstGen *elem = ir_const(ira, source_instr, field_type); 22236 memoize_field_init_val(ira->codegen, struct_type, field); 22237 if(field->init_val != nullptr && type_is_invalid(field->init_val->type)){ 22238 return ira->codegen->invalid_inst_gen; 22239 } 22240 copy_const_val(ira->codegen, elem->value, field->init_val); 22241 return ir_get_ref2(ira, source_instr, elem, field_type, true, false); 22242 } 22243 switch (type_has_one_possible_value(ira->codegen, field_type)) { 22244 case OnePossibleValueInvalid: 22245 return ira->codegen->invalid_inst_gen; 22246 case OnePossibleValueYes: { 22247 IrInstGen *elem = ir_const_move(ira, source_instr, 22248 get_the_one_possible_value(ira->codegen, field_type)); 22249 return ir_get_ref(ira, source_instr, elem, 22250 struct_ptr->value->type->data.pointer.is_const, 22251 struct_ptr->value->type->data.pointer.is_volatile); 22252 } 22253 case OnePossibleValueNo: 22254 break; 22255 } 22256 bool is_const = struct_ptr->value->type->data.pointer.is_const; 22257 bool is_volatile = struct_ptr->value->type->data.pointer.is_volatile; 22258 ZigType *ptr_type; 22259 if (is_anon_container(struct_type)) { 22260 ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 22261 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 22262 } else { 22263 ResolveStatus needed_resolve_status = 22264 (struct_type->data.structure.layout == ContainerLayoutAuto) ? 22265 ResolveStatusZeroBitsKnown : ResolveStatusSizeKnown; 22266 if ((err = type_resolve(ira->codegen, struct_type, needed_resolve_status))) 22267 return ira->codegen->invalid_inst_gen; 22268 assert(struct_ptr->value->type->id == ZigTypeIdPointer); 22269 uint32_t ptr_bit_offset = struct_ptr->value->type->data.pointer.bit_offset_in_host; 22270 uint32_t ptr_host_int_bytes = struct_ptr->value->type->data.pointer.host_int_bytes; 22271 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? 22272 get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes; 22273 ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 22274 is_const, is_volatile, PtrLenSingle, field->align, 22275 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), 22276 (uint32_t)host_int_bytes_for_result_type, false); 22277 } 22278 if (instr_is_comptime(struct_ptr)) { 22279 ZigValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad); 22280 if (!ptr_val) 22281 return ira->codegen->invalid_inst_gen; 22282 22283 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 22284 ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 22285 if (struct_val == nullptr) 22286 return ira->codegen->invalid_inst_gen; 22287 if (type_is_invalid(struct_val->type)) 22288 return ira->codegen->invalid_inst_gen; 22289 22290 // This to allow lazy values to be resolved. 22291 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 22292 source_instr->source_node, struct_val, UndefOk))) 22293 { 22294 return ira->codegen->invalid_inst_gen; 22295 } 22296 if (initializing && struct_val->special == ConstValSpecialUndef) { 22297 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count); 22298 struct_val->special = ConstValSpecialStatic; 22299 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) { 22300 ZigValue *field_val = struct_val->data.x_struct.fields[i]; 22301 field_val->special = ConstValSpecialUndef; 22302 field_val->type = resolve_struct_field_type(ira->codegen, 22303 struct_type->data.structure.fields[i]); 22304 field_val->parent.id = ConstParentIdStruct; 22305 field_val->parent.data.p_struct.struct_val = struct_val; 22306 field_val->parent.data.p_struct.field_index = i; 22307 } 22308 } 22309 IrInstGen *result; 22310 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 22311 result = ir_build_struct_field_ptr(ira, source_instr, struct_ptr, field, ptr_type); 22312 result->value->special = ConstValSpecialStatic; 22313 } else { 22314 result = ir_const(ira, source_instr, ptr_type); 22315 } 22316 ZigValue *const_val = result->value; 22317 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; 22318 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 22319 const_val->data.x_ptr.data.base_struct.struct_val = struct_val; 22320 const_val->data.x_ptr.data.base_struct.field_index = field->src_index; 22321 return result; 22322 } 22323 } 22324 return ir_build_struct_field_ptr(ira, source_instr, struct_ptr, field, ptr_type); 22325 } 22326 22327 static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, 22328 IrInst* source_instr, IrInstGen *container_ptr, ZigType *container_type) 22329 { 22330 // The type of the field is not available until a store using this pointer happens. 22331 // So, here we create a special pointer type which has the inferred struct type and 22332 // field name encoded in the type. Later, when there is a store via this pointer, 22333 // the field type will then be available, and the field will be added to the inferred 22334 // struct. 22335 22336 ZigType *container_ptr_type = container_ptr->value->type; 22337 ir_assert(container_ptr_type->id == ZigTypeIdPointer, source_instr); 22338 22339 InferredStructField *inferred_struct_field = heap::c_allocator.create<InferredStructField>(); 22340 inferred_struct_field->inferred_struct_type = container_type; 22341 inferred_struct_field->field_name = field_name; 22342 22343 ZigType *elem_type = ira->codegen->builtin_types.entry_anytype; 22344 ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 22345 container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile, 22346 PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field, nullptr); 22347 22348 if (instr_is_comptime(container_ptr)) { 22349 ZigValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 22350 if (ptr_val == nullptr) 22351 return ira->codegen->invalid_inst_gen; 22352 22353 IrInstGen *result; 22354 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 22355 result = ir_build_cast(ira, source_instr, container_ptr_type, container_ptr, CastOpNoop); 22356 } else { 22357 result = ir_const(ira, source_instr, field_ptr_type); 22358 } 22359 copy_const_val(ira->codegen, result->value, ptr_val); 22360 result->value->type = field_ptr_type; 22361 return result; 22362 } 22363 22364 return ir_build_cast(ira, source_instr, field_ptr_type, container_ptr, CastOpNoop); 22365 } 22366 22367 static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 22368 IrInst* source_instr, IrInstGen *container_ptr, IrInst *container_ptr_src, 22369 ZigType *container_type, bool initializing) 22370 { 22371 Error err; 22372 22373 ZigType *bare_type = container_ref_type(container_type); 22374 22375 if (initializing && bare_type->id == ZigTypeIdStruct && 22376 bare_type->data.structure.resolve_status == ResolveStatusBeingInferred) 22377 { 22378 return ir_analyze_inferred_field_ptr(ira, field_name, source_instr, container_ptr, bare_type); 22379 } 22380 22381 // Tracks wether we should return an undefined value of the correct type. 22382 // We do this if the container pointer is undefined and we are in a TypeOf call. 22383 bool return_undef = container_ptr->value->special == ConstValSpecialUndef && \ 22384 get_scope_typeof(source_instr->scope) != nullptr; 22385 22386 if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown))) 22387 return ira->codegen->invalid_inst_gen; 22388 22389 assert(container_ptr->value->type->id == ZigTypeIdPointer); 22390 if (bare_type->id == ZigTypeIdStruct) { 22391 TypeStructField *field = find_struct_type_field(bare_type, field_name); 22392 if (field != nullptr) { 22393 if (return_undef) { 22394 ZigType *field_ptr_type = get_pointer_to_type(ira->codegen, resolve_struct_field_type(ira->codegen, field), 22395 container_ptr->value->type->data.pointer.is_const); 22396 return ir_const_undef(ira, source_instr, field_ptr_type); 22397 } 22398 22399 return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); 22400 } else { 22401 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 22402 source_instr, container_ptr, container_ptr_src, container_type); 22403 } 22404 } 22405 22406 if (bare_type->id == ZigTypeIdEnum) { 22407 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 22408 source_instr, container_ptr, container_ptr_src, container_type); 22409 } 22410 22411 if (bare_type->id == ZigTypeIdUnion) { 22412 bool is_const = container_ptr->value->type->data.pointer.is_const; 22413 bool is_volatile = container_ptr->value->type->data.pointer.is_volatile; 22414 22415 TypeUnionField *field = find_union_type_field(bare_type, field_name); 22416 if (field == nullptr) { 22417 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 22418 source_instr, container_ptr, container_ptr_src, container_type); 22419 } 22420 22421 ZigType *field_type = resolve_union_field_type(ira->codegen, field); 22422 if (field_type == nullptr) 22423 return ira->codegen->invalid_inst_gen; 22424 22425 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 22426 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 22427 if (instr_is_comptime(container_ptr)) { 22428 ZigValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 22429 if (!ptr_val) 22430 return ira->codegen->invalid_inst_gen; 22431 22432 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && 22433 ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 22434 ZigValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 22435 if (union_val == nullptr) 22436 return ira->codegen->invalid_inst_gen; 22437 if (type_is_invalid(union_val->type)) 22438 return ira->codegen->invalid_inst_gen; 22439 22440 if (initializing) { 22441 ZigValue *payload_val = ira->codegen->pass1_arena->create<ZigValue>(); 22442 payload_val->special = ConstValSpecialUndef; 22443 payload_val->type = field_type; 22444 payload_val->parent.id = ConstParentIdUnion; 22445 payload_val->parent.data.p_union.union_val = union_val; 22446 22447 union_val->special = ConstValSpecialStatic; 22448 bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value); 22449 union_val->data.x_union.payload = payload_val; 22450 } else if (bare_type->data.unionation.layout != ContainerLayoutExtern) { 22451 TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); 22452 if (actual_field == nullptr) 22453 zig_unreachable(); 22454 22455 if (field != actual_field) { 22456 ir_add_error_node(ira, source_instr->source_node, 22457 buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), 22458 buf_ptr(actual_field->name))); 22459 return ira->codegen->invalid_inst_gen; 22460 } 22461 } 22462 22463 ZigValue *payload_val = union_val->data.x_union.payload; 22464 22465 IrInstGen *result; 22466 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 22467 result = ir_build_union_field_ptr(ira, source_instr, container_ptr, field, true, 22468 initializing, ptr_type); 22469 result->value->special = ConstValSpecialStatic; 22470 } else { 22471 result = ir_const(ira, source_instr, ptr_type); 22472 } 22473 ZigValue *const_val = result->value; 22474 const_val->data.x_ptr.special = ConstPtrSpecialRef; 22475 const_val->data.x_ptr.mut = container_ptr->value->data.x_ptr.mut; 22476 const_val->data.x_ptr.data.ref.pointee = payload_val; 22477 return result; 22478 } 22479 } 22480 22481 return ir_build_union_field_ptr(ira, source_instr, container_ptr, field, true, initializing, ptr_type); 22482 } 22483 22484 zig_unreachable(); 22485 } 22486 22487 static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { 22488 bool is_libc = target_is_libc_lib_name(ira->codegen->zig_target, buf_ptr(lib_name)); 22489 if (is_libc && ira->codegen->libc_link_lib == nullptr && !ira->codegen->reported_bad_link_libc_error) { 22490 ir_add_error_node(ira, source_node, 22491 buf_sprintf("dependency on library c must be explicitly specified in the build command")); 22492 ira->codegen->reported_bad_link_libc_error = true; 22493 } 22494 22495 LinkLib *link_lib = add_link_lib(ira->codegen, lib_name); 22496 for (size_t i = 0; i < link_lib->symbols.length; i += 1) { 22497 Buf *existing_symbol_name = link_lib->symbols.at(i); 22498 if (buf_eql_buf(existing_symbol_name, symbol_name)) { 22499 return; 22500 } 22501 } 22502 22503 if (!is_libc && !target_is_wasm(ira->codegen->zig_target) && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) { 22504 ErrorMsg *msg = ir_add_error_node(ira, source_node, 22505 buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code", 22506 buf_ptr(lib_name))); 22507 add_error_note(ira->codegen, msg, source_node, 22508 buf_sprintf("fixed by `--library %s` or `-fPIC`", buf_ptr(lib_name))); 22509 ira->codegen->reported_bad_link_libc_error = true; 22510 } 22511 22512 for (size_t i = 0; i < ira->codegen->forbidden_libs.length; i += 1) { 22513 Buf *forbidden_lib_name = ira->codegen->forbidden_libs.at(i); 22514 if (buf_eql_buf(lib_name, forbidden_lib_name)) { 22515 ir_add_error_node(ira, source_node, 22516 buf_sprintf("linking against forbidden library '%s'", buf_ptr(symbol_name))); 22517 } 22518 } 22519 link_lib->symbols.append(symbol_name); 22520 } 22521 22522 static IrInstGen *ir_error_dependency_loop(IrAnalyze *ira, IrInst* source_instr) { 22523 ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); 22524 return ira->codegen->invalid_inst_gen; 22525 } 22526 22527 static IrInstGen *ir_analyze_decl_ref(IrAnalyze *ira, IrInst* source_instruction, Tld *tld) { 22528 resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node, true); 22529 if (tld->resolution == TldResolutionInvalid) { 22530 return ira->codegen->invalid_inst_gen; 22531 } 22532 if (tld->resolution == TldResolutionResolving) 22533 return ir_error_dependency_loop(ira, source_instruction); 22534 22535 switch (tld->id) { 22536 case TldIdContainer: 22537 case TldIdCompTime: 22538 case TldIdUsingNamespace: 22539 zig_unreachable(); 22540 case TldIdVar: { 22541 TldVar *tld_var = (TldVar *)tld; 22542 ZigVar *var = tld_var->var; 22543 assert(var != nullptr); 22544 22545 if (tld_var->extern_lib_name != nullptr) { 22546 add_link_lib_symbol(ira, tld_var->extern_lib_name, buf_create_from_str(var->name), 22547 source_instruction->source_node); 22548 } 22549 22550 return ir_get_var_ptr(ira, source_instruction, var); 22551 } 22552 case TldIdFn: { 22553 TldFn *tld_fn = (TldFn *)tld; 22554 ZigFn *fn_entry = tld_fn->fn_entry; 22555 assert(fn_entry->type_entry != nullptr); 22556 22557 if (type_is_invalid(fn_entry->type_entry)) 22558 return ira->codegen->invalid_inst_gen; 22559 22560 if (tld_fn->extern_lib_name != nullptr) { 22561 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); 22562 } 22563 22564 IrInstGen *fn_inst = ir_const_fn(ira, source_instruction, fn_entry); 22565 return ir_get_ref(ira, source_instruction, fn_inst, true, false); 22566 } 22567 } 22568 zig_unreachable(); 22569 } 22570 22571 static ErrorTableEntry *find_err_table_entry(ZigType *err_set_type, Buf *field_name) { 22572 assert(err_set_type->id == ZigTypeIdErrorSet); 22573 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 22574 ErrorTableEntry *err_table_entry = err_set_type->data.error_set.errors[i]; 22575 if (buf_eql_buf(&err_table_entry->name, field_name)) { 22576 return err_table_entry; 22577 } 22578 } 22579 return nullptr; 22580 } 22581 22582 static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFieldPtr *field_ptr_instruction) { 22583 Error err; 22584 IrInstGen *container_ptr = field_ptr_instruction->container_ptr->child; 22585 if (type_is_invalid(container_ptr->value->type)) 22586 return ira->codegen->invalid_inst_gen; 22587 22588 ZigType *container_type = container_ptr->value->type->data.pointer.child_type; 22589 22590 Buf *field_name = field_ptr_instruction->field_name_buffer; 22591 if (!field_name) { 22592 IrInstGen *field_name_expr = field_ptr_instruction->field_name_expr->child; 22593 field_name = ir_resolve_str(ira, field_name_expr); 22594 if (!field_name) 22595 return ira->codegen->invalid_inst_gen; 22596 } 22597 22598 22599 AstNode *source_node = field_ptr_instruction->base.base.source_node; 22600 22601 if (type_is_invalid(container_type)) { 22602 return ira->codegen->invalid_inst_gen; 22603 } else if (is_tuple(container_type) && !field_ptr_instruction->initializing && buf_eql_str(field_name, "len")) { 22604 IrInstGen *len_inst = ir_const_unsigned(ira, &field_ptr_instruction->base.base, 22605 container_type->data.structure.src_field_count); 22606 return ir_get_ref(ira, &field_ptr_instruction->base.base, len_inst, true, false); 22607 } else if (is_slice(container_type) || is_container_ref(container_type)) { 22608 assert(container_ptr->value->type->id == ZigTypeIdPointer); 22609 if (container_type->id == ZigTypeIdPointer) { 22610 ZigType *bare_type = container_ref_type(container_type); 22611 IrInstGen *container_child = ir_get_deref(ira, &field_ptr_instruction->base.base, container_ptr, nullptr); 22612 IrInstGen *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base.base, 22613 container_child, &field_ptr_instruction->container_ptr->base, bare_type, 22614 field_ptr_instruction->initializing); 22615 return result; 22616 } else { 22617 IrInstGen *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base.base, 22618 container_ptr, &field_ptr_instruction->container_ptr->base, container_type, 22619 field_ptr_instruction->initializing); 22620 return result; 22621 } 22622 } else if (is_array_ref(container_type) && !field_ptr_instruction->initializing) { 22623 if (buf_eql_str(field_name, "len")) { 22624 ZigValue *len_val = ira->codegen->pass1_arena->create<ZigValue>(); 22625 if (container_type->id == ZigTypeIdPointer) { 22626 init_const_usize(ira->codegen, len_val, container_type->data.pointer.child_type->data.array.len); 22627 } else { 22628 init_const_usize(ira->codegen, len_val, container_type->data.array.len); 22629 } 22630 22631 ZigType *usize = ira->codegen->builtin_types.entry_usize; 22632 bool ptr_is_const = true; 22633 bool ptr_is_volatile = false; 22634 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, len_val, 22635 usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22636 } else { 22637 ir_add_error_node(ira, source_node, 22638 buf_sprintf("no field named '%s' in '%s'", buf_ptr(field_name), 22639 buf_ptr(&container_type->name))); 22640 return ira->codegen->invalid_inst_gen; 22641 } 22642 } else if (container_type->id == ZigTypeIdMetaType) { 22643 ZigValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 22644 if (!container_ptr_val) 22645 return ira->codegen->invalid_inst_gen; 22646 22647 assert(container_ptr->value->type->id == ZigTypeIdPointer); 22648 ZigValue *child_val = const_ptr_pointee(ira, ira->codegen, container_ptr_val, source_node); 22649 if (child_val == nullptr) 22650 return ira->codegen->invalid_inst_gen; 22651 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 22652 field_ptr_instruction->base.base.source_node, child_val, UndefBad))) 22653 { 22654 return ira->codegen->invalid_inst_gen; 22655 } 22656 ZigType *child_type = child_val->data.x_type; 22657 22658 if (type_is_invalid(child_type)) { 22659 return ira->codegen->invalid_inst_gen; 22660 } else if (is_container(child_type)) { 22661 if (child_type->id == ZigTypeIdEnum) { 22662 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) 22663 return ira->codegen->invalid_inst_gen; 22664 22665 TypeEnumField *field = find_enum_type_field(child_type, field_name); 22666 if (field) { 22667 bool ptr_is_const = true; 22668 bool ptr_is_volatile = false; 22669 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22670 create_const_enum(ira->codegen, child_type, &field->value), child_type, 22671 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22672 } 22673 } 22674 ScopeDecls *container_scope = get_container_scope(child_type); 22675 Tld *tld = find_container_decl(ira->codegen, container_scope, field_name); 22676 if (tld) { 22677 if (tld->visib_mod == VisibModPrivate && 22678 tld->import != get_scope_import(field_ptr_instruction->base.base.scope)) 22679 { 22680 ErrorMsg *msg = ir_add_error(ira, &field_ptr_instruction->base.base, 22681 buf_sprintf("'%s' is private", buf_ptr(field_name))); 22682 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); 22683 return ira->codegen->invalid_inst_gen; 22684 } 22685 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base.base, tld); 22686 } 22687 if (child_type->id == ZigTypeIdUnion && 22688 (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr || 22689 child_type->data.unionation.decl_node->data.container_decl.auto_enum)) 22690 { 22691 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) 22692 return ira->codegen->invalid_inst_gen; 22693 TypeUnionField *field = find_union_type_field(child_type, field_name); 22694 if (field) { 22695 ZigType *enum_type = child_type->data.unionation.tag_type; 22696 bool ptr_is_const = true; 22697 bool ptr_is_volatile = false; 22698 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22699 create_const_enum(ira->codegen, enum_type, &field->enum_field->value), enum_type, 22700 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22701 } 22702 } 22703 const char *container_name = (child_type == ira->codegen->root_import) ? 22704 "root source file" : buf_ptr(buf_sprintf("container '%s'", buf_ptr(&child_type->name))); 22705 ir_add_error(ira, &field_ptr_instruction->base.base, 22706 buf_sprintf("%s has no member called '%s'", 22707 container_name, buf_ptr(field_name))); 22708 return ira->codegen->invalid_inst_gen; 22709 } else if (child_type->id == ZigTypeIdErrorSet) { 22710 ErrorTableEntry *err_entry; 22711 ZigType *err_set_type; 22712 if (type_is_global_error_set(child_type)) { 22713 auto existing_entry = ira->codegen->error_table.maybe_get(field_name); 22714 if (existing_entry) { 22715 err_entry = existing_entry->value; 22716 } else { 22717 err_entry = heap::c_allocator.create<ErrorTableEntry>(); 22718 err_entry->decl_node = field_ptr_instruction->base.base.source_node; 22719 buf_init_from_buf(&err_entry->name, field_name); 22720 size_t error_value_count = ira->codegen->errors_by_index.length; 22721 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count)); 22722 err_entry->value = error_value_count; 22723 ira->codegen->errors_by_index.append(err_entry); 22724 ira->codegen->error_table.put(field_name, err_entry); 22725 } 22726 if (err_entry->set_with_only_this_in_it == nullptr) { 22727 err_entry->set_with_only_this_in_it = make_err_set_with_one_item(ira->codegen, 22728 field_ptr_instruction->base.base.scope, field_ptr_instruction->base.base.source_node, 22729 err_entry); 22730 } 22731 err_set_type = err_entry->set_with_only_this_in_it; 22732 } else { 22733 if (!resolve_inferred_error_set(ira->codegen, child_type, field_ptr_instruction->base.base.source_node)) { 22734 return ira->codegen->invalid_inst_gen; 22735 } 22736 err_entry = find_err_table_entry(child_type, field_name); 22737 if (err_entry == nullptr) { 22738 ir_add_error(ira, &field_ptr_instruction->base.base, 22739 buf_sprintf("no error named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&child_type->name))); 22740 return ira->codegen->invalid_inst_gen; 22741 } 22742 err_set_type = child_type; 22743 } 22744 ZigValue *const_val = ira->codegen->pass1_arena->create<ZigValue>(); 22745 const_val->special = ConstValSpecialStatic; 22746 const_val->type = err_set_type; 22747 const_val->data.x_err_set = err_entry; 22748 22749 bool ptr_is_const = true; 22750 bool ptr_is_volatile = false; 22751 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, const_val, 22752 err_set_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22753 } else if (child_type->id == ZigTypeIdInt) { 22754 if (buf_eql_str(field_name, "bit_count")) { 22755 bool ptr_is_const = true; 22756 bool ptr_is_volatile = false; 22757 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22758 create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int, 22759 child_type->data.integral.bit_count, false), 22760 ira->codegen->builtin_types.entry_num_lit_int, 22761 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22762 } else if (buf_eql_str(field_name, "is_signed")) { 22763 bool ptr_is_const = true; 22764 bool ptr_is_volatile = false; 22765 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22766 create_const_bool(ira->codegen, child_type->data.integral.is_signed), 22767 ira->codegen->builtin_types.entry_bool, 22768 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22769 } else { 22770 ir_add_error(ira, &field_ptr_instruction->base.base, 22771 buf_sprintf("type '%s' has no member called '%s'", 22772 buf_ptr(&child_type->name), buf_ptr(field_name))); 22773 return ira->codegen->invalid_inst_gen; 22774 } 22775 } else if (child_type->id == ZigTypeIdFloat) { 22776 if (buf_eql_str(field_name, "bit_count")) { 22777 bool ptr_is_const = true; 22778 bool ptr_is_volatile = false; 22779 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22780 create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int, 22781 child_type->data.floating.bit_count, false), 22782 ira->codegen->builtin_types.entry_num_lit_int, 22783 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22784 } else { 22785 ir_add_error(ira, &field_ptr_instruction->base.base, 22786 buf_sprintf("type '%s' has no member called '%s'", 22787 buf_ptr(&child_type->name), buf_ptr(field_name))); 22788 return ira->codegen->invalid_inst_gen; 22789 } 22790 } else if (child_type->id == ZigTypeIdPointer) { 22791 if (buf_eql_str(field_name, "Child")) { 22792 bool ptr_is_const = true; 22793 bool ptr_is_volatile = false; 22794 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22795 create_const_type(ira->codegen, child_type->data.pointer.child_type), 22796 ira->codegen->builtin_types.entry_type, 22797 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22798 } else if (buf_eql_str(field_name, "alignment")) { 22799 bool ptr_is_const = true; 22800 bool ptr_is_volatile = false; 22801 if ((err = type_resolve(ira->codegen, child_type->data.pointer.child_type, 22802 ResolveStatusAlignmentKnown))) 22803 { 22804 return ira->codegen->invalid_inst_gen; 22805 } 22806 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22807 create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int, 22808 get_ptr_align(ira->codegen, child_type), false), 22809 ira->codegen->builtin_types.entry_num_lit_int, 22810 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22811 } else { 22812 ir_add_error(ira, &field_ptr_instruction->base.base, 22813 buf_sprintf("type '%s' has no member called '%s'", 22814 buf_ptr(&child_type->name), buf_ptr(field_name))); 22815 return ira->codegen->invalid_inst_gen; 22816 } 22817 } else if (child_type->id == ZigTypeIdArray) { 22818 if (buf_eql_str(field_name, "Child")) { 22819 bool ptr_is_const = true; 22820 bool ptr_is_volatile = false; 22821 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22822 create_const_type(ira->codegen, child_type->data.array.child_type), 22823 ira->codegen->builtin_types.entry_type, 22824 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22825 } else if (buf_eql_str(field_name, "len")) { 22826 bool ptr_is_const = true; 22827 bool ptr_is_volatile = false; 22828 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22829 create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int, 22830 child_type->data.array.len, false), 22831 ira->codegen->builtin_types.entry_num_lit_int, 22832 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22833 } else { 22834 ir_add_error(ira, &field_ptr_instruction->base.base, 22835 buf_sprintf("type '%s' has no member called '%s'", 22836 buf_ptr(&child_type->name), buf_ptr(field_name))); 22837 return ira->codegen->invalid_inst_gen; 22838 } 22839 } else if (child_type->id == ZigTypeIdErrorUnion) { 22840 if (buf_eql_str(field_name, "Payload")) { 22841 bool ptr_is_const = true; 22842 bool ptr_is_volatile = false; 22843 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22844 create_const_type(ira->codegen, child_type->data.error_union.payload_type), 22845 ira->codegen->builtin_types.entry_type, 22846 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22847 } else if (buf_eql_str(field_name, "ErrorSet")) { 22848 bool ptr_is_const = true; 22849 bool ptr_is_volatile = false; 22850 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22851 create_const_type(ira->codegen, child_type->data.error_union.err_set_type), 22852 ira->codegen->builtin_types.entry_type, 22853 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22854 } else { 22855 ir_add_error(ira, &field_ptr_instruction->base.base, 22856 buf_sprintf("type '%s' has no member called '%s'", 22857 buf_ptr(&child_type->name), buf_ptr(field_name))); 22858 return ira->codegen->invalid_inst_gen; 22859 } 22860 } else if (child_type->id == ZigTypeIdOptional) { 22861 if (buf_eql_str(field_name, "Child")) { 22862 bool ptr_is_const = true; 22863 bool ptr_is_volatile = false; 22864 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22865 create_const_type(ira->codegen, child_type->data.maybe.child_type), 22866 ira->codegen->builtin_types.entry_type, 22867 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22868 } else { 22869 ir_add_error(ira, &field_ptr_instruction->base.base, 22870 buf_sprintf("type '%s' has no member called '%s'", 22871 buf_ptr(&child_type->name), buf_ptr(field_name))); 22872 return ira->codegen->invalid_inst_gen; 22873 } 22874 } else if (child_type->id == ZigTypeIdFn) { 22875 if (buf_eql_str(field_name, "ReturnType")) { 22876 if (child_type->data.fn.fn_type_id.return_type == nullptr) { 22877 // Return type can only ever be null, if the function is generic 22878 assert(child_type->data.fn.is_generic); 22879 22880 ir_add_error(ira, &field_ptr_instruction->base.base, 22881 buf_sprintf("ReturnType has not been resolved because '%s' is generic", buf_ptr(&child_type->name))); 22882 return ira->codegen->invalid_inst_gen; 22883 } 22884 22885 bool ptr_is_const = true; 22886 bool ptr_is_volatile = false; 22887 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22888 create_const_type(ira->codegen, child_type->data.fn.fn_type_id.return_type), 22889 ira->codegen->builtin_types.entry_type, 22890 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22891 } else if (buf_eql_str(field_name, "is_var_args")) { 22892 bool ptr_is_const = true; 22893 bool ptr_is_volatile = false; 22894 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22895 create_const_bool(ira->codegen, child_type->data.fn.fn_type_id.is_var_args), 22896 ira->codegen->builtin_types.entry_bool, 22897 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22898 } else if (buf_eql_str(field_name, "arg_count")) { 22899 bool ptr_is_const = true; 22900 bool ptr_is_volatile = false; 22901 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22902 create_const_usize(ira->codegen, child_type->data.fn.fn_type_id.param_count), 22903 ira->codegen->builtin_types.entry_usize, 22904 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22905 } else { 22906 ir_add_error(ira, &field_ptr_instruction->base.base, 22907 buf_sprintf("type '%s' has no member called '%s'", 22908 buf_ptr(&child_type->name), buf_ptr(field_name))); 22909 return ira->codegen->invalid_inst_gen; 22910 } 22911 } else { 22912 ir_add_error(ira, &field_ptr_instruction->base.base, 22913 buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); 22914 return ira->codegen->invalid_inst_gen; 22915 } 22916 } else if (field_ptr_instruction->initializing) { 22917 ir_add_error(ira, &field_ptr_instruction->base.base, 22918 buf_sprintf("type '%s' does not support struct initialization syntax", buf_ptr(&container_type->name))); 22919 return ira->codegen->invalid_inst_gen; 22920 } else { 22921 ir_add_error_node(ira, field_ptr_instruction->base.base.source_node, 22922 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); 22923 return ira->codegen->invalid_inst_gen; 22924 } 22925 } 22926 22927 static IrInstGen *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstSrcStorePtr *instruction) { 22928 IrInstGen *ptr = instruction->ptr->child; 22929 if (type_is_invalid(ptr->value->type)) 22930 return ira->codegen->invalid_inst_gen; 22931 22932 IrInstGen *value = instruction->value->child; 22933 if (type_is_invalid(value->value->type)) 22934 return ira->codegen->invalid_inst_gen; 22935 22936 return ir_analyze_store_ptr(ira, &instruction->base.base, ptr, value, instruction->allow_write_through_const); 22937 } 22938 22939 static IrInstGen *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstSrcLoadPtr *instruction) { 22940 IrInstGen *ptr = instruction->ptr->child; 22941 if (type_is_invalid(ptr->value->type)) 22942 return ira->codegen->invalid_inst_gen; 22943 return ir_get_deref(ira, &instruction->base.base, ptr, nullptr); 22944 } 22945 22946 static IrInstGen *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstSrcTypeOf *typeof_instruction) { 22947 ZigType *type_entry; 22948 22949 const size_t value_count = typeof_instruction->value_count; 22950 22951 // Fast path for the common case of TypeOf with a single argument 22952 if (value_count < 2) { 22953 type_entry = typeof_instruction->value.scalar->child->value->type; 22954 } else { 22955 IrInstGen **args = heap::c_allocator.allocate<IrInstGen*>(value_count); 22956 for (size_t i = 0; i < value_count; i += 1) { 22957 IrInstGen *value = typeof_instruction->value.list[i]->child; 22958 if (type_is_invalid(value->value->type)) 22959 return ira->codegen->invalid_inst_gen; 22960 args[i] = value; 22961 } 22962 22963 type_entry = ir_resolve_peer_types(ira, typeof_instruction->base.base.source_node, 22964 nullptr, args, value_count); 22965 22966 heap::c_allocator.deallocate(args, value_count); 22967 } 22968 22969 if (type_is_invalid(type_entry)) 22970 return ira->codegen->invalid_inst_gen; 22971 22972 return ir_const_type(ira, &typeof_instruction->base.base, type_entry); 22973 } 22974 22975 static IrInstGen *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstSrcSetCold *instruction) { 22976 if (ira->new_irb.exec->is_inline) { 22977 // ignore setCold when running functions at compile time 22978 return ir_const_void(ira, &instruction->base.base); 22979 } 22980 22981 IrInstGen *is_cold_value = instruction->is_cold->child; 22982 bool want_cold; 22983 if (!ir_resolve_bool(ira, is_cold_value, &want_cold)) 22984 return ira->codegen->invalid_inst_gen; 22985 22986 ZigFn *fn_entry = scope_fn_entry(instruction->base.base.scope); 22987 if (fn_entry == nullptr) { 22988 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setCold outside function")); 22989 return ira->codegen->invalid_inst_gen; 22990 } 22991 22992 if (fn_entry->set_cold_node != nullptr) { 22993 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, buf_sprintf("cold set twice in same function")); 22994 add_error_note(ira->codegen, msg, fn_entry->set_cold_node, buf_sprintf("first set here")); 22995 return ira->codegen->invalid_inst_gen; 22996 } 22997 22998 fn_entry->set_cold_node = instruction->base.base.source_node; 22999 fn_entry->is_cold = want_cold; 23000 23001 return ir_const_void(ira, &instruction->base.base); 23002 } 23003 23004 static IrInstGen *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira, 23005 IrInstSrcSetRuntimeSafety *set_runtime_safety_instruction) 23006 { 23007 if (ira->new_irb.exec->is_inline) { 23008 // ignore setRuntimeSafety when running functions at compile time 23009 return ir_const_void(ira, &set_runtime_safety_instruction->base.base); 23010 } 23011 23012 bool *safety_off_ptr; 23013 AstNode **safety_set_node_ptr; 23014 23015 Scope *scope = set_runtime_safety_instruction->base.base.scope; 23016 while (scope != nullptr) { 23017 if (scope->id == ScopeIdBlock) { 23018 ScopeBlock *block_scope = (ScopeBlock *)scope; 23019 safety_off_ptr = &block_scope->safety_off; 23020 safety_set_node_ptr = &block_scope->safety_set_node; 23021 break; 23022 } else if (scope->id == ScopeIdFnDef) { 23023 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 23024 ZigFn *target_fn = def_scope->fn_entry; 23025 assert(target_fn->def_scope != nullptr); 23026 safety_off_ptr = &target_fn->def_scope->safety_off; 23027 safety_set_node_ptr = &target_fn->def_scope->safety_set_node; 23028 break; 23029 } else if (scope->id == ScopeIdDecls) { 23030 ScopeDecls *decls_scope = (ScopeDecls *)scope; 23031 safety_off_ptr = &decls_scope->safety_off; 23032 safety_set_node_ptr = &decls_scope->safety_set_node; 23033 break; 23034 } else { 23035 scope = scope->parent; 23036 continue; 23037 } 23038 } 23039 assert(scope != nullptr); 23040 23041 IrInstGen *safety_on_value = set_runtime_safety_instruction->safety_on->child; 23042 bool want_runtime_safety; 23043 if (!ir_resolve_bool(ira, safety_on_value, &want_runtime_safety)) 23044 return ira->codegen->invalid_inst_gen; 23045 23046 AstNode *source_node = set_runtime_safety_instruction->base.base.source_node; 23047 if (*safety_set_node_ptr) { 23048 ErrorMsg *msg = ir_add_error_node(ira, source_node, 23049 buf_sprintf("runtime safety set twice for same scope")); 23050 add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here")); 23051 return ira->codegen->invalid_inst_gen; 23052 } 23053 *safety_set_node_ptr = source_node; 23054 *safety_off_ptr = !want_runtime_safety; 23055 23056 return ir_const_void(ira, &set_runtime_safety_instruction->base.base); 23057 } 23058 23059 static IrInstGen *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, 23060 IrInstSrcSetFloatMode *instruction) 23061 { 23062 if (ira->new_irb.exec->is_inline) { 23063 // ignore setFloatMode when running functions at compile time 23064 return ir_const_void(ira, &instruction->base.base); 23065 } 23066 23067 bool *fast_math_on_ptr; 23068 AstNode **fast_math_set_node_ptr; 23069 23070 Scope *scope = instruction->base.base.scope; 23071 while (scope != nullptr) { 23072 if (scope->id == ScopeIdBlock) { 23073 ScopeBlock *block_scope = (ScopeBlock *)scope; 23074 fast_math_on_ptr = &block_scope->fast_math_on; 23075 fast_math_set_node_ptr = &block_scope->fast_math_set_node; 23076 break; 23077 } else if (scope->id == ScopeIdFnDef) { 23078 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 23079 ZigFn *target_fn = def_scope->fn_entry; 23080 assert(target_fn->def_scope != nullptr); 23081 fast_math_on_ptr = &target_fn->def_scope->fast_math_on; 23082 fast_math_set_node_ptr = &target_fn->def_scope->fast_math_set_node; 23083 break; 23084 } else if (scope->id == ScopeIdDecls) { 23085 ScopeDecls *decls_scope = (ScopeDecls *)scope; 23086 fast_math_on_ptr = &decls_scope->fast_math_on; 23087 fast_math_set_node_ptr = &decls_scope->fast_math_set_node; 23088 break; 23089 } else { 23090 scope = scope->parent; 23091 continue; 23092 } 23093 } 23094 assert(scope != nullptr); 23095 23096 IrInstGen *float_mode_value = instruction->mode_value->child; 23097 FloatMode float_mode_scalar; 23098 if (!ir_resolve_float_mode(ira, float_mode_value, &float_mode_scalar)) 23099 return ira->codegen->invalid_inst_gen; 23100 23101 AstNode *source_node = instruction->base.base.source_node; 23102 if (*fast_math_set_node_ptr) { 23103 ErrorMsg *msg = ir_add_error_node(ira, source_node, 23104 buf_sprintf("float mode set twice for same scope")); 23105 add_error_note(ira->codegen, msg, *fast_math_set_node_ptr, buf_sprintf("first set here")); 23106 return ira->codegen->invalid_inst_gen; 23107 } 23108 *fast_math_set_node_ptr = source_node; 23109 *fast_math_on_ptr = (float_mode_scalar == FloatModeOptimized); 23110 23111 return ir_const_void(ira, &instruction->base.base); 23112 } 23113 23114 static IrInstGen *ir_analyze_instruction_any_frame_type(IrAnalyze *ira, IrInstSrcAnyFrameType *instruction) { 23115 ZigType *payload_type = nullptr; 23116 if (instruction->payload_type != nullptr) { 23117 payload_type = ir_resolve_type(ira, instruction->payload_type->child); 23118 if (type_is_invalid(payload_type)) 23119 return ira->codegen->invalid_inst_gen; 23120 } 23121 23122 ZigType *any_frame_type = get_any_frame_type(ira->codegen, payload_type); 23123 return ir_const_type(ira, &instruction->base.base, any_frame_type); 23124 } 23125 23126 static IrInstGen *ir_analyze_instruction_slice_type(IrAnalyze *ira, IrInstSrcSliceType *slice_type_instruction) { 23127 IrInstGen *result = ir_const(ira, &slice_type_instruction->base.base, ira->codegen->builtin_types.entry_type); 23128 result->value->special = ConstValSpecialLazy; 23129 23130 LazyValueSliceType *lazy_slice_type = heap::c_allocator.create<LazyValueSliceType>(); 23131 lazy_slice_type->ira = ira; ira_ref(ira); 23132 result->value->data.x_lazy = &lazy_slice_type->base; 23133 lazy_slice_type->base.id = LazyValueIdSliceType; 23134 23135 if (slice_type_instruction->align_value != nullptr) { 23136 lazy_slice_type->align_inst = slice_type_instruction->align_value->child; 23137 if (ir_resolve_const(ira, lazy_slice_type->align_inst, LazyOk) == nullptr) 23138 return ira->codegen->invalid_inst_gen; 23139 } 23140 23141 if (slice_type_instruction->sentinel != nullptr) { 23142 lazy_slice_type->sentinel = slice_type_instruction->sentinel->child; 23143 if (ir_resolve_const(ira, lazy_slice_type->sentinel, LazyOk) == nullptr) 23144 return ira->codegen->invalid_inst_gen; 23145 } 23146 23147 lazy_slice_type->elem_type = slice_type_instruction->child_type->child; 23148 if (ir_resolve_type_lazy(ira, lazy_slice_type->elem_type) == nullptr) 23149 return ira->codegen->invalid_inst_gen; 23150 23151 lazy_slice_type->is_const = slice_type_instruction->is_const; 23152 lazy_slice_type->is_volatile = slice_type_instruction->is_volatile; 23153 lazy_slice_type->is_allowzero = slice_type_instruction->is_allow_zero; 23154 23155 return result; 23156 } 23157 23158 static IrInstGen *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstSrcAsm *asm_instruction) { 23159 Error err; 23160 23161 assert(asm_instruction->base.base.source_node->type == NodeTypeAsmExpr); 23162 23163 AstNode *node = asm_instruction->base.base.source_node; 23164 AstNodeAsmExpr *asm_expr = &asm_instruction->base.base.source_node->data.asm_expr; 23165 23166 Buf *template_buf = ir_resolve_str(ira, asm_instruction->asm_template->child); 23167 if (template_buf == nullptr) 23168 return ira->codegen->invalid_inst_gen; 23169 23170 if (asm_instruction->is_global) { 23171 buf_append_char(&ira->codegen->global_asm, '\n'); 23172 buf_append_buf(&ira->codegen->global_asm, template_buf); 23173 23174 return ir_const_void(ira, &asm_instruction->base.base); 23175 } 23176 23177 if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base.base)) 23178 return ira->codegen->invalid_inst_gen; 23179 23180 ZigList<AsmToken> tok_list = {}; 23181 if ((err = parse_asm_template(ira, node, template_buf, &tok_list))) { 23182 return ira->codegen->invalid_inst_gen; 23183 } 23184 23185 for (size_t token_i = 0; token_i < tok_list.length; token_i += 1) { 23186 AsmToken asm_token = tok_list.at(token_i); 23187 if (asm_token.id == AsmTokenIdVar) { 23188 size_t index = find_asm_index(ira->codegen, node, &asm_token, template_buf); 23189 if (index == SIZE_MAX) { 23190 const char *ptr = buf_ptr(template_buf) + asm_token.start + 2; 23191 uint32_t len = asm_token.end - asm_token.start - 2; 23192 23193 add_node_error(ira->codegen, node, 23194 buf_sprintf("could not find '%.*s' in the inputs or outputs", 23195 len, ptr)); 23196 return ira->codegen->invalid_inst_gen; 23197 } 23198 } 23199 } 23200 23201 // TODO validate the output types and variable types 23202 23203 IrInstGen **input_list = heap::c_allocator.allocate<IrInstGen *>(asm_expr->input_list.length); 23204 IrInstGen **output_types = heap::c_allocator.allocate<IrInstGen *>(asm_expr->output_list.length); 23205 23206 ZigType *return_type = ira->codegen->builtin_types.entry_void; 23207 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 23208 AsmOutput *asm_output = asm_expr->output_list.at(i); 23209 if (asm_output->return_type) { 23210 output_types[i] = asm_instruction->output_types[i]->child; 23211 return_type = ir_resolve_type(ira, output_types[i]); 23212 if (type_is_invalid(return_type)) 23213 return ira->codegen->invalid_inst_gen; 23214 } 23215 } 23216 23217 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 23218 IrInstGen *const input_value = asm_instruction->input_list[i]->child; 23219 if (type_is_invalid(input_value->value->type)) 23220 return ira->codegen->invalid_inst_gen; 23221 23222 if (instr_is_comptime(input_value) && 23223 (input_value->value->type->id == ZigTypeIdComptimeInt || 23224 input_value->value->type->id == ZigTypeIdComptimeFloat)) { 23225 ir_add_error(ira, &input_value->base, 23226 buf_sprintf("expected sized integer or sized float, found %s", buf_ptr(&input_value->value->type->name))); 23227 return ira->codegen->invalid_inst_gen; 23228 } 23229 23230 input_list[i] = input_value; 23231 } 23232 23233 return ir_build_asm_gen(ira, &asm_instruction->base.base, 23234 template_buf, tok_list.items, tok_list.length, 23235 input_list, output_types, asm_instruction->output_vars, asm_instruction->return_count, 23236 asm_instruction->has_side_effects, return_type); 23237 } 23238 23239 static IrInstGen *ir_analyze_instruction_array_type(IrAnalyze *ira, IrInstSrcArrayType *array_type_instruction) { 23240 IrInstGen *result = ir_const(ira, &array_type_instruction->base.base, ira->codegen->builtin_types.entry_type); 23241 result->value->special = ConstValSpecialLazy; 23242 23243 LazyValueArrayType *lazy_array_type = heap::c_allocator.create<LazyValueArrayType>(); 23244 lazy_array_type->ira = ira; ira_ref(ira); 23245 result->value->data.x_lazy = &lazy_array_type->base; 23246 lazy_array_type->base.id = LazyValueIdArrayType; 23247 23248 lazy_array_type->elem_type = array_type_instruction->child_type->child; 23249 if (ir_resolve_type_lazy(ira, lazy_array_type->elem_type) == nullptr) 23250 return ira->codegen->invalid_inst_gen; 23251 23252 if (!ir_resolve_usize(ira, array_type_instruction->size->child, &lazy_array_type->length)) 23253 return ira->codegen->invalid_inst_gen; 23254 23255 if (array_type_instruction->sentinel != nullptr) { 23256 lazy_array_type->sentinel = array_type_instruction->sentinel->child; 23257 if (ir_resolve_const(ira, lazy_array_type->sentinel, LazyOk) == nullptr) 23258 return ira->codegen->invalid_inst_gen; 23259 } 23260 23261 return result; 23262 } 23263 23264 static IrInstGen *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstSrcSizeOf *instruction) { 23265 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 23266 result->value->special = ConstValSpecialLazy; 23267 23268 LazyValueSizeOf *lazy_size_of = heap::c_allocator.create<LazyValueSizeOf>(); 23269 lazy_size_of->ira = ira; ira_ref(ira); 23270 result->value->data.x_lazy = &lazy_size_of->base; 23271 lazy_size_of->base.id = LazyValueIdSizeOf; 23272 lazy_size_of->bit_size = instruction->bit_size; 23273 23274 lazy_size_of->target_type = instruction->type_value->child; 23275 if (ir_resolve_type_lazy(ira, lazy_size_of->target_type) == nullptr) 23276 return ira->codegen->invalid_inst_gen; 23277 23278 return result; 23279 } 23280 23281 static IrInstGen *ir_analyze_test_non_null(IrAnalyze *ira, IrInst *source_inst, IrInstGen *value) { 23282 ZigType *type_entry = value->value->type; 23283 23284 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.allow_zero) { 23285 if (instr_is_comptime(value)) { 23286 ZigValue *c_ptr_val = ir_resolve_const(ira, value, UndefOk); 23287 if (c_ptr_val == nullptr) 23288 return ira->codegen->invalid_inst_gen; 23289 if (c_ptr_val->special == ConstValSpecialUndef) 23290 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); 23291 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 23292 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 23293 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 23294 return ir_const_bool(ira, source_inst, !is_null); 23295 } 23296 23297 return ir_build_test_non_null_gen(ira, source_inst, value); 23298 } else if (type_entry->id == ZigTypeIdOptional) { 23299 if (instr_is_comptime(value)) { 23300 ZigValue *maybe_val = ir_resolve_const(ira, value, UndefOk); 23301 if (maybe_val == nullptr) 23302 return ira->codegen->invalid_inst_gen; 23303 if (maybe_val->special == ConstValSpecialUndef) 23304 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); 23305 23306 return ir_const_bool(ira, source_inst, !optional_value_is_null(maybe_val)); 23307 } 23308 23309 return ir_build_test_non_null_gen(ira, source_inst, value); 23310 } else if (type_entry->id == ZigTypeIdNull) { 23311 return ir_const_bool(ira, source_inst, false); 23312 } else { 23313 return ir_const_bool(ira, source_inst, true); 23314 } 23315 } 23316 23317 static IrInstGen *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrInstSrcTestNonNull *instruction) { 23318 IrInstGen *value = instruction->value->child; 23319 if (type_is_invalid(value->value->type)) 23320 return ira->codegen->invalid_inst_gen; 23321 23322 return ir_analyze_test_non_null(ira, &instruction->base.base, value); 23323 } 23324 23325 static IrInstGen *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInst* source_instr, 23326 IrInstGen *base_ptr, bool safety_check_on, bool initializing) 23327 { 23328 Error err; 23329 23330 ZigType *type_entry = get_ptr_elem_type(ira->codegen, base_ptr); 23331 if (type_is_invalid(type_entry)) 23332 return ira->codegen->invalid_inst_gen; 23333 23334 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.ptr_len == PtrLenC) { 23335 if (instr_is_comptime(base_ptr)) { 23336 ZigValue *val = ir_resolve_const(ira, base_ptr, UndefBad); 23337 if (!val) 23338 return ira->codegen->invalid_inst_gen; 23339 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 23340 ZigValue *c_ptr_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 23341 if (c_ptr_val == nullptr) 23342 return ira->codegen->invalid_inst_gen; 23343 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 23344 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 23345 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 23346 if (is_null) { 23347 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); 23348 return ira->codegen->invalid_inst_gen; 23349 } 23350 return base_ptr; 23351 } 23352 } 23353 if (!safety_check_on) 23354 return base_ptr; 23355 IrInstGen *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr); 23356 ir_build_assert_non_null(ira, source_instr, c_ptr_val); 23357 return base_ptr; 23358 } 23359 23360 if (type_entry->id != ZigTypeIdOptional) { 23361 ir_add_error(ira, &base_ptr->base, 23362 buf_sprintf("expected optional type, found '%s'", buf_ptr(&type_entry->name))); 23363 return ira->codegen->invalid_inst_gen; 23364 } 23365 23366 ZigType *child_type = type_entry->data.maybe.child_type; 23367 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, 23368 base_ptr->value->type->data.pointer.is_const, base_ptr->value->type->data.pointer.is_volatile, 23369 PtrLenSingle, 0, 0, 0, false); 23370 23371 bool same_comptime_repr = types_have_same_zig_comptime_repr(ira->codegen, child_type, type_entry); 23372 23373 if (instr_is_comptime(base_ptr)) { 23374 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 23375 if (ptr_val == nullptr) 23376 return ira->codegen->invalid_inst_gen; 23377 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 23378 ZigValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 23379 if (optional_val == nullptr) 23380 return ira->codegen->invalid_inst_gen; 23381 23382 if (initializing) { 23383 switch (type_has_one_possible_value(ira->codegen, child_type)) { 23384 case OnePossibleValueInvalid: 23385 return ira->codegen->invalid_inst_gen; 23386 case OnePossibleValueNo: 23387 if (!same_comptime_repr) { 23388 ZigValue *payload_val = ira->codegen->pass1_arena->create<ZigValue>(); 23389 payload_val->type = child_type; 23390 payload_val->special = ConstValSpecialUndef; 23391 payload_val->parent.id = ConstParentIdOptionalPayload; 23392 payload_val->parent.data.p_optional_payload.optional_val = optional_val; 23393 23394 optional_val->data.x_optional = payload_val; 23395 optional_val->special = ConstValSpecialStatic; 23396 } 23397 break; 23398 case OnePossibleValueYes: { 23399 optional_val->special = ConstValSpecialStatic; 23400 optional_val->data.x_optional = get_the_one_possible_value(ira->codegen, child_type); 23401 break; 23402 } 23403 } 23404 } else { 23405 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 23406 source_instr->source_node, optional_val, UndefBad))) 23407 return ira->codegen->invalid_inst_gen; 23408 if (optional_value_is_null(optional_val)) { 23409 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); 23410 return ira->codegen->invalid_inst_gen; 23411 } 23412 } 23413 23414 IrInstGen *result; 23415 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 23416 result = ir_build_optional_unwrap_ptr_gen(ira, source_instr, base_ptr, false, 23417 initializing, result_type); 23418 result->value->special = ConstValSpecialStatic; 23419 } else { 23420 result = ir_const(ira, source_instr, result_type); 23421 } 23422 ZigValue *result_val = result->value; 23423 result_val->data.x_ptr.special = ConstPtrSpecialRef; 23424 result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 23425 switch (type_has_one_possible_value(ira->codegen, child_type)) { 23426 case OnePossibleValueInvalid: 23427 return ira->codegen->invalid_inst_gen; 23428 case OnePossibleValueNo: 23429 if (same_comptime_repr) { 23430 result_val->data.x_ptr.data.ref.pointee = optional_val; 23431 } else { 23432 assert(optional_val->data.x_optional != nullptr); 23433 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; 23434 } 23435 break; 23436 case OnePossibleValueYes: 23437 assert(optional_val->data.x_optional != nullptr); 23438 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; 23439 break; 23440 } 23441 return result; 23442 } 23443 } 23444 23445 return ir_build_optional_unwrap_ptr_gen(ira, source_instr, base_ptr, safety_check_on, 23446 initializing, result_type); 23447 } 23448 23449 static IrInstGen *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, 23450 IrInstSrcOptionalUnwrapPtr *instruction) 23451 { 23452 IrInstGen *base_ptr = instruction->base_ptr->child; 23453 if (type_is_invalid(base_ptr->value->type)) 23454 return ira->codegen->invalid_inst_gen; 23455 23456 return ir_analyze_unwrap_optional_payload(ira, &instruction->base.base, base_ptr, 23457 instruction->safety_check_on, false); 23458 } 23459 23460 static IrInstGen *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstSrcCtz *instruction) { 23461 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 23462 if (type_is_invalid(int_type)) 23463 return ira->codegen->invalid_inst_gen; 23464 23465 IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); 23466 if (type_is_invalid(op->value->type)) 23467 return ira->codegen->invalid_inst_gen; 23468 23469 if (int_type->data.integral.bit_count == 0) 23470 return ir_const_unsigned(ira, &instruction->base.base, 0); 23471 23472 if (instr_is_comptime(op)) { 23473 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 23474 if (val == nullptr) 23475 return ira->codegen->invalid_inst_gen; 23476 if (val->special == ConstValSpecialUndef) 23477 return ir_const_undef(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 23478 size_t result_usize = bigint_ctz(&op->value->data.x_bigint, int_type->data.integral.bit_count); 23479 return ir_const_unsigned(ira, &instruction->base.base, result_usize); 23480 } 23481 23482 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 23483 return ir_build_ctz_gen(ira, &instruction->base.base, return_type, op); 23484 } 23485 23486 static IrInstGen *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstSrcClz *instruction) { 23487 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 23488 if (type_is_invalid(int_type)) 23489 return ira->codegen->invalid_inst_gen; 23490 23491 IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); 23492 if (type_is_invalid(op->value->type)) 23493 return ira->codegen->invalid_inst_gen; 23494 23495 if (int_type->data.integral.bit_count == 0) 23496 return ir_const_unsigned(ira, &instruction->base.base, 0); 23497 23498 if (instr_is_comptime(op)) { 23499 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 23500 if (val == nullptr) 23501 return ira->codegen->invalid_inst_gen; 23502 if (val->special == ConstValSpecialUndef) 23503 return ir_const_undef(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 23504 size_t result_usize = bigint_clz(&op->value->data.x_bigint, int_type->data.integral.bit_count); 23505 return ir_const_unsigned(ira, &instruction->base.base, result_usize); 23506 } 23507 23508 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 23509 return ir_build_clz_gen(ira, &instruction->base.base, return_type, op); 23510 } 23511 23512 static IrInstGen *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstSrcPopCount *instruction) { 23513 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 23514 if (type_is_invalid(int_type)) 23515 return ira->codegen->invalid_inst_gen; 23516 23517 IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); 23518 if (type_is_invalid(op->value->type)) 23519 return ira->codegen->invalid_inst_gen; 23520 23521 if (int_type->data.integral.bit_count == 0) 23522 return ir_const_unsigned(ira, &instruction->base.base, 0); 23523 23524 if (instr_is_comptime(op)) { 23525 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 23526 if (val == nullptr) 23527 return ira->codegen->invalid_inst_gen; 23528 if (val->special == ConstValSpecialUndef) 23529 return ir_const_undef(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 23530 23531 if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { 23532 size_t result = bigint_popcount_unsigned(&val->data.x_bigint); 23533 return ir_const_unsigned(ira, &instruction->base.base, result); 23534 } 23535 size_t result = bigint_popcount_signed(&val->data.x_bigint, int_type->data.integral.bit_count); 23536 return ir_const_unsigned(ira, &instruction->base.base, result); 23537 } 23538 23539 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 23540 return ir_build_pop_count_gen(ira, &instruction->base.base, return_type, op); 23541 } 23542 23543 static IrInstGen *ir_analyze_union_tag(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, bool is_gen) { 23544 if (type_is_invalid(value->value->type)) 23545 return ira->codegen->invalid_inst_gen; 23546 23547 if (value->value->type->id != ZigTypeIdUnion) { 23548 ir_add_error(ira, &value->base, 23549 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value->type->name))); 23550 return ira->codegen->invalid_inst_gen; 23551 } 23552 if (!value->value->type->data.unionation.have_explicit_tag_type && !is_gen) { 23553 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum")); 23554 if (value->value->type->data.unionation.decl_node != nullptr) { 23555 add_error_note(ira->codegen, msg, value->value->type->data.unionation.decl_node, 23556 buf_sprintf("declared here")); 23557 } 23558 return ira->codegen->invalid_inst_gen; 23559 } 23560 23561 ZigType *tag_type = value->value->type->data.unionation.tag_type; 23562 assert(tag_type->id == ZigTypeIdEnum); 23563 23564 if (instr_is_comptime(value)) { 23565 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 23566 if (!val) 23567 return ira->codegen->invalid_inst_gen; 23568 23569 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 23570 source_instr->scope, source_instr->source_node); 23571 const_instruction->base.value->type = tag_type; 23572 const_instruction->base.value->special = ConstValSpecialStatic; 23573 bigint_init_bigint(&const_instruction->base.value->data.x_enum_tag, &val->data.x_union.tag); 23574 return &const_instruction->base; 23575 } 23576 23577 return ir_build_union_tag(ira, source_instr, value, tag_type); 23578 } 23579 23580 static IrInstGen *ir_analyze_instruction_switch_br(IrAnalyze *ira, 23581 IrInstSrcSwitchBr *switch_br_instruction) 23582 { 23583 IrInstGen *target_value = switch_br_instruction->target_value->child; 23584 if (type_is_invalid(target_value->value->type)) 23585 return ir_unreach_error(ira); 23586 23587 if (switch_br_instruction->switch_prongs_void != nullptr) { 23588 if (type_is_invalid(switch_br_instruction->switch_prongs_void->child->value->type)) { 23589 return ir_unreach_error(ira); 23590 } 23591 } 23592 23593 23594 size_t case_count = switch_br_instruction->case_count; 23595 23596 bool is_comptime; 23597 if (!ir_resolve_comptime(ira, switch_br_instruction->is_comptime->child, &is_comptime)) 23598 return ira->codegen->invalid_inst_gen; 23599 23600 if (is_comptime || instr_is_comptime(target_value)) { 23601 ZigValue *target_val = ir_resolve_const(ira, target_value, UndefBad); 23602 if (!target_val) 23603 return ir_unreach_error(ira); 23604 23605 IrBasicBlockSrc *old_dest_block = switch_br_instruction->else_block; 23606 for (size_t i = 0; i < case_count; i += 1) { 23607 IrInstSrcSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 23608 IrInstGen *case_value = old_case->value->child; 23609 if (type_is_invalid(case_value->value->type)) 23610 return ir_unreach_error(ira); 23611 23612 IrInstGen *casted_case_value = ir_implicit_cast(ira, case_value, target_value->value->type); 23613 if (type_is_invalid(casted_case_value->value->type)) 23614 return ir_unreach_error(ira); 23615 23616 ZigValue *case_val = ir_resolve_const(ira, casted_case_value, UndefBad); 23617 if (!case_val) 23618 return ir_unreach_error(ira); 23619 23620 if (const_values_equal(ira->codegen, target_val, case_val)) { 23621 old_dest_block = old_case->block; 23622 break; 23623 } 23624 } 23625 23626 if (is_comptime || old_dest_block->ref_count == 1) { 23627 return ir_inline_bb(ira, &switch_br_instruction->base.base, old_dest_block); 23628 } else { 23629 IrBasicBlockGen *new_dest_block = ir_get_new_bb(ira, old_dest_block, &switch_br_instruction->base.base); 23630 IrInstGen *result = ir_build_br_gen(ira, &switch_br_instruction->base.base, new_dest_block); 23631 return ir_finish_anal(ira, result); 23632 } 23633 } 23634 23635 IrInstGenSwitchBrCase *cases = heap::c_allocator.allocate<IrInstGenSwitchBrCase>(case_count); 23636 for (size_t i = 0; i < case_count; i += 1) { 23637 IrInstSrcSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 23638 IrInstGenSwitchBrCase *new_case = &cases[i]; 23639 new_case->block = ir_get_new_bb(ira, old_case->block, &switch_br_instruction->base.base); 23640 new_case->value = ira->codegen->invalid_inst_gen; 23641 23642 // Calling ir_get_new_bb set the ref_instruction on the new basic block. 23643 // However a switch br may branch to the same basic block which would trigger an 23644 // incorrect re-generation of the block. So we set it to null here and assign 23645 // it back after the loop. 23646 new_case->block->ref_instruction = nullptr; 23647 23648 IrInstSrc *old_value = old_case->value; 23649 IrInstGen *new_value = old_value->child; 23650 if (type_is_invalid(new_value->value->type)) 23651 continue; 23652 23653 IrInstGen *casted_new_value = ir_implicit_cast(ira, new_value, target_value->value->type); 23654 if (type_is_invalid(casted_new_value->value->type)) 23655 continue; 23656 23657 if (!ir_resolve_const(ira, casted_new_value, UndefBad)) 23658 continue; 23659 23660 new_case->value = casted_new_value; 23661 } 23662 23663 for (size_t i = 0; i < case_count; i += 1) { 23664 IrInstGenSwitchBrCase *new_case = &cases[i]; 23665 if (type_is_invalid(new_case->value->value->type)) 23666 return ir_unreach_error(ira); 23667 new_case->block->ref_instruction = &switch_br_instruction->base.base; 23668 } 23669 23670 IrBasicBlockGen *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base.base); 23671 IrInstGenSwitchBr *switch_br = ir_build_switch_br_gen(ira, &switch_br_instruction->base.base, 23672 target_value, new_else_block, case_count, cases); 23673 return ir_finish_anal(ira, &switch_br->base); 23674 } 23675 23676 static IrInstGen *ir_analyze_instruction_switch_target(IrAnalyze *ira, 23677 IrInstSrcSwitchTarget *switch_target_instruction) 23678 { 23679 Error err; 23680 IrInstGen *target_value_ptr = switch_target_instruction->target_value_ptr->child; 23681 if (type_is_invalid(target_value_ptr->value->type)) 23682 return ira->codegen->invalid_inst_gen; 23683 23684 if (target_value_ptr->value->type->id == ZigTypeIdMetaType) { 23685 assert(instr_is_comptime(target_value_ptr)); 23686 ZigType *ptr_type = target_value_ptr->value->data.x_type; 23687 assert(ptr_type->id == ZigTypeIdPointer); 23688 return ir_const_type(ira, &switch_target_instruction->base.base, ptr_type->data.pointer.child_type); 23689 } 23690 23691 ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; 23692 ZigValue *pointee_val = nullptr; 23693 if (instr_is_comptime(target_value_ptr) && target_value_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 23694 pointee_val = const_ptr_pointee(ira, ira->codegen, target_value_ptr->value, target_value_ptr->base.source_node); 23695 if (pointee_val == nullptr) 23696 return ira->codegen->invalid_inst_gen; 23697 23698 if (pointee_val->special == ConstValSpecialRuntime) 23699 pointee_val = nullptr; 23700 } 23701 if ((err = type_resolve(ira->codegen, target_type, ResolveStatusSizeKnown))) 23702 return ira->codegen->invalid_inst_gen; 23703 23704 switch (target_type->id) { 23705 case ZigTypeIdInvalid: 23706 zig_unreachable(); 23707 case ZigTypeIdMetaType: 23708 case ZigTypeIdVoid: 23709 case ZigTypeIdBool: 23710 case ZigTypeIdInt: 23711 case ZigTypeIdFloat: 23712 case ZigTypeIdComptimeFloat: 23713 case ZigTypeIdComptimeInt: 23714 case ZigTypeIdEnumLiteral: 23715 case ZigTypeIdPointer: 23716 case ZigTypeIdFn: 23717 case ZigTypeIdErrorSet: { 23718 if (pointee_val) { 23719 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, nullptr); 23720 copy_const_val(ira->codegen, result->value, pointee_val); 23721 result->value->type = target_type; 23722 return result; 23723 } 23724 23725 IrInstGen *result = ir_get_deref(ira, &switch_target_instruction->base.base, target_value_ptr, nullptr); 23726 result->value->type = target_type; 23727 return result; 23728 } 23729 case ZigTypeIdUnion: { 23730 AstNode *decl_node = target_type->data.unionation.decl_node; 23731 if (!decl_node->data.container_decl.auto_enum && 23732 decl_node->data.container_decl.init_arg_expr == nullptr) 23733 { 23734 ErrorMsg *msg = ir_add_error(ira, &target_value_ptr->base, 23735 buf_sprintf("switch on union which has no attached enum")); 23736 add_error_note(ira->codegen, msg, decl_node, 23737 buf_sprintf("consider 'union(enum)' here")); 23738 return ira->codegen->invalid_inst_gen; 23739 } 23740 ZigType *tag_type = target_type->data.unionation.tag_type; 23741 assert(tag_type != nullptr); 23742 assert(tag_type->id == ZigTypeIdEnum); 23743 if (pointee_val) { 23744 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, tag_type); 23745 bigint_init_bigint(&result->value->data.x_enum_tag, &pointee_val->data.x_union.tag); 23746 return result; 23747 } 23748 if (tag_type->data.enumeration.src_field_count == 1) { 23749 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, tag_type); 23750 TypeEnumField *only_field = &tag_type->data.enumeration.fields[0]; 23751 bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value); 23752 return result; 23753 } 23754 23755 IrInstGen *union_value = ir_get_deref(ira, &switch_target_instruction->base.base, target_value_ptr, nullptr); 23756 union_value->value->type = target_type; 23757 23758 return ir_build_union_tag(ira, &switch_target_instruction->base.base, union_value, tag_type); 23759 } 23760 case ZigTypeIdEnum: { 23761 if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown))) 23762 return ira->codegen->invalid_inst_gen; 23763 if (target_type->data.enumeration.src_field_count == 1) { 23764 TypeEnumField *only_field = &target_type->data.enumeration.fields[0]; 23765 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, target_type); 23766 bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value); 23767 return result; 23768 } 23769 23770 if (pointee_val) { 23771 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, target_type); 23772 bigint_init_bigint(&result->value->data.x_enum_tag, &pointee_val->data.x_enum_tag); 23773 return result; 23774 } 23775 23776 IrInstGen *enum_value = ir_get_deref(ira, &switch_target_instruction->base.base, target_value_ptr, nullptr); 23777 enum_value->value->type = target_type; 23778 return enum_value; 23779 } 23780 case ZigTypeIdErrorUnion: 23781 case ZigTypeIdUnreachable: 23782 case ZigTypeIdArray: 23783 case ZigTypeIdStruct: 23784 case ZigTypeIdUndefined: 23785 case ZigTypeIdNull: 23786 case ZigTypeIdOptional: 23787 case ZigTypeIdBoundFn: 23788 case ZigTypeIdOpaque: 23789 case ZigTypeIdVector: 23790 case ZigTypeIdFnFrame: 23791 case ZigTypeIdAnyFrame: 23792 ir_add_error(ira, &switch_target_instruction->base.base, 23793 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name))); 23794 return ira->codegen->invalid_inst_gen; 23795 } 23796 zig_unreachable(); 23797 } 23798 23799 static IrInstGen *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstSrcSwitchVar *instruction) { 23800 IrInstGen *target_value_ptr = instruction->target_value_ptr->child; 23801 if (type_is_invalid(target_value_ptr->value->type)) 23802 return ira->codegen->invalid_inst_gen; 23803 23804 ZigType *ref_type = target_value_ptr->value->type; 23805 assert(ref_type->id == ZigTypeIdPointer); 23806 ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; 23807 if (target_type->id == ZigTypeIdUnion) { 23808 ZigType *enum_type = target_type->data.unionation.tag_type; 23809 assert(enum_type != nullptr); 23810 assert(enum_type->id == ZigTypeIdEnum); 23811 assert(instruction->prongs_len > 0); 23812 23813 IrInstGen *first_prong_value = instruction->prongs_ptr[0]->child; 23814 if (type_is_invalid(first_prong_value->value->type)) 23815 return ira->codegen->invalid_inst_gen; 23816 23817 IrInstGen *first_casted_prong_value = ir_implicit_cast(ira, first_prong_value, enum_type); 23818 if (type_is_invalid(first_casted_prong_value->value->type)) 23819 return ira->codegen->invalid_inst_gen; 23820 23821 ZigValue *first_prong_val = ir_resolve_const(ira, first_casted_prong_value, UndefBad); 23822 if (first_prong_val == nullptr) 23823 return ira->codegen->invalid_inst_gen; 23824 23825 TypeUnionField *first_field = find_union_field_by_tag(target_type, &first_prong_val->data.x_enum_tag); 23826 23827 ErrorMsg *invalid_payload_msg = nullptr; 23828 for (size_t prong_i = 1; prong_i < instruction->prongs_len; prong_i += 1) { 23829 IrInstGen *this_prong_inst = instruction->prongs_ptr[prong_i]->child; 23830 if (type_is_invalid(this_prong_inst->value->type)) 23831 return ira->codegen->invalid_inst_gen; 23832 23833 IrInstGen *this_casted_prong_value = ir_implicit_cast(ira, this_prong_inst, enum_type); 23834 if (type_is_invalid(this_casted_prong_value->value->type)) 23835 return ira->codegen->invalid_inst_gen; 23836 23837 ZigValue *this_prong = ir_resolve_const(ira, this_casted_prong_value, UndefBad); 23838 if (this_prong == nullptr) 23839 return ira->codegen->invalid_inst_gen; 23840 23841 TypeUnionField *payload_field = find_union_field_by_tag(target_type, &this_prong->data.x_enum_tag); 23842 ZigType *payload_type = payload_field->type_entry; 23843 if (first_field->type_entry != payload_type) { 23844 if (invalid_payload_msg == nullptr) { 23845 invalid_payload_msg = ir_add_error(ira, &instruction->base.base, 23846 buf_sprintf("capture group with incompatible types")); 23847 add_error_note(ira->codegen, invalid_payload_msg, first_prong_value->base.source_node, 23848 buf_sprintf("type '%s' here", buf_ptr(&first_field->type_entry->name))); 23849 } 23850 add_error_note(ira->codegen, invalid_payload_msg, this_prong_inst->base.source_node, 23851 buf_sprintf("type '%s' here", buf_ptr(&payload_field->type_entry->name))); 23852 } 23853 } 23854 23855 if (invalid_payload_msg != nullptr) { 23856 return ira->codegen->invalid_inst_gen; 23857 } 23858 23859 if (instr_is_comptime(target_value_ptr)) { 23860 ZigValue *target_val_ptr = ir_resolve_const(ira, target_value_ptr, UndefBad); 23861 if (!target_value_ptr) 23862 return ira->codegen->invalid_inst_gen; 23863 23864 ZigValue *pointee_val = const_ptr_pointee(ira, ira->codegen, target_val_ptr, instruction->base.base.source_node); 23865 if (pointee_val == nullptr) 23866 return ira->codegen->invalid_inst_gen; 23867 23868 IrInstGen *result = ir_const(ira, &instruction->base.base, 23869 get_pointer_to_type(ira->codegen, first_field->type_entry, 23870 target_val_ptr->type->data.pointer.is_const)); 23871 ZigValue *out_val = result->value; 23872 out_val->data.x_ptr.special = ConstPtrSpecialRef; 23873 out_val->data.x_ptr.mut = target_val_ptr->data.x_ptr.mut; 23874 out_val->data.x_ptr.data.ref.pointee = pointee_val->data.x_union.payload; 23875 return result; 23876 } 23877 23878 ZigType *result_type = get_pointer_to_type(ira->codegen, first_field->type_entry, 23879 target_value_ptr->value->type->data.pointer.is_const); 23880 return ir_build_union_field_ptr(ira, &instruction->base.base, target_value_ptr, first_field, 23881 false, false, result_type); 23882 } else if (target_type->id == ZigTypeIdErrorSet) { 23883 // construct an error set from the prong values 23884 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 23885 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 23886 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 23887 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 23888 ZigList<ErrorTableEntry *> error_list = {}; 23889 buf_resize(&err_set_type->name, 0); 23890 buf_appendf(&err_set_type->name, "error{"); 23891 for (size_t i = 0; i < instruction->prongs_len; i += 1) { 23892 ErrorTableEntry *err = ir_resolve_error(ira, instruction->prongs_ptr[i]->child); 23893 if (err == nullptr) 23894 return ira->codegen->invalid_inst_gen; 23895 error_list.append(err); 23896 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&err->name)); 23897 } 23898 err_set_type->data.error_set.errors = error_list.items; 23899 err_set_type->data.error_set.err_count = error_list.length; 23900 buf_appendf(&err_set_type->name, "}"); 23901 23902 23903 ZigType *new_target_value_ptr_type = get_pointer_to_type_extra(ira->codegen, 23904 err_set_type, 23905 ref_type->data.pointer.is_const, ref_type->data.pointer.is_volatile, 23906 ref_type->data.pointer.ptr_len, 23907 ref_type->data.pointer.explicit_alignment, 23908 ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, 23909 ref_type->data.pointer.allow_zero); 23910 return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, 23911 &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false, false); 23912 } else { 23913 ir_add_error(ira, &instruction->base.base, 23914 buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); 23915 return ira->codegen->invalid_inst_gen; 23916 } 23917 } 23918 23919 static IrInstGen *ir_analyze_instruction_switch_else_var(IrAnalyze *ira, 23920 IrInstSrcSwitchElseVar *instruction) 23921 { 23922 IrInstGen *target_value_ptr = instruction->target_value_ptr->child; 23923 if (type_is_invalid(target_value_ptr->value->type)) 23924 return ira->codegen->invalid_inst_gen; 23925 23926 ZigType *ref_type = target_value_ptr->value->type; 23927 assert(ref_type->id == ZigTypeIdPointer); 23928 ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; 23929 if (target_type->id == ZigTypeIdErrorSet) { 23930 // make a new set that has the other cases removed 23931 if (!resolve_inferred_error_set(ira->codegen, target_type, instruction->base.base.source_node)) { 23932 return ira->codegen->invalid_inst_gen; 23933 } 23934 if (type_is_global_error_set(target_type)) { 23935 // the type of the else capture variable still has to be the global error set. 23936 // once the runtime hint system is more sophisticated, we could add some hint information here. 23937 return target_value_ptr; 23938 } 23939 // Make note of the errors handled by other cases 23940 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); 23941 // We may not have any case in the switch if this is a lone else 23942 const size_t switch_cases = instruction->switch_br ? instruction->switch_br->case_count : 0; 23943 for (size_t case_i = 0; case_i < switch_cases; case_i += 1) { 23944 IrInstSrcSwitchBrCase *br_case = &instruction->switch_br->cases[case_i]; 23945 IrInstGen *case_expr = br_case->value->child; 23946 if (case_expr->value->type->id == ZigTypeIdErrorSet) { 23947 ErrorTableEntry *err = ir_resolve_error(ira, case_expr); 23948 if (err == nullptr) 23949 return ira->codegen->invalid_inst_gen; 23950 errors[err->value] = err; 23951 } else if (case_expr->value->type->id == ZigTypeIdMetaType) { 23952 ZigType *err_set_type = ir_resolve_type(ira, case_expr); 23953 if (type_is_invalid(err_set_type)) 23954 return ira->codegen->invalid_inst_gen; 23955 populate_error_set_table(errors, err_set_type); 23956 } else { 23957 zig_unreachable(); 23958 } 23959 } 23960 ZigList<ErrorTableEntry *> result_list = {}; 23961 23962 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 23963 buf_resize(&err_set_type->name, 0); 23964 buf_appendf(&err_set_type->name, "error{"); 23965 23966 // Look at all the errors in the type switched on and add them to the result_list 23967 // if they are not handled by cases. 23968 for (uint32_t i = 0; i < target_type->data.error_set.err_count; i += 1) { 23969 ErrorTableEntry *error_entry = target_type->data.error_set.errors[i]; 23970 ErrorTableEntry *existing_entry = errors[error_entry->value]; 23971 if (existing_entry == nullptr) { 23972 result_list.append(error_entry); 23973 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); 23974 } 23975 } 23976 heap::c_allocator.deallocate(errors, ira->codegen->errors_by_index.length); 23977 23978 err_set_type->data.error_set.err_count = result_list.length; 23979 err_set_type->data.error_set.errors = result_list.items; 23980 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 23981 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 23982 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 23983 23984 buf_appendf(&err_set_type->name, "}"); 23985 23986 ZigType *new_target_value_ptr_type = get_pointer_to_type_extra(ira->codegen, 23987 err_set_type, 23988 ref_type->data.pointer.is_const, ref_type->data.pointer.is_volatile, 23989 ref_type->data.pointer.ptr_len, 23990 ref_type->data.pointer.explicit_alignment, 23991 ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, 23992 ref_type->data.pointer.allow_zero); 23993 return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, 23994 &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false, false); 23995 } 23996 23997 return target_value_ptr; 23998 } 23999 24000 static IrInstGen *ir_analyze_instruction_import(IrAnalyze *ira, IrInstSrcImport *import_instruction) { 24001 Error err; 24002 24003 IrInstGen *name_value = import_instruction->name->child; 24004 Buf *import_target_str = ir_resolve_str(ira, name_value); 24005 if (!import_target_str) 24006 return ira->codegen->invalid_inst_gen; 24007 24008 AstNode *source_node = import_instruction->base.base.source_node; 24009 ZigType *import = source_node->owner; 24010 24011 ZigType *target_import; 24012 Buf *import_target_path; 24013 Buf full_path = BUF_INIT; 24014 if ((err = analyze_import(ira->codegen, import, import_target_str, &target_import, 24015 &import_target_path, &full_path))) 24016 { 24017 if (err == ErrorImportOutsidePkgPath) { 24018 ir_add_error_node(ira, source_node, 24019 buf_sprintf("import of file outside package path: '%s'", 24020 buf_ptr(import_target_path))); 24021 return ira->codegen->invalid_inst_gen; 24022 } else if (err == ErrorFileNotFound) { 24023 ir_add_error_node(ira, source_node, 24024 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); 24025 return ira->codegen->invalid_inst_gen; 24026 } else { 24027 ir_add_error_node(ira, source_node, 24028 buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); 24029 return ira->codegen->invalid_inst_gen; 24030 } 24031 } 24032 24033 return ir_const_type(ira, &import_instruction->base.base, target_import); 24034 } 24035 24036 static IrInstGen *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstSrcRef *ref_instruction) { 24037 IrInstGen *value = ref_instruction->value->child; 24038 if (type_is_invalid(value->value->type)) 24039 return ira->codegen->invalid_inst_gen; 24040 24041 bool is_const = false; 24042 bool is_volatile = false; 24043 24044 ZigValue *child_value = value->value; 24045 if (child_value->special == ConstValSpecialStatic) { 24046 is_const = true; 24047 } 24048 24049 return ir_get_ref(ira, &ref_instruction->base.base, value, is_const, is_volatile); 24050 } 24051 24052 static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instruction, 24053 AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstGen *field_result_loc, 24054 IrInstGen *result_loc) 24055 { 24056 Error err; 24057 assert(union_type->id == ZigTypeIdUnion); 24058 24059 if ((err = type_resolve(ira->codegen, union_type, ResolveStatusZeroBitsKnown))) 24060 return ira->codegen->invalid_inst_gen; 24061 24062 TypeUnionField *type_field = find_union_type_field(union_type, field_name); 24063 if (type_field == nullptr) { 24064 ir_add_error_node(ira, field_source_node, 24065 buf_sprintf("no field named '%s' in union '%s'", 24066 buf_ptr(field_name), buf_ptr(&union_type->name))); 24067 return ira->codegen->invalid_inst_gen; 24068 } 24069 24070 if (type_is_invalid(type_field->type_entry)) 24071 return ira->codegen->invalid_inst_gen; 24072 24073 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { 24074 if (instr_is_comptime(field_result_loc) && 24075 field_result_loc->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 24076 { 24077 // nothing 24078 } else { 24079 result_loc->value->special = ConstValSpecialRuntime; 24080 } 24081 } 24082 24083 bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instruction->scope) 24084 || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes; 24085 24086 IrInstGen *result = ir_get_deref(ira, source_instruction, result_loc, nullptr); 24087 if (is_comptime && !instr_is_comptime(result)) { 24088 ir_add_error(ira, &field_result_loc->base, 24089 buf_sprintf("unable to evaluate constant expression")); 24090 return ira->codegen->invalid_inst_gen; 24091 } 24092 return result; 24093 } 24094 24095 static IrInstGen *ir_analyze_container_init_fields(IrAnalyze *ira, IrInst *source_instr, 24096 ZigType *container_type, size_t instr_field_count, IrInstSrcContainerInitFieldsField *fields, 24097 IrInstGen *result_loc) 24098 { 24099 Error err; 24100 if (container_type->id == ZigTypeIdUnion) { 24101 if (instr_field_count != 1) { 24102 ir_add_error(ira, source_instr, 24103 buf_sprintf("union initialization expects exactly one field")); 24104 return ira->codegen->invalid_inst_gen; 24105 } 24106 IrInstSrcContainerInitFieldsField *field = &fields[0]; 24107 IrInstGen *field_result_loc = field->result_loc->child; 24108 if (type_is_invalid(field_result_loc->value->type)) 24109 return ira->codegen->invalid_inst_gen; 24110 24111 return ir_analyze_union_init(ira, source_instr, field->source_node, container_type, field->name, 24112 field_result_loc, result_loc); 24113 } 24114 if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { 24115 ir_add_error(ira, source_instr, 24116 buf_sprintf("type '%s' does not support struct initialization syntax", 24117 buf_ptr(&container_type->name))); 24118 return ira->codegen->invalid_inst_gen; 24119 } 24120 24121 if (container_type->data.structure.resolve_status == ResolveStatusBeingInferred) { 24122 // We're now done inferring the type. 24123 container_type->data.structure.resolve_status = ResolveStatusUnstarted; 24124 } 24125 24126 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 24127 return ira->codegen->invalid_inst_gen; 24128 24129 size_t actual_field_count = container_type->data.structure.src_field_count; 24130 24131 IrInstGen *first_non_const_instruction = nullptr; 24132 24133 AstNode **field_assign_nodes = heap::c_allocator.allocate<AstNode *>(actual_field_count); 24134 ZigList<IrInstGen *> const_ptrs = {}; 24135 24136 bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope) 24137 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; 24138 24139 24140 // Here we iterate over the fields that have been initialized, and emit 24141 // compile errors for missing fields and duplicate fields. 24142 // It is only now that we find out whether the struct initialization can be a comptime 24143 // value, but we have already emitted runtime instructions for the fields that 24144 // were initialized with runtime values, and have omitted instructions that would have 24145 // initialized fields with comptime values. 24146 // So now we must clean up this situation. If it turns out the struct initialization can 24147 // be a comptime value, overwrite ConstPtrMutInfer with ConstPtrMutComptimeConst. 24148 // Otherwise, we must emit instructions to runtime-initialize the fields that have 24149 // comptime-known values. 24150 24151 for (size_t i = 0; i < instr_field_count; i += 1) { 24152 IrInstSrcContainerInitFieldsField *field = &fields[i]; 24153 24154 IrInstGen *field_result_loc = field->result_loc->child; 24155 if (type_is_invalid(field_result_loc->value->type)) 24156 return ira->codegen->invalid_inst_gen; 24157 24158 TypeStructField *type_field = find_struct_type_field(container_type, field->name); 24159 if (!type_field) { 24160 ir_add_error_node(ira, field->source_node, 24161 buf_sprintf("no field named '%s' in struct '%s'", 24162 buf_ptr(field->name), buf_ptr(&container_type->name))); 24163 return ira->codegen->invalid_inst_gen; 24164 } 24165 24166 if (type_is_invalid(type_field->type_entry)) 24167 return ira->codegen->invalid_inst_gen; 24168 24169 size_t field_index = type_field->src_index; 24170 AstNode *existing_assign_node = field_assign_nodes[field_index]; 24171 if (existing_assign_node) { 24172 ErrorMsg *msg = ir_add_error_node(ira, field->source_node, buf_sprintf("duplicate field")); 24173 add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here")); 24174 return ira->codegen->invalid_inst_gen; 24175 } 24176 field_assign_nodes[field_index] = field->source_node; 24177 24178 if (instr_is_comptime(field_result_loc) && 24179 field_result_loc->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 24180 { 24181 const_ptrs.append(field_result_loc); 24182 } else { 24183 first_non_const_instruction = field_result_loc; 24184 } 24185 } 24186 24187 bool any_missing = false; 24188 for (size_t i = 0; i < actual_field_count; i += 1) { 24189 if (field_assign_nodes[i] != nullptr) continue; 24190 24191 // look for a default field value 24192 TypeStructField *field = container_type->data.structure.fields[i]; 24193 memoize_field_init_val(ira->codegen, container_type, field); 24194 if (field->init_val == nullptr) { 24195 ir_add_error(ira, source_instr, 24196 buf_sprintf("missing field: '%s'", buf_ptr(field->name))); 24197 any_missing = true; 24198 continue; 24199 } 24200 if (type_is_invalid(field->init_val->type)) 24201 return ira->codegen->invalid_inst_gen; 24202 24203 IrInstGen *runtime_inst = ir_const(ira, source_instr, field->init_val->type); 24204 copy_const_val(ira->codegen, runtime_inst->value, field->init_val); 24205 24206 IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, result_loc, 24207 container_type, true); 24208 ir_analyze_store_ptr(ira, source_instr, field_ptr, runtime_inst, false); 24209 if (instr_is_comptime(field_ptr) && field_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 24210 const_ptrs.append(field_ptr); 24211 } else { 24212 first_non_const_instruction = result_loc; 24213 } 24214 } 24215 if (any_missing) 24216 return ira->codegen->invalid_inst_gen; 24217 24218 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { 24219 if (const_ptrs.length != actual_field_count) { 24220 result_loc->value->special = ConstValSpecialRuntime; 24221 for (size_t i = 0; i < const_ptrs.length; i += 1) { 24222 IrInstGen *field_result_loc = const_ptrs.at(i); 24223 IrInstGen *deref = ir_get_deref(ira, &field_result_loc->base, field_result_loc, nullptr); 24224 field_result_loc->value->special = ConstValSpecialRuntime; 24225 ir_analyze_store_ptr(ira, &field_result_loc->base, field_result_loc, deref, false); 24226 } 24227 } 24228 } 24229 24230 IrInstGen *result = ir_get_deref(ira, source_instr, result_loc, nullptr); 24231 24232 if (is_comptime && !instr_is_comptime(result)) { 24233 ir_add_error_node(ira, first_non_const_instruction->base.source_node, 24234 buf_sprintf("unable to evaluate constant expression")); 24235 return ira->codegen->invalid_inst_gen; 24236 } 24237 24238 return result; 24239 } 24240 24241 static IrInstGen *ir_analyze_instruction_container_init_list(IrAnalyze *ira, 24242 IrInstSrcContainerInitList *instruction) 24243 { 24244 ir_assert(instruction->result_loc != nullptr, &instruction->base.base); 24245 IrInstGen *result_loc = instruction->result_loc->child; 24246 if (type_is_invalid(result_loc->value->type)) 24247 return result_loc; 24248 24249 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); 24250 if (result_loc->value->type->data.pointer.is_const) { 24251 ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant")); 24252 return ira->codegen->invalid_inst_gen; 24253 } 24254 24255 ZigType *container_type = result_loc->value->type->data.pointer.child_type; 24256 size_t elem_count = instruction->item_count; 24257 24258 if (is_slice(container_type)) { 24259 ir_add_error_node(ira, instruction->init_array_type_source_node, 24260 buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", 24261 buf_ptr(&container_type->name))); 24262 return ira->codegen->invalid_inst_gen; 24263 } 24264 24265 if (container_type->id == ZigTypeIdVoid) { 24266 if (elem_count != 0) { 24267 ir_add_error_node(ira, instruction->base.base.source_node, 24268 buf_sprintf("void expression expects no arguments")); 24269 return ira->codegen->invalid_inst_gen; 24270 } 24271 return ir_const_void(ira, &instruction->base.base); 24272 } 24273 24274 if (container_type->id == ZigTypeIdStruct && elem_count == 0) { 24275 ir_assert(instruction->result_loc != nullptr, &instruction->base.base); 24276 IrInstGen *result_loc = instruction->result_loc->child; 24277 if (type_is_invalid(result_loc->value->type)) 24278 return result_loc; 24279 return ir_analyze_container_init_fields(ira, &instruction->base.base, container_type, 0, nullptr, result_loc); 24280 } 24281 24282 if (container_type->id == ZigTypeIdArray) { 24283 ZigType *child_type = container_type->data.array.child_type; 24284 if (container_type->data.array.len != elem_count) { 24285 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count, nullptr); 24286 24287 ir_add_error(ira, &instruction->base.base, 24288 buf_sprintf("expected %s literal, found %s literal", 24289 buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); 24290 return ira->codegen->invalid_inst_gen; 24291 } 24292 } else if (container_type->id == ZigTypeIdStruct && 24293 container_type->data.structure.resolve_status == ResolveStatusBeingInferred) 24294 { 24295 // We're now done inferring the type. 24296 container_type->data.structure.resolve_status = ResolveStatusUnstarted; 24297 } else if (container_type->id == ZigTypeIdVector) { 24298 // OK 24299 } else { 24300 ir_add_error(ira, &instruction->base.base, 24301 buf_sprintf("type '%s' does not support array initialization", 24302 buf_ptr(&container_type->name))); 24303 return ira->codegen->invalid_inst_gen; 24304 } 24305 24306 switch (type_has_one_possible_value(ira->codegen, container_type)) { 24307 case OnePossibleValueInvalid: 24308 return ira->codegen->invalid_inst_gen; 24309 case OnePossibleValueYes: 24310 return ir_const_move(ira, &instruction->base.base, 24311 get_the_one_possible_value(ira->codegen, container_type)); 24312 case OnePossibleValueNo: 24313 break; 24314 } 24315 24316 bool is_comptime; 24317 switch (type_requires_comptime(ira->codegen, container_type)) { 24318 case ReqCompTimeInvalid: 24319 return ira->codegen->invalid_inst_gen; 24320 case ReqCompTimeNo: 24321 is_comptime = ir_should_inline(ira->old_irb.exec, instruction->base.base.scope); 24322 break; 24323 case ReqCompTimeYes: 24324 is_comptime = true; 24325 break; 24326 } 24327 24328 IrInstGen *first_non_const_instruction = nullptr; 24329 24330 // The Result Location Mechanism has already emitted runtime instructions to 24331 // initialize runtime elements and has omitted instructions for the comptime 24332 // elements. However it is only now that we find out whether the array initialization 24333 // can be a comptime value. So we must clean up the situation. If it turns out 24334 // array initialization can be a comptime value, overwrite ConstPtrMutInfer with 24335 // ConstPtrMutComptimeConst. Otherwise, emit instructions to runtime-initialize the 24336 // elements that have comptime-known values. 24337 ZigList<IrInstGen *> const_ptrs = {}; 24338 24339 for (size_t i = 0; i < elem_count; i += 1) { 24340 IrInstGen *elem_result_loc = instruction->elem_result_loc_list[i]->child; 24341 if (type_is_invalid(elem_result_loc->value->type)) 24342 return ira->codegen->invalid_inst_gen; 24343 24344 assert(elem_result_loc->value->type->id == ZigTypeIdPointer); 24345 24346 if (instr_is_comptime(elem_result_loc) && 24347 elem_result_loc->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 24348 { 24349 const_ptrs.append(elem_result_loc); 24350 } else { 24351 first_non_const_instruction = elem_result_loc; 24352 } 24353 } 24354 24355 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { 24356 if (const_ptrs.length != elem_count) { 24357 result_loc->value->special = ConstValSpecialRuntime; 24358 for (size_t i = 0; i < const_ptrs.length; i += 1) { 24359 IrInstGen *elem_result_loc = const_ptrs.at(i); 24360 assert(elem_result_loc->value->special == ConstValSpecialStatic); 24361 if (elem_result_loc->value->type->data.pointer.inferred_struct_field != nullptr) { 24362 // This field will be generated comptime; no need to do this. 24363 continue; 24364 } 24365 IrInstGen *deref = ir_get_deref(ira, &elem_result_loc->base, elem_result_loc, nullptr); 24366 elem_result_loc->value->special = ConstValSpecialRuntime; 24367 ir_analyze_store_ptr(ira, &elem_result_loc->base, elem_result_loc, deref, false); 24368 } 24369 } 24370 } 24371 24372 const_ptrs.deinit(); 24373 24374 IrInstGen *result = ir_get_deref(ira, &instruction->base.base, result_loc, nullptr); 24375 // If the result is a tuple, we are allowed to return a struct that uses ConstValSpecialRuntime fields at comptime. 24376 if (instr_is_comptime(result) || is_tuple(container_type)) 24377 return result; 24378 24379 if (is_comptime) { 24380 ir_add_error(ira, &first_non_const_instruction->base, 24381 buf_sprintf("unable to evaluate constant expression")); 24382 return ira->codegen->invalid_inst_gen; 24383 } 24384 24385 ZigType *result_elem_type = result_loc->value->type->data.pointer.child_type; 24386 if (is_slice(result_elem_type)) { 24387 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 24388 buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'", 24389 buf_ptr(&result_elem_type->name))); 24390 add_error_note(ira->codegen, msg, first_non_const_instruction->base.source_node, 24391 buf_sprintf("this value is not comptime-known")); 24392 return ira->codegen->invalid_inst_gen; 24393 } 24394 return result; 24395 } 24396 24397 static IrInstGen *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, 24398 IrInstSrcContainerInitFields *instruction) 24399 { 24400 ir_assert(instruction->result_loc != nullptr, &instruction->base.base); 24401 IrInstGen *result_loc = instruction->result_loc->child; 24402 if (type_is_invalid(result_loc->value->type)) 24403 return result_loc; 24404 24405 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); 24406 if (result_loc->value->type->data.pointer.is_const) { 24407 ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant")); 24408 return ira->codegen->invalid_inst_gen; 24409 } 24410 24411 ZigType *container_type = result_loc->value->type->data.pointer.child_type; 24412 24413 return ir_analyze_container_init_fields(ira, &instruction->base.base, container_type, 24414 instruction->field_count, instruction->fields, result_loc); 24415 } 24416 24417 static IrInstGen *ir_analyze_instruction_compile_err(IrAnalyze *ira, IrInstSrcCompileErr *instruction) { 24418 IrInstGen *msg_value = instruction->msg->child; 24419 Buf *msg_buf = ir_resolve_str(ira, msg_value); 24420 if (!msg_buf) 24421 return ira->codegen->invalid_inst_gen; 24422 24423 ir_add_error(ira, &instruction->base.base, msg_buf); 24424 24425 return ira->codegen->invalid_inst_gen; 24426 } 24427 24428 static IrInstGen *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInstSrcCompileLog *instruction) { 24429 Buf buf = BUF_INIT; 24430 fprintf(stderr, "| "); 24431 for (size_t i = 0; i < instruction->msg_count; i += 1) { 24432 IrInstGen *msg = instruction->msg_list[i]->child; 24433 if (type_is_invalid(msg->value->type)) 24434 return ira->codegen->invalid_inst_gen; 24435 buf_resize(&buf, 0); 24436 if (msg->value->special == ConstValSpecialLazy) { 24437 // Resolve any lazy value that's passed, we need its value 24438 if (ir_resolve_lazy(ira->codegen, msg->base.source_node, msg->value)) 24439 return ira->codegen->invalid_inst_gen; 24440 } 24441 render_const_value(ira->codegen, &buf, msg->value); 24442 const char *comma_str = (i != 0) ? ", " : ""; 24443 fprintf(stderr, "%s%s", comma_str, buf_ptr(&buf)); 24444 } 24445 fprintf(stderr, "\n"); 24446 24447 auto *expr = &instruction->base.base.source_node->data.fn_call_expr; 24448 if (!expr->seen) { 24449 // Here we bypass higher level functions such as ir_add_error because we do not want 24450 // invalidate_exec to be called. 24451 add_node_error(ira->codegen, instruction->base.base.source_node, buf_sprintf("found compile log statement")); 24452 } 24453 expr->seen = true; 24454 24455 return ir_const_void(ira, &instruction->base.base); 24456 } 24457 24458 static IrInstGen *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstSrcErrName *instruction) { 24459 IrInstGen *value = instruction->value->child; 24460 if (type_is_invalid(value->value->type)) 24461 return ira->codegen->invalid_inst_gen; 24462 24463 IrInstGen *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_global_error_set); 24464 if (type_is_invalid(casted_value->value->type)) 24465 return ira->codegen->invalid_inst_gen; 24466 24467 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 24468 true, false, PtrLenUnknown, 0, 0, 0, false); 24469 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 24470 if (instr_is_comptime(casted_value)) { 24471 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); 24472 if (val == nullptr) 24473 return ira->codegen->invalid_inst_gen; 24474 ErrorTableEntry *err = casted_value->value->data.x_err_set; 24475 if (!err->cached_error_name_val) { 24476 ZigValue *array_val = create_const_str_lit(ira->codegen, &err->name)->data.x_ptr.data.ref.pointee; 24477 err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); 24478 } 24479 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 24480 copy_const_val(ira->codegen, result->value, err->cached_error_name_val); 24481 result->value->type = str_type; 24482 return result; 24483 } 24484 24485 ira->codegen->generate_error_name_table = true; 24486 24487 return ir_build_err_name_gen(ira, &instruction->base.base, value, str_type); 24488 } 24489 24490 static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrcTagName *instruction) { 24491 Error err; 24492 IrInstGen *target = instruction->target->child; 24493 if (type_is_invalid(target->value->type)) 24494 return ira->codegen->invalid_inst_gen; 24495 24496 if (target->value->type->id == ZigTypeIdEnumLiteral) { 24497 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 24498 Buf *field_name = target->value->data.x_enum_literal; 24499 ZigValue *array_val = create_const_str_lit(ira->codegen, field_name)->data.x_ptr.data.ref.pointee; 24500 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field_name), true); 24501 return result; 24502 } 24503 24504 if (target->value->type->id == ZigTypeIdUnion) { 24505 target = ir_analyze_union_tag(ira, &instruction->base.base, target, instruction->base.is_gen); 24506 if (type_is_invalid(target->value->type)) 24507 return ira->codegen->invalid_inst_gen; 24508 } 24509 24510 if (target->value->type->id != ZigTypeIdEnum) { 24511 ir_add_error(ira, &target->base, 24512 buf_sprintf("expected enum tag, found '%s'", buf_ptr(&target->value->type->name))); 24513 return ira->codegen->invalid_inst_gen; 24514 } 24515 24516 if (target->value->type->data.enumeration.src_field_count == 1 && 24517 !target->value->type->data.enumeration.non_exhaustive) { 24518 TypeEnumField *only_field = &target->value->type->data.enumeration.fields[0]; 24519 ZigValue *array_val = create_const_str_lit(ira->codegen, only_field->name)->data.x_ptr.data.ref.pointee; 24520 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 24521 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(only_field->name), true); 24522 return result; 24523 } 24524 24525 if (instr_is_comptime(target)) { 24526 if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusZeroBitsKnown))) 24527 return ira->codegen->invalid_inst_gen; 24528 TypeEnumField *field = find_enum_field_by_tag(target->value->type, &target->value->data.x_bigint); 24529 if (field == nullptr) { 24530 Buf *int_buf = buf_alloc(); 24531 bigint_append_buf(int_buf, &target->value->data.x_bigint, 10); 24532 24533 ir_add_error(ira, &target->base, 24534 buf_sprintf("no tag by value %s", buf_ptr(int_buf))); 24535 return ira->codegen->invalid_inst_gen; 24536 } 24537 ZigValue *array_val = create_const_str_lit(ira->codegen, field->name)->data.x_ptr.data.ref.pointee; 24538 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 24539 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field->name), true); 24540 return result; 24541 } 24542 24543 ZigType *u8_ptr_type = get_pointer_to_type_extra( 24544 ira->codegen, ira->codegen->builtin_types.entry_u8, 24545 true, false, PtrLenUnknown, 24546 0, 0, 0, false); 24547 ZigType *result_type = get_slice_type(ira->codegen, u8_ptr_type); 24548 return ir_build_tag_name_gen(ira, &instruction->base.base, target, result_type); 24549 } 24550 24551 static IrInstGen *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, 24552 IrInstSrcFieldParentPtr *instruction) 24553 { 24554 Error err; 24555 IrInstGen *type_value = instruction->type_value->child; 24556 ZigType *container_type = ir_resolve_type(ira, type_value); 24557 if (type_is_invalid(container_type)) 24558 return ira->codegen->invalid_inst_gen; 24559 24560 IrInstGen *field_name_value = instruction->field_name->child; 24561 Buf *field_name = ir_resolve_str(ira, field_name_value); 24562 if (!field_name) 24563 return ira->codegen->invalid_inst_gen; 24564 24565 IrInstGen *field_ptr = instruction->field_ptr->child; 24566 if (type_is_invalid(field_ptr->value->type)) 24567 return ira->codegen->invalid_inst_gen; 24568 24569 if (container_type->id != ZigTypeIdStruct) { 24570 ir_add_error(ira, &type_value->base, 24571 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 24572 return ira->codegen->invalid_inst_gen; 24573 } 24574 24575 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 24576 return ira->codegen->invalid_inst_gen; 24577 24578 TypeStructField *field = find_struct_type_field(container_type, field_name); 24579 if (field == nullptr) { 24580 ir_add_error(ira, &field_name_value->base, 24581 buf_sprintf("struct '%s' has no field '%s'", 24582 buf_ptr(&container_type->name), buf_ptr(field_name))); 24583 return ira->codegen->invalid_inst_gen; 24584 } 24585 24586 if (field_ptr->value->type->id != ZigTypeIdPointer) { 24587 ir_add_error(ira, &field_ptr->base, 24588 buf_sprintf("expected pointer, found '%s'", buf_ptr(&field_ptr->value->type->name))); 24589 return ira->codegen->invalid_inst_gen; 24590 } 24591 24592 bool is_packed = (container_type->data.structure.layout == ContainerLayoutPacked); 24593 uint32_t field_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); 24594 uint32_t parent_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, container_type); 24595 24596 ZigType *field_ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, 24597 field_ptr->value->type->data.pointer.is_const, 24598 field_ptr->value->type->data.pointer.is_volatile, 24599 PtrLenSingle, 24600 field_ptr_align, 0, 0, false); 24601 IrInstGen *casted_field_ptr = ir_implicit_cast(ira, field_ptr, field_ptr_type); 24602 if (type_is_invalid(casted_field_ptr->value->type)) 24603 return ira->codegen->invalid_inst_gen; 24604 24605 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, container_type, 24606 casted_field_ptr->value->type->data.pointer.is_const, 24607 casted_field_ptr->value->type->data.pointer.is_volatile, 24608 PtrLenSingle, 24609 parent_ptr_align, 0, 0, false); 24610 24611 if (instr_is_comptime(casted_field_ptr)) { 24612 ZigValue *field_ptr_val = ir_resolve_const(ira, casted_field_ptr, UndefBad); 24613 if (!field_ptr_val) 24614 return ira->codegen->invalid_inst_gen; 24615 24616 if (field_ptr_val->data.x_ptr.special != ConstPtrSpecialBaseStruct) { 24617 ir_add_error(ira, &field_ptr->base, buf_sprintf("pointer value not based on parent struct")); 24618 return ira->codegen->invalid_inst_gen; 24619 } 24620 24621 size_t ptr_field_index = field_ptr_val->data.x_ptr.data.base_struct.field_index; 24622 if (ptr_field_index != field->src_index) { 24623 ir_add_error(ira, &instruction->base.base, 24624 buf_sprintf("field '%s' has index %" ZIG_PRI_usize " but pointer value is index %" ZIG_PRI_usize " of struct '%s'", 24625 buf_ptr(field->name), field->src_index, 24626 ptr_field_index, buf_ptr(&container_type->name))); 24627 return ira->codegen->invalid_inst_gen; 24628 } 24629 24630 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 24631 ZigValue *out_val = result->value; 24632 out_val->data.x_ptr.special = ConstPtrSpecialRef; 24633 out_val->data.x_ptr.data.ref.pointee = field_ptr_val->data.x_ptr.data.base_struct.struct_val; 24634 out_val->data.x_ptr.mut = field_ptr_val->data.x_ptr.mut; 24635 return result; 24636 } 24637 24638 return ir_build_field_parent_ptr_gen(ira, &instruction->base.base, casted_field_ptr, field, result_type); 24639 } 24640 24641 static TypeStructField *validate_byte_offset(IrAnalyze *ira, 24642 IrInstGen *type_value, 24643 IrInstGen *field_name_value, 24644 size_t *byte_offset) 24645 { 24646 ZigType *container_type = ir_resolve_type(ira, type_value); 24647 if (type_is_invalid(container_type)) 24648 return nullptr; 24649 24650 Error err; 24651 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 24652 return nullptr; 24653 24654 Buf *field_name = ir_resolve_str(ira, field_name_value); 24655 if (!field_name) 24656 return nullptr; 24657 24658 if (container_type->id != ZigTypeIdStruct) { 24659 ir_add_error(ira, &type_value->base, 24660 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 24661 return nullptr; 24662 } 24663 24664 TypeStructField *field = find_struct_type_field(container_type, field_name); 24665 if (field == nullptr) { 24666 ir_add_error(ira, &field_name_value->base, 24667 buf_sprintf("struct '%s' has no field '%s'", 24668 buf_ptr(&container_type->name), buf_ptr(field_name))); 24669 return nullptr; 24670 } 24671 24672 if (!type_has_bits(ira->codegen, field->type_entry)) { 24673 ir_add_error(ira, &field_name_value->base, 24674 buf_sprintf("zero-bit field '%s' in struct '%s' has no offset", 24675 buf_ptr(field_name), buf_ptr(&container_type->name))); 24676 return nullptr; 24677 } 24678 24679 *byte_offset = field->offset; 24680 return field; 24681 } 24682 24683 static IrInstGen *ir_analyze_instruction_byte_offset_of(IrAnalyze *ira, IrInstSrcByteOffsetOf *instruction) { 24684 IrInstGen *type_value = instruction->type_value->child; 24685 if (type_is_invalid(type_value->value->type)) 24686 return ira->codegen->invalid_inst_gen; 24687 24688 IrInstGen *field_name_value = instruction->field_name->child; 24689 size_t byte_offset = 0; 24690 if (!validate_byte_offset(ira, type_value, field_name_value, &byte_offset)) 24691 return ira->codegen->invalid_inst_gen; 24692 24693 24694 return ir_const_unsigned(ira, &instruction->base.base, byte_offset); 24695 } 24696 24697 static IrInstGen *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, IrInstSrcBitOffsetOf *instruction) { 24698 IrInstGen *type_value = instruction->type_value->child; 24699 if (type_is_invalid(type_value->value->type)) 24700 return ira->codegen->invalid_inst_gen; 24701 IrInstGen *field_name_value = instruction->field_name->child; 24702 size_t byte_offset = 0; 24703 TypeStructField *field = nullptr; 24704 if (!(field = validate_byte_offset(ira, type_value, field_name_value, &byte_offset))) 24705 return ira->codegen->invalid_inst_gen; 24706 24707 size_t bit_offset = byte_offset * 8 + field->bit_offset_in_host; 24708 return ir_const_unsigned(ira, &instruction->base.base, bit_offset); 24709 } 24710 24711 static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { 24712 Buf *field_name_buf; 24713 24714 assert(type != nullptr && !type_is_invalid(type)); 24715 field_name_buf = buf_create_from_str(field_name); 24716 TypeStructField *field = find_struct_type_field(type, field_name_buf); 24717 buf_deinit(field_name_buf); 24718 24719 if (field == nullptr || field->src_index != index) 24720 zig_panic("reference to unknown field %s", field_name); 24721 } 24722 24723 static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, ZigType *root) { 24724 Error err; 24725 ZigType *type_info_type = get_builtin_type(ira->codegen, "TypeInfo"); 24726 assert(type_info_type->id == ZigTypeIdUnion); 24727 if ((err = type_resolve(ira->codegen, type_info_type, ResolveStatusSizeKnown))) { 24728 zig_unreachable(); 24729 } 24730 24731 if (type_name == nullptr && root == nullptr) 24732 return type_info_type; 24733 else if (type_name == nullptr) 24734 return root; 24735 24736 ZigType *root_type = (root == nullptr) ? type_info_type : root; 24737 24738 ScopeDecls *type_info_scope = get_container_scope(root_type); 24739 assert(type_info_scope != nullptr); 24740 24741 Buf field_name = BUF_INIT; 24742 buf_init_from_str(&field_name, type_name); 24743 auto entry = type_info_scope->decl_table.get(&field_name); 24744 buf_deinit(&field_name); 24745 24746 TldVar *tld = (TldVar *)entry; 24747 assert(tld->base.id == TldIdVar); 24748 24749 ZigVar *var = tld->var; 24750 24751 assert(var->const_value->type->id == ZigTypeIdMetaType); 24752 24753 return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, nullptr, var->const_value); 24754 } 24755 24756 static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigValue *out_val, 24757 ScopeDecls *decls_scope, bool resolve_types) 24758 { 24759 Error err; 24760 ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr); 24761 if ((err = type_resolve(ira->codegen, type_info_declaration_type, ResolveStatusSizeKnown))) 24762 return err; 24763 24764 ensure_field_index(type_info_declaration_type, "name", 0); 24765 ensure_field_index(type_info_declaration_type, "is_pub", 1); 24766 ensure_field_index(type_info_declaration_type, "data", 2); 24767 24768 if (!resolve_types) { 24769 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, type_info_declaration_type, 24770 false, false, PtrLenUnknown, 0, 0, 0, false); 24771 24772 out_val->special = ConstValSpecialLazy; 24773 out_val->type = get_slice_type(ira->codegen, ptr_type); 24774 24775 LazyValueTypeInfoDecls *lazy_type_info_decls = heap::c_allocator.create<LazyValueTypeInfoDecls>(); 24776 lazy_type_info_decls->ira = ira; ira_ref(ira); 24777 out_val->data.x_lazy = &lazy_type_info_decls->base; 24778 lazy_type_info_decls->base.id = LazyValueIdTypeInfoDecls; 24779 24780 lazy_type_info_decls->source_instr = source_instr; 24781 lazy_type_info_decls->decls_scope = decls_scope; 24782 24783 return ErrorNone; 24784 } 24785 24786 ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type); 24787 if ((err = type_resolve(ira->codegen, type_info_declaration_data_type, ResolveStatusSizeKnown))) 24788 return err; 24789 24790 ZigType *type_info_fn_decl_type = ir_type_info_get_type(ira, "FnDecl", type_info_declaration_data_type); 24791 if ((err = type_resolve(ira->codegen, type_info_fn_decl_type, ResolveStatusSizeKnown))) 24792 return err; 24793 24794 ZigType *type_info_fn_decl_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_decl_type); 24795 if ((err = type_resolve(ira->codegen, type_info_fn_decl_inline_type, ResolveStatusSizeKnown))) 24796 return err; 24797 24798 // The unresolved declarations are collected in a separate queue to avoid 24799 // modifying decl_table while iterating over it 24800 ZigList<Tld*> resolve_decl_queue{}; 24801 24802 auto decl_it = decls_scope->decl_table.entry_iterator(); 24803 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; 24804 while ((curr_entry = decl_it.next()) != nullptr) { 24805 if (curr_entry->value->resolution == TldResolutionInvalid) { 24806 return ErrorSemanticAnalyzeFail; 24807 } 24808 24809 if (curr_entry->value->resolution == TldResolutionResolving) { 24810 ir_error_dependency_loop(ira, source_instr); 24811 return ErrorSemanticAnalyzeFail; 24812 } 24813 24814 // If the declaration is unresolved, force it to be resolved again. 24815 if (curr_entry->value->resolution == TldResolutionUnresolved) 24816 resolve_decl_queue.append(curr_entry->value); 24817 } 24818 24819 for (size_t i = 0; i < resolve_decl_queue.length; i++) { 24820 Tld *decl = resolve_decl_queue.at(i); 24821 resolve_top_level_decl(ira->codegen, decl, decl->source_node, false); 24822 if (decl->resolution == TldResolutionInvalid) { 24823 return ErrorSemanticAnalyzeFail; 24824 } 24825 } 24826 24827 resolve_decl_queue.deinit(); 24828 24829 // Loop through our declarations once to figure out how many declarations we will generate info for. 24830 int declaration_count = 0; 24831 decl_it = decls_scope->decl_table.entry_iterator(); 24832 while ((curr_entry = decl_it.next()) != nullptr) { 24833 // Skip comptime blocks and test functions. 24834 if (curr_entry->value->id == TldIdCompTime) 24835 continue; 24836 24837 if (curr_entry->value->id == TldIdFn) { 24838 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 24839 if (fn_entry->is_test) 24840 continue; 24841 } 24842 24843 declaration_count += 1; 24844 } 24845 24846 ZigValue *declaration_array = ira->codegen->pass1_arena->create<ZigValue>(); 24847 declaration_array->special = ConstValSpecialStatic; 24848 declaration_array->type = get_array_type(ira->codegen, type_info_declaration_type, declaration_count, nullptr); 24849 declaration_array->data.x_array.special = ConstArraySpecialNone; 24850 declaration_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(declaration_count); 24851 init_const_slice(ira->codegen, out_val, declaration_array, 0, declaration_count, false); 24852 24853 // Loop through the declarations and generate info. 24854 decl_it = decls_scope->decl_table.entry_iterator(); 24855 curr_entry = nullptr; 24856 int declaration_index = 0; 24857 while ((curr_entry = decl_it.next()) != nullptr) { 24858 // Skip comptime blocks and test functions. 24859 if (curr_entry->value->id == TldIdCompTime) { 24860 continue; 24861 } else if (curr_entry->value->id == TldIdFn) { 24862 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 24863 if (fn_entry->is_test) 24864 continue; 24865 } 24866 24867 ZigValue *declaration_val = &declaration_array->data.x_array.data.s_none.elements[declaration_index]; 24868 24869 declaration_val->special = ConstValSpecialStatic; 24870 declaration_val->type = type_info_declaration_type; 24871 24872 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3); 24873 ZigValue *name = create_const_str_lit(ira->codegen, curr_entry->key)->data.x_ptr.data.ref.pointee; 24874 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(curr_entry->key), true); 24875 inner_fields[1]->special = ConstValSpecialStatic; 24876 inner_fields[1]->type = ira->codegen->builtin_types.entry_bool; 24877 inner_fields[1]->data.x_bool = curr_entry->value->visib_mod == VisibModPub; 24878 inner_fields[2]->special = ConstValSpecialStatic; 24879 inner_fields[2]->type = type_info_declaration_data_type; 24880 inner_fields[2]->parent.id = ConstParentIdStruct; 24881 inner_fields[2]->parent.data.p_struct.struct_val = declaration_val; 24882 inner_fields[2]->parent.data.p_struct.field_index = 1; 24883 24884 switch (curr_entry->value->id) { 24885 case TldIdVar: 24886 { 24887 ZigVar *var = ((TldVar *)curr_entry->value)->var; 24888 assert(var != nullptr); 24889 24890 if ((err = type_resolve(ira->codegen, var->const_value->type, ResolveStatusSizeKnown))) 24891 return ErrorSemanticAnalyzeFail; 24892 24893 if (var->const_value->type->id == ZigTypeIdMetaType) { 24894 // We have a variable of type 'type', so it's actually a type declaration. 24895 // 0: Data.Type: type 24896 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0); 24897 inner_fields[2]->data.x_union.payload = var->const_value; 24898 } else { 24899 // We have a variable of another type, so we store the type of the variable. 24900 // 1: Data.Var: type 24901 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 1); 24902 24903 ZigValue *payload = ira->codegen->pass1_arena->create<ZigValue>(); 24904 payload->special = ConstValSpecialStatic; 24905 payload->type = ira->codegen->builtin_types.entry_type; 24906 payload->data.x_type = var->const_value->type; 24907 24908 inner_fields[2]->data.x_union.payload = payload; 24909 } 24910 24911 break; 24912 } 24913 case TldIdFn: 24914 { 24915 // 2: Data.Fn: Data.FnDecl 24916 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 2); 24917 24918 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 24919 assert(!fn_entry->is_test); 24920 assert(fn_entry->type_entry != nullptr); 24921 24922 AstNodeFnProto *fn_node = &fn_entry->proto_node->data.fn_proto; 24923 24924 ZigValue *fn_decl_val = ira->codegen->pass1_arena->create<ZigValue>(); 24925 fn_decl_val->special = ConstValSpecialStatic; 24926 fn_decl_val->type = type_info_fn_decl_type; 24927 fn_decl_val->parent.id = ConstParentIdUnion; 24928 fn_decl_val->parent.data.p_union.union_val = inner_fields[2]; 24929 24930 ZigValue **fn_decl_fields = alloc_const_vals_ptrs(ira->codegen, 9); 24931 fn_decl_val->data.x_struct.fields = fn_decl_fields; 24932 24933 // fn_type: type 24934 ensure_field_index(fn_decl_val->type, "fn_type", 0); 24935 fn_decl_fields[0]->special = ConstValSpecialStatic; 24936 fn_decl_fields[0]->type = ira->codegen->builtin_types.entry_type; 24937 fn_decl_fields[0]->data.x_type = fn_entry->type_entry; 24938 // inline_type: Data.FnDecl.Inline 24939 ensure_field_index(fn_decl_val->type, "inline_type", 1); 24940 fn_decl_fields[1]->special = ConstValSpecialStatic; 24941 fn_decl_fields[1]->type = type_info_fn_decl_inline_type; 24942 bigint_init_unsigned(&fn_decl_fields[1]->data.x_enum_tag, fn_entry->fn_inline); 24943 // is_var_args: bool 24944 ensure_field_index(fn_decl_val->type, "is_var_args", 2); 24945 bool is_varargs = fn_node->is_var_args; 24946 fn_decl_fields[2]->special = ConstValSpecialStatic; 24947 fn_decl_fields[2]->type = ira->codegen->builtin_types.entry_bool; 24948 fn_decl_fields[2]->data.x_bool = is_varargs; 24949 // is_extern: bool 24950 ensure_field_index(fn_decl_val->type, "is_extern", 3); 24951 fn_decl_fields[3]->special = ConstValSpecialStatic; 24952 fn_decl_fields[3]->type = ira->codegen->builtin_types.entry_bool; 24953 fn_decl_fields[3]->data.x_bool = fn_node->is_extern; 24954 // is_export: bool 24955 ensure_field_index(fn_decl_val->type, "is_export", 4); 24956 fn_decl_fields[4]->special = ConstValSpecialStatic; 24957 fn_decl_fields[4]->type = ira->codegen->builtin_types.entry_bool; 24958 fn_decl_fields[4]->data.x_bool = fn_node->is_export; 24959 // lib_name: ?[]const u8 24960 ensure_field_index(fn_decl_val->type, "lib_name", 5); 24961 fn_decl_fields[5]->special = ConstValSpecialStatic; 24962 ZigType *u8_ptr = get_pointer_to_type_extra( 24963 ira->codegen, ira->codegen->builtin_types.entry_u8, 24964 true, false, PtrLenUnknown, 24965 0, 0, 0, false); 24966 fn_decl_fields[5]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); 24967 if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) { 24968 fn_decl_fields[5]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>(); 24969 ZigValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name)->data.x_ptr.data.ref.pointee; 24970 init_const_slice(ira->codegen, fn_decl_fields[5]->data.x_optional, lib_name, 0, 24971 buf_len(fn_node->lib_name), true); 24972 } else { 24973 fn_decl_fields[5]->data.x_optional = nullptr; 24974 } 24975 // return_type: type 24976 ensure_field_index(fn_decl_val->type, "return_type", 6); 24977 fn_decl_fields[6]->special = ConstValSpecialStatic; 24978 fn_decl_fields[6]->type = ira->codegen->builtin_types.entry_type; 24979 fn_decl_fields[6]->data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; 24980 // arg_names: [][] const u8 24981 ensure_field_index(fn_decl_val->type, "arg_names", 7); 24982 size_t fn_arg_count = fn_entry->variable_list.length; 24983 ZigValue *fn_arg_name_array = ira->codegen->pass1_arena->create<ZigValue>(); 24984 fn_arg_name_array->special = ConstValSpecialStatic; 24985 fn_arg_name_array->type = get_array_type(ira->codegen, 24986 get_slice_type(ira->codegen, u8_ptr), fn_arg_count, nullptr); 24987 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; 24988 fn_arg_name_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(fn_arg_count); 24989 24990 init_const_slice(ira->codegen, fn_decl_fields[7], fn_arg_name_array, 0, fn_arg_count, false); 24991 24992 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { 24993 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index); 24994 ZigValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index]; 24995 ZigValue *arg_name = create_const_str_lit(ira->codegen, 24996 buf_create_from_str(arg_var->name))->data.x_ptr.data.ref.pointee; 24997 init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, strlen(arg_var->name), true); 24998 fn_arg_name_val->parent.id = ConstParentIdArray; 24999 fn_arg_name_val->parent.data.p_array.array_val = fn_arg_name_array; 25000 fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index; 25001 } 25002 25003 inner_fields[2]->data.x_union.payload = fn_decl_val; 25004 break; 25005 } 25006 case TldIdContainer: 25007 { 25008 ZigType *type_entry = ((TldContainer *)curr_entry->value)->type_entry; 25009 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) 25010 return ErrorSemanticAnalyzeFail; 25011 25012 // This is a type. 25013 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0); 25014 25015 ZigValue *payload = ira->codegen->pass1_arena->create<ZigValue>(); 25016 payload->special = ConstValSpecialStatic; 25017 payload->type = ira->codegen->builtin_types.entry_type; 25018 payload->data.x_type = type_entry; 25019 25020 inner_fields[2]->data.x_union.payload = payload; 25021 25022 break; 25023 } 25024 default: 25025 zig_unreachable(); 25026 } 25027 25028 declaration_val->data.x_struct.fields = inner_fields; 25029 declaration_index += 1; 25030 } 25031 25032 assert(declaration_index == declaration_count); 25033 return ErrorNone; 25034 } 25035 25036 static BuiltinPtrSize ptr_len_to_size_enum_index(PtrLen ptr_len) { 25037 switch (ptr_len) { 25038 case PtrLenSingle: 25039 return BuiltinPtrSizeOne; 25040 case PtrLenUnknown: 25041 return BuiltinPtrSizeMany; 25042 case PtrLenC: 25043 return BuiltinPtrSizeC; 25044 } 25045 zig_unreachable(); 25046 } 25047 25048 static PtrLen size_enum_index_to_ptr_len(BuiltinPtrSize size_enum_index) { 25049 switch (size_enum_index) { 25050 case BuiltinPtrSizeOne: 25051 return PtrLenSingle; 25052 case BuiltinPtrSizeMany: 25053 case BuiltinPtrSizeSlice: 25054 return PtrLenUnknown; 25055 case BuiltinPtrSizeC: 25056 return PtrLenC; 25057 } 25058 zig_unreachable(); 25059 } 25060 25061 static ZigValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_entry) { 25062 Error err; 25063 ZigType *attrs_type; 25064 BuiltinPtrSize size_enum_index; 25065 if (is_slice(ptr_type_entry)) { 25066 attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index]->type_entry; 25067 size_enum_index = BuiltinPtrSizeSlice; 25068 } else if (ptr_type_entry->id == ZigTypeIdPointer) { 25069 attrs_type = ptr_type_entry; 25070 size_enum_index = ptr_len_to_size_enum_index(ptr_type_entry->data.pointer.ptr_len); 25071 } else { 25072 zig_unreachable(); 25073 } 25074 25075 if ((err = type_resolve(ira->codegen, attrs_type->data.pointer.child_type, ResolveStatusSizeKnown))) 25076 return nullptr; 25077 25078 ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); 25079 assertNoError(type_resolve(ira->codegen, type_info_pointer_type, ResolveStatusSizeKnown)); 25080 25081 ZigValue *result = ira->codegen->pass1_arena->create<ZigValue>(); 25082 result->special = ConstValSpecialStatic; 25083 result->type = type_info_pointer_type; 25084 25085 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 7); 25086 result->data.x_struct.fields = fields; 25087 25088 // size: Size 25089 ensure_field_index(result->type, "size", 0); 25090 ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type); 25091 assertNoError(type_resolve(ira->codegen, type_info_pointer_size_type, ResolveStatusSizeKnown)); 25092 fields[0]->special = ConstValSpecialStatic; 25093 fields[0]->type = type_info_pointer_size_type; 25094 bigint_init_unsigned(&fields[0]->data.x_enum_tag, size_enum_index); 25095 25096 // is_const: bool 25097 ensure_field_index(result->type, "is_const", 1); 25098 fields[1]->special = ConstValSpecialStatic; 25099 fields[1]->type = ira->codegen->builtin_types.entry_bool; 25100 fields[1]->data.x_bool = attrs_type->data.pointer.is_const; 25101 // is_volatile: bool 25102 ensure_field_index(result->type, "is_volatile", 2); 25103 fields[2]->special = ConstValSpecialStatic; 25104 fields[2]->type = ira->codegen->builtin_types.entry_bool; 25105 fields[2]->data.x_bool = attrs_type->data.pointer.is_volatile; 25106 // alignment: u32 25107 ensure_field_index(result->type, "alignment", 3); 25108 fields[3]->special = ConstValSpecialStatic; 25109 fields[3]->type = ira->codegen->builtin_types.entry_num_lit_int; 25110 bigint_init_unsigned(&fields[3]->data.x_bigint, get_ptr_align(ira->codegen, attrs_type)); 25111 // child: type 25112 ensure_field_index(result->type, "child", 4); 25113 fields[4]->special = ConstValSpecialStatic; 25114 fields[4]->type = ira->codegen->builtin_types.entry_type; 25115 fields[4]->data.x_type = attrs_type->data.pointer.child_type; 25116 // is_allowzero: bool 25117 ensure_field_index(result->type, "is_allowzero", 5); 25118 fields[5]->special = ConstValSpecialStatic; 25119 fields[5]->type = ira->codegen->builtin_types.entry_bool; 25120 fields[5]->data.x_bool = attrs_type->data.pointer.allow_zero; 25121 // sentinel: anytype 25122 ensure_field_index(result->type, "sentinel", 6); 25123 fields[6]->special = ConstValSpecialStatic; 25124 if (attrs_type->data.pointer.child_type->id != ZigTypeIdOpaque) { 25125 fields[6]->type = get_optional_type(ira->codegen, attrs_type->data.pointer.child_type); 25126 set_optional_payload(fields[6], attrs_type->data.pointer.sentinel); 25127 } else { 25128 fields[6]->type = ira->codegen->builtin_types.entry_null; 25129 } 25130 25131 return result; 25132 }; 25133 25134 static void make_enum_field_val(IrAnalyze *ira, ZigValue *enum_field_val, TypeEnumField *enum_field, 25135 ZigType *type_info_enum_field_type) 25136 { 25137 enum_field_val->special = ConstValSpecialStatic; 25138 enum_field_val->type = type_info_enum_field_type; 25139 25140 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 2); 25141 inner_fields[1]->special = ConstValSpecialStatic; 25142 inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; 25143 25144 ZigValue *name = create_const_str_lit(ira->codegen, enum_field->name)->data.x_ptr.data.ref.pointee; 25145 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(enum_field->name), true); 25146 25147 bigint_init_bigint(&inner_fields[1]->data.x_bigint, &enum_field->value); 25148 25149 enum_field_val->data.x_struct.fields = inner_fields; 25150 } 25151 25152 static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigType *type_entry, 25153 ZigValue **out) 25154 { 25155 Error err; 25156 assert(type_entry != nullptr); 25157 assert(!type_is_invalid(type_entry)); 25158 25159 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) 25160 return err; 25161 25162 auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); 25163 if (entry != nullptr) { 25164 *out = entry->value; 25165 return ErrorNone; 25166 } 25167 25168 ZigValue *result = nullptr; 25169 switch (type_entry->id) { 25170 case ZigTypeIdInvalid: 25171 zig_unreachable(); 25172 case ZigTypeIdMetaType: 25173 case ZigTypeIdVoid: 25174 case ZigTypeIdBool: 25175 case ZigTypeIdUnreachable: 25176 case ZigTypeIdComptimeFloat: 25177 case ZigTypeIdComptimeInt: 25178 case ZigTypeIdEnumLiteral: 25179 case ZigTypeIdUndefined: 25180 case ZigTypeIdNull: 25181 case ZigTypeIdOpaque: 25182 result = ira->codegen->intern.for_void(); 25183 break; 25184 case ZigTypeIdInt: 25185 { 25186 result = ira->codegen->pass1_arena->create<ZigValue>(); 25187 result->special = ConstValSpecialStatic; 25188 result->type = ir_type_info_get_type(ira, "Int", nullptr); 25189 25190 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2); 25191 result->data.x_struct.fields = fields; 25192 25193 // is_signed: bool 25194 ensure_field_index(result->type, "is_signed", 0); 25195 fields[0]->special = ConstValSpecialStatic; 25196 fields[0]->type = ira->codegen->builtin_types.entry_bool; 25197 fields[0]->data.x_bool = type_entry->data.integral.is_signed; 25198 // bits: u8 25199 ensure_field_index(result->type, "bits", 1); 25200 fields[1]->special = ConstValSpecialStatic; 25201 fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; 25202 bigint_init_unsigned(&fields[1]->data.x_bigint, type_entry->data.integral.bit_count); 25203 25204 break; 25205 } 25206 case ZigTypeIdFloat: 25207 { 25208 result = ira->codegen->pass1_arena->create<ZigValue>(); 25209 result->special = ConstValSpecialStatic; 25210 result->type = ir_type_info_get_type(ira, "Float", nullptr); 25211 25212 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); 25213 result->data.x_struct.fields = fields; 25214 25215 // bits: u8 25216 ensure_field_index(result->type, "bits", 0); 25217 fields[0]->special = ConstValSpecialStatic; 25218 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; 25219 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.floating.bit_count); 25220 25221 break; 25222 } 25223 case ZigTypeIdPointer: 25224 { 25225 result = create_ptr_like_type_info(ira, type_entry); 25226 if (result == nullptr) 25227 return ErrorSemanticAnalyzeFail; 25228 break; 25229 } 25230 case ZigTypeIdArray: 25231 { 25232 result = ira->codegen->pass1_arena->create<ZigValue>(); 25233 result->special = ConstValSpecialStatic; 25234 result->type = ir_type_info_get_type(ira, "Array", nullptr); 25235 25236 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 3); 25237 result->data.x_struct.fields = fields; 25238 25239 // len: usize 25240 ensure_field_index(result->type, "len", 0); 25241 fields[0]->special = ConstValSpecialStatic; 25242 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; 25243 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.array.len); 25244 // child: type 25245 ensure_field_index(result->type, "child", 1); 25246 fields[1]->special = ConstValSpecialStatic; 25247 fields[1]->type = ira->codegen->builtin_types.entry_type; 25248 fields[1]->data.x_type = type_entry->data.array.child_type; 25249 // sentinel: anytype 25250 fields[2]->special = ConstValSpecialStatic; 25251 fields[2]->type = get_optional_type(ira->codegen, type_entry->data.array.child_type); 25252 fields[2]->data.x_optional = type_entry->data.array.sentinel; 25253 break; 25254 } 25255 case ZigTypeIdVector: { 25256 result = ira->codegen->pass1_arena->create<ZigValue>(); 25257 result->special = ConstValSpecialStatic; 25258 result->type = ir_type_info_get_type(ira, "Vector", nullptr); 25259 25260 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2); 25261 result->data.x_struct.fields = fields; 25262 25263 // len: usize 25264 ensure_field_index(result->type, "len", 0); 25265 fields[0]->special = ConstValSpecialStatic; 25266 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; 25267 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.vector.len); 25268 // child: type 25269 ensure_field_index(result->type, "child", 1); 25270 fields[1]->special = ConstValSpecialStatic; 25271 fields[1]->type = ira->codegen->builtin_types.entry_type; 25272 fields[1]->data.x_type = type_entry->data.vector.elem_type; 25273 25274 break; 25275 } 25276 case ZigTypeIdOptional: 25277 { 25278 result = ira->codegen->pass1_arena->create<ZigValue>(); 25279 result->special = ConstValSpecialStatic; 25280 result->type = ir_type_info_get_type(ira, "Optional", nullptr); 25281 25282 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); 25283 result->data.x_struct.fields = fields; 25284 25285 // child: type 25286 ensure_field_index(result->type, "child", 0); 25287 fields[0]->special = ConstValSpecialStatic; 25288 fields[0]->type = ira->codegen->builtin_types.entry_type; 25289 fields[0]->data.x_type = type_entry->data.maybe.child_type; 25290 25291 break; 25292 } 25293 case ZigTypeIdAnyFrame: { 25294 result = ira->codegen->pass1_arena->create<ZigValue>(); 25295 result->special = ConstValSpecialStatic; 25296 result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr); 25297 25298 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); 25299 result->data.x_struct.fields = fields; 25300 25301 // child: ?type 25302 ensure_field_index(result->type, "child", 0); 25303 fields[0]->special = ConstValSpecialStatic; 25304 fields[0]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 25305 fields[0]->data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr : 25306 create_const_type(ira->codegen, type_entry->data.any_frame.result_type); 25307 break; 25308 } 25309 case ZigTypeIdEnum: 25310 { 25311 result = ira->codegen->pass1_arena->create<ZigValue>(); 25312 result->special = ConstValSpecialStatic; 25313 result->type = ir_type_info_get_type(ira, "Enum", nullptr); 25314 25315 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 5); 25316 result->data.x_struct.fields = fields; 25317 25318 // layout: ContainerLayout 25319 ensure_field_index(result->type, "layout", 0); 25320 fields[0]->special = ConstValSpecialStatic; 25321 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 25322 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.enumeration.layout); 25323 // tag_type: type 25324 ensure_field_index(result->type, "tag_type", 1); 25325 fields[1]->special = ConstValSpecialStatic; 25326 fields[1]->type = ira->codegen->builtin_types.entry_type; 25327 fields[1]->data.x_type = type_entry->data.enumeration.tag_int_type; 25328 // fields: []TypeInfo.EnumField 25329 ensure_field_index(result->type, "fields", 2); 25330 25331 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 25332 if ((err = type_resolve(ira->codegen, type_info_enum_field_type, ResolveStatusSizeKnown))) { 25333 zig_unreachable(); 25334 } 25335 uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; 25336 25337 ZigValue *enum_field_array = ira->codegen->pass1_arena->create<ZigValue>(); 25338 enum_field_array->special = ConstValSpecialStatic; 25339 enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count, nullptr); 25340 enum_field_array->data.x_array.special = ConstArraySpecialNone; 25341 enum_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(enum_field_count); 25342 25343 init_const_slice(ira->codegen, fields[2], enum_field_array, 0, enum_field_count, false); 25344 25345 for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) 25346 { 25347 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index]; 25348 ZigValue *enum_field_val = &enum_field_array->data.x_array.data.s_none.elements[enum_field_index]; 25349 make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type); 25350 enum_field_val->parent.id = ConstParentIdArray; 25351 enum_field_val->parent.data.p_array.array_val = enum_field_array; 25352 enum_field_val->parent.data.p_array.elem_index = enum_field_index; 25353 } 25354 // decls: []TypeInfo.Declaration 25355 ensure_field_index(result->type, "decls", 3); 25356 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3], 25357 type_entry->data.enumeration.decls_scope, false))) 25358 { 25359 return err; 25360 } 25361 // is_exhaustive: bool 25362 ensure_field_index(result->type, "is_exhaustive", 4); 25363 fields[4]->special = ConstValSpecialStatic; 25364 fields[4]->type = ira->codegen->builtin_types.entry_bool; 25365 fields[4]->data.x_bool = !type_entry->data.enumeration.non_exhaustive; 25366 25367 break; 25368 } 25369 case ZigTypeIdErrorSet: 25370 { 25371 result = ira->codegen->pass1_arena->create<ZigValue>(); 25372 result->special = ConstValSpecialStatic; 25373 result->type = ir_type_info_get_type(ira, "ErrorSet", nullptr); 25374 25375 ZigType *type_info_error_type = ir_type_info_get_type(ira, "Error", nullptr); 25376 if (!resolve_inferred_error_set(ira->codegen, type_entry, source_instr->source_node)) { 25377 return ErrorSemanticAnalyzeFail; 25378 } 25379 if (type_is_global_error_set(type_entry)) { 25380 result->data.x_optional = nullptr; 25381 break; 25382 } 25383 if ((err = type_resolve(ira->codegen, type_info_error_type, ResolveStatusSizeKnown))) { 25384 zig_unreachable(); 25385 } 25386 ZigValue *slice_val = ira->codegen->pass1_arena->create<ZigValue>(); 25387 result->data.x_optional = slice_val; 25388 25389 uint32_t error_count = type_entry->data.error_set.err_count; 25390 ZigValue *error_array = ira->codegen->pass1_arena->create<ZigValue>(); 25391 error_array->special = ConstValSpecialStatic; 25392 error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count, nullptr); 25393 error_array->data.x_array.special = ConstArraySpecialNone; 25394 error_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(error_count); 25395 25396 init_const_slice(ira->codegen, slice_val, error_array, 0, error_count, false); 25397 for (uint32_t error_index = 0; error_index < error_count; error_index++) { 25398 ErrorTableEntry *error = type_entry->data.error_set.errors[error_index]; 25399 ZigValue *error_val = &error_array->data.x_array.data.s_none.elements[error_index]; 25400 25401 error_val->special = ConstValSpecialStatic; 25402 error_val->type = type_info_error_type; 25403 25404 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 2); 25405 inner_fields[1]->special = ConstValSpecialStatic; 25406 inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; 25407 25408 ZigValue *name = nullptr; 25409 if (error->cached_error_name_val != nullptr) 25410 name = error->cached_error_name_val; 25411 if (name == nullptr) 25412 name = create_const_str_lit(ira->codegen, &error->name)->data.x_ptr.data.ref.pointee; 25413 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(&error->name), true); 25414 bigint_init_unsigned(&inner_fields[1]->data.x_bigint, error->value); 25415 25416 error_val->data.x_struct.fields = inner_fields; 25417 error_val->parent.id = ConstParentIdArray; 25418 error_val->parent.data.p_array.array_val = error_array; 25419 error_val->parent.data.p_array.elem_index = error_index; 25420 } 25421 25422 break; 25423 } 25424 case ZigTypeIdErrorUnion: 25425 { 25426 result = ira->codegen->pass1_arena->create<ZigValue>(); 25427 result->special = ConstValSpecialStatic; 25428 result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr); 25429 25430 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2); 25431 result->data.x_struct.fields = fields; 25432 25433 // error_set: type 25434 ensure_field_index(result->type, "error_set", 0); 25435 fields[0]->special = ConstValSpecialStatic; 25436 fields[0]->type = ira->codegen->builtin_types.entry_type; 25437 fields[0]->data.x_type = type_entry->data.error_union.err_set_type; 25438 25439 // payload: type 25440 ensure_field_index(result->type, "payload", 1); 25441 fields[1]->special = ConstValSpecialStatic; 25442 fields[1]->type = ira->codegen->builtin_types.entry_type; 25443 fields[1]->data.x_type = type_entry->data.error_union.payload_type; 25444 25445 break; 25446 } 25447 case ZigTypeIdUnion: 25448 { 25449 result = ira->codegen->pass1_arena->create<ZigValue>(); 25450 result->special = ConstValSpecialStatic; 25451 result->type = ir_type_info_get_type(ira, "Union", nullptr); 25452 25453 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 4); 25454 result->data.x_struct.fields = fields; 25455 25456 // layout: ContainerLayout 25457 ensure_field_index(result->type, "layout", 0); 25458 fields[0]->special = ConstValSpecialStatic; 25459 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 25460 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.unionation.layout); 25461 // tag_type: ?type 25462 ensure_field_index(result->type, "tag_type", 1); 25463 fields[1]->special = ConstValSpecialStatic; 25464 fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 25465 25466 AstNode *union_decl_node = type_entry->data.unionation.decl_node; 25467 if (union_decl_node->data.container_decl.auto_enum || 25468 union_decl_node->data.container_decl.init_arg_expr != nullptr) 25469 { 25470 ZigValue *tag_type = ira->codegen->pass1_arena->create<ZigValue>(); 25471 tag_type->special = ConstValSpecialStatic; 25472 tag_type->type = ira->codegen->builtin_types.entry_type; 25473 tag_type->data.x_type = type_entry->data.unionation.tag_type; 25474 fields[1]->data.x_optional = tag_type; 25475 } else { 25476 fields[1]->data.x_optional = nullptr; 25477 } 25478 // fields: []TypeInfo.UnionField 25479 ensure_field_index(result->type, "fields", 2); 25480 25481 ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr); 25482 if ((err = type_resolve(ira->codegen, type_info_union_field_type, ResolveStatusSizeKnown))) 25483 zig_unreachable(); 25484 uint32_t union_field_count = type_entry->data.unionation.src_field_count; 25485 25486 ZigValue *union_field_array = ira->codegen->pass1_arena->create<ZigValue>(); 25487 union_field_array->special = ConstValSpecialStatic; 25488 union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count, nullptr); 25489 union_field_array->data.x_array.special = ConstArraySpecialNone; 25490 union_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(union_field_count); 25491 25492 init_const_slice(ira->codegen, fields[2], union_field_array, 0, union_field_count, false); 25493 25494 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 25495 25496 for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) { 25497 TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index]; 25498 ZigValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index]; 25499 25500 union_field_val->special = ConstValSpecialStatic; 25501 union_field_val->type = type_info_union_field_type; 25502 25503 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3); 25504 inner_fields[1]->special = ConstValSpecialStatic; 25505 inner_fields[1]->type = get_optional_type(ira->codegen, type_info_enum_field_type); 25506 25507 if (fields[1]->data.x_optional == nullptr) { 25508 inner_fields[1]->data.x_optional = nullptr; 25509 } else { 25510 inner_fields[1]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>(); 25511 make_enum_field_val(ira, inner_fields[1]->data.x_optional, union_field->enum_field, type_info_enum_field_type); 25512 } 25513 25514 inner_fields[2]->special = ConstValSpecialStatic; 25515 inner_fields[2]->type = ira->codegen->builtin_types.entry_type; 25516 inner_fields[2]->data.x_type = union_field->type_entry; 25517 25518 ZigValue *name = create_const_str_lit(ira->codegen, union_field->name)->data.x_ptr.data.ref.pointee; 25519 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true); 25520 25521 union_field_val->data.x_struct.fields = inner_fields; 25522 union_field_val->parent.id = ConstParentIdArray; 25523 union_field_val->parent.data.p_array.array_val = union_field_array; 25524 union_field_val->parent.data.p_array.elem_index = union_field_index; 25525 } 25526 // decls: []TypeInfo.Declaration 25527 ensure_field_index(result->type, "decls", 3); 25528 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3], 25529 type_entry->data.unionation.decls_scope, false))) 25530 { 25531 return err; 25532 } 25533 25534 break; 25535 } 25536 case ZigTypeIdStruct: 25537 { 25538 if (type_entry->data.structure.special == StructSpecialSlice) { 25539 result = create_ptr_like_type_info(ira, type_entry); 25540 if (result == nullptr) 25541 return ErrorSemanticAnalyzeFail; 25542 break; 25543 } 25544 25545 result = ira->codegen->pass1_arena->create<ZigValue>(); 25546 result->special = ConstValSpecialStatic; 25547 result->type = ir_type_info_get_type(ira, "Struct", nullptr); 25548 25549 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 4); 25550 result->data.x_struct.fields = fields; 25551 25552 // layout: ContainerLayout 25553 ensure_field_index(result->type, "layout", 0); 25554 fields[0]->special = ConstValSpecialStatic; 25555 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 25556 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.structure.layout); 25557 // fields: []TypeInfo.StructField 25558 ensure_field_index(result->type, "fields", 1); 25559 25560 ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr); 25561 if ((err = type_resolve(ira->codegen, type_info_struct_field_type, ResolveStatusSizeKnown))) { 25562 zig_unreachable(); 25563 } 25564 uint32_t struct_field_count = type_entry->data.structure.src_field_count; 25565 25566 ZigValue *struct_field_array = ira->codegen->pass1_arena->create<ZigValue>(); 25567 struct_field_array->special = ConstValSpecialStatic; 25568 struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count, nullptr); 25569 struct_field_array->data.x_array.special = ConstArraySpecialNone; 25570 struct_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(struct_field_count); 25571 25572 init_const_slice(ira->codegen, fields[1], struct_field_array, 0, struct_field_count, false); 25573 25574 for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) { 25575 TypeStructField *struct_field = type_entry->data.structure.fields[struct_field_index]; 25576 ZigValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index]; 25577 25578 struct_field_val->special = ConstValSpecialStatic; 25579 struct_field_val->type = type_info_struct_field_type; 25580 25581 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 4); 25582 inner_fields[1]->special = ConstValSpecialStatic; 25583 inner_fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int); 25584 25585 ZigType *field_type = resolve_struct_field_type(ira->codegen, struct_field); 25586 if (field_type == nullptr) 25587 return ErrorSemanticAnalyzeFail; 25588 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) 25589 return err; 25590 if (!type_has_bits(ira->codegen, struct_field->type_entry)) { 25591 inner_fields[1]->data.x_optional = nullptr; 25592 } else { 25593 size_t byte_offset = struct_field->offset; 25594 inner_fields[1]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>(); 25595 inner_fields[1]->data.x_optional->special = ConstValSpecialStatic; 25596 inner_fields[1]->data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int; 25597 bigint_init_unsigned(&inner_fields[1]->data.x_optional->data.x_bigint, byte_offset); 25598 } 25599 25600 inner_fields[2]->special = ConstValSpecialStatic; 25601 inner_fields[2]->type = ira->codegen->builtin_types.entry_type; 25602 inner_fields[2]->data.x_type = struct_field->type_entry; 25603 25604 // default_value: anytype 25605 inner_fields[3]->special = ConstValSpecialStatic; 25606 inner_fields[3]->type = get_optional_type2(ira->codegen, struct_field->type_entry); 25607 if (inner_fields[3]->type == nullptr) return ErrorSemanticAnalyzeFail; 25608 memoize_field_init_val(ira->codegen, type_entry, struct_field); 25609 if(struct_field->init_val != nullptr && type_is_invalid(struct_field->init_val->type)){ 25610 return ErrorSemanticAnalyzeFail; 25611 } 25612 set_optional_payload(inner_fields[3], struct_field->init_val); 25613 25614 ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee; 25615 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true); 25616 25617 struct_field_val->data.x_struct.fields = inner_fields; 25618 struct_field_val->parent.id = ConstParentIdArray; 25619 struct_field_val->parent.data.p_array.array_val = struct_field_array; 25620 struct_field_val->parent.data.p_array.elem_index = struct_field_index; 25621 } 25622 // decls: []TypeInfo.Declaration 25623 ensure_field_index(result->type, "decls", 2); 25624 if ((err = ir_make_type_info_decls(ira, source_instr, fields[2], 25625 type_entry->data.structure.decls_scope, false))) 25626 { 25627 return err; 25628 } 25629 25630 // is_tuple: bool 25631 ensure_field_index(result->type, "is_tuple", 3); 25632 fields[3]->special = ConstValSpecialStatic; 25633 fields[3]->type = ira->codegen->builtin_types.entry_bool; 25634 fields[3]->data.x_bool = is_tuple(type_entry); 25635 25636 break; 25637 } 25638 case ZigTypeIdFn: 25639 { 25640 result = ira->codegen->pass1_arena->create<ZigValue>(); 25641 result->special = ConstValSpecialStatic; 25642 result->type = ir_type_info_get_type(ira, "Fn", nullptr); 25643 25644 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 5); 25645 result->data.x_struct.fields = fields; 25646 25647 // calling_convention: TypeInfo.CallingConvention 25648 ensure_field_index(result->type, "calling_convention", 0); 25649 fields[0]->special = ConstValSpecialStatic; 25650 fields[0]->type = get_builtin_type(ira->codegen, "CallingConvention"); 25651 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); 25652 // is_generic: bool 25653 ensure_field_index(result->type, "is_generic", 1); 25654 bool is_generic = type_entry->data.fn.is_generic; 25655 fields[1]->special = ConstValSpecialStatic; 25656 fields[1]->type = ira->codegen->builtin_types.entry_bool; 25657 fields[1]->data.x_bool = is_generic; 25658 // is_varargs: bool 25659 ensure_field_index(result->type, "is_var_args", 2); 25660 bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; 25661 fields[2]->special = ConstValSpecialStatic; 25662 fields[2]->type = ira->codegen->builtin_types.entry_bool; 25663 fields[2]->data.x_bool = type_entry->data.fn.fn_type_id.is_var_args; 25664 // return_type: ?type 25665 ensure_field_index(result->type, "return_type", 3); 25666 fields[3]->special = ConstValSpecialStatic; 25667 fields[3]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 25668 if (type_entry->data.fn.fn_type_id.return_type == nullptr) 25669 fields[3]->data.x_optional = nullptr; 25670 else { 25671 ZigValue *return_type = ira->codegen->pass1_arena->create<ZigValue>(); 25672 return_type->special = ConstValSpecialStatic; 25673 return_type->type = ira->codegen->builtin_types.entry_type; 25674 return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; 25675 fields[3]->data.x_optional = return_type; 25676 } 25677 // args: []TypeInfo.FnArg 25678 ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); 25679 if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { 25680 zig_unreachable(); 25681 } 25682 size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - 25683 (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); 25684 25685 ZigValue *fn_arg_array = ira->codegen->pass1_arena->create<ZigValue>(); 25686 fn_arg_array->special = ConstValSpecialStatic; 25687 fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count, nullptr); 25688 fn_arg_array->data.x_array.special = ConstArraySpecialNone; 25689 fn_arg_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(fn_arg_count); 25690 25691 init_const_slice(ira->codegen, fields[4], fn_arg_array, 0, fn_arg_count, false); 25692 25693 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { 25694 FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; 25695 ZigValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index]; 25696 25697 fn_arg_val->special = ConstValSpecialStatic; 25698 fn_arg_val->type = type_info_fn_arg_type; 25699 25700 bool arg_is_generic = fn_param_info->type == nullptr; 25701 if (arg_is_generic) assert(is_generic); 25702 25703 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3); 25704 inner_fields[0]->special = ConstValSpecialStatic; 25705 inner_fields[0]->type = ira->codegen->builtin_types.entry_bool; 25706 inner_fields[0]->data.x_bool = arg_is_generic; 25707 inner_fields[1]->special = ConstValSpecialStatic; 25708 inner_fields[1]->type = ira->codegen->builtin_types.entry_bool; 25709 inner_fields[1]->data.x_bool = fn_param_info->is_noalias; 25710 inner_fields[2]->special = ConstValSpecialStatic; 25711 inner_fields[2]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 25712 25713 if (arg_is_generic) 25714 inner_fields[2]->data.x_optional = nullptr; 25715 else { 25716 ZigValue *arg_type = ira->codegen->pass1_arena->create<ZigValue>(); 25717 arg_type->special = ConstValSpecialStatic; 25718 arg_type->type = ira->codegen->builtin_types.entry_type; 25719 arg_type->data.x_type = fn_param_info->type; 25720 inner_fields[2]->data.x_optional = arg_type; 25721 } 25722 25723 fn_arg_val->data.x_struct.fields = inner_fields; 25724 fn_arg_val->parent.id = ConstParentIdArray; 25725 fn_arg_val->parent.data.p_array.array_val = fn_arg_array; 25726 fn_arg_val->parent.data.p_array.elem_index = fn_arg_index; 25727 } 25728 25729 break; 25730 } 25731 case ZigTypeIdBoundFn: 25732 { 25733 ZigType *fn_type = type_entry->data.bound_fn.fn_type; 25734 assert(fn_type->id == ZigTypeIdFn); 25735 if ((err = ir_make_type_info_value(ira, source_instr, fn_type, &result))) 25736 return err; 25737 25738 break; 25739 } 25740 case ZigTypeIdFnFrame: 25741 { 25742 result = ira->codegen->pass1_arena->create<ZigValue>(); 25743 result->special = ConstValSpecialStatic; 25744 result->type = ir_type_info_get_type(ira, "Frame", nullptr); 25745 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); 25746 result->data.x_struct.fields = fields; 25747 ZigFn *fn = type_entry->data.frame.fn; 25748 // function: anytype 25749 ensure_field_index(result->type, "function", 0); 25750 fields[0] = create_const_fn(ira->codegen, fn); 25751 break; 25752 } 25753 } 25754 25755 assert(result != nullptr); 25756 ira->codegen->type_info_cache.put(type_entry, result); 25757 *out = result; 25758 return ErrorNone; 25759 } 25760 25761 static IrInstGen *ir_analyze_instruction_type_info(IrAnalyze *ira, IrInstSrcTypeInfo *instruction) { 25762 Error err; 25763 IrInstGen *type_value = instruction->type_value->child; 25764 ZigType *type_entry = ir_resolve_type(ira, type_value); 25765 if (type_is_invalid(type_entry)) 25766 return ira->codegen->invalid_inst_gen; 25767 25768 ZigType *result_type = ir_type_info_get_type(ira, nullptr, nullptr); 25769 25770 ZigValue *payload; 25771 if ((err = ir_make_type_info_value(ira, &instruction->base.base, type_entry, &payload))) 25772 return ira->codegen->invalid_inst_gen; 25773 25774 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 25775 ZigValue *out_val = result->value; 25776 bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry)); 25777 out_val->data.x_union.payload = payload; 25778 25779 if (payload != nullptr) { 25780 payload->parent.id = ConstParentIdUnion; 25781 payload->parent.data.p_union.union_val = out_val; 25782 } 25783 25784 return result; 25785 } 25786 25787 static ZigValue *get_const_field(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, 25788 const char *name, size_t field_index) 25789 { 25790 Error err; 25791 ensure_field_index(struct_value->type, name, field_index); 25792 ZigValue *val = struct_value->data.x_struct.fields[field_index]; 25793 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_node, val, UndefBad))) 25794 return nullptr; 25795 return val; 25796 } 25797 25798 static Error get_const_field_sentinel(IrAnalyze *ira, IrInst* source_instr, ZigValue *struct_value, 25799 const char *name, size_t field_index, ZigType *elem_type, ZigValue **result) 25800 { 25801 ZigValue *field_val = get_const_field(ira, source_instr->source_node, struct_value, name, field_index); 25802 if (field_val == nullptr) 25803 return ErrorSemanticAnalyzeFail; 25804 25805 IrInstGen *field_inst = ir_const_move(ira, source_instr, field_val); 25806 IrInstGen *casted_field_inst = ir_implicit_cast(ira, field_inst, 25807 get_optional_type(ira->codegen, elem_type)); 25808 if (type_is_invalid(casted_field_inst->value->type)) 25809 return ErrorSemanticAnalyzeFail; 25810 25811 if (optional_value_is_null(casted_field_inst->value)) { 25812 *result = nullptr; 25813 } else { 25814 assert(type_has_optional_repr(casted_field_inst->value->type)); 25815 *result = casted_field_inst->value->data.x_optional; 25816 } 25817 25818 return ErrorNone; 25819 } 25820 25821 static Error get_const_field_bool(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, 25822 const char *name, size_t field_index, bool *out) 25823 { 25824 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 25825 if (value == nullptr) 25826 return ErrorSemanticAnalyzeFail; 25827 assert(value->type == ira->codegen->builtin_types.entry_bool); 25828 *out = value->data.x_bool; 25829 return ErrorNone; 25830 } 25831 25832 static BigInt *get_const_field_lit_int(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) 25833 { 25834 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 25835 if (value == nullptr) 25836 return nullptr; 25837 assert(value->type == ira->codegen->builtin_types.entry_num_lit_int); 25838 return &value->data.x_bigint; 25839 } 25840 25841 static ZigType *get_const_field_meta_type(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) 25842 { 25843 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 25844 if (value == nullptr) 25845 return ira->codegen->invalid_inst_gen->value->type; 25846 assert(value->type == ira->codegen->builtin_types.entry_type); 25847 return value->data.x_type; 25848 } 25849 25850 static ZigType *get_const_field_meta_type_optional(IrAnalyze *ira, AstNode *source_node, 25851 ZigValue *struct_value, const char *name, size_t field_index) 25852 { 25853 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 25854 if (value == nullptr) 25855 return ira->codegen->invalid_inst_gen->value->type; 25856 assert(value->type->id == ZigTypeIdOptional); 25857 assert(value->type->data.maybe.child_type == ira->codegen->builtin_types.entry_type); 25858 if (value->data.x_optional == nullptr) 25859 return nullptr; 25860 return value->data.x_optional->data.x_type; 25861 } 25862 25863 static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeId tagTypeId, ZigValue *payload) { 25864 Error err; 25865 switch (tagTypeId) { 25866 case ZigTypeIdInvalid: 25867 zig_unreachable(); 25868 case ZigTypeIdMetaType: 25869 return ira->codegen->builtin_types.entry_type; 25870 case ZigTypeIdVoid: 25871 return ira->codegen->builtin_types.entry_void; 25872 case ZigTypeIdBool: 25873 return ira->codegen->builtin_types.entry_bool; 25874 case ZigTypeIdUnreachable: 25875 return ira->codegen->builtin_types.entry_unreachable; 25876 case ZigTypeIdInt: { 25877 assert(payload->special == ConstValSpecialStatic); 25878 assert(payload->type == ir_type_info_get_type(ira, "Int", nullptr)); 25879 BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "bits", 1); 25880 if (bi == nullptr) 25881 return ira->codegen->invalid_inst_gen->value->type; 25882 bool is_signed; 25883 if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_signed", 0, &is_signed))) 25884 return ira->codegen->invalid_inst_gen->value->type; 25885 return get_int_type(ira->codegen, is_signed, bigint_as_u32(bi)); 25886 } 25887 case ZigTypeIdFloat: 25888 { 25889 assert(payload->special == ConstValSpecialStatic); 25890 assert(payload->type == ir_type_info_get_type(ira, "Float", nullptr)); 25891 BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "bits", 0); 25892 if (bi == nullptr) 25893 return ira->codegen->invalid_inst_gen->value->type; 25894 uint32_t bits = bigint_as_u32(bi); 25895 switch (bits) { 25896 case 16: return ira->codegen->builtin_types.entry_f16; 25897 case 32: return ira->codegen->builtin_types.entry_f32; 25898 case 64: return ira->codegen->builtin_types.entry_f64; 25899 case 128: return ira->codegen->builtin_types.entry_f128; 25900 } 25901 ir_add_error(ira, source_instr, buf_sprintf("%d-bit float unsupported", bits)); 25902 return ira->codegen->invalid_inst_gen->value->type; 25903 } 25904 case ZigTypeIdPointer: 25905 { 25906 ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); 25907 assert(payload->special == ConstValSpecialStatic); 25908 assert(payload->type == type_info_pointer_type); 25909 ZigValue *size_value = get_const_field(ira, source_instr->source_node, payload, "size", 0); 25910 assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type)); 25911 BuiltinPtrSize size_enum_index = (BuiltinPtrSize)bigint_as_u32(&size_value->data.x_enum_tag); 25912 PtrLen ptr_len = size_enum_index_to_ptr_len(size_enum_index); 25913 ZigType *elem_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 4); 25914 if (type_is_invalid(elem_type)) 25915 return ira->codegen->invalid_inst_gen->value->type; 25916 ZigValue *sentinel; 25917 if ((err = get_const_field_sentinel(ira, source_instr, payload, "sentinel", 6, 25918 elem_type, &sentinel))) 25919 { 25920 return ira->codegen->invalid_inst_gen->value->type; 25921 } 25922 if (sentinel != nullptr && (size_enum_index == BuiltinPtrSizeOne || size_enum_index == BuiltinPtrSizeC)) { 25923 ir_add_error(ira, source_instr, 25924 buf_sprintf("sentinels are only allowed on slices and unknown-length pointers")); 25925 return ira->codegen->invalid_inst_gen->value->type; 25926 } 25927 BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "alignment", 3); 25928 if (bi == nullptr) 25929 return ira->codegen->invalid_inst_gen->value->type; 25930 25931 bool is_const; 25932 if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_const", 1, &is_const))) 25933 return ira->codegen->invalid_inst_gen->value->type; 25934 25935 bool is_volatile; 25936 if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_volatile", 2, 25937 &is_volatile))) 25938 { 25939 return ira->codegen->invalid_inst_gen->value->type; 25940 } 25941 25942 bool is_allowzero; 25943 if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_allowzero", 5, 25944 &is_allowzero))) 25945 { 25946 return ira->codegen->invalid_inst_gen->value->type; 25947 } 25948 25949 25950 ZigType *ptr_type = get_pointer_to_type_extra2(ira->codegen, 25951 elem_type, 25952 is_const, 25953 is_volatile, 25954 ptr_len, 25955 bigint_as_u32(bi), 25956 0, // bit_offset_in_host 25957 0, // host_int_bytes 25958 is_allowzero, 25959 VECTOR_INDEX_NONE, nullptr, sentinel); 25960 if (size_enum_index != BuiltinPtrSizeSlice) 25961 return ptr_type; 25962 return get_slice_type(ira->codegen, ptr_type); 25963 } 25964 case ZigTypeIdArray: { 25965 assert(payload->special == ConstValSpecialStatic); 25966 assert(payload->type == ir_type_info_get_type(ira, "Array", nullptr)); 25967 ZigType *elem_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 1); 25968 if (type_is_invalid(elem_type)) 25969 return ira->codegen->invalid_inst_gen->value->type; 25970 ZigValue *sentinel; 25971 if ((err = get_const_field_sentinel(ira, source_instr, payload, "sentinel", 2, 25972 elem_type, &sentinel))) 25973 { 25974 return ira->codegen->invalid_inst_gen->value->type; 25975 } 25976 BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "len", 0); 25977 if (bi == nullptr) 25978 return ira->codegen->invalid_inst_gen->value->type; 25979 return get_array_type(ira->codegen, elem_type, bigint_as_u64(bi), sentinel); 25980 } 25981 case ZigTypeIdComptimeFloat: 25982 return ira->codegen->builtin_types.entry_num_lit_float; 25983 case ZigTypeIdComptimeInt: 25984 return ira->codegen->builtin_types.entry_num_lit_int; 25985 case ZigTypeIdUndefined: 25986 return ira->codegen->builtin_types.entry_undef; 25987 case ZigTypeIdNull: 25988 return ira->codegen->builtin_types.entry_null; 25989 case ZigTypeIdOptional: { 25990 assert(payload->special == ConstValSpecialStatic); 25991 assert(payload->type == ir_type_info_get_type(ira, "Optional", nullptr)); 25992 ZigType *child_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 0); 25993 return get_optional_type(ira->codegen, child_type); 25994 } 25995 case ZigTypeIdErrorUnion: { 25996 assert(payload->special == ConstValSpecialStatic); 25997 assert(payload->type == ir_type_info_get_type(ira, "ErrorUnion", nullptr)); 25998 ZigType *err_set_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "error_set", 0); 25999 ZigType *payload_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "payload", 1); 26000 return get_error_union_type(ira->codegen, err_set_type, payload_type); 26001 } 26002 case ZigTypeIdOpaque: { 26003 Buf *bare_name = buf_alloc(); 26004 Buf *full_name = get_anon_type_name(ira->codegen, 26005 ira->old_irb.exec, "opaque", source_instr->scope, source_instr->source_node, bare_name); 26006 return get_opaque_type(ira->codegen, 26007 source_instr->scope, source_instr->source_node, buf_ptr(full_name), bare_name); 26008 } 26009 case ZigTypeIdVector: { 26010 assert(payload->special == ConstValSpecialStatic); 26011 assert(payload->type == ir_type_info_get_type(ira, "Vector", nullptr)); 26012 BigInt *len = get_const_field_lit_int(ira, source_instr->source_node, payload, "len", 0); 26013 ZigType *child_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 1); 26014 Error err; 26015 if ((err = ir_validate_vector_elem_type(ira, source_instr->source_node, child_type))) { 26016 return ira->codegen->invalid_inst_gen->value->type; 26017 } 26018 return get_vector_type(ira->codegen, bigint_as_u32(len), child_type); 26019 } 26020 case ZigTypeIdAnyFrame: { 26021 assert(payload->special == ConstValSpecialStatic); 26022 assert(payload->type == ir_type_info_get_type(ira, "AnyFrame", nullptr)); 26023 ZigType *child_type = get_const_field_meta_type_optional(ira, source_instr->source_node, payload, "child", 0); 26024 return get_any_frame_type(ira->codegen, child_type); 26025 } 26026 case ZigTypeIdEnumLiteral: 26027 return ira->codegen->builtin_types.entry_enum_literal; 26028 case ZigTypeIdFnFrame: { 26029 assert(payload->special == ConstValSpecialStatic); 26030 assert(payload->type == ir_type_info_get_type(ira, "Frame", nullptr)); 26031 ZigValue *function = get_const_field(ira, source_instr->source_node, payload, "function", 0); 26032 assert(function->type->id == ZigTypeIdFn); 26033 ZigFn *fn = function->data.x_ptr.data.fn.fn_entry; 26034 return get_fn_frame_type(ira->codegen, fn); 26035 } 26036 case ZigTypeIdErrorSet: { 26037 assert(payload->special == ConstValSpecialStatic); 26038 assert(payload->type->id == ZigTypeIdOptional); 26039 ZigValue *slice = payload->data.x_optional; 26040 if (slice == nullptr) 26041 return ira->codegen->builtin_types.entry_global_error_set; 26042 assert(slice->special == ConstValSpecialStatic); 26043 assert(is_slice(slice->type)); 26044 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 26045 Buf bare_name = BUF_INIT; 26046 buf_init_from_buf(&err_set_type->name, get_anon_type_name(ira->codegen, ira->old_irb.exec, "error", source_instr->scope, source_instr->source_node, &bare_name)); 26047 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 26048 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 26049 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 26050 ZigValue *ptr = slice->data.x_struct.fields[slice_ptr_index]; 26051 assert(ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);; 26052 assert(ptr->data.x_ptr.data.base_array.elem_index == 0); 26053 ZigValue *arr = ptr->data.x_ptr.data.base_array.array_val; 26054 assert(arr->special == ConstValSpecialStatic); 26055 assert(arr->data.x_array.special == ConstArraySpecialNone); 26056 ZigValue *len = slice->data.x_struct.fields[slice_len_index]; 26057 size_t count = bigint_as_usize(&len->data.x_bigint); 26058 err_set_type->data.error_set.err_count = count; 26059 err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(count); 26060 bool *already_set = heap::c_allocator.allocate<bool>(ira->codegen->errors_by_index.length + count); 26061 for (size_t i = 0; i < count; i++) { 26062 ZigValue *error = &arr->data.x_array.data.s_none.elements[i]; 26063 assert(error->type == ir_type_info_get_type(ira, "Error", nullptr)); 26064 ErrorTableEntry *err_entry = heap::c_allocator.create<ErrorTableEntry>(); 26065 err_entry->decl_node = source_instr->source_node; 26066 ZigValue *name_slice = get_const_field(ira, source_instr->source_node, error, "name", 0); 26067 ZigValue *name_ptr = name_slice->data.x_struct.fields[slice_ptr_index]; 26068 ZigValue *name_len = name_slice->data.x_struct.fields[slice_len_index]; 26069 assert(name_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray); 26070 assert(name_ptr->data.x_ptr.data.base_array.elem_index == 0); 26071 ZigValue *name_arr = name_ptr->data.x_ptr.data.base_array.array_val; 26072 assert(name_arr->special == ConstValSpecialStatic); 26073 switch (name_arr->data.x_array.special) { 26074 case ConstArraySpecialUndef: 26075 return ira->codegen->invalid_inst_gen->value->type; 26076 case ConstArraySpecialNone: { 26077 buf_resize(&err_entry->name, 0); 26078 size_t name_count = bigint_as_usize(&name_len->data.x_bigint); 26079 for (size_t j = 0; j < name_count; j++) { 26080 ZigValue *ch_val = &name_arr->data.x_array.data.s_none.elements[j]; 26081 unsigned ch = bigint_as_u32(&ch_val->data.x_bigint); 26082 buf_append_char(&err_entry->name, ch); 26083 } 26084 break; 26085 } 26086 case ConstArraySpecialBuf: 26087 buf_init_from_buf(&err_entry->name, name_arr->data.x_array.data.s_buf); 26088 break; 26089 } 26090 auto existing_entry = ira->codegen->error_table.put_unique(&err_entry->name, err_entry); 26091 if (existing_entry) { 26092 err_entry->value = existing_entry->value->value; 26093 } else { 26094 size_t error_value_count = ira->codegen->errors_by_index.length; 26095 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count)); 26096 err_entry->value = error_value_count; 26097 ira->codegen->errors_by_index.append(err_entry); 26098 } 26099 if (already_set[err_entry->value]) { 26100 ir_add_error(ira, source_instr, buf_sprintf("duplicate error: %s", buf_ptr(&err_entry->name))); 26101 return ira->codegen->invalid_inst_gen->value->type; 26102 } else { 26103 already_set[err_entry->value] = true; 26104 } 26105 err_set_type->data.error_set.errors[i] = err_entry; 26106 } 26107 return err_set_type; 26108 } 26109 case ZigTypeIdEnum: 26110 ir_add_error(ira, source_instr, buf_sprintf( 26111 "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId))); 26112 return ira->codegen->invalid_inst_gen->value->type; 26113 case ZigTypeIdUnion: 26114 case ZigTypeIdFn: 26115 case ZigTypeIdBoundFn: 26116 case ZigTypeIdStruct: 26117 ir_add_error(ira, source_instr, buf_sprintf( 26118 "@Type not available for 'TypeInfo.%s'", type_id_name(tagTypeId))); 26119 return ira->codegen->invalid_inst_gen->value->type; 26120 } 26121 zig_unreachable(); 26122 } 26123 26124 static IrInstGen *ir_analyze_instruction_type(IrAnalyze *ira, IrInstSrcType *instruction) { 26125 IrInstGen *uncasted_type_info = instruction->type_info->child; 26126 if (type_is_invalid(uncasted_type_info->value->type)) 26127 return ira->codegen->invalid_inst_gen; 26128 26129 IrInstGen *type_info = ir_implicit_cast(ira, uncasted_type_info, ir_type_info_get_type(ira, nullptr, nullptr)); 26130 if (type_is_invalid(type_info->value->type)) 26131 return ira->codegen->invalid_inst_gen; 26132 26133 ZigValue *type_info_val = ir_resolve_const(ira, type_info, UndefBad); 26134 if (type_info_val == nullptr) 26135 return ira->codegen->invalid_inst_gen; 26136 ZigTypeId type_id_tag = type_id_at_index(bigint_as_usize(&type_info_val->data.x_union.tag)); 26137 ZigType *type = type_info_to_type(ira, &uncasted_type_info->base, type_id_tag, 26138 type_info_val->data.x_union.payload); 26139 if (type_is_invalid(type)) 26140 return ira->codegen->invalid_inst_gen; 26141 return ir_const_type(ira, &instruction->base.base, type); 26142 } 26143 26144 static IrInstGen *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira, 26145 IrInstSrcSetEvalBranchQuota *instruction) 26146 { 26147 uint64_t new_quota; 26148 if (!ir_resolve_usize(ira, instruction->new_quota->child, &new_quota)) 26149 return ira->codegen->invalid_inst_gen; 26150 26151 if (new_quota > *ira->new_irb.exec->backward_branch_quota) { 26152 *ira->new_irb.exec->backward_branch_quota = new_quota; 26153 } 26154 26155 return ir_const_void(ira, &instruction->base.base); 26156 } 26157 26158 static IrInstGen *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstSrcTypeName *instruction) { 26159 IrInstGen *type_value = instruction->type_value->child; 26160 ZigType *type_entry = ir_resolve_type(ira, type_value); 26161 if (type_is_invalid(type_entry)) 26162 return ira->codegen->invalid_inst_gen; 26163 26164 if (!type_entry->cached_const_name_val) { 26165 type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, type_bare_name(type_entry)); 26166 } 26167 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 26168 copy_const_val(ira->codegen, result->value, type_entry->cached_const_name_val); 26169 return result; 26170 } 26171 26172 static void ir_cimport_cache_paths(Buf *cache_dir, Buf *tmp_c_file_digest, Buf *out_zig_dir, Buf *out_zig_path) { 26173 buf_resize(out_zig_dir, 0); 26174 buf_resize(out_zig_path, 0); 26175 buf_appendf(out_zig_dir, "%s" OS_SEP "o" OS_SEP "%s", 26176 buf_ptr(cache_dir), buf_ptr(tmp_c_file_digest)); 26177 buf_appendf(out_zig_path, "%s" OS_SEP "cimport.zig", buf_ptr(out_zig_dir)); 26178 } 26179 static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImport *instruction) { 26180 Error err; 26181 AstNode *node = instruction->base.base.source_node; 26182 assert(node->type == NodeTypeFnCallExpr); 26183 AstNode *block_node = node->data.fn_call_expr.params.at(0); 26184 26185 ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.base.scope); 26186 26187 // Execute the C import block like an inline function 26188 ZigType *void_type = ira->codegen->builtin_types.entry_void; 26189 ZigValue *cimport_result; 26190 ZigValue *result_ptr; 26191 create_result_ptr(ira->codegen, void_type, &cimport_result, &result_ptr); 26192 if ((err = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, result_ptr, 26193 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, 26194 &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, UndefBad))) 26195 { 26196 return ira->codegen->invalid_inst_gen; 26197 } 26198 if (type_is_invalid(cimport_result->type)) 26199 return ira->codegen->invalid_inst_gen; 26200 26201 ZigPackage *cur_scope_pkg = scope_package(instruction->base.base.scope); 26202 Buf *namespace_name = buf_sprintf("%s.cimport:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, 26203 buf_ptr(&cur_scope_pkg->pkg_path), node->line + 1, node->column + 1); 26204 26205 ZigPackage *cimport_pkg = new_anonymous_package(); 26206 cimport_pkg->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package); 26207 cimport_pkg->package_table.put(buf_create_from_str("std"), ira->codegen->std_package); 26208 buf_init_from_buf(&cimport_pkg->pkg_path, namespace_name); 26209 26210 CacheHash *cache_hash; 26211 if ((err = create_c_object_cache(ira->codegen, &cache_hash, false))) { 26212 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to create cache: %s", err_str(err))); 26213 return ira->codegen->invalid_inst_gen; 26214 } 26215 cache_buf(cache_hash, &cimport_scope->buf); 26216 26217 // Set this because we're not adding any files before checking for a hit. 26218 cache_hash->force_check_manifest = true; 26219 26220 Buf tmp_c_file_digest = BUF_INIT; 26221 buf_resize(&tmp_c_file_digest, 0); 26222 if ((err = cache_hit(cache_hash, &tmp_c_file_digest))) { 26223 if (err != ErrorInvalidFormat) { 26224 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to check cache: %s", err_str(err))); 26225 return ira->codegen->invalid_inst_gen; 26226 } 26227 } 26228 ira->codegen->caches_to_release.append(cache_hash); 26229 26230 Buf *out_zig_dir = buf_alloc(); 26231 Buf *out_zig_path = buf_alloc(); 26232 if (buf_len(&tmp_c_file_digest) == 0 || cache_hash->files.length == 0) { 26233 // Cache Miss 26234 Buf *tmp_c_file_dir = buf_sprintf("%s" OS_SEP "o" OS_SEP "%s", 26235 buf_ptr(ira->codegen->cache_dir), buf_ptr(&cache_hash->b64_digest)); 26236 Buf *resolve_paths[] = { 26237 tmp_c_file_dir, 26238 buf_create_from_str("cimport.h"), 26239 }; 26240 Buf tmp_c_file_path = os_path_resolve(resolve_paths, 2); 26241 26242 if ((err = os_make_path(tmp_c_file_dir))) { 26243 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); 26244 return ira->codegen->invalid_inst_gen; 26245 } 26246 26247 if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { 26248 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); 26249 return ira->codegen->invalid_inst_gen; 26250 } 26251 if (ira->codegen->verbose_cimport) { 26252 fprintf(stderr, "@cImport source: %s\n", buf_ptr(&tmp_c_file_path)); 26253 } 26254 26255 Buf *tmp_dep_file = buf_sprintf("%s.d", buf_ptr(&tmp_c_file_path)); 26256 26257 ZigList<const char *> clang_argv = {0}; 26258 26259 add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true, FileExtC); 26260 26261 clang_argv.append(buf_ptr(&tmp_c_file_path)); 26262 26263 if (ira->codegen->verbose_cc) { 26264 fprintf(stderr, "clang"); 26265 for (size_t i = 0; i < clang_argv.length; i += 1) { 26266 fprintf(stderr, " %s", clang_argv.at(i)); 26267 } 26268 fprintf(stderr, "\n"); 26269 } 26270 26271 clang_argv.append(nullptr); // to make the [start...end] argument work 26272 26273 Stage2ErrorMsg *errors_ptr; 26274 size_t errors_len; 26275 Stage2Ast *ast; 26276 26277 const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir); 26278 26279 if ((err = stage2_translate_c(&ast, &errors_ptr, &errors_len, 26280 &clang_argv.at(0), &clang_argv.last(), resources_path))) 26281 { 26282 if (err != ErrorCCompileErrors) { 26283 ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err))); 26284 return ira->codegen->invalid_inst_gen; 26285 } 26286 26287 ErrorMsg *parent_err_msg = ir_add_error_node(ira, node, buf_sprintf("C import failed")); 26288 if (ira->codegen->libc_link_lib == nullptr) { 26289 add_error_note(ira->codegen, parent_err_msg, node, 26290 buf_sprintf("libc headers not available; compilation does not link against libc")); 26291 } 26292 for (size_t i = 0; i < errors_len; i += 1) { 26293 Stage2ErrorMsg *clang_err = &errors_ptr[i]; 26294 // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null 26295 if (clang_err->source && clang_err->filename_ptr) { 26296 ErrorMsg *err_msg = err_msg_create_with_offset( 26297 clang_err->filename_ptr ? 26298 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(), 26299 clang_err->line, clang_err->column, clang_err->offset, clang_err->source, 26300 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); 26301 err_msg_add_note(parent_err_msg, err_msg); 26302 } 26303 } 26304 26305 return ira->codegen->invalid_inst_gen; 26306 } 26307 if (ira->codegen->verbose_cimport) { 26308 fprintf(stderr, "@cImport .d file: %s\n", buf_ptr(tmp_dep_file)); 26309 } 26310 26311 if ((err = cache_add_dep_file(cache_hash, tmp_dep_file, false))) { 26312 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to parse .d file: %s", err_str(err))); 26313 return ira->codegen->invalid_inst_gen; 26314 } 26315 if ((err = cache_final(cache_hash, &tmp_c_file_digest))) { 26316 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to finalize cache: %s", err_str(err))); 26317 return ira->codegen->invalid_inst_gen; 26318 } 26319 26320 ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); 26321 if ((err = os_make_path(out_zig_dir))) { 26322 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make output dir: %s", err_str(err))); 26323 return ira->codegen->invalid_inst_gen; 26324 } 26325 FILE *out_file = fopen(buf_ptr(out_zig_path), "wb"); 26326 if (out_file == nullptr) { 26327 ir_add_error_node(ira, node, 26328 buf_sprintf("C import failed: unable to open output file: %s", strerror(errno))); 26329 return ira->codegen->invalid_inst_gen; 26330 } 26331 stage2_render_ast(ast, out_file); 26332 if (fclose(out_file) != 0) { 26333 ir_add_error_node(ira, node, 26334 buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno))); 26335 return ira->codegen->invalid_inst_gen; 26336 } 26337 26338 if (ira->codegen->verbose_cimport) { 26339 fprintf(stderr, "@cImport output: %s\n", buf_ptr(out_zig_path)); 26340 } 26341 26342 } else { 26343 // Cache Hit 26344 ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); 26345 if (ira->codegen->verbose_cimport) { 26346 fprintf(stderr, "@cImport cache hit: %s\n", buf_ptr(out_zig_path)); 26347 } 26348 } 26349 26350 Buf *import_code = buf_alloc(); 26351 if ((err = file_fetch(ira->codegen, out_zig_path, import_code))) { 26352 ir_add_error_node(ira, node, 26353 buf_sprintf("unable to open '%s': %s", buf_ptr(out_zig_path), err_str(err))); 26354 return ira->codegen->invalid_inst_gen; 26355 } 26356 ZigType *child_import = add_source_file(ira->codegen, cimport_pkg, out_zig_path, 26357 import_code, SourceKindCImport); 26358 return ir_const_type(ira, &instruction->base.base, child_import); 26359 } 26360 26361 static IrInstGen *ir_analyze_instruction_c_include(IrAnalyze *ira, IrInstSrcCInclude *instruction) { 26362 IrInstGen *name_value = instruction->name->child; 26363 if (type_is_invalid(name_value->value->type)) 26364 return ira->codegen->invalid_inst_gen; 26365 26366 Buf *include_name = ir_resolve_str(ira, name_value); 26367 if (!include_name) 26368 return ira->codegen->invalid_inst_gen; 26369 26370 Buf *c_import_buf = ira->new_irb.exec->c_import_buf; 26371 // We check for this error in pass1 26372 assert(c_import_buf); 26373 26374 buf_appendf(c_import_buf, "#include <%s>\n", buf_ptr(include_name)); 26375 26376 return ir_const_void(ira, &instruction->base.base); 26377 } 26378 26379 static IrInstGen *ir_analyze_instruction_c_define(IrAnalyze *ira, IrInstSrcCDefine *instruction) { 26380 IrInstGen *name = instruction->name->child; 26381 if (type_is_invalid(name->value->type)) 26382 return ira->codegen->invalid_inst_gen; 26383 26384 Buf *define_name = ir_resolve_str(ira, name); 26385 if (!define_name) 26386 return ira->codegen->invalid_inst_gen; 26387 26388 IrInstGen *value = instruction->value->child; 26389 if (type_is_invalid(value->value->type)) 26390 return ira->codegen->invalid_inst_gen; 26391 26392 Buf *define_value = nullptr; 26393 // The second parameter is either a string or void (equivalent to "") 26394 if (value->value->type->id != ZigTypeIdVoid) { 26395 define_value = ir_resolve_str(ira, value); 26396 if (!define_value) 26397 return ira->codegen->invalid_inst_gen; 26398 } 26399 26400 Buf *c_import_buf = ira->new_irb.exec->c_import_buf; 26401 // We check for this error in pass1 26402 assert(c_import_buf); 26403 26404 buf_appendf(c_import_buf, "#define %s %s\n", buf_ptr(define_name), 26405 define_value ? buf_ptr(define_value) : ""); 26406 26407 return ir_const_void(ira, &instruction->base.base); 26408 } 26409 26410 static IrInstGen *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstSrcCUndef *instruction) { 26411 IrInstGen *name = instruction->name->child; 26412 if (type_is_invalid(name->value->type)) 26413 return ira->codegen->invalid_inst_gen; 26414 26415 Buf *undef_name = ir_resolve_str(ira, name); 26416 if (!undef_name) 26417 return ira->codegen->invalid_inst_gen; 26418 26419 Buf *c_import_buf = ira->new_irb.exec->c_import_buf; 26420 // We check for this error in pass1 26421 assert(c_import_buf); 26422 26423 buf_appendf(c_import_buf, "#undef %s\n", buf_ptr(undef_name)); 26424 26425 return ir_const_void(ira, &instruction->base.base); 26426 } 26427 26428 static IrInstGen *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstSrcEmbedFile *instruction) { 26429 IrInstGen *name = instruction->name->child; 26430 if (type_is_invalid(name->value->type)) 26431 return ira->codegen->invalid_inst_gen; 26432 26433 Buf *rel_file_path = ir_resolve_str(ira, name); 26434 if (!rel_file_path) 26435 return ira->codegen->invalid_inst_gen; 26436 26437 ZigType *import = get_scope_import(instruction->base.base.scope); 26438 // figure out absolute path to resource 26439 Buf source_dir_path = BUF_INIT; 26440 os_path_dirname(import->data.structure.root_struct->path, &source_dir_path); 26441 26442 Buf *resolve_paths[] = { 26443 &source_dir_path, 26444 rel_file_path, 26445 }; 26446 Buf *file_path = buf_alloc(); 26447 *file_path = os_path_resolve(resolve_paths, 2); 26448 26449 // load from file system into const expr 26450 Buf *file_contents = buf_alloc(); 26451 Error err; 26452 if ((err = file_fetch(ira->codegen, file_path, file_contents))) { 26453 if (err == ErrorFileNotFound) { 26454 ir_add_error(ira, &instruction->name->base, 26455 buf_sprintf("unable to find '%s'", buf_ptr(file_path))); 26456 return ira->codegen->invalid_inst_gen; 26457 } else { 26458 ir_add_error(ira, &instruction->name->base, 26459 buf_sprintf("unable to open '%s': %s", buf_ptr(file_path), err_str(err))); 26460 return ira->codegen->invalid_inst_gen; 26461 } 26462 } 26463 26464 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 26465 init_const_str_lit(ira->codegen, result->value, file_contents); 26466 return result; 26467 } 26468 26469 static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxchg *instruction) { 26470 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->type_value->child); 26471 if (type_is_invalid(operand_type)) 26472 return ira->codegen->invalid_inst_gen; 26473 26474 if (operand_type->id == ZigTypeIdFloat) { 26475 ir_add_error(ira, &instruction->type_value->child->base, 26476 buf_sprintf("expected integer, enum or pointer type, found '%s'", buf_ptr(&operand_type->name))); 26477 return ira->codegen->invalid_inst_gen; 26478 } 26479 26480 IrInstGen *ptr = instruction->ptr->child; 26481 if (type_is_invalid(ptr->value->type)) 26482 return ira->codegen->invalid_inst_gen; 26483 26484 // TODO let this be volatile 26485 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 26486 IrInstGen *casted_ptr = ir_implicit_cast2(ira, &instruction->ptr->base, ptr, ptr_type); 26487 if (type_is_invalid(casted_ptr->value->type)) 26488 return ira->codegen->invalid_inst_gen; 26489 26490 IrInstGen *cmp_value = instruction->cmp_value->child; 26491 if (type_is_invalid(cmp_value->value->type)) 26492 return ira->codegen->invalid_inst_gen; 26493 26494 IrInstGen *new_value = instruction->new_value->child; 26495 if (type_is_invalid(new_value->value->type)) 26496 return ira->codegen->invalid_inst_gen; 26497 26498 IrInstGen *success_order_value = instruction->success_order_value->child; 26499 if (type_is_invalid(success_order_value->value->type)) 26500 return ira->codegen->invalid_inst_gen; 26501 26502 AtomicOrder success_order; 26503 if (!ir_resolve_atomic_order(ira, success_order_value, &success_order)) 26504 return ira->codegen->invalid_inst_gen; 26505 26506 IrInstGen *failure_order_value = instruction->failure_order_value->child; 26507 if (type_is_invalid(failure_order_value->value->type)) 26508 return ira->codegen->invalid_inst_gen; 26509 26510 AtomicOrder failure_order; 26511 if (!ir_resolve_atomic_order(ira, failure_order_value, &failure_order)) 26512 return ira->codegen->invalid_inst_gen; 26513 26514 IrInstGen *casted_cmp_value = ir_implicit_cast2(ira, &instruction->cmp_value->base, cmp_value, operand_type); 26515 if (type_is_invalid(casted_cmp_value->value->type)) 26516 return ira->codegen->invalid_inst_gen; 26517 26518 IrInstGen *casted_new_value = ir_implicit_cast2(ira, &instruction->new_value->base, new_value, operand_type); 26519 if (type_is_invalid(casted_new_value->value->type)) 26520 return ira->codegen->invalid_inst_gen; 26521 26522 if (success_order < AtomicOrderMonotonic) { 26523 ir_add_error(ira, &success_order_value->base, 26524 buf_sprintf("success atomic ordering must be Monotonic or stricter")); 26525 return ira->codegen->invalid_inst_gen; 26526 } 26527 if (failure_order < AtomicOrderMonotonic) { 26528 ir_add_error(ira, &failure_order_value->base, 26529 buf_sprintf("failure atomic ordering must be Monotonic or stricter")); 26530 return ira->codegen->invalid_inst_gen; 26531 } 26532 if (failure_order > success_order) { 26533 ir_add_error(ira, &failure_order_value->base, 26534 buf_sprintf("failure atomic ordering must be no stricter than success")); 26535 return ira->codegen->invalid_inst_gen; 26536 } 26537 if (failure_order == AtomicOrderRelease || failure_order == AtomicOrderAcqRel) { 26538 ir_add_error(ira, &failure_order_value->base, 26539 buf_sprintf("failure atomic ordering must not be Release or AcqRel")); 26540 return ira->codegen->invalid_inst_gen; 26541 } 26542 26543 ZigType *result_type = get_optional_type(ira->codegen, operand_type); 26544 26545 // special case zero bit types 26546 switch (type_has_one_possible_value(ira->codegen, operand_type)) { 26547 case OnePossibleValueInvalid: 26548 return ira->codegen->invalid_inst_gen; 26549 case OnePossibleValueYes: { 26550 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 26551 set_optional_value_to_null(result->value); 26552 return result; 26553 } 26554 case OnePossibleValueNo: 26555 break; 26556 } 26557 26558 if (instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar && 26559 instr_is_comptime(casted_cmp_value) && instr_is_comptime(casted_new_value)) { 26560 ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad); 26561 if (ptr_val == nullptr) 26562 return ira->codegen->invalid_inst_gen; 26563 26564 ZigValue *stored_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.base.source_node); 26565 if (stored_val == nullptr) 26566 return ira->codegen->invalid_inst_gen; 26567 26568 ZigValue *expected_val = ir_resolve_const(ira, casted_cmp_value, UndefBad); 26569 if (expected_val == nullptr) 26570 return ira->codegen->invalid_inst_gen; 26571 26572 ZigValue *new_val = ir_resolve_const(ira, casted_new_value, UndefBad); 26573 if (new_val == nullptr) 26574 return ira->codegen->invalid_inst_gen; 26575 26576 bool eql = const_values_equal(ira->codegen, stored_val, expected_val); 26577 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 26578 if (eql) { 26579 copy_const_val(ira->codegen, stored_val, new_val); 26580 set_optional_value_to_null(result->value); 26581 } else { 26582 set_optional_payload(result->value, stored_val); 26583 } 26584 return result; 26585 } 26586 26587 IrInstGen *result_loc; 26588 if (handle_is_ptr(ira->codegen, result_type)) { 26589 result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 26590 result_type, nullptr, true, true); 26591 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 26592 return result_loc; 26593 } 26594 } else { 26595 result_loc = nullptr; 26596 } 26597 26598 return ir_build_cmpxchg_gen(ira, &instruction->base.base, result_type, 26599 casted_ptr, casted_cmp_value, casted_new_value, 26600 success_order, failure_order, instruction->is_weak, result_loc); 26601 } 26602 26603 static IrInstGen *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstSrcFence *instruction) { 26604 IrInstGen *order_inst = instruction->order->child; 26605 if (type_is_invalid(order_inst->value->type)) 26606 return ira->codegen->invalid_inst_gen; 26607 26608 AtomicOrder order; 26609 if (!ir_resolve_atomic_order(ira, order_inst, &order)) 26610 return ira->codegen->invalid_inst_gen; 26611 26612 if (order < AtomicOrderAcquire) { 26613 ir_add_error(ira, &order_inst->base, 26614 buf_sprintf("atomic ordering must be Acquire or stricter")); 26615 return ira->codegen->invalid_inst_gen; 26616 } 26617 26618 return ir_build_fence_gen(ira, &instruction->base.base, order); 26619 } 26620 26621 static IrInstGen *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstSrcTruncate *instruction) { 26622 IrInstGen *dest_type_value = instruction->dest_type->child; 26623 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 26624 if (type_is_invalid(dest_type)) 26625 return ira->codegen->invalid_inst_gen; 26626 26627 if (dest_type->id != ZigTypeIdInt && 26628 dest_type->id != ZigTypeIdComptimeInt) 26629 { 26630 ir_add_error(ira, &dest_type_value->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 26631 return ira->codegen->invalid_inst_gen; 26632 } 26633 26634 IrInstGen *target = instruction->target->child; 26635 ZigType *src_type = target->value->type; 26636 if (type_is_invalid(src_type)) 26637 return ira->codegen->invalid_inst_gen; 26638 26639 if (src_type->id != ZigTypeIdInt && 26640 src_type->id != ZigTypeIdComptimeInt) 26641 { 26642 ir_add_error(ira, &target->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&src_type->name))); 26643 return ira->codegen->invalid_inst_gen; 26644 } 26645 26646 if (dest_type->id == ZigTypeIdComptimeInt) { 26647 return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); 26648 } 26649 26650 if (instr_is_comptime(target)) { 26651 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 26652 if (val == nullptr) 26653 return ira->codegen->invalid_inst_gen; 26654 26655 IrInstGen *result = ir_const(ira, &instruction->base.base, dest_type); 26656 bigint_truncate(&result->value->data.x_bigint, &val->data.x_bigint, 26657 dest_type->data.integral.bit_count, dest_type->data.integral.is_signed); 26658 return result; 26659 } 26660 26661 if (src_type->data.integral.bit_count == 0 || dest_type->data.integral.bit_count == 0) { 26662 IrInstGen *result = ir_const(ira, &instruction->base.base, dest_type); 26663 bigint_init_unsigned(&result->value->data.x_bigint, 0); 26664 return result; 26665 } 26666 26667 if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) { 26668 const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned"; 26669 ir_add_error(ira, &target->base, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name))); 26670 return ira->codegen->invalid_inst_gen; 26671 } else if (src_type->data.integral.bit_count < dest_type->data.integral.bit_count) { 26672 ir_add_error(ira, &target->base, buf_sprintf("type '%s' has fewer bits than destination type '%s'", 26673 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 26674 return ira->codegen->invalid_inst_gen; 26675 } 26676 26677 return ir_build_truncate_gen(ira, &instruction->base.base, dest_type, target); 26678 } 26679 26680 static IrInstGen *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstSrcIntCast *instruction) { 26681 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 26682 if (type_is_invalid(dest_type)) 26683 return ira->codegen->invalid_inst_gen; 26684 26685 if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { 26686 ir_add_error(ira, &instruction->dest_type->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 26687 return ira->codegen->invalid_inst_gen; 26688 } 26689 26690 IrInstGen *target = instruction->target->child; 26691 if (type_is_invalid(target->value->type)) 26692 return ira->codegen->invalid_inst_gen; 26693 26694 if (target->value->type->id != ZigTypeIdInt && target->value->type->id != ZigTypeIdComptimeInt) { 26695 ir_add_error(ira, &instruction->target->base, buf_sprintf("expected integer type, found '%s'", 26696 buf_ptr(&target->value->type->name))); 26697 return ira->codegen->invalid_inst_gen; 26698 } 26699 26700 if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeInt) { 26701 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 26702 if (val == nullptr) 26703 return ira->codegen->invalid_inst_gen; 26704 26705 return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); 26706 } 26707 26708 return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type); 26709 } 26710 26711 static IrInstGen *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstSrcFloatCast *instruction) { 26712 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 26713 if (type_is_invalid(dest_type)) 26714 return ira->codegen->invalid_inst_gen; 26715 26716 if (dest_type->id != ZigTypeIdFloat && dest_type->id != ZigTypeIdComptimeFloat) { 26717 ir_add_error(ira, &instruction->dest_type->base, 26718 buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); 26719 return ira->codegen->invalid_inst_gen; 26720 } 26721 26722 IrInstGen *target = instruction->target->child; 26723 if (type_is_invalid(target->value->type)) 26724 return ira->codegen->invalid_inst_gen; 26725 26726 if (target->value->type->id == ZigTypeIdComptimeInt || 26727 target->value->type->id == ZigTypeIdComptimeFloat) 26728 { 26729 if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { 26730 CastOp op; 26731 if (target->value->type->id == ZigTypeIdComptimeInt) { 26732 op = CastOpIntToFloat; 26733 } else { 26734 op = CastOpNumLitToConcrete; 26735 } 26736 return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, op); 26737 } else { 26738 return ira->codegen->invalid_inst_gen; 26739 } 26740 } 26741 26742 if (target->value->type->id != ZigTypeIdFloat) { 26743 ir_add_error(ira, &instruction->target->base, buf_sprintf("expected float type, found '%s'", 26744 buf_ptr(&target->value->type->name))); 26745 return ira->codegen->invalid_inst_gen; 26746 } 26747 26748 if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeFloat) { 26749 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 26750 if (val == nullptr) 26751 return ira->codegen->invalid_inst_gen; 26752 26753 return ir_analyze_widen_or_shorten(ira, &instruction->target->base, target, dest_type); 26754 } 26755 26756 return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type); 26757 } 26758 26759 static IrInstGen *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstSrcErrSetCast *instruction) { 26760 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 26761 if (type_is_invalid(dest_type)) 26762 return ira->codegen->invalid_inst_gen; 26763 26764 if (dest_type->id != ZigTypeIdErrorSet) { 26765 ir_add_error(ira, &instruction->dest_type->base, 26766 buf_sprintf("expected error set type, found '%s'", buf_ptr(&dest_type->name))); 26767 return ira->codegen->invalid_inst_gen; 26768 } 26769 26770 IrInstGen *target = instruction->target->child; 26771 if (type_is_invalid(target->value->type)) 26772 return ira->codegen->invalid_inst_gen; 26773 26774 if (target->value->type->id != ZigTypeIdErrorSet) { 26775 ir_add_error(ira, &instruction->target->base, 26776 buf_sprintf("expected error set type, found '%s'", buf_ptr(&target->value->type->name))); 26777 return ira->codegen->invalid_inst_gen; 26778 } 26779 26780 return ir_analyze_err_set_cast(ira, &instruction->base.base, target, dest_type); 26781 } 26782 26783 static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { 26784 Error err; 26785 26786 ZigType *ptr_type; 26787 if (is_slice(ty)) { 26788 TypeStructField *ptr_field = ty->data.structure.fields[slice_ptr_index]; 26789 ptr_type = resolve_struct_field_type(ira->codegen, ptr_field); 26790 } else { 26791 ptr_type = get_src_ptr_type(ty); 26792 } 26793 assert(ptr_type != nullptr); 26794 if (ptr_type->id == ZigTypeIdPointer) { 26795 if ((err = type_resolve(ira->codegen, ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 26796 return err; 26797 } else if (is_slice(ptr_type)) { 26798 TypeStructField *ptr_field = ptr_type->data.structure.fields[slice_ptr_index]; 26799 ZigType *slice_ptr_type = resolve_struct_field_type(ira->codegen, ptr_field); 26800 if ((err = type_resolve(ira->codegen, slice_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 26801 return err; 26802 } 26803 26804 *result_align = get_ptr_align(ira->codegen, ty); 26805 return ErrorNone; 26806 } 26807 26808 static IrInstGen *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstSrcIntToFloat *instruction) { 26809 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 26810 if (type_is_invalid(dest_type)) 26811 return ira->codegen->invalid_inst_gen; 26812 26813 if (dest_type->id != ZigTypeIdFloat && dest_type->id != ZigTypeIdComptimeFloat) { 26814 ir_add_error(ira, &instruction->dest_type->base, 26815 buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); 26816 return ira->codegen->invalid_inst_gen; 26817 } 26818 26819 IrInstGen *target = instruction->target->child; 26820 if (type_is_invalid(target->value->type)) 26821 return ira->codegen->invalid_inst_gen; 26822 26823 if (target->value->type->id != ZigTypeIdInt && target->value->type->id != ZigTypeIdComptimeInt) { 26824 ir_add_error(ira, &instruction->target->base, buf_sprintf("expected int type, found '%s'", 26825 buf_ptr(&target->value->type->name))); 26826 return ira->codegen->invalid_inst_gen; 26827 } 26828 26829 return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, CastOpIntToFloat); 26830 } 26831 26832 static IrInstGen *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstSrcFloatToInt *instruction) { 26833 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 26834 if (type_is_invalid(dest_type)) 26835 return ira->codegen->invalid_inst_gen; 26836 26837 if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { 26838 ir_add_error(ira, &instruction->dest_type->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 26839 return ira->codegen->invalid_inst_gen; 26840 } 26841 26842 IrInstGen *target = instruction->target->child; 26843 if (type_is_invalid(target->value->type)) 26844 return ira->codegen->invalid_inst_gen; 26845 26846 if (target->value->type->id == ZigTypeIdComptimeInt) { 26847 return ir_implicit_cast(ira, target, dest_type); 26848 } 26849 26850 if (target->value->type->id != ZigTypeIdFloat && target->value->type->id != ZigTypeIdComptimeFloat) { 26851 ir_add_error_node(ira, target->base.source_node, buf_sprintf("expected float type, found '%s'", 26852 buf_ptr(&target->value->type->name))); 26853 return ira->codegen->invalid_inst_gen; 26854 } 26855 26856 return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, CastOpFloatToInt); 26857 } 26858 26859 static IrInstGen *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstSrcErrToInt *instruction) { 26860 IrInstGen *target = instruction->target->child; 26861 if (type_is_invalid(target->value->type)) 26862 return ira->codegen->invalid_inst_gen; 26863 26864 IrInstGen *casted_target; 26865 if (target->value->type->id == ZigTypeIdErrorSet) { 26866 casted_target = target; 26867 } else { 26868 casted_target = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_global_error_set); 26869 if (type_is_invalid(casted_target->value->type)) 26870 return ira->codegen->invalid_inst_gen; 26871 } 26872 26873 return ir_analyze_err_to_int(ira, &instruction->base.base, casted_target, ira->codegen->err_tag_type); 26874 } 26875 26876 static IrInstGen *ir_analyze_instruction_int_to_err(IrAnalyze *ira, IrInstSrcIntToErr *instruction) { 26877 IrInstGen *target = instruction->target->child; 26878 if (type_is_invalid(target->value->type)) 26879 return ira->codegen->invalid_inst_gen; 26880 26881 IrInstGen *casted_target = ir_implicit_cast(ira, target, ira->codegen->err_tag_type); 26882 if (type_is_invalid(casted_target->value->type)) 26883 return ira->codegen->invalid_inst_gen; 26884 26885 return ir_analyze_int_to_err(ira, &instruction->base.base, casted_target, ira->codegen->builtin_types.entry_global_error_set); 26886 } 26887 26888 static IrInstGen *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstSrcBoolToInt *instruction) { 26889 IrInstGen *target = instruction->target->child; 26890 if (type_is_invalid(target->value->type)) 26891 return ira->codegen->invalid_inst_gen; 26892 26893 if (target->value->type->id != ZigTypeIdBool) { 26894 ir_add_error(ira, &instruction->target->base, buf_sprintf("expected bool, found '%s'", 26895 buf_ptr(&target->value->type->name))); 26896 return ira->codegen->invalid_inst_gen; 26897 } 26898 26899 if (instr_is_comptime(target)) { 26900 bool is_true; 26901 if (!ir_resolve_bool(ira, target, &is_true)) 26902 return ira->codegen->invalid_inst_gen; 26903 26904 return ir_const_unsigned(ira, &instruction->base.base, is_true ? 1 : 0); 26905 } 26906 26907 ZigType *u1_type = get_int_type(ira->codegen, false, 1); 26908 return ir_resolve_cast(ira, &instruction->base.base, target, u1_type, CastOpBoolToInt); 26909 } 26910 26911 static IrInstGen *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstSrcVectorType *instruction) { 26912 uint64_t len; 26913 if (!ir_resolve_unsigned(ira, instruction->len->child, ira->codegen->builtin_types.entry_u32, &len)) 26914 return ira->codegen->invalid_inst_gen; 26915 26916 ZigType *elem_type = ir_resolve_vector_elem_type(ira, instruction->elem_type->child); 26917 if (type_is_invalid(elem_type)) 26918 return ira->codegen->invalid_inst_gen; 26919 26920 ZigType *vector_type = get_vector_type(ira->codegen, len, elem_type); 26921 26922 return ir_const_type(ira, &instruction->base.base, vector_type); 26923 } 26924 26925 static IrInstGen *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInst* source_instr, 26926 ZigType *scalar_type, IrInstGen *a, IrInstGen *b, IrInstGen *mask) 26927 { 26928 Error err; 26929 ir_assert(source_instr && scalar_type && a && b && mask, source_instr); 26930 26931 if ((err = ir_validate_vector_elem_type(ira, source_instr->source_node, scalar_type))) 26932 return ira->codegen->invalid_inst_gen; 26933 26934 uint32_t len_mask; 26935 if (mask->value->type->id == ZigTypeIdVector) { 26936 len_mask = mask->value->type->data.vector.len; 26937 } else if (mask->value->type->id == ZigTypeIdArray) { 26938 len_mask = mask->value->type->data.array.len; 26939 } else { 26940 ir_add_error(ira, &mask->base, 26941 buf_sprintf("expected vector or array, found '%s'", 26942 buf_ptr(&mask->value->type->name))); 26943 return ira->codegen->invalid_inst_gen; 26944 } 26945 mask = ir_implicit_cast(ira, mask, get_vector_type(ira->codegen, len_mask, 26946 ira->codegen->builtin_types.entry_i32)); 26947 if (type_is_invalid(mask->value->type)) 26948 return ira->codegen->invalid_inst_gen; 26949 26950 uint32_t len_a; 26951 if (a->value->type->id == ZigTypeIdVector) { 26952 len_a = a->value->type->data.vector.len; 26953 } else if (a->value->type->id == ZigTypeIdArray) { 26954 len_a = a->value->type->data.array.len; 26955 } else if (a->value->type->id == ZigTypeIdUndefined) { 26956 len_a = UINT32_MAX; 26957 } else { 26958 ir_add_error(ira, &a->base, 26959 buf_sprintf("expected vector or array with element type '%s', found '%s'", 26960 buf_ptr(&scalar_type->name), 26961 buf_ptr(&a->value->type->name))); 26962 return ira->codegen->invalid_inst_gen; 26963 } 26964 26965 uint32_t len_b; 26966 if (b->value->type->id == ZigTypeIdVector) { 26967 len_b = b->value->type->data.vector.len; 26968 } else if (b->value->type->id == ZigTypeIdArray) { 26969 len_b = b->value->type->data.array.len; 26970 } else if (b->value->type->id == ZigTypeIdUndefined) { 26971 len_b = UINT32_MAX; 26972 } else { 26973 ir_add_error(ira, &b->base, 26974 buf_sprintf("expected vector or array with element type '%s', found '%s'", 26975 buf_ptr(&scalar_type->name), 26976 buf_ptr(&b->value->type->name))); 26977 return ira->codegen->invalid_inst_gen; 26978 } 26979 26980 if (len_a == UINT32_MAX && len_b == UINT32_MAX) { 26981 return ir_const_undef(ira, &a->base, get_vector_type(ira->codegen, len_mask, scalar_type)); 26982 } 26983 26984 if (len_a == UINT32_MAX) { 26985 len_a = len_b; 26986 a = ir_const_undef(ira, &a->base, get_vector_type(ira->codegen, len_a, scalar_type)); 26987 } else { 26988 a = ir_implicit_cast(ira, a, get_vector_type(ira->codegen, len_a, scalar_type)); 26989 if (type_is_invalid(a->value->type)) 26990 return ira->codegen->invalid_inst_gen; 26991 } 26992 26993 if (len_b == UINT32_MAX) { 26994 len_b = len_a; 26995 b = ir_const_undef(ira, &b->base, get_vector_type(ira->codegen, len_b, scalar_type)); 26996 } else { 26997 b = ir_implicit_cast(ira, b, get_vector_type(ira->codegen, len_b, scalar_type)); 26998 if (type_is_invalid(b->value->type)) 26999 return ira->codegen->invalid_inst_gen; 27000 } 27001 27002 ZigValue *mask_val = ir_resolve_const(ira, mask, UndefOk); 27003 if (mask_val == nullptr) 27004 return ira->codegen->invalid_inst_gen; 27005 27006 expand_undef_array(ira->codegen, mask_val); 27007 27008 for (uint32_t i = 0; i < len_mask; i += 1) { 27009 ZigValue *mask_elem_val = &mask_val->data.x_array.data.s_none.elements[i]; 27010 if (mask_elem_val->special == ConstValSpecialUndef) 27011 continue; 27012 int32_t v_i32 = bigint_as_signed(&mask_elem_val->data.x_bigint); 27013 uint32_t v; 27014 IrInstGen *chosen_operand; 27015 if (v_i32 >= 0) { 27016 v = (uint32_t)v_i32; 27017 chosen_operand = a; 27018 } else { 27019 v = (uint32_t)~v_i32; 27020 chosen_operand = b; 27021 } 27022 if (v >= chosen_operand->value->type->data.vector.len) { 27023 ErrorMsg *msg = ir_add_error(ira, &mask->base, 27024 buf_sprintf("mask index '%u' has out-of-bounds selection", i)); 27025 add_error_note(ira->codegen, msg, chosen_operand->base.source_node, 27026 buf_sprintf("selected index '%u' out of bounds of %s", v, 27027 buf_ptr(&chosen_operand->value->type->name))); 27028 if (chosen_operand == a && v < len_a + len_b) { 27029 add_error_note(ira->codegen, msg, b->base.source_node, 27030 buf_create_from_str("selections from the second vector are specified with negative numbers")); 27031 } 27032 return ira->codegen->invalid_inst_gen; 27033 } 27034 } 27035 27036 ZigType *result_type = get_vector_type(ira->codegen, len_mask, scalar_type); 27037 if (instr_is_comptime(a) && instr_is_comptime(b)) { 27038 ZigValue *a_val = ir_resolve_const(ira, a, UndefOk); 27039 if (a_val == nullptr) 27040 return ira->codegen->invalid_inst_gen; 27041 27042 ZigValue *b_val = ir_resolve_const(ira, b, UndefOk); 27043 if (b_val == nullptr) 27044 return ira->codegen->invalid_inst_gen; 27045 27046 expand_undef_array(ira->codegen, a_val); 27047 expand_undef_array(ira->codegen, b_val); 27048 27049 IrInstGen *result = ir_const(ira, source_instr, result_type); 27050 result->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(len_mask); 27051 for (uint32_t i = 0; i < mask_val->type->data.vector.len; i += 1) { 27052 ZigValue *mask_elem_val = &mask_val->data.x_array.data.s_none.elements[i]; 27053 ZigValue *result_elem_val = &result->value->data.x_array.data.s_none.elements[i]; 27054 if (mask_elem_val->special == ConstValSpecialUndef) { 27055 result_elem_val->special = ConstValSpecialUndef; 27056 continue; 27057 } 27058 int32_t v = bigint_as_signed(&mask_elem_val->data.x_bigint); 27059 // We've already checked for and emitted compile errors for index out of bounds here. 27060 ZigValue *src_elem_val = (v >= 0) ? 27061 &a->value->data.x_array.data.s_none.elements[v] : 27062 &b->value->data.x_array.data.s_none.elements[~v]; 27063 copy_const_val(ira->codegen, result_elem_val, src_elem_val); 27064 27065 ir_assert(result_elem_val->special == ConstValSpecialStatic, source_instr); 27066 } 27067 result->value->special = ConstValSpecialStatic; 27068 return result; 27069 } 27070 27071 // All static analysis passed, and not comptime. 27072 // For runtime codegen, vectors a and b must be the same length. Here we 27073 // recursively @shuffle the smaller vector to append undefined elements 27074 // to it up to the length of the longer vector. This recursion terminates 27075 // in 1 call because these calls to ir_analyze_shuffle_vector guarantee 27076 // len_a == len_b. 27077 if (len_a != len_b) { 27078 uint32_t len_min = min(len_a, len_b); 27079 uint32_t len_max = max(len_a, len_b); 27080 27081 IrInstGen *expand_mask = ir_const(ira, &mask->base, 27082 get_vector_type(ira->codegen, len_max, ira->codegen->builtin_types.entry_i32)); 27083 expand_mask->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(len_max); 27084 uint32_t i = 0; 27085 for (; i < len_min; i += 1) 27086 bigint_init_unsigned(&expand_mask->value->data.x_array.data.s_none.elements[i].data.x_bigint, i); 27087 for (; i < len_max; i += 1) 27088 bigint_init_signed(&expand_mask->value->data.x_array.data.s_none.elements[i].data.x_bigint, -1); 27089 27090 IrInstGen *undef = ir_const_undef(ira, source_instr, 27091 get_vector_type(ira->codegen, len_min, scalar_type)); 27092 27093 if (len_b < len_a) { 27094 b = ir_analyze_shuffle_vector(ira, source_instr, scalar_type, b, undef, expand_mask); 27095 } else { 27096 a = ir_analyze_shuffle_vector(ira, source_instr, scalar_type, a, undef, expand_mask); 27097 } 27098 } 27099 27100 return ir_build_shuffle_vector_gen(ira, source_instr->scope, source_instr->source_node, 27101 result_type, a, b, mask); 27102 } 27103 27104 static IrInstGen *ir_analyze_instruction_shuffle_vector(IrAnalyze *ira, IrInstSrcShuffleVector *instruction) { 27105 ZigType *scalar_type = ir_resolve_vector_elem_type(ira, instruction->scalar_type->child); 27106 if (type_is_invalid(scalar_type)) 27107 return ira->codegen->invalid_inst_gen; 27108 27109 IrInstGen *a = instruction->a->child; 27110 if (type_is_invalid(a->value->type)) 27111 return ira->codegen->invalid_inst_gen; 27112 27113 IrInstGen *b = instruction->b->child; 27114 if (type_is_invalid(b->value->type)) 27115 return ira->codegen->invalid_inst_gen; 27116 27117 IrInstGen *mask = instruction->mask->child; 27118 if (type_is_invalid(mask->value->type)) 27119 return ira->codegen->invalid_inst_gen; 27120 27121 return ir_analyze_shuffle_vector(ira, &instruction->base.base, scalar_type, a, b, mask); 27122 } 27123 27124 static IrInstGen *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstSrcSplat *instruction) { 27125 Error err; 27126 27127 IrInstGen *len = instruction->len->child; 27128 if (type_is_invalid(len->value->type)) 27129 return ira->codegen->invalid_inst_gen; 27130 27131 IrInstGen *scalar = instruction->scalar->child; 27132 if (type_is_invalid(scalar->value->type)) 27133 return ira->codegen->invalid_inst_gen; 27134 27135 uint64_t len_u64; 27136 if (!ir_resolve_unsigned(ira, len, ira->codegen->builtin_types.entry_u32, &len_u64)) 27137 return ira->codegen->invalid_inst_gen; 27138 uint32_t len_int = len_u64; 27139 27140 if ((err = ir_validate_vector_elem_type(ira, scalar->base.source_node, scalar->value->type))) 27141 return ira->codegen->invalid_inst_gen; 27142 27143 ZigType *return_type = get_vector_type(ira->codegen, len_int, scalar->value->type); 27144 27145 if (instr_is_comptime(scalar)) { 27146 ZigValue *scalar_val = ir_resolve_const(ira, scalar, UndefOk); 27147 if (scalar_val == nullptr) 27148 return ira->codegen->invalid_inst_gen; 27149 if (scalar_val->special == ConstValSpecialUndef) 27150 return ir_const_undef(ira, &instruction->base.base, return_type); 27151 27152 IrInstGen *result = ir_const(ira, &instruction->base.base, return_type); 27153 result->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(len_int); 27154 for (uint32_t i = 0; i < len_int; i += 1) { 27155 copy_const_val(ira->codegen, &result->value->data.x_array.data.s_none.elements[i], scalar_val); 27156 } 27157 return result; 27158 } 27159 27160 return ir_build_splat_gen(ira, &instruction->base.base, return_type, scalar); 27161 } 27162 27163 static IrInstGen *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstSrcBoolNot *instruction) { 27164 IrInstGen *value = instruction->value->child; 27165 if (type_is_invalid(value->value->type)) 27166 return ira->codegen->invalid_inst_gen; 27167 27168 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 27169 27170 IrInstGen *casted_value = ir_implicit_cast(ira, value, bool_type); 27171 if (type_is_invalid(casted_value->value->type)) 27172 return ira->codegen->invalid_inst_gen; 27173 27174 if (instr_is_comptime(casted_value)) { 27175 ZigValue *value = ir_resolve_const(ira, casted_value, UndefBad); 27176 if (value == nullptr) 27177 return ira->codegen->invalid_inst_gen; 27178 27179 return ir_const_bool(ira, &instruction->base.base, !value->data.x_bool); 27180 } 27181 27182 return ir_build_bool_not_gen(ira, &instruction->base.base, casted_value); 27183 } 27184 27185 static IrInstGen *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstSrcMemset *instruction) { 27186 Error err; 27187 27188 IrInstGen *dest_ptr = instruction->dest_ptr->child; 27189 if (type_is_invalid(dest_ptr->value->type)) 27190 return ira->codegen->invalid_inst_gen; 27191 27192 IrInstGen *byte_value = instruction->byte->child; 27193 if (type_is_invalid(byte_value->value->type)) 27194 return ira->codegen->invalid_inst_gen; 27195 27196 IrInstGen *count_value = instruction->count->child; 27197 if (type_is_invalid(count_value->value->type)) 27198 return ira->codegen->invalid_inst_gen; 27199 27200 ZigType *dest_uncasted_type = dest_ptr->value->type; 27201 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 27202 dest_uncasted_type->data.pointer.is_volatile; 27203 27204 ZigType *usize = ira->codegen->builtin_types.entry_usize; 27205 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 27206 uint32_t dest_align; 27207 if (dest_uncasted_type->id == ZigTypeIdPointer) { 27208 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 27209 return ira->codegen->invalid_inst_gen; 27210 } else { 27211 dest_align = get_abi_alignment(ira->codegen, u8); 27212 } 27213 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 27214 PtrLenUnknown, dest_align, 0, 0, false); 27215 27216 IrInstGen *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr); 27217 if (type_is_invalid(casted_dest_ptr->value->type)) 27218 return ira->codegen->invalid_inst_gen; 27219 27220 IrInstGen *casted_byte = ir_implicit_cast(ira, byte_value, u8); 27221 if (type_is_invalid(casted_byte->value->type)) 27222 return ira->codegen->invalid_inst_gen; 27223 27224 IrInstGen *casted_count = ir_implicit_cast(ira, count_value, usize); 27225 if (type_is_invalid(casted_count->value->type)) 27226 return ira->codegen->invalid_inst_gen; 27227 27228 // TODO test this at comptime with u8 and non-u8 types 27229 if (instr_is_comptime(casted_dest_ptr) && 27230 instr_is_comptime(casted_byte) && 27231 instr_is_comptime(casted_count)) 27232 { 27233 ZigValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); 27234 if (dest_ptr_val == nullptr) 27235 return ira->codegen->invalid_inst_gen; 27236 27237 ZigValue *byte_val = ir_resolve_const(ira, casted_byte, UndefOk); 27238 if (byte_val == nullptr) 27239 return ira->codegen->invalid_inst_gen; 27240 27241 ZigValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); 27242 if (count_val == nullptr) 27243 return ira->codegen->invalid_inst_gen; 27244 27245 if (casted_dest_ptr->value->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && 27246 casted_dest_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 27247 { 27248 ZigValue *dest_elements; 27249 size_t start; 27250 size_t bound_end; 27251 switch (dest_ptr_val->data.x_ptr.special) { 27252 case ConstPtrSpecialInvalid: 27253 case ConstPtrSpecialDiscard: 27254 zig_unreachable(); 27255 case ConstPtrSpecialRef: 27256 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 27257 start = 0; 27258 bound_end = 1; 27259 break; 27260 case ConstPtrSpecialSubArray: 27261 case ConstPtrSpecialBaseArray: 27262 { 27263 ZigValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 27264 expand_undef_array(ira->codegen, array_val); 27265 dest_elements = array_val->data.x_array.data.s_none.elements; 27266 start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 27267 bound_end = array_val->type->data.array.len; 27268 break; 27269 } 27270 case ConstPtrSpecialBaseStruct: 27271 zig_panic("TODO memset on const inner struct"); 27272 case ConstPtrSpecialBaseErrorUnionCode: 27273 zig_panic("TODO memset on const inner error union code"); 27274 case ConstPtrSpecialBaseErrorUnionPayload: 27275 zig_panic("TODO memset on const inner error union payload"); 27276 case ConstPtrSpecialBaseOptionalPayload: 27277 zig_panic("TODO memset on const inner optional payload"); 27278 case ConstPtrSpecialHardCodedAddr: 27279 zig_unreachable(); 27280 case ConstPtrSpecialFunction: 27281 zig_panic("TODO memset on ptr cast from function"); 27282 case ConstPtrSpecialNull: 27283 zig_panic("TODO memset on null ptr"); 27284 } 27285 27286 size_t count = bigint_as_usize(&count_val->data.x_bigint); 27287 size_t end = start + count; 27288 if (end > bound_end) { 27289 ir_add_error(ira, &count_value->base, buf_sprintf("out of bounds pointer access")); 27290 return ira->codegen->invalid_inst_gen; 27291 } 27292 27293 for (size_t i = start; i < end; i += 1) { 27294 copy_const_val(ira->codegen, &dest_elements[i], byte_val); 27295 } 27296 27297 return ir_const_void(ira, &instruction->base.base); 27298 } 27299 } 27300 27301 return ir_build_memset_gen(ira, &instruction->base.base, casted_dest_ptr, casted_byte, casted_count); 27302 } 27303 27304 static IrInstGen *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstSrcMemcpy *instruction) { 27305 Error err; 27306 27307 IrInstGen *dest_ptr = instruction->dest_ptr->child; 27308 if (type_is_invalid(dest_ptr->value->type)) 27309 return ira->codegen->invalid_inst_gen; 27310 27311 IrInstGen *src_ptr = instruction->src_ptr->child; 27312 if (type_is_invalid(src_ptr->value->type)) 27313 return ira->codegen->invalid_inst_gen; 27314 27315 IrInstGen *count_value = instruction->count->child; 27316 if (type_is_invalid(count_value->value->type)) 27317 return ira->codegen->invalid_inst_gen; 27318 27319 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 27320 ZigType *dest_uncasted_type = dest_ptr->value->type; 27321 ZigType *src_uncasted_type = src_ptr->value->type; 27322 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 27323 dest_uncasted_type->data.pointer.is_volatile; 27324 bool src_is_volatile = (src_uncasted_type->id == ZigTypeIdPointer) && 27325 src_uncasted_type->data.pointer.is_volatile; 27326 27327 uint32_t dest_align; 27328 if (dest_uncasted_type->id == ZigTypeIdPointer) { 27329 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 27330 return ira->codegen->invalid_inst_gen; 27331 } else { 27332 dest_align = get_abi_alignment(ira->codegen, u8); 27333 } 27334 27335 uint32_t src_align; 27336 if (src_uncasted_type->id == ZigTypeIdPointer) { 27337 if ((err = resolve_ptr_align(ira, src_uncasted_type, &src_align))) 27338 return ira->codegen->invalid_inst_gen; 27339 } else { 27340 src_align = get_abi_alignment(ira->codegen, u8); 27341 } 27342 27343 ZigType *usize = ira->codegen->builtin_types.entry_usize; 27344 ZigType *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 27345 PtrLenUnknown, dest_align, 0, 0, false); 27346 ZigType *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, src_is_volatile, 27347 PtrLenUnknown, src_align, 0, 0, false); 27348 27349 IrInstGen *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut); 27350 if (type_is_invalid(casted_dest_ptr->value->type)) 27351 return ira->codegen->invalid_inst_gen; 27352 27353 IrInstGen *casted_src_ptr = ir_implicit_cast(ira, src_ptr, u8_ptr_const); 27354 if (type_is_invalid(casted_src_ptr->value->type)) 27355 return ira->codegen->invalid_inst_gen; 27356 27357 IrInstGen *casted_count = ir_implicit_cast(ira, count_value, usize); 27358 if (type_is_invalid(casted_count->value->type)) 27359 return ira->codegen->invalid_inst_gen; 27360 27361 // TODO test this at comptime with u8 and non-u8 types 27362 // TODO test with dest ptr being a global runtime variable 27363 if (instr_is_comptime(casted_dest_ptr) && 27364 instr_is_comptime(casted_src_ptr) && 27365 instr_is_comptime(casted_count)) 27366 { 27367 ZigValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); 27368 if (dest_ptr_val == nullptr) 27369 return ira->codegen->invalid_inst_gen; 27370 27371 ZigValue *src_ptr_val = ir_resolve_const(ira, casted_src_ptr, UndefBad); 27372 if (src_ptr_val == nullptr) 27373 return ira->codegen->invalid_inst_gen; 27374 27375 ZigValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); 27376 if (count_val == nullptr) 27377 return ira->codegen->invalid_inst_gen; 27378 27379 if (dest_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 27380 size_t count = bigint_as_usize(&count_val->data.x_bigint); 27381 27382 ZigValue *dest_elements; 27383 size_t dest_start; 27384 size_t dest_end; 27385 switch (dest_ptr_val->data.x_ptr.special) { 27386 case ConstPtrSpecialInvalid: 27387 case ConstPtrSpecialDiscard: 27388 zig_unreachable(); 27389 case ConstPtrSpecialRef: 27390 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 27391 dest_start = 0; 27392 dest_end = 1; 27393 break; 27394 case ConstPtrSpecialSubArray: 27395 case ConstPtrSpecialBaseArray: 27396 { 27397 ZigValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 27398 expand_undef_array(ira->codegen, array_val); 27399 dest_elements = array_val->data.x_array.data.s_none.elements; 27400 dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 27401 dest_end = array_val->type->data.array.len; 27402 break; 27403 } 27404 case ConstPtrSpecialBaseStruct: 27405 zig_panic("TODO memcpy on const inner struct"); 27406 case ConstPtrSpecialBaseErrorUnionCode: 27407 zig_panic("TODO memcpy on const inner error union code"); 27408 case ConstPtrSpecialBaseErrorUnionPayload: 27409 zig_panic("TODO memcpy on const inner error union payload"); 27410 case ConstPtrSpecialBaseOptionalPayload: 27411 zig_panic("TODO memcpy on const inner optional payload"); 27412 case ConstPtrSpecialHardCodedAddr: 27413 zig_unreachable(); 27414 case ConstPtrSpecialFunction: 27415 zig_panic("TODO memcpy on ptr cast from function"); 27416 case ConstPtrSpecialNull: 27417 zig_panic("TODO memcpy on null ptr"); 27418 } 27419 27420 if (dest_start + count > dest_end) { 27421 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds pointer access")); 27422 return ira->codegen->invalid_inst_gen; 27423 } 27424 27425 ZigValue *src_elements; 27426 size_t src_start; 27427 size_t src_end; 27428 27429 switch (src_ptr_val->data.x_ptr.special) { 27430 case ConstPtrSpecialInvalid: 27431 case ConstPtrSpecialDiscard: 27432 zig_unreachable(); 27433 case ConstPtrSpecialRef: 27434 src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; 27435 src_start = 0; 27436 src_end = 1; 27437 break; 27438 case ConstPtrSpecialSubArray: 27439 case ConstPtrSpecialBaseArray: 27440 { 27441 ZigValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; 27442 expand_undef_array(ira->codegen, array_val); 27443 src_elements = array_val->data.x_array.data.s_none.elements; 27444 src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; 27445 src_end = array_val->type->data.array.len; 27446 break; 27447 } 27448 case ConstPtrSpecialBaseStruct: 27449 zig_panic("TODO memcpy on const inner struct"); 27450 case ConstPtrSpecialBaseErrorUnionCode: 27451 zig_panic("TODO memcpy on const inner error union code"); 27452 case ConstPtrSpecialBaseErrorUnionPayload: 27453 zig_panic("TODO memcpy on const inner error union payload"); 27454 case ConstPtrSpecialBaseOptionalPayload: 27455 zig_panic("TODO memcpy on const inner optional payload"); 27456 case ConstPtrSpecialHardCodedAddr: 27457 zig_unreachable(); 27458 case ConstPtrSpecialFunction: 27459 zig_panic("TODO memcpy on ptr cast from function"); 27460 case ConstPtrSpecialNull: 27461 zig_panic("TODO memcpy on null ptr"); 27462 } 27463 27464 if (src_start + count > src_end) { 27465 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds pointer access")); 27466 return ira->codegen->invalid_inst_gen; 27467 } 27468 27469 // TODO check for noalias violations - this should be generalized to work for any function 27470 27471 for (size_t i = 0; i < count; i += 1) { 27472 copy_const_val(ira->codegen, &dest_elements[dest_start + i], &src_elements[src_start + i]); 27473 } 27474 27475 return ir_const_void(ira, &instruction->base.base); 27476 } 27477 } 27478 27479 return ir_build_memcpy_gen(ira, &instruction->base.base, casted_dest_ptr, casted_src_ptr, casted_count); 27480 } 27481 27482 static ZigType *get_result_loc_type(IrAnalyze *ira, ResultLoc *result_loc) { 27483 if (result_loc == nullptr) return nullptr; 27484 27485 if (result_loc->id == ResultLocIdCast) { 27486 return ir_resolve_type(ira, result_loc->source_instruction->child); 27487 } 27488 27489 return nullptr; 27490 } 27491 27492 static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *instruction) { 27493 Error err; 27494 27495 IrInstGen *ptr_ptr = instruction->ptr->child; 27496 if (type_is_invalid(ptr_ptr->value->type)) 27497 return ira->codegen->invalid_inst_gen; 27498 27499 ZigType *ptr_ptr_type = ptr_ptr->value->type; 27500 assert(ptr_ptr_type->id == ZigTypeIdPointer); 27501 ZigType *array_type = ptr_ptr_type->data.pointer.child_type; 27502 27503 IrInstGen *start = instruction->start->child; 27504 if (type_is_invalid(start->value->type)) 27505 return ira->codegen->invalid_inst_gen; 27506 27507 ZigType *usize = ira->codegen->builtin_types.entry_usize; 27508 IrInstGen *casted_start = ir_implicit_cast(ira, start, usize); 27509 if (type_is_invalid(casted_start->value->type)) 27510 return ira->codegen->invalid_inst_gen; 27511 27512 IrInstGen *end; 27513 if (instruction->end) { 27514 end = instruction->end->child; 27515 if (type_is_invalid(end->value->type)) 27516 return ira->codegen->invalid_inst_gen; 27517 end = ir_implicit_cast(ira, end, usize); 27518 if (type_is_invalid(end->value->type)) 27519 return ira->codegen->invalid_inst_gen; 27520 } else { 27521 end = nullptr; 27522 } 27523 27524 ZigValue *slice_sentinel_val = nullptr; 27525 ZigType *non_sentinel_slice_ptr_type; 27526 ZigType *elem_type; 27527 27528 bool generate_non_null_assert = false; 27529 27530 if (array_type->id == ZigTypeIdArray) { 27531 elem_type = array_type->data.array.child_type; 27532 non_sentinel_slice_ptr_type = get_pointer_to_type_extra(ira->codegen, elem_type, 27533 ptr_ptr_type->data.pointer.is_const, 27534 ptr_ptr_type->data.pointer.is_volatile, 27535 PtrLenUnknown, 27536 ptr_ptr_type->data.pointer.explicit_alignment, 0, 0, false); 27537 } else if (array_type->id == ZigTypeIdPointer) { 27538 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 27539 ZigType *main_type = array_type->data.pointer.child_type; 27540 if (main_type->id == ZigTypeIdArray) { 27541 elem_type = main_type->data.pointer.child_type; 27542 non_sentinel_slice_ptr_type = get_pointer_to_type_extra(ira->codegen, 27543 elem_type, 27544 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile, 27545 PtrLenUnknown, 27546 array_type->data.pointer.explicit_alignment, 0, 0, false); 27547 } else { 27548 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of single-item pointer")); 27549 return ira->codegen->invalid_inst_gen; 27550 } 27551 } else { 27552 elem_type = array_type->data.pointer.child_type; 27553 if (array_type->data.pointer.ptr_len == PtrLenC) { 27554 array_type = adjust_ptr_len(ira->codegen, array_type, PtrLenUnknown); 27555 27556 // C pointers are allowzero by default. 27557 // However, we want to be able to slice them without generating an allowzero slice (see issue #4401). 27558 // To achieve this, we generate a runtime safety check and make the slice type non-allowzero. 27559 if (array_type->data.pointer.allow_zero) { 27560 array_type = adjust_ptr_allow_zero(ira->codegen, array_type, false); 27561 generate_non_null_assert = true; 27562 } 27563 } 27564 ZigType *maybe_sentineled_slice_ptr_type = array_type; 27565 non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr); 27566 if (!end) { 27567 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of pointer must include end value")); 27568 return ira->codegen->invalid_inst_gen; 27569 } 27570 } 27571 } else if (is_slice(array_type)) { 27572 ZigType *maybe_sentineled_slice_ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; 27573 slice_sentinel_val = maybe_sentineled_slice_ptr_type->data.pointer.sentinel; 27574 non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr); 27575 elem_type = non_sentinel_slice_ptr_type->data.pointer.child_type; 27576 } else { 27577 ir_add_error(ira, &instruction->base.base, 27578 buf_sprintf("slice of non-array type '%s'", buf_ptr(&array_type->name))); 27579 return ira->codegen->invalid_inst_gen; 27580 } 27581 27582 ZigValue *sentinel_val = nullptr; 27583 if (instruction->sentinel) { 27584 IrInstGen *uncasted_sentinel = instruction->sentinel->child; 27585 if (type_is_invalid(uncasted_sentinel->value->type)) 27586 return ira->codegen->invalid_inst_gen; 27587 IrInstGen *sentinel = ir_implicit_cast(ira, uncasted_sentinel, elem_type); 27588 if (type_is_invalid(sentinel->value->type)) 27589 return ira->codegen->invalid_inst_gen; 27590 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 27591 if (sentinel_val == nullptr) 27592 return ira->codegen->invalid_inst_gen; 27593 } 27594 27595 ZigType *child_array_type = (array_type->id == ZigTypeIdPointer && 27596 array_type->data.pointer.ptr_len == PtrLenSingle) ? array_type->data.pointer.child_type : array_type; 27597 27598 ZigType *return_type; 27599 27600 // If start index and end index are both comptime known, then the result type is a pointer to array 27601 // not a slice. However, if the start or end index is a lazy value, and the result location is a slice, 27602 // then the pointer-to-array would be casted to a slice anyway. So, we preserve the laziness of these 27603 // values by making the return type a slice. 27604 ZigType *res_loc_type = get_result_loc_type(ira, instruction->result_loc); 27605 bool result_loc_is_slice = (res_loc_type != nullptr && is_slice(res_loc_type)); 27606 bool end_is_known = !result_loc_is_slice && 27607 ((end != nullptr && value_is_comptime(end->value)) || 27608 (end == nullptr && child_array_type->id == ZigTypeIdArray)); 27609 27610 ZigValue *array_sentinel = sentinel_val; 27611 if (end_is_known) { 27612 uint64_t end_scalar; 27613 if (end != nullptr) { 27614 ZigValue *end_val = ir_resolve_const(ira, end, UndefBad); 27615 if (!end_val) 27616 return ira->codegen->invalid_inst_gen; 27617 end_scalar = bigint_as_u64(&end_val->data.x_bigint); 27618 } else { 27619 end_scalar = child_array_type->data.array.len; 27620 } 27621 array_sentinel = (child_array_type->id == ZigTypeIdArray && end_scalar == child_array_type->data.array.len) 27622 ? child_array_type->data.array.sentinel : sentinel_val; 27623 27624 if (value_is_comptime(casted_start->value)) { 27625 ZigValue *start_val = ir_resolve_const(ira, casted_start, UndefBad); 27626 if (!start_val) 27627 return ira->codegen->invalid_inst_gen; 27628 27629 uint64_t start_scalar = bigint_as_u64(&start_val->data.x_bigint); 27630 27631 if (start_scalar > end_scalar) { 27632 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds slice")); 27633 return ira->codegen->invalid_inst_gen; 27634 } 27635 27636 uint32_t base_ptr_align = non_sentinel_slice_ptr_type->data.pointer.explicit_alignment; 27637 uint32_t ptr_byte_alignment = 0; 27638 if (end_scalar > start_scalar) { 27639 if ((err = compute_elem_align(ira, elem_type, base_ptr_align, start_scalar, &ptr_byte_alignment))) 27640 return ira->codegen->invalid_inst_gen; 27641 } 27642 27643 ZigType *return_array_type = get_array_type(ira->codegen, elem_type, end_scalar - start_scalar, 27644 array_sentinel); 27645 return_type = get_pointer_to_type_extra(ira->codegen, return_array_type, 27646 non_sentinel_slice_ptr_type->data.pointer.is_const, 27647 non_sentinel_slice_ptr_type->data.pointer.is_volatile, 27648 PtrLenSingle, ptr_byte_alignment, 0, 0, false); 27649 goto done_with_return_type; 27650 } 27651 } else if (array_sentinel == nullptr && end == nullptr) { 27652 array_sentinel = slice_sentinel_val; 27653 } 27654 if (array_sentinel != nullptr) { 27655 // TODO deal with non-abi-alignment here 27656 ZigType *slice_ptr_type = adjust_ptr_sentinel(ira->codegen, non_sentinel_slice_ptr_type, array_sentinel); 27657 return_type = get_slice_type(ira->codegen, slice_ptr_type); 27658 } else { 27659 // TODO deal with non-abi-alignment here 27660 return_type = get_slice_type(ira->codegen, non_sentinel_slice_ptr_type); 27661 } 27662 done_with_return_type: 27663 27664 if (instr_is_comptime(ptr_ptr) && 27665 value_is_comptime(casted_start->value) && 27666 (!end || value_is_comptime(end->value))) 27667 { 27668 ZigValue *array_val; 27669 ZigValue *parent_ptr; 27670 size_t abs_offset; 27671 size_t rel_end; 27672 bool ptr_is_undef = false; 27673 if (child_array_type->id == ZigTypeIdArray) { 27674 if (array_type->id == ZigTypeIdPointer) { 27675 parent_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 27676 if (parent_ptr == nullptr) 27677 return ira->codegen->invalid_inst_gen; 27678 27679 if (parent_ptr->special == ConstValSpecialUndef) { 27680 array_val = nullptr; 27681 abs_offset = 0; 27682 rel_end = SIZE_MAX; 27683 ptr_is_undef = true; 27684 } else if (parent_ptr->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 27685 array_val = nullptr; 27686 abs_offset = 0; 27687 rel_end = SIZE_MAX; 27688 } else { 27689 array_val = const_ptr_pointee(ira, ira->codegen, parent_ptr, instruction->base.base.source_node); 27690 if (array_val == nullptr) 27691 return ira->codegen->invalid_inst_gen; 27692 27693 rel_end = child_array_type->data.array.len; 27694 abs_offset = 0; 27695 } 27696 } else { 27697 array_val = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 27698 if (array_val == nullptr) 27699 return ira->codegen->invalid_inst_gen; 27700 rel_end = array_type->data.array.len; 27701 parent_ptr = nullptr; 27702 abs_offset = 0; 27703 } 27704 } else if (array_type->id == ZigTypeIdPointer) { 27705 assert(array_type->data.pointer.ptr_len == PtrLenUnknown); 27706 parent_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 27707 if (parent_ptr == nullptr) 27708 return ira->codegen->invalid_inst_gen; 27709 27710 if (parent_ptr->special == ConstValSpecialUndef) { 27711 array_val = nullptr; 27712 abs_offset = 0; 27713 rel_end = SIZE_MAX; 27714 ptr_is_undef = true; 27715 } else switch (parent_ptr->data.x_ptr.special) { 27716 case ConstPtrSpecialInvalid: 27717 case ConstPtrSpecialDiscard: 27718 zig_unreachable(); 27719 case ConstPtrSpecialRef: 27720 if (parent_ptr->data.x_ptr.data.ref.pointee->type->id == ZigTypeIdArray) { 27721 array_val = parent_ptr->data.x_ptr.data.ref.pointee; 27722 abs_offset = 0; 27723 rel_end = array_val->type->data.array.len; 27724 } else { 27725 array_val = nullptr; 27726 abs_offset = SIZE_MAX; 27727 rel_end = 1; 27728 } 27729 break; 27730 case ConstPtrSpecialSubArray: 27731 case ConstPtrSpecialBaseArray: 27732 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 27733 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 27734 rel_end = array_val->type->data.array.len - abs_offset; 27735 break; 27736 case ConstPtrSpecialBaseStruct: 27737 zig_panic("TODO slice const inner struct"); 27738 case ConstPtrSpecialBaseErrorUnionCode: 27739 zig_panic("TODO slice const inner error union code"); 27740 case ConstPtrSpecialBaseErrorUnionPayload: 27741 zig_panic("TODO slice const inner error union payload"); 27742 case ConstPtrSpecialBaseOptionalPayload: 27743 zig_panic("TODO slice const inner optional payload"); 27744 case ConstPtrSpecialHardCodedAddr: 27745 array_val = nullptr; 27746 abs_offset = 0; 27747 rel_end = SIZE_MAX; 27748 break; 27749 case ConstPtrSpecialFunction: 27750 zig_panic("TODO slice of ptr cast from function"); 27751 case ConstPtrSpecialNull: 27752 zig_panic("TODO slice of null ptr"); 27753 } 27754 } else if (is_slice(array_type)) { 27755 ZigValue *slice_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 27756 if (slice_ptr == nullptr) 27757 return ira->codegen->invalid_inst_gen; 27758 27759 if (slice_ptr->special == ConstValSpecialUndef) { 27760 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of undefined")); 27761 return ira->codegen->invalid_inst_gen; 27762 } 27763 27764 parent_ptr = slice_ptr->data.x_struct.fields[slice_ptr_index]; 27765 if (parent_ptr->special == ConstValSpecialUndef) { 27766 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of undefined")); 27767 return ira->codegen->invalid_inst_gen; 27768 } 27769 27770 ZigValue *len_val = slice_ptr->data.x_struct.fields[slice_len_index]; 27771 27772 switch (parent_ptr->data.x_ptr.special) { 27773 case ConstPtrSpecialInvalid: 27774 case ConstPtrSpecialDiscard: 27775 zig_unreachable(); 27776 case ConstPtrSpecialRef: 27777 array_val = nullptr; 27778 abs_offset = SIZE_MAX; 27779 rel_end = 1; 27780 break; 27781 case ConstPtrSpecialSubArray: 27782 case ConstPtrSpecialBaseArray: 27783 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 27784 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 27785 rel_end = bigint_as_usize(&len_val->data.x_bigint); 27786 break; 27787 case ConstPtrSpecialBaseStruct: 27788 zig_panic("TODO slice const inner struct"); 27789 case ConstPtrSpecialBaseErrorUnionCode: 27790 zig_panic("TODO slice const inner error union code"); 27791 case ConstPtrSpecialBaseErrorUnionPayload: 27792 zig_panic("TODO slice const inner error union payload"); 27793 case ConstPtrSpecialBaseOptionalPayload: 27794 zig_panic("TODO slice const inner optional payload"); 27795 case ConstPtrSpecialHardCodedAddr: 27796 array_val = nullptr; 27797 abs_offset = 0; 27798 rel_end = bigint_as_usize(&len_val->data.x_bigint); 27799 break; 27800 case ConstPtrSpecialFunction: 27801 zig_panic("TODO slice of slice cast from function"); 27802 case ConstPtrSpecialNull: 27803 zig_panic("TODO slice of null"); 27804 } 27805 } else { 27806 zig_unreachable(); 27807 } 27808 27809 ZigValue *start_val = ir_resolve_const(ira, casted_start, UndefBad); 27810 if (!start_val) 27811 return ira->codegen->invalid_inst_gen; 27812 27813 uint64_t start_scalar = bigint_as_u64(&start_val->data.x_bigint); 27814 if (!ptr_is_undef && start_scalar > rel_end) { 27815 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds slice")); 27816 return ira->codegen->invalid_inst_gen; 27817 } 27818 27819 uint64_t end_scalar = rel_end; 27820 if (end) { 27821 ZigValue *end_val = ir_resolve_const(ira, end, UndefBad); 27822 if (!end_val) 27823 return ira->codegen->invalid_inst_gen; 27824 end_scalar = bigint_as_u64(&end_val->data.x_bigint); 27825 } 27826 if (!ptr_is_undef) { 27827 if (end_scalar > rel_end) { 27828 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds slice")); 27829 return ira->codegen->invalid_inst_gen; 27830 } 27831 if (start_scalar > end_scalar) { 27832 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice start is greater than end")); 27833 return ira->codegen->invalid_inst_gen; 27834 } 27835 } 27836 if (ptr_is_undef && start_scalar != end_scalar) { 27837 ir_add_error(ira, &instruction->base.base, buf_sprintf("non-zero length slice of undefined pointer")); 27838 return ira->codegen->invalid_inst_gen; 27839 } 27840 27841 // check sentinel when target is comptime-known 27842 { 27843 if (!sentinel_val) 27844 goto exit_check_sentinel; 27845 27846 switch (ptr_ptr->value->data.x_ptr.mut) { 27847 case ConstPtrMutComptimeConst: 27848 case ConstPtrMutComptimeVar: 27849 break; 27850 case ConstPtrMutRuntimeVar: 27851 case ConstPtrMutInfer: 27852 goto exit_check_sentinel; 27853 } 27854 27855 // prepare check parameters 27856 ZigValue *target = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 27857 if (target == nullptr) 27858 return ira->codegen->invalid_inst_gen; 27859 27860 uint64_t target_len = 0; 27861 ZigValue *target_sentinel = nullptr; 27862 ZigValue *target_elements = nullptr; 27863 27864 for (;;) { 27865 if (target->type->id == ZigTypeIdArray) { 27866 // handle `[N]T` 27867 target_len = target->type->data.array.len; 27868 target_sentinel = target->type->data.array.sentinel; 27869 target_elements = target->data.x_array.data.s_none.elements; 27870 break; 27871 } else if (target->type->id == ZigTypeIdPointer && target->type->data.pointer.child_type->id == ZigTypeIdArray) { 27872 // handle `*[N]T` 27873 target = const_ptr_pointee(ira, ira->codegen, target, instruction->base.base.source_node); 27874 if (target == nullptr) 27875 return ira->codegen->invalid_inst_gen; 27876 assert(target->type->id == ZigTypeIdArray); 27877 continue; 27878 } else if (target->type->id == ZigTypeIdPointer) { 27879 // handle `[*]T` 27880 // handle `[*c]T` 27881 switch (target->data.x_ptr.special) { 27882 case ConstPtrSpecialInvalid: 27883 case ConstPtrSpecialDiscard: 27884 zig_unreachable(); 27885 case ConstPtrSpecialRef: 27886 target = target->data.x_ptr.data.ref.pointee; 27887 assert(target->type->id == ZigTypeIdArray); 27888 continue; 27889 case ConstPtrSpecialBaseArray: 27890 case ConstPtrSpecialSubArray: 27891 target = target->data.x_ptr.data.base_array.array_val; 27892 assert(target->type->id == ZigTypeIdArray); 27893 continue; 27894 case ConstPtrSpecialBaseStruct: 27895 zig_panic("TODO slice const inner struct"); 27896 case ConstPtrSpecialBaseErrorUnionCode: 27897 zig_panic("TODO slice const inner error union code"); 27898 case ConstPtrSpecialBaseErrorUnionPayload: 27899 zig_panic("TODO slice const inner error union payload"); 27900 case ConstPtrSpecialBaseOptionalPayload: 27901 zig_panic("TODO slice const inner optional payload"); 27902 case ConstPtrSpecialHardCodedAddr: 27903 // skip check 27904 goto exit_check_sentinel; 27905 case ConstPtrSpecialFunction: 27906 zig_panic("TODO slice of ptr cast from function"); 27907 case ConstPtrSpecialNull: 27908 zig_panic("TODO slice of null ptr"); 27909 } 27910 break; 27911 } else if (is_slice(target->type)) { 27912 // handle `[]T` 27913 target = target->data.x_struct.fields[slice_ptr_index]; 27914 assert(target->type->id == ZigTypeIdPointer); 27915 continue; 27916 } 27917 27918 zig_unreachable(); 27919 } 27920 27921 // perform check 27922 if (target_sentinel == nullptr) { 27923 if (end_scalar >= target_len) { 27924 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel is out of bounds")); 27925 return ira->codegen->invalid_inst_gen; 27926 } 27927 if (!const_values_equal(ira->codegen, sentinel_val, &target_elements[end_scalar])) { 27928 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel does not match memory at target index")); 27929 return ira->codegen->invalid_inst_gen; 27930 } 27931 } else { 27932 assert(end_scalar <= target_len); 27933 if (end_scalar == target_len) { 27934 if (!const_values_equal(ira->codegen, sentinel_val, target_sentinel)) { 27935 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel does not match target-sentinel")); 27936 return ira->codegen->invalid_inst_gen; 27937 } 27938 } else { 27939 if (!const_values_equal(ira->codegen, sentinel_val, &target_elements[end_scalar])) { 27940 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel does not match memory at target index")); 27941 return ira->codegen->invalid_inst_gen; 27942 } 27943 } 27944 } 27945 } 27946 exit_check_sentinel: 27947 27948 IrInstGen *result = ir_const(ira, &instruction->base.base, return_type); 27949 27950 ZigValue *ptr_val; 27951 if (return_type->id == ZigTypeIdPointer) { 27952 // pointer to array 27953 ptr_val = result->value; 27954 } else { 27955 // slice 27956 result->value->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, 2); 27957 27958 ptr_val = result->value->data.x_struct.fields[slice_ptr_index]; 27959 27960 ZigValue *len_val = result->value->data.x_struct.fields[slice_len_index]; 27961 init_const_usize(ira->codegen, len_val, end_scalar - start_scalar); 27962 } 27963 27964 bool return_type_is_const = non_sentinel_slice_ptr_type->data.pointer.is_const; 27965 if (array_val) { 27966 size_t index = abs_offset + start_scalar; 27967 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, return_type_is_const, PtrLenUnknown); 27968 if (return_type->id == ZigTypeIdPointer) { 27969 ptr_val->data.x_ptr.special = ConstPtrSpecialSubArray; 27970 } 27971 if (array_type->id == ZigTypeIdArray) { 27972 ptr_val->data.x_ptr.mut = ptr_ptr->value->data.x_ptr.mut; 27973 } else if (is_slice(array_type)) { 27974 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 27975 } else if (array_type->id == ZigTypeIdPointer) { 27976 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 27977 } 27978 } else if (ptr_is_undef) { 27979 ptr_val->type = get_pointer_to_type(ira->codegen, parent_ptr->type->data.pointer.child_type, 27980 return_type_is_const); 27981 ptr_val->special = ConstValSpecialUndef; 27982 } else switch (parent_ptr->data.x_ptr.special) { 27983 case ConstPtrSpecialInvalid: 27984 case ConstPtrSpecialDiscard: 27985 zig_unreachable(); 27986 case ConstPtrSpecialRef: 27987 init_const_ptr_ref(ira->codegen, ptr_val, parent_ptr->data.x_ptr.data.ref.pointee, 27988 return_type_is_const); 27989 break; 27990 case ConstPtrSpecialSubArray: 27991 case ConstPtrSpecialBaseArray: 27992 zig_unreachable(); 27993 case ConstPtrSpecialBaseStruct: 27994 zig_panic("TODO"); 27995 case ConstPtrSpecialBaseErrorUnionCode: 27996 zig_panic("TODO"); 27997 case ConstPtrSpecialBaseErrorUnionPayload: 27998 zig_panic("TODO"); 27999 case ConstPtrSpecialBaseOptionalPayload: 28000 zig_panic("TODO"); 28001 case ConstPtrSpecialHardCodedAddr: 28002 init_const_ptr_hard_coded_addr(ira->codegen, ptr_val, 28003 parent_ptr->type->data.pointer.child_type, 28004 parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar, 28005 return_type_is_const); 28006 break; 28007 case ConstPtrSpecialFunction: 28008 zig_panic("TODO"); 28009 case ConstPtrSpecialNull: 28010 zig_panic("TODO"); 28011 } 28012 28013 // In the case of pointer-to-array, we must restore this because above it overwrites ptr_val->type 28014 result->value->type = return_type; 28015 return result; 28016 } 28017 28018 if (generate_non_null_assert) { 28019 IrInstGen *ptr_val = ir_get_deref(ira, &instruction->base.base, ptr_ptr, nullptr); 28020 28021 if (type_is_invalid(ptr_val->value->type)) 28022 return ira->codegen->invalid_inst_gen; 28023 28024 ir_build_assert_non_null(ira, &instruction->base.base, ptr_val); 28025 } 28026 28027 IrInstGen *result_loc = nullptr; 28028 28029 if (return_type->id != ZigTypeIdPointer) { 28030 result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 28031 return_type, nullptr, true, true); 28032 if (result_loc != nullptr) { 28033 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 28034 return result_loc; 28035 } 28036 28037 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); 28038 if (result_loc->value->type->data.pointer.is_const) { 28039 ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant")); 28040 return ira->codegen->invalid_inst_gen; 28041 } 28042 28043 IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type); 28044 dummy_value->value->special = ConstValSpecialRuntime; 28045 IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base, 28046 dummy_value, result_loc->value->type->data.pointer.child_type); 28047 if (type_is_invalid(dummy_result->value->type)) 28048 return ira->codegen->invalid_inst_gen; 28049 } 28050 } 28051 28052 return ir_build_slice_gen(ira, &instruction->base.base, return_type, ptr_ptr, 28053 casted_start, end, instruction->safety_check_on, result_loc, sentinel_val); 28054 } 28055 28056 static IrInstGen *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstSrcHasField *instruction) { 28057 Error err; 28058 ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); 28059 if (type_is_invalid(container_type)) 28060 return ira->codegen->invalid_inst_gen; 28061 28062 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusZeroBitsKnown))) 28063 return ira->codegen->invalid_inst_gen; 28064 28065 Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); 28066 if (field_name == nullptr) 28067 return ira->codegen->invalid_inst_gen; 28068 28069 bool result; 28070 if (container_type->id == ZigTypeIdStruct) { 28071 result = find_struct_type_field(container_type, field_name) != nullptr; 28072 } else if (container_type->id == ZigTypeIdEnum) { 28073 result = find_enum_type_field(container_type, field_name) != nullptr; 28074 } else if (container_type->id == ZigTypeIdUnion) { 28075 result = find_union_type_field(container_type, field_name) != nullptr; 28076 } else { 28077 ir_add_error(ira, &instruction->container_type->base, 28078 buf_sprintf("type '%s' does not support @hasField", buf_ptr(&container_type->name))); 28079 return ira->codegen->invalid_inst_gen; 28080 } 28081 return ir_const_bool(ira, &instruction->base.base, result); 28082 } 28083 28084 static IrInstGen *ir_analyze_instruction_wasm_memory_size(IrAnalyze *ira, IrInstSrcWasmMemorySize *instruction) { 28085 // TODO generate compile error for target_arch different than 32bit 28086 if (!target_is_wasm(ira->codegen->zig_target)) { 28087 ir_add_error_node(ira, instruction->base.base.source_node, 28088 buf_sprintf("@wasmMemorySize is a wasm32 feature only")); 28089 return ira->codegen->invalid_inst_gen; 28090 } 28091 28092 IrInstGen *index = instruction->index->child; 28093 if (type_is_invalid(index->value->type)) 28094 return ira->codegen->invalid_inst_gen; 28095 28096 ZigType *u32 = ira->codegen->builtin_types.entry_u32; 28097 28098 IrInstGen *casted_index = ir_implicit_cast(ira, index, u32); 28099 if (type_is_invalid(casted_index->value->type)) 28100 return ira->codegen->invalid_inst_gen; 28101 28102 return ir_build_wasm_memory_size_gen(ira, &instruction->base.base, casted_index); 28103 } 28104 28105 static IrInstGen *ir_analyze_instruction_wasm_memory_grow(IrAnalyze *ira, IrInstSrcWasmMemoryGrow *instruction) { 28106 // TODO generate compile error for target_arch different than 32bit 28107 if (!target_is_wasm(ira->codegen->zig_target)) { 28108 ir_add_error_node(ira, instruction->base.base.source_node, 28109 buf_sprintf("@wasmMemoryGrow is a wasm32 feature only")); 28110 return ira->codegen->invalid_inst_gen; 28111 } 28112 28113 IrInstGen *index = instruction->index->child; 28114 if (type_is_invalid(index->value->type)) 28115 return ira->codegen->invalid_inst_gen; 28116 28117 ZigType *u32 = ira->codegen->builtin_types.entry_u32; 28118 28119 IrInstGen *casted_index = ir_implicit_cast(ira, index, u32); 28120 if (type_is_invalid(casted_index->value->type)) 28121 return ira->codegen->invalid_inst_gen; 28122 28123 IrInstGen *delta = instruction->delta->child; 28124 if (type_is_invalid(delta->value->type)) 28125 return ira->codegen->invalid_inst_gen; 28126 28127 IrInstGen *casted_delta = ir_implicit_cast(ira, delta, u32); 28128 if (type_is_invalid(casted_delta->value->type)) 28129 return ira->codegen->invalid_inst_gen; 28130 28131 return ir_build_wasm_memory_grow_gen(ira, &instruction->base.base, casted_index, casted_delta); 28132 } 28133 28134 static IrInstGen *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstSrcBreakpoint *instruction) { 28135 return ir_build_breakpoint_gen(ira, &instruction->base.base); 28136 } 28137 28138 static IrInstGen *ir_analyze_instruction_return_address(IrAnalyze *ira, IrInstSrcReturnAddress *instruction) { 28139 return ir_build_return_address_gen(ira, &instruction->base.base); 28140 } 28141 28142 static IrInstGen *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstSrcFrameAddress *instruction) { 28143 return ir_build_frame_address_gen(ira, &instruction->base.base); 28144 } 28145 28146 static IrInstGen *ir_analyze_instruction_frame_handle(IrAnalyze *ira, IrInstSrcFrameHandle *instruction) { 28147 ZigFn *fn = ira->new_irb.exec->fn_entry; 28148 ir_assert(fn != nullptr, &instruction->base.base); 28149 28150 if (fn->inferred_async_node == nullptr) { 28151 fn->inferred_async_node = instruction->base.base.source_node; 28152 } 28153 28154 ZigType *frame_type = get_fn_frame_type(ira->codegen, fn); 28155 ZigType *ptr_frame_type = get_pointer_to_type(ira->codegen, frame_type, false); 28156 28157 return ir_build_handle_gen(ira, &instruction->base.base, ptr_frame_type); 28158 } 28159 28160 static IrInstGen *ir_analyze_instruction_frame_type(IrAnalyze *ira, IrInstSrcFrameType *instruction) { 28161 ZigFn *fn = ir_resolve_fn(ira, instruction->fn->child); 28162 if (fn == nullptr) 28163 return ira->codegen->invalid_inst_gen; 28164 28165 if (fn->type_entry->data.fn.is_generic) { 28166 ir_add_error(ira, &instruction->base.base, 28167 buf_sprintf("@Frame() of generic function")); 28168 return ira->codegen->invalid_inst_gen; 28169 } 28170 28171 ZigType *ty = get_fn_frame_type(ira->codegen, fn); 28172 return ir_const_type(ira, &instruction->base.base, ty); 28173 } 28174 28175 static IrInstGen *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstSrcFrameSize *instruction) { 28176 IrInstGen *fn = instruction->fn->child; 28177 if (type_is_invalid(fn->value->type)) 28178 return ira->codegen->invalid_inst_gen; 28179 28180 if (fn->value->type->id != ZigTypeIdFn) { 28181 ir_add_error(ira, &fn->base, 28182 buf_sprintf("expected function, found '%s'", buf_ptr(&fn->value->type->name))); 28183 return ira->codegen->invalid_inst_gen; 28184 } 28185 28186 ira->codegen->need_frame_size_prefix_data = true; 28187 28188 return ir_build_frame_size_gen(ira, &instruction->base.base, fn); 28189 } 28190 28191 static IrInstGen *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstSrcAlignOf *instruction) { 28192 // Here we create a lazy value in order to avoid resolving the alignment of the type 28193 // immediately. This avoids false positive dependency loops such as: 28194 // const Node = struct { 28195 // field: []align(@alignOf(Node)) Node, 28196 // }; 28197 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 28198 result->value->special = ConstValSpecialLazy; 28199 28200 LazyValueAlignOf *lazy_align_of = heap::c_allocator.create<LazyValueAlignOf>(); 28201 lazy_align_of->ira = ira; ira_ref(ira); 28202 result->value->data.x_lazy = &lazy_align_of->base; 28203 lazy_align_of->base.id = LazyValueIdAlignOf; 28204 28205 lazy_align_of->target_type = instruction->type_value->child; 28206 if (ir_resolve_type_lazy(ira, lazy_align_of->target_type) == nullptr) 28207 return ira->codegen->invalid_inst_gen; 28208 28209 return result; 28210 } 28211 28212 static IrInstGen *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstSrcOverflowOp *instruction) { 28213 Error err; 28214 28215 IrInstGen *type_value = instruction->type_value->child; 28216 if (type_is_invalid(type_value->value->type)) 28217 return ira->codegen->invalid_inst_gen; 28218 28219 ZigType *dest_type = ir_resolve_type(ira, type_value); 28220 if (type_is_invalid(dest_type)) 28221 return ira->codegen->invalid_inst_gen; 28222 28223 if (dest_type->id != ZigTypeIdInt) { 28224 ir_add_error(ira, &type_value->base, 28225 buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 28226 return ira->codegen->invalid_inst_gen; 28227 } 28228 28229 IrInstGen *op1 = instruction->op1->child; 28230 if (type_is_invalid(op1->value->type)) 28231 return ira->codegen->invalid_inst_gen; 28232 28233 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 28234 if (type_is_invalid(casted_op1->value->type)) 28235 return ira->codegen->invalid_inst_gen; 28236 28237 IrInstGen *op2 = instruction->op2->child; 28238 if (type_is_invalid(op2->value->type)) 28239 return ira->codegen->invalid_inst_gen; 28240 28241 IrInstGen *casted_op2; 28242 if (instruction->op == IrOverflowOpShl) { 28243 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 28244 dest_type->data.integral.bit_count - 1); 28245 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 28246 } else { 28247 casted_op2 = ir_implicit_cast(ira, op2, dest_type); 28248 } 28249 if (type_is_invalid(casted_op2->value->type)) 28250 return ira->codegen->invalid_inst_gen; 28251 28252 IrInstGen *result_ptr = instruction->result_ptr->child; 28253 if (type_is_invalid(result_ptr->value->type)) 28254 return ira->codegen->invalid_inst_gen; 28255 28256 ZigType *expected_ptr_type; 28257 if (result_ptr->value->type->id == ZigTypeIdPointer) { 28258 uint32_t alignment; 28259 if ((err = resolve_ptr_align(ira, result_ptr->value->type, &alignment))) 28260 return ira->codegen->invalid_inst_gen; 28261 expected_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_type, 28262 false, result_ptr->value->type->data.pointer.is_volatile, 28263 PtrLenSingle, 28264 alignment, 0, 0, false); 28265 } else { 28266 expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false); 28267 } 28268 28269 IrInstGen *casted_result_ptr = ir_implicit_cast(ira, result_ptr, expected_ptr_type); 28270 if (type_is_invalid(casted_result_ptr->value->type)) 28271 return ira->codegen->invalid_inst_gen; 28272 28273 if (instr_is_comptime(casted_op1) && 28274 instr_is_comptime(casted_op2) && 28275 instr_is_comptime(casted_result_ptr)) 28276 { 28277 ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 28278 if (op1_val == nullptr) 28279 return ira->codegen->invalid_inst_gen; 28280 28281 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 28282 if (op2_val == nullptr) 28283 return ira->codegen->invalid_inst_gen; 28284 28285 ZigValue *result_val = ir_resolve_const(ira, casted_result_ptr, UndefBad); 28286 if (result_val == nullptr) 28287 return ira->codegen->invalid_inst_gen; 28288 28289 BigInt *op1_bigint = &op1_val->data.x_bigint; 28290 BigInt *op2_bigint = &op2_val->data.x_bigint; 28291 ZigValue *pointee_val = const_ptr_pointee(ira, ira->codegen, result_val, 28292 casted_result_ptr->base.source_node); 28293 if (pointee_val == nullptr) 28294 return ira->codegen->invalid_inst_gen; 28295 BigInt *dest_bigint = &pointee_val->data.x_bigint; 28296 switch (instruction->op) { 28297 case IrOverflowOpAdd: 28298 bigint_add(dest_bigint, op1_bigint, op2_bigint); 28299 break; 28300 case IrOverflowOpSub: 28301 bigint_sub(dest_bigint, op1_bigint, op2_bigint); 28302 break; 28303 case IrOverflowOpMul: 28304 bigint_mul(dest_bigint, op1_bigint, op2_bigint); 28305 break; 28306 case IrOverflowOpShl: 28307 bigint_shl(dest_bigint, op1_bigint, op2_bigint); 28308 break; 28309 } 28310 bool result_bool = false; 28311 if (!bigint_fits_in_bits(dest_bigint, dest_type->data.integral.bit_count, 28312 dest_type->data.integral.is_signed)) 28313 { 28314 result_bool = true; 28315 BigInt tmp_bigint; 28316 bigint_init_bigint(&tmp_bigint, dest_bigint); 28317 bigint_truncate(dest_bigint, &tmp_bigint, dest_type->data.integral.bit_count, 28318 dest_type->data.integral.is_signed); 28319 } 28320 pointee_val->special = ConstValSpecialStatic; 28321 return ir_const_bool(ira, &instruction->base.base, result_bool); 28322 } 28323 28324 return ir_build_overflow_op_gen(ira, &instruction->base.base, instruction->op, 28325 casted_op1, casted_op2, casted_result_ptr, dest_type); 28326 } 28327 28328 static void ir_eval_mul_add(IrAnalyze *ira, IrInstSrcMulAdd *source_instr, ZigType *float_type, 28329 ZigValue *op1, ZigValue *op2, ZigValue *op3, ZigValue *out_val) { 28330 if (float_type->id == ZigTypeIdComptimeFloat) { 28331 f128M_mulAdd(&out_val->data.x_bigfloat.value, &op1->data.x_bigfloat.value, &op2->data.x_bigfloat.value, 28332 &op3->data.x_bigfloat.value); 28333 } else if (float_type->id == ZigTypeIdFloat) { 28334 switch (float_type->data.floating.bit_count) { 28335 case 16: 28336 out_val->data.x_f16 = f16_mulAdd(op1->data.x_f16, op2->data.x_f16, op3->data.x_f16); 28337 break; 28338 case 32: 28339 out_val->data.x_f32 = fmaf(op1->data.x_f32, op2->data.x_f32, op3->data.x_f32); 28340 break; 28341 case 64: 28342 out_val->data.x_f64 = fma(op1->data.x_f64, op2->data.x_f64, op3->data.x_f64); 28343 break; 28344 case 128: 28345 f128M_mulAdd(&op1->data.x_f128, &op2->data.x_f128, &op3->data.x_f128, &out_val->data.x_f128); 28346 break; 28347 default: 28348 zig_unreachable(); 28349 } 28350 } else { 28351 zig_unreachable(); 28352 } 28353 } 28354 28355 static IrInstGen *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstSrcMulAdd *instruction) { 28356 IrInstGen *type_value = instruction->type_value->child; 28357 if (type_is_invalid(type_value->value->type)) 28358 return ira->codegen->invalid_inst_gen; 28359 28360 ZigType *expr_type = ir_resolve_type(ira, type_value); 28361 if (type_is_invalid(expr_type)) 28362 return ira->codegen->invalid_inst_gen; 28363 28364 // Only allow float types, and vectors of floats. 28365 ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; 28366 if (float_type->id != ZigTypeIdFloat) { 28367 ir_add_error(ira, &type_value->base, 28368 buf_sprintf("expected float or vector of float type, found '%s'", buf_ptr(&float_type->name))); 28369 return ira->codegen->invalid_inst_gen; 28370 } 28371 28372 IrInstGen *op1 = instruction->op1->child; 28373 if (type_is_invalid(op1->value->type)) 28374 return ira->codegen->invalid_inst_gen; 28375 28376 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, expr_type); 28377 if (type_is_invalid(casted_op1->value->type)) 28378 return ira->codegen->invalid_inst_gen; 28379 28380 IrInstGen *op2 = instruction->op2->child; 28381 if (type_is_invalid(op2->value->type)) 28382 return ira->codegen->invalid_inst_gen; 28383 28384 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, expr_type); 28385 if (type_is_invalid(casted_op2->value->type)) 28386 return ira->codegen->invalid_inst_gen; 28387 28388 IrInstGen *op3 = instruction->op3->child; 28389 if (type_is_invalid(op3->value->type)) 28390 return ira->codegen->invalid_inst_gen; 28391 28392 IrInstGen *casted_op3 = ir_implicit_cast(ira, op3, expr_type); 28393 if (type_is_invalid(casted_op3->value->type)) 28394 return ira->codegen->invalid_inst_gen; 28395 28396 if (instr_is_comptime(casted_op1) && 28397 instr_is_comptime(casted_op2) && 28398 instr_is_comptime(casted_op3)) { 28399 ZigValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad); 28400 if (!op1_const) 28401 return ira->codegen->invalid_inst_gen; 28402 ZigValue *op2_const = ir_resolve_const(ira, casted_op2, UndefBad); 28403 if (!op2_const) 28404 return ira->codegen->invalid_inst_gen; 28405 ZigValue *op3_const = ir_resolve_const(ira, casted_op3, UndefBad); 28406 if (!op3_const) 28407 return ira->codegen->invalid_inst_gen; 28408 28409 IrInstGen *result = ir_const(ira, &instruction->base.base, expr_type); 28410 ZigValue *out_val = result->value; 28411 28412 if (expr_type->id == ZigTypeIdVector) { 28413 expand_undef_array(ira->codegen, op1_const); 28414 expand_undef_array(ira->codegen, op2_const); 28415 expand_undef_array(ira->codegen, op3_const); 28416 out_val->special = ConstValSpecialUndef; 28417 expand_undef_array(ira->codegen, out_val); 28418 size_t len = expr_type->data.vector.len; 28419 for (size_t i = 0; i < len; i += 1) { 28420 ZigValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i]; 28421 ZigValue *float_operand_op2 = &op2_const->data.x_array.data.s_none.elements[i]; 28422 ZigValue *float_operand_op3 = &op3_const->data.x_array.data.s_none.elements[i]; 28423 ZigValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; 28424 assert(float_operand_op1->type == float_type); 28425 assert(float_operand_op2->type == float_type); 28426 assert(float_operand_op3->type == float_type); 28427 assert(float_out_val->type == float_type); 28428 ir_eval_mul_add(ira, instruction, float_type, 28429 op1_const, op2_const, op3_const, float_out_val); 28430 float_out_val->type = float_type; 28431 } 28432 out_val->type = expr_type; 28433 out_val->special = ConstValSpecialStatic; 28434 } else { 28435 ir_eval_mul_add(ira, instruction, float_type, op1_const, op2_const, op3_const, out_val); 28436 } 28437 return result; 28438 } 28439 28440 return ir_build_mul_add_gen(ira, &instruction->base.base, casted_op1, casted_op2, casted_op3, expr_type); 28441 } 28442 28443 static IrInstGen *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstSrcTestErr *instruction) { 28444 IrInstGen *base_ptr = instruction->base_ptr->child; 28445 if (type_is_invalid(base_ptr->value->type)) 28446 return ira->codegen->invalid_inst_gen; 28447 28448 IrInstGen *value; 28449 if (instruction->base_ptr_is_payload) { 28450 value = base_ptr; 28451 } else { 28452 value = ir_get_deref(ira, &instruction->base.base, base_ptr, nullptr); 28453 } 28454 28455 ZigType *type_entry = value->value->type; 28456 if (type_is_invalid(type_entry)) 28457 return ira->codegen->invalid_inst_gen; 28458 if (type_entry->id == ZigTypeIdErrorUnion) { 28459 if (instr_is_comptime(value)) { 28460 ZigValue *err_union_val = ir_resolve_const(ira, value, UndefBad); 28461 if (!err_union_val) 28462 return ira->codegen->invalid_inst_gen; 28463 28464 if (err_union_val->special != ConstValSpecialRuntime) { 28465 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; 28466 return ir_const_bool(ira, &instruction->base.base, (err != nullptr)); 28467 } 28468 } 28469 28470 if (instruction->resolve_err_set) { 28471 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 28472 if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.base.source_node)) { 28473 return ira->codegen->invalid_inst_gen; 28474 } 28475 if (!type_is_global_error_set(err_set_type) && 28476 err_set_type->data.error_set.err_count == 0) 28477 { 28478 assert(!err_set_type->data.error_set.incomplete); 28479 return ir_const_bool(ira, &instruction->base.base, false); 28480 } 28481 } 28482 28483 return ir_build_test_err_gen(ira, &instruction->base.base, value); 28484 } else if (type_entry->id == ZigTypeIdErrorSet) { 28485 return ir_const_bool(ira, &instruction->base.base, true); 28486 } else { 28487 return ir_const_bool(ira, &instruction->base.base, false); 28488 } 28489 } 28490 28491 static IrInstGen *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInst* source_instr, 28492 IrInstGen *base_ptr, bool initializing) 28493 { 28494 ZigType *ptr_type = base_ptr->value->type; 28495 28496 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 28497 assert(ptr_type->id == ZigTypeIdPointer); 28498 28499 ZigType *type_entry = ptr_type->data.pointer.child_type; 28500 if (type_is_invalid(type_entry)) 28501 return ira->codegen->invalid_inst_gen; 28502 28503 if (type_entry->id != ZigTypeIdErrorUnion) { 28504 ir_add_error(ira, &base_ptr->base, 28505 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 28506 return ira->codegen->invalid_inst_gen; 28507 } 28508 28509 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 28510 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, err_set_type, 28511 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 28512 ptr_type->data.pointer.explicit_alignment, 0, 0, false); 28513 28514 if (instr_is_comptime(base_ptr)) { 28515 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 28516 if (!ptr_val) 28517 return ira->codegen->invalid_inst_gen; 28518 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && 28519 ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) 28520 { 28521 ZigValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 28522 if (err_union_val == nullptr) 28523 return ira->codegen->invalid_inst_gen; 28524 28525 if (initializing && err_union_val->special == ConstValSpecialUndef) { 28526 ZigValue *vals = ira->codegen->pass1_arena->allocate<ZigValue>(2); 28527 ZigValue *err_set_val = &vals[0]; 28528 ZigValue *payload_val = &vals[1]; 28529 28530 err_set_val->special = ConstValSpecialUndef; 28531 err_set_val->type = err_set_type; 28532 err_set_val->parent.id = ConstParentIdErrUnionCode; 28533 err_set_val->parent.data.p_err_union_code.err_union_val = err_union_val; 28534 28535 payload_val->special = ConstValSpecialUndef; 28536 payload_val->type = type_entry->data.error_union.payload_type; 28537 payload_val->parent.id = ConstParentIdErrUnionPayload; 28538 payload_val->parent.data.p_err_union_payload.err_union_val = err_union_val; 28539 28540 err_union_val->special = ConstValSpecialStatic; 28541 err_union_val->data.x_err_union.error_set = err_set_val; 28542 err_union_val->data.x_err_union.payload = payload_val; 28543 } 28544 ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr); 28545 28546 IrInstGen *result; 28547 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 28548 result = ir_build_unwrap_err_code_gen(ira, source_instr->scope, 28549 source_instr->source_node, base_ptr, result_type); 28550 result->value->special = ConstValSpecialStatic; 28551 } else { 28552 result = ir_const(ira, source_instr, result_type); 28553 } 28554 ZigValue *const_val = result->value; 28555 const_val->data.x_ptr.special = ConstPtrSpecialBaseErrorUnionCode; 28556 const_val->data.x_ptr.data.base_err_union_code.err_union_val = err_union_val; 28557 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 28558 return result; 28559 } 28560 } 28561 28562 return ir_build_unwrap_err_code_gen(ira, source_instr->scope, source_instr->source_node, base_ptr, result_type); 28563 } 28564 28565 static IrInstGen *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrInstSrcUnwrapErrCode *instruction) { 28566 IrInstGen *base_ptr = instruction->err_union_ptr->child; 28567 if (type_is_invalid(base_ptr->value->type)) 28568 return ira->codegen->invalid_inst_gen; 28569 return ir_analyze_unwrap_err_code(ira, &instruction->base.base, base_ptr, false); 28570 } 28571 28572 static IrInstGen *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInst* source_instr, 28573 IrInstGen *base_ptr, bool safety_check_on, bool initializing) 28574 { 28575 ZigType *ptr_type = base_ptr->value->type; 28576 28577 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 28578 assert(ptr_type->id == ZigTypeIdPointer); 28579 28580 ZigType *type_entry = ptr_type->data.pointer.child_type; 28581 if (type_is_invalid(type_entry)) 28582 return ira->codegen->invalid_inst_gen; 28583 28584 if (type_entry->id != ZigTypeIdErrorUnion) { 28585 ir_add_error(ira, &base_ptr->base, 28586 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 28587 return ira->codegen->invalid_inst_gen; 28588 } 28589 28590 ZigType *payload_type = type_entry->data.error_union.payload_type; 28591 if (type_is_invalid(payload_type)) 28592 return ira->codegen->invalid_inst_gen; 28593 28594 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, 28595 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 28596 PtrLenSingle, 0, 0, 0, false); 28597 28598 if (instr_is_comptime(base_ptr)) { 28599 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 28600 if (!ptr_val) 28601 return ira->codegen->invalid_inst_gen; 28602 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 28603 ZigValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 28604 if (err_union_val == nullptr) 28605 return ira->codegen->invalid_inst_gen; 28606 if (initializing && err_union_val->special == ConstValSpecialUndef) { 28607 ZigValue *vals = ira->codegen->pass1_arena->allocate<ZigValue>(2); 28608 ZigValue *err_set_val = &vals[0]; 28609 ZigValue *payload_val = &vals[1]; 28610 28611 err_set_val->special = ConstValSpecialStatic; 28612 err_set_val->type = type_entry->data.error_union.err_set_type; 28613 err_set_val->data.x_err_set = nullptr; 28614 28615 payload_val->special = ConstValSpecialUndef; 28616 payload_val->type = payload_type; 28617 28618 err_union_val->special = ConstValSpecialStatic; 28619 err_union_val->data.x_err_union.error_set = err_set_val; 28620 err_union_val->data.x_err_union.payload = payload_val; 28621 } 28622 28623 if (err_union_val->special != ConstValSpecialRuntime) { 28624 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; 28625 if (err != nullptr) { 28626 ir_add_error(ira, source_instr, 28627 buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); 28628 return ira->codegen->invalid_inst_gen; 28629 } 28630 28631 IrInstGen *result; 28632 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 28633 result = ir_build_unwrap_err_payload_gen(ira, source_instr->scope, 28634 source_instr->source_node, base_ptr, safety_check_on, initializing, result_type); 28635 result->value->special = ConstValSpecialStatic; 28636 } else { 28637 result = ir_const(ira, source_instr, result_type); 28638 } 28639 result->value->data.x_ptr.special = ConstPtrSpecialRef; 28640 result->value->data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; 28641 result->value->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 28642 return result; 28643 } 28644 } 28645 } 28646 28647 return ir_build_unwrap_err_payload_gen(ira, source_instr->scope, source_instr->source_node, 28648 base_ptr, safety_check_on, initializing, result_type); 28649 } 28650 28651 static IrInstGen *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, 28652 IrInstSrcUnwrapErrPayload *instruction) 28653 { 28654 assert(instruction->value->child); 28655 IrInstGen *value = instruction->value->child; 28656 if (type_is_invalid(value->value->type)) 28657 return ira->codegen->invalid_inst_gen; 28658 28659 return ir_analyze_unwrap_error_payload(ira, &instruction->base.base, value, instruction->safety_check_on, false); 28660 } 28661 28662 static IrInstGen *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstSrcFnProto *instruction) { 28663 AstNode *proto_node = instruction->base.base.source_node; 28664 assert(proto_node->type == NodeTypeFnProto); 28665 28666 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); 28667 result->value->special = ConstValSpecialLazy; 28668 28669 LazyValueFnType *lazy_fn_type = heap::c_allocator.create<LazyValueFnType>(); 28670 lazy_fn_type->ira = ira; ira_ref(ira); 28671 result->value->data.x_lazy = &lazy_fn_type->base; 28672 lazy_fn_type->base.id = LazyValueIdFnType; 28673 28674 if (proto_node->data.fn_proto.auto_err_set) { 28675 ir_add_error(ira, &instruction->base.base, 28676 buf_sprintf("inferring error set of return type valid only for function definitions")); 28677 return ira->codegen->invalid_inst_gen; 28678 } 28679 28680 lazy_fn_type->cc = cc_from_fn_proto(&proto_node->data.fn_proto); 28681 if (instruction->callconv_value != nullptr) { 28682 ZigType *cc_enum_type = get_builtin_type(ira->codegen, "CallingConvention"); 28683 28684 IrInstGen *casted_value = ir_implicit_cast(ira, instruction->callconv_value->child, cc_enum_type); 28685 if (type_is_invalid(casted_value->value->type)) 28686 return ira->codegen->invalid_inst_gen; 28687 28688 ZigValue *const_value = ir_resolve_const(ira, casted_value, UndefBad); 28689 if (const_value == nullptr) 28690 return ira->codegen->invalid_inst_gen; 28691 28692 lazy_fn_type->cc = (CallingConvention)bigint_as_u32(&const_value->data.x_enum_tag); 28693 } 28694 28695 size_t param_count = proto_node->data.fn_proto.params.length; 28696 lazy_fn_type->proto_node = proto_node; 28697 lazy_fn_type->param_types = heap::c_allocator.allocate<IrInstGen *>(param_count); 28698 28699 for (size_t param_index = 0; param_index < param_count; param_index += 1) { 28700 AstNode *param_node = proto_node->data.fn_proto.params.at(param_index); 28701 assert(param_node->type == NodeTypeParamDecl); 28702 28703 bool param_is_var_args = param_node->data.param_decl.is_var_args; 28704 if (param_is_var_args) { 28705 const CallingConvention cc = lazy_fn_type->cc; 28706 28707 if (cc == CallingConventionC) { 28708 break; 28709 } else { 28710 ir_add_error(ira, &instruction->base.base, 28711 buf_sprintf("var args only allowed in functions with C calling convention")); 28712 return ira->codegen->invalid_inst_gen; 28713 } 28714 } 28715 28716 if (instruction->param_types[param_index] == nullptr) { 28717 lazy_fn_type->is_generic = true; 28718 return result; 28719 } 28720 28721 IrInstGen *param_type_value = instruction->param_types[param_index]->child; 28722 if (type_is_invalid(param_type_value->value->type)) 28723 return ira->codegen->invalid_inst_gen; 28724 if (ir_resolve_const(ira, param_type_value, LazyOk) == nullptr) 28725 return ira->codegen->invalid_inst_gen; 28726 lazy_fn_type->param_types[param_index] = param_type_value; 28727 } 28728 28729 if (instruction->align_value != nullptr) { 28730 lazy_fn_type->align_inst = instruction->align_value->child; 28731 if (ir_resolve_const(ira, lazy_fn_type->align_inst, LazyOk) == nullptr) 28732 return ira->codegen->invalid_inst_gen; 28733 } 28734 28735 lazy_fn_type->return_type = instruction->return_type->child; 28736 if (ir_resolve_const(ira, lazy_fn_type->return_type, LazyOk) == nullptr) 28737 return ira->codegen->invalid_inst_gen; 28738 28739 return result; 28740 } 28741 28742 static IrInstGen *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstSrcTestComptime *instruction) { 28743 IrInstGen *value = instruction->value->child; 28744 if (type_is_invalid(value->value->type)) 28745 return ira->codegen->invalid_inst_gen; 28746 28747 return ir_const_bool(ira, &instruction->base.base, instr_is_comptime(value)); 28748 } 28749 28750 static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, 28751 IrInstSrcCheckSwitchProngs *instruction) 28752 { 28753 IrInstGen *target_value = instruction->target_value->child; 28754 ZigType *switch_type = target_value->value->type; 28755 if (type_is_invalid(switch_type)) 28756 return ira->codegen->invalid_inst_gen; 28757 28758 if (switch_type->id == ZigTypeIdEnum) { 28759 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> field_prev_uses = {}; 28760 field_prev_uses.init(switch_type->data.enumeration.src_field_count); 28761 28762 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 28763 IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 28764 28765 IrInstGen *start_value_uncasted = range->start->child; 28766 if (type_is_invalid(start_value_uncasted->value->type)) 28767 return ira->codegen->invalid_inst_gen; 28768 IrInstGen *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); 28769 if (type_is_invalid(start_value->value->type)) 28770 return ira->codegen->invalid_inst_gen; 28771 28772 IrInstGen *end_value_uncasted = range->end->child; 28773 if (type_is_invalid(end_value_uncasted->value->type)) 28774 return ira->codegen->invalid_inst_gen; 28775 IrInstGen *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); 28776 if (type_is_invalid(end_value->value->type)) 28777 return ira->codegen->invalid_inst_gen; 28778 28779 assert(start_value->value->type->id == ZigTypeIdEnum); 28780 BigInt start_index; 28781 bigint_init_bigint(&start_index, &start_value->value->data.x_enum_tag); 28782 28783 assert(end_value->value->type->id == ZigTypeIdEnum); 28784 BigInt end_index; 28785 bigint_init_bigint(&end_index, &end_value->value->data.x_enum_tag); 28786 28787 if (bigint_cmp(&start_index, &end_index) == CmpGT) { 28788 ir_add_error(ira, &start_value->base, 28789 buf_sprintf("range start value is greater than the end value")); 28790 } 28791 28792 BigInt field_index; 28793 bigint_init_bigint(&field_index, &start_index); 28794 for (;;) { 28795 Cmp cmp = bigint_cmp(&field_index, &end_index); 28796 if (cmp == CmpGT) { 28797 break; 28798 } 28799 auto entry = field_prev_uses.put_unique(field_index, start_value->base.source_node); 28800 if (entry) { 28801 AstNode *prev_node = entry->value; 28802 TypeEnumField *enum_field = find_enum_field_by_tag(switch_type, &field_index); 28803 assert(enum_field != nullptr); 28804 ErrorMsg *msg = ir_add_error(ira, &start_value->base, 28805 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), 28806 buf_ptr(enum_field->name))); 28807 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 28808 } 28809 bigint_incr(&field_index); 28810 } 28811 } 28812 if (instruction->have_underscore_prong) { 28813 if (!switch_type->data.enumeration.non_exhaustive){ 28814 ir_add_error(ira, &instruction->base.base, 28815 buf_sprintf("switch on non-exhaustive enum has `_` prong")); 28816 } 28817 for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { 28818 TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i]; 28819 if (buf_eql_str(enum_field->name, "_")) 28820 continue; 28821 28822 auto entry = field_prev_uses.maybe_get(enum_field->value); 28823 if (!entry) { 28824 ir_add_error(ira, &instruction->base.base, 28825 buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name), 28826 buf_ptr(enum_field->name))); 28827 } 28828 } 28829 } else if (!instruction->have_else_prong) { 28830 if (switch_type->data.enumeration.non_exhaustive) { 28831 ir_add_error(ira, &instruction->base.base, 28832 buf_sprintf("switch on non-exhaustive enum must include `else` or `_` prong")); 28833 } 28834 for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { 28835 TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i]; 28836 28837 auto entry = field_prev_uses.maybe_get(enum_field->value); 28838 if (!entry) { 28839 ir_add_error(ira, &instruction->base.base, 28840 buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name), 28841 buf_ptr(enum_field->name))); 28842 } 28843 } 28844 } 28845 } else if (switch_type->id == ZigTypeIdErrorSet) { 28846 if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->base.source_node)) { 28847 return ira->codegen->invalid_inst_gen; 28848 } 28849 28850 size_t field_prev_uses_count = ira->codegen->errors_by_index.length; 28851 AstNode **field_prev_uses = heap::c_allocator.allocate<AstNode *>(field_prev_uses_count); 28852 28853 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 28854 IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 28855 28856 IrInstGen *start_value_uncasted = range->start->child; 28857 if (type_is_invalid(start_value_uncasted->value->type)) 28858 return ira->codegen->invalid_inst_gen; 28859 IrInstGen *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); 28860 if (type_is_invalid(start_value->value->type)) 28861 return ira->codegen->invalid_inst_gen; 28862 28863 IrInstGen *end_value_uncasted = range->end->child; 28864 if (type_is_invalid(end_value_uncasted->value->type)) 28865 return ira->codegen->invalid_inst_gen; 28866 IrInstGen *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); 28867 if (type_is_invalid(end_value->value->type)) 28868 return ira->codegen->invalid_inst_gen; 28869 28870 ir_assert(start_value->value->type->id == ZigTypeIdErrorSet, &instruction->base.base); 28871 uint32_t start_index = start_value->value->data.x_err_set->value; 28872 28873 ir_assert(end_value->value->type->id == ZigTypeIdErrorSet, &instruction->base.base); 28874 uint32_t end_index = end_value->value->data.x_err_set->value; 28875 28876 if (start_index != end_index) { 28877 ir_add_error(ira, &end_value->base, buf_sprintf("ranges not allowed when switching on errors")); 28878 return ira->codegen->invalid_inst_gen; 28879 } 28880 28881 AstNode *prev_node = field_prev_uses[start_index]; 28882 if (prev_node != nullptr) { 28883 Buf *err_name = &ira->codegen->errors_by_index.at(start_index)->name; 28884 ErrorMsg *msg = ir_add_error(ira, &start_value->base, 28885 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), buf_ptr(err_name))); 28886 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 28887 } 28888 field_prev_uses[start_index] = start_value->base.source_node; 28889 } 28890 if (!instruction->have_else_prong) { 28891 if (type_is_global_error_set(switch_type)) { 28892 ir_add_error(ira, &instruction->base.base, 28893 buf_sprintf("else prong required when switching on type 'anyerror'")); 28894 return ira->codegen->invalid_inst_gen; 28895 } else { 28896 for (uint32_t i = 0; i < switch_type->data.error_set.err_count; i += 1) { 28897 ErrorTableEntry *err_entry = switch_type->data.error_set.errors[i]; 28898 28899 AstNode *prev_node = field_prev_uses[err_entry->value]; 28900 if (prev_node == nullptr) { 28901 ir_add_error(ira, &instruction->base.base, 28902 buf_sprintf("error.%s not handled in switch", buf_ptr(&err_entry->name))); 28903 } 28904 } 28905 } 28906 } 28907 28908 heap::c_allocator.deallocate(field_prev_uses, field_prev_uses_count); 28909 } else if (switch_type->id == ZigTypeIdInt) { 28910 RangeSet rs = {0}; 28911 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 28912 IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 28913 28914 IrInstGen *start_value = range->start->child; 28915 if (type_is_invalid(start_value->value->type)) 28916 return ira->codegen->invalid_inst_gen; 28917 IrInstGen *casted_start_value = ir_implicit_cast(ira, start_value, switch_type); 28918 if (type_is_invalid(casted_start_value->value->type)) 28919 return ira->codegen->invalid_inst_gen; 28920 28921 IrInstGen *end_value = range->end->child; 28922 if (type_is_invalid(end_value->value->type)) 28923 return ira->codegen->invalid_inst_gen; 28924 IrInstGen *casted_end_value = ir_implicit_cast(ira, end_value, switch_type); 28925 if (type_is_invalid(casted_end_value->value->type)) 28926 return ira->codegen->invalid_inst_gen; 28927 28928 ZigValue *start_val = ir_resolve_const(ira, casted_start_value, UndefBad); 28929 if (!start_val) 28930 return ira->codegen->invalid_inst_gen; 28931 28932 ZigValue *end_val = ir_resolve_const(ira, casted_end_value, UndefBad); 28933 if (!end_val) 28934 return ira->codegen->invalid_inst_gen; 28935 28936 assert(start_val->type->id == ZigTypeIdInt || start_val->type->id == ZigTypeIdComptimeInt); 28937 assert(end_val->type->id == ZigTypeIdInt || end_val->type->id == ZigTypeIdComptimeInt); 28938 28939 if (bigint_cmp(&start_val->data.x_bigint, &end_val->data.x_bigint) == CmpGT) { 28940 ir_add_error(ira, &start_value->base, 28941 buf_sprintf("range start value is greater than the end value")); 28942 } 28943 28944 AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint, 28945 start_value->base.source_node); 28946 if (prev_node != nullptr) { 28947 ErrorMsg *msg = ir_add_error(ira, &start_value->base, buf_sprintf("duplicate switch value")); 28948 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("previous value is here")); 28949 return ira->codegen->invalid_inst_gen; 28950 } 28951 } 28952 if (!instruction->have_else_prong) { 28953 BigInt min_val; 28954 eval_min_max_value_int(ira->codegen, switch_type, &min_val, false); 28955 BigInt max_val; 28956 eval_min_max_value_int(ira->codegen, switch_type, &max_val, true); 28957 if (!rangeset_spans(&rs, &min_val, &max_val)) { 28958 ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities")); 28959 return ira->codegen->invalid_inst_gen; 28960 } 28961 } 28962 } else if (switch_type->id == ZigTypeIdBool) { 28963 int seenTrue = 0; 28964 int seenFalse = 0; 28965 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 28966 IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 28967 28968 IrInstGen *value = range->start->child; 28969 28970 IrInstGen *casted_value = ir_implicit_cast(ira, value, switch_type); 28971 if (type_is_invalid(casted_value->value->type)) 28972 return ira->codegen->invalid_inst_gen; 28973 28974 ZigValue *const_expr_val = ir_resolve_const(ira, casted_value, UndefBad); 28975 if (!const_expr_val) 28976 return ira->codegen->invalid_inst_gen; 28977 28978 assert(const_expr_val->type->id == ZigTypeIdBool); 28979 28980 if (const_expr_val->data.x_bool == true) { 28981 seenTrue += 1; 28982 } else { 28983 seenFalse += 1; 28984 } 28985 28986 if ((seenTrue > 1) || (seenFalse > 1)) { 28987 ir_add_error(ira, &value->base, buf_sprintf("duplicate switch value")); 28988 return ira->codegen->invalid_inst_gen; 28989 } 28990 } 28991 if (((seenTrue < 1) || (seenFalse < 1)) && !instruction->have_else_prong) { 28992 ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities")); 28993 return ira->codegen->invalid_inst_gen; 28994 } 28995 } else if (!instruction->have_else_prong) { 28996 ir_add_error(ira, &instruction->base.base, 28997 buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name))); 28998 return ira->codegen->invalid_inst_gen; 28999 } else if(switch_type->id == ZigTypeIdMetaType) { 29000 HashMap<const ZigType*, IrInstGen*, type_ptr_hash, type_ptr_eql> prevs; 29001 // HashMap doubles capacity when reaching 60% capacity, 29002 // because we know the size at init we can avoid reallocation by doubling it here 29003 prevs.init(instruction->range_count * 2); 29004 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 29005 IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 29006 29007 IrInstGen *value = range->start->child; 29008 IrInstGen *casted_value = ir_implicit_cast(ira, value, switch_type); 29009 if (type_is_invalid(casted_value->value->type)) { 29010 prevs.deinit(); 29011 return ira->codegen->invalid_inst_gen; 29012 } 29013 29014 ZigValue *const_expr_val = ir_resolve_const(ira, casted_value, UndefBad); 29015 if (!const_expr_val) { 29016 prevs.deinit(); 29017 return ira->codegen->invalid_inst_gen; 29018 } 29019 29020 auto entry = prevs.put_unique(const_expr_val->data.x_type, value); 29021 if(entry != nullptr) { 29022 ErrorMsg *msg = ir_add_error(ira, &value->base, buf_sprintf("duplicate switch value")); 29023 add_error_note(ira->codegen, msg, entry->value->base.source_node, buf_sprintf("previous value is here")); 29024 prevs.deinit(); 29025 return ira->codegen->invalid_inst_gen; 29026 } 29027 } 29028 prevs.deinit(); 29029 } 29030 return ir_const_void(ira, &instruction->base.base); 29031 } 29032 29033 static IrInstGen *ir_analyze_instruction_check_statement_is_void(IrAnalyze *ira, 29034 IrInstSrcCheckStatementIsVoid *instruction) 29035 { 29036 IrInstGen *statement_value = instruction->statement_value->child; 29037 ZigType *statement_type = statement_value->value->type; 29038 if (type_is_invalid(statement_type)) 29039 return ira->codegen->invalid_inst_gen; 29040 29041 if (statement_type->id != ZigTypeIdVoid && statement_type->id != ZigTypeIdUnreachable) { 29042 ir_add_error(ira, &instruction->base.base, buf_sprintf("expression value is ignored")); 29043 } 29044 29045 return ir_const_void(ira, &instruction->base.base); 29046 } 29047 29048 static IrInstGen *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstSrcPanic *instruction) { 29049 IrInstGen *msg = instruction->msg->child; 29050 if (type_is_invalid(msg->value->type)) 29051 return ir_unreach_error(ira); 29052 29053 if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope)) { 29054 ir_add_error(ira, &instruction->base.base, buf_sprintf("encountered @panic at compile-time")); 29055 return ir_unreach_error(ira); 29056 } 29057 29058 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 29059 true, false, PtrLenUnknown, 0, 0, 0, false); 29060 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 29061 IrInstGen *casted_msg = ir_implicit_cast(ira, msg, str_type); 29062 if (type_is_invalid(casted_msg->value->type)) 29063 return ir_unreach_error(ira); 29064 29065 IrInstGen *new_instruction = ir_build_panic_gen(ira, &instruction->base.base, casted_msg); 29066 return ir_finish_anal(ira, new_instruction); 29067 } 29068 29069 static IrInstGen *ir_align_cast(IrAnalyze *ira, IrInstGen *target, uint32_t align_bytes, bool safety_check_on) { 29070 Error err; 29071 29072 ZigType *target_type = target->value->type; 29073 assert(!type_is_invalid(target_type)); 29074 29075 ZigType *result_type; 29076 uint32_t old_align_bytes; 29077 29078 if (target_type->id == ZigTypeIdPointer) { 29079 result_type = adjust_ptr_align(ira->codegen, target_type, align_bytes); 29080 if ((err = resolve_ptr_align(ira, target_type, &old_align_bytes))) 29081 return ira->codegen->invalid_inst_gen; 29082 } else if (target_type->id == ZigTypeIdFn) { 29083 FnTypeId fn_type_id = target_type->data.fn.fn_type_id; 29084 old_align_bytes = fn_type_id.alignment; 29085 fn_type_id.alignment = align_bytes; 29086 result_type = get_fn_type(ira->codegen, &fn_type_id); 29087 } else if (target_type->id == ZigTypeIdAnyFrame) { 29088 if (align_bytes >= target_fn_align(ira->codegen->zig_target)) { 29089 result_type = target_type; 29090 } else { 29091 ir_add_error(ira, &target->base, buf_sprintf("sub-aligned anyframe not allowed")); 29092 return ira->codegen->invalid_inst_gen; 29093 } 29094 } else if (target_type->id == ZigTypeIdOptional && 29095 target_type->data.maybe.child_type->id == ZigTypeIdPointer) 29096 { 29097 ZigType *ptr_type = target_type->data.maybe.child_type; 29098 if ((err = resolve_ptr_align(ira, ptr_type, &old_align_bytes))) 29099 return ira->codegen->invalid_inst_gen; 29100 ZigType *better_ptr_type = adjust_ptr_align(ira->codegen, ptr_type, align_bytes); 29101 29102 result_type = get_optional_type(ira->codegen, better_ptr_type); 29103 } else if (target_type->id == ZigTypeIdOptional && 29104 target_type->data.maybe.child_type->id == ZigTypeIdFn) 29105 { 29106 FnTypeId fn_type_id = target_type->data.maybe.child_type->data.fn.fn_type_id; 29107 old_align_bytes = fn_type_id.alignment; 29108 fn_type_id.alignment = align_bytes; 29109 ZigType *fn_type = get_fn_type(ira->codegen, &fn_type_id); 29110 result_type = get_optional_type(ira->codegen, fn_type); 29111 } else if (is_slice(target_type)) { 29112 ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry; 29113 if ((err = resolve_ptr_align(ira, slice_ptr_type, &old_align_bytes))) 29114 return ira->codegen->invalid_inst_gen; 29115 ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes); 29116 result_type = get_slice_type(ira->codegen, result_ptr_type); 29117 } else { 29118 ir_add_error(ira, &target->base, 29119 buf_sprintf("expected pointer or slice, found '%s'", buf_ptr(&target_type->name))); 29120 return ira->codegen->invalid_inst_gen; 29121 } 29122 29123 if (instr_is_comptime(target)) { 29124 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 29125 if (!val) 29126 return ira->codegen->invalid_inst_gen; 29127 29128 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 29129 val->data.x_ptr.data.hard_coded_addr.addr % align_bytes != 0) 29130 { 29131 ir_add_error(ira, &target->base, 29132 buf_sprintf("pointer address 0x%" ZIG_PRI_x64 " is not aligned to %" PRIu32 " bytes", 29133 val->data.x_ptr.data.hard_coded_addr.addr, align_bytes)); 29134 return ira->codegen->invalid_inst_gen; 29135 } 29136 29137 IrInstGen *result = ir_const(ira, &target->base, result_type); 29138 copy_const_val(ira->codegen, result->value, val); 29139 result->value->type = result_type; 29140 return result; 29141 } 29142 29143 if (safety_check_on && align_bytes > old_align_bytes && align_bytes != 1) { 29144 return ir_build_align_cast_gen(ira, target->base.scope, target->base.source_node, target, result_type); 29145 } else { 29146 return ir_build_cast(ira, &target->base, result_type, target, CastOpNoop); 29147 } 29148 } 29149 29150 static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr, 29151 IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on, 29152 bool keep_bigger_alignment) 29153 { 29154 Error err; 29155 29156 ZigType *src_type = ptr->value->type; 29157 assert(!type_is_invalid(src_type)); 29158 29159 if (src_type == dest_type) { 29160 return ptr; 29161 } 29162 29163 // We have a check for zero bits later so we use get_src_ptr_type to 29164 // validate src_type and dest_type. 29165 29166 ZigType *if_slice_ptr_type; 29167 if (is_slice(src_type)) { 29168 TypeStructField *ptr_field = src_type->data.structure.fields[slice_ptr_index]; 29169 if_slice_ptr_type = resolve_struct_field_type(ira->codegen, ptr_field); 29170 } else { 29171 if_slice_ptr_type = src_type; 29172 29173 ZigType *src_ptr_type = get_src_ptr_type(src_type); 29174 if (src_ptr_type == nullptr) { 29175 ir_add_error(ira, ptr_src, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name))); 29176 return ira->codegen->invalid_inst_gen; 29177 } 29178 } 29179 29180 ZigType *dest_ptr_type = get_src_ptr_type(dest_type); 29181 if (dest_ptr_type == nullptr) { 29182 ir_add_error(ira, dest_type_src, 29183 buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 29184 return ira->codegen->invalid_inst_gen; 29185 } 29186 29187 if (get_ptr_const(ira->codegen, src_type) && !get_ptr_const(ira->codegen, dest_type)) { 29188 ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); 29189 return ira->codegen->invalid_inst_gen; 29190 } 29191 uint32_t dest_align_bytes; 29192 if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) 29193 return ira->codegen->invalid_inst_gen; 29194 29195 uint32_t src_align_bytes = 0; 29196 if (keep_bigger_alignment || dest_align_bytes != 1) { 29197 if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) 29198 return ira->codegen->invalid_inst_gen; 29199 } 29200 29201 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 29202 return ira->codegen->invalid_inst_gen; 29203 29204 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown))) 29205 return ira->codegen->invalid_inst_gen; 29206 29207 if (safety_check_on && 29208 type_has_bits(ira->codegen, dest_type) && 29209 !type_has_bits(ira->codegen, if_slice_ptr_type)) 29210 { 29211 ErrorMsg *msg = ir_add_error(ira, source_instr, 29212 buf_sprintf("'%s' and '%s' do not have the same in-memory representation", 29213 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 29214 add_error_note(ira->codegen, msg, ptr_src->source_node, 29215 buf_sprintf("'%s' has no in-memory bits", buf_ptr(&src_type->name))); 29216 add_error_note(ira->codegen, msg, dest_type_src->source_node, 29217 buf_sprintf("'%s' has in-memory bits", buf_ptr(&dest_type->name))); 29218 return ira->codegen->invalid_inst_gen; 29219 } 29220 29221 // For slices, follow the `ptr` field. 29222 if (is_slice(src_type)) { 29223 TypeStructField *ptr_field = src_type->data.structure.fields[slice_ptr_index]; 29224 IrInstGen *ptr_ref = ir_get_ref(ira, source_instr, ptr, true, false); 29225 IrInstGen *ptr_ptr = ir_analyze_struct_field_ptr(ira, source_instr, ptr_field, ptr_ref, src_type, false); 29226 ptr = ir_get_deref(ira, source_instr, ptr_ptr, nullptr); 29227 } 29228 29229 if (instr_is_comptime(ptr)) { 29230 bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); 29231 UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad; 29232 ZigValue *val = ir_resolve_const(ira, ptr, is_undef_allowed); 29233 if (val == nullptr) 29234 return ira->codegen->invalid_inst_gen; 29235 29236 if (value_is_comptime(val) && val->special != ConstValSpecialUndef) { 29237 bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull || 29238 (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 29239 val->data.x_ptr.data.hard_coded_addr.addr == 0); 29240 if (is_addr_zero && !dest_allows_addr_zero) { 29241 ir_add_error(ira, source_instr, 29242 buf_sprintf("null pointer casted to type '%s'", buf_ptr(&dest_type->name))); 29243 return ira->codegen->invalid_inst_gen; 29244 } 29245 } 29246 29247 IrInstGen *result; 29248 if (val->data.x_ptr.mut == ConstPtrMutInfer) { 29249 result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); 29250 } else { 29251 result = ir_const(ira, source_instr, dest_type); 29252 } 29253 InferredStructField *isf = (val->type->id == ZigTypeIdPointer) ? 29254 val->type->data.pointer.inferred_struct_field : nullptr; 29255 if (isf == nullptr) { 29256 copy_const_val(ira->codegen, result->value, val); 29257 } else { 29258 // The destination value should have x_ptr struct pointing to underlying struct value 29259 result->value->data.x_ptr.mut = val->data.x_ptr.mut; 29260 TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); 29261 assert(field != nullptr); 29262 if (field->is_comptime) { 29263 result->value->data.x_ptr.special = ConstPtrSpecialRef; 29264 result->value->data.x_ptr.data.ref.pointee = field->init_val; 29265 } else { 29266 assert(val->data.x_ptr.special == ConstPtrSpecialRef); 29267 result->value->data.x_ptr.special = ConstPtrSpecialBaseStruct; 29268 result->value->data.x_ptr.data.base_struct.struct_val = val->data.x_ptr.data.ref.pointee; 29269 result->value->data.x_ptr.data.base_struct.field_index = field->src_index; 29270 } 29271 result->value->special = ConstValSpecialStatic; 29272 } 29273 result->value->type = dest_type; 29274 29275 // Keep the bigger alignment, it can only help- unless the target is zero bits. 29276 if (keep_bigger_alignment && src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { 29277 result = ir_align_cast(ira, result, src_align_bytes, false); 29278 } 29279 29280 return result; 29281 } 29282 29283 if (src_align_bytes != 0 && dest_align_bytes > src_align_bytes) { 29284 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 29285 add_error_note(ira->codegen, msg, ptr_src->source_node, 29286 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_type->name), src_align_bytes)); 29287 add_error_note(ira->codegen, msg, dest_type_src->source_node, 29288 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&dest_type->name), dest_align_bytes)); 29289 return ira->codegen->invalid_inst_gen; 29290 } 29291 29292 IrInstGen *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); 29293 29294 // Keep the bigger alignment, it can only help- unless the target is zero bits. 29295 IrInstGen *result; 29296 if (keep_bigger_alignment && src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { 29297 result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); 29298 if (type_is_invalid(result->value->type)) 29299 return ira->codegen->invalid_inst_gen; 29300 } else { 29301 result = casted_ptr; 29302 } 29303 return result; 29304 } 29305 29306 static IrInstGen *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstSrcPtrCast *instruction) { 29307 IrInstGen *dest_type_value = instruction->dest_type->child; 29308 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 29309 if (type_is_invalid(dest_type)) 29310 return ira->codegen->invalid_inst_gen; 29311 29312 IrInstGen *ptr = instruction->ptr->child; 29313 ZigType *src_type = ptr->value->type; 29314 if (type_is_invalid(src_type)) 29315 return ira->codegen->invalid_inst_gen; 29316 29317 bool keep_bigger_alignment = true; 29318 return ir_analyze_ptr_cast(ira, &instruction->base.base, ptr, &instruction->ptr->base, 29319 dest_type, &dest_type_value->base, instruction->safety_check_on, keep_bigger_alignment); 29320 } 29321 29322 static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ZigValue *val, size_t len) { 29323 size_t buf_i = 0; 29324 // TODO optimize the buf case 29325 expand_undef_array(codegen, val); 29326 for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) { 29327 ZigValue *elem = &val->data.x_array.data.s_none.elements[elem_i]; 29328 buf_write_value_bytes(codegen, &buf[buf_i], elem); 29329 buf_i += type_size(codegen, elem->type); 29330 } 29331 if (val->type->id == ZigTypeIdArray && val->type->data.array.sentinel != nullptr) { 29332 buf_write_value_bytes(codegen, &buf[buf_i], val->type->data.array.sentinel); 29333 } 29334 } 29335 29336 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val) { 29337 if (val->special == ConstValSpecialUndef) { 29338 expand_undef_struct(codegen, val); 29339 val->special = ConstValSpecialStatic; 29340 } 29341 assert(val->special == ConstValSpecialStatic); 29342 switch (val->type->id) { 29343 case ZigTypeIdInvalid: 29344 case ZigTypeIdMetaType: 29345 case ZigTypeIdOpaque: 29346 case ZigTypeIdBoundFn: 29347 case ZigTypeIdUnreachable: 29348 case ZigTypeIdComptimeFloat: 29349 case ZigTypeIdComptimeInt: 29350 case ZigTypeIdEnumLiteral: 29351 case ZigTypeIdUndefined: 29352 case ZigTypeIdNull: 29353 case ZigTypeIdErrorUnion: 29354 case ZigTypeIdErrorSet: 29355 zig_unreachable(); 29356 case ZigTypeIdVoid: 29357 return; 29358 case ZigTypeIdBool: 29359 buf[0] = val->data.x_bool ? 1 : 0; 29360 return; 29361 case ZigTypeIdInt: 29362 bigint_write_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 29363 codegen->is_big_endian); 29364 return; 29365 case ZigTypeIdEnum: 29366 bigint_write_twos_complement(&val->data.x_enum_tag, buf, 29367 val->type->data.enumeration.tag_int_type->data.integral.bit_count, 29368 codegen->is_big_endian); 29369 return; 29370 case ZigTypeIdFloat: 29371 float_write_ieee597(val, buf, codegen->is_big_endian); 29372 return; 29373 case ZigTypeIdPointer: 29374 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 29375 BigInt bn; 29376 bigint_init_unsigned(&bn, val->data.x_ptr.data.hard_coded_addr.addr); 29377 bigint_write_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, codegen->is_big_endian); 29378 return; 29379 } else { 29380 zig_unreachable(); 29381 } 29382 case ZigTypeIdArray: 29383 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.array.len); 29384 case ZigTypeIdVector: 29385 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.vector.len); 29386 case ZigTypeIdStruct: 29387 switch (val->type->data.structure.layout) { 29388 case ContainerLayoutAuto: 29389 zig_unreachable(); 29390 case ContainerLayoutExtern: { 29391 size_t src_field_count = val->type->data.structure.src_field_count; 29392 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { 29393 TypeStructField *struct_field = val->type->data.structure.fields[field_i]; 29394 if (struct_field->gen_index == SIZE_MAX) 29395 continue; 29396 ZigValue *field_val = val->data.x_struct.fields[field_i]; 29397 size_t offset = struct_field->offset; 29398 buf_write_value_bytes(codegen, buf + offset, field_val); 29399 } 29400 return; 29401 } 29402 case ContainerLayoutPacked: { 29403 size_t src_field_count = val->type->data.structure.src_field_count; 29404 size_t gen_field_count = val->type->data.structure.gen_field_count; 29405 size_t gen_i = 0; 29406 size_t src_i = 0; 29407 size_t offset = 0; 29408 bool is_big_endian = codegen->is_big_endian; 29409 uint8_t child_buf_prealloc[16]; 29410 size_t child_buf_len = 16; 29411 uint8_t *child_buf = child_buf_prealloc; 29412 while (gen_i < gen_field_count) { 29413 size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i]; 29414 if (big_int_byte_count > child_buf_len) { 29415 child_buf = heap::c_allocator.allocate_nonzero<uint8_t>(big_int_byte_count); 29416 child_buf_len = big_int_byte_count; 29417 } 29418 BigInt big_int; 29419 bigint_init_unsigned(&big_int, 0); 29420 size_t used_bits = 0; 29421 while (src_i < src_field_count) { 29422 TypeStructField *field = val->type->data.structure.fields[src_i]; 29423 assert(field->gen_index != SIZE_MAX); 29424 if (field->gen_index != gen_i) 29425 break; 29426 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); 29427 buf_write_value_bytes(codegen, child_buf, val->data.x_struct.fields[src_i]); 29428 BigInt child_val; 29429 bigint_read_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian, 29430 false); 29431 if (is_big_endian) { 29432 BigInt shift_amt; 29433 bigint_init_unsigned(&shift_amt, packed_bits_size); 29434 BigInt shifted; 29435 bigint_shl(&shifted, &big_int, &shift_amt); 29436 bigint_or(&big_int, &shifted, &child_val); 29437 } else { 29438 BigInt shift_amt; 29439 bigint_init_unsigned(&shift_amt, used_bits); 29440 BigInt child_val_shifted; 29441 bigint_shl(&child_val_shifted, &child_val, &shift_amt); 29442 BigInt tmp; 29443 bigint_or(&tmp, &big_int, &child_val_shifted); 29444 big_int = tmp; 29445 used_bits += packed_bits_size; 29446 } 29447 src_i += 1; 29448 } 29449 bigint_write_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian); 29450 offset += big_int_byte_count; 29451 gen_i += 1; 29452 } 29453 return; 29454 } 29455 } 29456 zig_unreachable(); 29457 case ZigTypeIdOptional: 29458 zig_panic("TODO buf_write_value_bytes maybe type"); 29459 case ZigTypeIdFn: 29460 zig_panic("TODO buf_write_value_bytes fn type"); 29461 case ZigTypeIdUnion: 29462 zig_panic("TODO buf_write_value_bytes union type"); 29463 case ZigTypeIdFnFrame: 29464 zig_panic("TODO buf_write_value_bytes async fn frame type"); 29465 case ZigTypeIdAnyFrame: 29466 zig_panic("TODO buf_write_value_bytes anyframe type"); 29467 } 29468 zig_unreachable(); 29469 } 29470 29471 static Error buf_read_value_bytes_array(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, 29472 ZigValue *val, ZigType *elem_type, size_t len) 29473 { 29474 Error err; 29475 uint64_t elem_size = type_size(codegen, elem_type); 29476 29477 switch (val->data.x_array.special) { 29478 case ConstArraySpecialNone: 29479 val->data.x_array.data.s_none.elements = codegen->pass1_arena->allocate<ZigValue>(len); 29480 for (size_t i = 0; i < len; i++) { 29481 ZigValue *elem = &val->data.x_array.data.s_none.elements[i]; 29482 elem->special = ConstValSpecialStatic; 29483 elem->type = elem_type; 29484 if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem))) 29485 return err; 29486 } 29487 return ErrorNone; 29488 case ConstArraySpecialUndef: 29489 zig_panic("TODO buf_read_value_bytes ConstArraySpecialUndef array type"); 29490 case ConstArraySpecialBuf: 29491 zig_panic("TODO buf_read_value_bytes ConstArraySpecialBuf array type"); 29492 } 29493 zig_unreachable(); 29494 } 29495 29496 static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ZigValue *val) { 29497 Error err; 29498 src_assert(val->special == ConstValSpecialStatic, source_node); 29499 switch (val->type->id) { 29500 case ZigTypeIdInvalid: 29501 case ZigTypeIdMetaType: 29502 case ZigTypeIdOpaque: 29503 case ZigTypeIdBoundFn: 29504 case ZigTypeIdUnreachable: 29505 case ZigTypeIdComptimeFloat: 29506 case ZigTypeIdComptimeInt: 29507 case ZigTypeIdEnumLiteral: 29508 case ZigTypeIdUndefined: 29509 case ZigTypeIdNull: 29510 zig_unreachable(); 29511 case ZigTypeIdVoid: 29512 return ErrorNone; 29513 case ZigTypeIdBool: 29514 val->data.x_bool = (buf[0] != 0); 29515 return ErrorNone; 29516 case ZigTypeIdInt: 29517 bigint_read_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 29518 codegen->is_big_endian, val->type->data.integral.is_signed); 29519 return ErrorNone; 29520 case ZigTypeIdFloat: 29521 float_read_ieee597(val, buf, codegen->is_big_endian); 29522 return ErrorNone; 29523 case ZigTypeIdPointer: 29524 { 29525 val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 29526 BigInt bn; 29527 bigint_read_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, 29528 codegen->is_big_endian, false); 29529 val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_usize(&bn); 29530 return ErrorNone; 29531 } 29532 case ZigTypeIdArray: 29533 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.array.child_type, 29534 val->type->data.array.len); 29535 case ZigTypeIdVector: 29536 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.vector.elem_type, 29537 val->type->data.vector.len); 29538 case ZigTypeIdEnum: 29539 switch (val->type->data.enumeration.layout) { 29540 case ContainerLayoutAuto: 29541 zig_panic("TODO buf_read_value_bytes enum auto"); 29542 case ContainerLayoutPacked: 29543 zig_panic("TODO buf_read_value_bytes enum packed"); 29544 case ContainerLayoutExtern: { 29545 ZigType *tag_int_type = val->type->data.enumeration.tag_int_type; 29546 src_assert(tag_int_type->id == ZigTypeIdInt, source_node); 29547 bigint_read_twos_complement(&val->data.x_enum_tag, buf, tag_int_type->data.integral.bit_count, 29548 codegen->is_big_endian, tag_int_type->data.integral.is_signed); 29549 return ErrorNone; 29550 } 29551 } 29552 zig_unreachable(); 29553 case ZigTypeIdStruct: 29554 switch (val->type->data.structure.layout) { 29555 case ContainerLayoutAuto: { 29556 switch(val->type->data.structure.special){ 29557 case StructSpecialNone: 29558 case StructSpecialInferredTuple: 29559 case StructSpecialInferredStruct: { 29560 ErrorMsg *msg = opt_ir_add_error_node(ira, codegen, source_node, 29561 buf_sprintf("non-extern, non-packed struct '%s' cannot have its bytes reinterpreted", 29562 buf_ptr(&val->type->name))); 29563 add_error_note(codegen, msg, val->type->data.structure.decl_node, 29564 buf_sprintf("declared here")); 29565 break; 29566 } 29567 case StructSpecialSlice: { 29568 opt_ir_add_error_node(ira, codegen, source_node, 29569 buf_sprintf("slice '%s' cannot have its bytes reinterpreted", 29570 buf_ptr(&val->type->name))); 29571 break; 29572 } 29573 } 29574 return ErrorSemanticAnalyzeFail; 29575 } 29576 case ContainerLayoutExtern: { 29577 size_t src_field_count = val->type->data.structure.src_field_count; 29578 val->data.x_struct.fields = alloc_const_vals_ptrs(codegen, src_field_count); 29579 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { 29580 ZigValue *field_val = val->data.x_struct.fields[field_i]; 29581 field_val->special = ConstValSpecialStatic; 29582 TypeStructField *struct_field = val->type->data.structure.fields[field_i]; 29583 field_val->type = struct_field->type_entry; 29584 if (struct_field->gen_index == SIZE_MAX) 29585 continue; 29586 size_t offset = struct_field->offset; 29587 uint8_t *new_buf = buf + offset; 29588 if ((err = buf_read_value_bytes(ira, codegen, source_node, new_buf, field_val))) 29589 return err; 29590 } 29591 return ErrorNone; 29592 } 29593 case ContainerLayoutPacked: { 29594 size_t src_field_count = val->type->data.structure.src_field_count; 29595 val->data.x_struct.fields = alloc_const_vals_ptrs(codegen, src_field_count); 29596 size_t gen_field_count = val->type->data.structure.gen_field_count; 29597 size_t gen_i = 0; 29598 size_t src_i = 0; 29599 size_t offset = 0; 29600 bool is_big_endian = codegen->is_big_endian; 29601 uint8_t child_buf_prealloc[16]; 29602 size_t child_buf_len = 16; 29603 uint8_t *child_buf = child_buf_prealloc; 29604 while (gen_i < gen_field_count) { 29605 size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i]; 29606 if (big_int_byte_count > child_buf_len) { 29607 child_buf = heap::c_allocator.allocate_nonzero<uint8_t>(big_int_byte_count); 29608 child_buf_len = big_int_byte_count; 29609 } 29610 BigInt big_int; 29611 bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false); 29612 uint64_t bit_offset = 0; 29613 while (src_i < src_field_count) { 29614 TypeStructField *field = val->type->data.structure.fields[src_i]; 29615 src_assert(field->gen_index != SIZE_MAX, source_node); 29616 if (field->gen_index != gen_i) 29617 break; 29618 ZigValue *field_val = val->data.x_struct.fields[src_i]; 29619 field_val->special = ConstValSpecialStatic; 29620 field_val->type = field->type_entry; 29621 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); 29622 29623 BigInt child_val; 29624 if (is_big_endian) { 29625 BigInt packed_bits_size_bi; 29626 bigint_init_unsigned(&packed_bits_size_bi, big_int_byte_count * 8 - packed_bits_size - bit_offset); 29627 BigInt tmp; 29628 bigint_shr(&tmp, &big_int, &packed_bits_size_bi); 29629 bigint_truncate(&child_val, &tmp, packed_bits_size, false); 29630 } else { 29631 BigInt packed_bits_size_bi; 29632 bigint_init_unsigned(&packed_bits_size_bi, packed_bits_size); 29633 bigint_truncate(&child_val, &big_int, packed_bits_size, false); 29634 BigInt tmp; 29635 bigint_shr(&tmp, &big_int, &packed_bits_size_bi); 29636 big_int = tmp; 29637 } 29638 29639 bigint_write_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian); 29640 if ((err = buf_read_value_bytes(ira, codegen, source_node, child_buf, field_val))) { 29641 return err; 29642 } 29643 29644 bit_offset += packed_bits_size; 29645 src_i += 1; 29646 } 29647 offset += big_int_byte_count; 29648 gen_i += 1; 29649 } 29650 return ErrorNone; 29651 } 29652 } 29653 zig_unreachable(); 29654 case ZigTypeIdOptional: 29655 zig_panic("TODO buf_read_value_bytes maybe type"); 29656 case ZigTypeIdErrorUnion: 29657 zig_panic("TODO buf_read_value_bytes error union"); 29658 case ZigTypeIdErrorSet: 29659 zig_panic("TODO buf_read_value_bytes pure error type"); 29660 case ZigTypeIdFn: 29661 zig_panic("TODO buf_read_value_bytes fn type"); 29662 case ZigTypeIdUnion: 29663 zig_panic("TODO buf_read_value_bytes union type"); 29664 case ZigTypeIdFnFrame: 29665 zig_panic("TODO buf_read_value_bytes async fn frame type"); 29666 case ZigTypeIdAnyFrame: 29667 zig_panic("TODO buf_read_value_bytes anyframe type"); 29668 } 29669 zig_unreachable(); 29670 } 29671 29672 static IrInstGen *ir_analyze_bit_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 29673 ZigType *dest_type) 29674 { 29675 Error err; 29676 29677 ZigType *src_type = value->value->type; 29678 ir_assert(type_can_bit_cast(src_type), source_instr); 29679 ir_assert(type_can_bit_cast(dest_type), source_instr); 29680 29681 if (dest_type->id == ZigTypeIdEnum) { 29682 ErrorMsg *msg = ir_add_error_node(ira, source_instr->source_node, 29683 buf_sprintf("cannot cast a value of type '%s'", buf_ptr(&dest_type->name))); 29684 add_error_note(ira->codegen, msg, source_instr->source_node, 29685 buf_sprintf("use @intToEnum for type coercion")); 29686 return ira->codegen->invalid_inst_gen; 29687 } 29688 29689 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown))) 29690 return ira->codegen->invalid_inst_gen; 29691 29692 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusSizeKnown))) 29693 return ira->codegen->invalid_inst_gen; 29694 29695 const bool src_is_ptr = handle_is_ptr(ira->codegen, src_type); 29696 const bool dest_is_ptr = handle_is_ptr(ira->codegen, dest_type); 29697 29698 const uint64_t dest_size_bytes = type_size(ira->codegen, dest_type); 29699 const uint64_t src_size_bytes = type_size(ira->codegen, src_type); 29700 if (dest_size_bytes != src_size_bytes) { 29701 ir_add_error(ira, source_instr, 29702 buf_sprintf("destination type '%s' has size %" ZIG_PRI_u64 " but source type '%s' has size %" ZIG_PRI_u64, 29703 buf_ptr(&dest_type->name), dest_size_bytes, 29704 buf_ptr(&src_type->name), src_size_bytes)); 29705 return ira->codegen->invalid_inst_gen; 29706 } 29707 29708 const uint64_t dest_size_bits = type_size_bits(ira->codegen, dest_type); 29709 const uint64_t src_size_bits = type_size_bits(ira->codegen, src_type); 29710 if (dest_size_bits != src_size_bits) { 29711 ir_add_error(ira, source_instr, 29712 buf_sprintf("destination type '%s' has %" ZIG_PRI_u64 " bits but source type '%s' has %" ZIG_PRI_u64 " bits", 29713 buf_ptr(&dest_type->name), dest_size_bits, 29714 buf_ptr(&src_type->name), src_size_bits)); 29715 return ira->codegen->invalid_inst_gen; 29716 } 29717 29718 if (instr_is_comptime(value)) { 29719 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 29720 if (!val) 29721 return ira->codegen->invalid_inst_gen; 29722 29723 IrInstGen *result = ir_const(ira, source_instr, dest_type); 29724 uint8_t *buf = heap::c_allocator.allocate_nonzero<uint8_t>(src_size_bytes); 29725 buf_write_value_bytes(ira->codegen, buf, val); 29726 if ((err = buf_read_value_bytes(ira, ira->codegen, source_instr->source_node, buf, result->value))) 29727 return ira->codegen->invalid_inst_gen; 29728 return result; 29729 } 29730 29731 if (dest_is_ptr && !src_is_ptr) { 29732 // Spill the scalar into a local memory location and take its address 29733 value = ir_get_ref(ira, source_instr, value, false, false); 29734 } 29735 29736 return ir_build_bit_cast_gen(ira, source_instr, value, dest_type); 29737 } 29738 29739 static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 29740 ZigType *ptr_type) 29741 { 29742 Error err; 29743 29744 ir_assert(get_src_ptr_type(ptr_type) != nullptr, source_instr); 29745 ir_assert(type_has_bits(ira->codegen, ptr_type), source_instr); 29746 29747 IrInstGen *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize); 29748 if (type_is_invalid(casted_int->value->type)) 29749 return ira->codegen->invalid_inst_gen; 29750 29751 if (instr_is_comptime(casted_int)) { 29752 ZigValue *val = ir_resolve_const(ira, casted_int, UndefBad); 29753 if (!val) 29754 return ira->codegen->invalid_inst_gen; 29755 29756 uint64_t addr = bigint_as_u64(&val->data.x_bigint); 29757 if (!ptr_allows_addr_zero(ptr_type) && addr == 0) { 29758 ir_add_error(ira, source_instr, 29759 buf_sprintf("pointer type '%s' does not allow address zero", buf_ptr(&ptr_type->name))); 29760 return ira->codegen->invalid_inst_gen; 29761 } 29762 29763 uint32_t align_bytes; 29764 if ((err = resolve_ptr_align(ira, ptr_type, &align_bytes))) 29765 return ira->codegen->invalid_inst_gen; 29766 29767 if (addr != 0 && addr % align_bytes != 0) { 29768 ir_add_error(ira, source_instr, 29769 buf_sprintf("pointer type '%s' requires aligned address", 29770 buf_ptr(&ptr_type->name))); 29771 return ira->codegen->invalid_inst_gen; 29772 } 29773 29774 IrInstGen *result = ir_const(ira, source_instr, ptr_type); 29775 if (ptr_type->id == ZigTypeIdOptional && addr == 0) { 29776 result->value->data.x_ptr.special = ConstPtrSpecialNull; 29777 result->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 29778 } else { 29779 result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 29780 result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; 29781 result->value->data.x_ptr.data.hard_coded_addr.addr = addr; 29782 } 29783 29784 return result; 29785 } 29786 29787 return ir_build_int_to_ptr_gen(ira, source_instr->scope, source_instr->source_node, casted_int, ptr_type); 29788 } 29789 29790 static IrInstGen *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstSrcIntToPtr *instruction) { 29791 Error err; 29792 IrInstGen *dest_type_value = instruction->dest_type->child; 29793 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 29794 if (type_is_invalid(dest_type)) 29795 return ira->codegen->invalid_inst_gen; 29796 29797 // We explicitly check for the size, so we can use get_src_ptr_type 29798 if (get_src_ptr_type(dest_type) == nullptr) { 29799 ir_add_error(ira, &dest_type_value->base, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 29800 return ira->codegen->invalid_inst_gen; 29801 } 29802 29803 bool has_bits; 29804 if ((err = type_has_bits2(ira->codegen, dest_type, &has_bits))) 29805 return ira->codegen->invalid_inst_gen; 29806 29807 if (!has_bits) { 29808 ir_add_error(ira, &dest_type_value->base, 29809 buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name))); 29810 return ira->codegen->invalid_inst_gen; 29811 } 29812 29813 IrInstGen *target = instruction->target->child; 29814 if (type_is_invalid(target->value->type)) 29815 return ira->codegen->invalid_inst_gen; 29816 29817 return ir_analyze_int_to_ptr(ira, &instruction->base.base, target, dest_type); 29818 } 29819 29820 static IrInstGen *ir_analyze_instruction_decl_ref(IrAnalyze *ira, IrInstSrcDeclRef *instruction) { 29821 IrInstGen *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base.base, instruction->tld); 29822 if (type_is_invalid(ref_instruction->value->type)) { 29823 return ira->codegen->invalid_inst_gen; 29824 } 29825 29826 if (instruction->lval == LValPtr || instruction->lval == LValAssign) { 29827 return ref_instruction; 29828 } else { 29829 return ir_get_deref(ira, &instruction->base.base, ref_instruction, nullptr); 29830 } 29831 } 29832 29833 static IrInstGen *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstSrcPtrToInt *instruction) { 29834 Error err; 29835 IrInstGen *target = instruction->target->child; 29836 if (type_is_invalid(target->value->type)) 29837 return ira->codegen->invalid_inst_gen; 29838 29839 ZigType *usize = ira->codegen->builtin_types.entry_usize; 29840 29841 ZigType *src_ptr_type = get_src_ptr_type(target->value->type); 29842 if (src_ptr_type == nullptr) { 29843 ir_add_error(ira, &target->base, 29844 buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value->type->name))); 29845 return ira->codegen->invalid_inst_gen; 29846 } 29847 29848 bool has_bits; 29849 if ((err = type_has_bits2(ira->codegen, src_ptr_type, &has_bits))) 29850 return ira->codegen->invalid_inst_gen; 29851 29852 if (!has_bits) { 29853 ir_add_error(ira, &target->base, 29854 buf_sprintf("pointer to size 0 type has no address")); 29855 return ira->codegen->invalid_inst_gen; 29856 } 29857 29858 if (instr_is_comptime(target)) { 29859 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 29860 if (!val) 29861 return ira->codegen->invalid_inst_gen; 29862 29863 // Since we've already run this type trough get_src_ptr_type it is 29864 // safe to access the x_ptr fields 29865 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 29866 IrInstGen *result = ir_const(ira, &instruction->base.base, usize); 29867 bigint_init_unsigned(&result->value->data.x_bigint, val->data.x_ptr.data.hard_coded_addr.addr); 29868 result->value->type = usize; 29869 return result; 29870 } else if (val->data.x_ptr.special == ConstPtrSpecialNull) { 29871 IrInstGen *result = ir_const(ira, &instruction->base.base, usize); 29872 bigint_init_unsigned(&result->value->data.x_bigint, 0); 29873 result->value->type = usize; 29874 return result; 29875 } 29876 } 29877 29878 return ir_build_ptr_to_int_gen(ira, &instruction->base.base, target); 29879 } 29880 29881 static IrInstGen *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstSrcPtrType *instruction) { 29882 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); 29883 result->value->special = ConstValSpecialLazy; 29884 29885 LazyValuePtrType *lazy_ptr_type = heap::c_allocator.create<LazyValuePtrType>(); 29886 lazy_ptr_type->ira = ira; ira_ref(ira); 29887 result->value->data.x_lazy = &lazy_ptr_type->base; 29888 lazy_ptr_type->base.id = LazyValueIdPtrType; 29889 29890 if (instruction->sentinel != nullptr) { 29891 if (instruction->ptr_len != PtrLenUnknown) { 29892 ir_add_error(ira, &instruction->base.base, 29893 buf_sprintf("sentinels are only allowed on unknown-length pointers")); 29894 return ira->codegen->invalid_inst_gen; 29895 } 29896 29897 lazy_ptr_type->sentinel = instruction->sentinel->child; 29898 if (ir_resolve_const(ira, lazy_ptr_type->sentinel, LazyOk) == nullptr) 29899 return ira->codegen->invalid_inst_gen; 29900 } 29901 29902 lazy_ptr_type->elem_type = instruction->child_type->child; 29903 if (ir_resolve_type_lazy(ira, lazy_ptr_type->elem_type) == nullptr) 29904 return ira->codegen->invalid_inst_gen; 29905 29906 if (instruction->align_value != nullptr) { 29907 lazy_ptr_type->align_inst = instruction->align_value->child; 29908 if (ir_resolve_const(ira, lazy_ptr_type->align_inst, LazyOk) == nullptr) 29909 return ira->codegen->invalid_inst_gen; 29910 } 29911 29912 lazy_ptr_type->ptr_len = instruction->ptr_len; 29913 lazy_ptr_type->is_const = instruction->is_const; 29914 lazy_ptr_type->is_volatile = instruction->is_volatile; 29915 lazy_ptr_type->is_allowzero = instruction->is_allow_zero; 29916 lazy_ptr_type->bit_offset_in_host = instruction->bit_offset_start; 29917 lazy_ptr_type->host_int_bytes = instruction->host_int_bytes; 29918 29919 return result; 29920 } 29921 29922 static IrInstGen *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstSrcAlignCast *instruction) { 29923 IrInstGen *target = instruction->target->child; 29924 if (type_is_invalid(target->value->type)) 29925 return ira->codegen->invalid_inst_gen; 29926 29927 ZigType *elem_type = nullptr; 29928 if (is_slice(target->value->type)) { 29929 ZigType *slice_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry; 29930 elem_type = slice_ptr_type->data.pointer.child_type; 29931 } else if (target->value->type->id == ZigTypeIdPointer) { 29932 elem_type = target->value->type->data.pointer.child_type; 29933 } 29934 29935 uint32_t align_bytes; 29936 IrInstGen *align_bytes_inst = instruction->align_bytes->child; 29937 if (!ir_resolve_align(ira, align_bytes_inst, elem_type, &align_bytes)) 29938 return ira->codegen->invalid_inst_gen; 29939 29940 IrInstGen *result = ir_align_cast(ira, target, align_bytes, true); 29941 if (type_is_invalid(result->value->type)) 29942 return ira->codegen->invalid_inst_gen; 29943 29944 return result; 29945 } 29946 29947 static IrInstGen *ir_analyze_instruction_opaque_type(IrAnalyze *ira, IrInstSrcOpaqueType *instruction) { 29948 Buf *bare_name = buf_alloc(); 29949 Buf *full_name = get_anon_type_name(ira->codegen, ira->old_irb.exec, "opaque", 29950 instruction->base.base.scope, instruction->base.base.source_node, bare_name); 29951 ZigType *result_type = get_opaque_type(ira->codegen, instruction->base.base.scope, 29952 instruction->base.base.source_node, buf_ptr(full_name), bare_name); 29953 return ir_const_type(ira, &instruction->base.base, result_type); 29954 } 29955 29956 static IrInstGen *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstSrcSetAlignStack *instruction) { 29957 uint32_t align_bytes; 29958 IrInstGen *align_bytes_inst = instruction->align_bytes->child; 29959 if (!ir_resolve_align(ira, align_bytes_inst, nullptr, &align_bytes)) 29960 return ira->codegen->invalid_inst_gen; 29961 29962 if (align_bytes > 256) { 29963 ir_add_error(ira, &instruction->base.base, buf_sprintf("attempt to @setAlignStack(%" PRIu32 "); maximum is 256", align_bytes)); 29964 return ira->codegen->invalid_inst_gen; 29965 } 29966 29967 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 29968 if (fn_entry == nullptr) { 29969 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack outside function")); 29970 return ira->codegen->invalid_inst_gen; 29971 } 29972 if (fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionNaked) { 29973 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack in naked function")); 29974 return ira->codegen->invalid_inst_gen; 29975 } 29976 29977 if (fn_entry->fn_inline == FnInlineAlways) { 29978 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack in inline function")); 29979 return ira->codegen->invalid_inst_gen; 29980 } 29981 29982 if (fn_entry->set_alignstack_node != nullptr) { 29983 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 29984 buf_sprintf("alignstack set twice")); 29985 add_error_note(ira->codegen, msg, fn_entry->set_alignstack_node, buf_sprintf("first set here")); 29986 return ira->codegen->invalid_inst_gen; 29987 } 29988 29989 fn_entry->set_alignstack_node = instruction->base.base.source_node; 29990 fn_entry->alignstack_value = align_bytes; 29991 29992 return ir_const_void(ira, &instruction->base.base); 29993 } 29994 29995 static IrInstGen *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstSrcArgType *instruction) { 29996 IrInstGen *fn_type_inst = instruction->fn_type->child; 29997 ZigType *fn_type = ir_resolve_type(ira, fn_type_inst); 29998 if (type_is_invalid(fn_type)) 29999 return ira->codegen->invalid_inst_gen; 30000 30001 IrInstGen *arg_index_inst = instruction->arg_index->child; 30002 uint64_t arg_index; 30003 if (!ir_resolve_usize(ira, arg_index_inst, &arg_index)) 30004 return ira->codegen->invalid_inst_gen; 30005 30006 if (fn_type->id == ZigTypeIdBoundFn) { 30007 fn_type = fn_type->data.bound_fn.fn_type; 30008 arg_index += 1; 30009 } 30010 if (fn_type->id != ZigTypeIdFn) { 30011 ir_add_error(ira, &fn_type_inst->base, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); 30012 return ira->codegen->invalid_inst_gen; 30013 } 30014 30015 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 30016 if (arg_index >= fn_type_id->param_count) { 30017 if (instruction->allow_var) { 30018 // TODO remove this with var args 30019 return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_anytype); 30020 } 30021 ir_add_error(ira, &arg_index_inst->base, 30022 buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments", 30023 arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count)); 30024 return ira->codegen->invalid_inst_gen; 30025 } 30026 30027 ZigType *result_type = fn_type_id->param_info[arg_index].type; 30028 if (result_type == nullptr) { 30029 // Args are only unresolved if our function is generic. 30030 ir_assert(fn_type->data.fn.is_generic, &instruction->base.base); 30031 30032 if (instruction->allow_var) { 30033 return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_anytype); 30034 } else { 30035 ir_add_error(ira, &arg_index_inst->base, 30036 buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", 30037 arg_index, buf_ptr(&fn_type->name))); 30038 return ira->codegen->invalid_inst_gen; 30039 } 30040 } 30041 return ir_const_type(ira, &instruction->base.base, result_type); 30042 } 30043 30044 static IrInstGen *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstSrcTagType *instruction) { 30045 Error err; 30046 IrInstGen *target_inst = instruction->target->child; 30047 ZigType *enum_type = ir_resolve_type(ira, target_inst); 30048 if (type_is_invalid(enum_type)) 30049 return ira->codegen->invalid_inst_gen; 30050 30051 if (enum_type->id == ZigTypeIdEnum) { 30052 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown))) 30053 return ira->codegen->invalid_inst_gen; 30054 30055 return ir_const_type(ira, &instruction->base.base, enum_type->data.enumeration.tag_int_type); 30056 } else if (enum_type->id == ZigTypeIdUnion) { 30057 ZigType *tag_type = ir_resolve_union_tag_type(ira, instruction->target->base.source_node, enum_type); 30058 if (type_is_invalid(tag_type)) 30059 return ira->codegen->invalid_inst_gen; 30060 return ir_const_type(ira, &instruction->base.base, tag_type); 30061 } else { 30062 ir_add_error(ira, &target_inst->base, buf_sprintf("expected enum or union, found '%s'", 30063 buf_ptr(&enum_type->name))); 30064 return ira->codegen->invalid_inst_gen; 30065 } 30066 } 30067 30068 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) { 30069 ZigType *operand_type = ir_resolve_type(ira, op); 30070 if (type_is_invalid(operand_type)) 30071 return ira->codegen->builtin_types.entry_invalid; 30072 30073 if (operand_type->id == ZigTypeIdInt || operand_type->id == ZigTypeIdEnum) { 30074 ZigType *int_type; 30075 if (operand_type->id == ZigTypeIdEnum) { 30076 int_type = operand_type->data.enumeration.tag_int_type; 30077 } else { 30078 int_type = operand_type; 30079 } 30080 auto bit_count = int_type->data.integral.bit_count; 30081 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); 30082 30083 if (bit_count > max_atomic_bits) { 30084 ir_add_error(ira, &op->base, 30085 buf_sprintf("expected %" PRIu32 "-bit integer type or smaller, found %" PRIu32 "-bit integer type", 30086 max_atomic_bits, bit_count)); 30087 return ira->codegen->builtin_types.entry_invalid; 30088 } 30089 } else if (operand_type->id == ZigTypeIdFloat) { 30090 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); 30091 if (operand_type->data.floating.bit_count > max_atomic_bits) { 30092 ir_add_error(ira, &op->base, 30093 buf_sprintf("expected %" PRIu32 "-bit float or smaller, found %" PRIu32 "-bit float", 30094 max_atomic_bits, (uint32_t) operand_type->data.floating.bit_count)); 30095 return ira->codegen->builtin_types.entry_invalid; 30096 } 30097 } else if (operand_type->id == ZigTypeIdBool) { 30098 // will be treated as u8 30099 } else { 30100 Error err; 30101 ZigType *operand_ptr_type; 30102 if ((err = get_codegen_ptr_type(ira->codegen, operand_type, &operand_ptr_type))) 30103 return ira->codegen->builtin_types.entry_invalid; 30104 if (operand_ptr_type == nullptr) { 30105 ir_add_error(ira, &op->base, 30106 buf_sprintf("expected integer, float, enum or pointer type, found '%s'", 30107 buf_ptr(&operand_type->name))); 30108 return ira->codegen->builtin_types.entry_invalid; 30109 } 30110 } 30111 30112 return operand_type; 30113 } 30114 30115 static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAtomicRmw *instruction) { 30116 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 30117 if (type_is_invalid(operand_type)) 30118 return ira->codegen->invalid_inst_gen; 30119 30120 IrInstGen *ptr_inst = instruction->ptr->child; 30121 if (type_is_invalid(ptr_inst->value->type)) 30122 return ira->codegen->invalid_inst_gen; 30123 30124 // TODO let this be volatile 30125 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 30126 IrInstGen *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 30127 if (type_is_invalid(casted_ptr->value->type)) 30128 return ira->codegen->invalid_inst_gen; 30129 30130 AtomicRmwOp op; 30131 if (!ir_resolve_atomic_rmw_op(ira, instruction->op->child, &op)) { 30132 return ira->codegen->invalid_inst_gen; 30133 } 30134 30135 if (operand_type->id == ZigTypeIdEnum && op != AtomicRmwOp_xchg) { 30136 ir_add_error(ira, &instruction->op->base, 30137 buf_sprintf("@atomicRmw with enum only allowed with .Xchg")); 30138 return ira->codegen->invalid_inst_gen; 30139 } else if (operand_type->id == ZigTypeIdBool && op != AtomicRmwOp_xchg) { 30140 ir_add_error(ira, &instruction->op->base, 30141 buf_sprintf("@atomicRmw with bool only allowed with .Xchg")); 30142 return ira->codegen->invalid_inst_gen; 30143 } else if (operand_type->id == ZigTypeIdFloat && op > AtomicRmwOp_sub) { 30144 ir_add_error(ira, &instruction->op->base, 30145 buf_sprintf("@atomicRmw with float only allowed with .Xchg, .Add and .Sub")); 30146 return ira->codegen->invalid_inst_gen; 30147 } 30148 30149 IrInstGen *operand = instruction->operand->child; 30150 if (type_is_invalid(operand->value->type)) 30151 return ira->codegen->invalid_inst_gen; 30152 30153 IrInstGen *casted_operand = ir_implicit_cast(ira, operand, operand_type); 30154 if (type_is_invalid(casted_operand->value->type)) 30155 return ira->codegen->invalid_inst_gen; 30156 30157 AtomicOrder ordering; 30158 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 30159 return ira->codegen->invalid_inst_gen; 30160 if (ordering == AtomicOrderUnordered) { 30161 ir_add_error(ira, &instruction->ordering->base, 30162 buf_sprintf("@atomicRmw atomic ordering must not be Unordered")); 30163 return ira->codegen->invalid_inst_gen; 30164 } 30165 30166 // special case zero bit types 30167 switch (type_has_one_possible_value(ira->codegen, operand_type)) { 30168 case OnePossibleValueInvalid: 30169 return ira->codegen->invalid_inst_gen; 30170 case OnePossibleValueYes: 30171 return ir_const_move(ira, &instruction->base.base, get_the_one_possible_value(ira->codegen, operand_type)); 30172 case OnePossibleValueNo: 30173 break; 30174 } 30175 30176 IrInst *source_inst = &instruction->base.base; 30177 if (instr_is_comptime(casted_operand) && instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar) { 30178 ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad); 30179 if (ptr_val == nullptr) 30180 return ira->codegen->invalid_inst_gen; 30181 30182 ZigValue *op1_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.base.source_node); 30183 if (op1_val == nullptr) 30184 return ira->codegen->invalid_inst_gen; 30185 30186 ZigValue *op2_val = ir_resolve_const(ira, casted_operand, UndefBad); 30187 if (op2_val == nullptr) 30188 return ira->codegen->invalid_inst_gen; 30189 30190 IrInstGen *result = ir_const(ira, source_inst, operand_type); 30191 copy_const_val(ira->codegen, result->value, op1_val); 30192 if (op == AtomicRmwOp_xchg) { 30193 copy_const_val(ira->codegen, op1_val, op2_val); 30194 return result; 30195 } 30196 30197 if (operand_type->id == ZigTypeIdPointer || operand_type->id == ZigTypeIdOptional) { 30198 ir_add_error(ira, &instruction->ordering->base, 30199 buf_sprintf("TODO comptime @atomicRmw with pointers other than .Xchg")); 30200 return ira->codegen->invalid_inst_gen; 30201 } 30202 30203 ErrorMsg *msg; 30204 if (op == AtomicRmwOp_min || op == AtomicRmwOp_max) { 30205 IrBinOp bin_op; 30206 if (op == AtomicRmwOp_min) 30207 // store op2 if op2 < op1 30208 bin_op = IrBinOpCmpGreaterThan; 30209 else 30210 // store op2 if op2 > op1 30211 bin_op = IrBinOpCmpLessThan; 30212 30213 IrInstGen *dummy_value = ir_const(ira, source_inst, operand_type); 30214 msg = ir_eval_bin_op_cmp_scalar(ira, source_inst, op1_val, bin_op, op2_val, dummy_value->value); 30215 if (msg != nullptr) { 30216 return ira->codegen->invalid_inst_gen; 30217 } 30218 if (dummy_value->value->data.x_bool) 30219 copy_const_val(ira->codegen, op1_val, op2_val); 30220 } else { 30221 IrBinOp bin_op; 30222 switch (op) { 30223 case AtomicRmwOp_xchg: 30224 case AtomicRmwOp_max: 30225 case AtomicRmwOp_min: 30226 zig_unreachable(); 30227 case AtomicRmwOp_add: 30228 if (operand_type->id == ZigTypeIdFloat) 30229 bin_op = IrBinOpAdd; 30230 else 30231 bin_op = IrBinOpAddWrap; 30232 break; 30233 case AtomicRmwOp_sub: 30234 if (operand_type->id == ZigTypeIdFloat) 30235 bin_op = IrBinOpSub; 30236 else 30237 bin_op = IrBinOpSubWrap; 30238 break; 30239 case AtomicRmwOp_and: 30240 case AtomicRmwOp_nand: 30241 bin_op = IrBinOpBinAnd; 30242 break; 30243 case AtomicRmwOp_or: 30244 bin_op = IrBinOpBinOr; 30245 break; 30246 case AtomicRmwOp_xor: 30247 bin_op = IrBinOpBinXor; 30248 break; 30249 } 30250 msg = ir_eval_math_op_scalar(ira, source_inst, operand_type, op1_val, bin_op, op2_val, op1_val); 30251 if (msg != nullptr) { 30252 return ira->codegen->invalid_inst_gen; 30253 } 30254 if (op == AtomicRmwOp_nand) { 30255 bigint_not(&op1_val->data.x_bigint, &op1_val->data.x_bigint, 30256 operand_type->data.integral.bit_count, operand_type->data.integral.is_signed); 30257 } 30258 } 30259 return result; 30260 } 30261 30262 return ir_build_atomic_rmw_gen(ira, source_inst, casted_ptr, casted_operand, op, 30263 ordering, operand_type); 30264 } 30265 30266 static IrInstGen *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstSrcAtomicLoad *instruction) { 30267 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 30268 if (type_is_invalid(operand_type)) 30269 return ira->codegen->invalid_inst_gen; 30270 30271 IrInstGen *ptr_inst = instruction->ptr->child; 30272 if (type_is_invalid(ptr_inst->value->type)) 30273 return ira->codegen->invalid_inst_gen; 30274 30275 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, true); 30276 IrInstGen *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 30277 if (type_is_invalid(casted_ptr->value->type)) 30278 return ira->codegen->invalid_inst_gen; 30279 30280 AtomicOrder ordering; 30281 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 30282 return ira->codegen->invalid_inst_gen; 30283 30284 if (ordering == AtomicOrderRelease || ordering == AtomicOrderAcqRel) { 30285 ir_assert(instruction->ordering != nullptr, &instruction->base.base); 30286 ir_add_error(ira, &instruction->ordering->base, 30287 buf_sprintf("@atomicLoad atomic ordering must not be Release or AcqRel")); 30288 return ira->codegen->invalid_inst_gen; 30289 } 30290 30291 if (instr_is_comptime(casted_ptr)) { 30292 IrInstGen *result = ir_get_deref(ira, &instruction->base.base, casted_ptr, nullptr); 30293 ir_assert(result->value->type != nullptr, &instruction->base.base); 30294 return result; 30295 } 30296 30297 return ir_build_atomic_load_gen(ira, &instruction->base.base, casted_ptr, ordering, operand_type); 30298 } 30299 30300 static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcAtomicStore *instruction) { 30301 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 30302 if (type_is_invalid(operand_type)) 30303 return ira->codegen->invalid_inst_gen; 30304 30305 IrInstGen *ptr_inst = instruction->ptr->child; 30306 if (type_is_invalid(ptr_inst->value->type)) 30307 return ira->codegen->invalid_inst_gen; 30308 30309 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 30310 IrInstGen *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 30311 if (type_is_invalid(casted_ptr->value->type)) 30312 return ira->codegen->invalid_inst_gen; 30313 30314 IrInstGen *value = instruction->value->child; 30315 if (type_is_invalid(value->value->type)) 30316 return ira->codegen->invalid_inst_gen; 30317 30318 IrInstGen *casted_value = ir_implicit_cast(ira, value, operand_type); 30319 if (type_is_invalid(casted_value->value->type)) 30320 return ira->codegen->invalid_inst_gen; 30321 30322 30323 AtomicOrder ordering; 30324 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 30325 return ira->codegen->invalid_inst_gen; 30326 30327 if (ordering == AtomicOrderAcquire || ordering == AtomicOrderAcqRel) { 30328 ir_assert(instruction->ordering != nullptr, &instruction->base.base); 30329 ir_add_error(ira, &instruction->ordering->base, 30330 buf_sprintf("@atomicStore atomic ordering must not be Acquire or AcqRel")); 30331 return ira->codegen->invalid_inst_gen; 30332 } 30333 30334 // special case zero bit types 30335 switch (type_has_one_possible_value(ira->codegen, operand_type)) { 30336 case OnePossibleValueInvalid: 30337 return ira->codegen->invalid_inst_gen; 30338 case OnePossibleValueYes: 30339 return ir_const_void(ira, &instruction->base.base); 30340 case OnePossibleValueNo: 30341 break; 30342 } 30343 30344 if (instr_is_comptime(casted_value) && instr_is_comptime(casted_ptr)) { 30345 IrInstGen *result = ir_analyze_store_ptr(ira, &instruction->base.base, casted_ptr, value, false); 30346 result->value->type = ira->codegen->builtin_types.entry_void; 30347 return result; 30348 } 30349 30350 return ir_build_atomic_store_gen(ira, &instruction->base.base, casted_ptr, casted_value, ordering); 30351 } 30352 30353 static IrInstGen *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstSrcSaveErrRetAddr *instruction) { 30354 return ir_build_save_err_ret_addr_gen(ira, &instruction->base.base); 30355 } 30356 30357 static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinFnId fop, ZigType *float_type, 30358 ZigValue *op, ZigValue *out_val) 30359 { 30360 assert(ira && source_instr && float_type && out_val && op); 30361 assert(float_type->id == ZigTypeIdFloat || 30362 float_type->id == ZigTypeIdComptimeFloat); 30363 30364 unsigned bits; 30365 30366 switch (float_type->id) { 30367 case ZigTypeIdComptimeFloat: 30368 bits = 128; 30369 break; 30370 case ZigTypeIdFloat: 30371 bits = float_type->data.floating.bit_count; 30372 break; 30373 default: 30374 zig_unreachable(); 30375 } 30376 30377 switch (bits) { 30378 case 16: { 30379 switch (fop) { 30380 case BuiltinFnIdSqrt: 30381 out_val->data.x_f16 = f16_sqrt(op->data.x_f16); 30382 break; 30383 case BuiltinFnIdSin: 30384 out_val->data.x_f16 = zig_double_to_f16(sin(zig_f16_to_double(op->data.x_f16))); 30385 break; 30386 case BuiltinFnIdCos: 30387 out_val->data.x_f16 = zig_double_to_f16(cos(zig_f16_to_double(op->data.x_f16))); 30388 break; 30389 case BuiltinFnIdExp: 30390 out_val->data.x_f16 = zig_double_to_f16(exp(zig_f16_to_double(op->data.x_f16))); 30391 break; 30392 case BuiltinFnIdExp2: 30393 out_val->data.x_f16 = zig_double_to_f16(exp2(zig_f16_to_double(op->data.x_f16))); 30394 break; 30395 case BuiltinFnIdLog: 30396 out_val->data.x_f16 = zig_double_to_f16(log(zig_f16_to_double(op->data.x_f16))); 30397 break; 30398 case BuiltinFnIdLog10: 30399 out_val->data.x_f16 = zig_double_to_f16(log10(zig_f16_to_double(op->data.x_f16))); 30400 break; 30401 case BuiltinFnIdLog2: 30402 out_val->data.x_f16 = zig_double_to_f16(log2(zig_f16_to_double(op->data.x_f16))); 30403 break; 30404 case BuiltinFnIdFabs: 30405 out_val->data.x_f16 = zig_double_to_f16(fabs(zig_f16_to_double(op->data.x_f16))); 30406 break; 30407 case BuiltinFnIdFloor: 30408 out_val->data.x_f16 = zig_double_to_f16(floor(zig_f16_to_double(op->data.x_f16))); 30409 break; 30410 case BuiltinFnIdCeil: 30411 out_val->data.x_f16 = zig_double_to_f16(ceil(zig_f16_to_double(op->data.x_f16))); 30412 break; 30413 case BuiltinFnIdTrunc: 30414 out_val->data.x_f16 = zig_double_to_f16(trunc(zig_f16_to_double(op->data.x_f16))); 30415 break; 30416 case BuiltinFnIdNearbyInt: 30417 out_val->data.x_f16 = zig_double_to_f16(nearbyint(zig_f16_to_double(op->data.x_f16))); 30418 break; 30419 case BuiltinFnIdRound: 30420 out_val->data.x_f16 = zig_double_to_f16(round(zig_f16_to_double(op->data.x_f16))); 30421 break; 30422 default: 30423 zig_unreachable(); 30424 }; 30425 break; 30426 } 30427 case 32: { 30428 switch (fop) { 30429 case BuiltinFnIdSqrt: 30430 out_val->data.x_f32 = sqrtf(op->data.x_f32); 30431 break; 30432 case BuiltinFnIdSin: 30433 out_val->data.x_f32 = sinf(op->data.x_f32); 30434 break; 30435 case BuiltinFnIdCos: 30436 out_val->data.x_f32 = cosf(op->data.x_f32); 30437 break; 30438 case BuiltinFnIdExp: 30439 out_val->data.x_f32 = expf(op->data.x_f32); 30440 break; 30441 case BuiltinFnIdExp2: 30442 out_val->data.x_f32 = exp2f(op->data.x_f32); 30443 break; 30444 case BuiltinFnIdLog: 30445 out_val->data.x_f32 = logf(op->data.x_f32); 30446 break; 30447 case BuiltinFnIdLog10: 30448 out_val->data.x_f32 = log10f(op->data.x_f32); 30449 break; 30450 case BuiltinFnIdLog2: 30451 out_val->data.x_f32 = log2f(op->data.x_f32); 30452 break; 30453 case BuiltinFnIdFabs: 30454 out_val->data.x_f32 = fabsf(op->data.x_f32); 30455 break; 30456 case BuiltinFnIdFloor: 30457 out_val->data.x_f32 = floorf(op->data.x_f32); 30458 break; 30459 case BuiltinFnIdCeil: 30460 out_val->data.x_f32 = ceilf(op->data.x_f32); 30461 break; 30462 case BuiltinFnIdTrunc: 30463 out_val->data.x_f32 = truncf(op->data.x_f32); 30464 break; 30465 case BuiltinFnIdNearbyInt: 30466 out_val->data.x_f32 = nearbyintf(op->data.x_f32); 30467 break; 30468 case BuiltinFnIdRound: 30469 out_val->data.x_f32 = roundf(op->data.x_f32); 30470 break; 30471 default: 30472 zig_unreachable(); 30473 }; 30474 break; 30475 } 30476 case 64: { 30477 switch (fop) { 30478 case BuiltinFnIdSqrt: 30479 out_val->data.x_f64 = sqrt(op->data.x_f64); 30480 break; 30481 case BuiltinFnIdSin: 30482 out_val->data.x_f64 = sin(op->data.x_f64); 30483 break; 30484 case BuiltinFnIdCos: 30485 out_val->data.x_f64 = cos(op->data.x_f64); 30486 break; 30487 case BuiltinFnIdExp: 30488 out_val->data.x_f64 = exp(op->data.x_f64); 30489 break; 30490 case BuiltinFnIdExp2: 30491 out_val->data.x_f64 = exp2(op->data.x_f64); 30492 break; 30493 case BuiltinFnIdLog: 30494 out_val->data.x_f64 = log(op->data.x_f64); 30495 break; 30496 case BuiltinFnIdLog10: 30497 out_val->data.x_f64 = log10(op->data.x_f64); 30498 break; 30499 case BuiltinFnIdLog2: 30500 out_val->data.x_f64 = log2(op->data.x_f64); 30501 break; 30502 case BuiltinFnIdFabs: 30503 out_val->data.x_f64 = fabs(op->data.x_f64); 30504 break; 30505 case BuiltinFnIdFloor: 30506 out_val->data.x_f64 = floor(op->data.x_f64); 30507 break; 30508 case BuiltinFnIdCeil: 30509 out_val->data.x_f64 = ceil(op->data.x_f64); 30510 break; 30511 case BuiltinFnIdTrunc: 30512 out_val->data.x_f64 = trunc(op->data.x_f64); 30513 break; 30514 case BuiltinFnIdNearbyInt: 30515 out_val->data.x_f64 = nearbyint(op->data.x_f64); 30516 break; 30517 case BuiltinFnIdRound: 30518 out_val->data.x_f64 = round(op->data.x_f64); 30519 break; 30520 default: 30521 zig_unreachable(); 30522 } 30523 break; 30524 } 30525 case 80: 30526 return ir_add_error(ira, source_instr, 30527 buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026", 30528 float_op_to_name(fop), buf_ptr(&float_type->name))); 30529 case 128: { 30530 float128_t *out, *in; 30531 if (float_type->id == ZigTypeIdComptimeFloat) { 30532 out = &out_val->data.x_bigfloat.value; 30533 in = &op->data.x_bigfloat.value; 30534 } else { 30535 out = &out_val->data.x_f128; 30536 in = &op->data.x_f128; 30537 } 30538 switch (fop) { 30539 case BuiltinFnIdSqrt: 30540 f128M_sqrt(in, out); 30541 break; 30542 case BuiltinFnIdFabs: 30543 f128M_abs(in, out); 30544 break; 30545 case BuiltinFnIdFloor: 30546 f128M_roundToInt(in, softfloat_round_min, false, out); 30547 break; 30548 case BuiltinFnIdCeil: 30549 f128M_roundToInt(in, softfloat_round_max, false, out); 30550 break; 30551 case BuiltinFnIdTrunc: 30552 f128M_trunc(in, out); 30553 break; 30554 case BuiltinFnIdRound: 30555 f128M_roundToInt(in, softfloat_round_near_maxMag, false, out); 30556 break; 30557 case BuiltinFnIdNearbyInt: 30558 case BuiltinFnIdSin: 30559 case BuiltinFnIdCos: 30560 case BuiltinFnIdExp: 30561 case BuiltinFnIdExp2: 30562 case BuiltinFnIdLog: 30563 case BuiltinFnIdLog10: 30564 case BuiltinFnIdLog2: 30565 return ir_add_error(ira, source_instr, 30566 buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026", 30567 float_op_to_name(fop), buf_ptr(&float_type->name))); 30568 default: 30569 zig_unreachable(); 30570 } 30571 break; 30572 } 30573 default: 30574 zig_unreachable(); 30575 } 30576 out_val->special = ConstValSpecialStatic; 30577 return nullptr; 30578 } 30579 30580 static IrInstGen *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstSrcFloatOp *instruction) { 30581 IrInstGen *operand = instruction->operand->child; 30582 ZigType *operand_type = operand->value->type; 30583 if (type_is_invalid(operand_type)) 30584 return ira->codegen->invalid_inst_gen; 30585 30586 // This instruction accepts floats and vectors of floats. 30587 ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ? 30588 operand_type->data.vector.elem_type : operand_type; 30589 30590 if (scalar_type->id != ZigTypeIdFloat && scalar_type->id != ZigTypeIdComptimeFloat) { 30591 ir_add_error(ira, &operand->base, 30592 buf_sprintf("expected float type, found '%s'", buf_ptr(&scalar_type->name))); 30593 return ira->codegen->invalid_inst_gen; 30594 } 30595 30596 if (instr_is_comptime(operand)) { 30597 ZigValue *operand_val = ir_resolve_const(ira, operand, UndefOk); 30598 if (operand_val == nullptr) 30599 return ira->codegen->invalid_inst_gen; 30600 if (operand_val->special == ConstValSpecialUndef) 30601 return ir_const_undef(ira, &instruction->base.base, operand_type); 30602 30603 IrInstGen *result = ir_const(ira, &instruction->base.base, operand_type); 30604 ZigValue *out_val = result->value; 30605 30606 if (operand_type->id == ZigTypeIdVector) { 30607 expand_undef_array(ira->codegen, operand_val); 30608 out_val->special = ConstValSpecialUndef; 30609 expand_undef_array(ira->codegen, out_val); 30610 size_t len = operand_type->data.vector.len; 30611 for (size_t i = 0; i < len; i += 1) { 30612 ZigValue *elem_operand = &operand_val->data.x_array.data.s_none.elements[i]; 30613 ZigValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; 30614 ir_assert(elem_operand->type == scalar_type, &instruction->base.base); 30615 ir_assert(float_out_val->type == scalar_type, &instruction->base.base); 30616 ErrorMsg *msg = ir_eval_float_op(ira, &instruction->base.base, instruction->fn_id, scalar_type, 30617 elem_operand, float_out_val); 30618 if (msg != nullptr) { 30619 add_error_note(ira->codegen, msg, instruction->base.base.source_node, 30620 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 30621 return ira->codegen->invalid_inst_gen; 30622 } 30623 float_out_val->type = scalar_type; 30624 } 30625 out_val->type = operand_type; 30626 out_val->special = ConstValSpecialStatic; 30627 } else { 30628 if (ir_eval_float_op(ira, &instruction->base.base, instruction->fn_id, scalar_type, 30629 operand_val, out_val) != nullptr) 30630 { 30631 return ira->codegen->invalid_inst_gen; 30632 } 30633 } 30634 return result; 30635 } 30636 30637 ir_assert(scalar_type->id == ZigTypeIdFloat, &instruction->base.base); 30638 30639 return ir_build_float_op_gen(ira, &instruction->base.base, operand, instruction->fn_id, operand_type); 30640 } 30641 30642 static IrInstGen *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstSrcBswap *instruction) { 30643 Error err; 30644 30645 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 30646 if (type_is_invalid(int_type)) 30647 return ira->codegen->invalid_inst_gen; 30648 30649 IrInstGen *uncasted_op = instruction->op->child; 30650 if (type_is_invalid(uncasted_op->value->type)) 30651 return ira->codegen->invalid_inst_gen; 30652 30653 uint32_t vector_len = UINT32_MAX; // means not a vector 30654 if (uncasted_op->value->type->id == ZigTypeIdArray) { 30655 bool can_be_vec_elem; 30656 if ((err = is_valid_vector_elem_type(ira->codegen, uncasted_op->value->type->data.array.child_type, 30657 &can_be_vec_elem))) 30658 { 30659 return ira->codegen->invalid_inst_gen; 30660 } 30661 if (can_be_vec_elem) { 30662 vector_len = uncasted_op->value->type->data.array.len; 30663 } 30664 } else if (uncasted_op->value->type->id == ZigTypeIdVector) { 30665 vector_len = uncasted_op->value->type->data.vector.len; 30666 } 30667 30668 bool is_vector = (vector_len != UINT32_MAX); 30669 ZigType *op_type = is_vector ? get_vector_type(ira->codegen, vector_len, int_type) : int_type; 30670 30671 IrInstGen *op = ir_implicit_cast(ira, uncasted_op, op_type); 30672 if (type_is_invalid(op->value->type)) 30673 return ira->codegen->invalid_inst_gen; 30674 30675 if (int_type->data.integral.bit_count == 8 || int_type->data.integral.bit_count == 0) 30676 return op; 30677 30678 if (int_type->data.integral.bit_count % 8 != 0) { 30679 ir_add_error(ira, &instruction->op->base, 30680 buf_sprintf("@byteSwap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8", 30681 buf_ptr(&int_type->name), int_type->data.integral.bit_count)); 30682 return ira->codegen->invalid_inst_gen; 30683 } 30684 30685 if (instr_is_comptime(op)) { 30686 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 30687 if (val == nullptr) 30688 return ira->codegen->invalid_inst_gen; 30689 if (val->special == ConstValSpecialUndef) 30690 return ir_const_undef(ira, &instruction->base.base, op_type); 30691 30692 IrInstGen *result = ir_const(ira, &instruction->base.base, op_type); 30693 const size_t buf_size = int_type->data.integral.bit_count / 8; 30694 uint8_t *buf = heap::c_allocator.allocate_nonzero<uint8_t>(buf_size); 30695 if (is_vector) { 30696 expand_undef_array(ira->codegen, val); 30697 result->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(op_type->data.vector.len); 30698 for (unsigned i = 0; i < op_type->data.vector.len; i += 1) { 30699 ZigValue *op_elem_val = &val->data.x_array.data.s_none.elements[i]; 30700 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, instruction->base.base.source_node, 30701 op_elem_val, UndefOk))) 30702 { 30703 return ira->codegen->invalid_inst_gen; 30704 } 30705 ZigValue *result_elem_val = &result->value->data.x_array.data.s_none.elements[i]; 30706 result_elem_val->type = int_type; 30707 result_elem_val->special = op_elem_val->special; 30708 if (op_elem_val->special == ConstValSpecialUndef) 30709 continue; 30710 30711 bigint_write_twos_complement(&op_elem_val->data.x_bigint, buf, int_type->data.integral.bit_count, true); 30712 bigint_read_twos_complement(&result->value->data.x_array.data.s_none.elements[i].data.x_bigint, 30713 buf, int_type->data.integral.bit_count, false, 30714 int_type->data.integral.is_signed); 30715 } 30716 } else { 30717 bigint_write_twos_complement(&val->data.x_bigint, buf, int_type->data.integral.bit_count, true); 30718 bigint_read_twos_complement(&result->value->data.x_bigint, buf, int_type->data.integral.bit_count, false, 30719 int_type->data.integral.is_signed); 30720 } 30721 heap::c_allocator.deallocate(buf, buf_size); 30722 return result; 30723 } 30724 30725 return ir_build_bswap_gen(ira, &instruction->base.base, op_type, op); 30726 } 30727 30728 static IrInstGen *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstSrcBitReverse *instruction) { 30729 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 30730 if (type_is_invalid(int_type)) 30731 return ira->codegen->invalid_inst_gen; 30732 30733 IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); 30734 if (type_is_invalid(op->value->type)) 30735 return ira->codegen->invalid_inst_gen; 30736 30737 if (int_type->data.integral.bit_count == 0) { 30738 IrInstGen *result = ir_const(ira, &instruction->base.base, int_type); 30739 bigint_init_unsigned(&result->value->data.x_bigint, 0); 30740 return result; 30741 } 30742 30743 if (instr_is_comptime(op)) { 30744 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 30745 if (val == nullptr) 30746 return ira->codegen->invalid_inst_gen; 30747 if (val->special == ConstValSpecialUndef) 30748 return ir_const_undef(ira, &instruction->base.base, int_type); 30749 30750 IrInstGen *result = ir_const(ira, &instruction->base.base, int_type); 30751 size_t num_bits = int_type->data.integral.bit_count; 30752 size_t buf_size = (num_bits + 7) / 8; 30753 uint8_t *comptime_buf = heap::c_allocator.allocate_nonzero<uint8_t>(buf_size); 30754 uint8_t *result_buf = heap::c_allocator.allocate_nonzero<uint8_t>(buf_size); 30755 memset(comptime_buf,0,buf_size); 30756 memset(result_buf,0,buf_size); 30757 30758 bigint_write_twos_complement(&val->data.x_bigint,comptime_buf,num_bits,ira->codegen->is_big_endian); 30759 30760 size_t bit_i = 0; 30761 size_t bit_rev_i = num_bits - 1; 30762 for (; bit_i < num_bits; bit_i++, bit_rev_i--) { 30763 if (comptime_buf[bit_i / 8] & (1 << (bit_i % 8))) { 30764 result_buf[bit_rev_i / 8] |= (1 << (bit_rev_i % 8)); 30765 } 30766 } 30767 30768 bigint_read_twos_complement(&result->value->data.x_bigint, 30769 result_buf, 30770 int_type->data.integral.bit_count, 30771 ira->codegen->is_big_endian, 30772 int_type->data.integral.is_signed); 30773 30774 return result; 30775 } 30776 30777 return ir_build_bit_reverse_gen(ira, &instruction->base.base, int_type, op); 30778 } 30779 30780 30781 static IrInstGen *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstSrcEnumToInt *instruction) { 30782 IrInstGen *target = instruction->target->child; 30783 if (type_is_invalid(target->value->type)) 30784 return ira->codegen->invalid_inst_gen; 30785 30786 return ir_analyze_enum_to_int(ira, &instruction->base.base, target); 30787 } 30788 30789 static IrInstGen *ir_analyze_instruction_int_to_enum(IrAnalyze *ira, IrInstSrcIntToEnum *instruction) { 30790 Error err; 30791 IrInstGen *dest_type_value = instruction->dest_type->child; 30792 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 30793 if (type_is_invalid(dest_type)) 30794 return ira->codegen->invalid_inst_gen; 30795 30796 if (dest_type->id != ZigTypeIdEnum) { 30797 ir_add_error(ira, &instruction->dest_type->base, 30798 buf_sprintf("expected enum, found type '%s'", buf_ptr(&dest_type->name))); 30799 return ira->codegen->invalid_inst_gen; 30800 } 30801 30802 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 30803 return ira->codegen->invalid_inst_gen; 30804 30805 ZigType *tag_type = dest_type->data.enumeration.tag_int_type; 30806 30807 IrInstGen *target = instruction->target->child; 30808 if (type_is_invalid(target->value->type)) 30809 return ira->codegen->invalid_inst_gen; 30810 30811 IrInstGen *casted_target = ir_implicit_cast(ira, target, tag_type); 30812 if (type_is_invalid(casted_target->value->type)) 30813 return ira->codegen->invalid_inst_gen; 30814 30815 return ir_analyze_int_to_enum(ira, &instruction->base.base, casted_target, dest_type); 30816 } 30817 30818 static IrInstGen *ir_analyze_instruction_check_runtime_scope(IrAnalyze *ira, IrInstSrcCheckRuntimeScope *instruction) { 30819 IrInstGen *block_comptime_inst = instruction->scope_is_comptime->child; 30820 bool scope_is_comptime; 30821 if (!ir_resolve_bool(ira, block_comptime_inst, &scope_is_comptime)) 30822 return ira->codegen->invalid_inst_gen; 30823 30824 IrInstGen *is_comptime_inst = instruction->is_comptime->child; 30825 bool is_comptime; 30826 if (!ir_resolve_bool(ira, is_comptime_inst, &is_comptime)) 30827 return ira->codegen->invalid_inst_gen; 30828 30829 if (!scope_is_comptime && is_comptime) { 30830 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 30831 buf_sprintf("comptime control flow inside runtime block")); 30832 add_error_note(ira->codegen, msg, block_comptime_inst->base.source_node, 30833 buf_sprintf("runtime block created here")); 30834 return ira->codegen->invalid_inst_gen; 30835 } 30836 30837 return ir_const_void(ira, &instruction->base.base); 30838 } 30839 30840 static IrInstGen *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstSrcHasDecl *instruction) { 30841 ZigType *container_type = ir_resolve_type(ira, instruction->container->child); 30842 if (type_is_invalid(container_type)) 30843 return ira->codegen->invalid_inst_gen; 30844 30845 Buf *name = ir_resolve_str(ira, instruction->name->child); 30846 if (name == nullptr) 30847 return ira->codegen->invalid_inst_gen; 30848 30849 if (!is_container(container_type)) { 30850 ir_add_error(ira, &instruction->container->base, 30851 buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&container_type->name))); 30852 return ira->codegen->invalid_inst_gen; 30853 } 30854 30855 ScopeDecls *container_scope = get_container_scope(container_type); 30856 Tld *tld = find_container_decl(ira->codegen, container_scope, name); 30857 if (tld == nullptr) 30858 return ir_const_bool(ira, &instruction->base.base, false); 30859 30860 if (tld->visib_mod == VisibModPrivate && tld->import != get_scope_import(instruction->base.base.scope)) { 30861 return ir_const_bool(ira, &instruction->base.base, false); 30862 } 30863 30864 return ir_const_bool(ira, &instruction->base.base, true); 30865 } 30866 30867 static IrInstGen *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, IrInstSrcUndeclaredIdent *instruction) { 30868 // put a variable of same name with invalid type in global scope 30869 // so that future references to this same name will find a variable with an invalid type 30870 populate_invalid_variable_in_scope(ira->codegen, instruction->base.base.scope, 30871 instruction->base.base.source_node, instruction->name); 30872 ir_add_error(ira, &instruction->base.base, 30873 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(instruction->name))); 30874 return ira->codegen->invalid_inst_gen; 30875 } 30876 30877 static IrInstGen *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstSrcEndExpr *instruction) { 30878 IrInstGen *value = instruction->value->child; 30879 if (type_is_invalid(value->value->type)) 30880 return ira->codegen->invalid_inst_gen; 30881 30882 bool was_written = instruction->result_loc->written; 30883 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 30884 value->value->type, value, false, true); 30885 if (result_loc != nullptr) { 30886 if (type_is_invalid(result_loc->value->type)) 30887 return ira->codegen->invalid_inst_gen; 30888 if (result_loc->value->type->id == ZigTypeIdUnreachable) 30889 return result_loc; 30890 30891 if (!was_written || instruction->result_loc->id == ResultLocIdPeer) { 30892 IrInstGen *store_ptr = ir_analyze_store_ptr(ira, &instruction->base.base, result_loc, value, 30893 instruction->result_loc->allow_write_through_const); 30894 if (type_is_invalid(store_ptr->value->type)) { 30895 return ira->codegen->invalid_inst_gen; 30896 } 30897 } 30898 30899 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer && 30900 instruction->result_loc->id != ResultLocIdPeer) 30901 { 30902 if (instr_is_comptime(value)) { 30903 result_loc->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 30904 } else { 30905 result_loc->value->special = ConstValSpecialRuntime; 30906 } 30907 } 30908 } 30909 30910 return ir_const_void(ira, &instruction->base.base); 30911 } 30912 30913 static IrInstGen *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstSrcImplicitCast *instruction) { 30914 IrInstGen *operand = instruction->operand->child; 30915 if (type_is_invalid(operand->value->type)) 30916 return operand; 30917 30918 ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child); 30919 if (type_is_invalid(dest_type)) 30920 return ira->codegen->invalid_inst_gen; 30921 return ir_implicit_cast2(ira, &instruction->base.base, operand, dest_type); 30922 } 30923 30924 static IrInstGen *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstSrcBitCast *instruction) { 30925 IrInstGen *operand = instruction->operand->child; 30926 if (type_is_invalid(operand->value->type)) 30927 return operand; 30928 30929 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, 30930 &instruction->result_loc_bit_cast->base, operand->value->type, operand, false, true); 30931 if (result_loc != nullptr && 30932 (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) 30933 { 30934 return result_loc; 30935 } 30936 30937 ZigType *dest_type = ir_resolve_type(ira, 30938 instruction->result_loc_bit_cast->base.source_instruction->child); 30939 if (type_is_invalid(dest_type)) 30940 return ira->codegen->invalid_inst_gen; 30941 return ir_analyze_bit_cast(ira, &instruction->base.base, operand, dest_type); 30942 } 30943 30944 static IrInstGen *ir_analyze_instruction_union_init_named_field(IrAnalyze *ira, 30945 IrInstSrcUnionInitNamedField *instruction) 30946 { 30947 ZigType *union_type = ir_resolve_type(ira, instruction->union_type->child); 30948 if (type_is_invalid(union_type)) 30949 return ira->codegen->invalid_inst_gen; 30950 30951 if (union_type->id != ZigTypeIdUnion) { 30952 ir_add_error(ira, &instruction->union_type->base, 30953 buf_sprintf("non-union type '%s' passed to @unionInit", buf_ptr(&union_type->name))); 30954 return ira->codegen->invalid_inst_gen; 30955 } 30956 30957 Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); 30958 if (field_name == nullptr) 30959 return ira->codegen->invalid_inst_gen; 30960 30961 IrInstGen *field_result_loc = instruction->field_result_loc->child; 30962 if (type_is_invalid(field_result_loc->value->type)) 30963 return ira->codegen->invalid_inst_gen; 30964 30965 IrInstGen *result_loc = instruction->result_loc->child; 30966 if (type_is_invalid(result_loc->value->type)) 30967 return ira->codegen->invalid_inst_gen; 30968 30969 return ir_analyze_union_init(ira, &instruction->base.base, instruction->base.base.source_node, 30970 union_type, field_name, field_result_loc, result_loc); 30971 } 30972 30973 static IrInstGen *ir_analyze_instruction_suspend_begin(IrAnalyze *ira, IrInstSrcSuspendBegin *instruction) { 30974 return ir_build_suspend_begin_gen(ira, &instruction->base.base); 30975 } 30976 30977 static IrInstGen *ir_analyze_instruction_suspend_finish(IrAnalyze *ira, IrInstSrcSuspendFinish *instruction) { 30978 IrInstGen *begin_base = instruction->begin->base.child; 30979 if (type_is_invalid(begin_base->value->type)) 30980 return ira->codegen->invalid_inst_gen; 30981 ir_assert(begin_base->id == IrInstGenIdSuspendBegin, &instruction->base.base); 30982 IrInstGenSuspendBegin *begin = reinterpret_cast<IrInstGenSuspendBegin *>(begin_base); 30983 30984 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 30985 ir_assert(fn_entry != nullptr, &instruction->base.base); 30986 30987 if (fn_entry->inferred_async_node == nullptr) { 30988 fn_entry->inferred_async_node = instruction->base.base.source_node; 30989 } 30990 30991 return ir_build_suspend_finish_gen(ira, &instruction->base.base, begin); 30992 } 30993 30994 static IrInstGen *analyze_frame_ptr_to_anyframe_T(IrAnalyze *ira, IrInst* source_instr, 30995 IrInstGen *frame_ptr, ZigFn **target_fn) 30996 { 30997 if (type_is_invalid(frame_ptr->value->type)) 30998 return ira->codegen->invalid_inst_gen; 30999 31000 *target_fn = nullptr; 31001 31002 ZigType *result_type; 31003 IrInstGen *frame; 31004 if (frame_ptr->value->type->id == ZigTypeIdPointer && 31005 frame_ptr->value->type->data.pointer.ptr_len == PtrLenSingle && 31006 frame_ptr->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 31007 { 31008 ZigFn *func = frame_ptr->value->type->data.pointer.child_type->data.frame.fn; 31009 result_type = func->type_entry->data.fn.fn_type_id.return_type; 31010 *target_fn = func; 31011 frame = frame_ptr; 31012 } else { 31013 frame = ir_get_deref(ira, source_instr, frame_ptr, nullptr); 31014 if (frame->value->type->id == ZigTypeIdPointer && 31015 frame->value->type->data.pointer.ptr_len == PtrLenSingle && 31016 frame->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 31017 { 31018 ZigFn *func = frame->value->type->data.pointer.child_type->data.frame.fn; 31019 result_type = func->type_entry->data.fn.fn_type_id.return_type; 31020 *target_fn = func; 31021 } else if (frame->value->type->id != ZigTypeIdAnyFrame || 31022 frame->value->type->data.any_frame.result_type == nullptr) 31023 { 31024 ir_add_error(ira, source_instr, 31025 buf_sprintf("expected anyframe->T, found '%s'", buf_ptr(&frame->value->type->name))); 31026 return ira->codegen->invalid_inst_gen; 31027 } else { 31028 result_type = frame->value->type->data.any_frame.result_type; 31029 } 31030 } 31031 31032 ZigType *any_frame_type = get_any_frame_type(ira->codegen, result_type); 31033 IrInstGen *casted_frame = ir_implicit_cast(ira, frame, any_frame_type); 31034 if (type_is_invalid(casted_frame->value->type)) 31035 return ira->codegen->invalid_inst_gen; 31036 31037 return casted_frame; 31038 } 31039 31040 static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *instruction) { 31041 IrInstGen *operand = instruction->frame->child; 31042 if (type_is_invalid(operand->value->type)) 31043 return ira->codegen->invalid_inst_gen; 31044 ZigFn *target_fn; 31045 IrInstGen *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base.base, operand, &target_fn); 31046 if (type_is_invalid(frame->value->type)) 31047 return ira->codegen->invalid_inst_gen; 31048 31049 ZigType *result_type = frame->value->type->data.any_frame.result_type; 31050 31051 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 31052 ir_assert(fn_entry != nullptr, &instruction->base.base); 31053 31054 // If it's not @Frame(func) then it's definitely a suspend point 31055 if (target_fn == nullptr && !instruction->is_nosuspend) { 31056 if (fn_entry->inferred_async_node == nullptr) { 31057 fn_entry->inferred_async_node = instruction->base.base.source_node; 31058 } 31059 } 31060 31061 if (type_can_fail(result_type)) { 31062 fn_entry->calls_or_awaits_errorable_fn = true; 31063 } 31064 31065 IrInstGen *result_loc; 31066 if (type_has_bits(ira->codegen, result_type)) { 31067 result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 31068 result_type, nullptr, true, true); 31069 if (result_loc != nullptr && 31070 (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) 31071 { 31072 return result_loc; 31073 } 31074 } else { 31075 result_loc = nullptr; 31076 } 31077 31078 IrInstGenAwait *result = ir_build_await_gen(ira, &instruction->base.base, frame, result_type, result_loc, 31079 instruction->is_nosuspend); 31080 result->target_fn = target_fn; 31081 fn_entry->await_list.append(result); 31082 return ir_finish_anal(ira, &result->base); 31083 } 31084 31085 static IrInstGen *ir_analyze_instruction_resume(IrAnalyze *ira, IrInstSrcResume *instruction) { 31086 IrInstGen *frame_ptr = instruction->frame->child; 31087 if (type_is_invalid(frame_ptr->value->type)) 31088 return ira->codegen->invalid_inst_gen; 31089 31090 IrInstGen *frame; 31091 if (frame_ptr->value->type->id == ZigTypeIdPointer && 31092 frame_ptr->value->type->data.pointer.ptr_len == PtrLenSingle && 31093 frame_ptr->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 31094 { 31095 frame = frame_ptr; 31096 } else { 31097 frame = ir_get_deref(ira, &instruction->base.base, frame_ptr, nullptr); 31098 } 31099 31100 ZigType *any_frame_type = get_any_frame_type(ira->codegen, nullptr); 31101 IrInstGen *casted_frame = ir_implicit_cast2(ira, &instruction->frame->base, frame, any_frame_type); 31102 if (type_is_invalid(casted_frame->value->type)) 31103 return ira->codegen->invalid_inst_gen; 31104 31105 return ir_build_resume_gen(ira, &instruction->base.base, casted_frame); 31106 } 31107 31108 static IrInstGen *ir_analyze_instruction_spill_begin(IrAnalyze *ira, IrInstSrcSpillBegin *instruction) { 31109 if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope)) 31110 return ir_const_void(ira, &instruction->base.base); 31111 31112 IrInstGen *operand = instruction->operand->child; 31113 if (type_is_invalid(operand->value->type)) 31114 return ira->codegen->invalid_inst_gen; 31115 31116 if (!type_has_bits(ira->codegen, operand->value->type)) 31117 return ir_const_void(ira, &instruction->base.base); 31118 31119 switch (instruction->spill_id) { 31120 case SpillIdInvalid: 31121 zig_unreachable(); 31122 case SpillIdRetErrCode: 31123 ira->new_irb.exec->need_err_code_spill = true; 31124 break; 31125 } 31126 31127 return ir_build_spill_begin_gen(ira, &instruction->base.base, operand, instruction->spill_id); 31128 } 31129 31130 static IrInstGen *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstSrcSpillEnd *instruction) { 31131 IrInstGen *operand = instruction->begin->operand->child; 31132 if (type_is_invalid(operand->value->type)) 31133 return ira->codegen->invalid_inst_gen; 31134 31135 if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope) || 31136 !type_has_bits(ira->codegen, operand->value->type) || 31137 instr_is_comptime(operand)) 31138 { 31139 return operand; 31140 } 31141 31142 ir_assert(instruction->begin->base.child->id == IrInstGenIdSpillBegin, &instruction->base.base); 31143 IrInstGenSpillBegin *begin = reinterpret_cast<IrInstGenSpillBegin *>(instruction->begin->base.child); 31144 31145 return ir_build_spill_end_gen(ira, &instruction->base.base, begin, operand->value->type); 31146 } 31147 31148 static IrInstGen *ir_analyze_instruction_src(IrAnalyze *ira, IrInstSrcSrc *instruction) { 31149 ZigFn *fn_entry = scope_fn_entry(instruction->base.base.scope); 31150 if (fn_entry == nullptr) { 31151 ir_add_error(ira, &instruction->base.base, buf_sprintf("@src outside function")); 31152 return ira->codegen->invalid_inst_gen; 31153 } 31154 31155 ZigType *u8_ptr = get_pointer_to_type_extra2( 31156 ira->codegen, ira->codegen->builtin_types.entry_u8, 31157 true, false, PtrLenUnknown, 31158 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr, ira->codegen->intern.for_zero_byte()); 31159 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 31160 31161 ZigType *source_location_type = get_builtin_type(ira->codegen, "SourceLocation"); 31162 if (type_resolve(ira->codegen, source_location_type, ResolveStatusSizeKnown)) { 31163 zig_unreachable(); 31164 } 31165 31166 ZigValue *result = ira->codegen->pass1_arena->create<ZigValue>(); 31167 result->special = ConstValSpecialStatic; 31168 result->type = source_location_type; 31169 31170 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 4); 31171 result->data.x_struct.fields = fields; 31172 31173 // file: [:0]const u8 31174 ensure_field_index(source_location_type, "file", 0); 31175 fields[0]->special = ConstValSpecialStatic; 31176 31177 ZigType *import = instruction->base.base.source_node->owner; 31178 Buf *path = import->data.structure.root_struct->path; 31179 ZigValue *file_name = create_const_str_lit(ira->codegen, path)->data.x_ptr.data.ref.pointee; 31180 init_const_slice(ira->codegen, fields[0], file_name, 0, buf_len(path), true); 31181 fields[0]->type = u8_slice; 31182 31183 // fn_name: [:0]const u8 31184 ensure_field_index(source_location_type, "fn_name", 1); 31185 fields[1]->special = ConstValSpecialStatic; 31186 31187 ZigValue *fn_name = create_const_str_lit(ira->codegen, &fn_entry->symbol_name)->data.x_ptr.data.ref.pointee; 31188 init_const_slice(ira->codegen, fields[1], fn_name, 0, buf_len(&fn_entry->symbol_name), true); 31189 fields[1]->type = u8_slice; 31190 31191 // line: u32 31192 ensure_field_index(source_location_type, "line", 2); 31193 fields[2]->special = ConstValSpecialStatic; 31194 fields[2]->type = ira->codegen->builtin_types.entry_u32; 31195 bigint_init_unsigned(&fields[2]->data.x_bigint, instruction->base.base.source_node->line + 1); 31196 31197 // column: u32 31198 ensure_field_index(source_location_type, "column", 3); 31199 fields[3]->special = ConstValSpecialStatic; 31200 fields[3]->type = ira->codegen->builtin_types.entry_u32; 31201 bigint_init_unsigned(&fields[3]->data.x_bigint, instruction->base.base.source_node->column + 1); 31202 31203 return ir_const_move(ira, &instruction->base.base, result); 31204 } 31205 31206 static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruction) { 31207 switch (instruction->id) { 31208 case IrInstSrcIdInvalid: 31209 zig_unreachable(); 31210 31211 case IrInstSrcIdReturn: 31212 return ir_analyze_instruction_return(ira, (IrInstSrcReturn *)instruction); 31213 case IrInstSrcIdConst: 31214 return ir_analyze_instruction_const(ira, (IrInstSrcConst *)instruction); 31215 case IrInstSrcIdUnOp: 31216 return ir_analyze_instruction_un_op(ira, (IrInstSrcUnOp *)instruction); 31217 case IrInstSrcIdBinOp: 31218 return ir_analyze_instruction_bin_op(ira, (IrInstSrcBinOp *)instruction); 31219 case IrInstSrcIdMergeErrSets: 31220 return ir_analyze_instruction_merge_err_sets(ira, (IrInstSrcMergeErrSets *)instruction); 31221 case IrInstSrcIdDeclVar: 31222 return ir_analyze_instruction_decl_var(ira, (IrInstSrcDeclVar *)instruction); 31223 case IrInstSrcIdLoadPtr: 31224 return ir_analyze_instruction_load_ptr(ira, (IrInstSrcLoadPtr *)instruction); 31225 case IrInstSrcIdStorePtr: 31226 return ir_analyze_instruction_store_ptr(ira, (IrInstSrcStorePtr *)instruction); 31227 case IrInstSrcIdElemPtr: 31228 return ir_analyze_instruction_elem_ptr(ira, (IrInstSrcElemPtr *)instruction); 31229 case IrInstSrcIdVarPtr: 31230 return ir_analyze_instruction_var_ptr(ira, (IrInstSrcVarPtr *)instruction); 31231 case IrInstSrcIdFieldPtr: 31232 return ir_analyze_instruction_field_ptr(ira, (IrInstSrcFieldPtr *)instruction); 31233 case IrInstSrcIdCall: 31234 return ir_analyze_instruction_call(ira, (IrInstSrcCall *)instruction); 31235 case IrInstSrcIdCallArgs: 31236 return ir_analyze_instruction_call_args(ira, (IrInstSrcCallArgs *)instruction); 31237 case IrInstSrcIdCallExtra: 31238 return ir_analyze_instruction_call_extra(ira, (IrInstSrcCallExtra *)instruction); 31239 case IrInstSrcIdAsyncCallExtra: 31240 return ir_analyze_instruction_async_call_extra(ira, (IrInstSrcAsyncCallExtra *)instruction); 31241 case IrInstSrcIdBr: 31242 return ir_analyze_instruction_br(ira, (IrInstSrcBr *)instruction); 31243 case IrInstSrcIdCondBr: 31244 return ir_analyze_instruction_cond_br(ira, (IrInstSrcCondBr *)instruction); 31245 case IrInstSrcIdUnreachable: 31246 return ir_analyze_instruction_unreachable(ira, (IrInstSrcUnreachable *)instruction); 31247 case IrInstSrcIdPhi: 31248 return ir_analyze_instruction_phi(ira, (IrInstSrcPhi *)instruction); 31249 case IrInstSrcIdTypeOf: 31250 return ir_analyze_instruction_typeof(ira, (IrInstSrcTypeOf *)instruction); 31251 case IrInstSrcIdSetCold: 31252 return ir_analyze_instruction_set_cold(ira, (IrInstSrcSetCold *)instruction); 31253 case IrInstSrcIdSetRuntimeSafety: 31254 return ir_analyze_instruction_set_runtime_safety(ira, (IrInstSrcSetRuntimeSafety *)instruction); 31255 case IrInstSrcIdSetFloatMode: 31256 return ir_analyze_instruction_set_float_mode(ira, (IrInstSrcSetFloatMode *)instruction); 31257 case IrInstSrcIdAnyFrameType: 31258 return ir_analyze_instruction_any_frame_type(ira, (IrInstSrcAnyFrameType *)instruction); 31259 case IrInstSrcIdSliceType: 31260 return ir_analyze_instruction_slice_type(ira, (IrInstSrcSliceType *)instruction); 31261 case IrInstSrcIdAsm: 31262 return ir_analyze_instruction_asm(ira, (IrInstSrcAsm *)instruction); 31263 case IrInstSrcIdArrayType: 31264 return ir_analyze_instruction_array_type(ira, (IrInstSrcArrayType *)instruction); 31265 case IrInstSrcIdSizeOf: 31266 return ir_analyze_instruction_size_of(ira, (IrInstSrcSizeOf *)instruction); 31267 case IrInstSrcIdTestNonNull: 31268 return ir_analyze_instruction_test_non_null(ira, (IrInstSrcTestNonNull *)instruction); 31269 case IrInstSrcIdOptionalUnwrapPtr: 31270 return ir_analyze_instruction_optional_unwrap_ptr(ira, (IrInstSrcOptionalUnwrapPtr *)instruction); 31271 case IrInstSrcIdClz: 31272 return ir_analyze_instruction_clz(ira, (IrInstSrcClz *)instruction); 31273 case IrInstSrcIdCtz: 31274 return ir_analyze_instruction_ctz(ira, (IrInstSrcCtz *)instruction); 31275 case IrInstSrcIdPopCount: 31276 return ir_analyze_instruction_pop_count(ira, (IrInstSrcPopCount *)instruction); 31277 case IrInstSrcIdBswap: 31278 return ir_analyze_instruction_bswap(ira, (IrInstSrcBswap *)instruction); 31279 case IrInstSrcIdBitReverse: 31280 return ir_analyze_instruction_bit_reverse(ira, (IrInstSrcBitReverse *)instruction); 31281 case IrInstSrcIdSwitchBr: 31282 return ir_analyze_instruction_switch_br(ira, (IrInstSrcSwitchBr *)instruction); 31283 case IrInstSrcIdSwitchTarget: 31284 return ir_analyze_instruction_switch_target(ira, (IrInstSrcSwitchTarget *)instruction); 31285 case IrInstSrcIdSwitchVar: 31286 return ir_analyze_instruction_switch_var(ira, (IrInstSrcSwitchVar *)instruction); 31287 case IrInstSrcIdSwitchElseVar: 31288 return ir_analyze_instruction_switch_else_var(ira, (IrInstSrcSwitchElseVar *)instruction); 31289 case IrInstSrcIdImport: 31290 return ir_analyze_instruction_import(ira, (IrInstSrcImport *)instruction); 31291 case IrInstSrcIdRef: 31292 return ir_analyze_instruction_ref(ira, (IrInstSrcRef *)instruction); 31293 case IrInstSrcIdContainerInitList: 31294 return ir_analyze_instruction_container_init_list(ira, (IrInstSrcContainerInitList *)instruction); 31295 case IrInstSrcIdContainerInitFields: 31296 return ir_analyze_instruction_container_init_fields(ira, (IrInstSrcContainerInitFields *)instruction); 31297 case IrInstSrcIdCompileErr: 31298 return ir_analyze_instruction_compile_err(ira, (IrInstSrcCompileErr *)instruction); 31299 case IrInstSrcIdCompileLog: 31300 return ir_analyze_instruction_compile_log(ira, (IrInstSrcCompileLog *)instruction); 31301 case IrInstSrcIdErrName: 31302 return ir_analyze_instruction_err_name(ira, (IrInstSrcErrName *)instruction); 31303 case IrInstSrcIdTypeName: 31304 return ir_analyze_instruction_type_name(ira, (IrInstSrcTypeName *)instruction); 31305 case IrInstSrcIdCImport: 31306 return ir_analyze_instruction_c_import(ira, (IrInstSrcCImport *)instruction); 31307 case IrInstSrcIdCInclude: 31308 return ir_analyze_instruction_c_include(ira, (IrInstSrcCInclude *)instruction); 31309 case IrInstSrcIdCDefine: 31310 return ir_analyze_instruction_c_define(ira, (IrInstSrcCDefine *)instruction); 31311 case IrInstSrcIdCUndef: 31312 return ir_analyze_instruction_c_undef(ira, (IrInstSrcCUndef *)instruction); 31313 case IrInstSrcIdEmbedFile: 31314 return ir_analyze_instruction_embed_file(ira, (IrInstSrcEmbedFile *)instruction); 31315 case IrInstSrcIdCmpxchg: 31316 return ir_analyze_instruction_cmpxchg(ira, (IrInstSrcCmpxchg *)instruction); 31317 case IrInstSrcIdFence: 31318 return ir_analyze_instruction_fence(ira, (IrInstSrcFence *)instruction); 31319 case IrInstSrcIdTruncate: 31320 return ir_analyze_instruction_truncate(ira, (IrInstSrcTruncate *)instruction); 31321 case IrInstSrcIdIntCast: 31322 return ir_analyze_instruction_int_cast(ira, (IrInstSrcIntCast *)instruction); 31323 case IrInstSrcIdFloatCast: 31324 return ir_analyze_instruction_float_cast(ira, (IrInstSrcFloatCast *)instruction); 31325 case IrInstSrcIdErrSetCast: 31326 return ir_analyze_instruction_err_set_cast(ira, (IrInstSrcErrSetCast *)instruction); 31327 case IrInstSrcIdIntToFloat: 31328 return ir_analyze_instruction_int_to_float(ira, (IrInstSrcIntToFloat *)instruction); 31329 case IrInstSrcIdFloatToInt: 31330 return ir_analyze_instruction_float_to_int(ira, (IrInstSrcFloatToInt *)instruction); 31331 case IrInstSrcIdBoolToInt: 31332 return ir_analyze_instruction_bool_to_int(ira, (IrInstSrcBoolToInt *)instruction); 31333 case IrInstSrcIdVectorType: 31334 return ir_analyze_instruction_vector_type(ira, (IrInstSrcVectorType *)instruction); 31335 case IrInstSrcIdShuffleVector: 31336 return ir_analyze_instruction_shuffle_vector(ira, (IrInstSrcShuffleVector *)instruction); 31337 case IrInstSrcIdSplat: 31338 return ir_analyze_instruction_splat(ira, (IrInstSrcSplat *)instruction); 31339 case IrInstSrcIdBoolNot: 31340 return ir_analyze_instruction_bool_not(ira, (IrInstSrcBoolNot *)instruction); 31341 case IrInstSrcIdMemset: 31342 return ir_analyze_instruction_memset(ira, (IrInstSrcMemset *)instruction); 31343 case IrInstSrcIdMemcpy: 31344 return ir_analyze_instruction_memcpy(ira, (IrInstSrcMemcpy *)instruction); 31345 case IrInstSrcIdSlice: 31346 return ir_analyze_instruction_slice(ira, (IrInstSrcSlice *)instruction); 31347 case IrInstSrcIdBreakpoint: 31348 return ir_analyze_instruction_breakpoint(ira, (IrInstSrcBreakpoint *)instruction); 31349 case IrInstSrcIdReturnAddress: 31350 return ir_analyze_instruction_return_address(ira, (IrInstSrcReturnAddress *)instruction); 31351 case IrInstSrcIdFrameAddress: 31352 return ir_analyze_instruction_frame_address(ira, (IrInstSrcFrameAddress *)instruction); 31353 case IrInstSrcIdFrameHandle: 31354 return ir_analyze_instruction_frame_handle(ira, (IrInstSrcFrameHandle *)instruction); 31355 case IrInstSrcIdFrameType: 31356 return ir_analyze_instruction_frame_type(ira, (IrInstSrcFrameType *)instruction); 31357 case IrInstSrcIdFrameSize: 31358 return ir_analyze_instruction_frame_size(ira, (IrInstSrcFrameSize *)instruction); 31359 case IrInstSrcIdAlignOf: 31360 return ir_analyze_instruction_align_of(ira, (IrInstSrcAlignOf *)instruction); 31361 case IrInstSrcIdOverflowOp: 31362 return ir_analyze_instruction_overflow_op(ira, (IrInstSrcOverflowOp *)instruction); 31363 case IrInstSrcIdTestErr: 31364 return ir_analyze_instruction_test_err(ira, (IrInstSrcTestErr *)instruction); 31365 case IrInstSrcIdUnwrapErrCode: 31366 return ir_analyze_instruction_unwrap_err_code(ira, (IrInstSrcUnwrapErrCode *)instruction); 31367 case IrInstSrcIdUnwrapErrPayload: 31368 return ir_analyze_instruction_unwrap_err_payload(ira, (IrInstSrcUnwrapErrPayload *)instruction); 31369 case IrInstSrcIdFnProto: 31370 return ir_analyze_instruction_fn_proto(ira, (IrInstSrcFnProto *)instruction); 31371 case IrInstSrcIdTestComptime: 31372 return ir_analyze_instruction_test_comptime(ira, (IrInstSrcTestComptime *)instruction); 31373 case IrInstSrcIdCheckSwitchProngs: 31374 return ir_analyze_instruction_check_switch_prongs(ira, (IrInstSrcCheckSwitchProngs *)instruction); 31375 case IrInstSrcIdCheckStatementIsVoid: 31376 return ir_analyze_instruction_check_statement_is_void(ira, (IrInstSrcCheckStatementIsVoid *)instruction); 31377 case IrInstSrcIdDeclRef: 31378 return ir_analyze_instruction_decl_ref(ira, (IrInstSrcDeclRef *)instruction); 31379 case IrInstSrcIdPanic: 31380 return ir_analyze_instruction_panic(ira, (IrInstSrcPanic *)instruction); 31381 case IrInstSrcIdPtrCast: 31382 return ir_analyze_instruction_ptr_cast(ira, (IrInstSrcPtrCast *)instruction); 31383 case IrInstSrcIdIntToPtr: 31384 return ir_analyze_instruction_int_to_ptr(ira, (IrInstSrcIntToPtr *)instruction); 31385 case IrInstSrcIdPtrToInt: 31386 return ir_analyze_instruction_ptr_to_int(ira, (IrInstSrcPtrToInt *)instruction); 31387 case IrInstSrcIdTagName: 31388 return ir_analyze_instruction_enum_tag_name(ira, (IrInstSrcTagName *)instruction); 31389 case IrInstSrcIdFieldParentPtr: 31390 return ir_analyze_instruction_field_parent_ptr(ira, (IrInstSrcFieldParentPtr *)instruction); 31391 case IrInstSrcIdByteOffsetOf: 31392 return ir_analyze_instruction_byte_offset_of(ira, (IrInstSrcByteOffsetOf *)instruction); 31393 case IrInstSrcIdBitOffsetOf: 31394 return ir_analyze_instruction_bit_offset_of(ira, (IrInstSrcBitOffsetOf *)instruction); 31395 case IrInstSrcIdTypeInfo: 31396 return ir_analyze_instruction_type_info(ira, (IrInstSrcTypeInfo *) instruction); 31397 case IrInstSrcIdType: 31398 return ir_analyze_instruction_type(ira, (IrInstSrcType *)instruction); 31399 case IrInstSrcIdHasField: 31400 return ir_analyze_instruction_has_field(ira, (IrInstSrcHasField *) instruction); 31401 case IrInstSrcIdSetEvalBranchQuota: 31402 return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstSrcSetEvalBranchQuota *)instruction); 31403 case IrInstSrcIdPtrType: 31404 return ir_analyze_instruction_ptr_type(ira, (IrInstSrcPtrType *)instruction); 31405 case IrInstSrcIdAlignCast: 31406 return ir_analyze_instruction_align_cast(ira, (IrInstSrcAlignCast *)instruction); 31407 case IrInstSrcIdImplicitCast: 31408 return ir_analyze_instruction_implicit_cast(ira, (IrInstSrcImplicitCast *)instruction); 31409 case IrInstSrcIdResolveResult: 31410 return ir_analyze_instruction_resolve_result(ira, (IrInstSrcResolveResult *)instruction); 31411 case IrInstSrcIdResetResult: 31412 return ir_analyze_instruction_reset_result(ira, (IrInstSrcResetResult *)instruction); 31413 case IrInstSrcIdOpaqueType: 31414 return ir_analyze_instruction_opaque_type(ira, (IrInstSrcOpaqueType *)instruction); 31415 case IrInstSrcIdSetAlignStack: 31416 return ir_analyze_instruction_set_align_stack(ira, (IrInstSrcSetAlignStack *)instruction); 31417 case IrInstSrcIdArgType: 31418 return ir_analyze_instruction_arg_type(ira, (IrInstSrcArgType *)instruction); 31419 case IrInstSrcIdTagType: 31420 return ir_analyze_instruction_tag_type(ira, (IrInstSrcTagType *)instruction); 31421 case IrInstSrcIdExport: 31422 return ir_analyze_instruction_export(ira, (IrInstSrcExport *)instruction); 31423 case IrInstSrcIdErrorReturnTrace: 31424 return ir_analyze_instruction_error_return_trace(ira, (IrInstSrcErrorReturnTrace *)instruction); 31425 case IrInstSrcIdErrorUnion: 31426 return ir_analyze_instruction_error_union(ira, (IrInstSrcErrorUnion *)instruction); 31427 case IrInstSrcIdAtomicRmw: 31428 return ir_analyze_instruction_atomic_rmw(ira, (IrInstSrcAtomicRmw *)instruction); 31429 case IrInstSrcIdAtomicLoad: 31430 return ir_analyze_instruction_atomic_load(ira, (IrInstSrcAtomicLoad *)instruction); 31431 case IrInstSrcIdAtomicStore: 31432 return ir_analyze_instruction_atomic_store(ira, (IrInstSrcAtomicStore *)instruction); 31433 case IrInstSrcIdSaveErrRetAddr: 31434 return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstSrcSaveErrRetAddr *)instruction); 31435 case IrInstSrcIdAddImplicitReturnType: 31436 return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstSrcAddImplicitReturnType *)instruction); 31437 case IrInstSrcIdFloatOp: 31438 return ir_analyze_instruction_float_op(ira, (IrInstSrcFloatOp *)instruction); 31439 case IrInstSrcIdMulAdd: 31440 return ir_analyze_instruction_mul_add(ira, (IrInstSrcMulAdd *)instruction); 31441 case IrInstSrcIdIntToErr: 31442 return ir_analyze_instruction_int_to_err(ira, (IrInstSrcIntToErr *)instruction); 31443 case IrInstSrcIdErrToInt: 31444 return ir_analyze_instruction_err_to_int(ira, (IrInstSrcErrToInt *)instruction); 31445 case IrInstSrcIdIntToEnum: 31446 return ir_analyze_instruction_int_to_enum(ira, (IrInstSrcIntToEnum *)instruction); 31447 case IrInstSrcIdEnumToInt: 31448 return ir_analyze_instruction_enum_to_int(ira, (IrInstSrcEnumToInt *)instruction); 31449 case IrInstSrcIdCheckRuntimeScope: 31450 return ir_analyze_instruction_check_runtime_scope(ira, (IrInstSrcCheckRuntimeScope *)instruction); 31451 case IrInstSrcIdHasDecl: 31452 return ir_analyze_instruction_has_decl(ira, (IrInstSrcHasDecl *)instruction); 31453 case IrInstSrcIdUndeclaredIdent: 31454 return ir_analyze_instruction_undeclared_ident(ira, (IrInstSrcUndeclaredIdent *)instruction); 31455 case IrInstSrcIdAlloca: 31456 return nullptr; 31457 case IrInstSrcIdEndExpr: 31458 return ir_analyze_instruction_end_expr(ira, (IrInstSrcEndExpr *)instruction); 31459 case IrInstSrcIdBitCast: 31460 return ir_analyze_instruction_bit_cast_src(ira, (IrInstSrcBitCast *)instruction); 31461 case IrInstSrcIdUnionInitNamedField: 31462 return ir_analyze_instruction_union_init_named_field(ira, (IrInstSrcUnionInitNamedField *)instruction); 31463 case IrInstSrcIdSuspendBegin: 31464 return ir_analyze_instruction_suspend_begin(ira, (IrInstSrcSuspendBegin *)instruction); 31465 case IrInstSrcIdSuspendFinish: 31466 return ir_analyze_instruction_suspend_finish(ira, (IrInstSrcSuspendFinish *)instruction); 31467 case IrInstSrcIdResume: 31468 return ir_analyze_instruction_resume(ira, (IrInstSrcResume *)instruction); 31469 case IrInstSrcIdAwait: 31470 return ir_analyze_instruction_await(ira, (IrInstSrcAwait *)instruction); 31471 case IrInstSrcIdSpillBegin: 31472 return ir_analyze_instruction_spill_begin(ira, (IrInstSrcSpillBegin *)instruction); 31473 case IrInstSrcIdSpillEnd: 31474 return ir_analyze_instruction_spill_end(ira, (IrInstSrcSpillEnd *)instruction); 31475 case IrInstSrcIdWasmMemorySize: 31476 return ir_analyze_instruction_wasm_memory_size(ira, (IrInstSrcWasmMemorySize *)instruction); 31477 case IrInstSrcIdWasmMemoryGrow: 31478 return ir_analyze_instruction_wasm_memory_grow(ira, (IrInstSrcWasmMemoryGrow *)instruction); 31479 case IrInstSrcIdSrc: 31480 return ir_analyze_instruction_src(ira, (IrInstSrcSrc *)instruction); 31481 } 31482 zig_unreachable(); 31483 } 31484 31485 // This function attempts to evaluate IR code while doing type checking and other analysis. 31486 // It emits to a new IrExecutableGen which is partially evaluated IR code. 31487 ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen *new_exec, 31488 ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *result_ptr) 31489 { 31490 assert(old_exec->first_err_trace_msg == nullptr); 31491 assert(expected_type == nullptr || !type_is_invalid(expected_type)); 31492 31493 IrAnalyze *ira = heap::c_allocator.create<IrAnalyze>(); 31494 ira->ref_count = 1; 31495 old_exec->analysis = ira; 31496 ira->codegen = codegen; 31497 31498 ira->explicit_return_type = expected_type; 31499 ira->explicit_return_type_source_node = expected_type_source_node; 31500 31501 ira->old_irb.codegen = codegen; 31502 ira->old_irb.exec = old_exec; 31503 31504 ira->new_irb.codegen = codegen; 31505 ira->new_irb.exec = new_exec; 31506 31507 IrBasicBlockSrc *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); 31508 IrBasicBlockGen *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); 31509 ira->new_irb.current_basic_block = new_entry_bb; 31510 ira->old_bb_index = 0; 31511 31512 ir_start_bb(ira, old_entry_bb, nullptr); 31513 31514 if (result_ptr != nullptr) { 31515 assert(result_ptr->type->id == ZigTypeIdPointer); 31516 IrInstGenConst *const_inst = ir_create_inst_noval<IrInstGenConst>( 31517 &ira->new_irb, new_exec->begin_scope, new_exec->source_node); 31518 const_inst->base.value = result_ptr; 31519 ira->return_ptr = &const_inst->base; 31520 } else { 31521 assert(new_exec->begin_scope != nullptr); 31522 assert(new_exec->source_node != nullptr); 31523 ira->return_ptr = ir_build_return_ptr(ira, new_exec->begin_scope, new_exec->source_node, 31524 get_pointer_to_type(codegen, expected_type, false)); 31525 } 31526 31527 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 31528 IrInstSrc *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 31529 31530 if (old_instruction->base.ref_count == 0 && !ir_inst_src_has_side_effects(old_instruction)) { 31531 ira->instruction_index += 1; 31532 continue; 31533 } 31534 31535 if (ira->codegen->verbose_ir) { 31536 fprintf(stderr, "~ "); 31537 old_instruction->src(); 31538 fprintf(stderr, "~ "); 31539 ir_print_inst_src(codegen, stderr, old_instruction, 0); 31540 bool want_break = false; 31541 if (ira->break_debug_id == old_instruction->base.debug_id) { 31542 want_break = true; 31543 } else if (old_instruction->base.source_node != nullptr) { 31544 for (size_t i = 0; i < dbg_ir_breakpoints_count; i += 1) { 31545 if (dbg_ir_breakpoints_buf[i].line == old_instruction->base.source_node->line + 1 && 31546 buf_ends_with_str(old_instruction->base.source_node->owner->data.structure.root_struct->path, 31547 dbg_ir_breakpoints_buf[i].src_file)) 31548 { 31549 want_break = true; 31550 } 31551 } 31552 } 31553 if (want_break) BREAKPOINT; 31554 } 31555 IrInstGen *new_instruction = ir_analyze_instruction_base(ira, old_instruction); 31556 if (new_instruction != nullptr) { 31557 ir_assert(new_instruction->value->type != nullptr || new_instruction->value->type != nullptr, &old_instruction->base); 31558 old_instruction->child = new_instruction; 31559 31560 if (type_is_invalid(new_instruction->value->type)) { 31561 if (ira->codegen->verbose_ir) { 31562 fprintf(stderr, "-> (invalid)"); 31563 } 31564 31565 if (new_exec->first_err_trace_msg != nullptr) { 31566 ira->codegen->trace_err = new_exec->first_err_trace_msg; 31567 } else { 31568 new_exec->first_err_trace_msg = ira->codegen->trace_err; 31569 } 31570 if (new_exec->first_err_trace_msg != nullptr && 31571 !old_instruction->base.source_node->already_traced_this_node) 31572 { 31573 old_instruction->base.source_node->already_traced_this_node = true; 31574 new_exec->first_err_trace_msg = add_error_note(ira->codegen, new_exec->first_err_trace_msg, 31575 old_instruction->base.source_node, buf_create_from_str("referenced here")); 31576 } 31577 return ira->codegen->builtin_types.entry_invalid; 31578 } else if (ira->codegen->verbose_ir) { 31579 fprintf(stderr, "-> "); 31580 if (new_instruction->value->type->id == ZigTypeIdUnreachable) { 31581 fprintf(stderr, "(noreturn)\n"); 31582 } else { 31583 ir_print_inst_gen(codegen, stderr, new_instruction, 0); 31584 } 31585 } 31586 31587 // unreachable instructions do their own control flow. 31588 if (new_instruction->value->type->id == ZigTypeIdUnreachable) 31589 continue; 31590 } else { 31591 if (ira->codegen->verbose_ir) { 31592 fprintf(stderr, "-> (null"); 31593 } 31594 } 31595 31596 ira->instruction_index += 1; 31597 } 31598 31599 ZigType *res_type; 31600 if (new_exec->first_err_trace_msg != nullptr) { 31601 codegen->trace_err = new_exec->first_err_trace_msg; 31602 if (codegen->trace_err != nullptr && new_exec->source_node != nullptr && 31603 !new_exec->source_node->already_traced_this_node) 31604 { 31605 new_exec->source_node->already_traced_this_node = true; 31606 codegen->trace_err = add_error_note(codegen, codegen->trace_err, 31607 new_exec->source_node, buf_create_from_str("referenced here")); 31608 } 31609 res_type = ira->codegen->builtin_types.entry_invalid; 31610 } else if (ira->src_implicit_return_type_list.length == 0) { 31611 res_type = codegen->builtin_types.entry_unreachable; 31612 } else { 31613 res_type = ir_resolve_peer_types(ira, expected_type_source_node, expected_type, ira->src_implicit_return_type_list.items, 31614 ira->src_implicit_return_type_list.length); 31615 } 31616 31617 // It is now safe to free Pass 1 IR instructions. 31618 ira_deref(ira); 31619 31620 return res_type; 31621 } 31622 31623 bool ir_inst_gen_has_side_effects(IrInstGen *instruction) { 31624 switch (instruction->id) { 31625 case IrInstGenIdInvalid: 31626 zig_unreachable(); 31627 case IrInstGenIdBr: 31628 case IrInstGenIdCondBr: 31629 case IrInstGenIdSwitchBr: 31630 case IrInstGenIdDeclVar: 31631 case IrInstGenIdStorePtr: 31632 case IrInstGenIdVectorStoreElem: 31633 case IrInstGenIdCall: 31634 case IrInstGenIdReturn: 31635 case IrInstGenIdUnreachable: 31636 case IrInstGenIdFence: 31637 case IrInstGenIdMemset: 31638 case IrInstGenIdMemcpy: 31639 case IrInstGenIdBreakpoint: 31640 case IrInstGenIdOverflowOp: // TODO when we support multiple returns this can be side effect free 31641 case IrInstGenIdPanic: 31642 case IrInstGenIdSaveErrRetAddr: 31643 case IrInstGenIdAtomicRmw: 31644 case IrInstGenIdAtomicStore: 31645 case IrInstGenIdCmpxchg: 31646 case IrInstGenIdAssertZero: 31647 case IrInstGenIdAssertNonNull: 31648 case IrInstGenIdPtrOfArrayToSlice: 31649 case IrInstGenIdSlice: 31650 case IrInstGenIdOptionalWrap: 31651 case IrInstGenIdVectorToArray: 31652 case IrInstGenIdSuspendBegin: 31653 case IrInstGenIdSuspendFinish: 31654 case IrInstGenIdResume: 31655 case IrInstGenIdAwait: 31656 case IrInstGenIdSpillBegin: 31657 case IrInstGenIdWasmMemoryGrow: 31658 return true; 31659 31660 case IrInstGenIdPhi: 31661 case IrInstGenIdBinOp: 31662 case IrInstGenIdConst: 31663 case IrInstGenIdCast: 31664 case IrInstGenIdElemPtr: 31665 case IrInstGenIdVarPtr: 31666 case IrInstGenIdReturnPtr: 31667 case IrInstGenIdStructFieldPtr: 31668 case IrInstGenIdTestNonNull: 31669 case IrInstGenIdClz: 31670 case IrInstGenIdCtz: 31671 case IrInstGenIdPopCount: 31672 case IrInstGenIdBswap: 31673 case IrInstGenIdBitReverse: 31674 case IrInstGenIdUnionTag: 31675 case IrInstGenIdTruncate: 31676 case IrInstGenIdShuffleVector: 31677 case IrInstGenIdSplat: 31678 case IrInstGenIdBoolNot: 31679 case IrInstGenIdReturnAddress: 31680 case IrInstGenIdFrameAddress: 31681 case IrInstGenIdFrameHandle: 31682 case IrInstGenIdFrameSize: 31683 case IrInstGenIdTestErr: 31684 case IrInstGenIdPtrCast: 31685 case IrInstGenIdBitCast: 31686 case IrInstGenIdWidenOrShorten: 31687 case IrInstGenIdPtrToInt: 31688 case IrInstGenIdIntToPtr: 31689 case IrInstGenIdIntToEnum: 31690 case IrInstGenIdIntToErr: 31691 case IrInstGenIdErrToInt: 31692 case IrInstGenIdErrName: 31693 case IrInstGenIdTagName: 31694 case IrInstGenIdFieldParentPtr: 31695 case IrInstGenIdAlignCast: 31696 case IrInstGenIdErrorReturnTrace: 31697 case IrInstGenIdFloatOp: 31698 case IrInstGenIdMulAdd: 31699 case IrInstGenIdAtomicLoad: 31700 case IrInstGenIdArrayToVector: 31701 case IrInstGenIdAlloca: 31702 case IrInstGenIdSpillEnd: 31703 case IrInstGenIdVectorExtractElem: 31704 case IrInstGenIdBinaryNot: 31705 case IrInstGenIdNegation: 31706 case IrInstGenIdNegationWrapping: 31707 case IrInstGenIdWasmMemorySize: 31708 return false; 31709 31710 case IrInstGenIdAsm: 31711 { 31712 IrInstGenAsm *asm_instruction = (IrInstGenAsm *)instruction; 31713 return asm_instruction->has_side_effects; 31714 } 31715 case IrInstGenIdUnwrapErrPayload: 31716 { 31717 IrInstGenUnwrapErrPayload *unwrap_err_payload_instruction = 31718 (IrInstGenUnwrapErrPayload *)instruction; 31719 return unwrap_err_payload_instruction->safety_check_on || 31720 unwrap_err_payload_instruction->initializing; 31721 } 31722 case IrInstGenIdUnwrapErrCode: 31723 return reinterpret_cast<IrInstGenUnwrapErrCode *>(instruction)->initializing; 31724 case IrInstGenIdUnionFieldPtr: 31725 return reinterpret_cast<IrInstGenUnionFieldPtr *>(instruction)->initializing; 31726 case IrInstGenIdOptionalUnwrapPtr: 31727 return reinterpret_cast<IrInstGenOptionalUnwrapPtr *>(instruction)->initializing; 31728 case IrInstGenIdErrWrapPayload: 31729 return reinterpret_cast<IrInstGenErrWrapPayload *>(instruction)->result_loc != nullptr; 31730 case IrInstGenIdErrWrapCode: 31731 return reinterpret_cast<IrInstGenErrWrapCode *>(instruction)->result_loc != nullptr; 31732 case IrInstGenIdLoadPtr: 31733 return reinterpret_cast<IrInstGenLoadPtr *>(instruction)->result_loc != nullptr; 31734 case IrInstGenIdRef: 31735 return reinterpret_cast<IrInstGenRef *>(instruction)->result_loc != nullptr; 31736 } 31737 zig_unreachable(); 31738 } 31739 31740 bool ir_inst_src_has_side_effects(IrInstSrc *instruction) { 31741 switch (instruction->id) { 31742 case IrInstSrcIdInvalid: 31743 zig_unreachable(); 31744 case IrInstSrcIdBr: 31745 case IrInstSrcIdCondBr: 31746 case IrInstSrcIdSwitchBr: 31747 case IrInstSrcIdDeclVar: 31748 case IrInstSrcIdStorePtr: 31749 case IrInstSrcIdCallExtra: 31750 case IrInstSrcIdAsyncCallExtra: 31751 case IrInstSrcIdCall: 31752 case IrInstSrcIdCallArgs: 31753 case IrInstSrcIdReturn: 31754 case IrInstSrcIdUnreachable: 31755 case IrInstSrcIdSetCold: 31756 case IrInstSrcIdSetRuntimeSafety: 31757 case IrInstSrcIdSetFloatMode: 31758 case IrInstSrcIdImport: 31759 case IrInstSrcIdCompileErr: 31760 case IrInstSrcIdCompileLog: 31761 case IrInstSrcIdCImport: 31762 case IrInstSrcIdCInclude: 31763 case IrInstSrcIdCDefine: 31764 case IrInstSrcIdCUndef: 31765 case IrInstSrcIdFence: 31766 case IrInstSrcIdMemset: 31767 case IrInstSrcIdMemcpy: 31768 case IrInstSrcIdBreakpoint: 31769 case IrInstSrcIdOverflowOp: // TODO when we support multiple returns this can be side effect free 31770 case IrInstSrcIdCheckSwitchProngs: 31771 case IrInstSrcIdCheckStatementIsVoid: 31772 case IrInstSrcIdCheckRuntimeScope: 31773 case IrInstSrcIdPanic: 31774 case IrInstSrcIdSetEvalBranchQuota: 31775 case IrInstSrcIdPtrType: 31776 case IrInstSrcIdSetAlignStack: 31777 case IrInstSrcIdExport: 31778 case IrInstSrcIdSaveErrRetAddr: 31779 case IrInstSrcIdAddImplicitReturnType: 31780 case IrInstSrcIdAtomicRmw: 31781 case IrInstSrcIdAtomicStore: 31782 case IrInstSrcIdCmpxchg: 31783 case IrInstSrcIdUndeclaredIdent: 31784 case IrInstSrcIdEndExpr: 31785 case IrInstSrcIdResetResult: 31786 case IrInstSrcIdSuspendBegin: 31787 case IrInstSrcIdSuspendFinish: 31788 case IrInstSrcIdResume: 31789 case IrInstSrcIdAwait: 31790 case IrInstSrcIdSpillBegin: 31791 case IrInstSrcIdWasmMemoryGrow: 31792 return true; 31793 31794 case IrInstSrcIdPhi: 31795 case IrInstSrcIdUnOp: 31796 case IrInstSrcIdBinOp: 31797 case IrInstSrcIdMergeErrSets: 31798 case IrInstSrcIdLoadPtr: 31799 case IrInstSrcIdConst: 31800 case IrInstSrcIdContainerInitList: 31801 case IrInstSrcIdContainerInitFields: 31802 case IrInstSrcIdUnionInitNamedField: 31803 case IrInstSrcIdFieldPtr: 31804 case IrInstSrcIdElemPtr: 31805 case IrInstSrcIdVarPtr: 31806 case IrInstSrcIdTypeOf: 31807 case IrInstSrcIdArrayType: 31808 case IrInstSrcIdSliceType: 31809 case IrInstSrcIdAnyFrameType: 31810 case IrInstSrcIdSizeOf: 31811 case IrInstSrcIdTestNonNull: 31812 case IrInstSrcIdOptionalUnwrapPtr: 31813 case IrInstSrcIdClz: 31814 case IrInstSrcIdCtz: 31815 case IrInstSrcIdPopCount: 31816 case IrInstSrcIdBswap: 31817 case IrInstSrcIdBitReverse: 31818 case IrInstSrcIdSwitchVar: 31819 case IrInstSrcIdSwitchElseVar: 31820 case IrInstSrcIdSwitchTarget: 31821 case IrInstSrcIdRef: 31822 case IrInstSrcIdEmbedFile: 31823 case IrInstSrcIdTruncate: 31824 case IrInstSrcIdVectorType: 31825 case IrInstSrcIdShuffleVector: 31826 case IrInstSrcIdSplat: 31827 case IrInstSrcIdBoolNot: 31828 case IrInstSrcIdSlice: 31829 case IrInstSrcIdAlignOf: 31830 case IrInstSrcIdReturnAddress: 31831 case IrInstSrcIdFrameAddress: 31832 case IrInstSrcIdFrameHandle: 31833 case IrInstSrcIdFrameType: 31834 case IrInstSrcIdFrameSize: 31835 case IrInstSrcIdTestErr: 31836 case IrInstSrcIdFnProto: 31837 case IrInstSrcIdTestComptime: 31838 case IrInstSrcIdPtrCast: 31839 case IrInstSrcIdBitCast: 31840 case IrInstSrcIdPtrToInt: 31841 case IrInstSrcIdIntToPtr: 31842 case IrInstSrcIdIntToEnum: 31843 case IrInstSrcIdIntToErr: 31844 case IrInstSrcIdErrToInt: 31845 case IrInstSrcIdDeclRef: 31846 case IrInstSrcIdErrName: 31847 case IrInstSrcIdTypeName: 31848 case IrInstSrcIdTagName: 31849 case IrInstSrcIdFieldParentPtr: 31850 case IrInstSrcIdByteOffsetOf: 31851 case IrInstSrcIdBitOffsetOf: 31852 case IrInstSrcIdTypeInfo: 31853 case IrInstSrcIdType: 31854 case IrInstSrcIdHasField: 31855 case IrInstSrcIdAlignCast: 31856 case IrInstSrcIdImplicitCast: 31857 case IrInstSrcIdResolveResult: 31858 case IrInstSrcIdOpaqueType: 31859 case IrInstSrcIdArgType: 31860 case IrInstSrcIdTagType: 31861 case IrInstSrcIdErrorReturnTrace: 31862 case IrInstSrcIdErrorUnion: 31863 case IrInstSrcIdFloatOp: 31864 case IrInstSrcIdMulAdd: 31865 case IrInstSrcIdAtomicLoad: 31866 case IrInstSrcIdIntCast: 31867 case IrInstSrcIdFloatCast: 31868 case IrInstSrcIdErrSetCast: 31869 case IrInstSrcIdIntToFloat: 31870 case IrInstSrcIdFloatToInt: 31871 case IrInstSrcIdBoolToInt: 31872 case IrInstSrcIdEnumToInt: 31873 case IrInstSrcIdHasDecl: 31874 case IrInstSrcIdAlloca: 31875 case IrInstSrcIdSpillEnd: 31876 case IrInstSrcIdWasmMemorySize: 31877 case IrInstSrcIdSrc: 31878 return false; 31879 31880 case IrInstSrcIdAsm: 31881 { 31882 IrInstSrcAsm *asm_instruction = (IrInstSrcAsm *)instruction; 31883 return asm_instruction->has_side_effects; 31884 } 31885 31886 case IrInstSrcIdUnwrapErrPayload: 31887 { 31888 IrInstSrcUnwrapErrPayload *unwrap_err_payload_instruction = 31889 (IrInstSrcUnwrapErrPayload *)instruction; 31890 return unwrap_err_payload_instruction->safety_check_on || 31891 unwrap_err_payload_instruction->initializing; 31892 } 31893 case IrInstSrcIdUnwrapErrCode: 31894 return reinterpret_cast<IrInstSrcUnwrapErrCode *>(instruction)->initializing; 31895 } 31896 zig_unreachable(); 31897 } 31898 31899 static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, LazyValueFnType *lazy_fn_type) { 31900 Error err; 31901 AstNode *proto_node = lazy_fn_type->proto_node; 31902 31903 FnTypeId fn_type_id = {0}; 31904 init_fn_type_id(&fn_type_id, proto_node, lazy_fn_type->cc, proto_node->data.fn_proto.params.length); 31905 31906 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { 31907 AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); 31908 assert(param_node->type == NodeTypeParamDecl); 31909 31910 bool param_is_var_args = param_node->data.param_decl.is_var_args; 31911 if (param_is_var_args) { 31912 if (fn_type_id.cc == CallingConventionC) { 31913 fn_type_id.param_count = fn_type_id.next_param_index; 31914 break; 31915 } else { 31916 ir_add_error_node(ira, param_node, 31917 buf_sprintf("var args only allowed in functions with C calling convention")); 31918 return nullptr; 31919 } 31920 } 31921 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; 31922 param_info->is_noalias = param_node->data.param_decl.is_noalias; 31923 31924 if (lazy_fn_type->param_types[fn_type_id.next_param_index] == nullptr) { 31925 param_info->type = nullptr; 31926 return get_generic_fn_type(ira->codegen, &fn_type_id); 31927 } else { 31928 IrInstGen *param_type_inst = lazy_fn_type->param_types[fn_type_id.next_param_index]; 31929 ZigType *param_type = ir_resolve_type(ira, param_type_inst); 31930 if (type_is_invalid(param_type)) 31931 return nullptr; 31932 31933 if(!is_valid_param_type(param_type)){ 31934 if(param_type->id == ZigTypeIdOpaque){ 31935 ir_add_error(ira, ¶m_type_inst->base, 31936 buf_sprintf("parameter of opaque type '%s' not allowed", buf_ptr(¶m_type->name))); 31937 } else { 31938 ir_add_error(ira, ¶m_type_inst->base, 31939 buf_sprintf("parameter of type '%s' not allowed", buf_ptr(¶m_type->name))); 31940 } 31941 31942 return nullptr; 31943 } 31944 31945 switch (type_requires_comptime(ira->codegen, param_type)) { 31946 case ReqCompTimeYes: 31947 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 31948 ir_add_error(ira, ¶m_type_inst->base, 31949 buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", 31950 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 31951 return nullptr; 31952 } 31953 param_info->type = param_type; 31954 fn_type_id.next_param_index += 1; 31955 return get_generic_fn_type(ira->codegen, &fn_type_id); 31956 case ReqCompTimeInvalid: 31957 return nullptr; 31958 case ReqCompTimeNo: 31959 break; 31960 } 31961 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 31962 bool has_bits; 31963 if ((err = type_has_bits2(ira->codegen, param_type, &has_bits))) 31964 return nullptr; 31965 if (!has_bits) { 31966 ir_add_error(ira, ¶m_type_inst->base, 31967 buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", 31968 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 31969 return nullptr; 31970 } 31971 } 31972 param_info->type = param_type; 31973 } 31974 } 31975 31976 if (lazy_fn_type->align_inst != nullptr) { 31977 if (!ir_resolve_align(ira, lazy_fn_type->align_inst, nullptr, &fn_type_id.alignment)) 31978 return nullptr; 31979 } 31980 31981 fn_type_id.return_type = ir_resolve_type(ira, lazy_fn_type->return_type); 31982 if (type_is_invalid(fn_type_id.return_type)) 31983 return nullptr; 31984 if (fn_type_id.return_type->id == ZigTypeIdOpaque) { 31985 ir_add_error(ira, &lazy_fn_type->return_type->base, buf_create_from_str("return type cannot be opaque")); 31986 return nullptr; 31987 } 31988 31989 return get_fn_type(ira->codegen, &fn_type_id); 31990 } 31991 31992 static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { 31993 Error err; 31994 if (val->special != ConstValSpecialLazy) 31995 return ErrorNone; 31996 switch (val->data.x_lazy->id) { 31997 case LazyValueIdInvalid: 31998 zig_unreachable(); 31999 case LazyValueIdTypeInfoDecls: { 32000 LazyValueTypeInfoDecls *type_info_decls = reinterpret_cast<LazyValueTypeInfoDecls *>(val->data.x_lazy); 32001 IrAnalyze *ira = type_info_decls->ira; 32002 32003 if ((err = ir_make_type_info_decls(ira, type_info_decls->source_instr, val, type_info_decls->decls_scope, true))) 32004 { 32005 return err; 32006 }; 32007 32008 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32009 return ErrorNone; 32010 } 32011 case LazyValueIdAlignOf: { 32012 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy); 32013 IrAnalyze *ira = lazy_align_of->ira; 32014 32015 if (lazy_align_of->target_type->value->special == ConstValSpecialStatic) { 32016 switch (lazy_align_of->target_type->value->data.x_type->id) { 32017 case ZigTypeIdInvalid: 32018 zig_unreachable(); 32019 case ZigTypeIdMetaType: 32020 case ZigTypeIdUnreachable: 32021 case ZigTypeIdComptimeFloat: 32022 case ZigTypeIdComptimeInt: 32023 case ZigTypeIdEnumLiteral: 32024 case ZigTypeIdUndefined: 32025 case ZigTypeIdNull: 32026 case ZigTypeIdBoundFn: 32027 case ZigTypeIdVoid: 32028 case ZigTypeIdOpaque: 32029 ir_add_error(ira, &lazy_align_of->target_type->base, 32030 buf_sprintf("no align available for type '%s'", 32031 buf_ptr(&lazy_align_of->target_type->value->data.x_type->name))); 32032 return ErrorSemanticAnalyzeFail; 32033 case ZigTypeIdBool: 32034 case ZigTypeIdInt: 32035 case ZigTypeIdFloat: 32036 case ZigTypeIdPointer: 32037 case ZigTypeIdArray: 32038 case ZigTypeIdStruct: 32039 case ZigTypeIdOptional: 32040 case ZigTypeIdErrorUnion: 32041 case ZigTypeIdErrorSet: 32042 case ZigTypeIdEnum: 32043 case ZigTypeIdUnion: 32044 case ZigTypeIdFn: 32045 case ZigTypeIdVector: 32046 case ZigTypeIdFnFrame: 32047 case ZigTypeIdAnyFrame: 32048 break; 32049 } 32050 } 32051 32052 uint32_t align_in_bytes; 32053 if ((err = type_val_resolve_abi_align(ira->codegen, source_node, 32054 lazy_align_of->target_type->value, &align_in_bytes))) 32055 { 32056 return err; 32057 } 32058 32059 val->special = ConstValSpecialStatic; 32060 assert(val->type->id == ZigTypeIdComptimeInt || val->type->id == ZigTypeIdInt); 32061 bigint_init_unsigned(&val->data.x_bigint, align_in_bytes); 32062 32063 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32064 return ErrorNone; 32065 } 32066 case LazyValueIdSizeOf: { 32067 LazyValueSizeOf *lazy_size_of = reinterpret_cast<LazyValueSizeOf *>(val->data.x_lazy); 32068 IrAnalyze *ira = lazy_size_of->ira; 32069 32070 if (lazy_size_of->target_type->value->special == ConstValSpecialStatic) { 32071 switch (lazy_size_of->target_type->value->data.x_type->id) { 32072 case ZigTypeIdInvalid: // handled above 32073 zig_unreachable(); 32074 case ZigTypeIdUnreachable: 32075 case ZigTypeIdUndefined: 32076 case ZigTypeIdNull: 32077 case ZigTypeIdBoundFn: 32078 case ZigTypeIdOpaque: 32079 ir_add_error(ira, &lazy_size_of->target_type->base, 32080 buf_sprintf("no size available for type '%s'", 32081 buf_ptr(&lazy_size_of->target_type->value->data.x_type->name))); 32082 return ErrorSemanticAnalyzeFail; 32083 case ZigTypeIdMetaType: 32084 case ZigTypeIdEnumLiteral: 32085 case ZigTypeIdComptimeFloat: 32086 case ZigTypeIdComptimeInt: 32087 case ZigTypeIdVoid: 32088 case ZigTypeIdBool: 32089 case ZigTypeIdInt: 32090 case ZigTypeIdFloat: 32091 case ZigTypeIdPointer: 32092 case ZigTypeIdArray: 32093 case ZigTypeIdStruct: 32094 case ZigTypeIdOptional: 32095 case ZigTypeIdErrorUnion: 32096 case ZigTypeIdErrorSet: 32097 case ZigTypeIdEnum: 32098 case ZigTypeIdUnion: 32099 case ZigTypeIdFn: 32100 case ZigTypeIdVector: 32101 case ZigTypeIdFnFrame: 32102 case ZigTypeIdAnyFrame: 32103 break; 32104 } 32105 } 32106 32107 size_t abi_size; 32108 size_t size_in_bits; 32109 if ((err = type_val_resolve_abi_size(ira->codegen, source_node, lazy_size_of->target_type->value, 32110 &abi_size, &size_in_bits))) 32111 { 32112 return err; 32113 } 32114 32115 val->special = ConstValSpecialStatic; 32116 assert(val->type->id == ZigTypeIdComptimeInt || val->type->id == ZigTypeIdInt); 32117 if (lazy_size_of->bit_size) 32118 bigint_init_unsigned(&val->data.x_bigint, size_in_bits); 32119 else 32120 bigint_init_unsigned(&val->data.x_bigint, abi_size); 32121 32122 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32123 return ErrorNone; 32124 } 32125 case LazyValueIdSliceType: { 32126 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(val->data.x_lazy); 32127 IrAnalyze *ira = lazy_slice_type->ira; 32128 32129 ZigType *elem_type = ir_resolve_type(ira, lazy_slice_type->elem_type); 32130 if (type_is_invalid(elem_type)) 32131 return ErrorSemanticAnalyzeFail; 32132 32133 ZigValue *sentinel_val; 32134 if (lazy_slice_type->sentinel != nullptr) { 32135 if (type_is_invalid(lazy_slice_type->sentinel->value->type)) 32136 return ErrorSemanticAnalyzeFail; 32137 IrInstGen *sentinel = ir_implicit_cast(ira, lazy_slice_type->sentinel, elem_type); 32138 if (type_is_invalid(sentinel->value->type)) 32139 return ErrorSemanticAnalyzeFail; 32140 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 32141 if (sentinel_val == nullptr) 32142 return ErrorSemanticAnalyzeFail; 32143 } else { 32144 sentinel_val = nullptr; 32145 } 32146 32147 uint32_t align_bytes = 0; 32148 if (lazy_slice_type->align_inst != nullptr) { 32149 if (!ir_resolve_align(ira, lazy_slice_type->align_inst, elem_type, &align_bytes)) 32150 return ErrorSemanticAnalyzeFail; 32151 } 32152 32153 switch (elem_type->id) { 32154 case ZigTypeIdInvalid: // handled above 32155 zig_unreachable(); 32156 case ZigTypeIdUnreachable: 32157 case ZigTypeIdUndefined: 32158 case ZigTypeIdNull: 32159 case ZigTypeIdOpaque: 32160 ir_add_error(ira, &lazy_slice_type->elem_type->base, 32161 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&elem_type->name))); 32162 return ErrorSemanticAnalyzeFail; 32163 case ZigTypeIdMetaType: 32164 case ZigTypeIdVoid: 32165 case ZigTypeIdBool: 32166 case ZigTypeIdInt: 32167 case ZigTypeIdFloat: 32168 case ZigTypeIdPointer: 32169 case ZigTypeIdArray: 32170 case ZigTypeIdStruct: 32171 case ZigTypeIdComptimeFloat: 32172 case ZigTypeIdComptimeInt: 32173 case ZigTypeIdEnumLiteral: 32174 case ZigTypeIdOptional: 32175 case ZigTypeIdErrorUnion: 32176 case ZigTypeIdErrorSet: 32177 case ZigTypeIdEnum: 32178 case ZigTypeIdUnion: 32179 case ZigTypeIdFn: 32180 case ZigTypeIdBoundFn: 32181 case ZigTypeIdVector: 32182 case ZigTypeIdFnFrame: 32183 case ZigTypeIdAnyFrame: 32184 break; 32185 } 32186 32187 ResolveStatus needed_status = (align_bytes == 0) ? 32188 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; 32189 if ((err = type_resolve(ira->codegen, elem_type, needed_status))) 32190 return err; 32191 ZigType *slice_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 32192 lazy_slice_type->is_const, lazy_slice_type->is_volatile, 32193 PtrLenUnknown, 32194 align_bytes, 32195 0, 0, lazy_slice_type->is_allowzero, 32196 VECTOR_INDEX_NONE, nullptr, sentinel_val); 32197 val->special = ConstValSpecialStatic; 32198 assert(val->type->id == ZigTypeIdMetaType); 32199 val->data.x_type = get_slice_type(ira->codegen, slice_ptr_type); 32200 32201 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32202 return ErrorNone; 32203 } 32204 case LazyValueIdPtrType: { 32205 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(val->data.x_lazy); 32206 IrAnalyze *ira = lazy_ptr_type->ira; 32207 32208 ZigType *elem_type = ir_resolve_type(ira, lazy_ptr_type->elem_type); 32209 if (type_is_invalid(elem_type)) 32210 return ErrorSemanticAnalyzeFail; 32211 32212 ZigValue *sentinel_val; 32213 if (lazy_ptr_type->sentinel != nullptr) { 32214 if (type_is_invalid(lazy_ptr_type->sentinel->value->type)) 32215 return ErrorSemanticAnalyzeFail; 32216 IrInstGen *sentinel = ir_implicit_cast(ira, lazy_ptr_type->sentinel, elem_type); 32217 if (type_is_invalid(sentinel->value->type)) 32218 return ErrorSemanticAnalyzeFail; 32219 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 32220 if (sentinel_val == nullptr) 32221 return ErrorSemanticAnalyzeFail; 32222 } else { 32223 sentinel_val = nullptr; 32224 } 32225 32226 uint32_t align_bytes = 0; 32227 if (lazy_ptr_type->align_inst != nullptr) { 32228 if (!ir_resolve_align(ira, lazy_ptr_type->align_inst, elem_type, &align_bytes)) 32229 return ErrorSemanticAnalyzeFail; 32230 } 32231 32232 if (elem_type->id == ZigTypeIdUnreachable) { 32233 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 32234 buf_create_from_str("pointer to noreturn not allowed")); 32235 return ErrorSemanticAnalyzeFail; 32236 } else if (elem_type->id == ZigTypeIdOpaque && lazy_ptr_type->ptr_len == PtrLenUnknown) { 32237 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 32238 buf_create_from_str("unknown-length pointer to opaque")); 32239 return ErrorSemanticAnalyzeFail; 32240 } else if (lazy_ptr_type->ptr_len == PtrLenC) { 32241 bool ok_type; 32242 if ((err = type_allowed_in_extern(ira->codegen, elem_type, &ok_type))) 32243 return err; 32244 if (!ok_type) { 32245 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 32246 buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", 32247 buf_ptr(&elem_type->name))); 32248 return ErrorSemanticAnalyzeFail; 32249 } else if (elem_type->id == ZigTypeIdOpaque) { 32250 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 32251 buf_sprintf("C pointers cannot point to opaque types")); 32252 return ErrorSemanticAnalyzeFail; 32253 } else if (lazy_ptr_type->is_allowzero) { 32254 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 32255 buf_sprintf("C pointers always allow address zero")); 32256 return ErrorSemanticAnalyzeFail; 32257 } 32258 } 32259 32260 if (align_bytes != 0) { 32261 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown))) 32262 return err; 32263 if (!type_has_bits(ira->codegen, elem_type)) 32264 align_bytes = 0; 32265 } 32266 bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC; 32267 assert(val->type->id == ZigTypeIdMetaType); 32268 val->data.x_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 32269 lazy_ptr_type->is_const, lazy_ptr_type->is_volatile, lazy_ptr_type->ptr_len, align_bytes, 32270 lazy_ptr_type->bit_offset_in_host, lazy_ptr_type->host_int_bytes, 32271 allow_zero, VECTOR_INDEX_NONE, nullptr, sentinel_val); 32272 val->special = ConstValSpecialStatic; 32273 32274 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32275 return ErrorNone; 32276 } 32277 case LazyValueIdArrayType: { 32278 LazyValueArrayType *lazy_array_type = reinterpret_cast<LazyValueArrayType *>(val->data.x_lazy); 32279 IrAnalyze *ira = lazy_array_type->ira; 32280 32281 ZigType *elem_type = ir_resolve_type(ira, lazy_array_type->elem_type); 32282 if (type_is_invalid(elem_type)) 32283 return ErrorSemanticAnalyzeFail; 32284 32285 switch (elem_type->id) { 32286 case ZigTypeIdInvalid: // handled above 32287 zig_unreachable(); 32288 case ZigTypeIdUnreachable: 32289 case ZigTypeIdUndefined: 32290 case ZigTypeIdNull: 32291 case ZigTypeIdOpaque: 32292 ir_add_error(ira, &lazy_array_type->elem_type->base, 32293 buf_sprintf("array of type '%s' not allowed", 32294 buf_ptr(&elem_type->name))); 32295 return ErrorSemanticAnalyzeFail; 32296 case ZigTypeIdMetaType: 32297 case ZigTypeIdVoid: 32298 case ZigTypeIdBool: 32299 case ZigTypeIdInt: 32300 case ZigTypeIdFloat: 32301 case ZigTypeIdPointer: 32302 case ZigTypeIdArray: 32303 case ZigTypeIdStruct: 32304 case ZigTypeIdComptimeFloat: 32305 case ZigTypeIdComptimeInt: 32306 case ZigTypeIdEnumLiteral: 32307 case ZigTypeIdOptional: 32308 case ZigTypeIdErrorUnion: 32309 case ZigTypeIdErrorSet: 32310 case ZigTypeIdEnum: 32311 case ZigTypeIdUnion: 32312 case ZigTypeIdFn: 32313 case ZigTypeIdBoundFn: 32314 case ZigTypeIdVector: 32315 case ZigTypeIdFnFrame: 32316 case ZigTypeIdAnyFrame: 32317 break; 32318 } 32319 32320 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) 32321 return err; 32322 32323 ZigValue *sentinel_val = nullptr; 32324 if (lazy_array_type->sentinel != nullptr) { 32325 if (type_is_invalid(lazy_array_type->sentinel->value->type)) 32326 return ErrorSemanticAnalyzeFail; 32327 IrInstGen *sentinel = ir_implicit_cast(ira, lazy_array_type->sentinel, elem_type); 32328 if (type_is_invalid(sentinel->value->type)) 32329 return ErrorSemanticAnalyzeFail; 32330 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 32331 if (sentinel_val == nullptr) 32332 return ErrorSemanticAnalyzeFail; 32333 } 32334 32335 assert(val->type->id == ZigTypeIdMetaType); 32336 val->data.x_type = get_array_type(ira->codegen, elem_type, lazy_array_type->length, sentinel_val); 32337 val->special = ConstValSpecialStatic; 32338 32339 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32340 return ErrorNone; 32341 } 32342 case LazyValueIdOptType: { 32343 LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(val->data.x_lazy); 32344 IrAnalyze *ira = lazy_opt_type->ira; 32345 32346 ZigType *payload_type = ir_resolve_type(ira, lazy_opt_type->payload_type); 32347 if (type_is_invalid(payload_type)) 32348 return ErrorSemanticAnalyzeFail; 32349 32350 if (payload_type->id == ZigTypeIdOpaque || payload_type->id == ZigTypeIdUnreachable) { 32351 ir_add_error(ira, &lazy_opt_type->payload_type->base, 32352 buf_sprintf("type '%s' cannot be optional", buf_ptr(&payload_type->name))); 32353 return ErrorSemanticAnalyzeFail; 32354 } 32355 32356 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 32357 return err; 32358 32359 assert(val->type->id == ZigTypeIdMetaType); 32360 val->data.x_type = get_optional_type(ira->codegen, payload_type); 32361 val->special = ConstValSpecialStatic; 32362 32363 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32364 return ErrorNone; 32365 } 32366 case LazyValueIdFnType: { 32367 LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(val->data.x_lazy); 32368 IrAnalyze *ira = lazy_fn_type->ira; 32369 ZigType *fn_type = ir_resolve_lazy_fn_type(ira, source_node, lazy_fn_type); 32370 if (fn_type == nullptr) 32371 return ErrorSemanticAnalyzeFail; 32372 val->special = ConstValSpecialStatic; 32373 assert(val->type->id == ZigTypeIdMetaType); 32374 val->data.x_type = fn_type; 32375 32376 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32377 return ErrorNone; 32378 } 32379 case LazyValueIdErrUnionType: { 32380 LazyValueErrUnionType *lazy_err_union_type = 32381 reinterpret_cast<LazyValueErrUnionType *>(val->data.x_lazy); 32382 IrAnalyze *ira = lazy_err_union_type->ira; 32383 32384 ZigType *err_set_type = ir_resolve_type(ira, lazy_err_union_type->err_set_type); 32385 if (type_is_invalid(err_set_type)) 32386 return ErrorSemanticAnalyzeFail; 32387 32388 ZigType *payload_type = ir_resolve_type(ira, lazy_err_union_type->payload_type); 32389 if (type_is_invalid(payload_type)) 32390 return ErrorSemanticAnalyzeFail; 32391 32392 if (err_set_type->id != ZigTypeIdErrorSet) { 32393 ir_add_error(ira, &lazy_err_union_type->err_set_type->base, 32394 buf_sprintf("expected error set type, found type '%s'", 32395 buf_ptr(&err_set_type->name))); 32396 return ErrorSemanticAnalyzeFail; 32397 } 32398 32399 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 32400 return ErrorSemanticAnalyzeFail; 32401 32402 assert(val->type->id == ZigTypeIdMetaType); 32403 val->data.x_type = get_error_union_type(ira->codegen, err_set_type, payload_type); 32404 val->special = ConstValSpecialStatic; 32405 32406 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32407 return ErrorNone; 32408 } 32409 } 32410 zig_unreachable(); 32411 } 32412 32413 Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val) { 32414 Error err; 32415 if ((err = ir_resolve_lazy_raw(source_node, val))) { 32416 if (codegen->trace_err != nullptr && source_node != nullptr && !source_node->already_traced_this_node) { 32417 source_node->already_traced_this_node = true; 32418 codegen->trace_err = add_error_note(codegen, codegen->trace_err, source_node, 32419 buf_create_from_str("referenced here")); 32420 } 32421 return err; 32422 } 32423 if (type_is_invalid(val->type)) { 32424 return ErrorSemanticAnalyzeFail; 32425 } 32426 return ErrorNone; 32427 } 32428 32429 void IrInst::src() { 32430 IrInst *inst = this; 32431 if (inst->source_node != nullptr) { 32432 inst->source_node->src(); 32433 } else { 32434 fprintf(stderr, "(null source node)\n"); 32435 } 32436 } 32437 32438 void IrInst::dump() { 32439 this->src(); 32440 fprintf(stderr, "IrInst(#%" PRIu32 ")\n", this->debug_id); 32441 } 32442 32443 void IrInstSrc::src() { 32444 this->base.src(); 32445 } 32446 32447 void IrInstGen::src() { 32448 this->base.src(); 32449 } 32450 32451 void IrInstSrc::dump() { 32452 IrInstSrc *inst = this; 32453 inst->src(); 32454 if (inst->base.scope == nullptr) { 32455 fprintf(stderr, "(null scope)\n"); 32456 } else { 32457 ir_print_inst_src(inst->base.scope->codegen, stderr, inst, 0); 32458 fprintf(stderr, "-> "); 32459 ir_print_inst_gen(inst->base.scope->codegen, stderr, inst->child, 0); 32460 } 32461 } 32462 void IrInstGen::dump() { 32463 IrInstGen *inst = this; 32464 inst->src(); 32465 if (inst->base.scope == nullptr) { 32466 fprintf(stderr, "(null scope)\n"); 32467 } else { 32468 ir_print_inst_gen(inst->base.scope->codegen, stderr, inst, 0); 32469 } 32470 } 32471 32472 void IrAnalyze::dump() { 32473 ir_print_gen(this->codegen, stderr, this->new_irb.exec, 0); 32474 if (this->new_irb.current_basic_block != nullptr) { 32475 fprintf(stderr, "Current basic block:\n"); 32476 ir_print_basic_block_gen(this->codegen, stderr, this->new_irb.current_basic_block, 1); 32477 } 32478 } 32479 32480 void dbg_ir_break(const char *src_file, uint32_t line) { 32481 dbg_ir_breakpoints_buf[dbg_ir_breakpoints_count] = {src_file, line}; 32482 dbg_ir_breakpoints_count += 1; 32483 } 32484 void dbg_ir_clear(void) { 32485 dbg_ir_breakpoints_count = 0; 32486 }