blob bb6ca554 (1456338B) - 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 IrInstSrcIdUnOp: 314 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnOp *>(inst)); 315 case IrInstSrcIdCondBr: 316 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCondBr *>(inst)); 317 case IrInstSrcIdBr: 318 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBr *>(inst)); 319 case IrInstSrcIdPhi: 320 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPhi *>(inst)); 321 case IrInstSrcIdContainerInitList: 322 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcContainerInitList *>(inst)); 323 case IrInstSrcIdContainerInitFields: 324 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcContainerInitFields *>(inst)); 325 case IrInstSrcIdUnreachable: 326 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnreachable *>(inst)); 327 case IrInstSrcIdElemPtr: 328 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcElemPtr *>(inst)); 329 case IrInstSrcIdVarPtr: 330 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVarPtr *>(inst)); 331 case IrInstSrcIdLoadPtr: 332 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcLoadPtr *>(inst)); 333 case IrInstSrcIdStorePtr: 334 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcStorePtr *>(inst)); 335 case IrInstSrcIdTypeOf: 336 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeOf *>(inst)); 337 case IrInstSrcIdFieldPtr: 338 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFieldPtr *>(inst)); 339 case IrInstSrcIdSetCold: 340 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetCold *>(inst)); 341 case IrInstSrcIdSetRuntimeSafety: 342 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetRuntimeSafety *>(inst)); 343 case IrInstSrcIdSetFloatMode: 344 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetFloatMode *>(inst)); 345 case IrInstSrcIdArrayType: 346 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcArrayType *>(inst)); 347 case IrInstSrcIdSliceType: 348 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSliceType *>(inst)); 349 case IrInstSrcIdAnyFrameType: 350 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAnyFrameType *>(inst)); 351 case IrInstSrcIdAsm: 352 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAsm *>(inst)); 353 case IrInstSrcIdSizeOf: 354 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSizeOf *>(inst)); 355 case IrInstSrcIdTestNonNull: 356 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestNonNull *>(inst)); 357 case IrInstSrcIdOptionalUnwrapPtr: 358 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOptionalUnwrapPtr *>(inst)); 359 case IrInstSrcIdPopCount: 360 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPopCount *>(inst)); 361 case IrInstSrcIdClz: 362 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcClz *>(inst)); 363 case IrInstSrcIdCtz: 364 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCtz *>(inst)); 365 case IrInstSrcIdBswap: 366 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBswap *>(inst)); 367 case IrInstSrcIdBitReverse: 368 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitReverse *>(inst)); 369 case IrInstSrcIdSwitchBr: 370 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchBr *>(inst)); 371 case IrInstSrcIdSwitchVar: 372 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchVar *>(inst)); 373 case IrInstSrcIdSwitchElseVar: 374 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchElseVar *>(inst)); 375 case IrInstSrcIdSwitchTarget: 376 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSwitchTarget *>(inst)); 377 case IrInstSrcIdImport: 378 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcImport *>(inst)); 379 case IrInstSrcIdRef: 380 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcRef *>(inst)); 381 case IrInstSrcIdCompileErr: 382 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCompileErr *>(inst)); 383 case IrInstSrcIdCompileLog: 384 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCompileLog *>(inst)); 385 case IrInstSrcIdErrName: 386 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrName *>(inst)); 387 case IrInstSrcIdCImport: 388 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCImport *>(inst)); 389 case IrInstSrcIdCInclude: 390 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCInclude *>(inst)); 391 case IrInstSrcIdCDefine: 392 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCDefine *>(inst)); 393 case IrInstSrcIdCUndef: 394 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCUndef *>(inst)); 395 case IrInstSrcIdEmbedFile: 396 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEmbedFile *>(inst)); 397 case IrInstSrcIdCmpxchg: 398 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCmpxchg *>(inst)); 399 case IrInstSrcIdFence: 400 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFence *>(inst)); 401 case IrInstSrcIdTruncate: 402 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTruncate *>(inst)); 403 case IrInstSrcIdIntCast: 404 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntCast *>(inst)); 405 case IrInstSrcIdFloatCast: 406 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst)); 407 case IrInstSrcIdErrSetCast: 408 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst)); 409 case IrInstSrcIdIntToFloat: 410 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst)); 411 case IrInstSrcIdFloatToInt: 412 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatToInt *>(inst)); 413 case IrInstSrcIdBoolToInt: 414 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolToInt *>(inst)); 415 case IrInstSrcIdVectorType: 416 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVectorType *>(inst)); 417 case IrInstSrcIdShuffleVector: 418 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcShuffleVector *>(inst)); 419 case IrInstSrcIdSplat: 420 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSplat *>(inst)); 421 case IrInstSrcIdBoolNot: 422 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolNot *>(inst)); 423 case IrInstSrcIdMemset: 424 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemset *>(inst)); 425 case IrInstSrcIdMemcpy: 426 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemcpy *>(inst)); 427 case IrInstSrcIdSlice: 428 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSlice *>(inst)); 429 case IrInstSrcIdBreakpoint: 430 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBreakpoint *>(inst)); 431 case IrInstSrcIdReturnAddress: 432 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcReturnAddress *>(inst)); 433 case IrInstSrcIdFrameAddress: 434 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameAddress *>(inst)); 435 case IrInstSrcIdFrameHandle: 436 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameHandle *>(inst)); 437 case IrInstSrcIdFrameType: 438 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameType *>(inst)); 439 case IrInstSrcIdFrameSize: 440 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFrameSize *>(inst)); 441 case IrInstSrcIdAlignOf: 442 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlignOf *>(inst)); 443 case IrInstSrcIdOverflowOp: 444 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOverflowOp *>(inst)); 445 case IrInstSrcIdTestErr: 446 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestErr *>(inst)); 447 case IrInstSrcIdUnwrapErrCode: 448 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnwrapErrCode *>(inst)); 449 case IrInstSrcIdUnwrapErrPayload: 450 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnwrapErrPayload *>(inst)); 451 case IrInstSrcIdFnProto: 452 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFnProto *>(inst)); 453 case IrInstSrcIdTestComptime: 454 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTestComptime *>(inst)); 455 case IrInstSrcIdPtrCast: 456 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrCast *>(inst)); 457 case IrInstSrcIdBitCast: 458 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitCast *>(inst)); 459 case IrInstSrcIdPtrToInt: 460 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrToInt *>(inst)); 461 case IrInstSrcIdIntToPtr: 462 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToPtr *>(inst)); 463 case IrInstSrcIdIntToEnum: 464 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToEnum *>(inst)); 465 case IrInstSrcIdIntToErr: 466 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToErr *>(inst)); 467 case IrInstSrcIdErrToInt: 468 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrToInt *>(inst)); 469 case IrInstSrcIdCheckSwitchProngs: 470 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckSwitchProngs *>(inst)); 471 case IrInstSrcIdCheckStatementIsVoid: 472 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckStatementIsVoid *>(inst)); 473 case IrInstSrcIdTypeName: 474 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeName *>(inst)); 475 case IrInstSrcIdTagName: 476 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTagName *>(inst)); 477 case IrInstSrcIdPtrType: 478 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPtrType *>(inst)); 479 case IrInstSrcIdDeclRef: 480 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcDeclRef *>(inst)); 481 case IrInstSrcIdPanic: 482 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcPanic *>(inst)); 483 case IrInstSrcIdFieldParentPtr: 484 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFieldParentPtr *>(inst)); 485 case IrInstSrcIdByteOffsetOf: 486 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcByteOffsetOf *>(inst)); 487 case IrInstSrcIdBitOffsetOf: 488 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBitOffsetOf *>(inst)); 489 case IrInstSrcIdTypeInfo: 490 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeInfo *>(inst)); 491 case IrInstSrcIdType: 492 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcType *>(inst)); 493 case IrInstSrcIdHasField: 494 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasField *>(inst)); 495 case IrInstSrcIdSetEvalBranchQuota: 496 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetEvalBranchQuota *>(inst)); 497 case IrInstSrcIdAlignCast: 498 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlignCast *>(inst)); 499 case IrInstSrcIdImplicitCast: 500 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcImplicitCast *>(inst)); 501 case IrInstSrcIdResolveResult: 502 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResolveResult *>(inst)); 503 case IrInstSrcIdResetResult: 504 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResetResult *>(inst)); 505 case IrInstSrcIdOpaqueType: 506 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcOpaqueType *>(inst)); 507 case IrInstSrcIdSetAlignStack: 508 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetAlignStack *>(inst)); 509 case IrInstSrcIdArgType: 510 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcArgType *>(inst)); 511 case IrInstSrcIdTagType: 512 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTagType *>(inst)); 513 case IrInstSrcIdExport: 514 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcExport *>(inst)); 515 case IrInstSrcIdErrorReturnTrace: 516 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrorReturnTrace *>(inst)); 517 case IrInstSrcIdErrorUnion: 518 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrorUnion *>(inst)); 519 case IrInstSrcIdAtomicRmw: 520 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicRmw *>(inst)); 521 case IrInstSrcIdSaveErrRetAddr: 522 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSaveErrRetAddr *>(inst)); 523 case IrInstSrcIdAddImplicitReturnType: 524 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAddImplicitReturnType *>(inst)); 525 case IrInstSrcIdFloatOp: 526 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatOp *>(inst)); 527 case IrInstSrcIdMulAdd: 528 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMulAdd *>(inst)); 529 case IrInstSrcIdAtomicLoad: 530 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicLoad *>(inst)); 531 case IrInstSrcIdAtomicStore: 532 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAtomicStore *>(inst)); 533 case IrInstSrcIdEnumToInt: 534 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEnumToInt *>(inst)); 535 case IrInstSrcIdCheckRuntimeScope: 536 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCheckRuntimeScope *>(inst)); 537 case IrInstSrcIdHasDecl: 538 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasDecl *>(inst)); 539 case IrInstSrcIdUndeclaredIdent: 540 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUndeclaredIdent *>(inst)); 541 case IrInstSrcIdAlloca: 542 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAlloca *>(inst)); 543 case IrInstSrcIdEndExpr: 544 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcEndExpr *>(inst)); 545 case IrInstSrcIdUnionInitNamedField: 546 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcUnionInitNamedField *>(inst)); 547 case IrInstSrcIdSuspendBegin: 548 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSuspendBegin *>(inst)); 549 case IrInstSrcIdSuspendFinish: 550 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSuspendFinish *>(inst)); 551 case IrInstSrcIdResume: 552 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcResume *>(inst)); 553 case IrInstSrcIdAwait: 554 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcAwait *>(inst)); 555 case IrInstSrcIdSpillBegin: 556 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSpillBegin *>(inst)); 557 case IrInstSrcIdSpillEnd: 558 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSpillEnd *>(inst)); 559 case IrInstSrcIdCallArgs: 560 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcCallArgs *>(inst)); 561 case IrInstSrcIdWasmMemorySize: 562 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcWasmMemorySize *>(inst)); 563 case IrInstSrcIdWasmMemoryGrow: 564 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcWasmMemoryGrow *>(inst)); 565 case IrInstSrcIdSrc: 566 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSrc *>(inst)); 567 } 568 zig_unreachable(); 569 } 570 571 void destroy_instruction_gen(IrInstGen *inst) { 572 switch (inst->id) { 573 case IrInstGenIdInvalid: 574 zig_unreachable(); 575 case IrInstGenIdReturn: 576 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenReturn *>(inst)); 577 case IrInstGenIdConst: 578 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenConst *>(inst)); 579 case IrInstGenIdBinOp: 580 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinOp *>(inst)); 581 case IrInstGenIdCast: 582 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCast *>(inst)); 583 case IrInstGenIdCall: 584 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCall *>(inst)); 585 case IrInstGenIdCondBr: 586 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCondBr *>(inst)); 587 case IrInstGenIdBr: 588 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBr *>(inst)); 589 case IrInstGenIdPhi: 590 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPhi *>(inst)); 591 case IrInstGenIdUnreachable: 592 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnreachable *>(inst)); 593 case IrInstGenIdElemPtr: 594 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenElemPtr *>(inst)); 595 case IrInstGenIdVarPtr: 596 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVarPtr *>(inst)); 597 case IrInstGenIdReturnPtr: 598 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenReturnPtr *>(inst)); 599 case IrInstGenIdLoadPtr: 600 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenLoadPtr *>(inst)); 601 case IrInstGenIdStorePtr: 602 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenStorePtr *>(inst)); 603 case IrInstGenIdVectorStoreElem: 604 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVectorStoreElem *>(inst)); 605 case IrInstGenIdStructFieldPtr: 606 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenStructFieldPtr *>(inst)); 607 case IrInstGenIdUnionFieldPtr: 608 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnionFieldPtr *>(inst)); 609 case IrInstGenIdAsm: 610 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAsm *>(inst)); 611 case IrInstGenIdTestNonNull: 612 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTestNonNull *>(inst)); 613 case IrInstGenIdOptionalUnwrapPtr: 614 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenOptionalUnwrapPtr *>(inst)); 615 case IrInstGenIdPopCount: 616 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPopCount *>(inst)); 617 case IrInstGenIdClz: 618 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenClz *>(inst)); 619 case IrInstGenIdCtz: 620 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCtz *>(inst)); 621 case IrInstGenIdBswap: 622 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBswap *>(inst)); 623 case IrInstGenIdBitReverse: 624 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBitReverse *>(inst)); 625 case IrInstGenIdSwitchBr: 626 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSwitchBr *>(inst)); 627 case IrInstGenIdUnionTag: 628 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnionTag *>(inst)); 629 case IrInstGenIdRef: 630 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenRef *>(inst)); 631 case IrInstGenIdErrName: 632 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrName *>(inst)); 633 case IrInstGenIdCmpxchg: 634 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenCmpxchg *>(inst)); 635 case IrInstGenIdFence: 636 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFence *>(inst)); 637 case IrInstGenIdTruncate: 638 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTruncate *>(inst)); 639 case IrInstGenIdShuffleVector: 640 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenShuffleVector *>(inst)); 641 case IrInstGenIdSplat: 642 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSplat *>(inst)); 643 case IrInstGenIdBoolNot: 644 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBoolNot *>(inst)); 645 case IrInstGenIdMemset: 646 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenMemset *>(inst)); 647 case IrInstGenIdMemcpy: 648 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenMemcpy *>(inst)); 649 case IrInstGenIdSlice: 650 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSlice *>(inst)); 651 case IrInstGenIdBreakpoint: 652 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBreakpoint *>(inst)); 653 case IrInstGenIdReturnAddress: 654 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenReturnAddress *>(inst)); 655 case IrInstGenIdFrameAddress: 656 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFrameAddress *>(inst)); 657 case IrInstGenIdFrameHandle: 658 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFrameHandle *>(inst)); 659 case IrInstGenIdFrameSize: 660 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFrameSize *>(inst)); 661 case IrInstGenIdOverflowOp: 662 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenOverflowOp *>(inst)); 663 case IrInstGenIdTestErr: 664 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTestErr *>(inst)); 665 case IrInstGenIdUnwrapErrCode: 666 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnwrapErrCode *>(inst)); 667 case IrInstGenIdUnwrapErrPayload: 668 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenUnwrapErrPayload *>(inst)); 669 case IrInstGenIdOptionalWrap: 670 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenOptionalWrap *>(inst)); 671 case IrInstGenIdErrWrapCode: 672 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrWrapCode *>(inst)); 673 case IrInstGenIdErrWrapPayload: 674 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrWrapPayload *>(inst)); 675 case IrInstGenIdPtrCast: 676 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPtrCast *>(inst)); 677 case IrInstGenIdBitCast: 678 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBitCast *>(inst)); 679 case IrInstGenIdWidenOrShorten: 680 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWidenOrShorten *>(inst)); 681 case IrInstGenIdPtrToInt: 682 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPtrToInt *>(inst)); 683 case IrInstGenIdIntToPtr: 684 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenIntToPtr *>(inst)); 685 case IrInstGenIdIntToEnum: 686 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenIntToEnum *>(inst)); 687 case IrInstGenIdIntToErr: 688 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenIntToErr *>(inst)); 689 case IrInstGenIdErrToInt: 690 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrToInt *>(inst)); 691 case IrInstGenIdTagName: 692 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenTagName *>(inst)); 693 case IrInstGenIdPanic: 694 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPanic *>(inst)); 695 case IrInstGenIdFieldParentPtr: 696 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFieldParentPtr *>(inst)); 697 case IrInstGenIdAlignCast: 698 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlignCast *>(inst)); 699 case IrInstGenIdErrorReturnTrace: 700 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenErrorReturnTrace *>(inst)); 701 case IrInstGenIdAtomicRmw: 702 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAtomicRmw *>(inst)); 703 case IrInstGenIdSaveErrRetAddr: 704 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSaveErrRetAddr *>(inst)); 705 case IrInstGenIdFloatOp: 706 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenFloatOp *>(inst)); 707 case IrInstGenIdMulAdd: 708 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenMulAdd *>(inst)); 709 case IrInstGenIdAtomicLoad: 710 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAtomicLoad *>(inst)); 711 case IrInstGenIdAtomicStore: 712 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAtomicStore *>(inst)); 713 case IrInstGenIdDeclVar: 714 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenDeclVar *>(inst)); 715 case IrInstGenIdArrayToVector: 716 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenArrayToVector *>(inst)); 717 case IrInstGenIdVectorToArray: 718 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVectorToArray *>(inst)); 719 case IrInstGenIdPtrOfArrayToSlice: 720 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenPtrOfArrayToSlice *>(inst)); 721 case IrInstGenIdAssertZero: 722 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertZero *>(inst)); 723 case IrInstGenIdAssertNonNull: 724 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertNonNull *>(inst)); 725 case IrInstGenIdAlloca: 726 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlloca *>(inst)); 727 case IrInstGenIdSuspendBegin: 728 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSuspendBegin *>(inst)); 729 case IrInstGenIdSuspendFinish: 730 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSuspendFinish *>(inst)); 731 case IrInstGenIdResume: 732 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenResume *>(inst)); 733 case IrInstGenIdAwait: 734 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAwait *>(inst)); 735 case IrInstGenIdSpillBegin: 736 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSpillBegin *>(inst)); 737 case IrInstGenIdSpillEnd: 738 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenSpillEnd *>(inst)); 739 case IrInstGenIdVectorExtractElem: 740 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenVectorExtractElem *>(inst)); 741 case IrInstGenIdBinaryNot: 742 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenBinaryNot *>(inst)); 743 case IrInstGenIdNegation: 744 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegation *>(inst)); 745 case IrInstGenIdNegationWrapping: 746 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenNegationWrapping *>(inst)); 747 case IrInstGenIdWasmMemorySize: 748 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWasmMemorySize *>(inst)); 749 case IrInstGenIdWasmMemoryGrow: 750 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenWasmMemoryGrow *>(inst)); 751 } 752 zig_unreachable(); 753 } 754 755 static void ira_ref(IrAnalyze *ira) { 756 ira->ref_count += 1; 757 } 758 static void ira_deref(IrAnalyze *ira) { 759 if (ira->ref_count > 1) { 760 ira->ref_count -= 1; 761 762 // immediate destruction of dangling IrInstGenConst is not possible 763 // free tracking memory because it will never be used 764 ira->new_irb.constants.deinit(&heap::c_allocator); 765 return; 766 } 767 assert(ira->ref_count != 0); 768 769 for (size_t bb_i = 0; bb_i < ira->old_irb.exec->basic_block_list.length; bb_i += 1) { 770 IrBasicBlockSrc *pass1_bb = ira->old_irb.exec->basic_block_list.items[bb_i]; 771 for (size_t inst_i = 0; inst_i < pass1_bb->instruction_list.length; inst_i += 1) { 772 IrInstSrc *pass1_inst = pass1_bb->instruction_list.items[inst_i]; 773 destroy_instruction_src(pass1_inst); 774 } 775 heap::c_allocator.destroy(pass1_bb); 776 } 777 ira->old_irb.exec->basic_block_list.deinit(); 778 ira->old_irb.exec->tld_list.deinit(); 779 heap::c_allocator.destroy(ira->old_irb.exec); 780 ira->src_implicit_return_type_list.deinit(); 781 ira->resume_stack.deinit(); 782 783 // destroy dangling IrInstGenConst 784 for (size_t i = 0; i < ira->new_irb.constants.length; i += 1) { 785 auto constant = ira->new_irb.constants.items[i]; 786 if (constant->base.base.ref_count == 0 && !ir_inst_gen_has_side_effects(&constant->base)) 787 destroy_instruction_gen(&constant->base); 788 } 789 ira->new_irb.constants.deinit(&heap::c_allocator); 790 791 heap::c_allocator.destroy(ira); 792 } 793 794 static ZigValue *const_ptr_pointee_unchecked_no_isf(CodeGen *g, ZigValue *const_val) { 795 assert(get_src_ptr_type(const_val->type) != nullptr); 796 assert(const_val->special == ConstValSpecialStatic); 797 798 switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { 799 case OnePossibleValueInvalid: 800 return nullptr; 801 case OnePossibleValueYes: 802 return get_the_one_possible_value(g, const_val->type->data.pointer.child_type); 803 case OnePossibleValueNo: 804 break; 805 } 806 807 ZigValue *result; 808 switch (const_val->data.x_ptr.special) { 809 case ConstPtrSpecialInvalid: 810 zig_unreachable(); 811 case ConstPtrSpecialRef: 812 result = const_val->data.x_ptr.data.ref.pointee; 813 break; 814 case ConstPtrSpecialBaseArray: { 815 ZigValue *array_val = const_val->data.x_ptr.data.base_array.array_val; 816 size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index; 817 if (elem_index == array_val->type->data.array.len) { 818 result = array_val->type->data.array.sentinel; 819 } else { 820 expand_undef_array(g, array_val); 821 result = &array_val->data.x_array.data.s_none.elements[elem_index]; 822 } 823 break; 824 } 825 case ConstPtrSpecialSubArray: { 826 ZigValue *array_val = const_val->data.x_ptr.data.base_array.array_val; 827 size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index; 828 829 // TODO handle sentinel terminated arrays 830 expand_undef_array(g, array_val); 831 result = g->pass1_arena->create<ZigValue>(); 832 result->special = array_val->special; 833 result->type = get_array_type(g, array_val->type->data.array.child_type, 834 array_val->type->data.array.len - elem_index, nullptr); 835 result->data.x_array.special = ConstArraySpecialNone; 836 result->data.x_array.data.s_none.elements = &array_val->data.x_array.data.s_none.elements[elem_index]; 837 result->parent.id = ConstParentIdArray; 838 result->parent.data.p_array.array_val = array_val; 839 result->parent.data.p_array.elem_index = elem_index; 840 break; 841 } 842 case ConstPtrSpecialBaseStruct: { 843 ZigValue *struct_val = const_val->data.x_ptr.data.base_struct.struct_val; 844 expand_undef_struct(g, struct_val); 845 result = struct_val->data.x_struct.fields[const_val->data.x_ptr.data.base_struct.field_index]; 846 break; 847 } 848 case ConstPtrSpecialBaseErrorUnionCode: 849 result = const_val->data.x_ptr.data.base_err_union_code.err_union_val->data.x_err_union.error_set; 850 break; 851 case ConstPtrSpecialBaseErrorUnionPayload: 852 result = const_val->data.x_ptr.data.base_err_union_payload.err_union_val->data.x_err_union.payload; 853 break; 854 case ConstPtrSpecialBaseOptionalPayload: 855 result = const_val->data.x_ptr.data.base_optional_payload.optional_val->data.x_optional; 856 break; 857 case ConstPtrSpecialNull: 858 result = const_val; 859 break; 860 case ConstPtrSpecialHardCodedAddr: 861 zig_unreachable(); 862 case ConstPtrSpecialDiscard: 863 zig_unreachable(); 864 case ConstPtrSpecialFunction: 865 zig_unreachable(); 866 } 867 assert(result != nullptr); 868 return result; 869 } 870 871 static ZigValue *const_ptr_pointee_unchecked(CodeGen *g, ZigValue *const_val) { 872 assert(get_src_ptr_type(const_val->type) != nullptr); 873 assert(const_val->special == ConstValSpecialStatic); 874 875 InferredStructField *isf = const_val->type->data.pointer.inferred_struct_field; 876 if (isf != nullptr) { 877 TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); 878 assert(field != nullptr); 879 if (field->is_comptime) { 880 assert(field->init_val != nullptr); 881 return field->init_val; 882 } 883 ZigValue *struct_val = const_ptr_pointee_unchecked_no_isf(g, const_val); 884 assert(struct_val->type->id == ZigTypeIdStruct); 885 return struct_val->data.x_struct.fields[field->src_index]; 886 } 887 888 return const_ptr_pointee_unchecked_no_isf(g, const_val); 889 } 890 891 static bool is_tuple(ZigType *type) { 892 return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialInferredTuple; 893 } 894 895 static bool is_slice(ZigType *type) { 896 return type->id == ZigTypeIdStruct && type->data.structure.special == StructSpecialSlice; 897 } 898 899 // This function returns true when you can change the type of a ZigValue and the 900 // value remains meaningful. 901 static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expected, ZigType *actual) { 902 if (expected == actual) 903 return true; 904 905 if (get_src_ptr_type(expected) != nullptr && get_src_ptr_type(actual) != nullptr) 906 return true; 907 908 if (is_opt_err_set(expected) && is_opt_err_set(actual)) 909 return true; 910 911 if (expected->id != actual->id) 912 return false; 913 914 switch (expected->id) { 915 case ZigTypeIdInvalid: 916 case ZigTypeIdUnreachable: 917 zig_unreachable(); 918 case ZigTypeIdMetaType: 919 case ZigTypeIdVoid: 920 case ZigTypeIdBool: 921 case ZigTypeIdComptimeFloat: 922 case ZigTypeIdComptimeInt: 923 case ZigTypeIdEnumLiteral: 924 case ZigTypeIdUndefined: 925 case ZigTypeIdNull: 926 case ZigTypeIdBoundFn: 927 case ZigTypeIdErrorSet: 928 case ZigTypeIdOpaque: 929 case ZigTypeIdAnyFrame: 930 case ZigTypeIdFn: 931 return true; 932 case ZigTypeIdPointer: 933 return expected->data.pointer.inferred_struct_field == actual->data.pointer.inferred_struct_field; 934 case ZigTypeIdFloat: 935 return expected->data.floating.bit_count == actual->data.floating.bit_count; 936 case ZigTypeIdInt: 937 return expected->data.integral.is_signed == actual->data.integral.is_signed; 938 case ZigTypeIdStruct: 939 return is_slice(expected) && is_slice(actual); 940 case ZigTypeIdOptional: 941 case ZigTypeIdErrorUnion: 942 case ZigTypeIdEnum: 943 case ZigTypeIdUnion: 944 case ZigTypeIdVector: 945 case ZigTypeIdFnFrame: 946 return false; 947 case ZigTypeIdArray: 948 return expected->data.array.len == actual->data.array.len && 949 expected->data.array.child_type == actual->data.array.child_type && 950 (expected->data.array.sentinel == nullptr || (actual->data.array.sentinel != nullptr && 951 const_values_equal(codegen, expected->data.array.sentinel, actual->data.array.sentinel))); 952 } 953 zig_unreachable(); 954 } 955 956 static bool ir_should_inline(IrExecutableSrc *exec, Scope *scope) { 957 if (exec->is_inline) 958 return true; 959 960 while (scope != nullptr) { 961 if (scope->id == ScopeIdCompTime) 962 return true; 963 if (scope->id == ScopeIdTypeOf) 964 return false; 965 if (scope->id == ScopeIdFnDef) 966 break; 967 scope = scope->parent; 968 } 969 return false; 970 } 971 972 static void ir_instruction_append(IrBasicBlockSrc *basic_block, IrInstSrc *instruction) { 973 assert(basic_block); 974 assert(instruction); 975 basic_block->instruction_list.append(instruction); 976 } 977 978 static void ir_inst_gen_append(IrBasicBlockGen *basic_block, IrInstGen *instruction) { 979 assert(basic_block); 980 assert(instruction); 981 basic_block->instruction_list.append(instruction); 982 } 983 984 static size_t exec_next_debug_id(IrExecutableSrc *exec) { 985 size_t result = exec->next_debug_id; 986 exec->next_debug_id += 1; 987 return result; 988 } 989 990 static size_t exec_next_debug_id_gen(IrExecutableGen *exec) { 991 size_t result = exec->next_debug_id; 992 exec->next_debug_id += 1; 993 return result; 994 } 995 996 static ZigFn *exec_fn_entry(IrExecutableSrc *exec) { 997 return exec->fn_entry; 998 } 999 1000 static Buf *exec_c_import_buf(IrExecutableSrc *exec) { 1001 return exec->c_import_buf; 1002 } 1003 1004 static bool value_is_comptime(ZigValue *const_val) { 1005 return const_val->special != ConstValSpecialRuntime; 1006 } 1007 1008 static bool instr_is_comptime(IrInstGen *instruction) { 1009 return value_is_comptime(instruction->value); 1010 } 1011 1012 static bool instr_is_unreachable(IrInstSrc *instruction) { 1013 return instruction->is_noreturn; 1014 } 1015 1016 static void ir_ref_bb(IrBasicBlockSrc *bb) { 1017 bb->ref_count += 1; 1018 } 1019 1020 static void ir_ref_instruction(IrInstSrc *instruction, IrBasicBlockSrc *cur_bb) { 1021 assert(instruction->id != IrInstSrcIdInvalid); 1022 instruction->base.ref_count += 1; 1023 if (instruction->owner_bb != cur_bb && !instr_is_unreachable(instruction) 1024 && instruction->id != IrInstSrcIdConst) 1025 { 1026 ir_ref_bb(instruction->owner_bb); 1027 } 1028 } 1029 1030 static void ir_ref_inst_gen(IrInstGen *instruction) { 1031 assert(instruction->id != IrInstGenIdInvalid); 1032 instruction->base.ref_count += 1; 1033 } 1034 1035 static void ir_ref_var(ZigVar *var) { 1036 var->ref_count += 1; 1037 } 1038 1039 static void create_result_ptr(CodeGen *codegen, ZigType *expected_type, 1040 ZigValue **out_result, ZigValue **out_result_ptr) 1041 { 1042 ZigValue *result = codegen->pass1_arena->create<ZigValue>(); 1043 ZigValue *result_ptr = codegen->pass1_arena->create<ZigValue>(); 1044 result->special = ConstValSpecialUndef; 1045 result->type = expected_type; 1046 result_ptr->special = ConstValSpecialStatic; 1047 result_ptr->type = get_pointer_to_type(codegen, result->type, false); 1048 result_ptr->data.x_ptr.mut = ConstPtrMutComptimeVar; 1049 result_ptr->data.x_ptr.special = ConstPtrSpecialRef; 1050 result_ptr->data.x_ptr.data.ref.pointee = result; 1051 1052 *out_result = result; 1053 *out_result_ptr = result_ptr; 1054 } 1055 1056 ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) { 1057 Error err; 1058 1059 ZigValue *result; 1060 ZigValue *result_ptr; 1061 create_result_ptr(ira->codegen, ira->codegen->builtin_types.entry_type, &result, &result_ptr); 1062 1063 if ((err = ir_eval_const_value(ira->codegen, scope, node, result_ptr, 1064 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 1065 nullptr, nullptr, node, nullptr, ira->new_irb.exec, nullptr, UndefBad))) 1066 { 1067 return ira->codegen->builtin_types.entry_invalid; 1068 } 1069 if (type_is_invalid(result->type)) 1070 return ira->codegen->builtin_types.entry_invalid; 1071 1072 assert(result->special != ConstValSpecialRuntime); 1073 ZigType *res_type = result->data.x_type; 1074 1075 return res_type; 1076 } 1077 1078 static IrBasicBlockSrc *ir_create_basic_block(IrBuilderSrc *irb, Scope *scope, const char *name_hint) { 1079 IrBasicBlockSrc *result = heap::c_allocator.create<IrBasicBlockSrc>(); 1080 result->scope = scope; 1081 result->name_hint = name_hint; 1082 result->debug_id = exec_next_debug_id(irb->exec); 1083 result->index = UINT32_MAX; // set later 1084 return result; 1085 } 1086 1087 static IrBasicBlockGen *ir_create_basic_block_gen(IrAnalyze *ira, Scope *scope, const char *name_hint) { 1088 IrBasicBlockGen *result = heap::c_allocator.create<IrBasicBlockGen>(); 1089 result->scope = scope; 1090 result->name_hint = name_hint; 1091 result->debug_id = exec_next_debug_id_gen(ira->new_irb.exec); 1092 return result; 1093 } 1094 1095 static IrBasicBlockGen *ir_build_bb_from(IrAnalyze *ira, IrBasicBlockSrc *other_bb) { 1096 IrBasicBlockGen *new_bb = ir_create_basic_block_gen(ira, other_bb->scope, other_bb->name_hint); 1097 other_bb->child = new_bb; 1098 return new_bb; 1099 } 1100 1101 static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclVar *) { 1102 return IrInstSrcIdDeclVar; 1103 } 1104 1105 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBr *) { 1106 return IrInstSrcIdBr; 1107 } 1108 1109 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCondBr *) { 1110 return IrInstSrcIdCondBr; 1111 } 1112 1113 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchBr *) { 1114 return IrInstSrcIdSwitchBr; 1115 } 1116 1117 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchVar *) { 1118 return IrInstSrcIdSwitchVar; 1119 } 1120 1121 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchElseVar *) { 1122 return IrInstSrcIdSwitchElseVar; 1123 } 1124 1125 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSwitchTarget *) { 1126 return IrInstSrcIdSwitchTarget; 1127 } 1128 1129 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPhi *) { 1130 return IrInstSrcIdPhi; 1131 } 1132 1133 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnOp *) { 1134 return IrInstSrcIdUnOp; 1135 } 1136 1137 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBinOp *) { 1138 return IrInstSrcIdBinOp; 1139 } 1140 1141 static constexpr IrInstSrcId ir_inst_id(IrInstSrcMergeErrSets *) { 1142 return IrInstSrcIdMergeErrSets; 1143 } 1144 1145 static constexpr IrInstSrcId ir_inst_id(IrInstSrcLoadPtr *) { 1146 return IrInstSrcIdLoadPtr; 1147 } 1148 1149 static constexpr IrInstSrcId ir_inst_id(IrInstSrcStorePtr *) { 1150 return IrInstSrcIdStorePtr; 1151 } 1152 1153 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldPtr *) { 1154 return IrInstSrcIdFieldPtr; 1155 } 1156 1157 static constexpr IrInstSrcId ir_inst_id(IrInstSrcElemPtr *) { 1158 return IrInstSrcIdElemPtr; 1159 } 1160 1161 static constexpr IrInstSrcId ir_inst_id(IrInstSrcVarPtr *) { 1162 return IrInstSrcIdVarPtr; 1163 } 1164 1165 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCall *) { 1166 return IrInstSrcIdCall; 1167 } 1168 1169 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallArgs *) { 1170 return IrInstSrcIdCallArgs; 1171 } 1172 1173 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCallExtra *) { 1174 return IrInstSrcIdCallExtra; 1175 } 1176 1177 static constexpr IrInstSrcId ir_inst_id(IrInstSrcConst *) { 1178 return IrInstSrcIdConst; 1179 } 1180 1181 static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturn *) { 1182 return IrInstSrcIdReturn; 1183 } 1184 1185 static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitList *) { 1186 return IrInstSrcIdContainerInitList; 1187 } 1188 1189 static constexpr IrInstSrcId ir_inst_id(IrInstSrcContainerInitFields *) { 1190 return IrInstSrcIdContainerInitFields; 1191 } 1192 1193 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnreachable *) { 1194 return IrInstSrcIdUnreachable; 1195 } 1196 1197 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeOf *) { 1198 return IrInstSrcIdTypeOf; 1199 } 1200 1201 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetCold *) { 1202 return IrInstSrcIdSetCold; 1203 } 1204 1205 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetRuntimeSafety *) { 1206 return IrInstSrcIdSetRuntimeSafety; 1207 } 1208 1209 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetFloatMode *) { 1210 return IrInstSrcIdSetFloatMode; 1211 } 1212 1213 static constexpr IrInstSrcId ir_inst_id(IrInstSrcArrayType *) { 1214 return IrInstSrcIdArrayType; 1215 } 1216 1217 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAnyFrameType *) { 1218 return IrInstSrcIdAnyFrameType; 1219 } 1220 1221 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSliceType *) { 1222 return IrInstSrcIdSliceType; 1223 } 1224 1225 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAsm *) { 1226 return IrInstSrcIdAsm; 1227 } 1228 1229 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSizeOf *) { 1230 return IrInstSrcIdSizeOf; 1231 } 1232 1233 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestNonNull *) { 1234 return IrInstSrcIdTestNonNull; 1235 } 1236 1237 static constexpr IrInstSrcId ir_inst_id(IrInstSrcOptionalUnwrapPtr *) { 1238 return IrInstSrcIdOptionalUnwrapPtr; 1239 } 1240 1241 static constexpr IrInstSrcId ir_inst_id(IrInstSrcClz *) { 1242 return IrInstSrcIdClz; 1243 } 1244 1245 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCtz *) { 1246 return IrInstSrcIdCtz; 1247 } 1248 1249 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPopCount *) { 1250 return IrInstSrcIdPopCount; 1251 } 1252 1253 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBswap *) { 1254 return IrInstSrcIdBswap; 1255 } 1256 1257 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitReverse *) { 1258 return IrInstSrcIdBitReverse; 1259 } 1260 1261 static constexpr IrInstSrcId ir_inst_id(IrInstSrcImport *) { 1262 return IrInstSrcIdImport; 1263 } 1264 1265 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCImport *) { 1266 return IrInstSrcIdCImport; 1267 } 1268 1269 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCInclude *) { 1270 return IrInstSrcIdCInclude; 1271 } 1272 1273 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCDefine *) { 1274 return IrInstSrcIdCDefine; 1275 } 1276 1277 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCUndef *) { 1278 return IrInstSrcIdCUndef; 1279 } 1280 1281 static constexpr IrInstSrcId ir_inst_id(IrInstSrcRef *) { 1282 return IrInstSrcIdRef; 1283 } 1284 1285 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileErr *) { 1286 return IrInstSrcIdCompileErr; 1287 } 1288 1289 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCompileLog *) { 1290 return IrInstSrcIdCompileLog; 1291 } 1292 1293 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrName *) { 1294 return IrInstSrcIdErrName; 1295 } 1296 1297 static constexpr IrInstSrcId ir_inst_id(IrInstSrcEmbedFile *) { 1298 return IrInstSrcIdEmbedFile; 1299 } 1300 1301 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCmpxchg *) { 1302 return IrInstSrcIdCmpxchg; 1303 } 1304 1305 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFence *) { 1306 return IrInstSrcIdFence; 1307 } 1308 1309 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTruncate *) { 1310 return IrInstSrcIdTruncate; 1311 } 1312 1313 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntCast *) { 1314 return IrInstSrcIdIntCast; 1315 } 1316 1317 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatCast *) { 1318 return IrInstSrcIdFloatCast; 1319 } 1320 1321 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToFloat *) { 1322 return IrInstSrcIdIntToFloat; 1323 } 1324 1325 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatToInt *) { 1326 return IrInstSrcIdFloatToInt; 1327 } 1328 1329 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolToInt *) { 1330 return IrInstSrcIdBoolToInt; 1331 } 1332 1333 static constexpr IrInstSrcId ir_inst_id(IrInstSrcVectorType *) { 1334 return IrInstSrcIdVectorType; 1335 } 1336 1337 static constexpr IrInstSrcId ir_inst_id(IrInstSrcShuffleVector *) { 1338 return IrInstSrcIdShuffleVector; 1339 } 1340 1341 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSplat *) { 1342 return IrInstSrcIdSplat; 1343 } 1344 1345 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolNot *) { 1346 return IrInstSrcIdBoolNot; 1347 } 1348 1349 static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemset *) { 1350 return IrInstSrcIdMemset; 1351 } 1352 1353 static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemcpy *) { 1354 return IrInstSrcIdMemcpy; 1355 } 1356 1357 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSlice *) { 1358 return IrInstSrcIdSlice; 1359 } 1360 1361 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBreakpoint *) { 1362 return IrInstSrcIdBreakpoint; 1363 } 1364 1365 static constexpr IrInstSrcId ir_inst_id(IrInstSrcReturnAddress *) { 1366 return IrInstSrcIdReturnAddress; 1367 } 1368 1369 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameAddress *) { 1370 return IrInstSrcIdFrameAddress; 1371 } 1372 1373 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameHandle *) { 1374 return IrInstSrcIdFrameHandle; 1375 } 1376 1377 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameType *) { 1378 return IrInstSrcIdFrameType; 1379 } 1380 1381 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFrameSize *) { 1382 return IrInstSrcIdFrameSize; 1383 } 1384 1385 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignOf *) { 1386 return IrInstSrcIdAlignOf; 1387 } 1388 1389 static constexpr IrInstSrcId ir_inst_id(IrInstSrcOverflowOp *) { 1390 return IrInstSrcIdOverflowOp; 1391 } 1392 1393 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestErr *) { 1394 return IrInstSrcIdTestErr; 1395 } 1396 1397 static constexpr IrInstSrcId ir_inst_id(IrInstSrcMulAdd *) { 1398 return IrInstSrcIdMulAdd; 1399 } 1400 1401 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFloatOp *) { 1402 return IrInstSrcIdFloatOp; 1403 } 1404 1405 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrCode *) { 1406 return IrInstSrcIdUnwrapErrCode; 1407 } 1408 1409 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnwrapErrPayload *) { 1410 return IrInstSrcIdUnwrapErrPayload; 1411 } 1412 1413 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFnProto *) { 1414 return IrInstSrcIdFnProto; 1415 } 1416 1417 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTestComptime *) { 1418 return IrInstSrcIdTestComptime; 1419 } 1420 1421 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrCast *) { 1422 return IrInstSrcIdPtrCast; 1423 } 1424 1425 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitCast *) { 1426 return IrInstSrcIdBitCast; 1427 } 1428 1429 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToPtr *) { 1430 return IrInstSrcIdIntToPtr; 1431 } 1432 1433 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrToInt *) { 1434 return IrInstSrcIdPtrToInt; 1435 } 1436 1437 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToEnum *) { 1438 return IrInstSrcIdIntToEnum; 1439 } 1440 1441 static constexpr IrInstSrcId ir_inst_id(IrInstSrcEnumToInt *) { 1442 return IrInstSrcIdEnumToInt; 1443 } 1444 1445 static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntToErr *) { 1446 return IrInstSrcIdIntToErr; 1447 } 1448 1449 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrToInt *) { 1450 return IrInstSrcIdErrToInt; 1451 } 1452 1453 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckSwitchProngs *) { 1454 return IrInstSrcIdCheckSwitchProngs; 1455 } 1456 1457 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckStatementIsVoid *) { 1458 return IrInstSrcIdCheckStatementIsVoid; 1459 } 1460 1461 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeName *) { 1462 return IrInstSrcIdTypeName; 1463 } 1464 1465 static constexpr IrInstSrcId ir_inst_id(IrInstSrcDeclRef *) { 1466 return IrInstSrcIdDeclRef; 1467 } 1468 1469 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPanic *) { 1470 return IrInstSrcIdPanic; 1471 } 1472 1473 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTagName *) { 1474 return IrInstSrcIdTagName; 1475 } 1476 1477 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTagType *) { 1478 return IrInstSrcIdTagType; 1479 } 1480 1481 static constexpr IrInstSrcId ir_inst_id(IrInstSrcFieldParentPtr *) { 1482 return IrInstSrcIdFieldParentPtr; 1483 } 1484 1485 static constexpr IrInstSrcId ir_inst_id(IrInstSrcByteOffsetOf *) { 1486 return IrInstSrcIdByteOffsetOf; 1487 } 1488 1489 static constexpr IrInstSrcId ir_inst_id(IrInstSrcBitOffsetOf *) { 1490 return IrInstSrcIdBitOffsetOf; 1491 } 1492 1493 static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeInfo *) { 1494 return IrInstSrcIdTypeInfo; 1495 } 1496 1497 static constexpr IrInstSrcId ir_inst_id(IrInstSrcType *) { 1498 return IrInstSrcIdType; 1499 } 1500 1501 static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasField *) { 1502 return IrInstSrcIdHasField; 1503 } 1504 1505 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetEvalBranchQuota *) { 1506 return IrInstSrcIdSetEvalBranchQuota; 1507 } 1508 1509 static constexpr IrInstSrcId ir_inst_id(IrInstSrcPtrType *) { 1510 return IrInstSrcIdPtrType; 1511 } 1512 1513 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlignCast *) { 1514 return IrInstSrcIdAlignCast; 1515 } 1516 1517 static constexpr IrInstSrcId ir_inst_id(IrInstSrcImplicitCast *) { 1518 return IrInstSrcIdImplicitCast; 1519 } 1520 1521 static constexpr IrInstSrcId ir_inst_id(IrInstSrcResolveResult *) { 1522 return IrInstSrcIdResolveResult; 1523 } 1524 1525 static constexpr IrInstSrcId ir_inst_id(IrInstSrcResetResult *) { 1526 return IrInstSrcIdResetResult; 1527 } 1528 1529 static constexpr IrInstSrcId ir_inst_id(IrInstSrcOpaqueType *) { 1530 return IrInstSrcIdOpaqueType; 1531 } 1532 1533 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetAlignStack *) { 1534 return IrInstSrcIdSetAlignStack; 1535 } 1536 1537 static constexpr IrInstSrcId ir_inst_id(IrInstSrcArgType *) { 1538 return IrInstSrcIdArgType; 1539 } 1540 1541 static constexpr IrInstSrcId ir_inst_id(IrInstSrcExport *) { 1542 return IrInstSrcIdExport; 1543 } 1544 1545 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorReturnTrace *) { 1546 return IrInstSrcIdErrorReturnTrace; 1547 } 1548 1549 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrorUnion *) { 1550 return IrInstSrcIdErrorUnion; 1551 } 1552 1553 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicRmw *) { 1554 return IrInstSrcIdAtomicRmw; 1555 } 1556 1557 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicLoad *) { 1558 return IrInstSrcIdAtomicLoad; 1559 } 1560 1561 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAtomicStore *) { 1562 return IrInstSrcIdAtomicStore; 1563 } 1564 1565 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSaveErrRetAddr *) { 1566 return IrInstSrcIdSaveErrRetAddr; 1567 } 1568 1569 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAddImplicitReturnType *) { 1570 return IrInstSrcIdAddImplicitReturnType; 1571 } 1572 1573 static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrSetCast *) { 1574 return IrInstSrcIdErrSetCast; 1575 } 1576 1577 static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckRuntimeScope *) { 1578 return IrInstSrcIdCheckRuntimeScope; 1579 } 1580 1581 static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasDecl *) { 1582 return IrInstSrcIdHasDecl; 1583 } 1584 1585 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUndeclaredIdent *) { 1586 return IrInstSrcIdUndeclaredIdent; 1587 } 1588 1589 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAlloca *) { 1590 return IrInstSrcIdAlloca; 1591 } 1592 1593 static constexpr IrInstSrcId ir_inst_id(IrInstSrcEndExpr *) { 1594 return IrInstSrcIdEndExpr; 1595 } 1596 1597 static constexpr IrInstSrcId ir_inst_id(IrInstSrcUnionInitNamedField *) { 1598 return IrInstSrcIdUnionInitNamedField; 1599 } 1600 1601 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSuspendBegin *) { 1602 return IrInstSrcIdSuspendBegin; 1603 } 1604 1605 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSuspendFinish *) { 1606 return IrInstSrcIdSuspendFinish; 1607 } 1608 1609 static constexpr IrInstSrcId ir_inst_id(IrInstSrcAwait *) { 1610 return IrInstSrcIdAwait; 1611 } 1612 1613 static constexpr IrInstSrcId ir_inst_id(IrInstSrcResume *) { 1614 return IrInstSrcIdResume; 1615 } 1616 1617 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSpillBegin *) { 1618 return IrInstSrcIdSpillBegin; 1619 } 1620 1621 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSpillEnd *) { 1622 return IrInstSrcIdSpillEnd; 1623 } 1624 1625 static constexpr IrInstSrcId ir_inst_id(IrInstSrcWasmMemorySize *) { 1626 return IrInstSrcIdWasmMemorySize; 1627 } 1628 1629 static constexpr IrInstSrcId ir_inst_id(IrInstSrcWasmMemoryGrow *) { 1630 return IrInstSrcIdWasmMemoryGrow; 1631 } 1632 1633 static constexpr IrInstSrcId ir_inst_id(IrInstSrcSrc *) { 1634 return IrInstSrcIdSrc; 1635 } 1636 1637 static constexpr IrInstGenId ir_inst_id(IrInstGenDeclVar *) { 1638 return IrInstGenIdDeclVar; 1639 } 1640 1641 static constexpr IrInstGenId ir_inst_id(IrInstGenBr *) { 1642 return IrInstGenIdBr; 1643 } 1644 1645 static constexpr IrInstGenId ir_inst_id(IrInstGenCondBr *) { 1646 return IrInstGenIdCondBr; 1647 } 1648 1649 static constexpr IrInstGenId ir_inst_id(IrInstGenSwitchBr *) { 1650 return IrInstGenIdSwitchBr; 1651 } 1652 1653 static constexpr IrInstGenId ir_inst_id(IrInstGenPhi *) { 1654 return IrInstGenIdPhi; 1655 } 1656 1657 static constexpr IrInstGenId ir_inst_id(IrInstGenBinaryNot *) { 1658 return IrInstGenIdBinaryNot; 1659 } 1660 1661 static constexpr IrInstGenId ir_inst_id(IrInstGenNegation *) { 1662 return IrInstGenIdNegation; 1663 } 1664 1665 static constexpr IrInstGenId ir_inst_id(IrInstGenNegationWrapping *) { 1666 return IrInstGenIdNegationWrapping; 1667 } 1668 1669 static constexpr IrInstGenId ir_inst_id(IrInstGenBinOp *) { 1670 return IrInstGenIdBinOp; 1671 } 1672 1673 static constexpr IrInstGenId ir_inst_id(IrInstGenLoadPtr *) { 1674 return IrInstGenIdLoadPtr; 1675 } 1676 1677 static constexpr IrInstGenId ir_inst_id(IrInstGenStorePtr *) { 1678 return IrInstGenIdStorePtr; 1679 } 1680 1681 static constexpr IrInstGenId ir_inst_id(IrInstGenVectorStoreElem *) { 1682 return IrInstGenIdVectorStoreElem; 1683 } 1684 1685 static constexpr IrInstGenId ir_inst_id(IrInstGenStructFieldPtr *) { 1686 return IrInstGenIdStructFieldPtr; 1687 } 1688 1689 static constexpr IrInstGenId ir_inst_id(IrInstGenUnionFieldPtr *) { 1690 return IrInstGenIdUnionFieldPtr; 1691 } 1692 1693 static constexpr IrInstGenId ir_inst_id(IrInstGenElemPtr *) { 1694 return IrInstGenIdElemPtr; 1695 } 1696 1697 static constexpr IrInstGenId ir_inst_id(IrInstGenVarPtr *) { 1698 return IrInstGenIdVarPtr; 1699 } 1700 1701 static constexpr IrInstGenId ir_inst_id(IrInstGenReturnPtr *) { 1702 return IrInstGenIdReturnPtr; 1703 } 1704 1705 static constexpr IrInstGenId ir_inst_id(IrInstGenCall *) { 1706 return IrInstGenIdCall; 1707 } 1708 1709 static constexpr IrInstGenId ir_inst_id(IrInstGenReturn *) { 1710 return IrInstGenIdReturn; 1711 } 1712 1713 static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) { 1714 return IrInstGenIdCast; 1715 } 1716 1717 static constexpr IrInstGenId ir_inst_id(IrInstGenUnreachable *) { 1718 return IrInstGenIdUnreachable; 1719 } 1720 1721 static constexpr IrInstGenId ir_inst_id(IrInstGenAsm *) { 1722 return IrInstGenIdAsm; 1723 } 1724 1725 static constexpr IrInstGenId ir_inst_id(IrInstGenTestNonNull *) { 1726 return IrInstGenIdTestNonNull; 1727 } 1728 1729 static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalUnwrapPtr *) { 1730 return IrInstGenIdOptionalUnwrapPtr; 1731 } 1732 1733 static constexpr IrInstGenId ir_inst_id(IrInstGenOptionalWrap *) { 1734 return IrInstGenIdOptionalWrap; 1735 } 1736 1737 static constexpr IrInstGenId ir_inst_id(IrInstGenUnionTag *) { 1738 return IrInstGenIdUnionTag; 1739 } 1740 1741 static constexpr IrInstGenId ir_inst_id(IrInstGenClz *) { 1742 return IrInstGenIdClz; 1743 } 1744 1745 static constexpr IrInstGenId ir_inst_id(IrInstGenCtz *) { 1746 return IrInstGenIdCtz; 1747 } 1748 1749 static constexpr IrInstGenId ir_inst_id(IrInstGenPopCount *) { 1750 return IrInstGenIdPopCount; 1751 } 1752 1753 static constexpr IrInstGenId ir_inst_id(IrInstGenBswap *) { 1754 return IrInstGenIdBswap; 1755 } 1756 1757 static constexpr IrInstGenId ir_inst_id(IrInstGenBitReverse *) { 1758 return IrInstGenIdBitReverse; 1759 } 1760 1761 static constexpr IrInstGenId ir_inst_id(IrInstGenRef *) { 1762 return IrInstGenIdRef; 1763 } 1764 1765 static constexpr IrInstGenId ir_inst_id(IrInstGenErrName *) { 1766 return IrInstGenIdErrName; 1767 } 1768 1769 static constexpr IrInstGenId ir_inst_id(IrInstGenCmpxchg *) { 1770 return IrInstGenIdCmpxchg; 1771 } 1772 1773 static constexpr IrInstGenId ir_inst_id(IrInstGenFence *) { 1774 return IrInstGenIdFence; 1775 } 1776 1777 static constexpr IrInstGenId ir_inst_id(IrInstGenTruncate *) { 1778 return IrInstGenIdTruncate; 1779 } 1780 1781 static constexpr IrInstGenId ir_inst_id(IrInstGenShuffleVector *) { 1782 return IrInstGenIdShuffleVector; 1783 } 1784 1785 static constexpr IrInstGenId ir_inst_id(IrInstGenSplat *) { 1786 return IrInstGenIdSplat; 1787 } 1788 1789 static constexpr IrInstGenId ir_inst_id(IrInstGenBoolNot *) { 1790 return IrInstGenIdBoolNot; 1791 } 1792 1793 static constexpr IrInstGenId ir_inst_id(IrInstGenMemset *) { 1794 return IrInstGenIdMemset; 1795 } 1796 1797 static constexpr IrInstGenId ir_inst_id(IrInstGenMemcpy *) { 1798 return IrInstGenIdMemcpy; 1799 } 1800 1801 static constexpr IrInstGenId ir_inst_id(IrInstGenSlice *) { 1802 return IrInstGenIdSlice; 1803 } 1804 1805 static constexpr IrInstGenId ir_inst_id(IrInstGenBreakpoint *) { 1806 return IrInstGenIdBreakpoint; 1807 } 1808 1809 static constexpr IrInstGenId ir_inst_id(IrInstGenReturnAddress *) { 1810 return IrInstGenIdReturnAddress; 1811 } 1812 1813 static constexpr IrInstGenId ir_inst_id(IrInstGenFrameAddress *) { 1814 return IrInstGenIdFrameAddress; 1815 } 1816 1817 static constexpr IrInstGenId ir_inst_id(IrInstGenFrameHandle *) { 1818 return IrInstGenIdFrameHandle; 1819 } 1820 1821 static constexpr IrInstGenId ir_inst_id(IrInstGenFrameSize *) { 1822 return IrInstGenIdFrameSize; 1823 } 1824 1825 static constexpr IrInstGenId ir_inst_id(IrInstGenOverflowOp *) { 1826 return IrInstGenIdOverflowOp; 1827 } 1828 1829 static constexpr IrInstGenId ir_inst_id(IrInstGenTestErr *) { 1830 return IrInstGenIdTestErr; 1831 } 1832 1833 static constexpr IrInstGenId ir_inst_id(IrInstGenMulAdd *) { 1834 return IrInstGenIdMulAdd; 1835 } 1836 1837 static constexpr IrInstGenId ir_inst_id(IrInstGenFloatOp *) { 1838 return IrInstGenIdFloatOp; 1839 } 1840 1841 static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrCode *) { 1842 return IrInstGenIdUnwrapErrCode; 1843 } 1844 1845 static constexpr IrInstGenId ir_inst_id(IrInstGenUnwrapErrPayload *) { 1846 return IrInstGenIdUnwrapErrPayload; 1847 } 1848 1849 static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapCode *) { 1850 return IrInstGenIdErrWrapCode; 1851 } 1852 1853 static constexpr IrInstGenId ir_inst_id(IrInstGenErrWrapPayload *) { 1854 return IrInstGenIdErrWrapPayload; 1855 } 1856 1857 static constexpr IrInstGenId ir_inst_id(IrInstGenPtrCast *) { 1858 return IrInstGenIdPtrCast; 1859 } 1860 1861 static constexpr IrInstGenId ir_inst_id(IrInstGenBitCast *) { 1862 return IrInstGenIdBitCast; 1863 } 1864 1865 static constexpr IrInstGenId ir_inst_id(IrInstGenWidenOrShorten *) { 1866 return IrInstGenIdWidenOrShorten; 1867 } 1868 1869 static constexpr IrInstGenId ir_inst_id(IrInstGenIntToPtr *) { 1870 return IrInstGenIdIntToPtr; 1871 } 1872 1873 static constexpr IrInstGenId ir_inst_id(IrInstGenPtrToInt *) { 1874 return IrInstGenIdPtrToInt; 1875 } 1876 1877 static constexpr IrInstGenId ir_inst_id(IrInstGenIntToEnum *) { 1878 return IrInstGenIdIntToEnum; 1879 } 1880 1881 static constexpr IrInstGenId ir_inst_id(IrInstGenIntToErr *) { 1882 return IrInstGenIdIntToErr; 1883 } 1884 1885 static constexpr IrInstGenId ir_inst_id(IrInstGenErrToInt *) { 1886 return IrInstGenIdErrToInt; 1887 } 1888 1889 static constexpr IrInstGenId ir_inst_id(IrInstGenPanic *) { 1890 return IrInstGenIdPanic; 1891 } 1892 1893 static constexpr IrInstGenId ir_inst_id(IrInstGenTagName *) { 1894 return IrInstGenIdTagName; 1895 } 1896 1897 static constexpr IrInstGenId ir_inst_id(IrInstGenFieldParentPtr *) { 1898 return IrInstGenIdFieldParentPtr; 1899 } 1900 1901 static constexpr IrInstGenId ir_inst_id(IrInstGenAlignCast *) { 1902 return IrInstGenIdAlignCast; 1903 } 1904 1905 static constexpr IrInstGenId ir_inst_id(IrInstGenErrorReturnTrace *) { 1906 return IrInstGenIdErrorReturnTrace; 1907 } 1908 1909 static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicRmw *) { 1910 return IrInstGenIdAtomicRmw; 1911 } 1912 1913 static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicLoad *) { 1914 return IrInstGenIdAtomicLoad; 1915 } 1916 1917 static constexpr IrInstGenId ir_inst_id(IrInstGenAtomicStore *) { 1918 return IrInstGenIdAtomicStore; 1919 } 1920 1921 static constexpr IrInstGenId ir_inst_id(IrInstGenSaveErrRetAddr *) { 1922 return IrInstGenIdSaveErrRetAddr; 1923 } 1924 1925 static constexpr IrInstGenId ir_inst_id(IrInstGenVectorToArray *) { 1926 return IrInstGenIdVectorToArray; 1927 } 1928 1929 static constexpr IrInstGenId ir_inst_id(IrInstGenArrayToVector *) { 1930 return IrInstGenIdArrayToVector; 1931 } 1932 1933 static constexpr IrInstGenId ir_inst_id(IrInstGenAssertZero *) { 1934 return IrInstGenIdAssertZero; 1935 } 1936 1937 static constexpr IrInstGenId ir_inst_id(IrInstGenAssertNonNull *) { 1938 return IrInstGenIdAssertNonNull; 1939 } 1940 1941 static constexpr IrInstGenId ir_inst_id(IrInstGenPtrOfArrayToSlice *) { 1942 return IrInstGenIdPtrOfArrayToSlice; 1943 } 1944 1945 static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendBegin *) { 1946 return IrInstGenIdSuspendBegin; 1947 } 1948 1949 static constexpr IrInstGenId ir_inst_id(IrInstGenSuspendFinish *) { 1950 return IrInstGenIdSuspendFinish; 1951 } 1952 1953 static constexpr IrInstGenId ir_inst_id(IrInstGenAwait *) { 1954 return IrInstGenIdAwait; 1955 } 1956 1957 static constexpr IrInstGenId ir_inst_id(IrInstGenResume *) { 1958 return IrInstGenIdResume; 1959 } 1960 1961 static constexpr IrInstGenId ir_inst_id(IrInstGenSpillBegin *) { 1962 return IrInstGenIdSpillBegin; 1963 } 1964 1965 static constexpr IrInstGenId ir_inst_id(IrInstGenSpillEnd *) { 1966 return IrInstGenIdSpillEnd; 1967 } 1968 1969 static constexpr IrInstGenId ir_inst_id(IrInstGenVectorExtractElem *) { 1970 return IrInstGenIdVectorExtractElem; 1971 } 1972 1973 static constexpr IrInstGenId ir_inst_id(IrInstGenAlloca *) { 1974 return IrInstGenIdAlloca; 1975 } 1976 1977 static constexpr IrInstGenId ir_inst_id(IrInstGenConst *) { 1978 return IrInstGenIdConst; 1979 } 1980 1981 static constexpr IrInstGenId ir_inst_id(IrInstGenWasmMemorySize *) { 1982 return IrInstGenIdWasmMemorySize; 1983 } 1984 1985 static constexpr IrInstGenId ir_inst_id(IrInstGenWasmMemoryGrow *) { 1986 return IrInstGenIdWasmMemoryGrow; 1987 } 1988 1989 template<typename T> 1990 static T *ir_create_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 1991 T *special_instruction = heap::c_allocator.create<T>(); 1992 special_instruction->base.id = ir_inst_id(special_instruction); 1993 special_instruction->base.base.scope = scope; 1994 special_instruction->base.base.source_node = source_node; 1995 special_instruction->base.base.debug_id = exec_next_debug_id(irb->exec); 1996 special_instruction->base.owner_bb = irb->current_basic_block; 1997 return special_instruction; 1998 } 1999 2000 template<typename T> 2001 static T *ir_create_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 2002 T *special_instruction = heap::c_allocator.create<T>(); 2003 special_instruction->base.id = ir_inst_id(special_instruction); 2004 special_instruction->base.base.scope = scope; 2005 special_instruction->base.base.source_node = source_node; 2006 special_instruction->base.base.debug_id = exec_next_debug_id_gen(irb->exec); 2007 special_instruction->base.owner_bb = irb->current_basic_block; 2008 special_instruction->base.value = irb->codegen->pass1_arena->create<ZigValue>(); 2009 return special_instruction; 2010 } 2011 2012 template<typename T> 2013 static T *ir_create_inst_noval(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 2014 T *special_instruction = heap::c_allocator.create<T>(); 2015 special_instruction->base.id = ir_inst_id(special_instruction); 2016 special_instruction->base.base.scope = scope; 2017 special_instruction->base.base.source_node = source_node; 2018 special_instruction->base.base.debug_id = exec_next_debug_id_gen(irb->exec); 2019 special_instruction->base.owner_bb = irb->current_basic_block; 2020 return special_instruction; 2021 } 2022 2023 template<typename T> 2024 static T *ir_build_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2025 T *special_instruction = ir_create_instruction<T>(irb, scope, source_node); 2026 ir_instruction_append(irb->current_basic_block, &special_instruction->base); 2027 return special_instruction; 2028 } 2029 2030 template<typename T> 2031 static T *ir_build_inst_gen(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 2032 T *special_instruction = ir_create_inst_gen<T>(irb, scope, source_node); 2033 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base); 2034 return special_instruction; 2035 } 2036 2037 template<typename T> 2038 static T *ir_build_inst_noreturn(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 2039 T *special_instruction = ir_create_inst_noval<T>(irb, scope, source_node); 2040 special_instruction->base.value = irb->codegen->intern.for_unreachable(); 2041 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base); 2042 return special_instruction; 2043 } 2044 2045 template<typename T> 2046 static T *ir_build_inst_void(IrBuilderGen *irb, Scope *scope, AstNode *source_node) { 2047 T *special_instruction = ir_create_inst_noval<T>(irb, scope, source_node); 2048 special_instruction->base.value = irb->codegen->intern.for_void(); 2049 ir_inst_gen_append(irb->current_basic_block, &special_instruction->base); 2050 return special_instruction; 2051 } 2052 2053 IrInstGen *ir_create_alloca(CodeGen *g, Scope *scope, AstNode *source_node, ZigFn *fn, 2054 ZigType *var_type, const char *name_hint) 2055 { 2056 IrInstGenAlloca *alloca_gen = heap::c_allocator.create<IrInstGenAlloca>(); 2057 alloca_gen->base.id = IrInstGenIdAlloca; 2058 alloca_gen->base.base.source_node = source_node; 2059 alloca_gen->base.base.scope = scope; 2060 alloca_gen->base.value = g->pass1_arena->create<ZigValue>(); 2061 alloca_gen->base.value->type = get_pointer_to_type(g, var_type, false); 2062 alloca_gen->base.base.ref_count = 1; 2063 alloca_gen->name_hint = name_hint; 2064 fn->alloca_gen_list.append(alloca_gen); 2065 return &alloca_gen->base; 2066 } 2067 2068 static IrInstGen *ir_build_cast(IrAnalyze *ira, IrInst *source_instr,ZigType *dest_type, 2069 IrInstGen *value, CastOp cast_op) 2070 { 2071 IrInstGenCast *inst = ir_build_inst_gen<IrInstGenCast>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2072 inst->base.value->type = dest_type; 2073 inst->value = value; 2074 inst->cast_op = cast_op; 2075 2076 ir_ref_inst_gen(value); 2077 2078 return &inst->base; 2079 } 2080 2081 static IrInstSrc *ir_build_cond_br(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *condition, 2082 IrBasicBlockSrc *then_block, IrBasicBlockSrc *else_block, IrInstSrc *is_comptime) 2083 { 2084 IrInstSrcCondBr *inst = ir_build_instruction<IrInstSrcCondBr>(irb, scope, source_node); 2085 inst->base.is_noreturn = true; 2086 inst->condition = condition; 2087 inst->then_block = then_block; 2088 inst->else_block = else_block; 2089 inst->is_comptime = is_comptime; 2090 2091 ir_ref_instruction(condition, irb->current_basic_block); 2092 ir_ref_bb(then_block); 2093 ir_ref_bb(else_block); 2094 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); 2095 2096 return &inst->base; 2097 } 2098 2099 static IrInstGen *ir_build_cond_br_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *condition, 2100 IrBasicBlockGen *then_block, IrBasicBlockGen *else_block) 2101 { 2102 IrInstGenCondBr *inst = ir_build_inst_noreturn<IrInstGenCondBr>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2103 inst->condition = condition; 2104 inst->then_block = then_block; 2105 inst->else_block = else_block; 2106 2107 ir_ref_inst_gen(condition); 2108 2109 return &inst->base; 2110 } 2111 2112 static IrInstSrc *ir_build_return_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *operand) { 2113 IrInstSrcReturn *inst = ir_build_instruction<IrInstSrcReturn>(irb, scope, source_node); 2114 inst->base.is_noreturn = true; 2115 inst->operand = operand; 2116 2117 if (operand != nullptr) ir_ref_instruction(operand, irb->current_basic_block); 2118 2119 return &inst->base; 2120 } 2121 2122 static IrInstGen *ir_build_return_gen(IrAnalyze *ira, IrInst *source_inst, IrInstGen *operand) { 2123 IrInstGenReturn *inst = ir_build_inst_noreturn<IrInstGenReturn>(&ira->new_irb, 2124 source_inst->scope, source_inst->source_node); 2125 inst->operand = operand; 2126 2127 if (operand != nullptr) ir_ref_inst_gen(operand); 2128 2129 return &inst->base; 2130 } 2131 2132 static IrInstSrc *ir_build_const_void(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2133 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2134 ir_instruction_append(irb->current_basic_block, &const_instruction->base); 2135 const_instruction->value = irb->codegen->intern.for_void(); 2136 return &const_instruction->base; 2137 } 2138 2139 static IrInstSrc *ir_build_const_undefined(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2140 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2141 ir_instruction_append(irb->current_basic_block, &const_instruction->base); 2142 const_instruction->value = irb->codegen->intern.for_undefined(); 2143 return &const_instruction->base; 2144 } 2145 2146 static IrInstSrc *ir_build_const_uint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, uint64_t value) { 2147 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2148 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2149 const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_int; 2150 const_instruction->value->special = ConstValSpecialStatic; 2151 bigint_init_unsigned(&const_instruction->value->data.x_bigint, value); 2152 return &const_instruction->base; 2153 } 2154 2155 static IrInstSrc *ir_build_const_bigint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigInt *bigint) { 2156 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2157 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2158 const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_int; 2159 const_instruction->value->special = ConstValSpecialStatic; 2160 bigint_init_bigint(&const_instruction->value->data.x_bigint, bigint); 2161 return &const_instruction->base; 2162 } 2163 2164 static IrInstSrc *ir_build_const_bigfloat(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, BigFloat *bigfloat) { 2165 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2166 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2167 const_instruction->value->type = irb->codegen->builtin_types.entry_num_lit_float; 2168 const_instruction->value->special = ConstValSpecialStatic; 2169 bigfloat_init_bigfloat(&const_instruction->value->data.x_bigfloat, bigfloat); 2170 return &const_instruction->base; 2171 } 2172 2173 static IrInstSrc *ir_build_const_null(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2174 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2175 ir_instruction_append(irb->current_basic_block, &const_instruction->base); 2176 const_instruction->value = irb->codegen->intern.for_null(); 2177 return &const_instruction->base; 2178 } 2179 2180 static IrInstSrc *ir_build_const_usize(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, uint64_t value) { 2181 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2182 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2183 const_instruction->value->type = irb->codegen->builtin_types.entry_usize; 2184 const_instruction->value->special = ConstValSpecialStatic; 2185 bigint_init_unsigned(&const_instruction->value->data.x_bigint, value); 2186 return &const_instruction->base; 2187 } 2188 2189 static IrInstSrc *ir_create_const_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2190 ZigType *type_entry) 2191 { 2192 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2193 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2194 const_instruction->value->type = irb->codegen->builtin_types.entry_type; 2195 const_instruction->value->special = ConstValSpecialStatic; 2196 const_instruction->value->data.x_type = type_entry; 2197 return &const_instruction->base; 2198 } 2199 2200 static IrInstSrc *ir_build_const_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2201 ZigType *type_entry) 2202 { 2203 IrInstSrc *instruction = ir_create_const_type(irb, scope, source_node, type_entry); 2204 ir_instruction_append(irb->current_basic_block, instruction); 2205 return instruction; 2206 } 2207 2208 static IrInstSrc *ir_build_const_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigType *import) { 2209 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2210 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2211 const_instruction->value->type = irb->codegen->builtin_types.entry_type; 2212 const_instruction->value->special = ConstValSpecialStatic; 2213 const_instruction->value->data.x_type = import; 2214 return &const_instruction->base; 2215 } 2216 2217 static IrInstSrc *ir_build_const_bool(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, bool value) { 2218 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2219 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2220 const_instruction->value->type = irb->codegen->builtin_types.entry_bool; 2221 const_instruction->value->special = ConstValSpecialStatic; 2222 const_instruction->value->data.x_bool = value; 2223 return &const_instruction->base; 2224 } 2225 2226 static IrInstSrc *ir_build_const_enum_literal(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *name) { 2227 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, source_node); 2228 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2229 const_instruction->value->type = irb->codegen->builtin_types.entry_enum_literal; 2230 const_instruction->value->special = ConstValSpecialStatic; 2231 const_instruction->value->data.x_enum_literal = name; 2232 return &const_instruction->base; 2233 } 2234 2235 static IrInstSrc *ir_create_const_str_lit(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *str) { 2236 IrInstSrcConst *const_instruction = ir_create_instruction<IrInstSrcConst>(irb, scope, source_node); 2237 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 2238 init_const_str_lit(irb->codegen, const_instruction->value, str); 2239 2240 return &const_instruction->base; 2241 } 2242 2243 static IrInstSrc *ir_build_const_str_lit(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *str) { 2244 IrInstSrc *instruction = ir_create_const_str_lit(irb, scope, source_node, str); 2245 ir_instruction_append(irb->current_basic_block, instruction); 2246 return instruction; 2247 } 2248 2249 static IrInstSrc *ir_build_bin_op(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, 2250 IrInstSrc *op1, IrInstSrc *op2, bool safety_check_on) 2251 { 2252 IrInstSrcBinOp *inst = ir_build_instruction<IrInstSrcBinOp>(irb, scope, source_node); 2253 inst->op_id = op_id; 2254 inst->op1 = op1; 2255 inst->op2 = op2; 2256 inst->safety_check_on = safety_check_on; 2257 2258 ir_ref_instruction(op1, irb->current_basic_block); 2259 ir_ref_instruction(op2, irb->current_basic_block); 2260 2261 return &inst->base; 2262 } 2263 2264 static IrInstGen *ir_build_bin_op_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *res_type, 2265 IrBinOp op_id, IrInstGen *op1, IrInstGen *op2, bool safety_check_on) 2266 { 2267 IrInstGenBinOp *inst = ir_build_inst_gen<IrInstGenBinOp>(&ira->new_irb, 2268 source_instr->scope, source_instr->source_node); 2269 inst->base.value->type = res_type; 2270 inst->op_id = op_id; 2271 inst->op1 = op1; 2272 inst->op2 = op2; 2273 inst->safety_check_on = safety_check_on; 2274 2275 ir_ref_inst_gen(op1); 2276 ir_ref_inst_gen(op2); 2277 2278 return &inst->base; 2279 } 2280 2281 2282 static IrInstSrc *ir_build_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2283 IrInstSrc *op1, IrInstSrc *op2, Buf *type_name) 2284 { 2285 IrInstSrcMergeErrSets *inst = ir_build_instruction<IrInstSrcMergeErrSets>(irb, scope, source_node); 2286 inst->op1 = op1; 2287 inst->op2 = op2; 2288 inst->type_name = type_name; 2289 2290 ir_ref_instruction(op1, irb->current_basic_block); 2291 ir_ref_instruction(op2, irb->current_basic_block); 2292 2293 return &inst->base; 2294 } 2295 2296 static IrInstSrc *ir_build_var_ptr_x(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var, 2297 ScopeFnDef *crossed_fndef_scope) 2298 { 2299 IrInstSrcVarPtr *instruction = ir_build_instruction<IrInstSrcVarPtr>(irb, scope, source_node); 2300 instruction->var = var; 2301 instruction->crossed_fndef_scope = crossed_fndef_scope; 2302 2303 ir_ref_var(var); 2304 2305 return &instruction->base; 2306 } 2307 2308 static IrInstSrc *ir_build_var_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var) { 2309 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr); 2310 } 2311 2312 static IrInstGen *ir_build_var_ptr_gen(IrAnalyze *ira, IrInst *source_instr, ZigVar *var) { 2313 IrInstGenVarPtr *instruction = ir_build_inst_gen<IrInstGenVarPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2314 instruction->var = var; 2315 2316 ir_ref_var(var); 2317 2318 return &instruction->base; 2319 } 2320 2321 static IrInstGen *ir_build_return_ptr(IrAnalyze *ira, Scope *scope, AstNode *source_node, ZigType *ty) { 2322 IrInstGenReturnPtr *instruction = ir_build_inst_gen<IrInstGenReturnPtr>(&ira->new_irb, scope, source_node); 2323 instruction->base.value->type = ty; 2324 return &instruction->base; 2325 } 2326 2327 static IrInstSrc *ir_build_elem_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2328 IrInstSrc *array_ptr, IrInstSrc *elem_index, bool safety_check_on, PtrLen ptr_len, 2329 AstNode *init_array_type_source_node) 2330 { 2331 IrInstSrcElemPtr *instruction = ir_build_instruction<IrInstSrcElemPtr>(irb, scope, source_node); 2332 instruction->array_ptr = array_ptr; 2333 instruction->elem_index = elem_index; 2334 instruction->safety_check_on = safety_check_on; 2335 instruction->ptr_len = ptr_len; 2336 instruction->init_array_type_source_node = init_array_type_source_node; 2337 2338 ir_ref_instruction(array_ptr, irb->current_basic_block); 2339 ir_ref_instruction(elem_index, irb->current_basic_block); 2340 2341 return &instruction->base; 2342 } 2343 2344 static IrInstGen *ir_build_elem_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 2345 IrInstGen *array_ptr, IrInstGen *elem_index, bool safety_check_on, ZigType *return_type) 2346 { 2347 IrInstGenElemPtr *instruction = ir_build_inst_gen<IrInstGenElemPtr>(&ira->new_irb, scope, source_node); 2348 instruction->base.value->type = return_type; 2349 instruction->array_ptr = array_ptr; 2350 instruction->elem_index = elem_index; 2351 instruction->safety_check_on = safety_check_on; 2352 2353 ir_ref_inst_gen(array_ptr); 2354 ir_ref_inst_gen(elem_index); 2355 2356 return &instruction->base; 2357 } 2358 2359 static IrInstSrc *ir_build_field_ptr_instruction(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2360 IrInstSrc *container_ptr, IrInstSrc *field_name_expr, bool initializing) 2361 { 2362 IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(irb, scope, source_node); 2363 instruction->container_ptr = container_ptr; 2364 instruction->field_name_buffer = nullptr; 2365 instruction->field_name_expr = field_name_expr; 2366 instruction->initializing = initializing; 2367 2368 ir_ref_instruction(container_ptr, irb->current_basic_block); 2369 ir_ref_instruction(field_name_expr, irb->current_basic_block); 2370 2371 return &instruction->base; 2372 } 2373 2374 static IrInstSrc *ir_build_field_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2375 IrInstSrc *container_ptr, Buf *field_name, bool initializing) 2376 { 2377 IrInstSrcFieldPtr *instruction = ir_build_instruction<IrInstSrcFieldPtr>(irb, scope, source_node); 2378 instruction->container_ptr = container_ptr; 2379 instruction->field_name_buffer = field_name; 2380 instruction->field_name_expr = nullptr; 2381 instruction->initializing = initializing; 2382 2383 ir_ref_instruction(container_ptr, irb->current_basic_block); 2384 2385 return &instruction->base; 2386 } 2387 2388 static IrInstSrc *ir_build_has_field(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2389 IrInstSrc *container_type, IrInstSrc *field_name) 2390 { 2391 IrInstSrcHasField *instruction = ir_build_instruction<IrInstSrcHasField>(irb, scope, source_node); 2392 instruction->container_type = container_type; 2393 instruction->field_name = field_name; 2394 2395 ir_ref_instruction(container_type, irb->current_basic_block); 2396 ir_ref_instruction(field_name, irb->current_basic_block); 2397 2398 return &instruction->base; 2399 } 2400 2401 static IrInstGen *ir_build_struct_field_ptr(IrAnalyze *ira, IrInst *source_instr, 2402 IrInstGen *struct_ptr, TypeStructField *field, ZigType *ptr_type) 2403 { 2404 IrInstGenStructFieldPtr *inst = ir_build_inst_gen<IrInstGenStructFieldPtr>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2405 inst->base.value->type = ptr_type; 2406 inst->struct_ptr = struct_ptr; 2407 inst->field = field; 2408 2409 ir_ref_inst_gen(struct_ptr); 2410 2411 return &inst->base; 2412 } 2413 2414 static IrInstGen *ir_build_union_field_ptr(IrAnalyze *ira, IrInst *source_instr, 2415 IrInstGen *union_ptr, TypeUnionField *field, bool safety_check_on, bool initializing, ZigType *ptr_type) 2416 { 2417 IrInstGenUnionFieldPtr *inst = ir_build_inst_gen<IrInstGenUnionFieldPtr>(&ira->new_irb, 2418 source_instr->scope, source_instr->source_node); 2419 inst->base.value->type = ptr_type; 2420 inst->initializing = initializing; 2421 inst->safety_check_on = safety_check_on; 2422 inst->union_ptr = union_ptr; 2423 inst->field = field; 2424 2425 ir_ref_inst_gen(union_ptr); 2426 2427 return &inst->base; 2428 } 2429 2430 static IrInstSrc *ir_build_call_extra(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2431 IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc *args, ResultLoc *result_loc) 2432 { 2433 IrInstSrcCallExtra *call_instruction = ir_build_instruction<IrInstSrcCallExtra>(irb, scope, source_node); 2434 call_instruction->options = options; 2435 call_instruction->fn_ref = fn_ref; 2436 call_instruction->args = args; 2437 call_instruction->result_loc = result_loc; 2438 2439 ir_ref_instruction(options, irb->current_basic_block); 2440 ir_ref_instruction(fn_ref, irb->current_basic_block); 2441 ir_ref_instruction(args, irb->current_basic_block); 2442 2443 return &call_instruction->base; 2444 } 2445 2446 static IrInstSrc *ir_build_call_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2447 IrInstSrc *options, IrInstSrc *fn_ref, IrInstSrc **args_ptr, size_t args_len, 2448 ResultLoc *result_loc) 2449 { 2450 IrInstSrcCallArgs *call_instruction = ir_build_instruction<IrInstSrcCallArgs>(irb, scope, source_node); 2451 call_instruction->options = options; 2452 call_instruction->fn_ref = fn_ref; 2453 call_instruction->args_ptr = args_ptr; 2454 call_instruction->args_len = args_len; 2455 call_instruction->result_loc = result_loc; 2456 2457 ir_ref_instruction(options, irb->current_basic_block); 2458 ir_ref_instruction(fn_ref, irb->current_basic_block); 2459 for (size_t i = 0; i < args_len; i += 1) 2460 ir_ref_instruction(args_ptr[i], irb->current_basic_block); 2461 2462 return &call_instruction->base; 2463 } 2464 2465 static IrInstSrc *ir_build_call_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2466 ZigFn *fn_entry, IrInstSrc *fn_ref, size_t arg_count, IrInstSrc **args, 2467 IrInstSrc *ret_ptr, CallModifier modifier, bool is_async_call_builtin, 2468 IrInstSrc *new_stack, ResultLoc *result_loc) 2469 { 2470 IrInstSrcCall *call_instruction = ir_build_instruction<IrInstSrcCall>(irb, scope, source_node); 2471 call_instruction->fn_entry = fn_entry; 2472 call_instruction->fn_ref = fn_ref; 2473 call_instruction->args = args; 2474 call_instruction->arg_count = arg_count; 2475 call_instruction->modifier = modifier; 2476 call_instruction->is_async_call_builtin = is_async_call_builtin; 2477 call_instruction->new_stack = new_stack; 2478 call_instruction->result_loc = result_loc; 2479 call_instruction->ret_ptr = ret_ptr; 2480 2481 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, irb->current_basic_block); 2482 for (size_t i = 0; i < arg_count; i += 1) 2483 ir_ref_instruction(args[i], irb->current_basic_block); 2484 if (ret_ptr != nullptr) ir_ref_instruction(ret_ptr, irb->current_basic_block); 2485 if (new_stack != nullptr) ir_ref_instruction(new_stack, irb->current_basic_block); 2486 2487 return &call_instruction->base; 2488 } 2489 2490 static IrInstGenCall *ir_build_call_gen(IrAnalyze *ira, IrInst *source_instruction, 2491 ZigFn *fn_entry, IrInstGen *fn_ref, size_t arg_count, IrInstGen **args, 2492 CallModifier modifier, IrInstGen *new_stack, bool is_async_call_builtin, 2493 IrInstGen *result_loc, ZigType *return_type) 2494 { 2495 IrInstGenCall *call_instruction = ir_build_inst_gen<IrInstGenCall>(&ira->new_irb, 2496 source_instruction->scope, source_instruction->source_node); 2497 call_instruction->base.value->type = return_type; 2498 call_instruction->fn_entry = fn_entry; 2499 call_instruction->fn_ref = fn_ref; 2500 call_instruction->args = args; 2501 call_instruction->arg_count = arg_count; 2502 call_instruction->modifier = modifier; 2503 call_instruction->is_async_call_builtin = is_async_call_builtin; 2504 call_instruction->new_stack = new_stack; 2505 call_instruction->result_loc = result_loc; 2506 2507 if (fn_ref != nullptr) ir_ref_inst_gen(fn_ref); 2508 for (size_t i = 0; i < arg_count; i += 1) 2509 ir_ref_inst_gen(args[i]); 2510 if (new_stack != nullptr) ir_ref_inst_gen(new_stack); 2511 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 2512 2513 return call_instruction; 2514 } 2515 2516 static IrInstSrc *ir_build_phi(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2517 size_t incoming_count, IrBasicBlockSrc **incoming_blocks, IrInstSrc **incoming_values, 2518 ResultLocPeerParent *peer_parent) 2519 { 2520 assert(incoming_count != 0); 2521 assert(incoming_count != SIZE_MAX); 2522 2523 IrInstSrcPhi *phi_instruction = ir_build_instruction<IrInstSrcPhi>(irb, scope, source_node); 2524 phi_instruction->incoming_count = incoming_count; 2525 phi_instruction->incoming_blocks = incoming_blocks; 2526 phi_instruction->incoming_values = incoming_values; 2527 phi_instruction->peer_parent = peer_parent; 2528 2529 for (size_t i = 0; i < incoming_count; i += 1) { 2530 ir_ref_bb(incoming_blocks[i]); 2531 ir_ref_instruction(incoming_values[i], irb->current_basic_block); 2532 } 2533 2534 return &phi_instruction->base; 2535 } 2536 2537 static IrInstGen *ir_build_phi_gen(IrAnalyze *ira, IrInst *source_instr, size_t incoming_count, 2538 IrBasicBlockGen **incoming_blocks, IrInstGen **incoming_values, ZigType *result_type) 2539 { 2540 assert(incoming_count != 0); 2541 assert(incoming_count != SIZE_MAX); 2542 2543 IrInstGenPhi *phi_instruction = ir_build_inst_gen<IrInstGenPhi>(&ira->new_irb, 2544 source_instr->scope, source_instr->source_node); 2545 phi_instruction->base.value->type = result_type; 2546 phi_instruction->incoming_count = incoming_count; 2547 phi_instruction->incoming_blocks = incoming_blocks; 2548 phi_instruction->incoming_values = incoming_values; 2549 2550 for (size_t i = 0; i < incoming_count; i += 1) { 2551 ir_ref_inst_gen(incoming_values[i]); 2552 } 2553 2554 return &phi_instruction->base; 2555 } 2556 2557 static IrInstSrc *ir_build_br(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2558 IrBasicBlockSrc *dest_block, IrInstSrc *is_comptime) 2559 { 2560 IrInstSrcBr *inst = ir_build_instruction<IrInstSrcBr>(irb, scope, source_node); 2561 inst->base.is_noreturn = true; 2562 inst->dest_block = dest_block; 2563 inst->is_comptime = is_comptime; 2564 2565 ir_ref_bb(dest_block); 2566 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 2567 2568 return &inst->base; 2569 } 2570 2571 static IrInstGen *ir_build_br_gen(IrAnalyze *ira, IrInst *source_instr, IrBasicBlockGen *dest_block) { 2572 IrInstGenBr *inst = ir_build_inst_noreturn<IrInstGenBr>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2573 inst->dest_block = dest_block; 2574 2575 return &inst->base; 2576 } 2577 2578 static IrInstSrc *ir_build_ptr_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2579 IrInstSrc *child_type, bool is_const, bool is_volatile, PtrLen ptr_len, 2580 IrInstSrc *sentinel, IrInstSrc *align_value, 2581 uint32_t bit_offset_start, uint32_t host_int_bytes, bool is_allow_zero) 2582 { 2583 IrInstSrcPtrType *inst = ir_build_instruction<IrInstSrcPtrType>(irb, scope, source_node); 2584 inst->sentinel = sentinel; 2585 inst->align_value = align_value; 2586 inst->child_type = child_type; 2587 inst->is_const = is_const; 2588 inst->is_volatile = is_volatile; 2589 inst->ptr_len = ptr_len; 2590 inst->bit_offset_start = bit_offset_start; 2591 inst->host_int_bytes = host_int_bytes; 2592 inst->is_allow_zero = is_allow_zero; 2593 2594 if (sentinel) ir_ref_instruction(sentinel, irb->current_basic_block); 2595 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 2596 ir_ref_instruction(child_type, irb->current_basic_block); 2597 2598 return &inst->base; 2599 } 2600 2601 static IrInstSrc *ir_build_un_op_lval(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, 2602 IrInstSrc *value, LVal lval, ResultLoc *result_loc) 2603 { 2604 IrInstSrcUnOp *instruction = ir_build_instruction<IrInstSrcUnOp>(irb, scope, source_node); 2605 instruction->op_id = op_id; 2606 instruction->value = value; 2607 instruction->lval = lval; 2608 instruction->result_loc = result_loc; 2609 2610 ir_ref_instruction(value, irb->current_basic_block); 2611 2612 return &instruction->base; 2613 } 2614 2615 static IrInstSrc *ir_build_un_op(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, 2616 IrInstSrc *value) 2617 { 2618 return ir_build_un_op_lval(irb, scope, source_node, op_id, value, LValNone, nullptr); 2619 } 2620 2621 static IrInstGen *ir_build_negation(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, ZigType *expr_type) { 2622 IrInstGenNegation *instruction = ir_build_inst_gen<IrInstGenNegation>(&ira->new_irb, 2623 source_instr->scope, source_instr->source_node); 2624 instruction->base.value->type = expr_type; 2625 instruction->operand = operand; 2626 2627 ir_ref_inst_gen(operand); 2628 2629 return &instruction->base; 2630 } 2631 2632 static IrInstGen *ir_build_negation_wrapping(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, 2633 ZigType *expr_type) 2634 { 2635 IrInstGenNegationWrapping *instruction = ir_build_inst_gen<IrInstGenNegationWrapping>(&ira->new_irb, 2636 source_instr->scope, source_instr->source_node); 2637 instruction->base.value->type = expr_type; 2638 instruction->operand = operand; 2639 2640 ir_ref_inst_gen(operand); 2641 2642 return &instruction->base; 2643 } 2644 2645 static IrInstGen *ir_build_binary_not(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, 2646 ZigType *expr_type) 2647 { 2648 IrInstGenBinaryNot *instruction = ir_build_inst_gen<IrInstGenBinaryNot>(&ira->new_irb, 2649 source_instr->scope, source_instr->source_node); 2650 instruction->base.value->type = expr_type; 2651 instruction->operand = operand; 2652 2653 ir_ref_inst_gen(operand); 2654 2655 return &instruction->base; 2656 } 2657 2658 static IrInstSrc *ir_build_container_init_list(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2659 size_t item_count, IrInstSrc **elem_result_loc_list, IrInstSrc *result_loc, 2660 AstNode *init_array_type_source_node) 2661 { 2662 IrInstSrcContainerInitList *container_init_list_instruction = 2663 ir_build_instruction<IrInstSrcContainerInitList>(irb, scope, source_node); 2664 container_init_list_instruction->item_count = item_count; 2665 container_init_list_instruction->elem_result_loc_list = elem_result_loc_list; 2666 container_init_list_instruction->result_loc = result_loc; 2667 container_init_list_instruction->init_array_type_source_node = init_array_type_source_node; 2668 2669 for (size_t i = 0; i < item_count; i += 1) { 2670 ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block); 2671 } 2672 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 2673 2674 return &container_init_list_instruction->base; 2675 } 2676 2677 static IrInstSrc *ir_build_container_init_fields(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2678 size_t field_count, IrInstSrcContainerInitFieldsField *fields, IrInstSrc *result_loc) 2679 { 2680 IrInstSrcContainerInitFields *container_init_fields_instruction = 2681 ir_build_instruction<IrInstSrcContainerInitFields>(irb, scope, source_node); 2682 container_init_fields_instruction->field_count = field_count; 2683 container_init_fields_instruction->fields = fields; 2684 container_init_fields_instruction->result_loc = result_loc; 2685 2686 for (size_t i = 0; i < field_count; i += 1) { 2687 ir_ref_instruction(fields[i].result_loc, irb->current_basic_block); 2688 } 2689 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 2690 2691 return &container_init_fields_instruction->base; 2692 } 2693 2694 static IrInstSrc *ir_build_unreachable(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 2695 IrInstSrcUnreachable *inst = ir_build_instruction<IrInstSrcUnreachable>(irb, scope, source_node); 2696 inst->base.is_noreturn = true; 2697 return &inst->base; 2698 } 2699 2700 static IrInstGen *ir_build_unreachable_gen(IrAnalyze *ira, IrInst *source_instr) { 2701 IrInstGenUnreachable *inst = ir_build_inst_noreturn<IrInstGenUnreachable>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2702 return &inst->base; 2703 } 2704 2705 static IrInstSrcStorePtr *ir_build_store_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2706 IrInstSrc *ptr, IrInstSrc *value) 2707 { 2708 IrInstSrcStorePtr *instruction = ir_build_instruction<IrInstSrcStorePtr>(irb, scope, source_node); 2709 instruction->ptr = ptr; 2710 instruction->value = value; 2711 2712 ir_ref_instruction(ptr, irb->current_basic_block); 2713 ir_ref_instruction(value, irb->current_basic_block); 2714 2715 return instruction; 2716 } 2717 2718 static IrInstGen *ir_build_store_ptr_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *ptr, IrInstGen *value) { 2719 IrInstGenStorePtr *instruction = ir_build_inst_void<IrInstGenStorePtr>(&ira->new_irb, 2720 source_instr->scope, source_instr->source_node); 2721 instruction->ptr = ptr; 2722 instruction->value = value; 2723 2724 ir_ref_inst_gen(ptr); 2725 ir_ref_inst_gen(value); 2726 2727 return &instruction->base; 2728 } 2729 2730 static IrInstGen *ir_build_vector_store_elem(IrAnalyze *ira, IrInst *src_inst, 2731 IrInstGen *vector_ptr, IrInstGen *index, IrInstGen *value) 2732 { 2733 IrInstGenVectorStoreElem *inst = ir_build_inst_void<IrInstGenVectorStoreElem>( 2734 &ira->new_irb, src_inst->scope, src_inst->source_node); 2735 inst->vector_ptr = vector_ptr; 2736 inst->index = index; 2737 inst->value = value; 2738 2739 ir_ref_inst_gen(vector_ptr); 2740 ir_ref_inst_gen(index); 2741 ir_ref_inst_gen(value); 2742 2743 return &inst->base; 2744 } 2745 2746 static IrInstSrc *ir_build_var_decl_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2747 ZigVar *var, IrInstSrc *align_value, IrInstSrc *ptr) 2748 { 2749 IrInstSrcDeclVar *inst = ir_build_instruction<IrInstSrcDeclVar>(irb, scope, source_node); 2750 inst->var = var; 2751 inst->align_value = align_value; 2752 inst->ptr = ptr; 2753 2754 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 2755 ir_ref_instruction(ptr, irb->current_basic_block); 2756 2757 return &inst->base; 2758 } 2759 2760 static IrInstGen *ir_build_var_decl_gen(IrAnalyze *ira, IrInst *source_instruction, 2761 ZigVar *var, IrInstGen *var_ptr) 2762 { 2763 IrInstGenDeclVar *inst = ir_build_inst_gen<IrInstGenDeclVar>(&ira->new_irb, 2764 source_instruction->scope, source_instruction->source_node); 2765 inst->base.value->special = ConstValSpecialStatic; 2766 inst->base.value->type = ira->codegen->builtin_types.entry_void; 2767 inst->var = var; 2768 inst->var_ptr = var_ptr; 2769 2770 ir_ref_inst_gen(var_ptr); 2771 2772 return &inst->base; 2773 } 2774 2775 static IrInstSrc *ir_build_export(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2776 IrInstSrc *target, IrInstSrc *options) 2777 { 2778 IrInstSrcExport *export_instruction = ir_build_instruction<IrInstSrcExport>( 2779 irb, scope, source_node); 2780 export_instruction->target = target; 2781 export_instruction->options = options; 2782 2783 ir_ref_instruction(target, irb->current_basic_block); 2784 ir_ref_instruction(options, irb->current_basic_block); 2785 2786 return &export_instruction->base; 2787 } 2788 2789 static IrInstSrc *ir_build_load_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *ptr) { 2790 IrInstSrcLoadPtr *instruction = ir_build_instruction<IrInstSrcLoadPtr>(irb, scope, source_node); 2791 instruction->ptr = ptr; 2792 2793 ir_ref_instruction(ptr, irb->current_basic_block); 2794 2795 return &instruction->base; 2796 } 2797 2798 static IrInstGen *ir_build_load_ptr_gen(IrAnalyze *ira, IrInst *source_instruction, 2799 IrInstGen *ptr, ZigType *ty, IrInstGen *result_loc) 2800 { 2801 IrInstGenLoadPtr *instruction = ir_build_inst_gen<IrInstGenLoadPtr>( 2802 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 2803 instruction->base.value->type = ty; 2804 instruction->ptr = ptr; 2805 instruction->result_loc = result_loc; 2806 2807 ir_ref_inst_gen(ptr); 2808 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 2809 2810 return &instruction->base; 2811 } 2812 2813 static IrInstSrc *ir_build_typeof_n(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2814 IrInstSrc **values, size_t value_count) 2815 { 2816 assert(value_count >= 2); 2817 2818 IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node); 2819 instruction->value.list = values; 2820 instruction->value_count = value_count; 2821 2822 for (size_t i = 0; i < value_count; i++) 2823 ir_ref_instruction(values[i], irb->current_basic_block); 2824 2825 return &instruction->base; 2826 } 2827 2828 static IrInstSrc *ir_build_typeof_1(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 2829 IrInstSrcTypeOf *instruction = ir_build_instruction<IrInstSrcTypeOf>(irb, scope, source_node); 2830 instruction->value.scalar = value; 2831 2832 ir_ref_instruction(value, irb->current_basic_block); 2833 2834 return &instruction->base; 2835 } 2836 2837 static IrInstSrc *ir_build_set_cold(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_cold) { 2838 IrInstSrcSetCold *instruction = ir_build_instruction<IrInstSrcSetCold>(irb, scope, source_node); 2839 instruction->is_cold = is_cold; 2840 2841 ir_ref_instruction(is_cold, irb->current_basic_block); 2842 2843 return &instruction->base; 2844 } 2845 2846 static IrInstSrc *ir_build_set_runtime_safety(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2847 IrInstSrc *safety_on) 2848 { 2849 IrInstSrcSetRuntimeSafety *inst = ir_build_instruction<IrInstSrcSetRuntimeSafety>(irb, scope, source_node); 2850 inst->safety_on = safety_on; 2851 2852 ir_ref_instruction(safety_on, irb->current_basic_block); 2853 2854 return &inst->base; 2855 } 2856 2857 static IrInstSrc *ir_build_set_float_mode(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2858 IrInstSrc *mode_value) 2859 { 2860 IrInstSrcSetFloatMode *instruction = ir_build_instruction<IrInstSrcSetFloatMode>(irb, scope, source_node); 2861 instruction->mode_value = mode_value; 2862 2863 ir_ref_instruction(mode_value, irb->current_basic_block); 2864 2865 return &instruction->base; 2866 } 2867 2868 static IrInstSrc *ir_build_array_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *size, 2869 IrInstSrc *sentinel, IrInstSrc *child_type) 2870 { 2871 IrInstSrcArrayType *instruction = ir_build_instruction<IrInstSrcArrayType>(irb, scope, source_node); 2872 instruction->size = size; 2873 instruction->sentinel = sentinel; 2874 instruction->child_type = child_type; 2875 2876 ir_ref_instruction(size, irb->current_basic_block); 2877 if (sentinel != nullptr) ir_ref_instruction(sentinel, irb->current_basic_block); 2878 ir_ref_instruction(child_type, irb->current_basic_block); 2879 2880 return &instruction->base; 2881 } 2882 2883 static IrInstSrc *ir_build_anyframe_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2884 IrInstSrc *payload_type) 2885 { 2886 IrInstSrcAnyFrameType *instruction = ir_build_instruction<IrInstSrcAnyFrameType>(irb, scope, source_node); 2887 instruction->payload_type = payload_type; 2888 2889 if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block); 2890 2891 return &instruction->base; 2892 } 2893 2894 static IrInstSrc *ir_build_slice_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2895 IrInstSrc *child_type, bool is_const, bool is_volatile, 2896 IrInstSrc *sentinel, IrInstSrc *align_value, bool is_allow_zero) 2897 { 2898 IrInstSrcSliceType *instruction = ir_build_instruction<IrInstSrcSliceType>(irb, scope, source_node); 2899 instruction->is_const = is_const; 2900 instruction->is_volatile = is_volatile; 2901 instruction->child_type = child_type; 2902 instruction->sentinel = sentinel; 2903 instruction->align_value = align_value; 2904 instruction->is_allow_zero = is_allow_zero; 2905 2906 if (sentinel != nullptr) ir_ref_instruction(sentinel, irb->current_basic_block); 2907 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 2908 ir_ref_instruction(child_type, irb->current_basic_block); 2909 2910 return &instruction->base; 2911 } 2912 2913 static IrInstSrc *ir_build_asm_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2914 IrInstSrc *asm_template, IrInstSrc **input_list, IrInstSrc **output_types, 2915 ZigVar **output_vars, size_t return_count, bool has_side_effects, bool is_global) 2916 { 2917 IrInstSrcAsm *instruction = ir_build_instruction<IrInstSrcAsm>(irb, scope, source_node); 2918 instruction->asm_template = asm_template; 2919 instruction->input_list = input_list; 2920 instruction->output_types = output_types; 2921 instruction->output_vars = output_vars; 2922 instruction->return_count = return_count; 2923 instruction->has_side_effects = has_side_effects; 2924 instruction->is_global = is_global; 2925 2926 assert(source_node->type == NodeTypeAsmExpr); 2927 for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) { 2928 IrInstSrc *output_type = output_types[i]; 2929 if (output_type) ir_ref_instruction(output_type, irb->current_basic_block); 2930 } 2931 2932 for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) { 2933 IrInstSrc *input_value = input_list[i]; 2934 ir_ref_instruction(input_value, irb->current_basic_block); 2935 } 2936 2937 return &instruction->base; 2938 } 2939 2940 static IrInstGen *ir_build_asm_gen(IrAnalyze *ira, IrInst *source_instr, 2941 Buf *asm_template, AsmToken *token_list, size_t token_list_len, 2942 IrInstGen **input_list, IrInstGen **output_types, ZigVar **output_vars, size_t return_count, 2943 bool has_side_effects, ZigType *return_type) 2944 { 2945 IrInstGenAsm *instruction = ir_build_inst_gen<IrInstGenAsm>(&ira->new_irb, source_instr->scope, source_instr->source_node); 2946 instruction->base.value->type = return_type; 2947 instruction->asm_template = asm_template; 2948 instruction->token_list = token_list; 2949 instruction->token_list_len = token_list_len; 2950 instruction->input_list = input_list; 2951 instruction->output_types = output_types; 2952 instruction->output_vars = output_vars; 2953 instruction->return_count = return_count; 2954 instruction->has_side_effects = has_side_effects; 2955 2956 assert(source_instr->source_node->type == NodeTypeAsmExpr); 2957 for (size_t i = 0; i < source_instr->source_node->data.asm_expr.output_list.length; i += 1) { 2958 IrInstGen *output_type = output_types[i]; 2959 if (output_type) ir_ref_inst_gen(output_type); 2960 } 2961 2962 for (size_t i = 0; i < source_instr->source_node->data.asm_expr.input_list.length; i += 1) { 2963 IrInstGen *input_value = input_list[i]; 2964 ir_ref_inst_gen(input_value); 2965 } 2966 2967 return &instruction->base; 2968 } 2969 2970 static IrInstSrc *ir_build_size_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value, 2971 bool bit_size) 2972 { 2973 IrInstSrcSizeOf *instruction = ir_build_instruction<IrInstSrcSizeOf>(irb, scope, source_node); 2974 instruction->type_value = type_value; 2975 instruction->bit_size = bit_size; 2976 2977 ir_ref_instruction(type_value, irb->current_basic_block); 2978 2979 return &instruction->base; 2980 } 2981 2982 static IrInstSrc *ir_build_test_non_null_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 2983 IrInstSrc *value) 2984 { 2985 IrInstSrcTestNonNull *instruction = ir_build_instruction<IrInstSrcTestNonNull>(irb, scope, source_node); 2986 instruction->value = value; 2987 2988 ir_ref_instruction(value, irb->current_basic_block); 2989 2990 return &instruction->base; 2991 } 2992 2993 static IrInstGen *ir_build_test_non_null_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) { 2994 IrInstGenTestNonNull *inst = ir_build_inst_gen<IrInstGenTestNonNull>(&ira->new_irb, 2995 source_instr->scope, source_instr->source_node); 2996 inst->base.value->type = ira->codegen->builtin_types.entry_bool; 2997 inst->value = value; 2998 2999 ir_ref_inst_gen(value); 3000 3001 return &inst->base; 3002 } 3003 3004 static IrInstSrc *ir_build_optional_unwrap_ptr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3005 IrInstSrc *base_ptr, bool safety_check_on) 3006 { 3007 IrInstSrcOptionalUnwrapPtr *instruction = ir_build_instruction<IrInstSrcOptionalUnwrapPtr>(irb, scope, source_node); 3008 instruction->base_ptr = base_ptr; 3009 instruction->safety_check_on = safety_check_on; 3010 3011 ir_ref_instruction(base_ptr, irb->current_basic_block); 3012 3013 return &instruction->base; 3014 } 3015 3016 static IrInstGen *ir_build_optional_unwrap_ptr_gen(IrAnalyze *ira, IrInst *source_instr, 3017 IrInstGen *base_ptr, bool safety_check_on, bool initializing, ZigType *result_type) 3018 { 3019 IrInstGenOptionalUnwrapPtr *inst = ir_build_inst_gen<IrInstGenOptionalUnwrapPtr>(&ira->new_irb, 3020 source_instr->scope, source_instr->source_node); 3021 inst->base.value->type = result_type; 3022 inst->base_ptr = base_ptr; 3023 inst->safety_check_on = safety_check_on; 3024 inst->initializing = initializing; 3025 3026 ir_ref_inst_gen(base_ptr); 3027 3028 return &inst->base; 3029 } 3030 3031 static IrInstGen *ir_build_optional_wrap(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_ty, 3032 IrInstGen *operand, IrInstGen *result_loc) 3033 { 3034 IrInstGenOptionalWrap *instruction = ir_build_inst_gen<IrInstGenOptionalWrap>( 3035 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3036 instruction->base.value->type = result_ty; 3037 instruction->operand = operand; 3038 instruction->result_loc = result_loc; 3039 3040 ir_ref_inst_gen(operand); 3041 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 3042 3043 return &instruction->base; 3044 } 3045 3046 static IrInstGen *ir_build_err_wrap_payload(IrAnalyze *ira, IrInst *source_instruction, 3047 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc) 3048 { 3049 IrInstGenErrWrapPayload *instruction = ir_build_inst_gen<IrInstGenErrWrapPayload>( 3050 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3051 instruction->base.value->type = result_type; 3052 instruction->operand = operand; 3053 instruction->result_loc = result_loc; 3054 3055 ir_ref_inst_gen(operand); 3056 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 3057 3058 return &instruction->base; 3059 } 3060 3061 static IrInstGen *ir_build_err_wrap_code(IrAnalyze *ira, IrInst *source_instruction, 3062 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc) 3063 { 3064 IrInstGenErrWrapCode *instruction = ir_build_inst_gen<IrInstGenErrWrapCode>( 3065 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3066 instruction->base.value->type = result_type; 3067 instruction->operand = operand; 3068 instruction->result_loc = result_loc; 3069 3070 ir_ref_inst_gen(operand); 3071 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 3072 3073 return &instruction->base; 3074 } 3075 3076 static IrInstSrc *ir_build_clz(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3077 IrInstSrc *op) 3078 { 3079 IrInstSrcClz *instruction = ir_build_instruction<IrInstSrcClz>(irb, scope, source_node); 3080 instruction->type = type; 3081 instruction->op = op; 3082 3083 ir_ref_instruction(type, irb->current_basic_block); 3084 ir_ref_instruction(op, irb->current_basic_block); 3085 3086 return &instruction->base; 3087 } 3088 3089 static IrInstGen *ir_build_clz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) { 3090 IrInstGenClz *instruction = ir_build_inst_gen<IrInstGenClz>(&ira->new_irb, 3091 source_instr->scope, source_instr->source_node); 3092 instruction->base.value->type = result_type; 3093 instruction->op = op; 3094 3095 ir_ref_inst_gen(op); 3096 3097 return &instruction->base; 3098 } 3099 3100 static IrInstSrc *ir_build_ctz(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3101 IrInstSrc *op) 3102 { 3103 IrInstSrcCtz *instruction = ir_build_instruction<IrInstSrcCtz>(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_ctz_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, IrInstGen *op) { 3114 IrInstGenCtz *instruction = ir_build_inst_gen<IrInstGenCtz>(&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_pop_count(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3125 IrInstSrc *op) 3126 { 3127 IrInstSrcPopCount *instruction = ir_build_instruction<IrInstSrcPopCount>(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_pop_count_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *result_type, 3138 IrInstGen *op) 3139 { 3140 IrInstGenPopCount *instruction = ir_build_inst_gen<IrInstGenPopCount>(&ira->new_irb, 3141 source_instr->scope, source_instr->source_node); 3142 instruction->base.value->type = result_type; 3143 instruction->op = op; 3144 3145 ir_ref_inst_gen(op); 3146 3147 return &instruction->base; 3148 } 3149 3150 static IrInstSrc *ir_build_bswap(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3151 IrInstSrc *op) 3152 { 3153 IrInstSrcBswap *instruction = ir_build_instruction<IrInstSrcBswap>(irb, scope, source_node); 3154 instruction->type = type; 3155 instruction->op = op; 3156 3157 ir_ref_instruction(type, irb->current_basic_block); 3158 ir_ref_instruction(op, irb->current_basic_block); 3159 3160 return &instruction->base; 3161 } 3162 3163 static IrInstGen *ir_build_bswap_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *op_type, 3164 IrInstGen *op) 3165 { 3166 IrInstGenBswap *instruction = ir_build_inst_gen<IrInstGenBswap>(&ira->new_irb, 3167 source_instr->scope, source_instr->source_node); 3168 instruction->base.value->type = op_type; 3169 instruction->op = op; 3170 3171 ir_ref_inst_gen(op); 3172 3173 return &instruction->base; 3174 } 3175 3176 static IrInstSrc *ir_build_bit_reverse(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type, 3177 IrInstSrc *op) 3178 { 3179 IrInstSrcBitReverse *instruction = ir_build_instruction<IrInstSrcBitReverse>(irb, scope, source_node); 3180 instruction->type = type; 3181 instruction->op = op; 3182 3183 ir_ref_instruction(type, irb->current_basic_block); 3184 ir_ref_instruction(op, irb->current_basic_block); 3185 3186 return &instruction->base; 3187 } 3188 3189 static IrInstGen *ir_build_bit_reverse_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *int_type, 3190 IrInstGen *op) 3191 { 3192 IrInstGenBitReverse *instruction = ir_build_inst_gen<IrInstGenBitReverse>(&ira->new_irb, 3193 source_instr->scope, source_instr->source_node); 3194 instruction->base.value->type = int_type; 3195 instruction->op = op; 3196 3197 ir_ref_inst_gen(op); 3198 3199 return &instruction->base; 3200 } 3201 3202 static IrInstSrcSwitchBr *ir_build_switch_br_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3203 IrInstSrc *target_value, IrBasicBlockSrc *else_block, size_t case_count, IrInstSrcSwitchBrCase *cases, 3204 IrInstSrc *is_comptime, IrInstSrc *switch_prongs_void) 3205 { 3206 IrInstSrcSwitchBr *instruction = ir_build_instruction<IrInstSrcSwitchBr>(irb, scope, source_node); 3207 instruction->base.is_noreturn = true; 3208 instruction->target_value = target_value; 3209 instruction->else_block = else_block; 3210 instruction->case_count = case_count; 3211 instruction->cases = cases; 3212 instruction->is_comptime = is_comptime; 3213 instruction->switch_prongs_void = switch_prongs_void; 3214 3215 ir_ref_instruction(target_value, irb->current_basic_block); 3216 ir_ref_instruction(is_comptime, irb->current_basic_block); 3217 ir_ref_bb(else_block); 3218 ir_ref_instruction(switch_prongs_void, irb->current_basic_block); 3219 3220 for (size_t i = 0; i < case_count; i += 1) { 3221 ir_ref_instruction(cases[i].value, irb->current_basic_block); 3222 ir_ref_bb(cases[i].block); 3223 } 3224 3225 return instruction; 3226 } 3227 3228 static IrInstGenSwitchBr *ir_build_switch_br_gen(IrAnalyze *ira, IrInst *source_instr, 3229 IrInstGen *target_value, IrBasicBlockGen *else_block, size_t case_count, IrInstGenSwitchBrCase *cases) 3230 { 3231 IrInstGenSwitchBr *instruction = ir_build_inst_noreturn<IrInstGenSwitchBr>(&ira->new_irb, 3232 source_instr->scope, source_instr->source_node); 3233 instruction->target_value = target_value; 3234 instruction->else_block = else_block; 3235 instruction->case_count = case_count; 3236 instruction->cases = cases; 3237 3238 ir_ref_inst_gen(target_value); 3239 3240 for (size_t i = 0; i < case_count; i += 1) { 3241 ir_ref_inst_gen(cases[i].value); 3242 } 3243 3244 return instruction; 3245 } 3246 3247 static IrInstSrc *ir_build_switch_target(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3248 IrInstSrc *target_value_ptr) 3249 { 3250 IrInstSrcSwitchTarget *instruction = ir_build_instruction<IrInstSrcSwitchTarget>(irb, scope, source_node); 3251 instruction->target_value_ptr = target_value_ptr; 3252 3253 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 3254 3255 return &instruction->base; 3256 } 3257 3258 static IrInstSrc *ir_build_switch_var(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3259 IrInstSrc *target_value_ptr, IrInstSrc **prongs_ptr, size_t prongs_len) 3260 { 3261 IrInstSrcSwitchVar *instruction = ir_build_instruction<IrInstSrcSwitchVar>(irb, scope, source_node); 3262 instruction->target_value_ptr = target_value_ptr; 3263 instruction->prongs_ptr = prongs_ptr; 3264 instruction->prongs_len = prongs_len; 3265 3266 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 3267 for (size_t i = 0; i < prongs_len; i += 1) { 3268 ir_ref_instruction(prongs_ptr[i], irb->current_basic_block); 3269 } 3270 3271 return &instruction->base; 3272 } 3273 3274 // For this instruction the switch_br must be set later. 3275 static IrInstSrcSwitchElseVar *ir_build_switch_else_var(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3276 IrInstSrc *target_value_ptr) 3277 { 3278 IrInstSrcSwitchElseVar *instruction = ir_build_instruction<IrInstSrcSwitchElseVar>(irb, scope, source_node); 3279 instruction->target_value_ptr = target_value_ptr; 3280 3281 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 3282 3283 return instruction; 3284 } 3285 3286 static IrInstGen *ir_build_union_tag(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, 3287 ZigType *tag_type) 3288 { 3289 IrInstGenUnionTag *instruction = ir_build_inst_gen<IrInstGenUnionTag>(&ira->new_irb, 3290 source_instr->scope, source_instr->source_node); 3291 instruction->value = value; 3292 instruction->base.value->type = tag_type; 3293 3294 ir_ref_inst_gen(value); 3295 3296 return &instruction->base; 3297 } 3298 3299 static IrInstSrc *ir_build_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { 3300 IrInstSrcImport *instruction = ir_build_instruction<IrInstSrcImport>(irb, scope, source_node); 3301 instruction->name = name; 3302 3303 ir_ref_instruction(name, irb->current_basic_block); 3304 3305 return &instruction->base; 3306 } 3307 3308 static IrInstSrc *ir_build_ref_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 3309 IrInstSrcRef *instruction = ir_build_instruction<IrInstSrcRef>(irb, scope, source_node); 3310 instruction->value = value; 3311 3312 ir_ref_instruction(value, irb->current_basic_block); 3313 3314 return &instruction->base; 3315 } 3316 3317 static IrInstGen *ir_build_ref_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type, 3318 IrInstGen *operand, IrInstGen *result_loc) 3319 { 3320 IrInstGenRef *instruction = ir_build_inst_gen<IrInstGenRef>(&ira->new_irb, 3321 source_instruction->scope, source_instruction->source_node); 3322 instruction->base.value->type = result_type; 3323 instruction->operand = operand; 3324 instruction->result_loc = result_loc; 3325 3326 ir_ref_inst_gen(operand); 3327 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 3328 3329 return &instruction->base; 3330 } 3331 3332 static IrInstSrc *ir_build_compile_err(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *msg) { 3333 IrInstSrcCompileErr *instruction = ir_build_instruction<IrInstSrcCompileErr>(irb, scope, source_node); 3334 instruction->msg = msg; 3335 3336 ir_ref_instruction(msg, irb->current_basic_block); 3337 3338 return &instruction->base; 3339 } 3340 3341 static IrInstSrc *ir_build_compile_log(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3342 size_t msg_count, IrInstSrc **msg_list) 3343 { 3344 IrInstSrcCompileLog *instruction = ir_build_instruction<IrInstSrcCompileLog>(irb, scope, source_node); 3345 instruction->msg_count = msg_count; 3346 instruction->msg_list = msg_list; 3347 3348 for (size_t i = 0; i < msg_count; i += 1) { 3349 ir_ref_instruction(msg_list[i], irb->current_basic_block); 3350 } 3351 3352 return &instruction->base; 3353 } 3354 3355 static IrInstSrc *ir_build_err_name(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 3356 IrInstSrcErrName *instruction = ir_build_instruction<IrInstSrcErrName>(irb, scope, source_node); 3357 instruction->value = value; 3358 3359 ir_ref_instruction(value, irb->current_basic_block); 3360 3361 return &instruction->base; 3362 } 3363 3364 static IrInstGen *ir_build_err_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, 3365 ZigType *str_type) 3366 { 3367 IrInstGenErrName *instruction = ir_build_inst_gen<IrInstGenErrName>(&ira->new_irb, 3368 source_instr->scope, source_instr->source_node); 3369 instruction->base.value->type = str_type; 3370 instruction->value = value; 3371 3372 ir_ref_inst_gen(value); 3373 3374 return &instruction->base; 3375 } 3376 3377 static IrInstSrc *ir_build_c_import(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3378 IrInstSrcCImport *instruction = ir_build_instruction<IrInstSrcCImport>(irb, scope, source_node); 3379 return &instruction->base; 3380 } 3381 3382 static IrInstSrc *ir_build_c_include(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { 3383 IrInstSrcCInclude *instruction = ir_build_instruction<IrInstSrcCInclude>(irb, scope, source_node); 3384 instruction->name = name; 3385 3386 ir_ref_instruction(name, irb->current_basic_block); 3387 3388 return &instruction->base; 3389 } 3390 3391 static IrInstSrc *ir_build_c_define(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name, IrInstSrc *value) { 3392 IrInstSrcCDefine *instruction = ir_build_instruction<IrInstSrcCDefine>(irb, scope, source_node); 3393 instruction->name = name; 3394 instruction->value = value; 3395 3396 ir_ref_instruction(name, irb->current_basic_block); 3397 ir_ref_instruction(value, irb->current_basic_block); 3398 3399 return &instruction->base; 3400 } 3401 3402 static IrInstSrc *ir_build_c_undef(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { 3403 IrInstSrcCUndef *instruction = ir_build_instruction<IrInstSrcCUndef>(irb, scope, source_node); 3404 instruction->name = name; 3405 3406 ir_ref_instruction(name, irb->current_basic_block); 3407 3408 return &instruction->base; 3409 } 3410 3411 static IrInstSrc *ir_build_embed_file(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *name) { 3412 IrInstSrcEmbedFile *instruction = ir_build_instruction<IrInstSrcEmbedFile>(irb, scope, source_node); 3413 instruction->name = name; 3414 3415 ir_ref_instruction(name, irb->current_basic_block); 3416 3417 return &instruction->base; 3418 } 3419 3420 static IrInstSrc *ir_build_cmpxchg_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3421 IrInstSrc *type_value, IrInstSrc *ptr, IrInstSrc *cmp_value, IrInstSrc *new_value, 3422 IrInstSrc *success_order_value, IrInstSrc *failure_order_value, bool is_weak, ResultLoc *result_loc) 3423 { 3424 IrInstSrcCmpxchg *instruction = ir_build_instruction<IrInstSrcCmpxchg>(irb, scope, source_node); 3425 instruction->type_value = type_value; 3426 instruction->ptr = ptr; 3427 instruction->cmp_value = cmp_value; 3428 instruction->new_value = new_value; 3429 instruction->success_order_value = success_order_value; 3430 instruction->failure_order_value = failure_order_value; 3431 instruction->is_weak = is_weak; 3432 instruction->result_loc = result_loc; 3433 3434 ir_ref_instruction(type_value, irb->current_basic_block); 3435 ir_ref_instruction(ptr, irb->current_basic_block); 3436 ir_ref_instruction(cmp_value, irb->current_basic_block); 3437 ir_ref_instruction(new_value, irb->current_basic_block); 3438 ir_ref_instruction(success_order_value, irb->current_basic_block); 3439 ir_ref_instruction(failure_order_value, irb->current_basic_block); 3440 3441 return &instruction->base; 3442 } 3443 3444 static IrInstGen *ir_build_cmpxchg_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type, 3445 IrInstGen *ptr, IrInstGen *cmp_value, IrInstGen *new_value, 3446 AtomicOrder success_order, AtomicOrder failure_order, bool is_weak, IrInstGen *result_loc) 3447 { 3448 IrInstGenCmpxchg *instruction = ir_build_inst_gen<IrInstGenCmpxchg>(&ira->new_irb, 3449 source_instruction->scope, source_instruction->source_node); 3450 instruction->base.value->type = result_type; 3451 instruction->ptr = ptr; 3452 instruction->cmp_value = cmp_value; 3453 instruction->new_value = new_value; 3454 instruction->success_order = success_order; 3455 instruction->failure_order = failure_order; 3456 instruction->is_weak = is_weak; 3457 instruction->result_loc = result_loc; 3458 3459 ir_ref_inst_gen(ptr); 3460 ir_ref_inst_gen(cmp_value); 3461 ir_ref_inst_gen(new_value); 3462 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 3463 3464 return &instruction->base; 3465 } 3466 3467 static IrInstSrc *ir_build_fence(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *order) { 3468 IrInstSrcFence *instruction = ir_build_instruction<IrInstSrcFence>(irb, scope, source_node); 3469 instruction->order = order; 3470 3471 ir_ref_instruction(order, irb->current_basic_block); 3472 3473 return &instruction->base; 3474 } 3475 3476 static IrInstGen *ir_build_fence_gen(IrAnalyze *ira, IrInst *source_instr, AtomicOrder order) { 3477 IrInstGenFence *instruction = ir_build_inst_void<IrInstGenFence>(&ira->new_irb, 3478 source_instr->scope, source_instr->source_node); 3479 instruction->order = order; 3480 3481 return &instruction->base; 3482 } 3483 3484 static IrInstSrc *ir_build_truncate(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3485 IrInstSrc *dest_type, IrInstSrc *target) 3486 { 3487 IrInstSrcTruncate *instruction = ir_build_instruction<IrInstSrcTruncate>(irb, scope, source_node); 3488 instruction->dest_type = dest_type; 3489 instruction->target = target; 3490 3491 ir_ref_instruction(dest_type, irb->current_basic_block); 3492 ir_ref_instruction(target, irb->current_basic_block); 3493 3494 return &instruction->base; 3495 } 3496 3497 static IrInstGen *ir_build_truncate_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *dest_type, 3498 IrInstGen *target) 3499 { 3500 IrInstGenTruncate *instruction = ir_build_inst_gen<IrInstGenTruncate>(&ira->new_irb, 3501 source_instr->scope, source_instr->source_node); 3502 instruction->base.value->type = dest_type; 3503 instruction->target = target; 3504 3505 ir_ref_inst_gen(target); 3506 3507 return &instruction->base; 3508 } 3509 3510 static IrInstSrc *ir_build_int_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *dest_type, 3511 IrInstSrc *target) 3512 { 3513 IrInstSrcIntCast *instruction = ir_build_instruction<IrInstSrcIntCast>(irb, scope, source_node); 3514 instruction->dest_type = dest_type; 3515 instruction->target = target; 3516 3517 ir_ref_instruction(dest_type, irb->current_basic_block); 3518 ir_ref_instruction(target, irb->current_basic_block); 3519 3520 return &instruction->base; 3521 } 3522 3523 static IrInstSrc *ir_build_float_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *dest_type, 3524 IrInstSrc *target) 3525 { 3526 IrInstSrcFloatCast *instruction = ir_build_instruction<IrInstSrcFloatCast>(irb, scope, source_node); 3527 instruction->dest_type = dest_type; 3528 instruction->target = target; 3529 3530 ir_ref_instruction(dest_type, irb->current_basic_block); 3531 ir_ref_instruction(target, irb->current_basic_block); 3532 3533 return &instruction->base; 3534 } 3535 3536 static IrInstSrc *ir_build_err_set_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3537 IrInstSrc *dest_type, IrInstSrc *target) 3538 { 3539 IrInstSrcErrSetCast *instruction = ir_build_instruction<IrInstSrcErrSetCast>(irb, scope, source_node); 3540 instruction->dest_type = dest_type; 3541 instruction->target = target; 3542 3543 ir_ref_instruction(dest_type, irb->current_basic_block); 3544 ir_ref_instruction(target, irb->current_basic_block); 3545 3546 return &instruction->base; 3547 } 3548 3549 static IrInstSrc *ir_build_int_to_float(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3550 IrInstSrc *dest_type, IrInstSrc *target) 3551 { 3552 IrInstSrcIntToFloat *instruction = ir_build_instruction<IrInstSrcIntToFloat>(irb, scope, source_node); 3553 instruction->dest_type = dest_type; 3554 instruction->target = target; 3555 3556 ir_ref_instruction(dest_type, irb->current_basic_block); 3557 ir_ref_instruction(target, irb->current_basic_block); 3558 3559 return &instruction->base; 3560 } 3561 3562 static IrInstSrc *ir_build_float_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3563 IrInstSrc *dest_type, IrInstSrc *target) 3564 { 3565 IrInstSrcFloatToInt *instruction = ir_build_instruction<IrInstSrcFloatToInt>(irb, scope, source_node); 3566 instruction->dest_type = dest_type; 3567 instruction->target = target; 3568 3569 ir_ref_instruction(dest_type, irb->current_basic_block); 3570 ir_ref_instruction(target, irb->current_basic_block); 3571 3572 return &instruction->base; 3573 } 3574 3575 static IrInstSrc *ir_build_bool_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target) { 3576 IrInstSrcBoolToInt *instruction = ir_build_instruction<IrInstSrcBoolToInt>(irb, scope, source_node); 3577 instruction->target = target; 3578 3579 ir_ref_instruction(target, irb->current_basic_block); 3580 3581 return &instruction->base; 3582 } 3583 3584 static IrInstSrc *ir_build_vector_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *len, 3585 IrInstSrc *elem_type) 3586 { 3587 IrInstSrcVectorType *instruction = ir_build_instruction<IrInstSrcVectorType>(irb, scope, source_node); 3588 instruction->len = len; 3589 instruction->elem_type = elem_type; 3590 3591 ir_ref_instruction(len, irb->current_basic_block); 3592 ir_ref_instruction(elem_type, irb->current_basic_block); 3593 3594 return &instruction->base; 3595 } 3596 3597 static IrInstSrc *ir_build_shuffle_vector(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3598 IrInstSrc *scalar_type, IrInstSrc *a, IrInstSrc *b, IrInstSrc *mask) 3599 { 3600 IrInstSrcShuffleVector *instruction = ir_build_instruction<IrInstSrcShuffleVector>(irb, scope, source_node); 3601 instruction->scalar_type = scalar_type; 3602 instruction->a = a; 3603 instruction->b = b; 3604 instruction->mask = mask; 3605 3606 if (scalar_type != nullptr) ir_ref_instruction(scalar_type, irb->current_basic_block); 3607 ir_ref_instruction(a, irb->current_basic_block); 3608 ir_ref_instruction(b, irb->current_basic_block); 3609 ir_ref_instruction(mask, irb->current_basic_block); 3610 3611 return &instruction->base; 3612 } 3613 3614 static IrInstGen *ir_build_shuffle_vector_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 3615 ZigType *result_type, IrInstGen *a, IrInstGen *b, IrInstGen *mask) 3616 { 3617 IrInstGenShuffleVector *inst = ir_build_inst_gen<IrInstGenShuffleVector>(&ira->new_irb, scope, source_node); 3618 inst->base.value->type = result_type; 3619 inst->a = a; 3620 inst->b = b; 3621 inst->mask = mask; 3622 3623 ir_ref_inst_gen(a); 3624 ir_ref_inst_gen(b); 3625 ir_ref_inst_gen(mask); 3626 3627 return &inst->base; 3628 } 3629 3630 static IrInstSrc *ir_build_splat_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3631 IrInstSrc *len, IrInstSrc *scalar) 3632 { 3633 IrInstSrcSplat *instruction = ir_build_instruction<IrInstSrcSplat>(irb, scope, source_node); 3634 instruction->len = len; 3635 instruction->scalar = scalar; 3636 3637 ir_ref_instruction(len, irb->current_basic_block); 3638 ir_ref_instruction(scalar, irb->current_basic_block); 3639 3640 return &instruction->base; 3641 } 3642 3643 static IrInstGen *ir_build_splat_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *result_type, 3644 IrInstGen *scalar) 3645 { 3646 IrInstGenSplat *instruction = ir_build_inst_gen<IrInstGenSplat>( 3647 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3648 instruction->base.value->type = result_type; 3649 instruction->scalar = scalar; 3650 3651 ir_ref_inst_gen(scalar); 3652 3653 return &instruction->base; 3654 } 3655 3656 static IrInstSrc *ir_build_bool_not(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 3657 IrInstSrcBoolNot *instruction = ir_build_instruction<IrInstSrcBoolNot>(irb, scope, source_node); 3658 instruction->value = value; 3659 3660 ir_ref_instruction(value, irb->current_basic_block); 3661 3662 return &instruction->base; 3663 } 3664 3665 static IrInstGen *ir_build_bool_not_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value) { 3666 IrInstGenBoolNot *instruction = ir_build_inst_gen<IrInstGenBoolNot>(&ira->new_irb, 3667 source_instr->scope, source_instr->source_node); 3668 instruction->base.value->type = ira->codegen->builtin_types.entry_bool; 3669 instruction->value = value; 3670 3671 ir_ref_inst_gen(value); 3672 3673 return &instruction->base; 3674 } 3675 3676 static IrInstSrc *ir_build_memset_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3677 IrInstSrc *dest_ptr, IrInstSrc *byte, IrInstSrc *count) 3678 { 3679 IrInstSrcMemset *instruction = ir_build_instruction<IrInstSrcMemset>(irb, scope, source_node); 3680 instruction->dest_ptr = dest_ptr; 3681 instruction->byte = byte; 3682 instruction->count = count; 3683 3684 ir_ref_instruction(dest_ptr, irb->current_basic_block); 3685 ir_ref_instruction(byte, irb->current_basic_block); 3686 ir_ref_instruction(count, irb->current_basic_block); 3687 3688 return &instruction->base; 3689 } 3690 3691 static IrInstGen *ir_build_memset_gen(IrAnalyze *ira, IrInst *source_instr, 3692 IrInstGen *dest_ptr, IrInstGen *byte, IrInstGen *count) 3693 { 3694 IrInstGenMemset *instruction = ir_build_inst_void<IrInstGenMemset>(&ira->new_irb, 3695 source_instr->scope, source_instr->source_node); 3696 instruction->dest_ptr = dest_ptr; 3697 instruction->byte = byte; 3698 instruction->count = count; 3699 3700 ir_ref_inst_gen(dest_ptr); 3701 ir_ref_inst_gen(byte); 3702 ir_ref_inst_gen(count); 3703 3704 return &instruction->base; 3705 } 3706 3707 static IrInstSrc *ir_build_memcpy_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3708 IrInstSrc *dest_ptr, IrInstSrc *src_ptr, IrInstSrc *count) 3709 { 3710 IrInstSrcMemcpy *instruction = ir_build_instruction<IrInstSrcMemcpy>(irb, scope, source_node); 3711 instruction->dest_ptr = dest_ptr; 3712 instruction->src_ptr = src_ptr; 3713 instruction->count = count; 3714 3715 ir_ref_instruction(dest_ptr, irb->current_basic_block); 3716 ir_ref_instruction(src_ptr, irb->current_basic_block); 3717 ir_ref_instruction(count, irb->current_basic_block); 3718 3719 return &instruction->base; 3720 } 3721 3722 static IrInstGen *ir_build_memcpy_gen(IrAnalyze *ira, IrInst *source_instr, 3723 IrInstGen *dest_ptr, IrInstGen *src_ptr, IrInstGen *count) 3724 { 3725 IrInstGenMemcpy *instruction = ir_build_inst_void<IrInstGenMemcpy>(&ira->new_irb, 3726 source_instr->scope, source_instr->source_node); 3727 instruction->dest_ptr = dest_ptr; 3728 instruction->src_ptr = src_ptr; 3729 instruction->count = count; 3730 3731 ir_ref_inst_gen(dest_ptr); 3732 ir_ref_inst_gen(src_ptr); 3733 ir_ref_inst_gen(count); 3734 3735 return &instruction->base; 3736 } 3737 3738 static IrInstSrc *ir_build_slice_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3739 IrInstSrc *ptr, IrInstSrc *start, IrInstSrc *end, IrInstSrc *sentinel, 3740 bool safety_check_on, ResultLoc *result_loc) 3741 { 3742 IrInstSrcSlice *instruction = ir_build_instruction<IrInstSrcSlice>(irb, scope, source_node); 3743 instruction->ptr = ptr; 3744 instruction->start = start; 3745 instruction->end = end; 3746 instruction->sentinel = sentinel; 3747 instruction->safety_check_on = safety_check_on; 3748 instruction->result_loc = result_loc; 3749 3750 ir_ref_instruction(ptr, irb->current_basic_block); 3751 ir_ref_instruction(start, irb->current_basic_block); 3752 if (end) ir_ref_instruction(end, irb->current_basic_block); 3753 if (sentinel) ir_ref_instruction(sentinel, irb->current_basic_block); 3754 3755 return &instruction->base; 3756 } 3757 3758 static IrInstGen *ir_build_slice_gen(IrAnalyze *ira, IrInst *source_instruction, ZigType *slice_type, 3759 IrInstGen *ptr, IrInstGen *start, IrInstGen *end, bool safety_check_on, IrInstGen *result_loc, 3760 ZigValue *sentinel) 3761 { 3762 IrInstGenSlice *instruction = ir_build_inst_gen<IrInstGenSlice>( 3763 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3764 instruction->base.value->type = slice_type; 3765 instruction->ptr = ptr; 3766 instruction->start = start; 3767 instruction->end = end; 3768 instruction->safety_check_on = safety_check_on; 3769 instruction->result_loc = result_loc; 3770 instruction->sentinel = sentinel; 3771 3772 ir_ref_inst_gen(ptr); 3773 ir_ref_inst_gen(start); 3774 if (end != nullptr) ir_ref_inst_gen(end); 3775 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 3776 3777 return &instruction->base; 3778 } 3779 3780 static IrInstSrc *ir_build_breakpoint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3781 IrInstSrcBreakpoint *instruction = ir_build_instruction<IrInstSrcBreakpoint>(irb, scope, source_node); 3782 return &instruction->base; 3783 } 3784 3785 static IrInstGen *ir_build_breakpoint_gen(IrAnalyze *ira, IrInst *source_instr) { 3786 IrInstGenBreakpoint *instruction = ir_build_inst_void<IrInstGenBreakpoint>(&ira->new_irb, 3787 source_instr->scope, source_instr->source_node); 3788 return &instruction->base; 3789 } 3790 3791 static IrInstSrc *ir_build_return_address_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3792 IrInstSrcReturnAddress *instruction = ir_build_instruction<IrInstSrcReturnAddress>(irb, scope, source_node); 3793 return &instruction->base; 3794 } 3795 3796 static IrInstGen *ir_build_return_address_gen(IrAnalyze *ira, IrInst *source_instr) { 3797 IrInstGenReturnAddress *inst = ir_build_inst_gen<IrInstGenReturnAddress>(&ira->new_irb, source_instr->scope, source_instr->source_node); 3798 inst->base.value->type = ira->codegen->builtin_types.entry_usize; 3799 return &inst->base; 3800 } 3801 3802 static IrInstSrc *ir_build_frame_address_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3803 IrInstSrcFrameAddress *inst = ir_build_instruction<IrInstSrcFrameAddress>(irb, scope, source_node); 3804 return &inst->base; 3805 } 3806 3807 static IrInstGen *ir_build_frame_address_gen(IrAnalyze *ira, IrInst *source_instr) { 3808 IrInstGenFrameAddress *inst = ir_build_inst_gen<IrInstGenFrameAddress>(&ira->new_irb, source_instr->scope, source_instr->source_node); 3809 inst->base.value->type = ira->codegen->builtin_types.entry_usize; 3810 return &inst->base; 3811 } 3812 3813 static IrInstSrc *ir_build_handle_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 3814 IrInstSrcFrameHandle *inst = ir_build_instruction<IrInstSrcFrameHandle>(irb, scope, source_node); 3815 return &inst->base; 3816 } 3817 3818 static IrInstGen *ir_build_handle_gen(IrAnalyze *ira, IrInst *source_instr, ZigType *ty) { 3819 IrInstGenFrameHandle *inst = ir_build_inst_gen<IrInstGenFrameHandle>(&ira->new_irb, source_instr->scope, source_instr->source_node); 3820 inst->base.value->type = ty; 3821 return &inst->base; 3822 } 3823 3824 static IrInstSrc *ir_build_frame_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *fn) { 3825 IrInstSrcFrameType *inst = ir_build_instruction<IrInstSrcFrameType>(irb, scope, source_node); 3826 inst->fn = fn; 3827 3828 ir_ref_instruction(fn, irb->current_basic_block); 3829 3830 return &inst->base; 3831 } 3832 3833 static IrInstSrc *ir_build_frame_size_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *fn) { 3834 IrInstSrcFrameSize *inst = ir_build_instruction<IrInstSrcFrameSize>(irb, scope, source_node); 3835 inst->fn = fn; 3836 3837 ir_ref_instruction(fn, irb->current_basic_block); 3838 3839 return &inst->base; 3840 } 3841 3842 static IrInstGen *ir_build_frame_size_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *fn) 3843 { 3844 IrInstGenFrameSize *inst = ir_build_inst_gen<IrInstGenFrameSize>(&ira->new_irb, source_instr->scope, source_instr->source_node); 3845 inst->base.value->type = ira->codegen->builtin_types.entry_usize; 3846 inst->fn = fn; 3847 3848 ir_ref_inst_gen(fn); 3849 3850 return &inst->base; 3851 } 3852 3853 static IrInstSrc *ir_build_overflow_op_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3854 IrOverflowOp op, IrInstSrc *type_value, IrInstSrc *op1, IrInstSrc *op2, IrInstSrc *result_ptr) 3855 { 3856 IrInstSrcOverflowOp *instruction = ir_build_instruction<IrInstSrcOverflowOp>(irb, scope, source_node); 3857 instruction->op = op; 3858 instruction->type_value = type_value; 3859 instruction->op1 = op1; 3860 instruction->op2 = op2; 3861 instruction->result_ptr = result_ptr; 3862 3863 ir_ref_instruction(type_value, irb->current_basic_block); 3864 ir_ref_instruction(op1, irb->current_basic_block); 3865 ir_ref_instruction(op2, irb->current_basic_block); 3866 ir_ref_instruction(result_ptr, irb->current_basic_block); 3867 3868 return &instruction->base; 3869 } 3870 3871 static IrInstGen *ir_build_overflow_op_gen(IrAnalyze *ira, IrInst *source_instr, 3872 IrOverflowOp op, IrInstGen *op1, IrInstGen *op2, IrInstGen *result_ptr, 3873 ZigType *result_ptr_type) 3874 { 3875 IrInstGenOverflowOp *instruction = ir_build_inst_gen<IrInstGenOverflowOp>(&ira->new_irb, 3876 source_instr->scope, source_instr->source_node); 3877 instruction->base.value->type = ira->codegen->builtin_types.entry_bool; 3878 instruction->op = op; 3879 instruction->op1 = op1; 3880 instruction->op2 = op2; 3881 instruction->result_ptr = result_ptr; 3882 instruction->result_ptr_type = result_ptr_type; 3883 3884 ir_ref_inst_gen(op1); 3885 ir_ref_inst_gen(op2); 3886 ir_ref_inst_gen(result_ptr); 3887 3888 return &instruction->base; 3889 } 3890 3891 static IrInstSrc *ir_build_float_op_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *operand, 3892 BuiltinFnId fn_id) 3893 { 3894 IrInstSrcFloatOp *instruction = ir_build_instruction<IrInstSrcFloatOp>(irb, scope, source_node); 3895 instruction->operand = operand; 3896 instruction->fn_id = fn_id; 3897 3898 ir_ref_instruction(operand, irb->current_basic_block); 3899 3900 return &instruction->base; 3901 } 3902 3903 static IrInstGen *ir_build_float_op_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, 3904 BuiltinFnId fn_id, ZigType *operand_type) 3905 { 3906 IrInstGenFloatOp *instruction = ir_build_inst_gen<IrInstGenFloatOp>(&ira->new_irb, 3907 source_instr->scope, source_instr->source_node); 3908 instruction->base.value->type = operand_type; 3909 instruction->operand = operand; 3910 instruction->fn_id = fn_id; 3911 3912 ir_ref_inst_gen(operand); 3913 3914 return &instruction->base; 3915 } 3916 3917 static IrInstSrc *ir_build_mul_add_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3918 IrInstSrc *type_value, IrInstSrc *op1, IrInstSrc *op2, IrInstSrc *op3) 3919 { 3920 IrInstSrcMulAdd *instruction = ir_build_instruction<IrInstSrcMulAdd>(irb, scope, source_node); 3921 instruction->type_value = type_value; 3922 instruction->op1 = op1; 3923 instruction->op2 = op2; 3924 instruction->op3 = op3; 3925 3926 ir_ref_instruction(type_value, irb->current_basic_block); 3927 ir_ref_instruction(op1, irb->current_basic_block); 3928 ir_ref_instruction(op2, irb->current_basic_block); 3929 ir_ref_instruction(op3, irb->current_basic_block); 3930 3931 return &instruction->base; 3932 } 3933 3934 static IrInstGen *ir_build_mul_add_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *op1, IrInstGen *op2, 3935 IrInstGen *op3, ZigType *expr_type) 3936 { 3937 IrInstGenMulAdd *instruction = ir_build_inst_gen<IrInstGenMulAdd>(&ira->new_irb, 3938 source_instr->scope, source_instr->source_node); 3939 instruction->base.value->type = expr_type; 3940 instruction->op1 = op1; 3941 instruction->op2 = op2; 3942 instruction->op3 = op3; 3943 3944 ir_ref_inst_gen(op1); 3945 ir_ref_inst_gen(op2); 3946 ir_ref_inst_gen(op3); 3947 3948 return &instruction->base; 3949 } 3950 3951 static IrInstSrc *ir_build_align_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value) { 3952 IrInstSrcAlignOf *instruction = ir_build_instruction<IrInstSrcAlignOf>(irb, scope, source_node); 3953 instruction->type_value = type_value; 3954 3955 ir_ref_instruction(type_value, irb->current_basic_block); 3956 3957 return &instruction->base; 3958 } 3959 3960 static IrInstSrc *ir_build_test_err_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3961 IrInstSrc *base_ptr, bool resolve_err_set, bool base_ptr_is_payload) 3962 { 3963 IrInstSrcTestErr *instruction = ir_build_instruction<IrInstSrcTestErr>(irb, scope, source_node); 3964 instruction->base_ptr = base_ptr; 3965 instruction->resolve_err_set = resolve_err_set; 3966 instruction->base_ptr_is_payload = base_ptr_is_payload; 3967 3968 ir_ref_instruction(base_ptr, irb->current_basic_block); 3969 3970 return &instruction->base; 3971 } 3972 3973 static IrInstGen *ir_build_test_err_gen(IrAnalyze *ira, IrInst *source_instruction, IrInstGen *err_union) { 3974 IrInstGenTestErr *instruction = ir_build_inst_gen<IrInstGenTestErr>( 3975 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 3976 instruction->base.value->type = ira->codegen->builtin_types.entry_bool; 3977 instruction->err_union = err_union; 3978 3979 ir_ref_inst_gen(err_union); 3980 3981 return &instruction->base; 3982 } 3983 3984 static IrInstSrc *ir_build_unwrap_err_code_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 3985 IrInstSrc *err_union_ptr) 3986 { 3987 IrInstSrcUnwrapErrCode *inst = ir_build_instruction<IrInstSrcUnwrapErrCode>(irb, scope, source_node); 3988 inst->err_union_ptr = err_union_ptr; 3989 3990 ir_ref_instruction(err_union_ptr, irb->current_basic_block); 3991 3992 return &inst->base; 3993 } 3994 3995 static IrInstGen *ir_build_unwrap_err_code_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 3996 IrInstGen *err_union_ptr, ZigType *result_type) 3997 { 3998 IrInstGenUnwrapErrCode *inst = ir_build_inst_gen<IrInstGenUnwrapErrCode>(&ira->new_irb, scope, source_node); 3999 inst->base.value->type = result_type; 4000 inst->err_union_ptr = err_union_ptr; 4001 4002 ir_ref_inst_gen(err_union_ptr); 4003 4004 return &inst->base; 4005 } 4006 4007 static IrInstSrc *ir_build_unwrap_err_payload_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4008 IrInstSrc *value, bool safety_check_on, bool initializing) 4009 { 4010 IrInstSrcUnwrapErrPayload *inst = ir_build_instruction<IrInstSrcUnwrapErrPayload>(irb, scope, source_node); 4011 inst->value = value; 4012 inst->safety_check_on = safety_check_on; 4013 inst->initializing = initializing; 4014 4015 ir_ref_instruction(value, irb->current_basic_block); 4016 4017 return &inst->base; 4018 } 4019 4020 static IrInstGen *ir_build_unwrap_err_payload_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 4021 IrInstGen *value, bool safety_check_on, bool initializing, ZigType *result_type) 4022 { 4023 IrInstGenUnwrapErrPayload *inst = ir_build_inst_gen<IrInstGenUnwrapErrPayload>(&ira->new_irb, scope, source_node); 4024 inst->base.value->type = result_type; 4025 inst->value = value; 4026 inst->safety_check_on = safety_check_on; 4027 inst->initializing = initializing; 4028 4029 ir_ref_inst_gen(value); 4030 4031 return &inst->base; 4032 } 4033 4034 static IrInstSrc *ir_build_fn_proto(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4035 IrInstSrc **param_types, IrInstSrc *align_value, IrInstSrc *callconv_value, 4036 IrInstSrc *return_type, bool is_var_args) 4037 { 4038 IrInstSrcFnProto *instruction = ir_build_instruction<IrInstSrcFnProto>(irb, scope, source_node); 4039 instruction->param_types = param_types; 4040 instruction->align_value = align_value; 4041 instruction->callconv_value = callconv_value; 4042 instruction->return_type = return_type; 4043 instruction->is_var_args = is_var_args; 4044 4045 assert(source_node->type == NodeTypeFnProto); 4046 size_t param_count = source_node->data.fn_proto.params.length; 4047 if (is_var_args) param_count -= 1; 4048 for (size_t i = 0; i < param_count; i += 1) { 4049 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block); 4050 } 4051 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 4052 if (callconv_value != nullptr) ir_ref_instruction(callconv_value, irb->current_basic_block); 4053 ir_ref_instruction(return_type, irb->current_basic_block); 4054 4055 return &instruction->base; 4056 } 4057 4058 static IrInstSrc *ir_build_test_comptime(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *value) { 4059 IrInstSrcTestComptime *instruction = ir_build_instruction<IrInstSrcTestComptime>(irb, scope, source_node); 4060 instruction->value = value; 4061 4062 ir_ref_instruction(value, irb->current_basic_block); 4063 4064 return &instruction->base; 4065 } 4066 4067 static IrInstSrc *ir_build_ptr_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4068 IrInstSrc *dest_type, IrInstSrc *ptr, bool safety_check_on) 4069 { 4070 IrInstSrcPtrCast *instruction = ir_build_instruction<IrInstSrcPtrCast>( 4071 irb, scope, source_node); 4072 instruction->dest_type = dest_type; 4073 instruction->ptr = ptr; 4074 instruction->safety_check_on = safety_check_on; 4075 4076 ir_ref_instruction(dest_type, irb->current_basic_block); 4077 ir_ref_instruction(ptr, irb->current_basic_block); 4078 4079 return &instruction->base; 4080 } 4081 4082 static IrInstGen *ir_build_ptr_cast_gen(IrAnalyze *ira, IrInst *source_instruction, 4083 ZigType *ptr_type, IrInstGen *ptr, bool safety_check_on) 4084 { 4085 IrInstGenPtrCast *instruction = ir_build_inst_gen<IrInstGenPtrCast>( 4086 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 4087 instruction->base.value->type = ptr_type; 4088 instruction->ptr = ptr; 4089 instruction->safety_check_on = safety_check_on; 4090 4091 ir_ref_inst_gen(ptr); 4092 4093 return &instruction->base; 4094 } 4095 4096 static IrInstSrc *ir_build_implicit_cast(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4097 IrInstSrc *operand, ResultLocCast *result_loc_cast) 4098 { 4099 IrInstSrcImplicitCast *instruction = ir_build_instruction<IrInstSrcImplicitCast>(irb, scope, source_node); 4100 instruction->operand = operand; 4101 instruction->result_loc_cast = result_loc_cast; 4102 4103 ir_ref_instruction(operand, irb->current_basic_block); 4104 4105 return &instruction->base; 4106 } 4107 4108 static IrInstSrc *ir_build_bit_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4109 IrInstSrc *operand, ResultLocBitCast *result_loc_bit_cast) 4110 { 4111 IrInstSrcBitCast *instruction = ir_build_instruction<IrInstSrcBitCast>(irb, scope, source_node); 4112 instruction->operand = operand; 4113 instruction->result_loc_bit_cast = result_loc_bit_cast; 4114 4115 ir_ref_instruction(operand, irb->current_basic_block); 4116 4117 return &instruction->base; 4118 } 4119 4120 static IrInstGen *ir_build_bit_cast_gen(IrAnalyze *ira, IrInst *source_instruction, 4121 IrInstGen *operand, ZigType *ty) 4122 { 4123 IrInstGenBitCast *instruction = ir_build_inst_gen<IrInstGenBitCast>( 4124 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 4125 instruction->base.value->type = ty; 4126 instruction->operand = operand; 4127 4128 ir_ref_inst_gen(operand); 4129 4130 return &instruction->base; 4131 } 4132 4133 static IrInstGen *ir_build_widen_or_shorten(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, 4134 ZigType *result_type) 4135 { 4136 IrInstGenWidenOrShorten *inst = ir_build_inst_gen<IrInstGenWidenOrShorten>(&ira->new_irb, scope, source_node); 4137 inst->base.value->type = result_type; 4138 inst->target = target; 4139 4140 ir_ref_inst_gen(target); 4141 4142 return &inst->base; 4143 } 4144 4145 static IrInstSrc *ir_build_int_to_ptr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4146 IrInstSrc *dest_type, IrInstSrc *target) 4147 { 4148 IrInstSrcIntToPtr *instruction = ir_build_instruction<IrInstSrcIntToPtr>(irb, scope, source_node); 4149 instruction->dest_type = dest_type; 4150 instruction->target = target; 4151 4152 ir_ref_instruction(dest_type, irb->current_basic_block); 4153 ir_ref_instruction(target, irb->current_basic_block); 4154 4155 return &instruction->base; 4156 } 4157 4158 static IrInstGen *ir_build_int_to_ptr_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 4159 IrInstGen *target, ZigType *ptr_type) 4160 { 4161 IrInstGenIntToPtr *instruction = ir_build_inst_gen<IrInstGenIntToPtr>(&ira->new_irb, scope, source_node); 4162 instruction->base.value->type = ptr_type; 4163 instruction->target = target; 4164 4165 ir_ref_inst_gen(target); 4166 4167 return &instruction->base; 4168 } 4169 4170 static IrInstSrc *ir_build_ptr_to_int_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4171 IrInstSrc *target) 4172 { 4173 IrInstSrcPtrToInt *inst = ir_build_instruction<IrInstSrcPtrToInt>(irb, scope, source_node); 4174 inst->target = target; 4175 4176 ir_ref_instruction(target, irb->current_basic_block); 4177 4178 return &inst->base; 4179 } 4180 4181 static IrInstGen *ir_build_ptr_to_int_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target) { 4182 IrInstGenPtrToInt *inst = ir_build_inst_gen<IrInstGenPtrToInt>(&ira->new_irb, source_instr->scope, source_instr->source_node); 4183 inst->base.value->type = ira->codegen->builtin_types.entry_usize; 4184 inst->target = target; 4185 4186 ir_ref_inst_gen(target); 4187 4188 return &inst->base; 4189 } 4190 4191 static IrInstSrc *ir_build_int_to_enum_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4192 IrInstSrc *dest_type, IrInstSrc *target) 4193 { 4194 IrInstSrcIntToEnum *instruction = ir_build_instruction<IrInstSrcIntToEnum>(irb, scope, source_node); 4195 instruction->dest_type = dest_type; 4196 instruction->target = target; 4197 4198 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 4199 ir_ref_instruction(target, irb->current_basic_block); 4200 4201 return &instruction->base; 4202 } 4203 4204 static IrInstGen *ir_build_int_to_enum_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 4205 ZigType *dest_type, IrInstGen *target) 4206 { 4207 IrInstGenIntToEnum *instruction = ir_build_inst_gen<IrInstGenIntToEnum>(&ira->new_irb, scope, source_node); 4208 instruction->base.value->type = dest_type; 4209 instruction->target = target; 4210 4211 ir_ref_inst_gen(target); 4212 4213 return &instruction->base; 4214 } 4215 4216 static IrInstSrc *ir_build_enum_to_int(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4217 IrInstSrc *target) 4218 { 4219 IrInstSrcEnumToInt *instruction = ir_build_instruction<IrInstSrcEnumToInt>( 4220 irb, scope, source_node); 4221 instruction->target = target; 4222 4223 ir_ref_instruction(target, irb->current_basic_block); 4224 4225 return &instruction->base; 4226 } 4227 4228 static IrInstSrc *ir_build_int_to_err_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4229 IrInstSrc *target) 4230 { 4231 IrInstSrcIntToErr *instruction = ir_build_instruction<IrInstSrcIntToErr>(irb, scope, source_node); 4232 instruction->target = target; 4233 4234 ir_ref_instruction(target, irb->current_basic_block); 4235 4236 return &instruction->base; 4237 } 4238 4239 static IrInstGen *ir_build_int_to_err_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, 4240 ZigType *wanted_type) 4241 { 4242 IrInstGenIntToErr *instruction = ir_build_inst_gen<IrInstGenIntToErr>(&ira->new_irb, scope, source_node); 4243 instruction->base.value->type = wanted_type; 4244 instruction->target = target; 4245 4246 ir_ref_inst_gen(target); 4247 4248 return &instruction->base; 4249 } 4250 4251 static IrInstSrc *ir_build_err_to_int_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4252 IrInstSrc *target) 4253 { 4254 IrInstSrcErrToInt *instruction = ir_build_instruction<IrInstSrcErrToInt>( 4255 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_err_to_int_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, 4264 ZigType *wanted_type) 4265 { 4266 IrInstGenErrToInt *instruction = ir_build_inst_gen<IrInstGenErrToInt>(&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_check_switch_prongs(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4276 IrInstSrc *target_value, IrInstSrcCheckSwitchProngsRange *ranges, size_t range_count, 4277 bool have_else_prong, bool have_underscore_prong) 4278 { 4279 IrInstSrcCheckSwitchProngs *instruction = ir_build_instruction<IrInstSrcCheckSwitchProngs>( 4280 irb, scope, source_node); 4281 instruction->target_value = target_value; 4282 instruction->ranges = ranges; 4283 instruction->range_count = range_count; 4284 instruction->have_else_prong = have_else_prong; 4285 instruction->have_underscore_prong = have_underscore_prong; 4286 4287 ir_ref_instruction(target_value, irb->current_basic_block); 4288 for (size_t i = 0; i < range_count; i += 1) { 4289 ir_ref_instruction(ranges[i].start, irb->current_basic_block); 4290 ir_ref_instruction(ranges[i].end, irb->current_basic_block); 4291 } 4292 4293 return &instruction->base; 4294 } 4295 4296 static IrInstSrc *ir_build_check_statement_is_void(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4297 IrInstSrc* statement_value) 4298 { 4299 IrInstSrcCheckStatementIsVoid *instruction = ir_build_instruction<IrInstSrcCheckStatementIsVoid>( 4300 irb, scope, source_node); 4301 instruction->statement_value = statement_value; 4302 4303 ir_ref_instruction(statement_value, irb->current_basic_block); 4304 4305 return &instruction->base; 4306 } 4307 4308 static IrInstSrc *ir_build_type_name(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4309 IrInstSrc *type_value) 4310 { 4311 IrInstSrcTypeName *instruction = ir_build_instruction<IrInstSrcTypeName>(irb, scope, source_node); 4312 instruction->type_value = type_value; 4313 4314 ir_ref_instruction(type_value, irb->current_basic_block); 4315 4316 return &instruction->base; 4317 } 4318 4319 static IrInstSrc *ir_build_decl_ref(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) { 4320 IrInstSrcDeclRef *instruction = ir_build_instruction<IrInstSrcDeclRef>(irb, scope, source_node); 4321 instruction->tld = tld; 4322 instruction->lval = lval; 4323 4324 return &instruction->base; 4325 } 4326 4327 static IrInstSrc *ir_build_panic_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *msg) { 4328 IrInstSrcPanic *instruction = ir_build_instruction<IrInstSrcPanic>(irb, scope, source_node); 4329 instruction->base.is_noreturn = true; 4330 instruction->msg = msg; 4331 4332 ir_ref_instruction(msg, irb->current_basic_block); 4333 4334 return &instruction->base; 4335 } 4336 4337 static IrInstGen *ir_build_panic_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *msg) { 4338 IrInstGenPanic *instruction = ir_build_inst_noreturn<IrInstGenPanic>(&ira->new_irb, 4339 source_instr->scope, source_instr->source_node); 4340 instruction->msg = msg; 4341 4342 ir_ref_inst_gen(msg); 4343 4344 return &instruction->base; 4345 } 4346 4347 static IrInstSrc *ir_build_tag_name_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target) { 4348 IrInstSrcTagName *instruction = ir_build_instruction<IrInstSrcTagName>(irb, scope, source_node); 4349 instruction->target = target; 4350 4351 ir_ref_instruction(target, irb->current_basic_block); 4352 4353 return &instruction->base; 4354 } 4355 4356 static IrInstGen *ir_build_tag_name_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target, 4357 ZigType *result_type) 4358 { 4359 IrInstGenTagName *instruction = ir_build_inst_gen<IrInstGenTagName>(&ira->new_irb, 4360 source_instr->scope, source_instr->source_node); 4361 instruction->base.value->type = result_type; 4362 instruction->target = target; 4363 4364 ir_ref_inst_gen(target); 4365 4366 return &instruction->base; 4367 } 4368 4369 static IrInstSrc *ir_build_tag_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4370 IrInstSrc *target) 4371 { 4372 IrInstSrcTagType *instruction = ir_build_instruction<IrInstSrcTagType>(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 IrInstSrc *ir_build_field_parent_ptr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4381 IrInstSrc *type_value, IrInstSrc *field_name, IrInstSrc *field_ptr) 4382 { 4383 IrInstSrcFieldParentPtr *inst = ir_build_instruction<IrInstSrcFieldParentPtr>( 4384 irb, scope, source_node); 4385 inst->type_value = type_value; 4386 inst->field_name = field_name; 4387 inst->field_ptr = field_ptr; 4388 4389 ir_ref_instruction(type_value, irb->current_basic_block); 4390 ir_ref_instruction(field_name, irb->current_basic_block); 4391 ir_ref_instruction(field_ptr, irb->current_basic_block); 4392 4393 return &inst->base; 4394 } 4395 4396 static IrInstGen *ir_build_field_parent_ptr_gen(IrAnalyze *ira, IrInst *source_instr, 4397 IrInstGen *field_ptr, TypeStructField *field, ZigType *result_type) 4398 { 4399 IrInstGenFieldParentPtr *inst = ir_build_inst_gen<IrInstGenFieldParentPtr>(&ira->new_irb, 4400 source_instr->scope, source_instr->source_node); 4401 inst->base.value->type = result_type; 4402 inst->field_ptr = field_ptr; 4403 inst->field = field; 4404 4405 ir_ref_inst_gen(field_ptr); 4406 4407 return &inst->base; 4408 } 4409 4410 static IrInstSrc *ir_build_byte_offset_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4411 IrInstSrc *type_value, IrInstSrc *field_name) 4412 { 4413 IrInstSrcByteOffsetOf *instruction = ir_build_instruction<IrInstSrcByteOffsetOf>(irb, scope, source_node); 4414 instruction->type_value = type_value; 4415 instruction->field_name = field_name; 4416 4417 ir_ref_instruction(type_value, irb->current_basic_block); 4418 ir_ref_instruction(field_name, irb->current_basic_block); 4419 4420 return &instruction->base; 4421 } 4422 4423 static IrInstSrc *ir_build_bit_offset_of(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4424 IrInstSrc *type_value, IrInstSrc *field_name) 4425 { 4426 IrInstSrcBitOffsetOf *instruction = ir_build_instruction<IrInstSrcBitOffsetOf>(irb, scope, source_node); 4427 instruction->type_value = type_value; 4428 instruction->field_name = field_name; 4429 4430 ir_ref_instruction(type_value, irb->current_basic_block); 4431 ir_ref_instruction(field_name, irb->current_basic_block); 4432 4433 return &instruction->base; 4434 } 4435 4436 static IrInstSrc *ir_build_type_info(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value) { 4437 IrInstSrcTypeInfo *instruction = ir_build_instruction<IrInstSrcTypeInfo>(irb, scope, source_node); 4438 instruction->type_value = type_value; 4439 4440 ir_ref_instruction(type_value, irb->current_basic_block); 4441 4442 return &instruction->base; 4443 } 4444 4445 static IrInstSrc *ir_build_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_info) { 4446 IrInstSrcType *instruction = ir_build_instruction<IrInstSrcType>(irb, scope, source_node); 4447 instruction->type_info = type_info; 4448 4449 ir_ref_instruction(type_info, irb->current_basic_block); 4450 4451 return &instruction->base; 4452 } 4453 4454 static IrInstSrc *ir_build_set_eval_branch_quota(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4455 IrInstSrc *new_quota) 4456 { 4457 IrInstSrcSetEvalBranchQuota *instruction = ir_build_instruction<IrInstSrcSetEvalBranchQuota>(irb, scope, source_node); 4458 instruction->new_quota = new_quota; 4459 4460 ir_ref_instruction(new_quota, irb->current_basic_block); 4461 4462 return &instruction->base; 4463 } 4464 4465 static IrInstSrc *ir_build_align_cast_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4466 IrInstSrc *align_bytes, IrInstSrc *target) 4467 { 4468 IrInstSrcAlignCast *instruction = ir_build_instruction<IrInstSrcAlignCast>(irb, scope, source_node); 4469 instruction->align_bytes = align_bytes; 4470 instruction->target = target; 4471 4472 ir_ref_instruction(align_bytes, irb->current_basic_block); 4473 ir_ref_instruction(target, irb->current_basic_block); 4474 4475 return &instruction->base; 4476 } 4477 4478 static IrInstGen *ir_build_align_cast_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, IrInstGen *target, 4479 ZigType *result_type) 4480 { 4481 IrInstGenAlignCast *instruction = ir_build_inst_gen<IrInstGenAlignCast>(&ira->new_irb, scope, source_node); 4482 instruction->base.value->type = result_type; 4483 instruction->target = target; 4484 4485 ir_ref_inst_gen(target); 4486 4487 return &instruction->base; 4488 } 4489 4490 static IrInstSrc *ir_build_resolve_result(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4491 ResultLoc *result_loc, IrInstSrc *ty) 4492 { 4493 IrInstSrcResolveResult *instruction = ir_build_instruction<IrInstSrcResolveResult>(irb, scope, source_node); 4494 instruction->result_loc = result_loc; 4495 instruction->ty = ty; 4496 4497 if (ty != nullptr) ir_ref_instruction(ty, irb->current_basic_block); 4498 4499 return &instruction->base; 4500 } 4501 4502 static IrInstSrc *ir_build_reset_result(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4503 ResultLoc *result_loc) 4504 { 4505 IrInstSrcResetResult *instruction = ir_build_instruction<IrInstSrcResetResult>(irb, scope, source_node); 4506 instruction->result_loc = result_loc; 4507 instruction->base.is_gen = true; 4508 4509 return &instruction->base; 4510 } 4511 4512 static IrInstSrc *ir_build_opaque_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 4513 IrInstSrcOpaqueType *instruction = ir_build_instruction<IrInstSrcOpaqueType>(irb, scope, source_node); 4514 4515 return &instruction->base; 4516 } 4517 4518 static IrInstSrc *ir_build_set_align_stack(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4519 IrInstSrc *align_bytes) 4520 { 4521 IrInstSrcSetAlignStack *instruction = ir_build_instruction<IrInstSrcSetAlignStack>(irb, scope, source_node); 4522 instruction->align_bytes = align_bytes; 4523 4524 ir_ref_instruction(align_bytes, irb->current_basic_block); 4525 4526 return &instruction->base; 4527 } 4528 4529 static IrInstSrc *ir_build_arg_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4530 IrInstSrc *fn_type, IrInstSrc *arg_index, bool allow_var) 4531 { 4532 IrInstSrcArgType *instruction = ir_build_instruction<IrInstSrcArgType>(irb, scope, source_node); 4533 instruction->fn_type = fn_type; 4534 instruction->arg_index = arg_index; 4535 instruction->allow_var = allow_var; 4536 4537 ir_ref_instruction(fn_type, irb->current_basic_block); 4538 ir_ref_instruction(arg_index, irb->current_basic_block); 4539 4540 return &instruction->base; 4541 } 4542 4543 static IrInstSrc *ir_build_error_return_trace_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4544 IrInstErrorReturnTraceOptional optional) 4545 { 4546 IrInstSrcErrorReturnTrace *inst = ir_build_instruction<IrInstSrcErrorReturnTrace>(irb, scope, source_node); 4547 inst->optional = optional; 4548 4549 return &inst->base; 4550 } 4551 4552 static IrInstGen *ir_build_error_return_trace_gen(IrAnalyze *ira, Scope *scope, AstNode *source_node, 4553 IrInstErrorReturnTraceOptional optional, ZigType *result_type) 4554 { 4555 IrInstGenErrorReturnTrace *inst = ir_build_inst_gen<IrInstGenErrorReturnTrace>(&ira->new_irb, scope, source_node); 4556 inst->base.value->type = result_type; 4557 inst->optional = optional; 4558 4559 return &inst->base; 4560 } 4561 4562 static IrInstSrc *ir_build_error_union(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4563 IrInstSrc *err_set, IrInstSrc *payload) 4564 { 4565 IrInstSrcErrorUnion *instruction = ir_build_instruction<IrInstSrcErrorUnion>(irb, scope, source_node); 4566 instruction->err_set = err_set; 4567 instruction->payload = payload; 4568 4569 ir_ref_instruction(err_set, irb->current_basic_block); 4570 ir_ref_instruction(payload, irb->current_basic_block); 4571 4572 return &instruction->base; 4573 } 4574 4575 static IrInstSrc *ir_build_atomic_rmw_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4576 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *op, IrInstSrc *operand, 4577 IrInstSrc *ordering) 4578 { 4579 IrInstSrcAtomicRmw *instruction = ir_build_instruction<IrInstSrcAtomicRmw>(irb, scope, source_node); 4580 instruction->operand_type = operand_type; 4581 instruction->ptr = ptr; 4582 instruction->op = op; 4583 instruction->operand = operand; 4584 instruction->ordering = ordering; 4585 4586 ir_ref_instruction(operand_type, irb->current_basic_block); 4587 ir_ref_instruction(ptr, irb->current_basic_block); 4588 ir_ref_instruction(op, irb->current_basic_block); 4589 ir_ref_instruction(operand, irb->current_basic_block); 4590 ir_ref_instruction(ordering, irb->current_basic_block); 4591 4592 return &instruction->base; 4593 } 4594 4595 static IrInstGen *ir_build_atomic_rmw_gen(IrAnalyze *ira, IrInst *source_instr, 4596 IrInstGen *ptr, IrInstGen *operand, AtomicRmwOp op, AtomicOrder ordering, ZigType *operand_type) 4597 { 4598 IrInstGenAtomicRmw *instruction = ir_build_inst_gen<IrInstGenAtomicRmw>(&ira->new_irb, source_instr->scope, source_instr->source_node); 4599 instruction->base.value->type = operand_type; 4600 instruction->ptr = ptr; 4601 instruction->op = op; 4602 instruction->operand = operand; 4603 instruction->ordering = ordering; 4604 4605 ir_ref_inst_gen(ptr); 4606 ir_ref_inst_gen(operand); 4607 4608 return &instruction->base; 4609 } 4610 4611 static IrInstSrc *ir_build_atomic_load_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4612 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *ordering) 4613 { 4614 IrInstSrcAtomicLoad *instruction = ir_build_instruction<IrInstSrcAtomicLoad>(irb, scope, source_node); 4615 instruction->operand_type = operand_type; 4616 instruction->ptr = ptr; 4617 instruction->ordering = ordering; 4618 4619 ir_ref_instruction(operand_type, irb->current_basic_block); 4620 ir_ref_instruction(ptr, irb->current_basic_block); 4621 ir_ref_instruction(ordering, irb->current_basic_block); 4622 4623 return &instruction->base; 4624 } 4625 4626 static IrInstGen *ir_build_atomic_load_gen(IrAnalyze *ira, IrInst *source_instr, 4627 IrInstGen *ptr, AtomicOrder ordering, ZigType *operand_type) 4628 { 4629 IrInstGenAtomicLoad *instruction = ir_build_inst_gen<IrInstGenAtomicLoad>(&ira->new_irb, 4630 source_instr->scope, source_instr->source_node); 4631 instruction->base.value->type = operand_type; 4632 instruction->ptr = ptr; 4633 instruction->ordering = ordering; 4634 4635 ir_ref_inst_gen(ptr); 4636 4637 return &instruction->base; 4638 } 4639 4640 static IrInstSrc *ir_build_atomic_store_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4641 IrInstSrc *operand_type, IrInstSrc *ptr, IrInstSrc *value, IrInstSrc *ordering) 4642 { 4643 IrInstSrcAtomicStore *instruction = ir_build_instruction<IrInstSrcAtomicStore>(irb, scope, source_node); 4644 instruction->operand_type = operand_type; 4645 instruction->ptr = ptr; 4646 instruction->value = value; 4647 instruction->ordering = ordering; 4648 4649 ir_ref_instruction(operand_type, irb->current_basic_block); 4650 ir_ref_instruction(ptr, irb->current_basic_block); 4651 ir_ref_instruction(value, irb->current_basic_block); 4652 ir_ref_instruction(ordering, irb->current_basic_block); 4653 4654 return &instruction->base; 4655 } 4656 4657 static IrInstGen *ir_build_atomic_store_gen(IrAnalyze *ira, IrInst *source_instr, 4658 IrInstGen *ptr, IrInstGen *value, AtomicOrder ordering) 4659 { 4660 IrInstGenAtomicStore *instruction = ir_build_inst_void<IrInstGenAtomicStore>(&ira->new_irb, 4661 source_instr->scope, source_instr->source_node); 4662 instruction->ptr = ptr; 4663 instruction->value = value; 4664 instruction->ordering = ordering; 4665 4666 ir_ref_inst_gen(ptr); 4667 ir_ref_inst_gen(value); 4668 4669 return &instruction->base; 4670 } 4671 4672 static IrInstSrc *ir_build_save_err_ret_addr_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 4673 IrInstSrcSaveErrRetAddr *inst = ir_build_instruction<IrInstSrcSaveErrRetAddr>(irb, scope, source_node); 4674 return &inst->base; 4675 } 4676 4677 static IrInstGen *ir_build_save_err_ret_addr_gen(IrAnalyze *ira, IrInst *source_instr) { 4678 IrInstGenSaveErrRetAddr *inst = ir_build_inst_void<IrInstGenSaveErrRetAddr>(&ira->new_irb, 4679 source_instr->scope, source_instr->source_node); 4680 return &inst->base; 4681 } 4682 4683 static IrInstSrc *ir_build_add_implicit_return_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4684 IrInstSrc *value, ResultLocReturn *result_loc_ret) 4685 { 4686 IrInstSrcAddImplicitReturnType *inst = ir_build_instruction<IrInstSrcAddImplicitReturnType>(irb, scope, source_node); 4687 inst->value = value; 4688 inst->result_loc_ret = result_loc_ret; 4689 4690 ir_ref_instruction(value, irb->current_basic_block); 4691 4692 return &inst->base; 4693 } 4694 4695 static IrInstSrc *ir_build_has_decl(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4696 IrInstSrc *container, IrInstSrc *name) 4697 { 4698 IrInstSrcHasDecl *instruction = ir_build_instruction<IrInstSrcHasDecl>(irb, scope, source_node); 4699 instruction->container = container; 4700 instruction->name = name; 4701 4702 ir_ref_instruction(container, irb->current_basic_block); 4703 ir_ref_instruction(name, irb->current_basic_block); 4704 4705 return &instruction->base; 4706 } 4707 4708 static IrInstSrc *ir_build_undeclared_identifier(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, Buf *name) { 4709 IrInstSrcUndeclaredIdent *instruction = ir_build_instruction<IrInstSrcUndeclaredIdent>(irb, scope, source_node); 4710 instruction->name = name; 4711 4712 return &instruction->base; 4713 } 4714 4715 static IrInstSrc *ir_build_check_runtime_scope(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *scope_is_comptime, IrInstSrc *is_comptime) { 4716 IrInstSrcCheckRuntimeScope *instruction = ir_build_instruction<IrInstSrcCheckRuntimeScope>(irb, scope, source_node); 4717 instruction->scope_is_comptime = scope_is_comptime; 4718 instruction->is_comptime = is_comptime; 4719 4720 ir_ref_instruction(scope_is_comptime, irb->current_basic_block); 4721 ir_ref_instruction(is_comptime, irb->current_basic_block); 4722 4723 return &instruction->base; 4724 } 4725 4726 static IrInstSrc *ir_build_union_init_named_field(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4727 IrInstSrc *union_type, IrInstSrc *field_name, IrInstSrc *field_result_loc, IrInstSrc *result_loc) 4728 { 4729 IrInstSrcUnionInitNamedField *instruction = ir_build_instruction<IrInstSrcUnionInitNamedField>(irb, scope, source_node); 4730 instruction->union_type = union_type; 4731 instruction->field_name = field_name; 4732 instruction->field_result_loc = field_result_loc; 4733 instruction->result_loc = result_loc; 4734 4735 ir_ref_instruction(union_type, irb->current_basic_block); 4736 ir_ref_instruction(field_name, irb->current_basic_block); 4737 ir_ref_instruction(field_result_loc, irb->current_basic_block); 4738 if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); 4739 4740 return &instruction->base; 4741 } 4742 4743 4744 static IrInstGen *ir_build_vector_to_array(IrAnalyze *ira, IrInst *source_instruction, 4745 ZigType *result_type, IrInstGen *vector, IrInstGen *result_loc) 4746 { 4747 IrInstGenVectorToArray *instruction = ir_build_inst_gen<IrInstGenVectorToArray>(&ira->new_irb, 4748 source_instruction->scope, source_instruction->source_node); 4749 instruction->base.value->type = result_type; 4750 instruction->vector = vector; 4751 instruction->result_loc = result_loc; 4752 4753 ir_ref_inst_gen(vector); 4754 ir_ref_inst_gen(result_loc); 4755 4756 return &instruction->base; 4757 } 4758 4759 static IrInstGen *ir_build_ptr_of_array_to_slice(IrAnalyze *ira, IrInst *source_instruction, 4760 ZigType *result_type, IrInstGen *operand, IrInstGen *result_loc) 4761 { 4762 IrInstGenPtrOfArrayToSlice *instruction = ir_build_inst_gen<IrInstGenPtrOfArrayToSlice>(&ira->new_irb, 4763 source_instruction->scope, source_instruction->source_node); 4764 instruction->base.value->type = result_type; 4765 instruction->operand = operand; 4766 instruction->result_loc = result_loc; 4767 4768 ir_ref_inst_gen(operand); 4769 ir_ref_inst_gen(result_loc); 4770 4771 return &instruction->base; 4772 } 4773 4774 static IrInstGen *ir_build_array_to_vector(IrAnalyze *ira, IrInst *source_instruction, 4775 IrInstGen *array, ZigType *result_type) 4776 { 4777 IrInstGenArrayToVector *instruction = ir_build_inst_gen<IrInstGenArrayToVector>(&ira->new_irb, 4778 source_instruction->scope, source_instruction->source_node); 4779 instruction->base.value->type = result_type; 4780 instruction->array = array; 4781 4782 ir_ref_inst_gen(array); 4783 4784 return &instruction->base; 4785 } 4786 4787 static IrInstGen *ir_build_assert_zero(IrAnalyze *ira, IrInst *source_instruction, 4788 IrInstGen *target) 4789 { 4790 IrInstGenAssertZero *instruction = ir_build_inst_gen<IrInstGenAssertZero>(&ira->new_irb, 4791 source_instruction->scope, source_instruction->source_node); 4792 instruction->base.value->type = ira->codegen->builtin_types.entry_void; 4793 instruction->target = target; 4794 4795 ir_ref_inst_gen(target); 4796 4797 return &instruction->base; 4798 } 4799 4800 static IrInstGen *ir_build_assert_non_null(IrAnalyze *ira, IrInst *source_instruction, 4801 IrInstGen *target) 4802 { 4803 IrInstGenAssertNonNull *instruction = ir_build_inst_gen<IrInstGenAssertNonNull>(&ira->new_irb, 4804 source_instruction->scope, source_instruction->source_node); 4805 instruction->base.value->type = ira->codegen->builtin_types.entry_void; 4806 instruction->target = target; 4807 4808 ir_ref_inst_gen(target); 4809 4810 return &instruction->base; 4811 } 4812 4813 static IrInstSrc *ir_build_alloca_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4814 IrInstSrc *align, const char *name_hint, IrInstSrc *is_comptime) 4815 { 4816 IrInstSrcAlloca *instruction = ir_build_instruction<IrInstSrcAlloca>(irb, scope, source_node); 4817 instruction->base.is_gen = true; 4818 instruction->align = align; 4819 instruction->name_hint = name_hint; 4820 instruction->is_comptime = is_comptime; 4821 4822 if (align != nullptr) ir_ref_instruction(align, irb->current_basic_block); 4823 if (is_comptime != nullptr) ir_ref_instruction(is_comptime, irb->current_basic_block); 4824 4825 return &instruction->base; 4826 } 4827 4828 static IrInstGenAlloca *ir_build_alloca_gen(IrAnalyze *ira, IrInst *source_instruction, 4829 uint32_t align, const char *name_hint) 4830 { 4831 IrInstGenAlloca *instruction = ir_create_inst_gen<IrInstGenAlloca>(&ira->new_irb, 4832 source_instruction->scope, source_instruction->source_node); 4833 instruction->align = align; 4834 instruction->name_hint = name_hint; 4835 4836 return instruction; 4837 } 4838 4839 static IrInstSrc *ir_build_end_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4840 IrInstSrc *value, ResultLoc *result_loc) 4841 { 4842 IrInstSrcEndExpr *instruction = ir_build_instruction<IrInstSrcEndExpr>(irb, scope, source_node); 4843 instruction->base.is_gen = true; 4844 instruction->value = value; 4845 instruction->result_loc = result_loc; 4846 4847 ir_ref_instruction(value, irb->current_basic_block); 4848 4849 return &instruction->base; 4850 } 4851 4852 static IrInstSrcSuspendBegin *ir_build_suspend_begin_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 4853 return ir_build_instruction<IrInstSrcSuspendBegin>(irb, scope, source_node); 4854 } 4855 4856 static IrInstGen *ir_build_suspend_begin_gen(IrAnalyze *ira, IrInst *source_instr) { 4857 IrInstGenSuspendBegin *inst = ir_build_inst_void<IrInstGenSuspendBegin>(&ira->new_irb, 4858 source_instr->scope, source_instr->source_node); 4859 return &inst->base; 4860 } 4861 4862 static IrInstSrc *ir_build_suspend_finish_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4863 IrInstSrcSuspendBegin *begin) 4864 { 4865 IrInstSrcSuspendFinish *inst = ir_build_instruction<IrInstSrcSuspendFinish>(irb, scope, source_node); 4866 inst->begin = begin; 4867 4868 ir_ref_instruction(&begin->base, irb->current_basic_block); 4869 4870 return &inst->base; 4871 } 4872 4873 static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSuspendBegin *begin) { 4874 IrInstGenSuspendFinish *inst = ir_build_inst_void<IrInstGenSuspendFinish>(&ira->new_irb, 4875 source_instr->scope, source_instr->source_node); 4876 inst->begin = begin; 4877 4878 ir_ref_inst_gen(&begin->base); 4879 4880 return &inst->base; 4881 } 4882 4883 static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4884 IrInstSrc *frame, ResultLoc *result_loc, bool is_nosuspend) 4885 { 4886 IrInstSrcAwait *instruction = ir_build_instruction<IrInstSrcAwait>(irb, scope, source_node); 4887 instruction->frame = frame; 4888 instruction->result_loc = result_loc; 4889 instruction->is_nosuspend = is_nosuspend; 4890 4891 ir_ref_instruction(frame, irb->current_basic_block); 4892 4893 return &instruction->base; 4894 } 4895 4896 static IrInstGenAwait *ir_build_await_gen(IrAnalyze *ira, IrInst *source_instruction, 4897 IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc, bool is_nosuspend) 4898 { 4899 IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb, 4900 source_instruction->scope, source_instruction->source_node); 4901 instruction->base.value->type = result_type; 4902 instruction->frame = frame; 4903 instruction->result_loc = result_loc; 4904 instruction->is_nosuspend = is_nosuspend; 4905 4906 ir_ref_inst_gen(frame); 4907 if (result_loc != nullptr) ir_ref_inst_gen(result_loc); 4908 4909 return instruction; 4910 } 4911 4912 static IrInstSrc *ir_build_resume_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *frame) { 4913 IrInstSrcResume *instruction = ir_build_instruction<IrInstSrcResume>(irb, scope, source_node); 4914 instruction->frame = frame; 4915 4916 ir_ref_instruction(frame, irb->current_basic_block); 4917 4918 return &instruction->base; 4919 } 4920 4921 static IrInstGen *ir_build_resume_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *frame) { 4922 IrInstGenResume *instruction = ir_build_inst_void<IrInstGenResume>(&ira->new_irb, 4923 source_instr->scope, source_instr->source_node); 4924 instruction->frame = frame; 4925 4926 ir_ref_inst_gen(frame); 4927 4928 return &instruction->base; 4929 } 4930 4931 static IrInstSrcSpillBegin *ir_build_spill_begin_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4932 IrInstSrc *operand, SpillId spill_id) 4933 { 4934 IrInstSrcSpillBegin *instruction = ir_build_instruction<IrInstSrcSpillBegin>(irb, scope, source_node); 4935 instruction->operand = operand; 4936 instruction->spill_id = spill_id; 4937 4938 ir_ref_instruction(operand, irb->current_basic_block); 4939 4940 return instruction; 4941 } 4942 4943 static IrInstGen *ir_build_spill_begin_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *operand, 4944 SpillId spill_id) 4945 { 4946 IrInstGenSpillBegin *instruction = ir_build_inst_void<IrInstGenSpillBegin>(&ira->new_irb, 4947 source_instr->scope, source_instr->source_node); 4948 instruction->operand = operand; 4949 instruction->spill_id = spill_id; 4950 4951 ir_ref_inst_gen(operand); 4952 4953 return &instruction->base; 4954 } 4955 4956 static IrInstSrc *ir_build_spill_end_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 4957 IrInstSrcSpillBegin *begin) 4958 { 4959 IrInstSrcSpillEnd *instruction = ir_build_instruction<IrInstSrcSpillEnd>(irb, scope, source_node); 4960 instruction->begin = begin; 4961 4962 ir_ref_instruction(&begin->base, irb->current_basic_block); 4963 4964 return &instruction->base; 4965 } 4966 4967 static IrInstGen *ir_build_spill_end_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGenSpillBegin *begin, 4968 ZigType *result_type) 4969 { 4970 IrInstGenSpillEnd *instruction = ir_build_inst_gen<IrInstGenSpillEnd>(&ira->new_irb, 4971 source_instr->scope, source_instr->source_node); 4972 instruction->base.value->type = result_type; 4973 instruction->begin = begin; 4974 4975 ir_ref_inst_gen(&begin->base); 4976 4977 return &instruction->base; 4978 } 4979 4980 static IrInstGen *ir_build_vector_extract_elem(IrAnalyze *ira, IrInst *source_instruction, 4981 IrInstGen *vector, IrInstGen *index) 4982 { 4983 IrInstGenVectorExtractElem *instruction = ir_build_inst_gen<IrInstGenVectorExtractElem>( 4984 &ira->new_irb, source_instruction->scope, source_instruction->source_node); 4985 instruction->base.value->type = vector->value->type->data.vector.elem_type; 4986 instruction->vector = vector; 4987 instruction->index = index; 4988 4989 ir_ref_inst_gen(vector); 4990 ir_ref_inst_gen(index); 4991 4992 return &instruction->base; 4993 } 4994 4995 static IrInstSrc *ir_build_wasm_memory_size_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *index) { 4996 IrInstSrcWasmMemorySize *instruction = ir_build_instruction<IrInstSrcWasmMemorySize>(irb, scope, source_node); 4997 instruction->index = index; 4998 4999 ir_ref_instruction(index, irb->current_basic_block); 5000 5001 return &instruction->base; 5002 } 5003 5004 static IrInstGen *ir_build_wasm_memory_size_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *index) { 5005 IrInstGenWasmMemorySize *instruction = ir_build_inst_gen<IrInstGenWasmMemorySize>(&ira->new_irb, 5006 source_instr->scope, source_instr->source_node); 5007 instruction->base.value->type = ira->codegen->builtin_types.entry_u32; 5008 instruction->index = index; 5009 5010 ir_ref_inst_gen(index); 5011 5012 return &instruction->base; 5013 } 5014 5015 static IrInstSrc *ir_build_wasm_memory_grow_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *index, IrInstSrc *delta) { 5016 IrInstSrcWasmMemoryGrow *instruction = ir_build_instruction<IrInstSrcWasmMemoryGrow>(irb, scope, source_node); 5017 instruction->index = index; 5018 instruction->delta = delta; 5019 5020 ir_ref_instruction(index, irb->current_basic_block); 5021 ir_ref_instruction(delta, irb->current_basic_block); 5022 5023 return &instruction->base; 5024 } 5025 5026 static IrInstGen *ir_build_wasm_memory_grow_gen(IrAnalyze *ira, IrInst *source_instr, IrInstGen *index, IrInstGen *delta) { 5027 IrInstGenWasmMemoryGrow *instruction = ir_build_inst_gen<IrInstGenWasmMemoryGrow>(&ira->new_irb, 5028 source_instr->scope, source_instr->source_node); 5029 instruction->base.value->type = ira->codegen->builtin_types.entry_i32; 5030 instruction->index = index; 5031 instruction->delta = delta; 5032 5033 ir_ref_inst_gen(index); 5034 ir_ref_inst_gen(delta); 5035 5036 return &instruction->base; 5037 } 5038 5039 static IrInstSrc *ir_build_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) { 5040 IrInstSrcSrc *instruction = ir_build_instruction<IrInstSrcSrc>(irb, scope, source_node); 5041 5042 return &instruction->base; 5043 } 5044 5045 static void ir_count_defers(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { 5046 results[ReturnKindUnconditional] = 0; 5047 results[ReturnKindError] = 0; 5048 5049 Scope *scope = inner_scope; 5050 5051 while (scope != outer_scope) { 5052 assert(scope); 5053 switch (scope->id) { 5054 case ScopeIdDefer: { 5055 AstNode *defer_node = scope->source_node; 5056 assert(defer_node->type == NodeTypeDefer); 5057 ReturnKind defer_kind = defer_node->data.defer.kind; 5058 results[defer_kind] += 1; 5059 scope = scope->parent; 5060 continue; 5061 } 5062 case ScopeIdDecls: 5063 case ScopeIdFnDef: 5064 return; 5065 case ScopeIdBlock: 5066 case ScopeIdVarDecl: 5067 case ScopeIdLoop: 5068 case ScopeIdSuspend: 5069 case ScopeIdCompTime: 5070 case ScopeIdNoSuspend: 5071 case ScopeIdRuntime: 5072 case ScopeIdTypeOf: 5073 case ScopeIdExpr: 5074 scope = scope->parent; 5075 continue; 5076 case ScopeIdDeferExpr: 5077 case ScopeIdCImport: 5078 zig_unreachable(); 5079 } 5080 } 5081 } 5082 5083 static IrInstSrc *ir_mark_gen(IrInstSrc *instruction) { 5084 instruction->is_gen = true; 5085 return instruction; 5086 } 5087 5088 static bool ir_gen_defers_for_block(IrBuilderSrc *irb, Scope *inner_scope, Scope *outer_scope, bool *is_noreturn, IrInstSrc *err_value) { 5089 Scope *scope = inner_scope; 5090 if (is_noreturn != nullptr) *is_noreturn = false; 5091 while (scope != outer_scope) { 5092 if (!scope) 5093 return true; 5094 5095 switch (scope->id) { 5096 case ScopeIdDefer: { 5097 AstNode *defer_node = scope->source_node; 5098 assert(defer_node->type == NodeTypeDefer); 5099 ReturnKind defer_kind = defer_node->data.defer.kind; 5100 AstNode *defer_expr_node = defer_node->data.defer.expr; 5101 AstNode *defer_var_node = defer_node->data.defer.err_payload; 5102 5103 if (defer_kind == ReturnKindError && err_value == nullptr) { 5104 // This is an `errdefer` but we're generating code for a 5105 // `return` that doesn't return an error, skip it 5106 scope = scope->parent; 5107 continue; 5108 } 5109 5110 Scope *defer_expr_scope = defer_node->data.defer.expr_scope; 5111 if (defer_var_node != nullptr) { 5112 assert(defer_kind == ReturnKindError); 5113 assert(defer_var_node->type == NodeTypeSymbol); 5114 Buf *var_name = defer_var_node->data.symbol_expr.symbol; 5115 5116 if (defer_expr_node->type == NodeTypeUnreachable) { 5117 add_node_error(irb->codegen, defer_var_node, 5118 buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); 5119 return false; 5120 } 5121 5122 IrInstSrc *is_comptime; 5123 if (ir_should_inline(irb->exec, defer_expr_scope)) { 5124 is_comptime = ir_build_const_bool(irb, defer_expr_scope, 5125 defer_expr_node, true); 5126 } else { 5127 is_comptime = ir_build_test_comptime(irb, defer_expr_scope, 5128 defer_expr_node, err_value); 5129 } 5130 5131 ZigVar *err_var = ir_create_var(irb, defer_var_node, defer_expr_scope, 5132 var_name, true, true, false, is_comptime); 5133 build_decl_var_and_init(irb, defer_expr_scope, defer_var_node, err_var, err_value, 5134 buf_ptr(var_name), is_comptime); 5135 5136 defer_expr_scope = err_var->child_scope; 5137 } 5138 5139 IrInstSrc *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope); 5140 if (defer_expr_value == irb->codegen->invalid_inst_src) 5141 return irb->codegen->invalid_inst_src; 5142 5143 if (defer_expr_value->is_noreturn) { 5144 if (is_noreturn != nullptr) *is_noreturn = true; 5145 } else { 5146 ir_mark_gen(ir_build_check_statement_is_void(irb, defer_expr_scope, defer_expr_node, 5147 defer_expr_value)); 5148 } 5149 scope = scope->parent; 5150 continue; 5151 } 5152 case ScopeIdDecls: 5153 case ScopeIdFnDef: 5154 return true; 5155 case ScopeIdBlock: 5156 case ScopeIdVarDecl: 5157 case ScopeIdLoop: 5158 case ScopeIdSuspend: 5159 case ScopeIdCompTime: 5160 case ScopeIdNoSuspend: 5161 case ScopeIdRuntime: 5162 case ScopeIdTypeOf: 5163 case ScopeIdExpr: 5164 scope = scope->parent; 5165 continue; 5166 case ScopeIdDeferExpr: 5167 case ScopeIdCImport: 5168 zig_unreachable(); 5169 } 5170 } 5171 return true; 5172 } 5173 5174 static void ir_set_cursor_at_end_gen(IrBuilderGen *irb, IrBasicBlockGen *basic_block) { 5175 assert(basic_block); 5176 irb->current_basic_block = basic_block; 5177 } 5178 5179 static void ir_set_cursor_at_end(IrBuilderSrc *irb, IrBasicBlockSrc *basic_block) { 5180 assert(basic_block); 5181 irb->current_basic_block = basic_block; 5182 } 5183 5184 static void ir_append_basic_block_gen(IrBuilderGen *irb, IrBasicBlockGen *bb) { 5185 assert(!bb->already_appended); 5186 bb->already_appended = true; 5187 irb->exec->basic_block_list.append(bb); 5188 } 5189 5190 static void ir_set_cursor_at_end_and_append_block_gen(IrBuilderGen *irb, IrBasicBlockGen *basic_block) { 5191 ir_append_basic_block_gen(irb, basic_block); 5192 ir_set_cursor_at_end_gen(irb, basic_block); 5193 } 5194 5195 static void ir_set_cursor_at_end_and_append_block(IrBuilderSrc *irb, IrBasicBlockSrc *basic_block) { 5196 basic_block->index = irb->exec->basic_block_list.length; 5197 irb->exec->basic_block_list.append(basic_block); 5198 ir_set_cursor_at_end(irb, basic_block); 5199 } 5200 5201 static ScopeSuspend *get_scope_suspend(Scope *scope) { 5202 while (scope) { 5203 if (scope->id == ScopeIdSuspend) 5204 return (ScopeSuspend *)scope; 5205 if (scope->id == ScopeIdFnDef) 5206 return nullptr; 5207 5208 scope = scope->parent; 5209 } 5210 return nullptr; 5211 } 5212 5213 static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { 5214 while (scope) { 5215 if (scope->id == ScopeIdDeferExpr) 5216 return (ScopeDeferExpr *)scope; 5217 if (scope->id == ScopeIdFnDef) 5218 return nullptr; 5219 5220 scope = scope->parent; 5221 } 5222 return nullptr; 5223 } 5224 5225 static IrInstSrc *ir_gen_return(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 5226 assert(node->type == NodeTypeReturnExpr); 5227 5228 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); 5229 if (scope_defer_expr) { 5230 if (!scope_defer_expr->reported_err) { 5231 add_node_error(irb->codegen, node, buf_sprintf("cannot return from defer expression")); 5232 scope_defer_expr->reported_err = true; 5233 } 5234 return irb->codegen->invalid_inst_src; 5235 } 5236 5237 Scope *outer_scope = irb->exec->begin_scope; 5238 5239 AstNode *expr_node = node->data.return_expr.expr; 5240 switch (node->data.return_expr.kind) { 5241 case ReturnKindUnconditional: 5242 { 5243 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>(); 5244 result_loc_ret->base.id = ResultLocIdReturn; 5245 ir_build_reset_result(irb, scope, node, &result_loc_ret->base); 5246 5247 IrInstSrc *return_value; 5248 if (expr_node) { 5249 // Temporarily set this so that if we return a type it gets the name of the function 5250 ZigFn *prev_name_fn = irb->exec->name_fn; 5251 irb->exec->name_fn = exec_fn_entry(irb->exec); 5252 return_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, &result_loc_ret->base); 5253 irb->exec->name_fn = prev_name_fn; 5254 if (return_value == irb->codegen->invalid_inst_src) 5255 return irb->codegen->invalid_inst_src; 5256 } else { 5257 return_value = ir_build_const_void(irb, scope, node); 5258 ir_build_end_expr(irb, scope, node, return_value, &result_loc_ret->base); 5259 } 5260 5261 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value, result_loc_ret)); 5262 5263 size_t defer_counts[2]; 5264 ir_count_defers(irb, scope, outer_scope, defer_counts); 5265 bool have_err_defers = defer_counts[ReturnKindError] > 0; 5266 if (!have_err_defers && !irb->codegen->have_err_ret_tracing) { 5267 // only generate unconditional defers 5268 if (!ir_gen_defers_for_block(irb, scope, outer_scope, nullptr, nullptr)) 5269 return irb->codegen->invalid_inst_src; 5270 IrInstSrc *result = ir_build_return_src(irb, scope, node, nullptr); 5271 result_loc_ret->base.source_instruction = result; 5272 return result; 5273 } 5274 bool should_inline = ir_should_inline(irb->exec, scope); 5275 5276 IrBasicBlockSrc *err_block = ir_create_basic_block(irb, scope, "ErrRetErr"); 5277 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk"); 5278 5279 IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node, return_value, false, true); 5280 5281 IrInstSrc *is_comptime; 5282 if (should_inline) { 5283 is_comptime = ir_build_const_bool(irb, scope, node, should_inline); 5284 } else { 5285 is_comptime = ir_build_test_comptime(irb, scope, node, is_err); 5286 } 5287 5288 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime)); 5289 IrBasicBlockSrc *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt"); 5290 5291 ir_set_cursor_at_end_and_append_block(irb, err_block); 5292 if (!ir_gen_defers_for_block(irb, scope, outer_scope, nullptr, return_value)) 5293 return irb->codegen->invalid_inst_src; 5294 if (irb->codegen->have_err_ret_tracing && !should_inline) { 5295 ir_build_save_err_ret_addr_src(irb, scope, node); 5296 } 5297 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 5298 5299 ir_set_cursor_at_end_and_append_block(irb, ok_block); 5300 if (!ir_gen_defers_for_block(irb, scope, outer_scope, nullptr, nullptr)) 5301 return irb->codegen->invalid_inst_src; 5302 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 5303 5304 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); 5305 IrInstSrc *result = ir_build_return_src(irb, scope, node, nullptr); 5306 result_loc_ret->base.source_instruction = result; 5307 return result; 5308 } 5309 case ReturnKindError: 5310 { 5311 assert(expr_node); 5312 IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 5313 if (err_union_ptr == irb->codegen->invalid_inst_src) 5314 return irb->codegen->invalid_inst_src; 5315 IrInstSrc *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr, true, false); 5316 5317 IrBasicBlockSrc *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); 5318 IrBasicBlockSrc *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); 5319 IrInstSrc *is_comptime; 5320 bool should_inline = ir_should_inline(irb->exec, scope); 5321 if (should_inline) { 5322 is_comptime = ir_build_const_bool(irb, scope, node, true); 5323 } else { 5324 is_comptime = ir_build_test_comptime(irb, scope, node, is_err_val); 5325 } 5326 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime)); 5327 5328 ir_set_cursor_at_end_and_append_block(irb, return_block); 5329 IrInstSrc *err_val_ptr = ir_build_unwrap_err_code_src(irb, scope, node, err_union_ptr); 5330 IrInstSrc *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); 5331 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, err_val, nullptr)); 5332 IrInstSrcSpillBegin *spill_begin = ir_build_spill_begin_src(irb, scope, node, err_val, 5333 SpillIdRetErrCode); 5334 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>(); 5335 result_loc_ret->base.id = ResultLocIdReturn; 5336 ir_build_reset_result(irb, scope, node, &result_loc_ret->base); 5337 ir_build_end_expr(irb, scope, node, err_val, &result_loc_ret->base); 5338 5339 bool is_noreturn = false; 5340 if (!ir_gen_defers_for_block(irb, scope, outer_scope, &is_noreturn, err_val)) { 5341 return irb->codegen->invalid_inst_src; 5342 } 5343 if (!is_noreturn) { 5344 if (irb->codegen->have_err_ret_tracing && !should_inline) { 5345 ir_build_save_err_ret_addr_src(irb, scope, node); 5346 } 5347 err_val = ir_build_spill_end_src(irb, scope, node, spill_begin); 5348 IrInstSrc *ret_inst = ir_build_return_src(irb, scope, node, err_val); 5349 result_loc_ret->base.source_instruction = ret_inst; 5350 } 5351 5352 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5353 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(irb, scope, node, err_union_ptr, false, false); 5354 if (lval == LValPtr) 5355 return unwrapped_ptr; 5356 else 5357 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, unwrapped_ptr), result_loc); 5358 } 5359 } 5360 zig_unreachable(); 5361 } 5362 5363 static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope, 5364 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime, 5365 bool skip_name_check) 5366 { 5367 ZigVar *variable_entry = heap::c_allocator.create<ZigVar>(); 5368 variable_entry->parent_scope = parent_scope; 5369 variable_entry->shadowable = is_shadowable; 5370 variable_entry->is_comptime = is_comptime; 5371 variable_entry->src_arg_index = SIZE_MAX; 5372 variable_entry->const_value = codegen->pass1_arena->create<ZigValue>(); 5373 5374 if (is_comptime != nullptr) { 5375 is_comptime->base.ref_count += 1; 5376 } 5377 5378 if (name) { 5379 variable_entry->name = strdup(buf_ptr(name)); 5380 5381 if (!skip_name_check) { 5382 ZigVar *existing_var = find_variable(codegen, parent_scope, name, nullptr); 5383 if (existing_var && !existing_var->shadowable) { 5384 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) { 5385 ErrorMsg *msg = add_node_error(codegen, node, 5386 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); 5387 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); 5388 } 5389 variable_entry->var_type = codegen->builtin_types.entry_invalid; 5390 } else { 5391 ZigType *type; 5392 if (get_primitive_type(codegen, name, &type) != ErrorPrimitiveTypeNotFound) { 5393 add_node_error(codegen, node, 5394 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name))); 5395 variable_entry->var_type = codegen->builtin_types.entry_invalid; 5396 } else { 5397 Tld *tld = find_decl(codegen, parent_scope, name); 5398 if (tld != nullptr) { 5399 bool want_err_msg = true; 5400 if (tld->id == TldIdVar) { 5401 ZigVar *var = reinterpret_cast<TldVar *>(tld)->var; 5402 if (var != nullptr && var->var_type != nullptr && type_is_invalid(var->var_type)) { 5403 want_err_msg = false; 5404 } 5405 } 5406 if (want_err_msg) { 5407 ErrorMsg *msg = add_node_error(codegen, node, 5408 buf_sprintf("redefinition of '%s'", buf_ptr(name))); 5409 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here")); 5410 } 5411 variable_entry->var_type = codegen->builtin_types.entry_invalid; 5412 } 5413 } 5414 } 5415 } 5416 } else { 5417 assert(is_shadowable); 5418 // TODO make this name not actually be in scope. user should be able to make a variable called "_anon" 5419 // might already be solved, let's just make sure it has test coverage 5420 // maybe we put a prefix on this so the debug info doesn't clobber user debug info for same named variables 5421 variable_entry->name = "_anon"; 5422 } 5423 5424 variable_entry->src_is_const = src_is_const; 5425 variable_entry->gen_is_const = gen_is_const; 5426 variable_entry->decl_node = node; 5427 variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry); 5428 5429 return variable_entry; 5430 } 5431 5432 // Set name to nullptr to make the variable anonymous (not visible to programmer). 5433 // After you call this function var->child_scope has the variable in scope 5434 static ZigVar *ir_create_var(IrBuilderSrc *irb, AstNode *node, Scope *scope, Buf *name, 5435 bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstSrc *is_comptime) 5436 { 5437 bool is_underscored = name ? buf_eql_str(name, "_") : false; 5438 ZigVar *var = create_local_var(irb->codegen, node, scope, 5439 (is_underscored ? nullptr : name), src_is_const, gen_is_const, 5440 (is_underscored ? true : is_shadowable), is_comptime, false); 5441 assert(var->child_scope); 5442 return var; 5443 } 5444 5445 static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) { 5446 ResultLocPeer *result = heap::c_allocator.create<ResultLocPeer>(); 5447 result->base.id = ResultLocIdPeer; 5448 result->base.source_instruction = peer_parent->base.source_instruction; 5449 result->parent = peer_parent; 5450 result->base.allow_write_through_const = peer_parent->parent->allow_write_through_const; 5451 return result; 5452 } 5453 5454 static IrInstSrc *ir_gen_block(IrBuilderSrc *irb, Scope *parent_scope, AstNode *block_node, LVal lval, 5455 ResultLoc *result_loc) 5456 { 5457 assert(block_node->type == NodeTypeBlock); 5458 5459 ZigList<IrInstSrc *> incoming_values = {0}; 5460 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 5461 5462 ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope); 5463 5464 Scope *outer_block_scope = &scope_block->base; 5465 Scope *child_scope = outer_block_scope; 5466 5467 ZigFn *fn_entry = scope_fn_entry(parent_scope); 5468 if (fn_entry && fn_entry->child_scope == parent_scope) { 5469 fn_entry->def_scope = scope_block; 5470 } 5471 5472 if (block_node->data.block.statements.length == 0) { 5473 // {} 5474 return ir_lval_wrap(irb, parent_scope, ir_build_const_void(irb, child_scope, block_node), lval, result_loc); 5475 } 5476 5477 if (block_node->data.block.name != nullptr) { 5478 scope_block->lval = lval; 5479 scope_block->incoming_blocks = &incoming_blocks; 5480 scope_block->incoming_values = &incoming_values; 5481 scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd"); 5482 scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, 5483 ir_should_inline(irb->exec, parent_scope)); 5484 5485 scope_block->peer_parent = heap::c_allocator.create<ResultLocPeerParent>(); 5486 scope_block->peer_parent->base.id = ResultLocIdPeerParent; 5487 scope_block->peer_parent->base.source_instruction = scope_block->is_comptime; 5488 scope_block->peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; 5489 scope_block->peer_parent->end_bb = scope_block->end_block; 5490 scope_block->peer_parent->is_comptime = scope_block->is_comptime; 5491 scope_block->peer_parent->parent = result_loc; 5492 ir_build_reset_result(irb, parent_scope, block_node, &scope_block->peer_parent->base); 5493 } 5494 5495 bool is_continuation_unreachable = false; 5496 bool found_invalid_inst = false; 5497 IrInstSrc *noreturn_return_value = nullptr; 5498 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { 5499 AstNode *statement_node = block_node->data.block.statements.at(i); 5500 5501 IrInstSrc *statement_value = ir_gen_node(irb, statement_node, child_scope); 5502 if (statement_value == irb->codegen->invalid_inst_src) { 5503 // keep generating all the elements of the block in case of error, 5504 // we want to collect other compile errors 5505 found_invalid_inst = true; 5506 continue; 5507 } 5508 5509 is_continuation_unreachable = instr_is_unreachable(statement_value); 5510 if (is_continuation_unreachable) { 5511 // keep the last noreturn statement value around in case we need to return it 5512 noreturn_return_value = statement_value; 5513 } 5514 // This logic must be kept in sync with 5515 // [STMT_EXPR_TEST_THING] <--- (search this token) 5516 if (statement_node->type == NodeTypeDefer) { 5517 // defer starts a new scope 5518 child_scope = statement_node->data.defer.child_scope; 5519 assert(child_scope); 5520 } else if (statement_value->id == IrInstSrcIdDeclVar) { 5521 // variable declarations start a new scope 5522 IrInstSrcDeclVar *decl_var_instruction = (IrInstSrcDeclVar *)statement_value; 5523 child_scope = decl_var_instruction->var->child_scope; 5524 } else if (!is_continuation_unreachable) { 5525 // this statement's value must be void 5526 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value)); 5527 } 5528 } 5529 5530 if (found_invalid_inst) 5531 return irb->codegen->invalid_inst_src; 5532 5533 if (is_continuation_unreachable) { 5534 assert(noreturn_return_value != nullptr); 5535 if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) { 5536 return noreturn_return_value; 5537 } 5538 5539 if (scope_block->peer_parent != nullptr && scope_block->peer_parent->peers.length != 0) { 5540 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; 5541 } 5542 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 5543 IrInstSrc *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, 5544 incoming_blocks.items, incoming_values.items, scope_block->peer_parent); 5545 return ir_expr_wrap(irb, parent_scope, phi, result_loc); 5546 } else { 5547 incoming_blocks.append(irb->current_basic_block); 5548 IrInstSrc *else_expr_result = ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node)); 5549 5550 if (scope_block->peer_parent != nullptr) { 5551 ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent); 5552 scope_block->peer_parent->peers.append(peer_result); 5553 ir_build_end_expr(irb, parent_scope, block_node, else_expr_result, &peer_result->base); 5554 5555 if (scope_block->peer_parent->peers.length != 0) { 5556 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block; 5557 } 5558 } 5559 5560 incoming_values.append(else_expr_result); 5561 } 5562 5563 bool is_return_from_fn = block_node == irb->main_block_node; 5564 if (!is_return_from_fn) { 5565 if (!ir_gen_defers_for_block(irb, child_scope, outer_block_scope, nullptr, nullptr)) 5566 return irb->codegen->invalid_inst_src; 5567 } 5568 5569 IrInstSrc *result; 5570 if (block_node->data.block.name != nullptr) { 5571 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); 5572 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 5573 IrInstSrc *phi = ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, 5574 incoming_blocks.items, incoming_values.items, scope_block->peer_parent); 5575 result = ir_expr_wrap(irb, parent_scope, phi, result_loc); 5576 } else { 5577 IrInstSrc *void_inst = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)); 5578 result = ir_lval_wrap(irb, parent_scope, void_inst, lval, result_loc); 5579 } 5580 if (!is_return_from_fn) 5581 return result; 5582 5583 // no need for save_err_ret_addr because this cannot return error 5584 // only generate unconditional defers 5585 5586 ir_mark_gen(ir_build_add_implicit_return_type(irb, child_scope, block_node, result, nullptr)); 5587 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>(); 5588 result_loc_ret->base.id = ResultLocIdReturn; 5589 ir_build_reset_result(irb, parent_scope, block_node, &result_loc_ret->base); 5590 ir_mark_gen(ir_build_end_expr(irb, parent_scope, block_node, result, &result_loc_ret->base)); 5591 if (!ir_gen_defers_for_block(irb, child_scope, outer_block_scope, nullptr, nullptr)) 5592 return irb->codegen->invalid_inst_src; 5593 return ir_mark_gen(ir_build_return_src(irb, child_scope, result->base.source_node, result)); 5594 } 5595 5596 static IrInstSrc *ir_gen_bin_op_id(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 5597 Scope *inner_scope = scope; 5598 if (op_id == IrBinOpArrayCat || op_id == IrBinOpArrayMult) { 5599 inner_scope = create_comptime_scope(irb->codegen, node, scope); 5600 } 5601 5602 IrInstSrc *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, inner_scope); 5603 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, inner_scope); 5604 5605 if (op1 == irb->codegen->invalid_inst_src || op2 == irb->codegen->invalid_inst_src) 5606 return irb->codegen->invalid_inst_src; 5607 5608 return ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 5609 } 5610 5611 static IrInstSrc *ir_gen_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5612 IrInstSrc *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 5613 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5614 5615 if (op1 == irb->codegen->invalid_inst_src || op2 == irb->codegen->invalid_inst_src) 5616 return irb->codegen->invalid_inst_src; 5617 5618 // TODO only pass type_name when the || operator is the top level AST node in the var decl expr 5619 Buf bare_name = BUF_INIT; 5620 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error", scope, node, &bare_name); 5621 5622 return ir_build_merge_err_sets(irb, scope, node, op1, op2, type_name); 5623 } 5624 5625 static IrInstSrc *ir_gen_assign(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5626 IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValAssign, nullptr); 5627 if (lvalue == irb->codegen->invalid_inst_src) 5628 return irb->codegen->invalid_inst_src; 5629 5630 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>(); 5631 result_loc_inst->base.id = ResultLocIdInstruction; 5632 result_loc_inst->base.source_instruction = lvalue; 5633 ir_ref_instruction(lvalue, irb->current_basic_block); 5634 ir_build_reset_result(irb, scope, node, &result_loc_inst->base); 5635 5636 IrInstSrc *rvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op2, scope, LValNone, 5637 &result_loc_inst->base); 5638 if (rvalue == irb->codegen->invalid_inst_src) 5639 return irb->codegen->invalid_inst_src; 5640 5641 return ir_build_const_void(irb, scope, node); 5642 } 5643 5644 static IrInstSrc *ir_gen_assign_merge_err_sets(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5645 IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValAssign, nullptr); 5646 if (lvalue == irb->codegen->invalid_inst_src) 5647 return lvalue; 5648 IrInstSrc *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); 5649 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5650 if (op2 == irb->codegen->invalid_inst_src) 5651 return op2; 5652 IrInstSrc *result = ir_build_merge_err_sets(irb, scope, node, op1, op2, nullptr); 5653 ir_build_store_ptr(irb, scope, node, lvalue, result); 5654 return ir_build_const_void(irb, scope, node); 5655 } 5656 5657 static IrInstSrc *ir_gen_assign_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 5658 IrInstSrc *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValAssign, nullptr); 5659 if (lvalue == irb->codegen->invalid_inst_src) 5660 return lvalue; 5661 IrInstSrc *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); 5662 IrInstSrc *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5663 if (op2 == irb->codegen->invalid_inst_src) 5664 return op2; 5665 IrInstSrc *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 5666 ir_build_store_ptr(irb, scope, node, lvalue, result); 5667 return ir_build_const_void(irb, scope, node); 5668 } 5669 5670 static IrInstSrc *ir_gen_bool_or(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5671 assert(node->type == NodeTypeBinOpExpr); 5672 5673 IrInstSrc *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 5674 if (val1 == irb->codegen->invalid_inst_src) 5675 return irb->codegen->invalid_inst_src; 5676 IrBasicBlockSrc *post_val1_block = irb->current_basic_block; 5677 5678 IrInstSrc *is_comptime; 5679 if (ir_should_inline(irb->exec, scope)) { 5680 is_comptime = ir_build_const_bool(irb, scope, node, true); 5681 } else { 5682 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 5683 } 5684 5685 // block for when val1 == false 5686 IrBasicBlockSrc *false_block = ir_create_basic_block(irb, scope, "BoolOrFalse"); 5687 // block for when val1 == true (don't even evaluate the second part) 5688 IrBasicBlockSrc *true_block = ir_create_basic_block(irb, scope, "BoolOrTrue"); 5689 5690 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 5691 5692 ir_set_cursor_at_end_and_append_block(irb, false_block); 5693 IrInstSrc *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5694 if (val2 == irb->codegen->invalid_inst_src) 5695 return irb->codegen->invalid_inst_src; 5696 IrBasicBlockSrc *post_val2_block = irb->current_basic_block; 5697 5698 ir_build_br(irb, scope, node, true_block, is_comptime); 5699 5700 ir_set_cursor_at_end_and_append_block(irb, true_block); 5701 5702 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 5703 incoming_values[0] = val1; 5704 incoming_values[1] = val2; 5705 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 5706 incoming_blocks[0] = post_val1_block; 5707 incoming_blocks[1] = post_val2_block; 5708 5709 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); 5710 } 5711 5712 static IrInstSrc *ir_gen_bool_and(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5713 assert(node->type == NodeTypeBinOpExpr); 5714 5715 IrInstSrc *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 5716 if (val1 == irb->codegen->invalid_inst_src) 5717 return irb->codegen->invalid_inst_src; 5718 IrBasicBlockSrc *post_val1_block = irb->current_basic_block; 5719 5720 IrInstSrc *is_comptime; 5721 if (ir_should_inline(irb->exec, scope)) { 5722 is_comptime = ir_build_const_bool(irb, scope, node, true); 5723 } else { 5724 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 5725 } 5726 5727 // block for when val1 == true 5728 IrBasicBlockSrc *true_block = ir_create_basic_block(irb, scope, "BoolAndTrue"); 5729 // block for when val1 == false (don't even evaluate the second part) 5730 IrBasicBlockSrc *false_block = ir_create_basic_block(irb, scope, "BoolAndFalse"); 5731 5732 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 5733 5734 ir_set_cursor_at_end_and_append_block(irb, true_block); 5735 IrInstSrc *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 5736 if (val2 == irb->codegen->invalid_inst_src) 5737 return irb->codegen->invalid_inst_src; 5738 IrBasicBlockSrc *post_val2_block = irb->current_basic_block; 5739 5740 ir_build_br(irb, scope, node, false_block, is_comptime); 5741 5742 ir_set_cursor_at_end_and_append_block(irb, false_block); 5743 5744 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 5745 incoming_values[0] = val1; 5746 incoming_values[1] = val2; 5747 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 5748 incoming_blocks[0] = post_val1_block; 5749 incoming_blocks[1] = post_val2_block; 5750 5751 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, nullptr); 5752 } 5753 5754 static ResultLocPeerParent *ir_build_result_peers(IrBuilderSrc *irb, IrInstSrc *cond_br_inst, 5755 IrBasicBlockSrc *end_block, ResultLoc *parent, IrInstSrc *is_comptime) 5756 { 5757 ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>(); 5758 peer_parent->base.id = ResultLocIdPeerParent; 5759 peer_parent->base.source_instruction = cond_br_inst; 5760 peer_parent->base.allow_write_through_const = parent->allow_write_through_const; 5761 peer_parent->end_bb = end_block; 5762 peer_parent->is_comptime = is_comptime; 5763 peer_parent->parent = parent; 5764 5765 IrInstSrc *popped_inst = irb->current_basic_block->instruction_list.pop(); 5766 ir_assert(popped_inst == cond_br_inst, &cond_br_inst->base); 5767 5768 ir_build_reset_result(irb, cond_br_inst->base.scope, cond_br_inst->base.source_node, &peer_parent->base); 5769 irb->current_basic_block->instruction_list.append(popped_inst); 5770 5771 return peer_parent; 5772 } 5773 5774 static ResultLocPeerParent *ir_build_binary_result_peers(IrBuilderSrc *irb, IrInstSrc *cond_br_inst, 5775 IrBasicBlockSrc *else_block, IrBasicBlockSrc *end_block, ResultLoc *parent, IrInstSrc *is_comptime) 5776 { 5777 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, parent, is_comptime); 5778 5779 peer_parent->peers.append(create_peer_result(peer_parent)); 5780 peer_parent->peers.last()->next_bb = else_block; 5781 5782 peer_parent->peers.append(create_peer_result(peer_parent)); 5783 peer_parent->peers.last()->next_bb = end_block; 5784 5785 return peer_parent; 5786 } 5787 5788 static IrInstSrc *ir_gen_orelse(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval, 5789 ResultLoc *result_loc) 5790 { 5791 assert(node->type == NodeTypeBinOpExpr); 5792 5793 AstNode *op1_node = node->data.bin_op_expr.op1; 5794 AstNode *op2_node = node->data.bin_op_expr.op2; 5795 5796 IrInstSrc *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr, nullptr); 5797 if (maybe_ptr == irb->codegen->invalid_inst_src) 5798 return irb->codegen->invalid_inst_src; 5799 5800 IrInstSrc *maybe_val = ir_build_load_ptr(irb, parent_scope, node, maybe_ptr); 5801 IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, parent_scope, node, maybe_val); 5802 5803 IrInstSrc *is_comptime; 5804 if (ir_should_inline(irb->exec, parent_scope)) { 5805 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 5806 } else { 5807 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_non_null); 5808 } 5809 5810 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); 5811 IrBasicBlockSrc *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); 5812 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); 5813 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); 5814 5815 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, 5816 result_loc, is_comptime); 5817 5818 ir_set_cursor_at_end_and_append_block(irb, null_block); 5819 IrInstSrc *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, LValNone, 5820 &peer_parent->peers.at(0)->base); 5821 if (null_result == irb->codegen->invalid_inst_src) 5822 return irb->codegen->invalid_inst_src; 5823 IrBasicBlockSrc *after_null_block = irb->current_basic_block; 5824 if (!instr_is_unreachable(null_result)) 5825 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 5826 5827 ir_set_cursor_at_end_and_append_block(irb, ok_block); 5828 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false); 5829 IrInstSrc *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 5830 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); 5831 IrBasicBlockSrc *after_ok_block = irb->current_basic_block; 5832 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 5833 5834 ir_set_cursor_at_end_and_append_block(irb, end_block); 5835 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 5836 incoming_values[0] = null_result; 5837 incoming_values[1] = unwrapped_payload; 5838 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 5839 incoming_blocks[0] = after_null_block; 5840 incoming_blocks[1] = after_ok_block; 5841 IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); 5842 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 5843 } 5844 5845 static IrInstSrc *ir_gen_error_union(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 5846 assert(node->type == NodeTypeBinOpExpr); 5847 5848 AstNode *op1_node = node->data.bin_op_expr.op1; 5849 AstNode *op2_node = node->data.bin_op_expr.op2; 5850 5851 IrInstSrc *err_set = ir_gen_node(irb, op1_node, parent_scope); 5852 if (err_set == irb->codegen->invalid_inst_src) 5853 return irb->codegen->invalid_inst_src; 5854 5855 IrInstSrc *payload = ir_gen_node(irb, op2_node, parent_scope); 5856 if (payload == irb->codegen->invalid_inst_src) 5857 return irb->codegen->invalid_inst_src; 5858 5859 return ir_build_error_union(irb, parent_scope, node, err_set, payload); 5860 } 5861 5862 static IrInstSrc *ir_gen_bin_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 5863 assert(node->type == NodeTypeBinOpExpr); 5864 5865 BinOpType bin_op_type = node->data.bin_op_expr.bin_op; 5866 switch (bin_op_type) { 5867 case BinOpTypeInvalid: 5868 zig_unreachable(); 5869 case BinOpTypeAssign: 5870 return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc); 5871 case BinOpTypeAssignTimes: 5872 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMult), lval, result_loc); 5873 case BinOpTypeAssignTimesWrap: 5874 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap), lval, result_loc); 5875 case BinOpTypeAssignDiv: 5876 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); 5877 case BinOpTypeAssignMod: 5878 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); 5879 case BinOpTypeAssignPlus: 5880 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAdd), lval, result_loc); 5881 case BinOpTypeAssignPlusWrap: 5882 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap), lval, result_loc); 5883 case BinOpTypeAssignMinus: 5884 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSub), lval, result_loc); 5885 case BinOpTypeAssignMinusWrap: 5886 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap), lval, result_loc); 5887 case BinOpTypeAssignBitShiftLeft: 5888 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); 5889 case BinOpTypeAssignBitShiftRight: 5890 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); 5891 case BinOpTypeAssignBitAnd: 5892 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd), lval, result_loc); 5893 case BinOpTypeAssignBitXor: 5894 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinXor), lval, result_loc); 5895 case BinOpTypeAssignBitOr: 5896 return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinOr), lval, result_loc); 5897 case BinOpTypeAssignMergeErrorSets: 5898 return ir_lval_wrap(irb, scope, ir_gen_assign_merge_err_sets(irb, scope, node), lval, result_loc); 5899 case BinOpTypeBoolOr: 5900 return ir_lval_wrap(irb, scope, ir_gen_bool_or(irb, scope, node), lval, result_loc); 5901 case BinOpTypeBoolAnd: 5902 return ir_lval_wrap(irb, scope, ir_gen_bool_and(irb, scope, node), lval, result_loc); 5903 case BinOpTypeCmpEq: 5904 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq), lval, result_loc); 5905 case BinOpTypeCmpNotEq: 5906 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq), lval, result_loc); 5907 case BinOpTypeCmpLessThan: 5908 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan), lval, result_loc); 5909 case BinOpTypeCmpGreaterThan: 5910 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan), lval, result_loc); 5911 case BinOpTypeCmpLessOrEq: 5912 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq), lval, result_loc); 5913 case BinOpTypeCmpGreaterOrEq: 5914 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc); 5915 case BinOpTypeBinOr: 5916 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr), lval, result_loc); 5917 case BinOpTypeBinXor: 5918 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor), lval, result_loc); 5919 case BinOpTypeBinAnd: 5920 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd), lval, result_loc); 5921 case BinOpTypeBitShiftLeft: 5922 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); 5923 case BinOpTypeBitShiftRight: 5924 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); 5925 case BinOpTypeAdd: 5926 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd), lval, result_loc); 5927 case BinOpTypeAddWrap: 5928 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap), lval, result_loc); 5929 case BinOpTypeSub: 5930 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSub), lval, result_loc); 5931 case BinOpTypeSubWrap: 5932 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap), lval, result_loc); 5933 case BinOpTypeMult: 5934 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMult), lval, result_loc); 5935 case BinOpTypeMultWrap: 5936 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap), lval, result_loc); 5937 case BinOpTypeDiv: 5938 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); 5939 case BinOpTypeMod: 5940 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); 5941 case BinOpTypeArrayCat: 5942 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat), lval, result_loc); 5943 case BinOpTypeArrayMult: 5944 return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult), lval, result_loc); 5945 case BinOpTypeMergeErrorSets: 5946 return ir_lval_wrap(irb, scope, ir_gen_merge_err_sets(irb, scope, node), lval, result_loc); 5947 case BinOpTypeUnwrapOptional: 5948 return ir_gen_orelse(irb, scope, node, lval, result_loc); 5949 case BinOpTypeErrorUnion: 5950 return ir_lval_wrap(irb, scope, ir_gen_error_union(irb, scope, node), lval, result_loc); 5951 } 5952 zig_unreachable(); 5953 } 5954 5955 static IrInstSrc *ir_gen_int_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5956 assert(node->type == NodeTypeIntLiteral); 5957 5958 return ir_build_const_bigint(irb, scope, node, node->data.int_literal.bigint); 5959 } 5960 5961 static IrInstSrc *ir_gen_float_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5962 assert(node->type == NodeTypeFloatLiteral); 5963 5964 if (node->data.float_literal.overflow) { 5965 add_node_error(irb->codegen, node, buf_sprintf("float literal out of range of any type")); 5966 return irb->codegen->invalid_inst_src; 5967 } 5968 5969 return ir_build_const_bigfloat(irb, scope, node, node->data.float_literal.bigfloat); 5970 } 5971 5972 static IrInstSrc *ir_gen_char_lit(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5973 assert(node->type == NodeTypeCharLiteral); 5974 5975 return ir_build_const_uint(irb, scope, node, node->data.char_literal.value); 5976 } 5977 5978 static IrInstSrc *ir_gen_null_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 5979 assert(node->type == NodeTypeNullLiteral); 5980 5981 return ir_build_const_null(irb, scope, node); 5982 } 5983 5984 static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode *node, Buf *var_name) { 5985 ScopeDecls *scope_decls = nullptr; 5986 while (scope != nullptr) { 5987 if (scope->id == ScopeIdDecls) { 5988 scope_decls = reinterpret_cast<ScopeDecls *>(scope); 5989 } 5990 scope = scope->parent; 5991 } 5992 TldVar *tld_var = heap::c_allocator.create<TldVar>(); 5993 init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); 5994 tld_var->base.resolution = TldResolutionInvalid; 5995 tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, 5996 g->invalid_inst_gen->value, &tld_var->base, g->builtin_types.entry_invalid); 5997 scope_decls->decl_table.put(var_name, &tld_var->base); 5998 } 5999 6000 static IrInstSrc *ir_gen_symbol(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 6001 Error err; 6002 assert(node->type == NodeTypeSymbol); 6003 6004 Buf *variable_name = node->data.symbol_expr.symbol; 6005 6006 if (buf_eql_str(variable_name, "_")) { 6007 if (lval == LValAssign) { 6008 IrInstSrcConst *const_instruction = ir_build_instruction<IrInstSrcConst>(irb, scope, node); 6009 const_instruction->value = irb->codegen->pass1_arena->create<ZigValue>(); 6010 const_instruction->value->type = get_pointer_to_type(irb->codegen, 6011 irb->codegen->builtin_types.entry_void, false); 6012 const_instruction->value->special = ConstValSpecialStatic; 6013 const_instruction->value->data.x_ptr.special = ConstPtrSpecialDiscard; 6014 return &const_instruction->base; 6015 } else { 6016 add_node_error(irb->codegen, node, buf_sprintf("`_` may only be used to assign things to")); 6017 return irb->codegen->invalid_inst_src; 6018 } 6019 } 6020 6021 ZigType *primitive_type; 6022 if ((err = get_primitive_type(irb->codegen, variable_name, &primitive_type))) { 6023 if (err == ErrorOverflow) { 6024 add_node_error(irb->codegen, node, 6025 buf_sprintf("primitive integer type '%s' exceeds maximum bit width of 65535", 6026 buf_ptr(variable_name))); 6027 return irb->codegen->invalid_inst_src; 6028 } 6029 assert(err == ErrorPrimitiveTypeNotFound); 6030 } else { 6031 IrInstSrc *value = ir_build_const_type(irb, scope, node, primitive_type); 6032 if (lval == LValPtr || lval == LValAssign) { 6033 return ir_build_ref_src(irb, scope, node, value); 6034 } else { 6035 return ir_expr_wrap(irb, scope, value, result_loc); 6036 } 6037 } 6038 6039 ScopeFnDef *crossed_fndef_scope; 6040 ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope); 6041 if (var) { 6042 IrInstSrc *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); 6043 if (lval == LValPtr || lval == LValAssign) { 6044 return var_ptr; 6045 } else { 6046 return ir_expr_wrap(irb, scope, ir_build_load_ptr(irb, scope, node, var_ptr), result_loc); 6047 } 6048 } 6049 6050 Tld *tld = find_decl(irb->codegen, scope, variable_name); 6051 if (tld) { 6052 IrInstSrc *decl_ref = ir_build_decl_ref(irb, scope, node, tld, lval); 6053 if (lval == LValPtr || lval == LValAssign) { 6054 return decl_ref; 6055 } else { 6056 return ir_expr_wrap(irb, scope, decl_ref, result_loc); 6057 } 6058 } 6059 6060 if (get_container_scope(node->owner)->any_imports_failed) { 6061 // skip the error message since we had a failing import in this file 6062 // if an import breaks we don't need redundant undeclared identifier errors 6063 return irb->codegen->invalid_inst_src; 6064 } 6065 6066 return ir_build_undeclared_identifier(irb, scope, node, variable_name); 6067 } 6068 6069 static IrInstSrc *ir_gen_array_access(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 6070 ResultLoc *result_loc) 6071 { 6072 assert(node->type == NodeTypeArrayAccessExpr); 6073 6074 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; 6075 IrInstSrc *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr, nullptr); 6076 if (array_ref_instruction == irb->codegen->invalid_inst_src) 6077 return array_ref_instruction; 6078 6079 // Create an usize-typed result location to hold the subscript value, this 6080 // makes it possible for the compiler to infer the subscript expression type 6081 // if needed 6082 IrInstSrc *usize_type_inst = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 6083 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, usize_type_inst, no_result_loc()); 6084 6085 AstNode *subscript_node = node->data.array_access_expr.subscript; 6086 IrInstSrc *subscript_value = ir_gen_node_extra(irb, subscript_node, scope, LValNone, &result_loc_cast->base); 6087 if (subscript_value == irb->codegen->invalid_inst_src) 6088 return irb->codegen->invalid_inst_src; 6089 6090 IrInstSrc *subscript_instruction = ir_build_implicit_cast(irb, scope, subscript_node, subscript_value, result_loc_cast); 6091 6092 IrInstSrc *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, 6093 subscript_instruction, true, PtrLenSingle, nullptr); 6094 if (lval == LValPtr || lval == LValAssign) 6095 return ptr_instruction; 6096 6097 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 6098 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 6099 } 6100 6101 static IrInstSrc *ir_gen_field_access(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 6102 assert(node->type == NodeTypeFieldAccessExpr); 6103 6104 AstNode *container_ref_node = node->data.field_access_expr.struct_expr; 6105 Buf *field_name = node->data.field_access_expr.field_name; 6106 6107 IrInstSrc *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr, nullptr); 6108 if (container_ref_instruction == irb->codegen->invalid_inst_src) 6109 return container_ref_instruction; 6110 6111 return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name, false); 6112 } 6113 6114 static IrInstSrc *ir_gen_overflow_op(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrOverflowOp op) { 6115 assert(node->type == NodeTypeFnCallExpr); 6116 6117 AstNode *type_node = node->data.fn_call_expr.params.at(0); 6118 AstNode *op1_node = node->data.fn_call_expr.params.at(1); 6119 AstNode *op2_node = node->data.fn_call_expr.params.at(2); 6120 AstNode *result_ptr_node = node->data.fn_call_expr.params.at(3); 6121 6122 6123 IrInstSrc *type_value = ir_gen_node(irb, type_node, scope); 6124 if (type_value == irb->codegen->invalid_inst_src) 6125 return irb->codegen->invalid_inst_src; 6126 6127 IrInstSrc *op1 = ir_gen_node(irb, op1_node, scope); 6128 if (op1 == irb->codegen->invalid_inst_src) 6129 return irb->codegen->invalid_inst_src; 6130 6131 IrInstSrc *op2 = ir_gen_node(irb, op2_node, scope); 6132 if (op2 == irb->codegen->invalid_inst_src) 6133 return irb->codegen->invalid_inst_src; 6134 6135 IrInstSrc *result_ptr = ir_gen_node(irb, result_ptr_node, scope); 6136 if (result_ptr == irb->codegen->invalid_inst_src) 6137 return irb->codegen->invalid_inst_src; 6138 6139 return ir_build_overflow_op_src(irb, scope, node, op, type_value, op1, op2, result_ptr); 6140 } 6141 6142 static IrInstSrc *ir_gen_mul_add(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 6143 assert(node->type == NodeTypeFnCallExpr); 6144 6145 AstNode *type_node = node->data.fn_call_expr.params.at(0); 6146 AstNode *op1_node = node->data.fn_call_expr.params.at(1); 6147 AstNode *op2_node = node->data.fn_call_expr.params.at(2); 6148 AstNode *op3_node = node->data.fn_call_expr.params.at(3); 6149 6150 IrInstSrc *type_value = ir_gen_node(irb, type_node, scope); 6151 if (type_value == irb->codegen->invalid_inst_src) 6152 return irb->codegen->invalid_inst_src; 6153 6154 IrInstSrc *op1 = ir_gen_node(irb, op1_node, scope); 6155 if (op1 == irb->codegen->invalid_inst_src) 6156 return irb->codegen->invalid_inst_src; 6157 6158 IrInstSrc *op2 = ir_gen_node(irb, op2_node, scope); 6159 if (op2 == irb->codegen->invalid_inst_src) 6160 return irb->codegen->invalid_inst_src; 6161 6162 IrInstSrc *op3 = ir_gen_node(irb, op3_node, scope); 6163 if (op3 == irb->codegen->invalid_inst_src) 6164 return irb->codegen->invalid_inst_src; 6165 6166 return ir_build_mul_add_src(irb, scope, node, type_value, op1, op2, op3); 6167 } 6168 6169 static IrInstSrc *ir_gen_this(IrBuilderSrc *irb, Scope *orig_scope, AstNode *node) { 6170 for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) { 6171 if (it_scope->id == ScopeIdDecls) { 6172 ScopeDecls *decls_scope = (ScopeDecls *)it_scope; 6173 ZigType *container_type = decls_scope->container_type; 6174 if (container_type != nullptr) { 6175 return ir_build_const_type(irb, orig_scope, node, container_type); 6176 } else { 6177 return ir_build_const_import(irb, orig_scope, node, decls_scope->import); 6178 } 6179 } 6180 } 6181 zig_unreachable(); 6182 } 6183 6184 static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *await_node, AstNode *call_node, 6185 LVal lval, ResultLoc *result_loc) 6186 { 6187 size_t arg_offset = 3; 6188 if (call_node->data.fn_call_expr.params.length < arg_offset) { 6189 add_node_error(irb->codegen, call_node, 6190 buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, 6191 arg_offset, call_node->data.fn_call_expr.params.length)); 6192 return irb->codegen->invalid_inst_src; 6193 } 6194 6195 AstNode *bytes_node = call_node->data.fn_call_expr.params.at(0); 6196 IrInstSrc *bytes = ir_gen_node(irb, bytes_node, scope); 6197 if (bytes == irb->codegen->invalid_inst_src) 6198 return bytes; 6199 6200 AstNode *ret_ptr_node = call_node->data.fn_call_expr.params.at(1); 6201 IrInstSrc *ret_ptr = ir_gen_node(irb, ret_ptr_node, scope); 6202 if (ret_ptr == irb->codegen->invalid_inst_src) 6203 return ret_ptr; 6204 6205 AstNode *fn_ref_node = call_node->data.fn_call_expr.params.at(2); 6206 IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 6207 if (fn_ref == irb->codegen->invalid_inst_src) 6208 return fn_ref; 6209 6210 size_t arg_count = call_node->data.fn_call_expr.params.length - arg_offset; 6211 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count); 6212 for (size_t i = 0; i < arg_count; i += 1) { 6213 AstNode *arg_node = call_node->data.fn_call_expr.params.at(i + arg_offset); 6214 IrInstSrc *arg = ir_gen_node(irb, arg_node, scope); 6215 if (arg == irb->codegen->invalid_inst_src) 6216 return arg; 6217 args[i] = arg; 6218 } 6219 6220 CallModifier modifier = (await_node == nullptr) ? CallModifierAsync : CallModifierNone; 6221 bool is_async_call_builtin = true; 6222 IrInstSrc *call = ir_build_call_src(irb, scope, call_node, nullptr, fn_ref, arg_count, args, 6223 ret_ptr, modifier, is_async_call_builtin, bytes, result_loc); 6224 return ir_lval_wrap(irb, scope, call, lval, result_loc); 6225 } 6226 6227 static IrInstSrc *ir_gen_fn_call_with_args(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 6228 AstNode *fn_ref_node, CallModifier modifier, IrInstSrc *options, 6229 AstNode **args_ptr, size_t args_len, LVal lval, ResultLoc *result_loc) 6230 { 6231 IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 6232 if (fn_ref == irb->codegen->invalid_inst_src) 6233 return fn_ref; 6234 6235 IrInstSrc *fn_type = ir_build_typeof_1(irb, scope, source_node, fn_ref); 6236 6237 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(args_len); 6238 for (size_t i = 0; i < args_len; i += 1) { 6239 AstNode *arg_node = args_ptr[i]; 6240 6241 IrInstSrc *arg_index = ir_build_const_usize(irb, scope, arg_node, i); 6242 IrInstSrc *arg_type = ir_build_arg_type(irb, scope, source_node, fn_type, arg_index, true); 6243 ResultLoc *no_result = no_result_loc(); 6244 ir_build_reset_result(irb, scope, source_node, no_result); 6245 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, arg_type, no_result); 6246 6247 IrInstSrc *arg = ir_gen_node_extra(irb, arg_node, scope, LValNone, &result_loc_cast->base); 6248 if (arg == irb->codegen->invalid_inst_src) 6249 return arg; 6250 6251 args[i] = ir_build_implicit_cast(irb, scope, arg_node, arg, result_loc_cast); 6252 } 6253 6254 IrInstSrc *fn_call; 6255 if (options != nullptr) { 6256 fn_call = ir_build_call_args(irb, scope, source_node, options, fn_ref, args, args_len, result_loc); 6257 } else { 6258 fn_call = ir_build_call_src(irb, scope, source_node, nullptr, fn_ref, args_len, args, nullptr, 6259 modifier, false, nullptr, result_loc); 6260 } 6261 return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); 6262 } 6263 6264 static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 6265 ResultLoc *result_loc) 6266 { 6267 assert(node->type == NodeTypeFnCallExpr); 6268 6269 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; 6270 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 6271 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 6272 6273 if (!entry) { 6274 add_node_error(irb->codegen, node, 6275 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name))); 6276 return irb->codegen->invalid_inst_src; 6277 } 6278 6279 BuiltinFnEntry *builtin_fn = entry->value; 6280 size_t actual_param_count = node->data.fn_call_expr.params.length; 6281 6282 if (builtin_fn->param_count != SIZE_MAX && builtin_fn->param_count != actual_param_count) { 6283 add_node_error(irb->codegen, node, 6284 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, 6285 builtin_fn->param_count, actual_param_count)); 6286 return irb->codegen->invalid_inst_src; 6287 } 6288 6289 switch (builtin_fn->id) { 6290 case BuiltinFnIdInvalid: 6291 zig_unreachable(); 6292 case BuiltinFnIdTypeof: 6293 { 6294 Scope *sub_scope = create_typeof_scope(irb->codegen, node, scope); 6295 6296 size_t arg_count = node->data.fn_call_expr.params.length; 6297 6298 IrInstSrc *type_of; 6299 6300 if (arg_count == 0) { 6301 add_node_error(irb->codegen, node, 6302 buf_sprintf("expected at least 1 argument, found 0")); 6303 return irb->codegen->invalid_inst_src; 6304 } else if (arg_count == 1) { 6305 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6306 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, sub_scope); 6307 if (arg0_value == irb->codegen->invalid_inst_src) 6308 return arg0_value; 6309 6310 type_of = ir_build_typeof_1(irb, scope, node, arg0_value); 6311 } else { 6312 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(arg_count); 6313 for (size_t i = 0; i < arg_count; i += 1) { 6314 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 6315 IrInstSrc *arg = ir_gen_node(irb, arg_node, sub_scope); 6316 if (arg == irb->codegen->invalid_inst_src) 6317 return irb->codegen->invalid_inst_src; 6318 args[i] = arg; 6319 } 6320 6321 type_of = ir_build_typeof_n(irb, scope, node, args, arg_count); 6322 } 6323 return ir_lval_wrap(irb, scope, type_of, lval, result_loc); 6324 } 6325 case BuiltinFnIdSetCold: 6326 { 6327 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6328 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6329 if (arg0_value == irb->codegen->invalid_inst_src) 6330 return arg0_value; 6331 6332 IrInstSrc *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); 6333 return ir_lval_wrap(irb, scope, set_cold, lval, result_loc); 6334 } 6335 case BuiltinFnIdSetRuntimeSafety: 6336 { 6337 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6338 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6339 if (arg0_value == irb->codegen->invalid_inst_src) 6340 return arg0_value; 6341 6342 IrInstSrc *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); 6343 return ir_lval_wrap(irb, scope, set_safety, lval, result_loc); 6344 } 6345 case BuiltinFnIdSetFloatMode: 6346 { 6347 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6348 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6349 if (arg0_value == irb->codegen->invalid_inst_src) 6350 return arg0_value; 6351 6352 IrInstSrc *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value); 6353 return ir_lval_wrap(irb, scope, set_float_mode, lval, result_loc); 6354 } 6355 case BuiltinFnIdSizeof: 6356 case BuiltinFnIdBitSizeof: 6357 { 6358 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6359 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6360 if (arg0_value == irb->codegen->invalid_inst_src) 6361 return arg0_value; 6362 6363 IrInstSrc *size_of = ir_build_size_of(irb, scope, node, arg0_value, builtin_fn->id == BuiltinFnIdBitSizeof); 6364 return ir_lval_wrap(irb, scope, size_of, lval, result_loc); 6365 } 6366 case BuiltinFnIdImport: 6367 { 6368 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6369 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6370 if (arg0_value == irb->codegen->invalid_inst_src) 6371 return arg0_value; 6372 6373 IrInstSrc *import = ir_build_import(irb, scope, node, arg0_value); 6374 return ir_lval_wrap(irb, scope, import, lval, result_loc); 6375 } 6376 case BuiltinFnIdCImport: 6377 { 6378 IrInstSrc *c_import = ir_build_c_import(irb, scope, node); 6379 return ir_lval_wrap(irb, scope, c_import, lval, result_loc); 6380 } 6381 case BuiltinFnIdCInclude: 6382 { 6383 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6384 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6385 if (arg0_value == irb->codegen->invalid_inst_src) 6386 return arg0_value; 6387 6388 if (!exec_c_import_buf(irb->exec)) { 6389 add_node_error(irb->codegen, node, buf_sprintf("C include valid only inside C import block")); 6390 return irb->codegen->invalid_inst_src; 6391 } 6392 6393 IrInstSrc *c_include = ir_build_c_include(irb, scope, node, arg0_value); 6394 return ir_lval_wrap(irb, scope, c_include, lval, result_loc); 6395 } 6396 case BuiltinFnIdCDefine: 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 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6404 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6405 if (arg1_value == irb->codegen->invalid_inst_src) 6406 return arg1_value; 6407 6408 if (!exec_c_import_buf(irb->exec)) { 6409 add_node_error(irb->codegen, node, buf_sprintf("C define valid only inside C import block")); 6410 return irb->codegen->invalid_inst_src; 6411 } 6412 6413 IrInstSrc *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); 6414 return ir_lval_wrap(irb, scope, c_define, lval, result_loc); 6415 } 6416 case BuiltinFnIdCUndef: 6417 { 6418 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6419 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6420 if (arg0_value == irb->codegen->invalid_inst_src) 6421 return arg0_value; 6422 6423 if (!exec_c_import_buf(irb->exec)) { 6424 add_node_error(irb->codegen, node, buf_sprintf("C undef valid only inside C import block")); 6425 return irb->codegen->invalid_inst_src; 6426 } 6427 6428 IrInstSrc *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); 6429 return ir_lval_wrap(irb, scope, c_undef, lval, result_loc); 6430 } 6431 case BuiltinFnIdCompileErr: 6432 { 6433 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6434 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6435 if (arg0_value == irb->codegen->invalid_inst_src) 6436 return arg0_value; 6437 6438 IrInstSrc *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); 6439 return ir_lval_wrap(irb, scope, compile_err, lval, result_loc); 6440 } 6441 case BuiltinFnIdCompileLog: 6442 { 6443 IrInstSrc **args = heap::c_allocator.allocate<IrInstSrc*>(actual_param_count); 6444 6445 for (size_t i = 0; i < actual_param_count; i += 1) { 6446 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 6447 args[i] = ir_gen_node(irb, arg_node, scope); 6448 if (args[i] == irb->codegen->invalid_inst_src) 6449 return irb->codegen->invalid_inst_src; 6450 } 6451 6452 IrInstSrc *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); 6453 return ir_lval_wrap(irb, scope, compile_log, lval, result_loc); 6454 } 6455 case BuiltinFnIdErrName: 6456 { 6457 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6458 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6459 if (arg0_value == irb->codegen->invalid_inst_src) 6460 return arg0_value; 6461 6462 IrInstSrc *err_name = ir_build_err_name(irb, scope, node, arg0_value); 6463 return ir_lval_wrap(irb, scope, err_name, lval, result_loc); 6464 } 6465 case BuiltinFnIdEmbedFile: 6466 { 6467 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6468 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6469 if (arg0_value == irb->codegen->invalid_inst_src) 6470 return arg0_value; 6471 6472 IrInstSrc *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); 6473 return ir_lval_wrap(irb, scope, embed_file, lval, result_loc); 6474 } 6475 case BuiltinFnIdCmpxchgWeak: 6476 case BuiltinFnIdCmpxchgStrong: 6477 { 6478 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6479 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6480 if (arg0_value == irb->codegen->invalid_inst_src) 6481 return arg0_value; 6482 6483 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6484 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6485 if (arg1_value == irb->codegen->invalid_inst_src) 6486 return arg1_value; 6487 6488 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 6489 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 6490 if (arg2_value == irb->codegen->invalid_inst_src) 6491 return arg2_value; 6492 6493 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 6494 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); 6495 if (arg3_value == irb->codegen->invalid_inst_src) 6496 return arg3_value; 6497 6498 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 6499 IrInstSrc *arg4_value = ir_gen_node(irb, arg4_node, scope); 6500 if (arg4_value == irb->codegen->invalid_inst_src) 6501 return arg4_value; 6502 6503 AstNode *arg5_node = node->data.fn_call_expr.params.at(5); 6504 IrInstSrc *arg5_value = ir_gen_node(irb, arg5_node, scope); 6505 if (arg5_value == irb->codegen->invalid_inst_src) 6506 return arg5_value; 6507 6508 IrInstSrc *cmpxchg = ir_build_cmpxchg_src(irb, scope, node, arg0_value, arg1_value, 6509 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak), 6510 result_loc); 6511 return ir_lval_wrap(irb, scope, cmpxchg, lval, result_loc); 6512 } 6513 case BuiltinFnIdFence: 6514 { 6515 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6516 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6517 if (arg0_value == irb->codegen->invalid_inst_src) 6518 return arg0_value; 6519 6520 IrInstSrc *fence = ir_build_fence(irb, scope, node, arg0_value); 6521 return ir_lval_wrap(irb, scope, fence, lval, result_loc); 6522 } 6523 case BuiltinFnIdDivExact: 6524 { 6525 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6526 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6527 if (arg0_value == irb->codegen->invalid_inst_src) 6528 return arg0_value; 6529 6530 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6531 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6532 if (arg1_value == irb->codegen->invalid_inst_src) 6533 return arg1_value; 6534 6535 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); 6536 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6537 } 6538 case BuiltinFnIdDivTrunc: 6539 { 6540 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6541 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6542 if (arg0_value == irb->codegen->invalid_inst_src) 6543 return arg0_value; 6544 6545 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6546 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6547 if (arg1_value == irb->codegen->invalid_inst_src) 6548 return arg1_value; 6549 6550 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); 6551 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6552 } 6553 case BuiltinFnIdDivFloor: 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 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6561 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6562 if (arg1_value == irb->codegen->invalid_inst_src) 6563 return arg1_value; 6564 6565 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); 6566 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6567 } 6568 case BuiltinFnIdRem: 6569 { 6570 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6571 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6572 if (arg0_value == irb->codegen->invalid_inst_src) 6573 return arg0_value; 6574 6575 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6576 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6577 if (arg1_value == irb->codegen->invalid_inst_src) 6578 return arg1_value; 6579 6580 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); 6581 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6582 } 6583 case BuiltinFnIdMod: 6584 { 6585 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6586 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6587 if (arg0_value == irb->codegen->invalid_inst_src) 6588 return arg0_value; 6589 6590 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6591 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6592 if (arg1_value == irb->codegen->invalid_inst_src) 6593 return arg1_value; 6594 6595 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); 6596 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 6597 } 6598 case BuiltinFnIdSqrt: 6599 case BuiltinFnIdSin: 6600 case BuiltinFnIdCos: 6601 case BuiltinFnIdExp: 6602 case BuiltinFnIdExp2: 6603 case BuiltinFnIdLog: 6604 case BuiltinFnIdLog2: 6605 case BuiltinFnIdLog10: 6606 case BuiltinFnIdFabs: 6607 case BuiltinFnIdFloor: 6608 case BuiltinFnIdCeil: 6609 case BuiltinFnIdTrunc: 6610 case BuiltinFnIdNearbyInt: 6611 case BuiltinFnIdRound: 6612 { 6613 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6614 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6615 if (arg0_value == irb->codegen->invalid_inst_src) 6616 return arg0_value; 6617 6618 IrInstSrc *inst = ir_build_float_op_src(irb, scope, node, arg0_value, builtin_fn->id); 6619 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 6620 } 6621 case BuiltinFnIdTruncate: 6622 { 6623 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6624 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6625 if (arg0_value == irb->codegen->invalid_inst_src) 6626 return arg0_value; 6627 6628 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6629 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6630 if (arg1_value == irb->codegen->invalid_inst_src) 6631 return arg1_value; 6632 6633 IrInstSrc *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); 6634 return ir_lval_wrap(irb, scope, truncate, lval, result_loc); 6635 } 6636 case BuiltinFnIdIntCast: 6637 { 6638 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6639 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6640 if (arg0_value == irb->codegen->invalid_inst_src) 6641 return arg0_value; 6642 6643 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6644 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6645 if (arg1_value == irb->codegen->invalid_inst_src) 6646 return arg1_value; 6647 6648 IrInstSrc *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); 6649 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6650 } 6651 case BuiltinFnIdFloatCast: 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 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6659 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6660 if (arg1_value == irb->codegen->invalid_inst_src) 6661 return arg1_value; 6662 6663 IrInstSrc *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); 6664 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6665 } 6666 case BuiltinFnIdErrSetCast: 6667 { 6668 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6669 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6670 if (arg0_value == irb->codegen->invalid_inst_src) 6671 return arg0_value; 6672 6673 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6674 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6675 if (arg1_value == irb->codegen->invalid_inst_src) 6676 return arg1_value; 6677 6678 IrInstSrc *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); 6679 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6680 } 6681 case BuiltinFnIdIntToFloat: 6682 { 6683 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6684 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6685 if (arg0_value == irb->codegen->invalid_inst_src) 6686 return arg0_value; 6687 6688 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6689 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6690 if (arg1_value == irb->codegen->invalid_inst_src) 6691 return arg1_value; 6692 6693 IrInstSrc *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); 6694 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6695 } 6696 case BuiltinFnIdFloatToInt: 6697 { 6698 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6699 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6700 if (arg0_value == irb->codegen->invalid_inst_src) 6701 return arg0_value; 6702 6703 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6704 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6705 if (arg1_value == irb->codegen->invalid_inst_src) 6706 return arg1_value; 6707 6708 IrInstSrc *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); 6709 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6710 } 6711 case BuiltinFnIdErrToInt: 6712 { 6713 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6714 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6715 if (arg0_value == irb->codegen->invalid_inst_src) 6716 return arg0_value; 6717 6718 IrInstSrc *result = ir_build_err_to_int_src(irb, scope, node, arg0_value); 6719 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6720 } 6721 case BuiltinFnIdIntToErr: 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 IrInstSrc *result = ir_build_int_to_err_src(irb, scope, node, arg0_value); 6729 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6730 } 6731 case BuiltinFnIdBoolToInt: 6732 { 6733 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6734 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6735 if (arg0_value == irb->codegen->invalid_inst_src) 6736 return arg0_value; 6737 6738 IrInstSrc *result = ir_build_bool_to_int(irb, scope, node, arg0_value); 6739 return ir_lval_wrap(irb, scope, result, lval, result_loc); 6740 } 6741 case BuiltinFnIdVectorType: 6742 { 6743 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6744 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6745 if (arg0_value == irb->codegen->invalid_inst_src) 6746 return arg0_value; 6747 6748 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6749 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6750 if (arg1_value == irb->codegen->invalid_inst_src) 6751 return arg1_value; 6752 6753 IrInstSrc *vector_type = ir_build_vector_type(irb, scope, node, arg0_value, arg1_value); 6754 return ir_lval_wrap(irb, scope, vector_type, lval, result_loc); 6755 } 6756 case BuiltinFnIdShuffle: 6757 { 6758 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6759 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6760 if (arg0_value == irb->codegen->invalid_inst_src) 6761 return arg0_value; 6762 6763 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6764 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6765 if (arg1_value == irb->codegen->invalid_inst_src) 6766 return arg1_value; 6767 6768 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 6769 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 6770 if (arg2_value == irb->codegen->invalid_inst_src) 6771 return arg2_value; 6772 6773 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 6774 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); 6775 if (arg3_value == irb->codegen->invalid_inst_src) 6776 return arg3_value; 6777 6778 IrInstSrc *shuffle_vector = ir_build_shuffle_vector(irb, scope, node, 6779 arg0_value, arg1_value, arg2_value, arg3_value); 6780 return ir_lval_wrap(irb, scope, shuffle_vector, lval, result_loc); 6781 } 6782 case BuiltinFnIdSplat: 6783 { 6784 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6785 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6786 if (arg0_value == irb->codegen->invalid_inst_src) 6787 return arg0_value; 6788 6789 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6790 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6791 if (arg1_value == irb->codegen->invalid_inst_src) 6792 return arg1_value; 6793 6794 IrInstSrc *splat = ir_build_splat_src(irb, scope, node, 6795 arg0_value, arg1_value); 6796 return ir_lval_wrap(irb, scope, splat, lval, result_loc); 6797 } 6798 case BuiltinFnIdMemcpy: 6799 { 6800 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6801 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6802 if (arg0_value == irb->codegen->invalid_inst_src) 6803 return arg0_value; 6804 6805 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6806 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6807 if (arg1_value == irb->codegen->invalid_inst_src) 6808 return arg1_value; 6809 6810 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 6811 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 6812 if (arg2_value == irb->codegen->invalid_inst_src) 6813 return arg2_value; 6814 6815 IrInstSrc *ir_memcpy = ir_build_memcpy_src(irb, scope, node, arg0_value, arg1_value, arg2_value); 6816 return ir_lval_wrap(irb, scope, ir_memcpy, lval, result_loc); 6817 } 6818 case BuiltinFnIdMemset: 6819 { 6820 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6821 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6822 if (arg0_value == irb->codegen->invalid_inst_src) 6823 return arg0_value; 6824 6825 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6826 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6827 if (arg1_value == irb->codegen->invalid_inst_src) 6828 return arg1_value; 6829 6830 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 6831 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 6832 if (arg2_value == irb->codegen->invalid_inst_src) 6833 return arg2_value; 6834 6835 IrInstSrc *ir_memset = ir_build_memset_src(irb, scope, node, arg0_value, arg1_value, arg2_value); 6836 return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc); 6837 } 6838 case BuiltinFnIdWasmMemorySize: 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 IrInstSrc *ir_wasm_memory_size = ir_build_wasm_memory_size_src(irb, scope, node, arg0_value); 6846 return ir_lval_wrap(irb, scope, ir_wasm_memory_size, lval, result_loc); 6847 } 6848 case BuiltinFnIdWasmMemoryGrow: 6849 { 6850 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6851 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6852 if (arg0_value == irb->codegen->invalid_inst_src) 6853 return arg0_value; 6854 6855 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6856 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6857 if (arg1_value == irb->codegen->invalid_inst_src) 6858 return arg1_value; 6859 6860 IrInstSrc *ir_wasm_memory_grow = ir_build_wasm_memory_grow_src(irb, scope, node, arg0_value, arg1_value); 6861 return ir_lval_wrap(irb, scope, ir_wasm_memory_grow, lval, result_loc); 6862 } 6863 case BuiltinFnIdField: 6864 { 6865 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6866 IrInstSrc *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr, nullptr); 6867 if (arg0_value == irb->codegen->invalid_inst_src) 6868 return arg0_value; 6869 6870 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6871 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6872 if (arg1_value == irb->codegen->invalid_inst_src) 6873 return arg1_value; 6874 6875 IrInstSrc *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, 6876 arg0_value, arg1_value, false); 6877 6878 if (lval == LValPtr || lval == LValAssign) 6879 return ptr_instruction; 6880 6881 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 6882 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 6883 } 6884 case BuiltinFnIdHasField: 6885 { 6886 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6887 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6888 if (arg0_value == irb->codegen->invalid_inst_src) 6889 return arg0_value; 6890 6891 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6892 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6893 if (arg1_value == irb->codegen->invalid_inst_src) 6894 return arg1_value; 6895 6896 IrInstSrc *type_info = ir_build_has_field(irb, scope, node, arg0_value, arg1_value); 6897 return ir_lval_wrap(irb, scope, type_info, lval, result_loc); 6898 } 6899 case BuiltinFnIdTypeInfo: 6900 { 6901 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6902 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6903 if (arg0_value == irb->codegen->invalid_inst_src) 6904 return arg0_value; 6905 6906 IrInstSrc *type_info = ir_build_type_info(irb, scope, node, arg0_value); 6907 return ir_lval_wrap(irb, scope, type_info, lval, result_loc); 6908 } 6909 case BuiltinFnIdType: 6910 { 6911 AstNode *arg_node = node->data.fn_call_expr.params.at(0); 6912 IrInstSrc *arg = ir_gen_node(irb, arg_node, scope); 6913 if (arg == irb->codegen->invalid_inst_src) 6914 return arg; 6915 6916 IrInstSrc *type = ir_build_type(irb, scope, node, arg); 6917 return ir_lval_wrap(irb, scope, type, lval, result_loc); 6918 } 6919 case BuiltinFnIdBreakpoint: 6920 return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval, result_loc); 6921 case BuiltinFnIdReturnAddress: 6922 return ir_lval_wrap(irb, scope, ir_build_return_address_src(irb, scope, node), lval, result_loc); 6923 case BuiltinFnIdFrameAddress: 6924 return ir_lval_wrap(irb, scope, ir_build_frame_address_src(irb, scope, node), lval, result_loc); 6925 case BuiltinFnIdFrameHandle: 6926 if (!irb->exec->fn_entry) { 6927 add_node_error(irb->codegen, node, buf_sprintf("@frame() called outside of function definition")); 6928 return irb->codegen->invalid_inst_src; 6929 } 6930 return ir_lval_wrap(irb, scope, ir_build_handle_src(irb, scope, node), lval, result_loc); 6931 case BuiltinFnIdFrameType: { 6932 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6933 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6934 if (arg0_value == irb->codegen->invalid_inst_src) 6935 return arg0_value; 6936 6937 IrInstSrc *frame_type = ir_build_frame_type(irb, scope, node, arg0_value); 6938 return ir_lval_wrap(irb, scope, frame_type, lval, result_loc); 6939 } 6940 case BuiltinFnIdFrameSize: { 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 *frame_size = ir_build_frame_size_src(irb, scope, node, arg0_value); 6947 return ir_lval_wrap(irb, scope, frame_size, lval, result_loc); 6948 } 6949 case BuiltinFnIdAlignOf: 6950 { 6951 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6952 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6953 if (arg0_value == irb->codegen->invalid_inst_src) 6954 return arg0_value; 6955 6956 IrInstSrc *align_of = ir_build_align_of(irb, scope, node, arg0_value); 6957 return ir_lval_wrap(irb, scope, align_of, lval, result_loc); 6958 } 6959 case BuiltinFnIdAddWithOverflow: 6960 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval, result_loc); 6961 case BuiltinFnIdSubWithOverflow: 6962 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval, result_loc); 6963 case BuiltinFnIdMulWithOverflow: 6964 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval, result_loc); 6965 case BuiltinFnIdShlWithOverflow: 6966 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval, result_loc); 6967 case BuiltinFnIdMulAdd: 6968 return ir_lval_wrap(irb, scope, ir_gen_mul_add(irb, scope, node), lval, result_loc); 6969 case BuiltinFnIdTypeName: 6970 { 6971 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 6972 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 6973 if (arg0_value == irb->codegen->invalid_inst_src) 6974 return arg0_value; 6975 6976 IrInstSrc *type_name = ir_build_type_name(irb, scope, node, arg0_value); 6977 return ir_lval_wrap(irb, scope, type_name, lval, result_loc); 6978 } 6979 case BuiltinFnIdPanic: 6980 { 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 *panic = ir_build_panic_src(irb, scope, node, arg0_value); 6987 return ir_lval_wrap(irb, scope, panic, lval, result_loc); 6988 } 6989 case BuiltinFnIdPtrCast: 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 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 6997 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 6998 if (arg1_value == irb->codegen->invalid_inst_src) 6999 return arg1_value; 7000 7001 IrInstSrc *ptr_cast = ir_build_ptr_cast_src(irb, scope, node, arg0_value, arg1_value, true); 7002 return ir_lval_wrap(irb, scope, ptr_cast, lval, result_loc); 7003 } 7004 case BuiltinFnIdBitCast: 7005 { 7006 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); 7007 IrInstSrc *dest_type = ir_gen_node(irb, dest_type_node, scope); 7008 if (dest_type == irb->codegen->invalid_inst_src) 7009 return dest_type; 7010 7011 ResultLocBitCast *result_loc_bit_cast = heap::c_allocator.create<ResultLocBitCast>(); 7012 result_loc_bit_cast->base.id = ResultLocIdBitCast; 7013 result_loc_bit_cast->base.source_instruction = dest_type; 7014 result_loc_bit_cast->base.allow_write_through_const = result_loc->allow_write_through_const; 7015 ir_ref_instruction(dest_type, irb->current_basic_block); 7016 result_loc_bit_cast->parent = result_loc; 7017 7018 ir_build_reset_result(irb, scope, node, &result_loc_bit_cast->base); 7019 7020 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7021 IrInstSrc *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, 7022 &result_loc_bit_cast->base); 7023 if (arg1_value == irb->codegen->invalid_inst_src) 7024 return arg1_value; 7025 7026 IrInstSrc *bitcast = ir_build_bit_cast_src(irb, scope, arg1_node, arg1_value, result_loc_bit_cast); 7027 return ir_lval_wrap(irb, scope, bitcast, lval, result_loc); 7028 } 7029 case BuiltinFnIdAs: 7030 { 7031 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0); 7032 IrInstSrc *dest_type = ir_gen_node(irb, dest_type_node, scope); 7033 if (dest_type == irb->codegen->invalid_inst_src) 7034 return dest_type; 7035 7036 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, dest_type, result_loc); 7037 7038 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7039 IrInstSrc *arg1_value = ir_gen_node_extra(irb, arg1_node, scope, LValNone, 7040 &result_loc_cast->base); 7041 if (arg1_value == irb->codegen->invalid_inst_src) 7042 return arg1_value; 7043 7044 IrInstSrc *result = ir_build_implicit_cast(irb, scope, node, arg1_value, result_loc_cast); 7045 return ir_lval_wrap(irb, scope, result, lval, result_loc); 7046 } 7047 case BuiltinFnIdIntToPtr: 7048 { 7049 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7050 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7051 if (arg0_value == irb->codegen->invalid_inst_src) 7052 return arg0_value; 7053 7054 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7055 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7056 if (arg1_value == irb->codegen->invalid_inst_src) 7057 return arg1_value; 7058 7059 IrInstSrc *int_to_ptr = ir_build_int_to_ptr_src(irb, scope, node, arg0_value, arg1_value); 7060 return ir_lval_wrap(irb, scope, int_to_ptr, lval, result_loc); 7061 } 7062 case BuiltinFnIdPtrToInt: 7063 { 7064 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7065 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7066 if (arg0_value == irb->codegen->invalid_inst_src) 7067 return arg0_value; 7068 7069 IrInstSrc *ptr_to_int = ir_build_ptr_to_int_src(irb, scope, node, arg0_value); 7070 return ir_lval_wrap(irb, scope, ptr_to_int, lval, result_loc); 7071 } 7072 case BuiltinFnIdTagName: 7073 { 7074 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7075 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7076 if (arg0_value == irb->codegen->invalid_inst_src) 7077 return arg0_value; 7078 7079 IrInstSrc *tag_name = ir_build_tag_name_src(irb, scope, node, arg0_value); 7080 return ir_lval_wrap(irb, scope, tag_name, lval, result_loc); 7081 } 7082 case BuiltinFnIdTagType: 7083 { 7084 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7085 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7086 if (arg0_value == irb->codegen->invalid_inst_src) 7087 return arg0_value; 7088 7089 IrInstSrc *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); 7090 return ir_lval_wrap(irb, scope, tag_type, lval, result_loc); 7091 } 7092 case BuiltinFnIdFieldParentPtr: 7093 { 7094 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7095 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7096 if (arg0_value == irb->codegen->invalid_inst_src) 7097 return arg0_value; 7098 7099 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7100 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7101 if (arg1_value == irb->codegen->invalid_inst_src) 7102 return arg1_value; 7103 7104 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 7105 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 7106 if (arg2_value == irb->codegen->invalid_inst_src) 7107 return arg2_value; 7108 7109 IrInstSrc *field_parent_ptr = ir_build_field_parent_ptr_src(irb, scope, node, 7110 arg0_value, arg1_value, arg2_value); 7111 return ir_lval_wrap(irb, scope, field_parent_ptr, lval, result_loc); 7112 } 7113 case BuiltinFnIdByteOffsetOf: 7114 { 7115 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7116 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7117 if (arg0_value == irb->codegen->invalid_inst_src) 7118 return arg0_value; 7119 7120 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7121 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7122 if (arg1_value == irb->codegen->invalid_inst_src) 7123 return arg1_value; 7124 7125 IrInstSrc *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value); 7126 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); 7127 } 7128 case BuiltinFnIdBitOffsetOf: 7129 { 7130 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7131 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7132 if (arg0_value == irb->codegen->invalid_inst_src) 7133 return arg0_value; 7134 7135 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7136 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7137 if (arg1_value == irb->codegen->invalid_inst_src) 7138 return arg1_value; 7139 7140 IrInstSrc *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); 7141 return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); 7142 } 7143 case BuiltinFnIdCall: { 7144 // Cast the options parameter to the options type 7145 ZigType *options_type = get_builtin_type(irb->codegen, "CallOptions"); 7146 IrInstSrc *options_type_inst = ir_build_const_type(irb, scope, node, options_type); 7147 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, options_type_inst, no_result_loc()); 7148 7149 AstNode *options_node = node->data.fn_call_expr.params.at(0); 7150 IrInstSrc *options_inner = ir_gen_node_extra(irb, options_node, scope, 7151 LValNone, &result_loc_cast->base); 7152 if (options_inner == irb->codegen->invalid_inst_src) 7153 return options_inner; 7154 IrInstSrc *options = ir_build_implicit_cast(irb, scope, options_node, options_inner, result_loc_cast); 7155 7156 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); 7157 AstNode *args_node = node->data.fn_call_expr.params.at(2); 7158 if (args_node->type == NodeTypeContainerInitExpr) { 7159 if (args_node->data.container_init_expr.kind == ContainerInitKindArray || 7160 args_node->data.container_init_expr.entries.length == 0) 7161 { 7162 return ir_gen_fn_call_with_args(irb, scope, node, 7163 fn_ref_node, CallModifierNone, options, 7164 args_node->data.container_init_expr.entries.items, 7165 args_node->data.container_init_expr.entries.length, 7166 lval, result_loc); 7167 } else { 7168 exec_add_error_node(irb->codegen, irb->exec, args_node, 7169 buf_sprintf("TODO: @call with anon struct literal")); 7170 return irb->codegen->invalid_inst_src; 7171 } 7172 } else { 7173 IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 7174 if (fn_ref == irb->codegen->invalid_inst_src) 7175 return fn_ref; 7176 7177 IrInstSrc *args = ir_gen_node(irb, args_node, scope); 7178 if (args == irb->codegen->invalid_inst_src) 7179 return args; 7180 7181 IrInstSrc *call = ir_build_call_extra(irb, scope, node, options, fn_ref, args, result_loc); 7182 return ir_lval_wrap(irb, scope, call, lval, result_loc); 7183 } 7184 } 7185 case BuiltinFnIdAsyncCall: 7186 return ir_gen_async_call(irb, scope, nullptr, node, lval, result_loc); 7187 case BuiltinFnIdShlExact: 7188 { 7189 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7190 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7191 if (arg0_value == irb->codegen->invalid_inst_src) 7192 return arg0_value; 7193 7194 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7195 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7196 if (arg1_value == irb->codegen->invalid_inst_src) 7197 return arg1_value; 7198 7199 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); 7200 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 7201 } 7202 case BuiltinFnIdShrExact: 7203 { 7204 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7205 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7206 if (arg0_value == irb->codegen->invalid_inst_src) 7207 return arg0_value; 7208 7209 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7210 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7211 if (arg1_value == irb->codegen->invalid_inst_src) 7212 return arg1_value; 7213 7214 IrInstSrc *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); 7215 return ir_lval_wrap(irb, scope, bin_op, lval, result_loc); 7216 } 7217 case BuiltinFnIdSetEvalBranchQuota: 7218 { 7219 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7220 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7221 if (arg0_value == irb->codegen->invalid_inst_src) 7222 return arg0_value; 7223 7224 IrInstSrc *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); 7225 return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval, result_loc); 7226 } 7227 case BuiltinFnIdAlignCast: 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 *align_cast = ir_build_align_cast_src(irb, scope, node, arg0_value, arg1_value); 7240 return ir_lval_wrap(irb, scope, align_cast, lval, result_loc); 7241 } 7242 case BuiltinFnIdOpaqueType: 7243 { 7244 IrInstSrc *opaque_type = ir_build_opaque_type(irb, scope, node); 7245 return ir_lval_wrap(irb, scope, opaque_type, lval, result_loc); 7246 } 7247 case BuiltinFnIdThis: 7248 { 7249 IrInstSrc *this_inst = ir_gen_this(irb, scope, node); 7250 return ir_lval_wrap(irb, scope, this_inst, lval, result_loc); 7251 } 7252 case BuiltinFnIdSetAlignStack: 7253 { 7254 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7255 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7256 if (arg0_value == irb->codegen->invalid_inst_src) 7257 return arg0_value; 7258 7259 IrInstSrc *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); 7260 return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc); 7261 } 7262 case BuiltinFnIdExport: 7263 { 7264 // Cast the options parameter to the options type 7265 ZigType *options_type = get_builtin_type(irb->codegen, "ExportOptions"); 7266 IrInstSrc *options_type_inst = ir_build_const_type(irb, scope, node, options_type); 7267 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(irb, options_type_inst, no_result_loc()); 7268 7269 AstNode *target_node = node->data.fn_call_expr.params.at(0); 7270 IrInstSrc *target_value = ir_gen_node(irb, target_node, scope); 7271 if (target_value == irb->codegen->invalid_inst_src) 7272 return target_value; 7273 7274 AstNode *options_node = node->data.fn_call_expr.params.at(1); 7275 IrInstSrc *options_value = ir_gen_node_extra(irb, options_node, 7276 scope, LValNone, &result_loc_cast->base); 7277 if (options_value == irb->codegen->invalid_inst_src) 7278 return options_value; 7279 7280 IrInstSrc *casted_options_value = ir_build_implicit_cast( 7281 irb, scope, options_node, options_value, result_loc_cast); 7282 7283 IrInstSrc *ir_export = ir_build_export(irb, scope, node, target_value, casted_options_value); 7284 return ir_lval_wrap(irb, scope, ir_export, lval, result_loc); 7285 } 7286 case BuiltinFnIdErrorReturnTrace: 7287 { 7288 IrInstSrc *error_return_trace = ir_build_error_return_trace_src(irb, scope, node, 7289 IrInstErrorReturnTraceNull); 7290 return ir_lval_wrap(irb, scope, error_return_trace, lval, result_loc); 7291 } 7292 case BuiltinFnIdAtomicRmw: 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 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7300 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7301 if (arg1_value == irb->codegen->invalid_inst_src) 7302 return arg1_value; 7303 7304 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 7305 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 7306 if (arg2_value == irb->codegen->invalid_inst_src) 7307 return arg2_value; 7308 7309 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 7310 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); 7311 if (arg3_value == irb->codegen->invalid_inst_src) 7312 return arg3_value; 7313 7314 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 7315 IrInstSrc *arg4_value = ir_gen_node(irb, arg4_node, scope); 7316 if (arg4_value == irb->codegen->invalid_inst_src) 7317 return arg4_value; 7318 7319 IrInstSrc *inst = ir_build_atomic_rmw_src(irb, scope, node, 7320 arg0_value, arg1_value, arg2_value, arg3_value, arg4_value); 7321 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 7322 } 7323 case BuiltinFnIdAtomicLoad: 7324 { 7325 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7326 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7327 if (arg0_value == irb->codegen->invalid_inst_src) 7328 return arg0_value; 7329 7330 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7331 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7332 if (arg1_value == irb->codegen->invalid_inst_src) 7333 return arg1_value; 7334 7335 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 7336 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 7337 if (arg2_value == irb->codegen->invalid_inst_src) 7338 return arg2_value; 7339 7340 IrInstSrc *inst = ir_build_atomic_load_src(irb, scope, node, arg0_value, arg1_value, arg2_value); 7341 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 7342 } 7343 case BuiltinFnIdAtomicStore: 7344 { 7345 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7346 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7347 if (arg0_value == irb->codegen->invalid_inst_src) 7348 return arg0_value; 7349 7350 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7351 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7352 if (arg1_value == irb->codegen->invalid_inst_src) 7353 return arg1_value; 7354 7355 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 7356 IrInstSrc *arg2_value = ir_gen_node(irb, arg2_node, scope); 7357 if (arg2_value == irb->codegen->invalid_inst_src) 7358 return arg2_value; 7359 7360 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 7361 IrInstSrc *arg3_value = ir_gen_node(irb, arg3_node, scope); 7362 if (arg3_value == irb->codegen->invalid_inst_src) 7363 return arg3_value; 7364 7365 IrInstSrc *inst = ir_build_atomic_store_src(irb, scope, node, arg0_value, arg1_value, 7366 arg2_value, arg3_value); 7367 return ir_lval_wrap(irb, scope, inst, lval, result_loc); 7368 } 7369 case BuiltinFnIdIntToEnum: 7370 { 7371 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7372 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7373 if (arg0_value == irb->codegen->invalid_inst_src) 7374 return arg0_value; 7375 7376 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7377 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7378 if (arg1_value == irb->codegen->invalid_inst_src) 7379 return arg1_value; 7380 7381 IrInstSrc *result = ir_build_int_to_enum_src(irb, scope, node, arg0_value, arg1_value); 7382 return ir_lval_wrap(irb, scope, result, lval, result_loc); 7383 } 7384 case BuiltinFnIdEnumToInt: 7385 { 7386 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7387 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7388 if (arg0_value == irb->codegen->invalid_inst_src) 7389 return arg0_value; 7390 7391 IrInstSrc *result = ir_build_enum_to_int(irb, scope, node, arg0_value); 7392 return ir_lval_wrap(irb, scope, result, lval, result_loc); 7393 } 7394 case BuiltinFnIdCtz: 7395 case BuiltinFnIdPopCount: 7396 case BuiltinFnIdClz: 7397 case BuiltinFnIdBswap: 7398 case BuiltinFnIdBitReverse: 7399 { 7400 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7401 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7402 if (arg0_value == irb->codegen->invalid_inst_src) 7403 return arg0_value; 7404 7405 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7406 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7407 if (arg1_value == irb->codegen->invalid_inst_src) 7408 return arg1_value; 7409 7410 IrInstSrc *result; 7411 switch (builtin_fn->id) { 7412 case BuiltinFnIdCtz: 7413 result = ir_build_ctz(irb, scope, node, arg0_value, arg1_value); 7414 break; 7415 case BuiltinFnIdPopCount: 7416 result = ir_build_pop_count(irb, scope, node, arg0_value, arg1_value); 7417 break; 7418 case BuiltinFnIdClz: 7419 result = ir_build_clz(irb, scope, node, arg0_value, arg1_value); 7420 break; 7421 case BuiltinFnIdBswap: 7422 result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value); 7423 break; 7424 case BuiltinFnIdBitReverse: 7425 result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value); 7426 break; 7427 default: 7428 zig_unreachable(); 7429 } 7430 return ir_lval_wrap(irb, scope, result, lval, result_loc); 7431 } 7432 case BuiltinFnIdHasDecl: 7433 { 7434 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 7435 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope); 7436 if (arg0_value == irb->codegen->invalid_inst_src) 7437 return arg0_value; 7438 7439 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 7440 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope); 7441 if (arg1_value == irb->codegen->invalid_inst_src) 7442 return arg1_value; 7443 7444 IrInstSrc *has_decl = ir_build_has_decl(irb, scope, node, arg0_value, arg1_value); 7445 return ir_lval_wrap(irb, scope, has_decl, lval, result_loc); 7446 } 7447 case BuiltinFnIdUnionInit: 7448 { 7449 AstNode *union_type_node = node->data.fn_call_expr.params.at(0); 7450 IrInstSrc *union_type_inst = ir_gen_node(irb, union_type_node, scope); 7451 if (union_type_inst == irb->codegen->invalid_inst_src) 7452 return union_type_inst; 7453 7454 AstNode *name_node = node->data.fn_call_expr.params.at(1); 7455 IrInstSrc *name_inst = ir_gen_node(irb, name_node, scope); 7456 if (name_inst == irb->codegen->invalid_inst_src) 7457 return name_inst; 7458 7459 AstNode *init_node = node->data.fn_call_expr.params.at(2); 7460 7461 return ir_gen_union_init_expr(irb, scope, node, union_type_inst, name_inst, init_node, 7462 lval, result_loc); 7463 } 7464 case BuiltinFnIdSrc: 7465 { 7466 IrInstSrc *src_inst = ir_build_src(irb, scope, node); 7467 return ir_lval_wrap(irb, scope, src_inst, lval, result_loc); 7468 } 7469 } 7470 zig_unreachable(); 7471 } 7472 7473 static ScopeNoSuspend *get_scope_nosuspend(Scope *scope) { 7474 while (scope) { 7475 if (scope->id == ScopeIdNoSuspend) 7476 return (ScopeNoSuspend *)scope; 7477 if (scope->id == ScopeIdFnDef) 7478 return nullptr; 7479 7480 scope = scope->parent; 7481 } 7482 return nullptr; 7483 } 7484 7485 static IrInstSrc *ir_gen_fn_call(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 7486 ResultLoc *result_loc) 7487 { 7488 assert(node->type == NodeTypeFnCallExpr); 7489 7490 if (node->data.fn_call_expr.modifier == CallModifierBuiltin) 7491 return ir_gen_builtin_fn_call(irb, scope, node, lval, result_loc); 7492 7493 bool is_nosuspend = get_scope_nosuspend(scope) != nullptr; 7494 CallModifier modifier = node->data.fn_call_expr.modifier; 7495 if (is_nosuspend) { 7496 if (modifier == CallModifierAsync) { 7497 add_node_error(irb->codegen, node, 7498 buf_sprintf("async call in nosuspend scope")); 7499 return irb->codegen->invalid_inst_src; 7500 } 7501 modifier = CallModifierNoSuspend; 7502 } 7503 7504 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; 7505 return ir_gen_fn_call_with_args(irb, scope, node, fn_ref_node, modifier, 7506 nullptr, node->data.fn_call_expr.params.items, node->data.fn_call_expr.params.length, lval, result_loc); 7507 } 7508 7509 static IrInstSrc *ir_gen_if_bool_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 7510 ResultLoc *result_loc) 7511 { 7512 assert(node->type == NodeTypeIfBoolExpr); 7513 7514 IrInstSrc *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); 7515 if (condition == irb->codegen->invalid_inst_src) 7516 return irb->codegen->invalid_inst_src; 7517 7518 IrInstSrc *is_comptime; 7519 if (ir_should_inline(irb->exec, scope)) { 7520 is_comptime = ir_build_const_bool(irb, scope, node, true); 7521 } else { 7522 is_comptime = ir_build_test_comptime(irb, scope, node, condition); 7523 } 7524 7525 AstNode *then_node = node->data.if_bool_expr.then_block; 7526 AstNode *else_node = node->data.if_bool_expr.else_node; 7527 7528 IrBasicBlockSrc *then_block = ir_create_basic_block(irb, scope, "Then"); 7529 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "Else"); 7530 IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "EndIf"); 7531 7532 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, condition, 7533 then_block, else_block, is_comptime); 7534 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 7535 result_loc, is_comptime); 7536 7537 ir_set_cursor_at_end_and_append_block(irb, then_block); 7538 7539 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 7540 IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, subexpr_scope, lval, 7541 &peer_parent->peers.at(0)->base); 7542 if (then_expr_result == irb->codegen->invalid_inst_src) 7543 return irb->codegen->invalid_inst_src; 7544 IrBasicBlockSrc *after_then_block = irb->current_basic_block; 7545 if (!instr_is_unreachable(then_expr_result)) 7546 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 7547 7548 ir_set_cursor_at_end_and_append_block(irb, else_block); 7549 IrInstSrc *else_expr_result; 7550 if (else_node) { 7551 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); 7552 if (else_expr_result == irb->codegen->invalid_inst_src) 7553 return irb->codegen->invalid_inst_src; 7554 } else { 7555 else_expr_result = ir_build_const_void(irb, scope, node); 7556 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 7557 } 7558 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 7559 if (!instr_is_unreachable(else_expr_result)) 7560 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 7561 7562 ir_set_cursor_at_end_and_append_block(irb, endif_block); 7563 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 7564 incoming_values[0] = then_expr_result; 7565 incoming_values[1] = else_expr_result; 7566 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 7567 incoming_blocks[0] = after_then_block; 7568 incoming_blocks[1] = after_else_block; 7569 7570 IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 7571 return ir_expr_wrap(irb, scope, phi, result_loc); 7572 } 7573 7574 static IrInstSrc *ir_gen_prefix_op_id_lval(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { 7575 assert(node->type == NodeTypePrefixOpExpr); 7576 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 7577 7578 IrInstSrc *value = ir_gen_node_extra(irb, expr_node, scope, lval, nullptr); 7579 if (value == irb->codegen->invalid_inst_src) 7580 return value; 7581 7582 return ir_build_un_op(irb, scope, node, op_id, value); 7583 } 7584 7585 static IrInstSrc *ir_gen_prefix_op_id(IrBuilderSrc *irb, Scope *scope, AstNode *node, IrUnOp op_id) { 7586 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone); 7587 } 7588 7589 static IrInstSrc *ir_expr_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *inst, ResultLoc *result_loc) { 7590 if (inst == irb->codegen->invalid_inst_src) return inst; 7591 ir_build_end_expr(irb, scope, inst->base.source_node, inst, result_loc); 7592 return inst; 7593 } 7594 7595 static IrInstSrc *ir_lval_wrap(IrBuilderSrc *irb, Scope *scope, IrInstSrc *value, LVal lval, 7596 ResultLoc *result_loc) 7597 { 7598 // This logic must be kept in sync with 7599 // [STMT_EXPR_TEST_THING] <--- (search this token) 7600 if (value == irb->codegen->invalid_inst_src || 7601 instr_is_unreachable(value) || 7602 value->base.source_node->type == NodeTypeDefer || 7603 value->id == IrInstSrcIdDeclVar) 7604 { 7605 return value; 7606 } 7607 7608 assert(lval != LValAssign); 7609 if (lval == LValPtr) { 7610 // We needed a pointer to a value, but we got a value. So we create 7611 // an instruction which just makes a pointer of it. 7612 return ir_build_ref_src(irb, scope, value->base.source_node, value); 7613 } else if (result_loc != nullptr) { 7614 return ir_expr_wrap(irb, scope, value, result_loc); 7615 } else { 7616 return value; 7617 } 7618 7619 } 7620 7621 static PtrLen star_token_to_ptr_len(TokenId token_id) { 7622 switch (token_id) { 7623 case TokenIdStar: 7624 case TokenIdStarStar: 7625 return PtrLenSingle; 7626 case TokenIdLBracket: 7627 return PtrLenUnknown; 7628 case TokenIdSymbol: 7629 return PtrLenC; 7630 default: 7631 zig_unreachable(); 7632 } 7633 } 7634 7635 static IrInstSrc *ir_gen_pointer_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 7636 assert(node->type == NodeTypePointerType); 7637 7638 PtrLen ptr_len = star_token_to_ptr_len(node->data.pointer_type.star_token->id); 7639 7640 bool is_const = node->data.pointer_type.is_const; 7641 bool is_volatile = node->data.pointer_type.is_volatile; 7642 bool is_allow_zero = node->data.pointer_type.allow_zero_token != nullptr; 7643 AstNode *sentinel_expr = node->data.pointer_type.sentinel; 7644 AstNode *expr_node = node->data.pointer_type.op_expr; 7645 AstNode *align_expr = node->data.pointer_type.align_expr; 7646 7647 IrInstSrc *sentinel; 7648 if (sentinel_expr != nullptr) { 7649 sentinel = ir_gen_node(irb, sentinel_expr, scope); 7650 if (sentinel == irb->codegen->invalid_inst_src) 7651 return sentinel; 7652 } else { 7653 sentinel = nullptr; 7654 } 7655 7656 IrInstSrc *align_value; 7657 if (align_expr != nullptr) { 7658 align_value = ir_gen_node(irb, align_expr, scope); 7659 if (align_value == irb->codegen->invalid_inst_src) 7660 return align_value; 7661 } else { 7662 align_value = nullptr; 7663 } 7664 7665 IrInstSrc *child_type = ir_gen_node(irb, expr_node, scope); 7666 if (child_type == irb->codegen->invalid_inst_src) 7667 return child_type; 7668 7669 uint32_t bit_offset_start = 0; 7670 if (node->data.pointer_type.bit_offset_start != nullptr) { 7671 if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_start, 32, false)) { 7672 Buf *val_buf = buf_alloc(); 7673 bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_start, 10); 7674 exec_add_error_node(irb->codegen, irb->exec, node, 7675 buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf))); 7676 return irb->codegen->invalid_inst_src; 7677 } 7678 bit_offset_start = bigint_as_u32(node->data.pointer_type.bit_offset_start); 7679 } 7680 7681 uint32_t host_int_bytes = 0; 7682 if (node->data.pointer_type.host_int_bytes != nullptr) { 7683 if (!bigint_fits_in_bits(node->data.pointer_type.host_int_bytes, 32, false)) { 7684 Buf *val_buf = buf_alloc(); 7685 bigint_append_buf(val_buf, node->data.pointer_type.host_int_bytes, 10); 7686 exec_add_error_node(irb->codegen, irb->exec, node, 7687 buf_sprintf("value %s too large for u32 byte count", buf_ptr(val_buf))); 7688 return irb->codegen->invalid_inst_src; 7689 } 7690 host_int_bytes = bigint_as_u32(node->data.pointer_type.host_int_bytes); 7691 } 7692 7693 if (host_int_bytes != 0 && bit_offset_start >= host_int_bytes * 8) { 7694 exec_add_error_node(irb->codegen, irb->exec, node, 7695 buf_sprintf("bit offset starts after end of host integer")); 7696 return irb->codegen->invalid_inst_src; 7697 } 7698 7699 return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile, 7700 ptr_len, sentinel, align_value, bit_offset_start, host_int_bytes, is_allow_zero); 7701 } 7702 7703 static IrInstSrc *ir_gen_catch_unreachable(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 7704 AstNode *expr_node, LVal lval, ResultLoc *result_loc) 7705 { 7706 IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 7707 if (err_union_ptr == irb->codegen->invalid_inst_src) 7708 return irb->codegen->invalid_inst_src; 7709 7710 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, scope, source_node, err_union_ptr, true, false); 7711 if (payload_ptr == irb->codegen->invalid_inst_src) 7712 return irb->codegen->invalid_inst_src; 7713 7714 if (lval == LValPtr) 7715 return payload_ptr; 7716 7717 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, source_node, payload_ptr); 7718 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 7719 } 7720 7721 static IrInstSrc *ir_gen_bool_not(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 7722 assert(node->type == NodeTypePrefixOpExpr); 7723 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 7724 7725 IrInstSrc *value = ir_gen_node(irb, expr_node, scope); 7726 if (value == irb->codegen->invalid_inst_src) 7727 return irb->codegen->invalid_inst_src; 7728 7729 return ir_build_bool_not(irb, scope, node, value); 7730 } 7731 7732 static IrInstSrc *ir_gen_prefix_op_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 7733 ResultLoc *result_loc) 7734 { 7735 assert(node->type == NodeTypePrefixOpExpr); 7736 7737 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; 7738 7739 switch (prefix_op) { 7740 case PrefixOpInvalid: 7741 zig_unreachable(); 7742 case PrefixOpBoolNot: 7743 return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval, result_loc); 7744 case PrefixOpBinNot: 7745 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval, result_loc); 7746 case PrefixOpNegation: 7747 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval, result_loc); 7748 case PrefixOpNegationWrap: 7749 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval, result_loc); 7750 case PrefixOpOptional: 7751 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval, result_loc); 7752 case PrefixOpAddrOf: { 7753 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 7754 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr), lval, result_loc); 7755 } 7756 } 7757 zig_unreachable(); 7758 } 7759 7760 static IrInstSrc *ir_gen_union_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, 7761 IrInstSrc *union_type, IrInstSrc *field_name, AstNode *expr_node, 7762 LVal lval, ResultLoc *parent_result_loc) 7763 { 7764 IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, source_node, parent_result_loc, union_type); 7765 IrInstSrc *field_ptr = ir_build_field_ptr_instruction(irb, scope, source_node, container_ptr, 7766 field_name, true); 7767 7768 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>(); 7769 result_loc_inst->base.id = ResultLocIdInstruction; 7770 result_loc_inst->base.source_instruction = field_ptr; 7771 ir_ref_instruction(field_ptr, irb->current_basic_block); 7772 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 7773 7774 IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 7775 &result_loc_inst->base); 7776 if (expr_value == irb->codegen->invalid_inst_src) 7777 return expr_value; 7778 7779 IrInstSrc *init_union = ir_build_union_init_named_field(irb, scope, source_node, union_type, 7780 field_name, field_ptr, container_ptr); 7781 7782 return ir_lval_wrap(irb, scope, init_union, lval, parent_result_loc); 7783 } 7784 7785 static IrInstSrc *ir_gen_container_init_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 7786 ResultLoc *parent_result_loc) 7787 { 7788 assert(node->type == NodeTypeContainerInitExpr); 7789 7790 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; 7791 ContainerInitKind kind = container_init_expr->kind; 7792 7793 ResultLocCast *result_loc_cast = nullptr; 7794 ResultLoc *child_result_loc; 7795 AstNode *init_array_type_source_node; 7796 if (container_init_expr->type != nullptr) { 7797 IrInstSrc *container_type; 7798 if (container_init_expr->type->type == NodeTypeInferredArrayType) { 7799 if (kind == ContainerInitKindStruct) { 7800 add_node_error(irb->codegen, container_init_expr->type, 7801 buf_sprintf("initializing array with struct syntax")); 7802 return irb->codegen->invalid_inst_src; 7803 } 7804 IrInstSrc *sentinel; 7805 if (container_init_expr->type->data.inferred_array_type.sentinel != nullptr) { 7806 sentinel = ir_gen_node(irb, container_init_expr->type->data.inferred_array_type.sentinel, scope); 7807 if (sentinel == irb->codegen->invalid_inst_src) 7808 return sentinel; 7809 } else { 7810 sentinel = nullptr; 7811 } 7812 7813 IrInstSrc *elem_type = ir_gen_node(irb, 7814 container_init_expr->type->data.inferred_array_type.child_type, scope); 7815 if (elem_type == irb->codegen->invalid_inst_src) 7816 return elem_type; 7817 size_t item_count = container_init_expr->entries.length; 7818 IrInstSrc *item_count_inst = ir_build_const_usize(irb, scope, node, item_count); 7819 container_type = ir_build_array_type(irb, scope, node, item_count_inst, sentinel, elem_type); 7820 } else { 7821 container_type = ir_gen_node(irb, container_init_expr->type, scope); 7822 if (container_type == irb->codegen->invalid_inst_src) 7823 return container_type; 7824 } 7825 7826 result_loc_cast = ir_build_cast_result_loc(irb, container_type, parent_result_loc); 7827 child_result_loc = &result_loc_cast->base; 7828 init_array_type_source_node = container_type->base.source_node; 7829 } else { 7830 child_result_loc = parent_result_loc; 7831 if (parent_result_loc->source_instruction != nullptr) { 7832 init_array_type_source_node = parent_result_loc->source_instruction->base.source_node; 7833 } else { 7834 init_array_type_source_node = node; 7835 } 7836 } 7837 7838 switch (kind) { 7839 case ContainerInitKindStruct: { 7840 IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc, 7841 nullptr); 7842 7843 size_t field_count = container_init_expr->entries.length; 7844 IrInstSrcContainerInitFieldsField *fields = heap::c_allocator.allocate<IrInstSrcContainerInitFieldsField>(field_count); 7845 for (size_t i = 0; i < field_count; i += 1) { 7846 AstNode *entry_node = container_init_expr->entries.at(i); 7847 assert(entry_node->type == NodeTypeStructValueField); 7848 7849 Buf *name = entry_node->data.struct_val_field.name; 7850 AstNode *expr_node = entry_node->data.struct_val_field.expr; 7851 7852 IrInstSrc *field_ptr = ir_build_field_ptr(irb, scope, entry_node, container_ptr, name, true); 7853 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>(); 7854 result_loc_inst->base.id = ResultLocIdInstruction; 7855 result_loc_inst->base.source_instruction = field_ptr; 7856 result_loc_inst->base.allow_write_through_const = true; 7857 ir_ref_instruction(field_ptr, irb->current_basic_block); 7858 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 7859 7860 IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 7861 &result_loc_inst->base); 7862 if (expr_value == irb->codegen->invalid_inst_src) 7863 return expr_value; 7864 7865 fields[i].name = name; 7866 fields[i].source_node = entry_node; 7867 fields[i].result_loc = field_ptr; 7868 } 7869 IrInstSrc *result = ir_build_container_init_fields(irb, scope, node, field_count, 7870 fields, container_ptr); 7871 7872 if (result_loc_cast != nullptr) { 7873 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast); 7874 } 7875 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc); 7876 } 7877 case ContainerInitKindArray: { 7878 size_t item_count = container_init_expr->entries.length; 7879 7880 IrInstSrc *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc, 7881 nullptr); 7882 7883 IrInstSrc **result_locs = heap::c_allocator.allocate<IrInstSrc *>(item_count); 7884 for (size_t i = 0; i < item_count; i += 1) { 7885 AstNode *expr_node = container_init_expr->entries.at(i); 7886 7887 IrInstSrc *elem_index = ir_build_const_usize(irb, scope, expr_node, i); 7888 IrInstSrc *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, 7889 elem_index, false, PtrLenSingle, init_array_type_source_node); 7890 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>(); 7891 result_loc_inst->base.id = ResultLocIdInstruction; 7892 result_loc_inst->base.source_instruction = elem_ptr; 7893 result_loc_inst->base.allow_write_through_const = true; 7894 ir_ref_instruction(elem_ptr, irb->current_basic_block); 7895 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); 7896 7897 IrInstSrc *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, 7898 &result_loc_inst->base); 7899 if (expr_value == irb->codegen->invalid_inst_src) 7900 return expr_value; 7901 7902 result_locs[i] = elem_ptr; 7903 } 7904 IrInstSrc *result = ir_build_container_init_list(irb, scope, node, item_count, 7905 result_locs, container_ptr, init_array_type_source_node); 7906 if (result_loc_cast != nullptr) { 7907 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast); 7908 } 7909 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc); 7910 } 7911 } 7912 zig_unreachable(); 7913 } 7914 7915 static ResultLocVar *ir_build_var_result_loc(IrBuilderSrc *irb, IrInstSrc *alloca, ZigVar *var) { 7916 ResultLocVar *result_loc_var = heap::c_allocator.create<ResultLocVar>(); 7917 result_loc_var->base.id = ResultLocIdVar; 7918 result_loc_var->base.source_instruction = alloca; 7919 result_loc_var->base.allow_write_through_const = true; 7920 result_loc_var->var = var; 7921 7922 ir_build_reset_result(irb, alloca->base.scope, alloca->base.source_node, &result_loc_var->base); 7923 7924 return result_loc_var; 7925 } 7926 7927 static ResultLocCast *ir_build_cast_result_loc(IrBuilderSrc *irb, IrInstSrc *dest_type, 7928 ResultLoc *parent_result_loc) 7929 { 7930 ResultLocCast *result_loc_cast = heap::c_allocator.create<ResultLocCast>(); 7931 result_loc_cast->base.id = ResultLocIdCast; 7932 result_loc_cast->base.source_instruction = dest_type; 7933 result_loc_cast->base.allow_write_through_const = parent_result_loc->allow_write_through_const; 7934 ir_ref_instruction(dest_type, irb->current_basic_block); 7935 result_loc_cast->parent = parent_result_loc; 7936 7937 ir_build_reset_result(irb, dest_type->base.scope, dest_type->base.source_node, &result_loc_cast->base); 7938 7939 return result_loc_cast; 7940 } 7941 7942 static void build_decl_var_and_init(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, ZigVar *var, 7943 IrInstSrc *init, const char *name_hint, IrInstSrc *is_comptime) 7944 { 7945 IrInstSrc *alloca = ir_build_alloca_src(irb, scope, source_node, nullptr, name_hint, is_comptime); 7946 ResultLocVar *var_result_loc = ir_build_var_result_loc(irb, alloca, var); 7947 ir_build_end_expr(irb, scope, source_node, init, &var_result_loc->base); 7948 ir_build_var_decl_src(irb, scope, source_node, var, nullptr, alloca); 7949 } 7950 7951 static IrInstSrc *ir_gen_var_decl(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 7952 assert(node->type == NodeTypeVariableDeclaration); 7953 7954 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; 7955 7956 if (buf_eql_str(variable_declaration->symbol, "_")) { 7957 add_node_error(irb->codegen, node, buf_sprintf("`_` is not a declarable symbol")); 7958 return irb->codegen->invalid_inst_src; 7959 } 7960 7961 // Used for the type expr and the align expr 7962 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 7963 7964 IrInstSrc *type_instruction; 7965 if (variable_declaration->type != nullptr) { 7966 type_instruction = ir_gen_node(irb, variable_declaration->type, comptime_scope); 7967 if (type_instruction == irb->codegen->invalid_inst_src) 7968 return type_instruction; 7969 } else { 7970 type_instruction = nullptr; 7971 } 7972 7973 bool is_shadowable = false; 7974 bool is_const = variable_declaration->is_const; 7975 bool is_extern = variable_declaration->is_extern; 7976 7977 bool is_comptime_scalar = ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime; 7978 IrInstSrc *is_comptime = ir_build_const_bool(irb, scope, node, is_comptime_scalar); 7979 ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, 7980 is_const, is_const, is_shadowable, is_comptime); 7981 // we detect IrInstSrcDeclVar in gen_block to make sure the next node 7982 // is inside var->child_scope 7983 7984 if (!is_extern && !variable_declaration->expr) { 7985 var->var_type = irb->codegen->builtin_types.entry_invalid; 7986 add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); 7987 return irb->codegen->invalid_inst_src; 7988 } 7989 7990 IrInstSrc *align_value = nullptr; 7991 if (variable_declaration->align_expr != nullptr) { 7992 align_value = ir_gen_node(irb, variable_declaration->align_expr, comptime_scope); 7993 if (align_value == irb->codegen->invalid_inst_src) 7994 return align_value; 7995 } 7996 7997 if (variable_declaration->section_expr != nullptr) { 7998 add_node_error(irb->codegen, variable_declaration->section_expr, 7999 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol))); 8000 } 8001 8002 // Parser should ensure that this never happens 8003 assert(variable_declaration->threadlocal_tok == nullptr); 8004 8005 IrInstSrc *alloca = ir_build_alloca_src(irb, scope, node, align_value, 8006 buf_ptr(variable_declaration->symbol), is_comptime); 8007 8008 // Create a result location for the initialization expression. 8009 ResultLocVar *result_loc_var = ir_build_var_result_loc(irb, alloca, var); 8010 ResultLoc *init_result_loc; 8011 ResultLocCast *result_loc_cast; 8012 if (type_instruction != nullptr) { 8013 result_loc_cast = ir_build_cast_result_loc(irb, type_instruction, &result_loc_var->base); 8014 init_result_loc = &result_loc_cast->base; 8015 } else { 8016 result_loc_cast = nullptr; 8017 init_result_loc = &result_loc_var->base; 8018 } 8019 8020 Scope *init_scope = is_comptime_scalar ? 8021 create_comptime_scope(irb->codegen, variable_declaration->expr, scope) : scope; 8022 8023 // Temporarily set the name of the IrExecutableSrc to the VariableDeclaration 8024 // so that the struct or enum from the init expression inherits the name. 8025 Buf *old_exec_name = irb->exec->name; 8026 irb->exec->name = variable_declaration->symbol; 8027 IrInstSrc *init_value = ir_gen_node_extra(irb, variable_declaration->expr, init_scope, 8028 LValNone, init_result_loc); 8029 irb->exec->name = old_exec_name; 8030 8031 if (init_value == irb->codegen->invalid_inst_src) 8032 return irb->codegen->invalid_inst_src; 8033 8034 if (result_loc_cast != nullptr) { 8035 IrInstSrc *implicit_cast = ir_build_implicit_cast(irb, scope, init_value->base.source_node, 8036 init_value, result_loc_cast); 8037 ir_build_end_expr(irb, scope, node, implicit_cast, &result_loc_var->base); 8038 } 8039 8040 return ir_build_var_decl_src(irb, scope, node, var, align_value, alloca); 8041 } 8042 8043 static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 8044 ResultLoc *result_loc) 8045 { 8046 assert(node->type == NodeTypeWhileExpr); 8047 8048 AstNode *continue_expr_node = node->data.while_expr.continue_expr; 8049 AstNode *else_node = node->data.while_expr.else_node; 8050 8051 IrBasicBlockSrc *cond_block = ir_create_basic_block(irb, scope, "WhileCond"); 8052 IrBasicBlockSrc *body_block = ir_create_basic_block(irb, scope, "WhileBody"); 8053 IrBasicBlockSrc *continue_block = continue_expr_node ? 8054 ir_create_basic_block(irb, scope, "WhileContinue") : cond_block; 8055 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, scope, "WhileEnd"); 8056 IrBasicBlockSrc *else_block = else_node ? 8057 ir_create_basic_block(irb, scope, "WhileElse") : end_block; 8058 8059 IrInstSrc *is_comptime = ir_build_const_bool(irb, scope, node, 8060 ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline); 8061 ir_build_br(irb, scope, node, cond_block, is_comptime); 8062 8063 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 8064 Buf *var_symbol = node->data.while_expr.var_symbol; 8065 Buf *err_symbol = node->data.while_expr.err_symbol; 8066 if (err_symbol != nullptr) { 8067 ir_set_cursor_at_end_and_append_block(irb, cond_block); 8068 8069 Scope *payload_scope; 8070 AstNode *symbol_node = node; // TODO make more accurate 8071 ZigVar *payload_var; 8072 if (var_symbol) { 8073 // TODO make it an error to write to payload variable 8074 payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 8075 true, false, false, is_comptime); 8076 payload_scope = payload_var->child_scope; 8077 } else { 8078 payload_scope = subexpr_scope; 8079 } 8080 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, payload_scope); 8081 IrInstSrc *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, 8082 LValPtr, nullptr); 8083 if (err_val_ptr == irb->codegen->invalid_inst_src) 8084 return err_val_ptr; 8085 IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr, 8086 true, false); 8087 IrBasicBlockSrc *after_cond_block = irb->current_basic_block; 8088 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 8089 IrInstSrc *cond_br_inst; 8090 if (!instr_is_unreachable(is_err)) { 8091 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, 8092 else_block, body_block, is_comptime); 8093 cond_br_inst->is_gen = true; 8094 } else { 8095 // for the purposes of the source instruction to ir_build_result_peers 8096 cond_br_inst = irb->current_basic_block->instruction_list.last(); 8097 } 8098 8099 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 8100 is_comptime); 8101 8102 ir_set_cursor_at_end_and_append_block(irb, body_block); 8103 if (var_symbol) { 8104 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, &spill_scope->base, symbol_node, 8105 err_val_ptr, false, false); 8106 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ? 8107 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, symbol_node, payload_ptr); 8108 build_decl_var_and_init(irb, payload_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime); 8109 } 8110 8111 ZigList<IrInstSrc *> incoming_values = {0}; 8112 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 8113 8114 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope); 8115 loop_scope->break_block = end_block; 8116 loop_scope->continue_block = continue_block; 8117 loop_scope->is_comptime = is_comptime; 8118 loop_scope->incoming_blocks = &incoming_blocks; 8119 loop_scope->incoming_values = &incoming_values; 8120 loop_scope->lval = lval; 8121 loop_scope->peer_parent = peer_parent; 8122 loop_scope->spill_scope = spill_scope; 8123 8124 // Note the body block of the loop is not the place that lval and result_loc are used - 8125 // it's actually in break statements, handled similarly to return statements. 8126 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 8127 IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 8128 if (body_result == irb->codegen->invalid_inst_src) 8129 return body_result; 8130 8131 if (!instr_is_unreachable(body_result)) { 8132 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result)); 8133 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime)); 8134 } 8135 8136 if (continue_expr_node) { 8137 ir_set_cursor_at_end_and_append_block(irb, continue_block); 8138 IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, payload_scope); 8139 if (expr_result == irb->codegen->invalid_inst_src) 8140 return expr_result; 8141 if (!instr_is_unreachable(expr_result)) { 8142 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, continue_expr_node, expr_result)); 8143 ir_mark_gen(ir_build_br(irb, payload_scope, node, cond_block, is_comptime)); 8144 } 8145 } 8146 8147 ir_set_cursor_at_end_and_append_block(irb, else_block); 8148 assert(else_node != nullptr); 8149 8150 // TODO make it an error to write to error variable 8151 AstNode *err_symbol_node = else_node; // TODO make more accurate 8152 ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol, 8153 true, false, false, is_comptime); 8154 Scope *err_scope = err_var->child_scope; 8155 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, err_symbol_node, err_val_ptr); 8156 IrInstSrc *err_value = ir_build_load_ptr(irb, err_scope, err_symbol_node, err_ptr); 8157 build_decl_var_and_init(irb, err_scope, err_symbol_node, err_var, err_value, buf_ptr(err_symbol), is_comptime); 8158 8159 if (peer_parent->peers.length != 0) { 8160 peer_parent->peers.last()->next_bb = else_block; 8161 } 8162 ResultLocPeer *peer_result = create_peer_result(peer_parent); 8163 peer_parent->peers.append(peer_result); 8164 IrInstSrc *else_result = ir_gen_node_extra(irb, else_node, err_scope, lval, &peer_result->base); 8165 if (else_result == irb->codegen->invalid_inst_src) 8166 return else_result; 8167 if (!instr_is_unreachable(else_result)) 8168 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 8169 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8170 ir_set_cursor_at_end_and_append_block(irb, end_block); 8171 if (else_result) { 8172 incoming_blocks.append(after_else_block); 8173 incoming_values.append(else_result); 8174 } else { 8175 incoming_blocks.append(after_cond_block); 8176 incoming_values.append(void_else_result); 8177 } 8178 if (peer_parent->peers.length != 0) { 8179 peer_parent->peers.last()->next_bb = end_block; 8180 } 8181 8182 IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 8183 incoming_blocks.items, incoming_values.items, peer_parent); 8184 return ir_expr_wrap(irb, scope, phi, result_loc); 8185 } else if (var_symbol != nullptr) { 8186 ir_set_cursor_at_end_and_append_block(irb, cond_block); 8187 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 8188 // TODO make it an error to write to payload variable 8189 AstNode *symbol_node = node; // TODO make more accurate 8190 8191 ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 8192 true, false, false, is_comptime); 8193 Scope *child_scope = payload_var->child_scope; 8194 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, child_scope); 8195 IrInstSrc *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, 8196 LValPtr, nullptr); 8197 if (maybe_val_ptr == irb->codegen->invalid_inst_src) 8198 return maybe_val_ptr; 8199 IrInstSrc *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); 8200 IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, scope, node->data.while_expr.condition, maybe_val); 8201 IrBasicBlockSrc *after_cond_block = irb->current_basic_block; 8202 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 8203 IrInstSrc *cond_br_inst; 8204 if (!instr_is_unreachable(is_non_null)) { 8205 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, 8206 body_block, else_block, is_comptime); 8207 cond_br_inst->is_gen = true; 8208 } else { 8209 // for the purposes of the source instruction to ir_build_result_peers 8210 cond_br_inst = irb->current_basic_block->instruction_list.last(); 8211 } 8212 8213 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 8214 is_comptime); 8215 8216 ir_set_cursor_at_end_and_append_block(irb, body_block); 8217 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, &spill_scope->base, symbol_node, maybe_val_ptr, false); 8218 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ? 8219 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, symbol_node, payload_ptr); 8220 build_decl_var_and_init(irb, child_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime); 8221 8222 ZigList<IrInstSrc *> incoming_values = {0}; 8223 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 8224 8225 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 8226 loop_scope->break_block = end_block; 8227 loop_scope->continue_block = continue_block; 8228 loop_scope->is_comptime = is_comptime; 8229 loop_scope->incoming_blocks = &incoming_blocks; 8230 loop_scope->incoming_values = &incoming_values; 8231 loop_scope->lval = lval; 8232 loop_scope->peer_parent = peer_parent; 8233 loop_scope->spill_scope = spill_scope; 8234 8235 // Note the body block of the loop is not the place that lval and result_loc are used - 8236 // it's actually in break statements, handled similarly to return statements. 8237 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 8238 IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 8239 if (body_result == irb->codegen->invalid_inst_src) 8240 return body_result; 8241 8242 if (!instr_is_unreachable(body_result)) { 8243 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result)); 8244 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 8245 } 8246 8247 if (continue_expr_node) { 8248 ir_set_cursor_at_end_and_append_block(irb, continue_block); 8249 IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, child_scope); 8250 if (expr_result == irb->codegen->invalid_inst_src) 8251 return expr_result; 8252 if (!instr_is_unreachable(expr_result)) { 8253 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, continue_expr_node, expr_result)); 8254 ir_mark_gen(ir_build_br(irb, child_scope, node, cond_block, is_comptime)); 8255 } 8256 } 8257 8258 IrInstSrc *else_result = nullptr; 8259 if (else_node) { 8260 ir_set_cursor_at_end_and_append_block(irb, else_block); 8261 8262 if (peer_parent->peers.length != 0) { 8263 peer_parent->peers.last()->next_bb = else_block; 8264 } 8265 ResultLocPeer *peer_result = create_peer_result(peer_parent); 8266 peer_parent->peers.append(peer_result); 8267 else_result = ir_gen_node_extra(irb, else_node, scope, lval, &peer_result->base); 8268 if (else_result == irb->codegen->invalid_inst_src) 8269 return else_result; 8270 if (!instr_is_unreachable(else_result)) 8271 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 8272 } 8273 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8274 ir_set_cursor_at_end_and_append_block(irb, end_block); 8275 if (else_result) { 8276 incoming_blocks.append(after_else_block); 8277 incoming_values.append(else_result); 8278 } else { 8279 incoming_blocks.append(after_cond_block); 8280 incoming_values.append(void_else_result); 8281 } 8282 if (peer_parent->peers.length != 0) { 8283 peer_parent->peers.last()->next_bb = end_block; 8284 } 8285 8286 IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 8287 incoming_blocks.items, incoming_values.items, peer_parent); 8288 return ir_expr_wrap(irb, scope, phi, result_loc); 8289 } else { 8290 ir_set_cursor_at_end_and_append_block(irb, cond_block); 8291 IrInstSrc *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); 8292 if (cond_val == irb->codegen->invalid_inst_src) 8293 return cond_val; 8294 IrBasicBlockSrc *after_cond_block = irb->current_basic_block; 8295 IrInstSrc *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 8296 IrInstSrc *cond_br_inst; 8297 if (!instr_is_unreachable(cond_val)) { 8298 cond_br_inst = ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, 8299 body_block, else_block, is_comptime); 8300 cond_br_inst->is_gen = true; 8301 } else { 8302 // for the purposes of the source instruction to ir_build_result_peers 8303 cond_br_inst = irb->current_basic_block->instruction_list.last(); 8304 } 8305 8306 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, 8307 is_comptime); 8308 ir_set_cursor_at_end_and_append_block(irb, body_block); 8309 8310 ZigList<IrInstSrc *> incoming_values = {0}; 8311 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 8312 8313 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 8314 8315 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope); 8316 loop_scope->break_block = end_block; 8317 loop_scope->continue_block = continue_block; 8318 loop_scope->is_comptime = is_comptime; 8319 loop_scope->incoming_blocks = &incoming_blocks; 8320 loop_scope->incoming_values = &incoming_values; 8321 loop_scope->lval = lval; 8322 loop_scope->peer_parent = peer_parent; 8323 8324 // Note the body block of the loop is not the place that lval and result_loc are used - 8325 // it's actually in break statements, handled similarly to return statements. 8326 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 8327 IrInstSrc *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 8328 if (body_result == irb->codegen->invalid_inst_src) 8329 return body_result; 8330 8331 if (!instr_is_unreachable(body_result)) { 8332 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result)); 8333 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime)); 8334 } 8335 8336 if (continue_expr_node) { 8337 ir_set_cursor_at_end_and_append_block(irb, continue_block); 8338 IrInstSrc *expr_result = ir_gen_node(irb, continue_expr_node, subexpr_scope); 8339 if (expr_result == irb->codegen->invalid_inst_src) 8340 return expr_result; 8341 if (!instr_is_unreachable(expr_result)) { 8342 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, continue_expr_node, expr_result)); 8343 ir_mark_gen(ir_build_br(irb, scope, node, cond_block, is_comptime)); 8344 } 8345 } 8346 8347 IrInstSrc *else_result = nullptr; 8348 if (else_node) { 8349 ir_set_cursor_at_end_and_append_block(irb, else_block); 8350 8351 if (peer_parent->peers.length != 0) { 8352 peer_parent->peers.last()->next_bb = else_block; 8353 } 8354 ResultLocPeer *peer_result = create_peer_result(peer_parent); 8355 peer_parent->peers.append(peer_result); 8356 8357 else_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_result->base); 8358 if (else_result == irb->codegen->invalid_inst_src) 8359 return else_result; 8360 if (!instr_is_unreachable(else_result)) 8361 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 8362 } 8363 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8364 ir_set_cursor_at_end_and_append_block(irb, end_block); 8365 if (else_result) { 8366 incoming_blocks.append(after_else_block); 8367 incoming_values.append(else_result); 8368 } else { 8369 incoming_blocks.append(after_cond_block); 8370 incoming_values.append(void_else_result); 8371 } 8372 if (peer_parent->peers.length != 0) { 8373 peer_parent->peers.last()->next_bb = end_block; 8374 } 8375 8376 IrInstSrc *phi = ir_build_phi(irb, scope, node, incoming_blocks.length, 8377 incoming_blocks.items, incoming_values.items, peer_parent); 8378 return ir_expr_wrap(irb, scope, phi, result_loc); 8379 } 8380 } 8381 8382 static IrInstSrc *ir_gen_for_expr(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval, 8383 ResultLoc *result_loc) 8384 { 8385 assert(node->type == NodeTypeForExpr); 8386 8387 AstNode *array_node = node->data.for_expr.array_expr; 8388 AstNode *elem_node = node->data.for_expr.elem_node; 8389 AstNode *index_node = node->data.for_expr.index_node; 8390 AstNode *body_node = node->data.for_expr.body; 8391 AstNode *else_node = node->data.for_expr.else_node; 8392 8393 if (!elem_node) { 8394 add_node_error(irb->codegen, node, buf_sprintf("for loop expression missing element parameter")); 8395 return irb->codegen->invalid_inst_src; 8396 } 8397 assert(elem_node->type == NodeTypeSymbol); 8398 8399 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, node, parent_scope); 8400 8401 IrInstSrc *array_val_ptr = ir_gen_node_extra(irb, array_node, &spill_scope->base, LValPtr, nullptr); 8402 if (array_val_ptr == irb->codegen->invalid_inst_src) 8403 return array_val_ptr; 8404 8405 IrInstSrc *is_comptime = ir_build_const_bool(irb, parent_scope, node, 8406 ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); 8407 8408 AstNode *index_var_source_node; 8409 ZigVar *index_var; 8410 const char *index_var_name; 8411 if (index_node) { 8412 index_var_source_node = index_node; 8413 Buf *index_var_name_buf = index_node->data.symbol_expr.symbol; 8414 index_var = ir_create_var(irb, index_node, parent_scope, index_var_name_buf, true, false, false, is_comptime); 8415 index_var_name = buf_ptr(index_var_name_buf); 8416 } else { 8417 index_var_source_node = node; 8418 index_var = ir_create_var(irb, node, parent_scope, nullptr, true, false, true, is_comptime); 8419 index_var_name = "i"; 8420 } 8421 8422 IrInstSrc *zero = ir_build_const_usize(irb, parent_scope, node, 0); 8423 build_decl_var_and_init(irb, parent_scope, index_var_source_node, index_var, zero, index_var_name, is_comptime); 8424 parent_scope = index_var->child_scope; 8425 8426 IrInstSrc *one = ir_build_const_usize(irb, parent_scope, node, 1); 8427 IrInstSrc *index_ptr = ir_build_var_ptr(irb, parent_scope, node, index_var); 8428 8429 8430 IrBasicBlockSrc *cond_block = ir_create_basic_block(irb, parent_scope, "ForCond"); 8431 IrBasicBlockSrc *body_block = ir_create_basic_block(irb, parent_scope, "ForBody"); 8432 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "ForEnd"); 8433 IrBasicBlockSrc *else_block = else_node ? ir_create_basic_block(irb, parent_scope, "ForElse") : end_block; 8434 IrBasicBlockSrc *continue_block = ir_create_basic_block(irb, parent_scope, "ForContinue"); 8435 8436 Buf *len_field_name = buf_create_from_str("len"); 8437 IrInstSrc *len_ref = ir_build_field_ptr(irb, parent_scope, node, array_val_ptr, len_field_name, false); 8438 IrInstSrc *len_val = ir_build_load_ptr(irb, &spill_scope->base, node, len_ref); 8439 ir_build_br(irb, parent_scope, node, cond_block, is_comptime); 8440 8441 ir_set_cursor_at_end_and_append_block(irb, cond_block); 8442 IrInstSrc *index_val = ir_build_load_ptr(irb, &spill_scope->base, node, index_ptr); 8443 IrInstSrc *cond = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); 8444 IrBasicBlockSrc *after_cond_block = irb->current_basic_block; 8445 IrInstSrc *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); 8446 IrInstSrc *cond_br_inst = ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, cond, 8447 body_block, else_block, is_comptime)); 8448 8449 ResultLocPeerParent *peer_parent = ir_build_result_peers(irb, cond_br_inst, end_block, result_loc, is_comptime); 8450 8451 ir_set_cursor_at_end_and_append_block(irb, body_block); 8452 IrInstSrc *elem_ptr = ir_build_elem_ptr(irb, &spill_scope->base, node, array_val_ptr, index_val, 8453 false, PtrLenSingle, nullptr); 8454 // TODO make it an error to write to element variable or i variable. 8455 Buf *elem_var_name = elem_node->data.symbol_expr.symbol; 8456 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); 8457 Scope *child_scope = elem_var->child_scope; 8458 8459 IrInstSrc *elem_value = node->data.for_expr.elem_is_ptr ? 8460 elem_ptr : ir_build_load_ptr(irb, &spill_scope->base, elem_node, elem_ptr); 8461 build_decl_var_and_init(irb, parent_scope, elem_node, elem_var, elem_value, buf_ptr(elem_var_name), is_comptime); 8462 8463 ZigList<IrInstSrc *> incoming_values = {0}; 8464 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 8465 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 8466 loop_scope->break_block = end_block; 8467 loop_scope->continue_block = continue_block; 8468 loop_scope->is_comptime = is_comptime; 8469 loop_scope->incoming_blocks = &incoming_blocks; 8470 loop_scope->incoming_values = &incoming_values; 8471 loop_scope->lval = LValNone; 8472 loop_scope->peer_parent = peer_parent; 8473 loop_scope->spill_scope = spill_scope; 8474 8475 // Note the body block of the loop is not the place that lval and result_loc are used - 8476 // it's actually in break statements, handled similarly to return statements. 8477 // That is why we set those values in loop_scope above and not in this ir_gen_node call. 8478 IrInstSrc *body_result = ir_gen_node(irb, body_node, &loop_scope->base); 8479 if (body_result == irb->codegen->invalid_inst_src) 8480 return irb->codegen->invalid_inst_src; 8481 8482 if (!instr_is_unreachable(body_result)) { 8483 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result)); 8484 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 8485 } 8486 8487 ir_set_cursor_at_end_and_append_block(irb, continue_block); 8488 IrInstSrc *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false); 8489 ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)->allow_write_through_const = true; 8490 ir_build_br(irb, child_scope, node, cond_block, is_comptime); 8491 8492 IrInstSrc *else_result = nullptr; 8493 if (else_node) { 8494 ir_set_cursor_at_end_and_append_block(irb, else_block); 8495 8496 if (peer_parent->peers.length != 0) { 8497 peer_parent->peers.last()->next_bb = else_block; 8498 } 8499 ResultLocPeer *peer_result = create_peer_result(peer_parent); 8500 peer_parent->peers.append(peer_result); 8501 else_result = ir_gen_node_extra(irb, else_node, parent_scope, LValNone, &peer_result->base); 8502 if (else_result == irb->codegen->invalid_inst_src) 8503 return else_result; 8504 if (!instr_is_unreachable(else_result)) 8505 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 8506 } 8507 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8508 ir_set_cursor_at_end_and_append_block(irb, end_block); 8509 8510 if (else_result) { 8511 incoming_blocks.append(after_else_block); 8512 incoming_values.append(else_result); 8513 } else { 8514 incoming_blocks.append(after_cond_block); 8515 incoming_values.append(void_else_value); 8516 } 8517 if (peer_parent->peers.length != 0) { 8518 peer_parent->peers.last()->next_bb = end_block; 8519 } 8520 8521 IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, 8522 incoming_blocks.items, incoming_values.items, peer_parent); 8523 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 8524 } 8525 8526 static IrInstSrc *ir_gen_bool_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8527 assert(node->type == NodeTypeBoolLiteral); 8528 return ir_build_const_bool(irb, scope, node, node->data.bool_literal.value); 8529 } 8530 8531 static IrInstSrc *ir_gen_enum_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8532 assert(node->type == NodeTypeEnumLiteral); 8533 Buf *name = &node->data.enum_literal.identifier->data.str_lit.str; 8534 return ir_build_const_enum_literal(irb, scope, node, name); 8535 } 8536 8537 static IrInstSrc *ir_gen_string_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8538 assert(node->type == NodeTypeStringLiteral); 8539 8540 return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf); 8541 } 8542 8543 static IrInstSrc *ir_gen_array_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8544 assert(node->type == NodeTypeArrayType); 8545 8546 AstNode *size_node = node->data.array_type.size; 8547 AstNode *child_type_node = node->data.array_type.child_type; 8548 bool is_const = node->data.array_type.is_const; 8549 bool is_volatile = node->data.array_type.is_volatile; 8550 bool is_allow_zero = node->data.array_type.allow_zero_token != nullptr; 8551 AstNode *sentinel_expr = node->data.array_type.sentinel; 8552 AstNode *align_expr = node->data.array_type.align_expr; 8553 8554 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 8555 8556 IrInstSrc *sentinel; 8557 if (sentinel_expr != nullptr) { 8558 sentinel = ir_gen_node(irb, sentinel_expr, comptime_scope); 8559 if (sentinel == irb->codegen->invalid_inst_src) 8560 return sentinel; 8561 } else { 8562 sentinel = nullptr; 8563 } 8564 8565 if (size_node) { 8566 if (is_const) { 8567 add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type")); 8568 return irb->codegen->invalid_inst_src; 8569 } 8570 if (is_volatile) { 8571 add_node_error(irb->codegen, node, buf_create_from_str("volatile qualifier invalid on array type")); 8572 return irb->codegen->invalid_inst_src; 8573 } 8574 if (is_allow_zero) { 8575 add_node_error(irb->codegen, node, buf_create_from_str("allowzero qualifier invalid on array type")); 8576 return irb->codegen->invalid_inst_src; 8577 } 8578 if (align_expr != nullptr) { 8579 add_node_error(irb->codegen, node, buf_create_from_str("align qualifier invalid on array type")); 8580 return irb->codegen->invalid_inst_src; 8581 } 8582 8583 IrInstSrc *size_value = ir_gen_node(irb, size_node, comptime_scope); 8584 if (size_value == irb->codegen->invalid_inst_src) 8585 return size_value; 8586 8587 IrInstSrc *child_type = ir_gen_node(irb, child_type_node, comptime_scope); 8588 if (child_type == irb->codegen->invalid_inst_src) 8589 return child_type; 8590 8591 return ir_build_array_type(irb, scope, node, size_value, sentinel, child_type); 8592 } else { 8593 IrInstSrc *align_value; 8594 if (align_expr != nullptr) { 8595 align_value = ir_gen_node(irb, align_expr, comptime_scope); 8596 if (align_value == irb->codegen->invalid_inst_src) 8597 return align_value; 8598 } else { 8599 align_value = nullptr; 8600 } 8601 8602 IrInstSrc *child_type = ir_gen_node(irb, child_type_node, comptime_scope); 8603 if (child_type == irb->codegen->invalid_inst_src) 8604 return child_type; 8605 8606 return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, sentinel, 8607 align_value, is_allow_zero); 8608 } 8609 } 8610 8611 static IrInstSrc *ir_gen_anyframe_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8612 assert(node->type == NodeTypeAnyFrameType); 8613 8614 AstNode *payload_type_node = node->data.anyframe_type.payload_type; 8615 IrInstSrc *payload_type_value = nullptr; 8616 8617 if (payload_type_node != nullptr) { 8618 payload_type_value = ir_gen_node(irb, payload_type_node, scope); 8619 if (payload_type_value == irb->codegen->invalid_inst_src) 8620 return payload_type_value; 8621 8622 } 8623 8624 return ir_build_anyframe_type(irb, scope, node, payload_type_value); 8625 } 8626 8627 static IrInstSrc *ir_gen_undefined_literal(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8628 assert(node->type == NodeTypeUndefinedLiteral); 8629 return ir_build_const_undefined(irb, scope, node); 8630 } 8631 8632 static Error parse_asm_template(IrAnalyze *ira, AstNode *source_node, Buf *asm_template, 8633 ZigList<AsmToken> *tok_list) 8634 { 8635 // TODO Connect the errors in this function back up to the actual source location 8636 // rather than just the token. https://github.com/ziglang/zig/issues/2080 8637 enum State { 8638 StateStart, 8639 StatePercent, 8640 StateTemplate, 8641 StateVar, 8642 }; 8643 8644 assert(tok_list->length == 0); 8645 8646 AsmToken *cur_tok = nullptr; 8647 8648 enum State state = StateStart; 8649 8650 for (size_t i = 0; i < buf_len(asm_template); i += 1) { 8651 uint8_t c = *((uint8_t*)buf_ptr(asm_template) + i); 8652 switch (state) { 8653 case StateStart: 8654 if (c == '%') { 8655 tok_list->add_one(); 8656 cur_tok = &tok_list->last(); 8657 cur_tok->id = AsmTokenIdPercent; 8658 cur_tok->start = i; 8659 state = StatePercent; 8660 } else { 8661 tok_list->add_one(); 8662 cur_tok = &tok_list->last(); 8663 cur_tok->id = AsmTokenIdTemplate; 8664 cur_tok->start = i; 8665 state = StateTemplate; 8666 } 8667 break; 8668 case StatePercent: 8669 if (c == '%') { 8670 cur_tok->end = i; 8671 state = StateStart; 8672 } else if (c == '[') { 8673 cur_tok->id = AsmTokenIdVar; 8674 state = StateVar; 8675 } else if (c == '=') { 8676 cur_tok->id = AsmTokenIdUniqueId; 8677 cur_tok->end = i; 8678 state = StateStart; 8679 } else { 8680 add_node_error(ira->codegen, source_node, 8681 buf_create_from_str("expected a '%' or '['")); 8682 return ErrorSemanticAnalyzeFail; 8683 } 8684 break; 8685 case StateTemplate: 8686 if (c == '%') { 8687 cur_tok->end = i; 8688 i -= 1; 8689 cur_tok = nullptr; 8690 state = StateStart; 8691 } 8692 break; 8693 case StateVar: 8694 if (c == ']') { 8695 cur_tok->end = i; 8696 state = StateStart; 8697 } else if ((c >= 'a' && c <= 'z') || 8698 (c >= '0' && c <= '9') || 8699 (c == '_')) 8700 { 8701 // do nothing 8702 } else { 8703 add_node_error(ira->codegen, source_node, 8704 buf_sprintf("invalid substitution character: '%c'", c)); 8705 return ErrorSemanticAnalyzeFail; 8706 } 8707 break; 8708 } 8709 } 8710 8711 switch (state) { 8712 case StateStart: 8713 break; 8714 case StatePercent: 8715 case StateVar: 8716 add_node_error(ira->codegen, source_node, buf_sprintf("unexpected end of assembly template")); 8717 return ErrorSemanticAnalyzeFail; 8718 case StateTemplate: 8719 cur_tok->end = buf_len(asm_template); 8720 break; 8721 } 8722 return ErrorNone; 8723 } 8724 8725 static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_template) { 8726 const char *ptr = buf_ptr(src_template) + tok->start + 2; 8727 size_t len = tok->end - tok->start - 2; 8728 size_t result = 0; 8729 for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1, result += 1) { 8730 AsmOutput *asm_output = node->data.asm_expr.output_list.at(i); 8731 if (buf_eql_mem(asm_output->asm_symbolic_name, ptr, len)) { 8732 return result; 8733 } 8734 } 8735 for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1, result += 1) { 8736 AsmInput *asm_input = node->data.asm_expr.input_list.at(i); 8737 if (buf_eql_mem(asm_input->asm_symbolic_name, ptr, len)) { 8738 return result; 8739 } 8740 } 8741 return SIZE_MAX; 8742 } 8743 8744 static IrInstSrc *ir_gen_asm_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 8745 assert(node->type == NodeTypeAsmExpr); 8746 AstNodeAsmExpr *asm_expr = &node->data.asm_expr; 8747 8748 IrInstSrc *asm_template = ir_gen_node(irb, asm_expr->asm_template, scope); 8749 if (asm_template == irb->codegen->invalid_inst_src) 8750 return irb->codegen->invalid_inst_src; 8751 8752 bool is_volatile = asm_expr->volatile_token != nullptr; 8753 bool in_fn_scope = (scope_fn_entry(scope) != nullptr); 8754 8755 if (!in_fn_scope) { 8756 if (is_volatile) { 8757 add_token_error(irb->codegen, node->owner, asm_expr->volatile_token, 8758 buf_sprintf("volatile is meaningless on global assembly")); 8759 return irb->codegen->invalid_inst_src; 8760 } 8761 8762 if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 || 8763 asm_expr->clobber_list.length != 0) 8764 { 8765 add_node_error(irb->codegen, node, 8766 buf_sprintf("global assembly cannot have inputs, outputs, or clobbers")); 8767 return irb->codegen->invalid_inst_src; 8768 } 8769 8770 return ir_build_asm_src(irb, scope, node, asm_template, nullptr, nullptr, 8771 nullptr, 0, is_volatile, true); 8772 } 8773 8774 IrInstSrc **input_list = heap::c_allocator.allocate<IrInstSrc *>(asm_expr->input_list.length); 8775 IrInstSrc **output_types = heap::c_allocator.allocate<IrInstSrc *>(asm_expr->output_list.length); 8776 ZigVar **output_vars = heap::c_allocator.allocate<ZigVar *>(asm_expr->output_list.length); 8777 size_t return_count = 0; 8778 if (!is_volatile && asm_expr->output_list.length == 0) { 8779 add_node_error(irb->codegen, node, 8780 buf_sprintf("assembly expression with no output must be marked volatile")); 8781 return irb->codegen->invalid_inst_src; 8782 } 8783 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 8784 AsmOutput *asm_output = asm_expr->output_list.at(i); 8785 if (asm_output->return_type) { 8786 return_count += 1; 8787 8788 IrInstSrc *return_type = ir_gen_node(irb, asm_output->return_type, scope); 8789 if (return_type == irb->codegen->invalid_inst_src) 8790 return irb->codegen->invalid_inst_src; 8791 if (return_count > 1) { 8792 add_node_error(irb->codegen, node, 8793 buf_sprintf("inline assembly allows up to one output value")); 8794 return irb->codegen->invalid_inst_src; 8795 } 8796 output_types[i] = return_type; 8797 } else { 8798 Buf *variable_name = asm_output->variable_name; 8799 // TODO there is some duplication here with ir_gen_symbol. I need to do a full audit of how 8800 // inline assembly works. https://github.com/ziglang/zig/issues/215 8801 ZigVar *var = find_variable(irb->codegen, scope, variable_name, nullptr); 8802 if (var) { 8803 output_vars[i] = var; 8804 } else { 8805 add_node_error(irb->codegen, node, 8806 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); 8807 return irb->codegen->invalid_inst_src; 8808 } 8809 } 8810 8811 const char modifier = *buf_ptr(asm_output->constraint); 8812 if (modifier != '=') { 8813 add_node_error(irb->codegen, node, 8814 buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported." 8815 " Compiler TODO: see https://github.com/ziglang/zig/issues/215", 8816 buf_ptr(asm_output->asm_symbolic_name), modifier)); 8817 return irb->codegen->invalid_inst_src; 8818 } 8819 } 8820 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 8821 AsmInput *asm_input = asm_expr->input_list.at(i); 8822 IrInstSrc *input_value = ir_gen_node(irb, asm_input->expr, scope); 8823 if (input_value == irb->codegen->invalid_inst_src) 8824 return irb->codegen->invalid_inst_src; 8825 8826 input_list[i] = input_value; 8827 } 8828 8829 return ir_build_asm_src(irb, scope, node, asm_template, input_list, output_types, 8830 output_vars, return_count, is_volatile, false); 8831 } 8832 8833 static IrInstSrc *ir_gen_if_optional_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 8834 ResultLoc *result_loc) 8835 { 8836 assert(node->type == NodeTypeIfOptional); 8837 8838 Buf *var_symbol = node->data.test_expr.var_symbol; 8839 AstNode *expr_node = node->data.test_expr.target_node; 8840 AstNode *then_node = node->data.test_expr.then_node; 8841 AstNode *else_node = node->data.test_expr.else_node; 8842 bool var_is_ptr = node->data.test_expr.var_is_ptr; 8843 8844 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, expr_node, scope); 8845 spill_scope->spill_harder = true; 8846 8847 IrInstSrc *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, &spill_scope->base, LValPtr, nullptr); 8848 if (maybe_val_ptr == irb->codegen->invalid_inst_src) 8849 return maybe_val_ptr; 8850 8851 IrInstSrc *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr); 8852 IrInstSrc *is_non_null = ir_build_test_non_null_src(irb, scope, node, maybe_val); 8853 8854 IrBasicBlockSrc *then_block = ir_create_basic_block(irb, scope, "OptionalThen"); 8855 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "OptionalElse"); 8856 IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "OptionalEndIf"); 8857 8858 IrInstSrc *is_comptime; 8859 if (ir_should_inline(irb->exec, scope)) { 8860 is_comptime = ir_build_const_bool(irb, scope, node, true); 8861 } else { 8862 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); 8863 } 8864 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, is_non_null, 8865 then_block, else_block, is_comptime); 8866 8867 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 8868 result_loc, is_comptime); 8869 8870 ir_set_cursor_at_end_and_append_block(irb, then_block); 8871 8872 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, &spill_scope->base, is_comptime); 8873 Scope *var_scope; 8874 if (var_symbol) { 8875 bool is_shadowable = false; 8876 bool is_const = true; 8877 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 8878 var_symbol, is_const, is_const, is_shadowable, is_comptime); 8879 8880 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false); 8881 IrInstSrc *var_value = var_is_ptr ? 8882 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, node, payload_ptr); 8883 build_decl_var_and_init(irb, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), is_comptime); 8884 var_scope = var->child_scope; 8885 } else { 8886 var_scope = subexpr_scope; 8887 } 8888 IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, 8889 &peer_parent->peers.at(0)->base); 8890 if (then_expr_result == irb->codegen->invalid_inst_src) 8891 return then_expr_result; 8892 IrBasicBlockSrc *after_then_block = irb->current_basic_block; 8893 if (!instr_is_unreachable(then_expr_result)) 8894 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 8895 8896 ir_set_cursor_at_end_and_append_block(irb, else_block); 8897 IrInstSrc *else_expr_result; 8898 if (else_node) { 8899 else_expr_result = ir_gen_node_extra(irb, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base); 8900 if (else_expr_result == irb->codegen->invalid_inst_src) 8901 return else_expr_result; 8902 } else { 8903 else_expr_result = ir_build_const_void(irb, scope, node); 8904 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 8905 } 8906 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 8907 if (!instr_is_unreachable(else_expr_result)) 8908 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 8909 8910 ir_set_cursor_at_end_and_append_block(irb, endif_block); 8911 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 8912 incoming_values[0] = then_expr_result; 8913 incoming_values[1] = else_expr_result; 8914 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 8915 incoming_blocks[0] = after_then_block; 8916 incoming_blocks[1] = after_else_block; 8917 8918 IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 8919 return ir_expr_wrap(irb, scope, phi, result_loc); 8920 } 8921 8922 static IrInstSrc *ir_gen_if_err_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 8923 ResultLoc *result_loc) 8924 { 8925 assert(node->type == NodeTypeIfErrorExpr); 8926 8927 AstNode *target_node = node->data.if_err_expr.target_node; 8928 AstNode *then_node = node->data.if_err_expr.then_node; 8929 AstNode *else_node = node->data.if_err_expr.else_node; 8930 bool var_is_ptr = node->data.if_err_expr.var_is_ptr; 8931 bool var_is_const = true; 8932 Buf *var_symbol = node->data.if_err_expr.var_symbol; 8933 Buf *err_symbol = node->data.if_err_expr.err_symbol; 8934 8935 IrInstSrc *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); 8936 if (err_val_ptr == irb->codegen->invalid_inst_src) 8937 return err_val_ptr; 8938 8939 IrInstSrc *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); 8940 IrInstSrc *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr, true, false); 8941 8942 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, scope, "TryOk"); 8943 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "TryElse"); 8944 IrBasicBlockSrc *endif_block = ir_create_basic_block(irb, scope, "TryEnd"); 8945 8946 bool force_comptime = ir_should_inline(irb->exec, scope); 8947 IrInstSrc *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); 8948 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); 8949 8950 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, else_block, endif_block, 8951 result_loc, is_comptime); 8952 8953 ir_set_cursor_at_end_and_append_block(irb, ok_block); 8954 8955 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 8956 Scope *var_scope; 8957 if (var_symbol) { 8958 bool is_shadowable = false; 8959 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); 8960 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 8961 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); 8962 8963 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, subexpr_scope, node, err_val_ptr, false, false); 8964 IrInstSrc *var_value = var_is_ptr ? 8965 payload_ptr : ir_build_load_ptr(irb, subexpr_scope, node, payload_ptr); 8966 build_decl_var_and_init(irb, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), var_is_comptime); 8967 var_scope = var->child_scope; 8968 } else { 8969 var_scope = subexpr_scope; 8970 } 8971 IrInstSrc *then_expr_result = ir_gen_node_extra(irb, then_node, var_scope, lval, 8972 &peer_parent->peers.at(0)->base); 8973 if (then_expr_result == irb->codegen->invalid_inst_src) 8974 return then_expr_result; 8975 IrBasicBlockSrc *after_then_block = irb->current_basic_block; 8976 if (!instr_is_unreachable(then_expr_result)) 8977 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 8978 8979 ir_set_cursor_at_end_and_append_block(irb, else_block); 8980 8981 IrInstSrc *else_expr_result; 8982 if (else_node) { 8983 Scope *err_var_scope; 8984 if (err_symbol) { 8985 bool is_shadowable = false; 8986 bool is_const = true; 8987 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 8988 err_symbol, is_const, is_const, is_shadowable, is_comptime); 8989 8990 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, subexpr_scope, node, err_val_ptr); 8991 IrInstSrc *err_value = ir_build_load_ptr(irb, subexpr_scope, node, err_ptr); 8992 build_decl_var_and_init(irb, subexpr_scope, node, var, err_value, buf_ptr(err_symbol), is_comptime); 8993 err_var_scope = var->child_scope; 8994 } else { 8995 err_var_scope = subexpr_scope; 8996 } 8997 else_expr_result = ir_gen_node_extra(irb, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base); 8998 if (else_expr_result == irb->codegen->invalid_inst_src) 8999 return else_expr_result; 9000 } else { 9001 else_expr_result = ir_build_const_void(irb, scope, node); 9002 ir_build_end_expr(irb, scope, node, else_expr_result, &peer_parent->peers.at(1)->base); 9003 } 9004 IrBasicBlockSrc *after_else_block = irb->current_basic_block; 9005 if (!instr_is_unreachable(else_expr_result)) 9006 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 9007 9008 ir_set_cursor_at_end_and_append_block(irb, endif_block); 9009 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 9010 incoming_values[0] = then_expr_result; 9011 incoming_values[1] = else_expr_result; 9012 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 9013 incoming_blocks[0] = after_then_block; 9014 incoming_blocks[1] = after_else_block; 9015 9016 IrInstSrc *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values, peer_parent); 9017 return ir_expr_wrap(irb, scope, phi, result_loc); 9018 } 9019 9020 static bool ir_gen_switch_prong_expr(IrBuilderSrc *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, 9021 IrBasicBlockSrc *end_block, IrInstSrc *is_comptime, IrInstSrc *var_is_comptime, 9022 IrInstSrc *target_value_ptr, IrInstSrc **prong_values, size_t prong_values_len, 9023 ZigList<IrBasicBlockSrc *> *incoming_blocks, ZigList<IrInstSrc *> *incoming_values, 9024 IrInstSrcSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc) 9025 { 9026 assert(switch_node->type == NodeTypeSwitchExpr); 9027 assert(prong_node->type == NodeTypeSwitchProng); 9028 9029 AstNode *expr_node = prong_node->data.switch_prong.expr; 9030 AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol; 9031 Scope *child_scope; 9032 if (var_symbol_node) { 9033 assert(var_symbol_node->type == NodeTypeSymbol); 9034 Buf *var_name = var_symbol_node->data.symbol_expr.symbol; 9035 bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr; 9036 9037 bool is_shadowable = false; 9038 bool is_const = true; 9039 ZigVar *var = ir_create_var(irb, var_symbol_node, scope, 9040 var_name, is_const, is_const, is_shadowable, var_is_comptime); 9041 child_scope = var->child_scope; 9042 IrInstSrc *var_value; 9043 if (out_switch_else_var != nullptr) { 9044 IrInstSrcSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node, 9045 target_value_ptr); 9046 *out_switch_else_var = switch_else_var; 9047 IrInstSrc *payload_ptr = &switch_else_var->base; 9048 var_value = var_is_ptr ? 9049 payload_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, payload_ptr); 9050 } else if (prong_values != nullptr) { 9051 IrInstSrc *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, 9052 prong_values, prong_values_len); 9053 var_value = var_is_ptr ? 9054 payload_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, payload_ptr); 9055 } else { 9056 var_value = var_is_ptr ? 9057 target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr); 9058 } 9059 build_decl_var_and_init(irb, scope, var_symbol_node, var, var_value, buf_ptr(var_name), var_is_comptime); 9060 } else { 9061 child_scope = scope; 9062 } 9063 9064 IrInstSrc *expr_result = ir_gen_node_extra(irb, expr_node, child_scope, lval, result_loc); 9065 if (expr_result == irb->codegen->invalid_inst_src) 9066 return false; 9067 if (!instr_is_unreachable(expr_result)) 9068 ir_mark_gen(ir_build_br(irb, scope, switch_node, end_block, is_comptime)); 9069 incoming_blocks->append(irb->current_basic_block); 9070 incoming_values->append(expr_result); 9071 return true; 9072 } 9073 9074 static IrInstSrc *ir_gen_switch_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 9075 ResultLoc *result_loc) 9076 { 9077 assert(node->type == NodeTypeSwitchExpr); 9078 9079 AstNode *target_node = node->data.switch_expr.expr; 9080 IrInstSrc *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr, nullptr); 9081 if (target_value_ptr == irb->codegen->invalid_inst_src) 9082 return target_value_ptr; 9083 IrInstSrc *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); 9084 9085 IrBasicBlockSrc *else_block = ir_create_basic_block(irb, scope, "SwitchElse"); 9086 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, scope, "SwitchEnd"); 9087 9088 size_t prong_count = node->data.switch_expr.prongs.length; 9089 ZigList<IrInstSrcSwitchBrCase> cases = {0}; 9090 9091 IrInstSrc *is_comptime; 9092 IrInstSrc *var_is_comptime; 9093 if (ir_should_inline(irb->exec, scope)) { 9094 is_comptime = ir_build_const_bool(irb, scope, node, true); 9095 var_is_comptime = is_comptime; 9096 } else { 9097 is_comptime = ir_build_test_comptime(irb, scope, node, target_value); 9098 var_is_comptime = ir_build_test_comptime(irb, scope, node, target_value_ptr); 9099 } 9100 9101 ZigList<IrInstSrc *> incoming_values = {0}; 9102 ZigList<IrBasicBlockSrc *> incoming_blocks = {0}; 9103 ZigList<IrInstSrcCheckSwitchProngsRange> check_ranges = {0}; 9104 9105 IrInstSrcSwitchElseVar *switch_else_var = nullptr; 9106 9107 ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>(); 9108 peer_parent->base.id = ResultLocIdPeerParent; 9109 peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const; 9110 peer_parent->end_bb = end_block; 9111 peer_parent->is_comptime = is_comptime; 9112 peer_parent->parent = result_loc; 9113 9114 ir_build_reset_result(irb, scope, node, &peer_parent->base); 9115 9116 // First do the else and the ranges 9117 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 9118 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 9119 AstNode *else_prong = nullptr; 9120 AstNode *underscore_prong = nullptr; 9121 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 9122 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 9123 size_t prong_item_count = prong_node->data.switch_prong.items.length; 9124 if (prong_node->data.switch_prong.any_items_are_range) { 9125 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 9126 9127 IrInstSrc *ok_bit = nullptr; 9128 AstNode *last_item_node = nullptr; 9129 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 9130 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 9131 last_item_node = item_node; 9132 if (item_node->type == NodeTypeSwitchRange) { 9133 AstNode *start_node = item_node->data.switch_range.start; 9134 AstNode *end_node = item_node->data.switch_range.end; 9135 9136 IrInstSrc *start_value = ir_gen_node(irb, start_node, comptime_scope); 9137 if (start_value == irb->codegen->invalid_inst_src) 9138 return irb->codegen->invalid_inst_src; 9139 9140 IrInstSrc *end_value = ir_gen_node(irb, end_node, comptime_scope); 9141 if (end_value == irb->codegen->invalid_inst_src) 9142 return irb->codegen->invalid_inst_src; 9143 9144 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one(); 9145 check_range->start = start_value; 9146 check_range->end = end_value; 9147 9148 IrInstSrc *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq, 9149 target_value, start_value, false); 9150 IrInstSrc *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq, 9151 target_value, end_value, false); 9152 IrInstSrc *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd, 9153 lower_range_ok, upper_range_ok, false); 9154 if (ok_bit) { 9155 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false); 9156 } else { 9157 ok_bit = both_ok; 9158 } 9159 } else { 9160 IrInstSrc *item_value = ir_gen_node(irb, item_node, comptime_scope); 9161 if (item_value == irb->codegen->invalid_inst_src) 9162 return irb->codegen->invalid_inst_src; 9163 9164 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one(); 9165 check_range->start = item_value; 9166 check_range->end = item_value; 9167 9168 IrInstSrc *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq, 9169 item_value, target_value, false); 9170 if (ok_bit) { 9171 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false); 9172 } else { 9173 ok_bit = cmp_ok; 9174 } 9175 } 9176 } 9177 9178 IrBasicBlockSrc *range_block_yes = ir_create_basic_block(irb, scope, "SwitchRangeYes"); 9179 IrBasicBlockSrc *range_block_no = ir_create_basic_block(irb, scope, "SwitchRangeNo"); 9180 9181 assert(ok_bit); 9182 assert(last_item_node); 9183 IrInstSrc *br_inst = ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, 9184 range_block_yes, range_block_no, is_comptime)); 9185 if (peer_parent->base.source_instruction == nullptr) { 9186 peer_parent->base.source_instruction = br_inst; 9187 } 9188 9189 if (peer_parent->peers.length > 0) { 9190 peer_parent->peers.last()->next_bb = range_block_yes; 9191 } 9192 peer_parent->peers.append(this_peer_result_loc); 9193 ir_set_cursor_at_end_and_append_block(irb, range_block_yes); 9194 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 9195 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, 9196 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) 9197 { 9198 return irb->codegen->invalid_inst_src; 9199 } 9200 9201 ir_set_cursor_at_end_and_append_block(irb, range_block_no); 9202 } else { 9203 if (prong_item_count == 0) { 9204 if (else_prong) { 9205 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 9206 buf_sprintf("multiple else prongs in switch expression")); 9207 add_error_note(irb->codegen, msg, else_prong, 9208 buf_sprintf("previous else prong is here")); 9209 return irb->codegen->invalid_inst_src; 9210 } 9211 else_prong = prong_node; 9212 } else if (prong_item_count == 1 && 9213 prong_node->data.switch_prong.items.at(0)->type == NodeTypeSymbol && 9214 buf_eql_str(prong_node->data.switch_prong.items.at(0)->data.symbol_expr.symbol, "_")) { 9215 if (underscore_prong) { 9216 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 9217 buf_sprintf("multiple '_' prongs in switch expression")); 9218 add_error_note(irb->codegen, msg, underscore_prong, 9219 buf_sprintf("previous '_' prong is here")); 9220 return irb->codegen->invalid_inst_src; 9221 } 9222 underscore_prong = prong_node; 9223 } else { 9224 continue; 9225 } 9226 if (underscore_prong && else_prong) { 9227 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 9228 buf_sprintf("else and '_' prong in switch expression")); 9229 if (underscore_prong == prong_node) 9230 add_error_note(irb->codegen, msg, else_prong, 9231 buf_sprintf("else prong is here")); 9232 else 9233 add_error_note(irb->codegen, msg, underscore_prong, 9234 buf_sprintf("'_' prong is here")); 9235 return irb->codegen->invalid_inst_src; 9236 } 9237 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 9238 9239 IrBasicBlockSrc *prev_block = irb->current_basic_block; 9240 if (peer_parent->peers.length > 0) { 9241 peer_parent->peers.last()->next_bb = else_block; 9242 } 9243 peer_parent->peers.append(this_peer_result_loc); 9244 ir_set_cursor_at_end_and_append_block(irb, else_block); 9245 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 9246 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, 9247 &switch_else_var, LValNone, &this_peer_result_loc->base)) 9248 { 9249 return irb->codegen->invalid_inst_src; 9250 } 9251 ir_set_cursor_at_end(irb, prev_block); 9252 } 9253 } 9254 9255 // next do the non-else non-ranges 9256 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 9257 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 9258 size_t prong_item_count = prong_node->data.switch_prong.items.length; 9259 if (prong_item_count == 0) 9260 continue; 9261 if (prong_node->data.switch_prong.any_items_are_range) 9262 continue; 9263 if (underscore_prong == prong_node) 9264 continue; 9265 9266 ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent); 9267 9268 IrBasicBlockSrc *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); 9269 IrInstSrc **items = heap::c_allocator.allocate<IrInstSrc *>(prong_item_count); 9270 9271 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 9272 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 9273 assert(item_node->type != NodeTypeSwitchRange); 9274 9275 IrInstSrc *item_value = ir_gen_node(irb, item_node, comptime_scope); 9276 if (item_value == irb->codegen->invalid_inst_src) 9277 return irb->codegen->invalid_inst_src; 9278 9279 IrInstSrcCheckSwitchProngsRange *check_range = check_ranges.add_one(); 9280 check_range->start = item_value; 9281 check_range->end = item_value; 9282 9283 IrInstSrcSwitchBrCase *this_case = cases.add_one(); 9284 this_case->value = item_value; 9285 this_case->block = prong_block; 9286 9287 items[item_i] = item_value; 9288 } 9289 9290 IrBasicBlockSrc *prev_block = irb->current_basic_block; 9291 if (peer_parent->peers.length > 0) { 9292 peer_parent->peers.last()->next_bb = prong_block; 9293 } 9294 peer_parent->peers.append(this_peer_result_loc); 9295 ir_set_cursor_at_end_and_append_block(irb, prong_block); 9296 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 9297 is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, 9298 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) 9299 { 9300 return irb->codegen->invalid_inst_src; 9301 } 9302 9303 ir_set_cursor_at_end(irb, prev_block); 9304 9305 } 9306 9307 IrInstSrc *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, 9308 check_ranges.items, check_ranges.length, else_prong != nullptr, underscore_prong != nullptr); 9309 9310 IrInstSrc *br_instruction; 9311 if (cases.length == 0) { 9312 br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime); 9313 } else { 9314 IrInstSrcSwitchBr *switch_br = ir_build_switch_br_src(irb, scope, node, target_value, else_block, 9315 cases.length, cases.items, is_comptime, switch_prongs_void); 9316 if (switch_else_var != nullptr) { 9317 switch_else_var->switch_br = switch_br; 9318 } 9319 br_instruction = &switch_br->base; 9320 } 9321 if (peer_parent->base.source_instruction == nullptr) { 9322 peer_parent->base.source_instruction = br_instruction; 9323 } 9324 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 9325 peer_parent->peers.at(i)->base.source_instruction = peer_parent->base.source_instruction; 9326 } 9327 9328 if (!else_prong && !underscore_prong) { 9329 if (peer_parent->peers.length != 0) { 9330 peer_parent->peers.last()->next_bb = else_block; 9331 } 9332 ir_set_cursor_at_end_and_append_block(irb, else_block); 9333 ir_build_unreachable(irb, scope, node); 9334 } else { 9335 if (peer_parent->peers.length != 0) { 9336 peer_parent->peers.last()->next_bb = end_block; 9337 } 9338 } 9339 9340 ir_set_cursor_at_end_and_append_block(irb, end_block); 9341 assert(incoming_blocks.length == incoming_values.length); 9342 IrInstSrc *result_instruction; 9343 if (incoming_blocks.length == 0) { 9344 result_instruction = ir_build_const_void(irb, scope, node); 9345 } else { 9346 result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length, 9347 incoming_blocks.items, incoming_values.items, peer_parent); 9348 } 9349 return ir_lval_wrap(irb, scope, result_instruction, lval, result_loc); 9350 } 9351 9352 static IrInstSrc *ir_gen_comptime(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) { 9353 assert(node->type == NodeTypeCompTime); 9354 9355 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); 9356 // purposefully pass null for result_loc and let EndExpr handle it 9357 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); 9358 } 9359 9360 static IrInstSrc *ir_gen_nosuspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval) { 9361 assert(node->type == NodeTypeNoSuspend); 9362 9363 Scope *child_scope = create_nosuspend_scope(irb->codegen, node, parent_scope); 9364 // purposefully pass null for result_loc and let EndExpr handle it 9365 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval, nullptr); 9366 } 9367 9368 static IrInstSrc *ir_gen_return_from_block(IrBuilderSrc *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { 9369 IrInstSrc *is_comptime; 9370 if (ir_should_inline(irb->exec, break_scope)) { 9371 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 9372 } else { 9373 is_comptime = block_scope->is_comptime; 9374 } 9375 9376 IrInstSrc *result_value; 9377 if (node->data.break_expr.expr) { 9378 ResultLocPeer *peer_result = create_peer_result(block_scope->peer_parent); 9379 block_scope->peer_parent->peers.append(peer_result); 9380 9381 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, block_scope->lval, 9382 &peer_result->base); 9383 if (result_value == irb->codegen->invalid_inst_src) 9384 return irb->codegen->invalid_inst_src; 9385 } else { 9386 result_value = ir_build_const_void(irb, break_scope, node); 9387 } 9388 9389 IrBasicBlockSrc *dest_block = block_scope->end_block; 9390 if (!ir_gen_defers_for_block(irb, break_scope, dest_block->scope, nullptr, nullptr)) 9391 return irb->codegen->invalid_inst_src; 9392 9393 block_scope->incoming_blocks->append(irb->current_basic_block); 9394 block_scope->incoming_values->append(result_value); 9395 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 9396 } 9397 9398 static IrInstSrc *ir_gen_break(IrBuilderSrc *irb, Scope *break_scope, AstNode *node) { 9399 assert(node->type == NodeTypeBreak); 9400 9401 // Search up the scope. We'll find one of these things first: 9402 // * function definition scope or global scope => error, break outside loop 9403 // * defer expression scope => error, cannot break out of defer expression 9404 // * loop scope => OK 9405 // * (if it's a labeled break) labeled block => OK 9406 9407 Scope *search_scope = break_scope; 9408 ScopeLoop *loop_scope; 9409 for (;;) { 9410 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 9411 if (node->data.break_expr.name != nullptr) { 9412 add_node_error(irb->codegen, node, buf_sprintf("label not found: '%s'", buf_ptr(node->data.break_expr.name))); 9413 return irb->codegen->invalid_inst_src; 9414 } else { 9415 add_node_error(irb->codegen, node, buf_sprintf("break expression outside loop")); 9416 return irb->codegen->invalid_inst_src; 9417 } 9418 } else if (search_scope->id == ScopeIdDeferExpr) { 9419 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of defer expression")); 9420 return irb->codegen->invalid_inst_src; 9421 } else if (search_scope->id == ScopeIdLoop) { 9422 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 9423 if (node->data.break_expr.name == nullptr || 9424 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name))) 9425 { 9426 loop_scope = this_loop_scope; 9427 break; 9428 } 9429 } else if (search_scope->id == ScopeIdBlock) { 9430 ScopeBlock *this_block_scope = (ScopeBlock *)search_scope; 9431 if (node->data.break_expr.name != nullptr && 9432 (this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name))) 9433 { 9434 assert(this_block_scope->end_block != nullptr); 9435 return ir_gen_return_from_block(irb, break_scope, node, this_block_scope); 9436 } 9437 } else if (search_scope->id == ScopeIdSuspend) { 9438 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of suspend block")); 9439 return irb->codegen->invalid_inst_src; 9440 } 9441 search_scope = search_scope->parent; 9442 } 9443 9444 IrInstSrc *is_comptime; 9445 if (ir_should_inline(irb->exec, break_scope)) { 9446 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 9447 } else { 9448 is_comptime = loop_scope->is_comptime; 9449 } 9450 9451 IrInstSrc *result_value; 9452 if (node->data.break_expr.expr) { 9453 ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent); 9454 loop_scope->peer_parent->peers.append(peer_result); 9455 9456 result_value = ir_gen_node_extra(irb, node->data.break_expr.expr, break_scope, 9457 loop_scope->lval, &peer_result->base); 9458 if (result_value == irb->codegen->invalid_inst_src) 9459 return irb->codegen->invalid_inst_src; 9460 } else { 9461 result_value = ir_build_const_void(irb, break_scope, node); 9462 } 9463 9464 IrBasicBlockSrc *dest_block = loop_scope->break_block; 9465 if (!ir_gen_defers_for_block(irb, break_scope, dest_block->scope, nullptr, nullptr)) 9466 return irb->codegen->invalid_inst_src; 9467 9468 loop_scope->incoming_blocks->append(irb->current_basic_block); 9469 loop_scope->incoming_values->append(result_value); 9470 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 9471 } 9472 9473 static IrInstSrc *ir_gen_continue(IrBuilderSrc *irb, Scope *continue_scope, AstNode *node) { 9474 assert(node->type == NodeTypeContinue); 9475 9476 // Search up the scope. We'll find one of these things first: 9477 // * function definition scope or global scope => error, break outside loop 9478 // * defer expression scope => error, cannot break out of defer expression 9479 // * loop scope => OK 9480 9481 ZigList<ScopeRuntime *> runtime_scopes = {}; 9482 9483 Scope *search_scope = continue_scope; 9484 ScopeLoop *loop_scope; 9485 for (;;) { 9486 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 9487 if (node->data.continue_expr.name != nullptr) { 9488 add_node_error(irb->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.continue_expr.name))); 9489 return irb->codegen->invalid_inst_src; 9490 } else { 9491 add_node_error(irb->codegen, node, buf_sprintf("continue expression outside loop")); 9492 return irb->codegen->invalid_inst_src; 9493 } 9494 } else if (search_scope->id == ScopeIdDeferExpr) { 9495 add_node_error(irb->codegen, node, buf_sprintf("cannot continue out of defer expression")); 9496 return irb->codegen->invalid_inst_src; 9497 } else if (search_scope->id == ScopeIdLoop) { 9498 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 9499 if (node->data.continue_expr.name == nullptr || 9500 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name))) 9501 { 9502 loop_scope = this_loop_scope; 9503 break; 9504 } 9505 } else if (search_scope->id == ScopeIdRuntime) { 9506 ScopeRuntime *scope_runtime = (ScopeRuntime *)search_scope; 9507 runtime_scopes.append(scope_runtime); 9508 } 9509 search_scope = search_scope->parent; 9510 } 9511 9512 IrInstSrc *is_comptime; 9513 if (ir_should_inline(irb->exec, continue_scope)) { 9514 is_comptime = ir_build_const_bool(irb, continue_scope, node, true); 9515 } else { 9516 is_comptime = loop_scope->is_comptime; 9517 } 9518 9519 for (size_t i = 0; i < runtime_scopes.length; i += 1) { 9520 ScopeRuntime *scope_runtime = runtime_scopes.at(i); 9521 ir_mark_gen(ir_build_check_runtime_scope(irb, continue_scope, node, scope_runtime->is_comptime, is_comptime)); 9522 } 9523 9524 IrBasicBlockSrc *dest_block = loop_scope->continue_block; 9525 if (!ir_gen_defers_for_block(irb, continue_scope, dest_block->scope, nullptr, nullptr)) 9526 return irb->codegen->invalid_inst_src; 9527 return ir_mark_gen(ir_build_br(irb, continue_scope, node, dest_block, is_comptime)); 9528 } 9529 9530 static IrInstSrc *ir_gen_error_type(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 9531 assert(node->type == NodeTypeErrorType); 9532 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_global_error_set); 9533 } 9534 9535 static IrInstSrc *ir_gen_defer(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 9536 assert(node->type == NodeTypeDefer); 9537 9538 ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope); 9539 node->data.defer.child_scope = &defer_child_scope->base; 9540 9541 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(irb->codegen, node, parent_scope); 9542 node->data.defer.expr_scope = &defer_expr_scope->base; 9543 9544 return ir_build_const_void(irb, parent_scope, node); 9545 } 9546 9547 static IrInstSrc *ir_gen_slice(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { 9548 assert(node->type == NodeTypeSliceExpr); 9549 9550 AstNodeSliceExpr *slice_expr = &node->data.slice_expr; 9551 AstNode *array_node = slice_expr->array_ref_expr; 9552 AstNode *start_node = slice_expr->start; 9553 AstNode *end_node = slice_expr->end; 9554 AstNode *sentinel_node = slice_expr->sentinel; 9555 9556 IrInstSrc *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr, nullptr); 9557 if (ptr_value == irb->codegen->invalid_inst_src) 9558 return irb->codegen->invalid_inst_src; 9559 9560 IrInstSrc *start_value = ir_gen_node(irb, start_node, scope); 9561 if (start_value == irb->codegen->invalid_inst_src) 9562 return irb->codegen->invalid_inst_src; 9563 9564 IrInstSrc *end_value; 9565 if (end_node) { 9566 end_value = ir_gen_node(irb, end_node, scope); 9567 if (end_value == irb->codegen->invalid_inst_src) 9568 return irb->codegen->invalid_inst_src; 9569 } else { 9570 end_value = nullptr; 9571 } 9572 9573 IrInstSrc *sentinel_value; 9574 if (sentinel_node) { 9575 sentinel_value = ir_gen_node(irb, sentinel_node, scope); 9576 if (sentinel_value == irb->codegen->invalid_inst_src) 9577 return irb->codegen->invalid_inst_src; 9578 } else { 9579 sentinel_value = nullptr; 9580 } 9581 9582 IrInstSrc *slice = ir_build_slice_src(irb, scope, node, ptr_value, start_value, end_value, 9583 sentinel_value, true, result_loc); 9584 return ir_lval_wrap(irb, scope, slice, lval, result_loc); 9585 } 9586 9587 static IrInstSrc *ir_gen_catch(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node, LVal lval, 9588 ResultLoc *result_loc) 9589 { 9590 assert(node->type == NodeTypeCatchExpr); 9591 9592 AstNode *op1_node = node->data.unwrap_err_expr.op1; 9593 AstNode *op2_node = node->data.unwrap_err_expr.op2; 9594 AstNode *var_node = node->data.unwrap_err_expr.symbol; 9595 9596 if (op2_node->type == NodeTypeUnreachable) { 9597 if (var_node != nullptr) { 9598 assert(var_node->type == NodeTypeSymbol); 9599 Buf *var_name = var_node->data.symbol_expr.symbol; 9600 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); 9601 return irb->codegen->invalid_inst_src; 9602 } 9603 return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, lval, result_loc); 9604 } 9605 9606 9607 ScopeExpr *spill_scope = create_expr_scope(irb->codegen, op1_node, parent_scope); 9608 spill_scope->spill_harder = true; 9609 9610 IrInstSrc *err_union_ptr = ir_gen_node_extra(irb, op1_node, &spill_scope->base, LValPtr, nullptr); 9611 if (err_union_ptr == irb->codegen->invalid_inst_src) 9612 return irb->codegen->invalid_inst_src; 9613 9614 IrInstSrc *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr, true, false); 9615 9616 IrInstSrc *is_comptime; 9617 if (ir_should_inline(irb->exec, parent_scope)) { 9618 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 9619 } else { 9620 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_err); 9621 } 9622 9623 IrBasicBlockSrc *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); 9624 IrBasicBlockSrc *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); 9625 IrBasicBlockSrc *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); 9626 IrInstSrc *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); 9627 9628 ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(irb, cond_br_inst, ok_block, end_block, result_loc, 9629 is_comptime); 9630 9631 ir_set_cursor_at_end_and_append_block(irb, err_block); 9632 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, &spill_scope->base, is_comptime); 9633 Scope *err_scope; 9634 if (var_node) { 9635 assert(var_node->type == NodeTypeSymbol); 9636 Buf *var_name = var_node->data.symbol_expr.symbol; 9637 bool is_const = true; 9638 bool is_shadowable = false; 9639 ZigVar *var = ir_create_var(irb, node, subexpr_scope, var_name, 9640 is_const, is_const, is_shadowable, is_comptime); 9641 err_scope = var->child_scope; 9642 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, node, err_union_ptr); 9643 IrInstSrc *err_value = ir_build_load_ptr(irb, err_scope, var_node, err_ptr); 9644 build_decl_var_and_init(irb, err_scope, var_node, var, err_value, buf_ptr(var_name), is_comptime); 9645 } else { 9646 err_scope = subexpr_scope; 9647 } 9648 IrInstSrc *err_result = ir_gen_node_extra(irb, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base); 9649 if (err_result == irb->codegen->invalid_inst_src) 9650 return irb->codegen->invalid_inst_src; 9651 IrBasicBlockSrc *after_err_block = irb->current_basic_block; 9652 if (!instr_is_unreachable(err_result)) 9653 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 9654 9655 ir_set_cursor_at_end_and_append_block(irb, ok_block); 9656 IrInstSrc *unwrapped_ptr = ir_build_unwrap_err_payload_src(irb, parent_scope, node, err_union_ptr, false, false); 9657 IrInstSrc *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 9658 ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base); 9659 IrBasicBlockSrc *after_ok_block = irb->current_basic_block; 9660 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 9661 9662 ir_set_cursor_at_end_and_append_block(irb, end_block); 9663 IrInstSrc **incoming_values = heap::c_allocator.allocate<IrInstSrc *>(2); 9664 incoming_values[0] = err_result; 9665 incoming_values[1] = unwrapped_payload; 9666 IrBasicBlockSrc **incoming_blocks = heap::c_allocator.allocate<IrBasicBlockSrc *>(2); 9667 incoming_blocks[0] = after_err_block; 9668 incoming_blocks[1] = after_ok_block; 9669 IrInstSrc *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent); 9670 return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); 9671 } 9672 9673 static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) { 9674 if (inner_scope == nullptr || inner_scope == outer_scope) return false; 9675 bool need_comma = render_instance_name_recursive(codegen, name, outer_scope, inner_scope->parent); 9676 if (inner_scope->id != ScopeIdVarDecl) 9677 return need_comma; 9678 9679 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; 9680 if (need_comma) 9681 buf_append_char(name, ','); 9682 // TODO: const ptr reinterpret here to make the var type agree with the value? 9683 render_const_value(codegen, name, var_scope->var->const_value); 9684 return true; 9685 } 9686 9687 static Buf *get_anon_type_name(CodeGen *codegen, IrExecutableSrc *exec, const char *kind_name, 9688 Scope *scope, AstNode *source_node, Buf *out_bare_name) 9689 { 9690 if (exec != nullptr && exec->name) { 9691 ZigType *import = get_scope_import(scope); 9692 Buf *namespace_name = buf_alloc(); 9693 append_namespace_qualification(codegen, namespace_name, import); 9694 buf_append_buf(namespace_name, exec->name); 9695 buf_init_from_buf(out_bare_name, exec->name); 9696 return namespace_name; 9697 } else if (exec != nullptr && exec->name_fn != nullptr) { 9698 Buf *name = buf_alloc(); 9699 buf_append_buf(name, &exec->name_fn->symbol_name); 9700 buf_appendf(name, "("); 9701 render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope); 9702 buf_appendf(name, ")"); 9703 buf_init_from_buf(out_bare_name, name); 9704 return name; 9705 } else { 9706 ZigType *import = get_scope_import(scope); 9707 Buf *namespace_name = buf_alloc(); 9708 append_namespace_qualification(codegen, namespace_name, import); 9709 buf_appendf(namespace_name, "%s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, kind_name, 9710 source_node->line + 1, source_node->column + 1); 9711 buf_init_from_buf(out_bare_name, namespace_name); 9712 return namespace_name; 9713 } 9714 } 9715 9716 static IrInstSrc *ir_gen_container_decl(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 9717 assert(node->type == NodeTypeContainerDecl); 9718 9719 ContainerKind kind = node->data.container_decl.kind; 9720 Buf *bare_name = buf_alloc(); 9721 Buf *name = get_anon_type_name(irb->codegen, irb->exec, container_string(kind), parent_scope, node, bare_name); 9722 9723 ContainerLayout layout = node->data.container_decl.layout; 9724 ZigType *container_type = get_partial_container_type(irb->codegen, parent_scope, 9725 kind, node, buf_ptr(name), bare_name, layout); 9726 ScopeDecls *child_scope = get_container_scope(container_type); 9727 9728 for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) { 9729 AstNode *child_node = node->data.container_decl.decls.at(i); 9730 scan_decls(irb->codegen, child_scope, child_node); 9731 } 9732 9733 TldContainer *tld_container = heap::c_allocator.create<TldContainer>(); 9734 init_tld(&tld_container->base, TldIdContainer, bare_name, VisibModPub, node, parent_scope); 9735 tld_container->type_entry = container_type; 9736 tld_container->decls_scope = child_scope; 9737 irb->codegen->resolve_queue.append(&tld_container->base); 9738 9739 // Add this to the list to mark as invalid if analyzing this exec fails. 9740 irb->exec->tld_list.append(&tld_container->base); 9741 9742 return ir_build_const_type(irb, parent_scope, node, container_type); 9743 } 9744 9745 // errors should be populated with set1's values 9746 static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigType *set1, ZigType *set2, 9747 Buf *type_name) 9748 { 9749 assert(set1->id == ZigTypeIdErrorSet); 9750 assert(set2->id == ZigTypeIdErrorSet); 9751 9752 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 9753 err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits; 9754 err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align; 9755 err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size; 9756 if (type_name == nullptr) { 9757 buf_resize(&err_set_type->name, 0); 9758 buf_appendf(&err_set_type->name, "error{"); 9759 } else { 9760 buf_init_from_buf(&err_set_type->name, type_name); 9761 } 9762 9763 for (uint32_t i = 0, count = set1->data.error_set.err_count; i < count; i += 1) { 9764 assert(errors[set1->data.error_set.errors[i]->value] == set1->data.error_set.errors[i]); 9765 } 9766 9767 uint32_t count = set1->data.error_set.err_count; 9768 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 9769 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 9770 if (errors[error_entry->value] == nullptr) { 9771 count += 1; 9772 } 9773 } 9774 9775 err_set_type->data.error_set.err_count = count; 9776 err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(count); 9777 9778 bool need_comma = false; 9779 for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { 9780 ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; 9781 if (type_name == nullptr) { 9782 const char *comma = need_comma ? "," : ""; 9783 need_comma = true; 9784 buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&error_entry->name)); 9785 } 9786 err_set_type->data.error_set.errors[i] = error_entry; 9787 } 9788 9789 uint32_t index = set1->data.error_set.err_count; 9790 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 9791 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 9792 if (errors[error_entry->value] == nullptr) { 9793 errors[error_entry->value] = error_entry; 9794 if (type_name == nullptr) { 9795 const char *comma = need_comma ? "," : ""; 9796 need_comma = true; 9797 buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&error_entry->name)); 9798 } 9799 err_set_type->data.error_set.errors[index] = error_entry; 9800 index += 1; 9801 } 9802 } 9803 assert(index == count); 9804 9805 if (type_name == nullptr) { 9806 buf_appendf(&err_set_type->name, "}"); 9807 } 9808 9809 return err_set_type; 9810 9811 } 9812 9813 static ZigType *make_err_set_with_one_item(CodeGen *g, Scope *parent_scope, AstNode *node, 9814 ErrorTableEntry *err_entry) 9815 { 9816 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 9817 buf_resize(&err_set_type->name, 0); 9818 buf_appendf(&err_set_type->name, "error{%s}", buf_ptr(&err_entry->name)); 9819 err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits; 9820 err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align; 9821 err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size; 9822 err_set_type->data.error_set.err_count = 1; 9823 err_set_type->data.error_set.errors = heap::c_allocator.create<ErrorTableEntry *>(); 9824 9825 err_set_type->data.error_set.errors[0] = err_entry; 9826 9827 return err_set_type; 9828 } 9829 9830 static AstNode *ast_field_to_symbol_node(AstNode *err_set_field_node) { 9831 if (err_set_field_node->type == NodeTypeSymbol) { 9832 return err_set_field_node; 9833 } else if (err_set_field_node->type == NodeTypeErrorSetField) { 9834 assert(err_set_field_node->data.err_set_field.field_name->type == NodeTypeSymbol); 9835 return err_set_field_node->data.err_set_field.field_name; 9836 } else { 9837 return err_set_field_node; 9838 } 9839 } 9840 9841 static IrInstSrc *ir_gen_err_set_decl(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 9842 assert(node->type == NodeTypeErrorSetDecl); 9843 9844 uint32_t err_count = node->data.err_set_decl.decls.length; 9845 9846 Buf bare_name = BUF_INIT; 9847 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error", parent_scope, node, &bare_name); 9848 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 9849 buf_init_from_buf(&err_set_type->name, type_name); 9850 err_set_type->data.error_set.err_count = err_count; 9851 err_set_type->size_in_bits = irb->codegen->builtin_types.entry_global_error_set->size_in_bits; 9852 err_set_type->abi_align = irb->codegen->builtin_types.entry_global_error_set->abi_align; 9853 err_set_type->abi_size = irb->codegen->builtin_types.entry_global_error_set->abi_size; 9854 err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(err_count); 9855 9856 size_t errors_count = irb->codegen->errors_by_index.length + err_count; 9857 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count); 9858 9859 for (uint32_t i = 0; i < err_count; i += 1) { 9860 AstNode *field_node = node->data.err_set_decl.decls.at(i); 9861 AstNode *symbol_node = ast_field_to_symbol_node(field_node); 9862 Buf *err_name = symbol_node->data.symbol_expr.symbol; 9863 ErrorTableEntry *err = heap::c_allocator.create<ErrorTableEntry>(); 9864 err->decl_node = field_node; 9865 buf_init_from_buf(&err->name, err_name); 9866 9867 auto existing_entry = irb->codegen->error_table.put_unique(err_name, err); 9868 if (existing_entry) { 9869 err->value = existing_entry->value->value; 9870 } else { 9871 size_t error_value_count = irb->codegen->errors_by_index.length; 9872 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)irb->codegen->err_tag_type->data.integral.bit_count)); 9873 err->value = error_value_count; 9874 irb->codegen->errors_by_index.append(err); 9875 } 9876 err_set_type->data.error_set.errors[i] = err; 9877 9878 ErrorTableEntry *prev_err = errors[err->value]; 9879 if (prev_err != nullptr) { 9880 ErrorMsg *msg = add_node_error(irb->codegen, ast_field_to_symbol_node(err->decl_node), 9881 buf_sprintf("duplicate error: '%s'", buf_ptr(&err->name))); 9882 add_error_note(irb->codegen, msg, ast_field_to_symbol_node(prev_err->decl_node), 9883 buf_sprintf("other error here")); 9884 return irb->codegen->invalid_inst_src; 9885 } 9886 errors[err->value] = err; 9887 } 9888 heap::c_allocator.deallocate(errors, errors_count); 9889 return ir_build_const_type(irb, parent_scope, node, err_set_type); 9890 } 9891 9892 static IrInstSrc *ir_gen_fn_proto(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 9893 assert(node->type == NodeTypeFnProto); 9894 9895 size_t param_count = node->data.fn_proto.params.length; 9896 IrInstSrc **param_types = heap::c_allocator.allocate<IrInstSrc*>(param_count); 9897 9898 bool is_var_args = false; 9899 for (size_t i = 0; i < param_count; i += 1) { 9900 AstNode *param_node = node->data.fn_proto.params.at(i); 9901 if (param_node->data.param_decl.is_var_args) { 9902 is_var_args = true; 9903 break; 9904 } 9905 if (param_node->data.param_decl.var_token == nullptr) { 9906 AstNode *type_node = param_node->data.param_decl.type; 9907 IrInstSrc *type_value = ir_gen_node(irb, type_node, parent_scope); 9908 if (type_value == irb->codegen->invalid_inst_src) 9909 return irb->codegen->invalid_inst_src; 9910 param_types[i] = type_value; 9911 } else { 9912 param_types[i] = nullptr; 9913 } 9914 } 9915 9916 IrInstSrc *align_value = nullptr; 9917 if (node->data.fn_proto.align_expr != nullptr) { 9918 align_value = ir_gen_node(irb, node->data.fn_proto.align_expr, parent_scope); 9919 if (align_value == irb->codegen->invalid_inst_src) 9920 return irb->codegen->invalid_inst_src; 9921 } 9922 9923 IrInstSrc *callconv_value = nullptr; 9924 if (node->data.fn_proto.callconv_expr != nullptr) { 9925 callconv_value = ir_gen_node(irb, node->data.fn_proto.callconv_expr, parent_scope); 9926 if (callconv_value == irb->codegen->invalid_inst_src) 9927 return irb->codegen->invalid_inst_src; 9928 } 9929 9930 IrInstSrc *return_type; 9931 if (node->data.fn_proto.return_var_token == nullptr) { 9932 if (node->data.fn_proto.return_type == nullptr) { 9933 return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void); 9934 } else { 9935 return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope); 9936 if (return_type == irb->codegen->invalid_inst_src) 9937 return irb->codegen->invalid_inst_src; 9938 } 9939 } else { 9940 add_node_error(irb->codegen, node, 9941 buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447")); 9942 return irb->codegen->invalid_inst_src; 9943 //return_type = nullptr; 9944 } 9945 9946 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, callconv_value, return_type, is_var_args); 9947 } 9948 9949 static IrInstSrc *ir_gen_resume(IrBuilderSrc *irb, Scope *scope, AstNode *node) { 9950 assert(node->type == NodeTypeResume); 9951 if (get_scope_nosuspend(scope) != nullptr) { 9952 add_node_error(irb->codegen, node, buf_sprintf("resume in nosuspend scope")); 9953 return irb->codegen->invalid_inst_src; 9954 } 9955 9956 IrInstSrc *target_inst = ir_gen_node_extra(irb, node->data.resume_expr.expr, scope, LValPtr, nullptr); 9957 if (target_inst == irb->codegen->invalid_inst_src) 9958 return irb->codegen->invalid_inst_src; 9959 9960 return ir_build_resume_src(irb, scope, node, target_inst); 9961 } 9962 9963 static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *node, LVal lval, 9964 ResultLoc *result_loc) 9965 { 9966 assert(node->type == NodeTypeAwaitExpr); 9967 9968 bool is_nosuspend = get_scope_nosuspend(scope) != nullptr; 9969 9970 AstNode *expr_node = node->data.await_expr.expr; 9971 if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) { 9972 AstNode *fn_ref_expr = expr_node->data.fn_call_expr.fn_ref_expr; 9973 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 9974 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 9975 if (entry != nullptr) { 9976 BuiltinFnEntry *builtin_fn = entry->value; 9977 if (builtin_fn->id == BuiltinFnIdAsyncCall) { 9978 return ir_gen_async_call(irb, scope, node, expr_node, lval, result_loc); 9979 } 9980 } 9981 } 9982 9983 ZigFn *fn_entry = exec_fn_entry(irb->exec); 9984 if (!fn_entry) { 9985 add_node_error(irb->codegen, node, buf_sprintf("await outside function definition")); 9986 return irb->codegen->invalid_inst_src; 9987 } 9988 ScopeSuspend *existing_suspend_scope = get_scope_suspend(scope); 9989 if (existing_suspend_scope) { 9990 if (!existing_suspend_scope->reported_err) { 9991 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot await inside suspend block")); 9992 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("suspend block here")); 9993 existing_suspend_scope->reported_err = true; 9994 } 9995 return irb->codegen->invalid_inst_src; 9996 } 9997 9998 IrInstSrc *target_inst = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 9999 if (target_inst == irb->codegen->invalid_inst_src) 10000 return irb->codegen->invalid_inst_src; 10001 10002 IrInstSrc *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc, is_nosuspend); 10003 return ir_lval_wrap(irb, scope, await_inst, lval, result_loc); 10004 } 10005 10006 static IrInstSrc *ir_gen_suspend(IrBuilderSrc *irb, Scope *parent_scope, AstNode *node) { 10007 assert(node->type == NodeTypeSuspend); 10008 10009 ZigFn *fn_entry = exec_fn_entry(irb->exec); 10010 if (!fn_entry) { 10011 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition")); 10012 return irb->codegen->invalid_inst_src; 10013 } 10014 if (get_scope_nosuspend(parent_scope) != nullptr) { 10015 add_node_error(irb->codegen, node, buf_sprintf("suspend in nosuspend scope")); 10016 return irb->codegen->invalid_inst_src; 10017 } 10018 10019 ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope); 10020 if (existing_suspend_scope) { 10021 if (!existing_suspend_scope->reported_err) { 10022 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside suspend block")); 10023 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here")); 10024 existing_suspend_scope->reported_err = true; 10025 } 10026 return irb->codegen->invalid_inst_src; 10027 } 10028 10029 IrInstSrcSuspendBegin *begin = ir_build_suspend_begin_src(irb, parent_scope, node); 10030 if (node->data.suspend.block != nullptr) { 10031 ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); 10032 Scope *child_scope = &suspend_scope->base; 10033 IrInstSrc *susp_res = ir_gen_node(irb, node->data.suspend.block, child_scope); 10034 if (susp_res == irb->codegen->invalid_inst_src) 10035 return irb->codegen->invalid_inst_src; 10036 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.suspend.block, susp_res)); 10037 } 10038 10039 return ir_mark_gen(ir_build_suspend_finish_src(irb, parent_scope, node, begin)); 10040 } 10041 10042 static IrInstSrc *ir_gen_node_raw(IrBuilderSrc *irb, AstNode *node, Scope *scope, 10043 LVal lval, ResultLoc *result_loc) 10044 { 10045 assert(scope); 10046 switch (node->type) { 10047 case NodeTypeStructValueField: 10048 case NodeTypeParamDecl: 10049 case NodeTypeUsingNamespace: 10050 case NodeTypeSwitchProng: 10051 case NodeTypeSwitchRange: 10052 case NodeTypeStructField: 10053 case NodeTypeErrorSetField: 10054 case NodeTypeFnDef: 10055 case NodeTypeTestDecl: 10056 zig_unreachable(); 10057 case NodeTypeBlock: 10058 return ir_gen_block(irb, scope, node, lval, result_loc); 10059 case NodeTypeGroupedExpr: 10060 return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc); 10061 case NodeTypeBinOpExpr: 10062 return ir_gen_bin_op(irb, scope, node, lval, result_loc); 10063 case NodeTypeIntLiteral: 10064 return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval, result_loc); 10065 case NodeTypeFloatLiteral: 10066 return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval, result_loc); 10067 case NodeTypeCharLiteral: 10068 return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval, result_loc); 10069 case NodeTypeSymbol: 10070 return ir_gen_symbol(irb, scope, node, lval, result_loc); 10071 case NodeTypeFnCallExpr: 10072 return ir_gen_fn_call(irb, scope, node, lval, result_loc); 10073 case NodeTypeIfBoolExpr: 10074 return ir_gen_if_bool_expr(irb, scope, node, lval, result_loc); 10075 case NodeTypePrefixOpExpr: 10076 return ir_gen_prefix_op_expr(irb, scope, node, lval, result_loc); 10077 case NodeTypeContainerInitExpr: 10078 return ir_gen_container_init_expr(irb, scope, node, lval, result_loc); 10079 case NodeTypeVariableDeclaration: 10080 return ir_gen_var_decl(irb, scope, node); 10081 case NodeTypeWhileExpr: 10082 return ir_gen_while_expr(irb, scope, node, lval, result_loc); 10083 case NodeTypeForExpr: 10084 return ir_gen_for_expr(irb, scope, node, lval, result_loc); 10085 case NodeTypeArrayAccessExpr: 10086 return ir_gen_array_access(irb, scope, node, lval, result_loc); 10087 case NodeTypeReturnExpr: 10088 return ir_gen_return(irb, scope, node, lval, result_loc); 10089 case NodeTypeFieldAccessExpr: 10090 { 10091 IrInstSrc *ptr_instruction = ir_gen_field_access(irb, scope, node); 10092 if (ptr_instruction == irb->codegen->invalid_inst_src) 10093 return ptr_instruction; 10094 if (lval == LValPtr || lval == LValAssign) 10095 return ptr_instruction; 10096 10097 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, ptr_instruction); 10098 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 10099 } 10100 case NodeTypePtrDeref: { 10101 AstNode *expr_node = node->data.ptr_deref_expr.target; 10102 10103 LVal child_lval = lval; 10104 if (child_lval == LValAssign) 10105 child_lval = LValPtr; 10106 10107 IrInstSrc *value = ir_gen_node_extra(irb, expr_node, scope, child_lval, nullptr); 10108 if (value == irb->codegen->invalid_inst_src) 10109 return value; 10110 10111 // We essentially just converted any lvalue from &(x.*) to (&x).*; 10112 // this inhibits checking that x is a pointer later, so we directly 10113 // record whether the pointer check is needed 10114 IrInstSrc *un_op = ir_build_un_op_lval(irb, scope, node, IrUnOpDereference, value, lval, result_loc); 10115 return ir_expr_wrap(irb, scope, un_op, result_loc); 10116 } 10117 case NodeTypeUnwrapOptional: { 10118 AstNode *expr_node = node->data.unwrap_optional.expr; 10119 10120 IrInstSrc *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr); 10121 if (maybe_ptr == irb->codegen->invalid_inst_src) 10122 return irb->codegen->invalid_inst_src; 10123 10124 IrInstSrc *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, scope, node, maybe_ptr, true ); 10125 if (lval == LValPtr || lval == LValAssign) 10126 return unwrapped_ptr; 10127 10128 IrInstSrc *load_ptr = ir_build_load_ptr(irb, scope, node, unwrapped_ptr); 10129 return ir_expr_wrap(irb, scope, load_ptr, result_loc); 10130 } 10131 case NodeTypeBoolLiteral: 10132 return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval, result_loc); 10133 case NodeTypeArrayType: 10134 return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval, result_loc); 10135 case NodeTypePointerType: 10136 return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval, result_loc); 10137 case NodeTypeAnyFrameType: 10138 return ir_lval_wrap(irb, scope, ir_gen_anyframe_type(irb, scope, node), lval, result_loc); 10139 case NodeTypeStringLiteral: 10140 return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval, result_loc); 10141 case NodeTypeUndefinedLiteral: 10142 return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval, result_loc); 10143 case NodeTypeAsmExpr: 10144 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval, result_loc); 10145 case NodeTypeNullLiteral: 10146 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval, result_loc); 10147 case NodeTypeIfErrorExpr: 10148 return ir_gen_if_err_expr(irb, scope, node, lval, result_loc); 10149 case NodeTypeIfOptional: 10150 return ir_gen_if_optional_expr(irb, scope, node, lval, result_loc); 10151 case NodeTypeSwitchExpr: 10152 return ir_gen_switch_expr(irb, scope, node, lval, result_loc); 10153 case NodeTypeCompTime: 10154 return ir_expr_wrap(irb, scope, ir_gen_comptime(irb, scope, node, lval), result_loc); 10155 case NodeTypeNoSuspend: 10156 return ir_expr_wrap(irb, scope, ir_gen_nosuspend(irb, scope, node, lval), result_loc); 10157 case NodeTypeErrorType: 10158 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval, result_loc); 10159 case NodeTypeBreak: 10160 return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval, result_loc); 10161 case NodeTypeContinue: 10162 return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval, result_loc); 10163 case NodeTypeUnreachable: 10164 return ir_build_unreachable(irb, scope, node); 10165 case NodeTypeDefer: 10166 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval, result_loc); 10167 case NodeTypeSliceExpr: 10168 return ir_gen_slice(irb, scope, node, lval, result_loc); 10169 case NodeTypeCatchExpr: 10170 return ir_gen_catch(irb, scope, node, lval, result_loc); 10171 case NodeTypeContainerDecl: 10172 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval, result_loc); 10173 case NodeTypeFnProto: 10174 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval, result_loc); 10175 case NodeTypeErrorSetDecl: 10176 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval, result_loc); 10177 case NodeTypeResume: 10178 return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval, result_loc); 10179 case NodeTypeAwaitExpr: 10180 return ir_gen_await_expr(irb, scope, node, lval, result_loc); 10181 case NodeTypeSuspend: 10182 return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval, result_loc); 10183 case NodeTypeEnumLiteral: 10184 return ir_lval_wrap(irb, scope, ir_gen_enum_literal(irb, scope, node), lval, result_loc); 10185 case NodeTypeInferredArrayType: 10186 add_node_error(irb->codegen, node, 10187 buf_sprintf("inferred array size invalid here")); 10188 return irb->codegen->invalid_inst_src; 10189 case NodeTypeVarFieldType: 10190 return ir_lval_wrap(irb, scope, 10191 ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_var), lval, result_loc); 10192 } 10193 zig_unreachable(); 10194 } 10195 10196 static ResultLoc *no_result_loc(void) { 10197 ResultLocNone *result_loc_none = heap::c_allocator.create<ResultLocNone>(); 10198 result_loc_none->base.id = ResultLocIdNone; 10199 return &result_loc_none->base; 10200 } 10201 10202 static IrInstSrc *ir_gen_node_extra(IrBuilderSrc *irb, AstNode *node, Scope *scope, LVal lval, 10203 ResultLoc *result_loc) 10204 { 10205 if (lval == LValAssign) { 10206 switch (node->type) { 10207 case NodeTypeStructValueField: 10208 case NodeTypeParamDecl: 10209 case NodeTypeUsingNamespace: 10210 case NodeTypeSwitchProng: 10211 case NodeTypeSwitchRange: 10212 case NodeTypeStructField: 10213 case NodeTypeErrorSetField: 10214 case NodeTypeFnDef: 10215 case NodeTypeTestDecl: 10216 zig_unreachable(); 10217 10218 // cannot be assigned to 10219 case NodeTypeBlock: 10220 case NodeTypeGroupedExpr: 10221 case NodeTypeBinOpExpr: 10222 case NodeTypeIntLiteral: 10223 case NodeTypeFloatLiteral: 10224 case NodeTypeCharLiteral: 10225 case NodeTypeIfBoolExpr: 10226 case NodeTypeContainerInitExpr: 10227 case NodeTypeVariableDeclaration: 10228 case NodeTypeWhileExpr: 10229 case NodeTypeForExpr: 10230 case NodeTypeReturnExpr: 10231 case NodeTypeBoolLiteral: 10232 case NodeTypeArrayType: 10233 case NodeTypePointerType: 10234 case NodeTypeAnyFrameType: 10235 case NodeTypeStringLiteral: 10236 case NodeTypeUndefinedLiteral: 10237 case NodeTypeAsmExpr: 10238 case NodeTypeNullLiteral: 10239 case NodeTypeIfErrorExpr: 10240 case NodeTypeIfOptional: 10241 case NodeTypeSwitchExpr: 10242 case NodeTypeCompTime: 10243 case NodeTypeNoSuspend: 10244 case NodeTypeErrorType: 10245 case NodeTypeBreak: 10246 case NodeTypeContinue: 10247 case NodeTypeUnreachable: 10248 case NodeTypeDefer: 10249 case NodeTypeSliceExpr: 10250 case NodeTypeCatchExpr: 10251 case NodeTypeContainerDecl: 10252 case NodeTypeFnProto: 10253 case NodeTypeErrorSetDecl: 10254 case NodeTypeResume: 10255 case NodeTypeAwaitExpr: 10256 case NodeTypeSuspend: 10257 case NodeTypeEnumLiteral: 10258 case NodeTypeInferredArrayType: 10259 case NodeTypeVarFieldType: 10260 case NodeTypePrefixOpExpr: 10261 add_node_error(irb->codegen, node, 10262 buf_sprintf("invalid left-hand side to assignment")); 10263 return irb->codegen->invalid_inst_src; 10264 10265 // @field can be assigned to 10266 case NodeTypeFnCallExpr: 10267 if (node->data.fn_call_expr.modifier == CallModifierBuiltin) { 10268 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; 10269 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 10270 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 10271 10272 if (!entry) { 10273 add_node_error(irb->codegen, node, 10274 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name))); 10275 return irb->codegen->invalid_inst_src; 10276 } 10277 10278 if (entry->value->id == BuiltinFnIdField) { 10279 break; 10280 } 10281 } 10282 add_node_error(irb->codegen, node, 10283 buf_sprintf("invalid left-hand side to assignment")); 10284 return irb->codegen->invalid_inst_src; 10285 10286 10287 // can be assigned to 10288 case NodeTypeUnwrapOptional: 10289 case NodeTypePtrDeref: 10290 case NodeTypeFieldAccessExpr: 10291 case NodeTypeArrayAccessExpr: 10292 case NodeTypeSymbol: 10293 break; 10294 } 10295 } 10296 if (result_loc == nullptr) { 10297 // Create a result location indicating there is none - but if one gets created 10298 // it will be properly distributed. 10299 result_loc = no_result_loc(); 10300 ir_build_reset_result(irb, scope, node, result_loc); 10301 } 10302 Scope *child_scope; 10303 if (irb->exec->is_inline || 10304 (irb->exec->fn_entry != nullptr && irb->exec->fn_entry->child_scope == scope)) 10305 { 10306 child_scope = scope; 10307 } else { 10308 child_scope = &create_expr_scope(irb->codegen, node, scope)->base; 10309 } 10310 IrInstSrc *result = ir_gen_node_raw(irb, node, child_scope, lval, result_loc); 10311 if (result == irb->codegen->invalid_inst_src) { 10312 if (irb->exec->first_err_trace_msg == nullptr) { 10313 irb->exec->first_err_trace_msg = irb->codegen->trace_err; 10314 } 10315 } 10316 return result; 10317 } 10318 10319 static IrInstSrc *ir_gen_node(IrBuilderSrc *irb, AstNode *node, Scope *scope) { 10320 return ir_gen_node_extra(irb, node, scope, LValNone, nullptr); 10321 } 10322 10323 static void invalidate_exec(IrExecutableSrc *exec, ErrorMsg *msg) { 10324 if (exec->first_err_trace_msg != nullptr) 10325 return; 10326 10327 exec->first_err_trace_msg = msg; 10328 10329 for (size_t i = 0; i < exec->tld_list.length; i += 1) { 10330 exec->tld_list.items[i]->resolution = TldResolutionInvalid; 10331 } 10332 } 10333 10334 static void invalidate_exec_gen(IrExecutableGen *exec, ErrorMsg *msg) { 10335 if (exec->first_err_trace_msg != nullptr) 10336 return; 10337 10338 exec->first_err_trace_msg = msg; 10339 10340 for (size_t i = 0; i < exec->tld_list.length; i += 1) { 10341 exec->tld_list.items[i]->resolution = TldResolutionInvalid; 10342 } 10343 10344 if (exec->source_exec != nullptr) 10345 invalidate_exec(exec->source_exec, msg); 10346 } 10347 10348 10349 bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutableSrc *ir_executable) { 10350 assert(node->owner); 10351 10352 IrBuilderSrc ir_builder = {0}; 10353 IrBuilderSrc *irb = &ir_builder; 10354 10355 irb->codegen = codegen; 10356 irb->exec = ir_executable; 10357 irb->main_block_node = node; 10358 10359 IrBasicBlockSrc *entry_block = ir_create_basic_block(irb, scope, "Entry"); 10360 ir_set_cursor_at_end_and_append_block(irb, entry_block); 10361 // Entry block gets a reference because we enter it to begin. 10362 ir_ref_bb(irb->current_basic_block); 10363 10364 IrInstSrc *result = ir_gen_node_extra(irb, node, scope, LValNone, nullptr); 10365 10366 if (result == irb->codegen->invalid_inst_src) 10367 return false; 10368 10369 if (irb->exec->first_err_trace_msg != nullptr) { 10370 codegen->trace_err = irb->exec->first_err_trace_msg; 10371 return false; 10372 } 10373 10374 if (!instr_is_unreachable(result)) { 10375 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, result->base.source_node, result, nullptr)); 10376 // no need for save_err_ret_addr because this cannot return error 10377 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>(); 10378 result_loc_ret->base.id = ResultLocIdReturn; 10379 ir_build_reset_result(irb, scope, node, &result_loc_ret->base); 10380 ir_mark_gen(ir_build_end_expr(irb, scope, node, result, &result_loc_ret->base)); 10381 ir_mark_gen(ir_build_return_src(irb, scope, result->base.source_node, result)); 10382 } 10383 10384 return true; 10385 } 10386 10387 bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) { 10388 assert(fn_entry); 10389 10390 IrExecutableSrc *ir_executable = fn_entry->ir_executable; 10391 AstNode *body_node = fn_entry->body_node; 10392 10393 assert(fn_entry->child_scope); 10394 10395 return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable); 10396 } 10397 10398 static void ir_add_call_stack_errors_gen(CodeGen *codegen, IrExecutableGen *exec, ErrorMsg *err_msg, int limit) { 10399 if (!exec || !exec->source_node || limit < 0) return; 10400 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); 10401 10402 ir_add_call_stack_errors_gen(codegen, exec->parent_exec, err_msg, limit - 1); 10403 } 10404 10405 static void ir_add_call_stack_errors(CodeGen *codegen, IrExecutableSrc *exec, ErrorMsg *err_msg, int limit) { 10406 if (!exec || !exec->source_node || limit < 0) return; 10407 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); 10408 10409 ir_add_call_stack_errors_gen(codegen, exec->parent_exec, err_msg, limit - 1); 10410 } 10411 10412 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutableSrc *exec, AstNode *source_node, Buf *msg) { 10413 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); 10414 invalidate_exec(exec, err_msg); 10415 if (exec->parent_exec) { 10416 ir_add_call_stack_errors(codegen, exec, err_msg, 10); 10417 } 10418 return err_msg; 10419 } 10420 10421 static ErrorMsg *exec_add_error_node_gen(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, Buf *msg) { 10422 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); 10423 invalidate_exec_gen(exec, err_msg); 10424 if (exec->parent_exec) { 10425 ir_add_call_stack_errors_gen(codegen, exec, err_msg, 10); 10426 } 10427 return err_msg; 10428 } 10429 10430 static ErrorMsg *ir_add_error_node(IrAnalyze *ira, AstNode *source_node, Buf *msg) { 10431 return exec_add_error_node_gen(ira->codegen, ira->new_irb.exec, source_node, msg); 10432 } 10433 10434 static ErrorMsg *opt_ir_add_error_node(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, Buf *msg) { 10435 if (ira != nullptr) 10436 return exec_add_error_node_gen(codegen, ira->new_irb.exec, source_node, msg); 10437 else 10438 return add_node_error(codegen, source_node, msg); 10439 } 10440 10441 static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInst *source_instruction, Buf *msg) { 10442 return ir_add_error_node(ira, source_instruction->source_node, msg); 10443 } 10444 10445 static void ir_assert_impl(bool ok, IrInst *source_instruction, char const *file, unsigned int line) { 10446 if (ok) return; 10447 src_assert_impl(ok, source_instruction->source_node, file, line); 10448 } 10449 10450 static void ir_assert_gen_impl(bool ok, IrInstGen *source_instruction, char const *file, unsigned int line) { 10451 if (ok) return; 10452 src_assert_impl(ok, source_instruction->base.source_node, file, line); 10453 } 10454 10455 // This function takes a comptime ptr and makes the child const value conform to the type 10456 // described by the pointer. 10457 static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 10458 ZigValue *ptr_val) 10459 { 10460 Error err; 10461 assert(ptr_val->type->id == ZigTypeIdPointer); 10462 assert(ptr_val->special == ConstValSpecialStatic); 10463 ZigValue tmp = {}; 10464 tmp.special = ConstValSpecialStatic; 10465 tmp.type = ptr_val->type->data.pointer.child_type; 10466 if ((err = ir_read_const_ptr(ira, codegen, source_node, &tmp, ptr_val))) 10467 return err; 10468 ZigValue *child_val = const_ptr_pointee_unchecked(codegen, ptr_val); 10469 copy_const_val(codegen, child_val, &tmp); 10470 return ErrorNone; 10471 } 10472 10473 ZigValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ZigValue *const_val, 10474 AstNode *source_node) 10475 { 10476 Error err; 10477 ZigValue *val = const_ptr_pointee_unchecked(codegen, const_val); 10478 if (val == nullptr) return nullptr; 10479 assert(const_val->type->id == ZigTypeIdPointer); 10480 ZigType *expected_type = const_val->type->data.pointer.child_type; 10481 if (expected_type == codegen->builtin_types.entry_var) { 10482 return val; 10483 } 10484 switch (type_has_one_possible_value(codegen, expected_type)) { 10485 case OnePossibleValueInvalid: 10486 return nullptr; 10487 case OnePossibleValueNo: 10488 break; 10489 case OnePossibleValueYes: 10490 return get_the_one_possible_value(codegen, expected_type); 10491 } 10492 if (!types_have_same_zig_comptime_repr(codegen, expected_type, val->type)) { 10493 if ((err = eval_comptime_ptr_reinterpret(ira, codegen, source_node, const_val))) 10494 return nullptr; 10495 return const_ptr_pointee_unchecked(codegen, const_val); 10496 } 10497 return val; 10498 } 10499 10500 static Error ir_exec_scan_for_side_effects(CodeGen *codegen, IrExecutableGen *exec) { 10501 IrBasicBlockGen *bb = exec->basic_block_list.at(0); 10502 for (size_t i = 0; i < bb->instruction_list.length; i += 1) { 10503 IrInstGen *instruction = bb->instruction_list.at(i); 10504 if (instruction->id == IrInstGenIdReturn) { 10505 return ErrorNone; 10506 } else if (ir_inst_gen_has_side_effects(instruction)) { 10507 if (instr_is_comptime(instruction)) { 10508 switch (instruction->id) { 10509 case IrInstGenIdUnwrapErrPayload: 10510 case IrInstGenIdOptionalUnwrapPtr: 10511 case IrInstGenIdUnionFieldPtr: 10512 continue; 10513 default: 10514 break; 10515 } 10516 } 10517 if (get_scope_typeof(instruction->base.scope) != nullptr) { 10518 // doesn't count, it's inside a @TypeOf() 10519 continue; 10520 } 10521 exec_add_error_node_gen(codegen, exec, instruction->base.source_node, 10522 buf_sprintf("unable to evaluate constant expression")); 10523 return ErrorSemanticAnalyzeFail; 10524 } 10525 } 10526 zig_unreachable(); 10527 } 10528 10529 static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInst* source_instruction) { 10530 if (ir_should_inline(ira->old_irb.exec, source_instruction->scope)) { 10531 ir_add_error(ira, source_instruction, buf_sprintf("unable to evaluate constant expression")); 10532 return false; 10533 } 10534 return true; 10535 } 10536 10537 static bool const_val_fits_in_num_lit(ZigValue *const_val, ZigType *num_lit_type) { 10538 return ((num_lit_type->id == ZigTypeIdComptimeFloat && 10539 (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat)) || 10540 (num_lit_type->id == ZigTypeIdComptimeInt && 10541 (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt))); 10542 } 10543 10544 static bool float_has_fraction(ZigValue *const_val) { 10545 if (const_val->type->id == ZigTypeIdComptimeFloat) { 10546 return bigfloat_has_fraction(&const_val->data.x_bigfloat); 10547 } else if (const_val->type->id == ZigTypeIdFloat) { 10548 switch (const_val->type->data.floating.bit_count) { 10549 case 16: 10550 { 10551 float16_t floored = f16_roundToInt(const_val->data.x_f16, softfloat_round_minMag, false); 10552 return !f16_eq(floored, const_val->data.x_f16); 10553 } 10554 case 32: 10555 return floorf(const_val->data.x_f32) != const_val->data.x_f32; 10556 case 64: 10557 return floor(const_val->data.x_f64) != const_val->data.x_f64; 10558 case 128: 10559 { 10560 float128_t floored; 10561 f128M_roundToInt(&const_val->data.x_f128, softfloat_round_minMag, false, &floored); 10562 return !f128M_eq(&floored, &const_val->data.x_f128); 10563 } 10564 default: 10565 zig_unreachable(); 10566 } 10567 } else { 10568 zig_unreachable(); 10569 } 10570 } 10571 10572 static void float_append_buf(Buf *buf, ZigValue *const_val) { 10573 if (const_val->type->id == ZigTypeIdComptimeFloat) { 10574 bigfloat_append_buf(buf, &const_val->data.x_bigfloat); 10575 } else if (const_val->type->id == ZigTypeIdFloat) { 10576 switch (const_val->type->data.floating.bit_count) { 10577 case 16: 10578 buf_appendf(buf, "%f", zig_f16_to_double(const_val->data.x_f16)); 10579 break; 10580 case 32: 10581 buf_appendf(buf, "%f", const_val->data.x_f32); 10582 break; 10583 case 64: 10584 buf_appendf(buf, "%f", const_val->data.x_f64); 10585 break; 10586 case 128: 10587 { 10588 // TODO actual implementation 10589 const size_t extra_len = 100; 10590 size_t old_len = buf_len(buf); 10591 buf_resize(buf, old_len + extra_len); 10592 10593 float64_t f64_value = f128M_to_f64(&const_val->data.x_f128); 10594 double double_value; 10595 memcpy(&double_value, &f64_value, sizeof(double)); 10596 10597 int len = snprintf(buf_ptr(buf) + old_len, extra_len, "%f", double_value); 10598 assert(len > 0); 10599 buf_resize(buf, old_len + len); 10600 break; 10601 } 10602 default: 10603 zig_unreachable(); 10604 } 10605 } else { 10606 zig_unreachable(); 10607 } 10608 } 10609 10610 static void float_init_bigint(BigInt *bigint, ZigValue *const_val) { 10611 if (const_val->type->id == ZigTypeIdComptimeFloat) { 10612 bigint_init_bigfloat(bigint, &const_val->data.x_bigfloat); 10613 } else if (const_val->type->id == ZigTypeIdFloat) { 10614 switch (const_val->type->data.floating.bit_count) { 10615 case 16: 10616 { 10617 double x = zig_f16_to_double(const_val->data.x_f16); 10618 if (x >= 0) { 10619 bigint_init_unsigned(bigint, (uint64_t)x); 10620 } else { 10621 bigint_init_unsigned(bigint, (uint64_t)-x); 10622 bigint->is_negative = true; 10623 } 10624 break; 10625 } 10626 case 32: 10627 if (const_val->data.x_f32 >= 0) { 10628 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f32)); 10629 } else { 10630 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f32)); 10631 bigint->is_negative = true; 10632 } 10633 break; 10634 case 64: 10635 if (const_val->data.x_f64 >= 0) { 10636 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f64)); 10637 } else { 10638 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f64)); 10639 bigint->is_negative = true; 10640 } 10641 break; 10642 case 128: 10643 { 10644 BigFloat tmp_float; 10645 bigfloat_init_128(&tmp_float, const_val->data.x_f128); 10646 bigint_init_bigfloat(bigint, &tmp_float); 10647 } 10648 break; 10649 default: 10650 zig_unreachable(); 10651 } 10652 } else { 10653 zig_unreachable(); 10654 } 10655 } 10656 10657 static void float_init_bigfloat(ZigValue *dest_val, BigFloat *bigfloat) { 10658 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10659 bigfloat_init_bigfloat(&dest_val->data.x_bigfloat, bigfloat); 10660 } else if (dest_val->type->id == ZigTypeIdFloat) { 10661 switch (dest_val->type->data.floating.bit_count) { 10662 case 16: 10663 dest_val->data.x_f16 = bigfloat_to_f16(bigfloat); 10664 break; 10665 case 32: 10666 dest_val->data.x_f32 = bigfloat_to_f32(bigfloat); 10667 break; 10668 case 64: 10669 dest_val->data.x_f64 = bigfloat_to_f64(bigfloat); 10670 break; 10671 case 80: 10672 zig_panic("TODO"); 10673 case 128: 10674 dest_val->data.x_f128 = bigfloat_to_f128(bigfloat); 10675 break; 10676 default: 10677 zig_unreachable(); 10678 } 10679 } else { 10680 zig_unreachable(); 10681 } 10682 } 10683 10684 static void float_init_f16(ZigValue *dest_val, float16_t x) { 10685 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10686 bigfloat_init_16(&dest_val->data.x_bigfloat, x); 10687 } else if (dest_val->type->id == ZigTypeIdFloat) { 10688 switch (dest_val->type->data.floating.bit_count) { 10689 case 16: 10690 dest_val->data.x_f16 = x; 10691 break; 10692 case 32: 10693 dest_val->data.x_f32 = zig_f16_to_double(x); 10694 break; 10695 case 64: 10696 dest_val->data.x_f64 = zig_f16_to_double(x); 10697 break; 10698 case 128: 10699 f16_to_f128M(x, &dest_val->data.x_f128); 10700 break; 10701 default: 10702 zig_unreachable(); 10703 } 10704 } else { 10705 zig_unreachable(); 10706 } 10707 } 10708 10709 static void float_init_f32(ZigValue *dest_val, float x) { 10710 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10711 bigfloat_init_32(&dest_val->data.x_bigfloat, x); 10712 } else if (dest_val->type->id == ZigTypeIdFloat) { 10713 switch (dest_val->type->data.floating.bit_count) { 10714 case 16: 10715 dest_val->data.x_f16 = zig_double_to_f16(x); 10716 break; 10717 case 32: 10718 dest_val->data.x_f32 = x; 10719 break; 10720 case 64: 10721 dest_val->data.x_f64 = x; 10722 break; 10723 case 128: 10724 { 10725 float32_t x_f32; 10726 memcpy(&x_f32, &x, sizeof(float)); 10727 f32_to_f128M(x_f32, &dest_val->data.x_f128); 10728 break; 10729 } 10730 default: 10731 zig_unreachable(); 10732 } 10733 } else { 10734 zig_unreachable(); 10735 } 10736 } 10737 10738 static void float_init_f64(ZigValue *dest_val, double x) { 10739 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10740 bigfloat_init_64(&dest_val->data.x_bigfloat, x); 10741 } else if (dest_val->type->id == ZigTypeIdFloat) { 10742 switch (dest_val->type->data.floating.bit_count) { 10743 case 16: 10744 dest_val->data.x_f16 = zig_double_to_f16(x); 10745 break; 10746 case 32: 10747 dest_val->data.x_f32 = x; 10748 break; 10749 case 64: 10750 dest_val->data.x_f64 = x; 10751 break; 10752 case 128: 10753 { 10754 float64_t x_f64; 10755 memcpy(&x_f64, &x, sizeof(double)); 10756 f64_to_f128M(x_f64, &dest_val->data.x_f128); 10757 break; 10758 } 10759 default: 10760 zig_unreachable(); 10761 } 10762 } else { 10763 zig_unreachable(); 10764 } 10765 } 10766 10767 static void float_init_f128(ZigValue *dest_val, float128_t x) { 10768 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 10769 bigfloat_init_128(&dest_val->data.x_bigfloat, x); 10770 } else if (dest_val->type->id == ZigTypeIdFloat) { 10771 switch (dest_val->type->data.floating.bit_count) { 10772 case 16: 10773 dest_val->data.x_f16 = f128M_to_f16(&x); 10774 break; 10775 case 32: 10776 { 10777 float32_t f32_val = f128M_to_f32(&x); 10778 memcpy(&dest_val->data.x_f32, &f32_val, sizeof(float)); 10779 break; 10780 } 10781 case 64: 10782 { 10783 float64_t f64_val = f128M_to_f64(&x); 10784 memcpy(&dest_val->data.x_f64, &f64_val, sizeof(double)); 10785 break; 10786 } 10787 case 128: 10788 { 10789 memcpy(&dest_val->data.x_f128, &x, sizeof(float128_t)); 10790 break; 10791 } 10792 default: 10793 zig_unreachable(); 10794 } 10795 } else { 10796 zig_unreachable(); 10797 } 10798 } 10799 10800 static void float_init_float(ZigValue *dest_val, ZigValue *src_val) { 10801 if (src_val->type->id == ZigTypeIdComptimeFloat) { 10802 float_init_bigfloat(dest_val, &src_val->data.x_bigfloat); 10803 } else if (src_val->type->id == ZigTypeIdFloat) { 10804 switch (src_val->type->data.floating.bit_count) { 10805 case 16: 10806 float_init_f16(dest_val, src_val->data.x_f16); 10807 break; 10808 case 32: 10809 float_init_f32(dest_val, src_val->data.x_f32); 10810 break; 10811 case 64: 10812 float_init_f64(dest_val, src_val->data.x_f64); 10813 break; 10814 case 128: 10815 float_init_f128(dest_val, src_val->data.x_f128); 10816 break; 10817 default: 10818 zig_unreachable(); 10819 } 10820 } else { 10821 zig_unreachable(); 10822 } 10823 } 10824 10825 static bool float_is_nan(ZigValue *op) { 10826 if (op->type->id == ZigTypeIdComptimeFloat) { 10827 return bigfloat_is_nan(&op->data.x_bigfloat); 10828 } else if (op->type->id == ZigTypeIdFloat) { 10829 switch (op->type->data.floating.bit_count) { 10830 case 16: 10831 return f16_isSignalingNaN(op->data.x_f16); 10832 case 32: 10833 return op->data.x_f32 != op->data.x_f32; 10834 case 64: 10835 return op->data.x_f64 != op->data.x_f64; 10836 case 128: 10837 return f128M_isSignalingNaN(&op->data.x_f128); 10838 default: 10839 zig_unreachable(); 10840 } 10841 } else { 10842 zig_unreachable(); 10843 } 10844 } 10845 10846 static Cmp float_cmp(ZigValue *op1, ZigValue *op2) { 10847 if (op1->type == op2->type) { 10848 if (op1->type->id == ZigTypeIdComptimeFloat) { 10849 return bigfloat_cmp(&op1->data.x_bigfloat, &op2->data.x_bigfloat); 10850 } else if (op1->type->id == ZigTypeIdFloat) { 10851 switch (op1->type->data.floating.bit_count) { 10852 case 16: 10853 if (f16_lt(op1->data.x_f16, op2->data.x_f16)) { 10854 return CmpLT; 10855 } else if (f16_lt(op2->data.x_f16, op1->data.x_f16)) { 10856 return CmpGT; 10857 } else { 10858 return CmpEQ; 10859 } 10860 case 32: 10861 if (op1->data.x_f32 > op2->data.x_f32) { 10862 return CmpGT; 10863 } else if (op1->data.x_f32 < op2->data.x_f32) { 10864 return CmpLT; 10865 } else { 10866 return CmpEQ; 10867 } 10868 case 64: 10869 if (op1->data.x_f64 > op2->data.x_f64) { 10870 return CmpGT; 10871 } else if (op1->data.x_f64 < op2->data.x_f64) { 10872 return CmpLT; 10873 } else { 10874 return CmpEQ; 10875 } 10876 case 128: 10877 if (f128M_lt(&op1->data.x_f128, &op2->data.x_f128)) { 10878 return CmpLT; 10879 } else if (f128M_eq(&op1->data.x_f128, &op2->data.x_f128)) { 10880 return CmpEQ; 10881 } else { 10882 return CmpGT; 10883 } 10884 default: 10885 zig_unreachable(); 10886 } 10887 } else { 10888 zig_unreachable(); 10889 } 10890 } 10891 BigFloat op1_big; 10892 BigFloat op2_big; 10893 float_init_bigfloat(op1, &op1_big); 10894 float_init_bigfloat(op2, &op2_big); 10895 return bigfloat_cmp(&op1_big, &op2_big); 10896 } 10897 10898 // This function cannot handle NaN 10899 static Cmp float_cmp_zero(ZigValue *op) { 10900 if (op->type->id == ZigTypeIdComptimeFloat) { 10901 return bigfloat_cmp_zero(&op->data.x_bigfloat); 10902 } else if (op->type->id == ZigTypeIdFloat) { 10903 switch (op->type->data.floating.bit_count) { 10904 case 16: 10905 { 10906 const float16_t zero = zig_double_to_f16(0); 10907 if (f16_lt(op->data.x_f16, zero)) { 10908 return CmpLT; 10909 } else if (f16_lt(zero, op->data.x_f16)) { 10910 return CmpGT; 10911 } else { 10912 return CmpEQ; 10913 } 10914 } 10915 case 32: 10916 if (op->data.x_f32 < 0.0) { 10917 return CmpLT; 10918 } else if (op->data.x_f32 > 0.0) { 10919 return CmpGT; 10920 } else { 10921 return CmpEQ; 10922 } 10923 case 64: 10924 if (op->data.x_f64 < 0.0) { 10925 return CmpLT; 10926 } else if (op->data.x_f64 > 0.0) { 10927 return CmpGT; 10928 } else { 10929 return CmpEQ; 10930 } 10931 case 128: 10932 float128_t zero_float; 10933 ui32_to_f128M(0, &zero_float); 10934 if (f128M_lt(&op->data.x_f128, &zero_float)) { 10935 return CmpLT; 10936 } else if (f128M_eq(&op->data.x_f128, &zero_float)) { 10937 return CmpEQ; 10938 } else { 10939 return CmpGT; 10940 } 10941 default: 10942 zig_unreachable(); 10943 } 10944 } else { 10945 zig_unreachable(); 10946 } 10947 } 10948 10949 static void float_add(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 10950 assert(op1->type == op2->type); 10951 out_val->type = op1->type; 10952 if (op1->type->id == ZigTypeIdComptimeFloat) { 10953 bigfloat_add(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 10954 } else if (op1->type->id == ZigTypeIdFloat) { 10955 switch (op1->type->data.floating.bit_count) { 10956 case 16: 10957 out_val->data.x_f16 = f16_add(op1->data.x_f16, op2->data.x_f16); 10958 return; 10959 case 32: 10960 out_val->data.x_f32 = op1->data.x_f32 + op2->data.x_f32; 10961 return; 10962 case 64: 10963 out_val->data.x_f64 = op1->data.x_f64 + op2->data.x_f64; 10964 return; 10965 case 128: 10966 f128M_add(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 10967 return; 10968 default: 10969 zig_unreachable(); 10970 } 10971 } else { 10972 zig_unreachable(); 10973 } 10974 } 10975 10976 static void float_sub(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 10977 assert(op1->type == op2->type); 10978 out_val->type = op1->type; 10979 if (op1->type->id == ZigTypeIdComptimeFloat) { 10980 bigfloat_sub(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 10981 } else if (op1->type->id == ZigTypeIdFloat) { 10982 switch (op1->type->data.floating.bit_count) { 10983 case 16: 10984 out_val->data.x_f16 = f16_sub(op1->data.x_f16, op2->data.x_f16); 10985 return; 10986 case 32: 10987 out_val->data.x_f32 = op1->data.x_f32 - op2->data.x_f32; 10988 return; 10989 case 64: 10990 out_val->data.x_f64 = op1->data.x_f64 - op2->data.x_f64; 10991 return; 10992 case 128: 10993 f128M_sub(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 10994 return; 10995 default: 10996 zig_unreachable(); 10997 } 10998 } else { 10999 zig_unreachable(); 11000 } 11001 } 11002 11003 static void float_mul(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 11004 assert(op1->type == op2->type); 11005 out_val->type = op1->type; 11006 if (op1->type->id == ZigTypeIdComptimeFloat) { 11007 bigfloat_mul(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 11008 } else if (op1->type->id == ZigTypeIdFloat) { 11009 switch (op1->type->data.floating.bit_count) { 11010 case 16: 11011 out_val->data.x_f16 = f16_mul(op1->data.x_f16, op2->data.x_f16); 11012 return; 11013 case 32: 11014 out_val->data.x_f32 = op1->data.x_f32 * op2->data.x_f32; 11015 return; 11016 case 64: 11017 out_val->data.x_f64 = op1->data.x_f64 * op2->data.x_f64; 11018 return; 11019 case 128: 11020 f128M_mul(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11021 return; 11022 default: 11023 zig_unreachable(); 11024 } 11025 } else { 11026 zig_unreachable(); 11027 } 11028 } 11029 11030 static void float_div(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 11031 assert(op1->type == op2->type); 11032 out_val->type = op1->type; 11033 if (op1->type->id == ZigTypeIdComptimeFloat) { 11034 bigfloat_div(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 11035 } else if (op1->type->id == ZigTypeIdFloat) { 11036 switch (op1->type->data.floating.bit_count) { 11037 case 16: 11038 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 11039 return; 11040 case 32: 11041 out_val->data.x_f32 = op1->data.x_f32 / op2->data.x_f32; 11042 return; 11043 case 64: 11044 out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64; 11045 return; 11046 case 128: 11047 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11048 return; 11049 default: 11050 zig_unreachable(); 11051 } 11052 } else { 11053 zig_unreachable(); 11054 } 11055 } 11056 11057 static void float_div_trunc(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 11058 assert(op1->type == op2->type); 11059 out_val->type = op1->type; 11060 if (op1->type->id == ZigTypeIdComptimeFloat) { 11061 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 11062 } else if (op1->type->id == ZigTypeIdFloat) { 11063 switch (op1->type->data.floating.bit_count) { 11064 case 16: 11065 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 11066 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_minMag, false); 11067 return; 11068 case 32: 11069 out_val->data.x_f32 = truncf(op1->data.x_f32 / op2->data.x_f32); 11070 return; 11071 case 64: 11072 out_val->data.x_f64 = trunc(op1->data.x_f64 / op2->data.x_f64); 11073 return; 11074 case 128: 11075 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11076 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_minMag, false, &out_val->data.x_f128); 11077 return; 11078 default: 11079 zig_unreachable(); 11080 } 11081 } else { 11082 zig_unreachable(); 11083 } 11084 } 11085 11086 static void float_div_floor(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 11087 assert(op1->type == op2->type); 11088 out_val->type = op1->type; 11089 if (op1->type->id == ZigTypeIdComptimeFloat) { 11090 bigfloat_div_floor(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 11091 } else if (op1->type->id == ZigTypeIdFloat) { 11092 switch (op1->type->data.floating.bit_count) { 11093 case 16: 11094 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 11095 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_min, false); 11096 return; 11097 case 32: 11098 out_val->data.x_f32 = floorf(op1->data.x_f32 / op2->data.x_f32); 11099 return; 11100 case 64: 11101 out_val->data.x_f64 = floor(op1->data.x_f64 / op2->data.x_f64); 11102 return; 11103 case 128: 11104 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11105 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_min, false, &out_val->data.x_f128); 11106 return; 11107 default: 11108 zig_unreachable(); 11109 } 11110 } else { 11111 zig_unreachable(); 11112 } 11113 } 11114 11115 static void float_rem(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 11116 assert(op1->type == op2->type); 11117 out_val->type = op1->type; 11118 if (op1->type->id == ZigTypeIdComptimeFloat) { 11119 bigfloat_rem(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 11120 } else if (op1->type->id == ZigTypeIdFloat) { 11121 switch (op1->type->data.floating.bit_count) { 11122 case 16: 11123 out_val->data.x_f16 = f16_rem(op1->data.x_f16, op2->data.x_f16); 11124 return; 11125 case 32: 11126 out_val->data.x_f32 = fmodf(op1->data.x_f32, op2->data.x_f32); 11127 return; 11128 case 64: 11129 out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64); 11130 return; 11131 case 128: 11132 f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11133 return; 11134 default: 11135 zig_unreachable(); 11136 } 11137 } else { 11138 zig_unreachable(); 11139 } 11140 } 11141 11142 // c = a - b * trunc(a / b) 11143 static float16_t zig_f16_mod(float16_t a, float16_t b) { 11144 float16_t c; 11145 c = f16_div(a, b); 11146 c = f16_roundToInt(c, softfloat_round_min, true); 11147 c = f16_mul(b, c); 11148 c = f16_sub(a, c); 11149 return c; 11150 } 11151 11152 // c = a - b * trunc(a / b) 11153 static void zig_f128M_mod(const float128_t* a, const float128_t* b, float128_t* c) { 11154 f128M_div(a, b, c); 11155 f128M_roundToInt(c, softfloat_round_min, true, c); 11156 f128M_mul(b, c, c); 11157 f128M_sub(a, c, c); 11158 } 11159 11160 static void float_mod(ZigValue *out_val, ZigValue *op1, ZigValue *op2) { 11161 assert(op1->type == op2->type); 11162 out_val->type = op1->type; 11163 if (op1->type->id == ZigTypeIdComptimeFloat) { 11164 bigfloat_mod(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 11165 } else if (op1->type->id == ZigTypeIdFloat) { 11166 switch (op1->type->data.floating.bit_count) { 11167 case 16: 11168 out_val->data.x_f16 = zig_f16_mod(op1->data.x_f16, op2->data.x_f16); 11169 return; 11170 case 32: 11171 out_val->data.x_f32 = fmodf(fmodf(op1->data.x_f32, op2->data.x_f32) + op2->data.x_f32, op2->data.x_f32); 11172 return; 11173 case 64: 11174 out_val->data.x_f64 = fmod(fmod(op1->data.x_f64, op2->data.x_f64) + op2->data.x_f64, op2->data.x_f64); 11175 return; 11176 case 128: 11177 zig_f128M_mod(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 11178 return; 11179 default: 11180 zig_unreachable(); 11181 } 11182 } else { 11183 zig_unreachable(); 11184 } 11185 } 11186 11187 static void float_negate(ZigValue *out_val, ZigValue *op) { 11188 out_val->type = op->type; 11189 if (op->type->id == ZigTypeIdComptimeFloat) { 11190 bigfloat_negate(&out_val->data.x_bigfloat, &op->data.x_bigfloat); 11191 } else if (op->type->id == ZigTypeIdFloat) { 11192 switch (op->type->data.floating.bit_count) { 11193 case 16: 11194 { 11195 const float16_t zero = zig_double_to_f16(0); 11196 out_val->data.x_f16 = f16_sub(zero, op->data.x_f16); 11197 return; 11198 } 11199 case 32: 11200 out_val->data.x_f32 = -op->data.x_f32; 11201 return; 11202 case 64: 11203 out_val->data.x_f64 = -op->data.x_f64; 11204 return; 11205 case 128: 11206 float128_t zero_f128; 11207 ui32_to_f128M(0, &zero_f128); 11208 f128M_sub(&zero_f128, &op->data.x_f128, &out_val->data.x_f128); 11209 return; 11210 default: 11211 zig_unreachable(); 11212 } 11213 } else { 11214 zig_unreachable(); 11215 } 11216 } 11217 11218 void float_write_ieee597(ZigValue *op, uint8_t *buf, bool is_big_endian) { 11219 if (op->type->id != ZigTypeIdFloat) 11220 zig_unreachable(); 11221 11222 const unsigned n = op->type->data.floating.bit_count / 8; 11223 assert(n <= 16); 11224 11225 switch (op->type->data.floating.bit_count) { 11226 case 16: 11227 memcpy(buf, &op->data.x_f16, 2); 11228 break; 11229 case 32: 11230 memcpy(buf, &op->data.x_f32, 4); 11231 break; 11232 case 64: 11233 memcpy(buf, &op->data.x_f64, 8); 11234 break; 11235 case 128: 11236 memcpy(buf, &op->data.x_f128, 16); 11237 break; 11238 default: 11239 zig_unreachable(); 11240 } 11241 11242 if (is_big_endian) { 11243 // Byteswap in place if needed 11244 for (size_t i = 0; i < n / 2; i++) { 11245 uint8_t u = buf[i]; 11246 buf[i] = buf[n - 1 - i]; 11247 buf[n - 1 - i] = u; 11248 } 11249 } 11250 } 11251 11252 void float_read_ieee597(ZigValue *val, uint8_t *buf, bool is_big_endian) { 11253 if (val->type->id != ZigTypeIdFloat) 11254 zig_unreachable(); 11255 11256 const unsigned n = val->type->data.floating.bit_count / 8; 11257 assert(n <= 16); 11258 11259 uint8_t tmp[16]; 11260 uint8_t *ptr = buf; 11261 11262 if (is_big_endian) { 11263 memcpy(tmp, buf, n); 11264 11265 // Byteswap if needed 11266 for (size_t i = 0; i < n / 2; i++) { 11267 uint8_t u = tmp[i]; 11268 tmp[i] = tmp[n - 1 - i]; 11269 tmp[n - 1 - i] = u; 11270 } 11271 11272 ptr = tmp; 11273 } 11274 11275 switch (val->type->data.floating.bit_count) { 11276 case 16: 11277 memcpy(&val->data.x_f16, ptr, 2); 11278 return; 11279 case 32: 11280 memcpy(&val->data.x_f32, ptr, 4); 11281 return; 11282 case 64: 11283 memcpy(&val->data.x_f64, ptr, 8); 11284 return; 11285 case 128: 11286 memcpy(&val->data.x_f128, ptr, 16); 11287 return; 11288 default: 11289 zig_unreachable(); 11290 } 11291 } 11292 11293 static void value_to_bigfloat(BigFloat *out, ZigValue *val) { 11294 switch (val->type->id) { 11295 case ZigTypeIdInt: 11296 case ZigTypeIdComptimeInt: 11297 bigfloat_init_bigint(out, &val->data.x_bigint); 11298 return; 11299 case ZigTypeIdComptimeFloat: 11300 *out = val->data.x_bigfloat; 11301 return; 11302 case ZigTypeIdFloat: switch (val->type->data.floating.bit_count) { 11303 case 16: 11304 bigfloat_init_16(out, val->data.x_f16); 11305 return; 11306 case 32: 11307 bigfloat_init_32(out, val->data.x_f32); 11308 return; 11309 case 64: 11310 bigfloat_init_64(out, val->data.x_f64); 11311 return; 11312 case 80: 11313 zig_panic("TODO"); 11314 case 128: 11315 bigfloat_init_128(out, val->data.x_f128); 11316 return; 11317 default: 11318 zig_unreachable(); 11319 } 11320 default: 11321 zig_unreachable(); 11322 } 11323 } 11324 11325 static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstGen *instruction, ZigType *other_type, 11326 bool explicit_cast) 11327 { 11328 if (type_is_invalid(other_type)) { 11329 return false; 11330 } 11331 11332 ZigValue *const_val = ir_resolve_const(ira, instruction, LazyOkNoUndef); 11333 if (const_val == nullptr) 11334 return false; 11335 11336 if (const_val->special == ConstValSpecialLazy) { 11337 switch (const_val->data.x_lazy->id) { 11338 case LazyValueIdAlignOf: { 11339 // This is guaranteed to fit into a u29 11340 if (other_type->id == ZigTypeIdComptimeInt) 11341 return true; 11342 size_t align_bits = get_align_amt_type(ira->codegen)->data.integral.bit_count; 11343 if (other_type->id == ZigTypeIdInt && !other_type->data.integral.is_signed && 11344 other_type->data.integral.bit_count >= align_bits) 11345 { 11346 return true; 11347 } 11348 break; 11349 } 11350 case LazyValueIdSizeOf: { 11351 // This is guaranteed to fit into a usize 11352 if (other_type->id == ZigTypeIdComptimeInt) 11353 return true; 11354 size_t usize_bits = ira->codegen->builtin_types.entry_usize->data.integral.bit_count; 11355 if (other_type->id == ZigTypeIdInt && !other_type->data.integral.is_signed && 11356 other_type->data.integral.bit_count >= usize_bits) 11357 { 11358 return true; 11359 } 11360 break; 11361 } 11362 default: 11363 break; 11364 } 11365 } 11366 11367 const_val = ir_resolve_const(ira, instruction, UndefBad); 11368 if (const_val == nullptr) 11369 return false; 11370 11371 bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt); 11372 bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat); 11373 assert(const_val_is_int || const_val_is_float); 11374 11375 if (const_val_is_int && other_type->id == ZigTypeIdComptimeFloat) { 11376 return true; 11377 } 11378 if (other_type->id == ZigTypeIdFloat) { 11379 if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) { 11380 return true; 11381 } 11382 if (const_val->type->id == ZigTypeIdInt) { 11383 BigFloat tmp_bf; 11384 bigfloat_init_bigint(&tmp_bf, &const_val->data.x_bigint); 11385 BigFloat orig_bf; 11386 switch (other_type->data.floating.bit_count) { 11387 case 16: { 11388 float16_t tmp = bigfloat_to_f16(&tmp_bf); 11389 bigfloat_init_16(&orig_bf, tmp); 11390 break; 11391 } 11392 case 32: { 11393 float tmp = bigfloat_to_f32(&tmp_bf); 11394 bigfloat_init_32(&orig_bf, tmp); 11395 break; 11396 } 11397 case 64: { 11398 double tmp = bigfloat_to_f64(&tmp_bf); 11399 bigfloat_init_64(&orig_bf, tmp); 11400 break; 11401 } 11402 case 80: 11403 zig_panic("TODO"); 11404 case 128: { 11405 float128_t tmp = bigfloat_to_f128(&tmp_bf); 11406 bigfloat_init_128(&orig_bf, tmp); 11407 break; 11408 } 11409 default: 11410 zig_unreachable(); 11411 } 11412 BigInt orig_bi; 11413 bigint_init_bigfloat(&orig_bi, &orig_bf); 11414 if (bigint_cmp(&orig_bi, &const_val->data.x_bigint) == CmpEQ) { 11415 return true; 11416 } 11417 Buf *val_buf = buf_alloc(); 11418 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 11419 ir_add_error_node(ira, instruction->base.source_node, 11420 buf_sprintf("type %s cannot represent integer value %s", 11421 buf_ptr(&other_type->name), 11422 buf_ptr(val_buf))); 11423 return false; 11424 } 11425 if (other_type->data.floating.bit_count >= const_val->type->data.floating.bit_count) { 11426 return true; 11427 } 11428 switch (other_type->data.floating.bit_count) { 11429 case 16: 11430 switch (const_val->type->data.floating.bit_count) { 11431 case 32: { 11432 float16_t tmp = zig_double_to_f16(const_val->data.x_f32); 11433 float orig = zig_f16_to_double(tmp); 11434 if (const_val->data.x_f32 == orig) { 11435 return true; 11436 } 11437 break; 11438 } 11439 case 64: { 11440 float16_t tmp = zig_double_to_f16(const_val->data.x_f64); 11441 double orig = zig_f16_to_double(tmp); 11442 if (const_val->data.x_f64 == orig) { 11443 return true; 11444 } 11445 break; 11446 } 11447 case 80: 11448 zig_panic("TODO"); 11449 case 128: { 11450 float16_t tmp = f128M_to_f16(&const_val->data.x_f128); 11451 float128_t orig; 11452 f16_to_f128M(tmp, &orig); 11453 if (f128M_eq(&orig, &const_val->data.x_f128)) { 11454 return true; 11455 } 11456 break; 11457 } 11458 default: 11459 zig_unreachable(); 11460 } 11461 break; 11462 case 32: 11463 switch (const_val->type->data.floating.bit_count) { 11464 case 64: { 11465 float tmp = const_val->data.x_f64; 11466 double orig = tmp; 11467 if (const_val->data.x_f64 == orig) { 11468 return true; 11469 } 11470 break; 11471 } 11472 case 80: 11473 zig_panic("TODO"); 11474 case 128: { 11475 float32_t tmp = f128M_to_f32(&const_val->data.x_f128); 11476 float128_t orig; 11477 f32_to_f128M(tmp, &orig); 11478 if (f128M_eq(&orig, &const_val->data.x_f128)) { 11479 return true; 11480 } 11481 break; 11482 } 11483 default: 11484 zig_unreachable(); 11485 } 11486 break; 11487 case 64: 11488 switch (const_val->type->data.floating.bit_count) { 11489 case 80: 11490 zig_panic("TODO"); 11491 case 128: { 11492 float64_t tmp = f128M_to_f64(&const_val->data.x_f128); 11493 float128_t orig; 11494 f64_to_f128M(tmp, &orig); 11495 if (f128M_eq(&orig, &const_val->data.x_f128)) { 11496 return true; 11497 } 11498 break; 11499 } 11500 default: 11501 zig_unreachable(); 11502 } 11503 break; 11504 case 80: 11505 assert(const_val->type->data.floating.bit_count == 128); 11506 zig_panic("TODO"); 11507 case 128: 11508 return true; 11509 default: 11510 zig_unreachable(); 11511 } 11512 Buf *val_buf = buf_alloc(); 11513 float_append_buf(val_buf, const_val); 11514 ir_add_error_node(ira, instruction->base.source_node, 11515 buf_sprintf("cast of value %s to type '%s' loses information", 11516 buf_ptr(val_buf), 11517 buf_ptr(&other_type->name))); 11518 return false; 11519 } else if (other_type->id == ZigTypeIdInt && const_val_is_int) { 11520 if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 11521 Buf *val_buf = buf_alloc(); 11522 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 11523 ir_add_error_node(ira, instruction->base.source_node, 11524 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 11525 buf_ptr(val_buf), 11526 buf_ptr(&other_type->name))); 11527 return false; 11528 } 11529 if (bigint_fits_in_bits(&const_val->data.x_bigint, other_type->data.integral.bit_count, 11530 other_type->data.integral.is_signed)) 11531 { 11532 return true; 11533 } 11534 } else if (const_val_fits_in_num_lit(const_val, other_type)) { 11535 return true; 11536 } else if (other_type->id == ZigTypeIdOptional) { 11537 ZigType *child_type = other_type->data.maybe.child_type; 11538 if (const_val_fits_in_num_lit(const_val, child_type)) { 11539 return true; 11540 } else if (child_type->id == ZigTypeIdInt && const_val_is_int) { 11541 if (!child_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 11542 Buf *val_buf = buf_alloc(); 11543 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 11544 ir_add_error_node(ira, instruction->base.source_node, 11545 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 11546 buf_ptr(val_buf), 11547 buf_ptr(&child_type->name))); 11548 return false; 11549 } 11550 if (bigint_fits_in_bits(&const_val->data.x_bigint, 11551 child_type->data.integral.bit_count, 11552 child_type->data.integral.is_signed)) 11553 { 11554 return true; 11555 } 11556 } else if (child_type->id == ZigTypeIdFloat && const_val_is_float) { 11557 return true; 11558 } 11559 } 11560 if (explicit_cast && (other_type->id == ZigTypeIdInt || other_type->id == ZigTypeIdComptimeInt) && 11561 const_val_is_float) 11562 { 11563 if (float_has_fraction(const_val)) { 11564 Buf *val_buf = buf_alloc(); 11565 float_append_buf(val_buf, const_val); 11566 11567 ir_add_error_node(ira, instruction->base.source_node, 11568 buf_sprintf("fractional component prevents float value %s from being casted to type '%s'", 11569 buf_ptr(val_buf), 11570 buf_ptr(&other_type->name))); 11571 return false; 11572 } else { 11573 if (other_type->id == ZigTypeIdComptimeInt) { 11574 return true; 11575 } else { 11576 BigInt bigint; 11577 float_init_bigint(&bigint, const_val); 11578 if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count, 11579 other_type->data.integral.is_signed)) 11580 { 11581 return true; 11582 } 11583 } 11584 } 11585 } 11586 11587 const char *num_lit_str; 11588 Buf *val_buf = buf_alloc(); 11589 if (const_val_is_float) { 11590 num_lit_str = "float"; 11591 float_append_buf(val_buf, const_val); 11592 } else { 11593 num_lit_str = "integer"; 11594 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 11595 } 11596 11597 ir_add_error_node(ira, instruction->base.source_node, 11598 buf_sprintf("%s value %s cannot be coerced to type '%s'", 11599 num_lit_str, 11600 buf_ptr(val_buf), 11601 buf_ptr(&other_type->name))); 11602 return false; 11603 } 11604 11605 static bool is_tagged_union(ZigType *type) { 11606 if (type->id != ZigTypeIdUnion) 11607 return false; 11608 return (type->data.unionation.decl_node->data.container_decl.auto_enum || 11609 type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr); 11610 } 11611 11612 static void populate_error_set_table(ErrorTableEntry **errors, ZigType *set) { 11613 assert(set->id == ZigTypeIdErrorSet); 11614 for (uint32_t i = 0; i < set->data.error_set.err_count; i += 1) { 11615 ErrorTableEntry *error_entry = set->data.error_set.errors[i]; 11616 assert(errors[error_entry->value] == nullptr); 11617 errors[error_entry->value] = error_entry; 11618 } 11619 } 11620 11621 static ErrorTableEntry *better_documented_error(ErrorTableEntry *preferred, ErrorTableEntry *other) { 11622 if (preferred->decl_node->type == NodeTypeErrorSetField) 11623 return preferred; 11624 if (other->decl_node->type == NodeTypeErrorSetField) 11625 return other; 11626 return preferred; 11627 } 11628 11629 static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigType *set2, 11630 AstNode *source_node) 11631 { 11632 assert(set1->id == ZigTypeIdErrorSet); 11633 assert(set2->id == ZigTypeIdErrorSet); 11634 11635 if (!resolve_inferred_error_set(ira->codegen, set1, source_node)) { 11636 return ira->codegen->builtin_types.entry_invalid; 11637 } 11638 if (!resolve_inferred_error_set(ira->codegen, set2, source_node)) { 11639 return ira->codegen->builtin_types.entry_invalid; 11640 } 11641 if (type_is_global_error_set(set1)) { 11642 return set2; 11643 } 11644 if (type_is_global_error_set(set2)) { 11645 return set1; 11646 } 11647 size_t errors_count = ira->codegen->errors_by_index.length; 11648 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count); 11649 populate_error_set_table(errors, set1); 11650 ZigList<ErrorTableEntry *> intersection_list = {}; 11651 11652 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 11653 buf_resize(&err_set_type->name, 0); 11654 buf_appendf(&err_set_type->name, "error{"); 11655 11656 bool need_comma = false; 11657 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 11658 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 11659 ErrorTableEntry *existing_entry = errors[error_entry->value]; 11660 if (existing_entry != nullptr) { 11661 // prefer the one with docs 11662 const char *comma = need_comma ? "," : ""; 11663 need_comma = true; 11664 ErrorTableEntry *existing_entry_with_docs = better_documented_error(existing_entry, error_entry); 11665 intersection_list.append(existing_entry_with_docs); 11666 buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&existing_entry_with_docs->name)); 11667 } 11668 } 11669 heap::c_allocator.deallocate(errors, errors_count); 11670 11671 err_set_type->data.error_set.err_count = intersection_list.length; 11672 err_set_type->data.error_set.errors = intersection_list.items; 11673 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 11674 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 11675 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 11676 11677 buf_appendf(&err_set_type->name, "}"); 11678 11679 return err_set_type; 11680 } 11681 11682 static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted_type, 11683 ZigType *actual_type, AstNode *source_node, bool wanted_is_mutable) 11684 { 11685 CodeGen *g = ira->codegen; 11686 ConstCastOnly result = {}; 11687 result.id = ConstCastResultIdOk; 11688 11689 Error err; 11690 11691 if (wanted_type == actual_type) 11692 return result; 11693 11694 // If pointers have the same representation in memory, they can be "const-casted". 11695 // `const` attribute can be gained 11696 // `volatile` attribute can be gained 11697 // `allowzero` attribute can be gained (whether from explicit attribute, C pointer, or optional pointer) 11698 // but only if !wanted_is_mutable 11699 // alignment can be decreased 11700 // bit offset attributes must match exactly 11701 // PtrLenSingle/PtrLenUnknown must match exactly, but PtrLenC matches either one 11702 // sentinel-terminated pointers can coerce into PtrLenUnknown 11703 ZigType *wanted_ptr_type = get_src_ptr_type(wanted_type); 11704 ZigType *actual_ptr_type = get_src_ptr_type(actual_type); 11705 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); 11706 bool actual_allows_zero = ptr_allows_addr_zero(actual_type); 11707 bool wanted_is_c_ptr = wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC; 11708 bool actual_is_c_ptr = actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenC; 11709 bool wanted_opt_or_ptr = wanted_ptr_type != nullptr && wanted_ptr_type->id == ZigTypeIdPointer; 11710 bool actual_opt_or_ptr = actual_ptr_type != nullptr && actual_ptr_type->id == ZigTypeIdPointer; 11711 if (wanted_opt_or_ptr && actual_opt_or_ptr) { 11712 bool ok_null_term_ptrs = 11713 wanted_ptr_type->data.pointer.sentinel == nullptr || 11714 (actual_ptr_type->data.pointer.sentinel != nullptr && 11715 const_values_equal(ira->codegen, wanted_ptr_type->data.pointer.sentinel, 11716 actual_ptr_type->data.pointer.sentinel)) || 11717 actual_ptr_type->data.pointer.ptr_len == PtrLenC; 11718 if (!ok_null_term_ptrs) { 11719 result.id = ConstCastResultIdPtrSentinel; 11720 result.data.bad_ptr_sentinel = heap::c_allocator.allocate_nonzero<ConstCastPtrSentinel>(1); 11721 result.data.bad_ptr_sentinel->wanted_type = wanted_ptr_type; 11722 result.data.bad_ptr_sentinel->actual_type = actual_ptr_type; 11723 return result; 11724 } 11725 bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len; 11726 if (!(ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr)) { 11727 result.id = ConstCastResultIdPtrLens; 11728 return result; 11729 } 11730 11731 bool ok_cv_qualifiers = 11732 (!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 11733 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile); 11734 if (!ok_cv_qualifiers) { 11735 result.id = ConstCastResultIdCV; 11736 result.data.bad_cv = heap::c_allocator.allocate_nonzero<ConstCastBadCV>(1); 11737 result.data.bad_cv->wanted_type = wanted_ptr_type; 11738 result.data.bad_cv->actual_type = actual_ptr_type; 11739 return result; 11740 } 11741 11742 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 11743 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 11744 if (child.id == ConstCastResultIdInvalid) 11745 return child; 11746 if (child.id != ConstCastResultIdOk) { 11747 result.id = ConstCastResultIdPointerChild; 11748 result.data.pointer_mismatch = heap::c_allocator.allocate_nonzero<ConstCastPointerMismatch>(1); 11749 result.data.pointer_mismatch->child = child; 11750 result.data.pointer_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 11751 result.data.pointer_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 11752 return result; 11753 } 11754 bool ok_allows_zero = (wanted_allows_zero && 11755 (actual_allows_zero || !wanted_is_mutable)) || 11756 (!wanted_allows_zero && !actual_allows_zero); 11757 if (!ok_allows_zero) { 11758 result.id = ConstCastResultIdBadAllowsZero; 11759 result.data.bad_allows_zero = heap::c_allocator.allocate_nonzero<ConstCastBadAllowsZero>(1); 11760 result.data.bad_allows_zero->wanted_type = wanted_type; 11761 result.data.bad_allows_zero->actual_type = actual_type; 11762 return result; 11763 } 11764 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 11765 result.id = ConstCastResultIdInvalid; 11766 return result; 11767 } 11768 if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 11769 result.id = ConstCastResultIdInvalid; 11770 return result; 11771 } 11772 if ((err = type_resolve(g, wanted_type, ResolveStatusZeroBitsKnown))) { 11773 result.id = ConstCastResultIdInvalid; 11774 return result; 11775 } 11776 if ((err = type_resolve(g, actual_type, ResolveStatusZeroBitsKnown))) { 11777 result.id = ConstCastResultIdInvalid; 11778 return result; 11779 } 11780 if (type_has_bits(g, wanted_type) == type_has_bits(g, actual_type) && 11781 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && 11782 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && 11783 get_ptr_align(ira->codegen, actual_ptr_type) >= get_ptr_align(ira->codegen, wanted_ptr_type)) 11784 { 11785 return result; 11786 } 11787 } 11788 11789 // arrays 11790 if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdArray && 11791 wanted_type->data.array.len == actual_type->data.array.len) 11792 { 11793 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.array.child_type, 11794 actual_type->data.array.child_type, source_node, wanted_is_mutable); 11795 if (child.id == ConstCastResultIdInvalid) 11796 return child; 11797 if (child.id != ConstCastResultIdOk) { 11798 result.id = ConstCastResultIdArrayChild; 11799 result.data.array_mismatch = heap::c_allocator.allocate_nonzero<ConstCastArrayMismatch>(1); 11800 result.data.array_mismatch->child = child; 11801 result.data.array_mismatch->wanted_child = wanted_type->data.array.child_type; 11802 result.data.array_mismatch->actual_child = actual_type->data.array.child_type; 11803 return result; 11804 } 11805 bool ok_null_terminated = (wanted_type->data.array.sentinel == nullptr) || 11806 (actual_type->data.array.sentinel != nullptr && 11807 const_values_equal(ira->codegen, wanted_type->data.array.sentinel, actual_type->data.array.sentinel)); 11808 if (!ok_null_terminated) { 11809 result.id = ConstCastResultIdSentinelArrays; 11810 result.data.sentinel_arrays = heap::c_allocator.allocate_nonzero<ConstCastBadNullTermArrays>(1); 11811 result.data.sentinel_arrays->child = child; 11812 result.data.sentinel_arrays->wanted_type = wanted_type; 11813 result.data.sentinel_arrays->actual_type = actual_type; 11814 return result; 11815 } 11816 return result; 11817 } 11818 11819 // slice const 11820 if (is_slice(wanted_type) && is_slice(actual_type)) { 11821 ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index]->type_entry; 11822 ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry; 11823 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 11824 result.id = ConstCastResultIdInvalid; 11825 return result; 11826 } 11827 if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 11828 result.id = ConstCastResultIdInvalid; 11829 return result; 11830 } 11831 bool ok_sentinels = 11832 wanted_ptr_type->data.pointer.sentinel == nullptr || 11833 (actual_ptr_type->data.pointer.sentinel != nullptr && 11834 const_values_equal(ira->codegen, wanted_ptr_type->data.pointer.sentinel, 11835 actual_ptr_type->data.pointer.sentinel)); 11836 if (!ok_sentinels) { 11837 result.id = ConstCastResultIdPtrSentinel; 11838 result.data.bad_ptr_sentinel = heap::c_allocator.allocate_nonzero<ConstCastPtrSentinel>(1); 11839 result.data.bad_ptr_sentinel->wanted_type = wanted_ptr_type; 11840 result.data.bad_ptr_sentinel->actual_type = actual_ptr_type; 11841 return result; 11842 } 11843 if ((!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 11844 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) && 11845 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && 11846 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && 11847 get_ptr_align(g, actual_ptr_type) >= get_ptr_align(g, wanted_ptr_type)) 11848 { 11849 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 11850 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 11851 if (child.id == ConstCastResultIdInvalid) 11852 return child; 11853 if (child.id != ConstCastResultIdOk) { 11854 result.id = ConstCastResultIdSliceChild; 11855 result.data.slice_mismatch = heap::c_allocator.allocate_nonzero<ConstCastSliceMismatch>(1); 11856 result.data.slice_mismatch->child = child; 11857 result.data.slice_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 11858 result.data.slice_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 11859 } 11860 return result; 11861 } 11862 } 11863 11864 // maybe 11865 if (wanted_type->id == ZigTypeIdOptional && actual_type->id == ZigTypeIdOptional) { 11866 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.maybe.child_type, 11867 actual_type->data.maybe.child_type, source_node, wanted_is_mutable); 11868 if (child.id == ConstCastResultIdInvalid) 11869 return child; 11870 if (child.id != ConstCastResultIdOk) { 11871 result.id = ConstCastResultIdOptionalChild; 11872 result.data.optional = heap::c_allocator.allocate_nonzero<ConstCastOptionalMismatch>(1); 11873 result.data.optional->child = child; 11874 result.data.optional->wanted_child = wanted_type->data.maybe.child_type; 11875 result.data.optional->actual_child = actual_type->data.maybe.child_type; 11876 } 11877 return result; 11878 } 11879 11880 // error union 11881 if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id == ZigTypeIdErrorUnion) { 11882 ConstCastOnly payload_child = types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, 11883 actual_type->data.error_union.payload_type, source_node, wanted_is_mutable); 11884 if (payload_child.id == ConstCastResultIdInvalid) 11885 return payload_child; 11886 if (payload_child.id != ConstCastResultIdOk) { 11887 result.id = ConstCastResultIdErrorUnionPayload; 11888 result.data.error_union_payload = heap::c_allocator.allocate_nonzero<ConstCastErrUnionPayloadMismatch>(1); 11889 result.data.error_union_payload->child = payload_child; 11890 result.data.error_union_payload->wanted_payload = wanted_type->data.error_union.payload_type; 11891 result.data.error_union_payload->actual_payload = actual_type->data.error_union.payload_type; 11892 return result; 11893 } 11894 ConstCastOnly error_set_child = types_match_const_cast_only(ira, wanted_type->data.error_union.err_set_type, 11895 actual_type->data.error_union.err_set_type, source_node, wanted_is_mutable); 11896 if (error_set_child.id == ConstCastResultIdInvalid) 11897 return error_set_child; 11898 if (error_set_child.id != ConstCastResultIdOk) { 11899 result.id = ConstCastResultIdErrorUnionErrorSet; 11900 result.data.error_union_error_set = heap::c_allocator.allocate_nonzero<ConstCastErrUnionErrSetMismatch>(1); 11901 result.data.error_union_error_set->child = error_set_child; 11902 result.data.error_union_error_set->wanted_err_set = wanted_type->data.error_union.err_set_type; 11903 result.data.error_union_error_set->actual_err_set = actual_type->data.error_union.err_set_type; 11904 return result; 11905 } 11906 return result; 11907 } 11908 11909 // error set 11910 if (wanted_type->id == ZigTypeIdErrorSet && actual_type->id == ZigTypeIdErrorSet) { 11911 ZigType *contained_set = actual_type; 11912 ZigType *container_set = wanted_type; 11913 11914 // if the container set is inferred, then this will always work. 11915 if (container_set->data.error_set.infer_fn != nullptr && container_set->data.error_set.incomplete) { 11916 return result; 11917 } 11918 // if the container set is the global one, it will always work. 11919 if (type_is_global_error_set(container_set)) { 11920 return result; 11921 } 11922 11923 if (!resolve_inferred_error_set(ira->codegen, contained_set, source_node)) { 11924 result.id = ConstCastResultIdUnresolvedInferredErrSet; 11925 return result; 11926 } 11927 11928 if (type_is_global_error_set(contained_set)) { 11929 result.id = ConstCastResultIdErrSetGlobal; 11930 return result; 11931 } 11932 11933 size_t errors_count = g->errors_by_index.length; 11934 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count); 11935 for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) { 11936 ErrorTableEntry *error_entry = container_set->data.error_set.errors[i]; 11937 assert(errors[error_entry->value] == nullptr); 11938 errors[error_entry->value] = error_entry; 11939 } 11940 for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) { 11941 ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i]; 11942 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 11943 if (error_entry == nullptr) { 11944 if (result.id == ConstCastResultIdOk) { 11945 result.id = ConstCastResultIdErrSet; 11946 result.data.error_set_mismatch = heap::c_allocator.create<ConstCastErrSetMismatch>(); 11947 } 11948 result.data.error_set_mismatch->missing_errors.append(contained_error_entry); 11949 } 11950 } 11951 heap::c_allocator.deallocate(errors, errors_count); 11952 return result; 11953 } 11954 11955 // fn 11956 if (wanted_type->id == ZigTypeIdFn && 11957 actual_type->id == ZigTypeIdFn) 11958 { 11959 if (wanted_type->data.fn.fn_type_id.alignment > actual_type->data.fn.fn_type_id.alignment) { 11960 result.id = ConstCastResultIdFnAlign; 11961 return result; 11962 } 11963 if (wanted_type->data.fn.fn_type_id.is_var_args != actual_type->data.fn.fn_type_id.is_var_args) { 11964 result.id = ConstCastResultIdFnVarArgs; 11965 return result; 11966 } 11967 if (wanted_type->data.fn.is_generic != actual_type->data.fn.is_generic) { 11968 result.id = ConstCastResultIdFnIsGeneric; 11969 return result; 11970 } 11971 if (!wanted_type->data.fn.is_generic && 11972 actual_type->data.fn.fn_type_id.return_type->id != ZigTypeIdUnreachable) 11973 { 11974 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.fn.fn_type_id.return_type, 11975 actual_type->data.fn.fn_type_id.return_type, source_node, false); 11976 if (child.id == ConstCastResultIdInvalid) 11977 return child; 11978 if (child.id != ConstCastResultIdOk) { 11979 result.id = ConstCastResultIdFnReturnType; 11980 result.data.return_type = heap::c_allocator.allocate_nonzero<ConstCastOnly>(1); 11981 *result.data.return_type = child; 11982 return result; 11983 } 11984 } 11985 if (wanted_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { 11986 result.id = ConstCastResultIdFnArgCount; 11987 return result; 11988 } 11989 if (wanted_type->data.fn.fn_type_id.next_param_index != actual_type->data.fn.fn_type_id.next_param_index) { 11990 result.id = ConstCastResultIdFnGenericArgCount; 11991 return result; 11992 } 11993 assert(wanted_type->data.fn.is_generic || 11994 wanted_type->data.fn.fn_type_id.next_param_index == wanted_type->data.fn.fn_type_id.param_count); 11995 for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.param_count; i += 1) { 11996 // note it's reversed for parameters 11997 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i]; 11998 FnTypeParamInfo *expected_param_info = &wanted_type->data.fn.fn_type_id.param_info[i]; 11999 12000 ConstCastOnly arg_child = types_match_const_cast_only(ira, actual_param_info->type, 12001 expected_param_info->type, source_node, false); 12002 if (arg_child.id == ConstCastResultIdInvalid) 12003 return arg_child; 12004 if (arg_child.id != ConstCastResultIdOk) { 12005 result.id = ConstCastResultIdFnArg; 12006 result.data.fn_arg.arg_index = i; 12007 result.data.fn_arg.actual_param_type = actual_param_info->type; 12008 result.data.fn_arg.expected_param_type = expected_param_info->type; 12009 result.data.fn_arg.child = heap::c_allocator.allocate_nonzero<ConstCastOnly>(1); 12010 *result.data.fn_arg.child = arg_child; 12011 return result; 12012 } 12013 12014 if (expected_param_info->is_noalias != actual_param_info->is_noalias) { 12015 result.id = ConstCastResultIdFnArgNoAlias; 12016 result.data.arg_no_alias.arg_index = i; 12017 return result; 12018 } 12019 } 12020 if (wanted_type->data.fn.fn_type_id.cc != actual_type->data.fn.fn_type_id.cc) { 12021 // ConstCastResultIdFnCC is guaranteed to be the last one reported, meaning everything else is ok. 12022 result.id = ConstCastResultIdFnCC; 12023 return result; 12024 } 12025 return result; 12026 } 12027 12028 if (wanted_type->id == ZigTypeIdInt && actual_type->id == ZigTypeIdInt) { 12029 if (wanted_type->data.integral.is_signed != actual_type->data.integral.is_signed || 12030 wanted_type->data.integral.bit_count != actual_type->data.integral.bit_count) 12031 { 12032 result.id = ConstCastResultIdIntShorten; 12033 result.data.int_shorten = heap::c_allocator.allocate_nonzero<ConstCastIntShorten>(1); 12034 result.data.int_shorten->wanted_type = wanted_type; 12035 result.data.int_shorten->actual_type = actual_type; 12036 return result; 12037 } 12038 return result; 12039 } 12040 12041 result.id = ConstCastResultIdType; 12042 result.data.type_mismatch = heap::c_allocator.allocate_nonzero<ConstCastTypeMismatch>(1); 12043 result.data.type_mismatch->wanted_type = wanted_type; 12044 result.data.type_mismatch->actual_type = actual_type; 12045 return result; 12046 } 12047 12048 static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) { 12049 size_t old_errors_count = *errors_count; 12050 *errors_count = g->errors_by_index.length; 12051 *errors = heap::c_allocator.reallocate(*errors, old_errors_count, *errors_count); 12052 } 12053 12054 static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigType *expected_type, 12055 IrInstGen **instructions, size_t instruction_count) 12056 { 12057 Error err; 12058 assert(instruction_count >= 1); 12059 IrInstGen *prev_inst; 12060 size_t i = 0; 12061 for (;;) { 12062 prev_inst = instructions[i]; 12063 if (type_is_invalid(prev_inst->value->type)) { 12064 return ira->codegen->builtin_types.entry_invalid; 12065 } 12066 if (prev_inst->value->type->id == ZigTypeIdUnreachable) { 12067 i += 1; 12068 if (i == instruction_count) { 12069 return prev_inst->value->type; 12070 } 12071 continue; 12072 } 12073 break; 12074 } 12075 ErrorTableEntry **errors = nullptr; 12076 size_t errors_count = 0; 12077 ZigType *err_set_type = nullptr; 12078 if (prev_inst->value->type->id == ZigTypeIdErrorSet) { 12079 if (!resolve_inferred_error_set(ira->codegen, prev_inst->value->type, prev_inst->base.source_node)) { 12080 return ira->codegen->builtin_types.entry_invalid; 12081 } 12082 if (type_is_global_error_set(prev_inst->value->type)) { 12083 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12084 } else { 12085 err_set_type = prev_inst->value->type; 12086 update_errors_helper(ira->codegen, &errors, &errors_count); 12087 12088 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12089 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 12090 assert(errors[error_entry->value] == nullptr); 12091 errors[error_entry->value] = error_entry; 12092 } 12093 } 12094 } 12095 12096 bool any_are_null = (prev_inst->value->type->id == ZigTypeIdNull); 12097 bool convert_to_const_slice = false; 12098 bool make_the_slice_const = false; 12099 bool make_the_pointer_const = false; 12100 for (; i < instruction_count; i += 1) { 12101 IrInstGen *cur_inst = instructions[i]; 12102 ZigType *cur_type = cur_inst->value->type; 12103 ZigType *prev_type = prev_inst->value->type; 12104 12105 if (type_is_invalid(cur_type)) { 12106 return cur_type; 12107 } 12108 12109 if (prev_type == cur_type) { 12110 continue; 12111 } 12112 12113 if (prev_type->id == ZigTypeIdUnreachable) { 12114 prev_inst = cur_inst; 12115 continue; 12116 } 12117 12118 if (cur_type->id == ZigTypeIdUnreachable) { 12119 continue; 12120 } 12121 12122 if (prev_type->id == ZigTypeIdErrorSet) { 12123 ir_assert_gen(err_set_type != nullptr, prev_inst); 12124 if (cur_type->id == ZigTypeIdErrorSet) { 12125 if (type_is_global_error_set(err_set_type)) { 12126 continue; 12127 } 12128 bool allow_infer = cur_type->data.error_set.infer_fn != nullptr && 12129 cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12130 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) { 12131 return ira->codegen->builtin_types.entry_invalid; 12132 } 12133 if (!allow_infer && type_is_global_error_set(cur_type)) { 12134 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12135 prev_inst = cur_inst; 12136 continue; 12137 } 12138 12139 // number of declared errors might have increased now 12140 update_errors_helper(ira->codegen, &errors, &errors_count); 12141 12142 // if err_set_type is a superset of cur_type, keep err_set_type. 12143 // if cur_type is a superset of err_set_type, switch err_set_type to cur_type 12144 bool prev_is_superset = true; 12145 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 12146 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 12147 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 12148 if (error_entry == nullptr) { 12149 prev_is_superset = false; 12150 break; 12151 } 12152 } 12153 if (prev_is_superset) { 12154 continue; 12155 } 12156 12157 // unset everything in errors 12158 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12159 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 12160 errors[error_entry->value] = nullptr; 12161 } 12162 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 12163 assert(errors[i] == nullptr); 12164 } 12165 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 12166 ErrorTableEntry *error_entry = cur_type->data.error_set.errors[i]; 12167 assert(errors[error_entry->value] == nullptr); 12168 errors[error_entry->value] = error_entry; 12169 } 12170 bool cur_is_superset = true; 12171 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12172 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 12173 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 12174 if (error_entry == nullptr) { 12175 cur_is_superset = false; 12176 break; 12177 } 12178 } 12179 if (cur_is_superset) { 12180 err_set_type = cur_type; 12181 prev_inst = cur_inst; 12182 assert(errors != nullptr); 12183 continue; 12184 } 12185 12186 // neither of them are supersets. so we invent a new error set type that is a union of both of them 12187 err_set_type = get_error_set_union(ira->codegen, errors, cur_type, err_set_type, nullptr); 12188 assert(errors != nullptr); 12189 continue; 12190 } else if (cur_type->id == ZigTypeIdErrorUnion) { 12191 if (type_is_global_error_set(err_set_type)) { 12192 prev_inst = cur_inst; 12193 continue; 12194 } 12195 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 12196 bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr && 12197 cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12198 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) { 12199 return ira->codegen->builtin_types.entry_invalid; 12200 } 12201 if (!allow_infer && type_is_global_error_set(cur_err_set_type)) { 12202 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12203 prev_inst = cur_inst; 12204 continue; 12205 } 12206 12207 update_errors_helper(ira->codegen, &errors, &errors_count); 12208 12209 // test if err_set_type is a subset of cur_type's error set 12210 // unset everything in errors 12211 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12212 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 12213 errors[error_entry->value] = nullptr; 12214 } 12215 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 12216 assert(errors[i] == nullptr); 12217 } 12218 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 12219 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 12220 assert(errors[error_entry->value] == nullptr); 12221 errors[error_entry->value] = error_entry; 12222 } 12223 bool cur_is_superset = true; 12224 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12225 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 12226 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 12227 if (error_entry == nullptr) { 12228 cur_is_superset = false; 12229 break; 12230 } 12231 } 12232 if (cur_is_superset) { 12233 err_set_type = cur_err_set_type; 12234 prev_inst = cur_inst; 12235 assert(errors != nullptr); 12236 continue; 12237 } 12238 12239 // not a subset. invent new error set type, union of both of them 12240 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, err_set_type, nullptr); 12241 prev_inst = cur_inst; 12242 assert(errors != nullptr); 12243 continue; 12244 } else { 12245 prev_inst = cur_inst; 12246 continue; 12247 } 12248 } 12249 12250 if (cur_type->id == ZigTypeIdErrorSet) { 12251 bool allow_infer = cur_type->data.error_set.infer_fn != nullptr && 12252 cur_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12253 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->base.source_node)) { 12254 return ira->codegen->builtin_types.entry_invalid; 12255 } 12256 if (!allow_infer && type_is_global_error_set(cur_type)) { 12257 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12258 continue; 12259 } 12260 if (err_set_type != nullptr && type_is_global_error_set(err_set_type)) { 12261 continue; 12262 } 12263 12264 update_errors_helper(ira->codegen, &errors, &errors_count); 12265 12266 if (err_set_type == nullptr) { 12267 bool allow_infer = false; 12268 if (prev_type->id == ZigTypeIdErrorUnion) { 12269 err_set_type = prev_type->data.error_union.err_set_type; 12270 allow_infer = err_set_type->data.error_set.infer_fn != nullptr && 12271 err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12272 } else { 12273 err_set_type = cur_type; 12274 } 12275 12276 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, err_set_type, cur_inst->base.source_node)) { 12277 return ira->codegen->builtin_types.entry_invalid; 12278 } 12279 12280 if (!allow_infer && type_is_global_error_set(err_set_type)) { 12281 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12282 continue; 12283 } 12284 12285 update_errors_helper(ira->codegen, &errors, &errors_count); 12286 12287 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12288 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 12289 assert(errors[error_entry->value] == nullptr); 12290 errors[error_entry->value] = error_entry; 12291 } 12292 if (err_set_type == cur_type) { 12293 continue; 12294 } 12295 } 12296 // check if the cur type error set is a subset 12297 bool prev_is_superset = true; 12298 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 12299 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 12300 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 12301 if (error_entry == nullptr) { 12302 prev_is_superset = false; 12303 break; 12304 } 12305 } 12306 if (prev_is_superset) { 12307 continue; 12308 } 12309 // not a subset. invent new error set type, union of both of them 12310 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_type, nullptr); 12311 assert(errors != nullptr); 12312 continue; 12313 } 12314 12315 if (prev_type->id == ZigTypeIdErrorUnion && cur_type->id == ZigTypeIdErrorUnion) { 12316 ZigType *prev_payload_type = prev_type->data.error_union.payload_type; 12317 ZigType *cur_payload_type = cur_type->data.error_union.payload_type; 12318 12319 bool const_cast_prev = types_match_const_cast_only(ira, prev_payload_type, cur_payload_type, 12320 source_node, false).id == ConstCastResultIdOk; 12321 bool const_cast_cur = types_match_const_cast_only(ira, cur_payload_type, prev_payload_type, 12322 source_node, false).id == ConstCastResultIdOk; 12323 12324 if (const_cast_prev || const_cast_cur) { 12325 if (const_cast_cur) { 12326 prev_inst = cur_inst; 12327 } 12328 12329 ZigType *prev_err_set_type = (err_set_type == nullptr) ? prev_type->data.error_union.err_set_type : err_set_type; 12330 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 12331 if (prev_err_set_type == cur_err_set_type) 12332 continue; 12333 12334 bool allow_infer_prev = prev_err_set_type->data.error_set.infer_fn != nullptr && 12335 prev_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12336 bool allow_infer_cur = cur_err_set_type->data.error_set.infer_fn != nullptr && 12337 cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12338 12339 if (!allow_infer_prev && !resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->base.source_node)) { 12340 return ira->codegen->builtin_types.entry_invalid; 12341 } 12342 12343 if (!allow_infer_cur && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) { 12344 return ira->codegen->builtin_types.entry_invalid; 12345 } 12346 12347 if ((!allow_infer_prev && type_is_global_error_set(prev_err_set_type)) || 12348 (!allow_infer_cur && type_is_global_error_set(cur_err_set_type))) 12349 { 12350 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12351 continue; 12352 } 12353 12354 update_errors_helper(ira->codegen, &errors, &errors_count); 12355 12356 if (err_set_type == nullptr) { 12357 err_set_type = prev_err_set_type; 12358 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 12359 ErrorTableEntry *error_entry = prev_err_set_type->data.error_set.errors[i]; 12360 assert(errors[error_entry->value] == nullptr); 12361 errors[error_entry->value] = error_entry; 12362 } 12363 } 12364 bool prev_is_superset = true; 12365 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 12366 ErrorTableEntry *contained_error_entry = cur_err_set_type->data.error_set.errors[i]; 12367 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 12368 if (error_entry == nullptr) { 12369 prev_is_superset = false; 12370 break; 12371 } 12372 } 12373 if (prev_is_superset) { 12374 continue; 12375 } 12376 // unset all the errors 12377 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 12378 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 12379 errors[error_entry->value] = nullptr; 12380 } 12381 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 12382 assert(errors[i] == nullptr); 12383 } 12384 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 12385 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 12386 assert(errors[error_entry->value] == nullptr); 12387 errors[error_entry->value] = error_entry; 12388 } 12389 bool cur_is_superset = true; 12390 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 12391 ErrorTableEntry *contained_error_entry = prev_err_set_type->data.error_set.errors[i]; 12392 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 12393 if (error_entry == nullptr) { 12394 cur_is_superset = false; 12395 break; 12396 } 12397 } 12398 if (cur_is_superset) { 12399 err_set_type = cur_err_set_type; 12400 continue; 12401 } 12402 12403 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, prev_err_set_type, nullptr); 12404 continue; 12405 } 12406 } 12407 12408 if (prev_type->id == ZigTypeIdNull) { 12409 prev_inst = cur_inst; 12410 any_are_null = true; 12411 continue; 12412 } 12413 12414 if (cur_type->id == ZigTypeIdNull) { 12415 any_are_null = true; 12416 continue; 12417 } 12418 12419 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdEnumLiteral) { 12420 TypeEnumField *field = find_enum_type_field(prev_type, cur_inst->value->data.x_enum_literal); 12421 if (field != nullptr) { 12422 continue; 12423 } 12424 } 12425 if (is_tagged_union(prev_type) && cur_type->id == ZigTypeIdEnumLiteral) { 12426 TypeUnionField *field = find_union_type_field(prev_type, cur_inst->value->data.x_enum_literal); 12427 if (field != nullptr) { 12428 continue; 12429 } 12430 } 12431 12432 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdEnumLiteral) { 12433 TypeEnumField *field = find_enum_type_field(cur_type, prev_inst->value->data.x_enum_literal); 12434 if (field != nullptr) { 12435 prev_inst = cur_inst; 12436 continue; 12437 } 12438 } 12439 12440 if (is_tagged_union(cur_type) && prev_type->id == ZigTypeIdEnumLiteral) { 12441 TypeUnionField *field = find_union_type_field(cur_type, prev_inst->value->data.x_enum_literal); 12442 if (field != nullptr) { 12443 prev_inst = cur_inst; 12444 continue; 12445 } 12446 } 12447 12448 if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenC && 12449 (cur_type->id == ZigTypeIdComptimeInt || cur_type->id == ZigTypeIdInt)) 12450 { 12451 continue; 12452 } 12453 12454 if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenC && 12455 (prev_type->id == ZigTypeIdComptimeInt || prev_type->id == ZigTypeIdInt)) 12456 { 12457 prev_inst = cur_inst; 12458 continue; 12459 } 12460 12461 if (prev_type->id == ZigTypeIdPointer && cur_type->id == ZigTypeIdPointer) { 12462 if (prev_type->data.pointer.ptr_len == PtrLenC && 12463 types_match_const_cast_only(ira, prev_type->data.pointer.child_type, 12464 cur_type->data.pointer.child_type, source_node, 12465 !prev_type->data.pointer.is_const).id == ConstCastResultIdOk) 12466 { 12467 continue; 12468 } 12469 if (cur_type->data.pointer.ptr_len == PtrLenC && 12470 types_match_const_cast_only(ira, cur_type->data.pointer.child_type, 12471 prev_type->data.pointer.child_type, source_node, 12472 !cur_type->data.pointer.is_const).id == ConstCastResultIdOk) 12473 { 12474 prev_inst = cur_inst; 12475 continue; 12476 } 12477 } 12478 12479 if (types_match_const_cast_only(ira, prev_type, cur_type, source_node, false).id == ConstCastResultIdOk) { 12480 continue; 12481 } 12482 12483 if (types_match_const_cast_only(ira, cur_type, prev_type, source_node, false).id == ConstCastResultIdOk) { 12484 prev_inst = cur_inst; 12485 continue; 12486 } 12487 12488 if (prev_type->id == ZigTypeIdInt && 12489 cur_type->id == ZigTypeIdInt && 12490 prev_type->data.integral.is_signed == cur_type->data.integral.is_signed) 12491 { 12492 if (cur_type->data.integral.bit_count > prev_type->data.integral.bit_count) { 12493 prev_inst = cur_inst; 12494 } 12495 continue; 12496 } 12497 12498 if (prev_type->id == ZigTypeIdFloat && cur_type->id == ZigTypeIdFloat) { 12499 if (cur_type->data.floating.bit_count > prev_type->data.floating.bit_count) { 12500 prev_inst = cur_inst; 12501 } 12502 continue; 12503 } 12504 12505 if (prev_type->id == ZigTypeIdErrorUnion && 12506 types_match_const_cast_only(ira, prev_type->data.error_union.payload_type, cur_type, 12507 source_node, false).id == ConstCastResultIdOk) 12508 { 12509 continue; 12510 } 12511 12512 if (cur_type->id == ZigTypeIdErrorUnion && 12513 types_match_const_cast_only(ira, cur_type->data.error_union.payload_type, prev_type, 12514 source_node, false).id == ConstCastResultIdOk) 12515 { 12516 if (err_set_type != nullptr) { 12517 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 12518 bool allow_infer = cur_err_set_type->data.error_set.infer_fn != nullptr && 12519 cur_err_set_type->data.error_set.infer_fn == ira->new_irb.exec->fn_entry; 12520 if (!allow_infer && !resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->base.source_node)) { 12521 return ira->codegen->builtin_types.entry_invalid; 12522 } 12523 if ((!allow_infer && type_is_global_error_set(cur_err_set_type)) || 12524 type_is_global_error_set(err_set_type)) 12525 { 12526 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 12527 prev_inst = cur_inst; 12528 continue; 12529 } 12530 12531 update_errors_helper(ira->codegen, &errors, &errors_count); 12532 12533 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_err_set_type, nullptr); 12534 } 12535 prev_inst = cur_inst; 12536 continue; 12537 } 12538 12539 if (prev_type->id == ZigTypeIdOptional && 12540 types_match_const_cast_only(ira, prev_type->data.maybe.child_type, cur_type, 12541 source_node, false).id == ConstCastResultIdOk) 12542 { 12543 continue; 12544 } 12545 12546 if (cur_type->id == ZigTypeIdOptional && 12547 types_match_const_cast_only(ira, cur_type->data.maybe.child_type, prev_type, 12548 source_node, false).id == ConstCastResultIdOk) 12549 { 12550 prev_inst = cur_inst; 12551 continue; 12552 } 12553 12554 if (prev_type->id == ZigTypeIdOptional && 12555 types_match_const_cast_only(ira, cur_type, prev_type->data.maybe.child_type, 12556 source_node, false).id == ConstCastResultIdOk) 12557 { 12558 prev_inst = cur_inst; 12559 any_are_null = true; 12560 continue; 12561 } 12562 12563 if (cur_type->id == ZigTypeIdOptional && 12564 types_match_const_cast_only(ira, prev_type, cur_type->data.maybe.child_type, 12565 source_node, false).id == ConstCastResultIdOk) 12566 { 12567 any_are_null = true; 12568 continue; 12569 } 12570 12571 if (cur_type->id == ZigTypeIdUndefined) { 12572 continue; 12573 } 12574 12575 if (prev_type->id == ZigTypeIdUndefined) { 12576 prev_inst = cur_inst; 12577 continue; 12578 } 12579 12580 if (prev_type->id == ZigTypeIdComptimeInt || 12581 prev_type->id == ZigTypeIdComptimeFloat) 12582 { 12583 if (ir_num_lit_fits_in_other_type(ira, prev_inst, cur_type, false)) { 12584 prev_inst = cur_inst; 12585 continue; 12586 } else { 12587 return ira->codegen->builtin_types.entry_invalid; 12588 } 12589 } 12590 12591 if (cur_type->id == ZigTypeIdComptimeInt || 12592 cur_type->id == ZigTypeIdComptimeFloat) 12593 { 12594 if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type, false)) { 12595 continue; 12596 } else { 12597 return ira->codegen->builtin_types.entry_invalid; 12598 } 12599 } 12600 12601 // *[N]T to [*]T 12602 if (prev_type->id == ZigTypeIdPointer && 12603 prev_type->data.pointer.ptr_len == PtrLenSingle && 12604 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 12605 ((cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenUnknown))) 12606 { 12607 prev_inst = cur_inst; 12608 12609 if (prev_type->data.pointer.is_const && !cur_type->data.pointer.is_const) { 12610 // const array pointer and non-const unknown pointer 12611 make_the_pointer_const = true; 12612 } 12613 continue; 12614 } 12615 12616 // *[N]T to [*]T 12617 if (cur_type->id == ZigTypeIdPointer && 12618 cur_type->data.pointer.ptr_len == PtrLenSingle && 12619 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 12620 ((prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenUnknown))) 12621 { 12622 if (cur_type->data.pointer.is_const && !prev_type->data.pointer.is_const) { 12623 // const array pointer and non-const unknown pointer 12624 make_the_pointer_const = true; 12625 } 12626 continue; 12627 } 12628 12629 // *[N]T to []T 12630 // *[N]T to E![]T 12631 if (cur_type->id == ZigTypeIdPointer && 12632 cur_type->data.pointer.ptr_len == PtrLenSingle && 12633 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 12634 ((prev_type->id == ZigTypeIdErrorUnion && is_slice(prev_type->data.error_union.payload_type)) || 12635 is_slice(prev_type))) 12636 { 12637 ZigType *array_type = cur_type->data.pointer.child_type; 12638 ZigType *slice_type = (prev_type->id == ZigTypeIdErrorUnion) ? 12639 prev_type->data.error_union.payload_type : prev_type; 12640 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 12641 if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 12642 array_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 12643 { 12644 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 || 12645 !cur_type->data.pointer.is_const); 12646 if (!const_ok) make_the_slice_const = true; 12647 convert_to_const_slice = false; 12648 continue; 12649 } 12650 } 12651 12652 // *[N]T to []T 12653 // *[N]T to E![]T 12654 if (prev_type->id == ZigTypeIdPointer && 12655 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 12656 prev_type->data.pointer.ptr_len == PtrLenSingle && 12657 ((cur_type->id == ZigTypeIdErrorUnion && is_slice(cur_type->data.error_union.payload_type)) || 12658 (cur_type->id == ZigTypeIdOptional && is_slice(cur_type->data.maybe.child_type)) || 12659 is_slice(cur_type))) 12660 { 12661 ZigType *array_type = prev_type->data.pointer.child_type; 12662 ZigType *slice_type; 12663 switch (cur_type->id) { 12664 case ZigTypeIdErrorUnion: 12665 slice_type = cur_type->data.error_union.payload_type; 12666 break; 12667 case ZigTypeIdOptional: 12668 slice_type = cur_type->data.maybe.child_type; 12669 break; 12670 default: 12671 slice_type = cur_type; 12672 break; 12673 } 12674 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 12675 if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 12676 array_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 12677 { 12678 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 || 12679 !prev_type->data.pointer.is_const); 12680 if (!const_ok) make_the_slice_const = true; 12681 prev_inst = cur_inst; 12682 convert_to_const_slice = false; 12683 continue; 12684 } 12685 } 12686 12687 // *[N]T and *[M]T 12688 if (cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle && 12689 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 12690 prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenSingle && 12691 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 12692 ( 12693 prev_type->data.pointer.child_type->data.array.sentinel == nullptr || 12694 (cur_type->data.pointer.child_type->data.array.sentinel != nullptr && 12695 const_values_equal(ira->codegen, prev_type->data.pointer.child_type->data.array.sentinel, 12696 cur_type->data.pointer.child_type->data.array.sentinel)) 12697 ) && 12698 types_match_const_cast_only(ira, 12699 cur_type->data.pointer.child_type->data.array.child_type, 12700 prev_type->data.pointer.child_type->data.array.child_type, 12701 source_node, !cur_type->data.pointer.is_const).id == ConstCastResultIdOk) 12702 { 12703 bool const_ok = (cur_type->data.pointer.is_const || !prev_type->data.pointer.is_const || 12704 prev_type->data.pointer.child_type->data.array.len == 0); 12705 if (!const_ok) make_the_slice_const = true; 12706 prev_inst = cur_inst; 12707 convert_to_const_slice = true; 12708 continue; 12709 } 12710 if (prev_type->id == ZigTypeIdPointer && prev_type->data.pointer.ptr_len == PtrLenSingle && 12711 prev_type->data.pointer.child_type->id == ZigTypeIdArray && 12712 cur_type->id == ZigTypeIdPointer && cur_type->data.pointer.ptr_len == PtrLenSingle && 12713 cur_type->data.pointer.child_type->id == ZigTypeIdArray && 12714 ( 12715 cur_type->data.pointer.child_type->data.array.sentinel == nullptr || 12716 (prev_type->data.pointer.child_type->data.array.sentinel != nullptr && 12717 const_values_equal(ira->codegen, cur_type->data.pointer.child_type->data.array.sentinel, 12718 prev_type->data.pointer.child_type->data.array.sentinel)) 12719 ) && 12720 types_match_const_cast_only(ira, 12721 prev_type->data.pointer.child_type->data.array.child_type, 12722 cur_type->data.pointer.child_type->data.array.child_type, 12723 source_node, !prev_type->data.pointer.is_const).id == ConstCastResultIdOk) 12724 { 12725 bool const_ok = (prev_type->data.pointer.is_const || !cur_type->data.pointer.is_const || 12726 cur_type->data.pointer.child_type->data.array.len == 0); 12727 if (!const_ok) make_the_slice_const = true; 12728 convert_to_const_slice = true; 12729 continue; 12730 } 12731 12732 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdUnion && 12733 (cur_type->data.unionation.decl_node->data.container_decl.auto_enum || cur_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 12734 { 12735 if ((err = type_resolve(ira->codegen, cur_type, ResolveStatusZeroBitsKnown))) 12736 return ira->codegen->builtin_types.entry_invalid; 12737 if (cur_type->data.unionation.tag_type == prev_type) { 12738 continue; 12739 } 12740 } 12741 12742 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdUnion && 12743 (prev_type->data.unionation.decl_node->data.container_decl.auto_enum || prev_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 12744 { 12745 if ((err = type_resolve(ira->codegen, prev_type, ResolveStatusZeroBitsKnown))) 12746 return ira->codegen->builtin_types.entry_invalid; 12747 if (prev_type->data.unionation.tag_type == cur_type) { 12748 prev_inst = cur_inst; 12749 continue; 12750 } 12751 } 12752 12753 ErrorMsg *msg = ir_add_error_node(ira, source_node, 12754 buf_sprintf("incompatible types: '%s' and '%s'", 12755 buf_ptr(&prev_type->name), buf_ptr(&cur_type->name))); 12756 add_error_note(ira->codegen, msg, prev_inst->base.source_node, 12757 buf_sprintf("type '%s' here", buf_ptr(&prev_type->name))); 12758 add_error_note(ira->codegen, msg, cur_inst->base.source_node, 12759 buf_sprintf("type '%s' here", buf_ptr(&cur_type->name))); 12760 12761 return ira->codegen->builtin_types.entry_invalid; 12762 } 12763 12764 heap::c_allocator.deallocate(errors, errors_count); 12765 12766 if (convert_to_const_slice) { 12767 if (prev_inst->value->type->id == ZigTypeIdPointer) { 12768 ZigType *array_type = prev_inst->value->type->data.pointer.child_type; 12769 src_assert(array_type->id == ZigTypeIdArray, source_node); 12770 ZigType *ptr_type = get_pointer_to_type_extra2( 12771 ira->codegen, array_type->data.array.child_type, 12772 prev_inst->value->type->data.pointer.is_const || make_the_slice_const, false, 12773 PtrLenUnknown, 12774 0, 0, 0, false, 12775 VECTOR_INDEX_NONE, nullptr, array_type->data.array.sentinel); 12776 ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); 12777 if (err_set_type != nullptr) { 12778 return get_error_union_type(ira->codegen, err_set_type, slice_type); 12779 } else { 12780 return slice_type; 12781 } 12782 } else { 12783 zig_unreachable(); 12784 } 12785 } else if (err_set_type != nullptr) { 12786 if (prev_inst->value->type->id == ZigTypeIdErrorSet) { 12787 return err_set_type; 12788 } else if (prev_inst->value->type->id == ZigTypeIdErrorUnion) { 12789 ZigType *payload_type = prev_inst->value->type->data.error_union.payload_type; 12790 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 12791 return ira->codegen->builtin_types.entry_invalid; 12792 return get_error_union_type(ira->codegen, err_set_type, payload_type); 12793 } else if (expected_type != nullptr && expected_type->id == ZigTypeIdErrorUnion) { 12794 ZigType *payload_type = expected_type->data.error_union.payload_type; 12795 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 12796 return ira->codegen->builtin_types.entry_invalid; 12797 return get_error_union_type(ira->codegen, err_set_type, payload_type); 12798 } else { 12799 if (prev_inst->value->type->id == ZigTypeIdComptimeInt || 12800 prev_inst->value->type->id == ZigTypeIdComptimeFloat) 12801 { 12802 ir_add_error_node(ira, source_node, 12803 buf_sprintf("unable to make error union out of number literal")); 12804 return ira->codegen->builtin_types.entry_invalid; 12805 } else if (prev_inst->value->type->id == ZigTypeIdNull) { 12806 ir_add_error_node(ira, source_node, 12807 buf_sprintf("unable to make error union out of null literal")); 12808 return ira->codegen->builtin_types.entry_invalid; 12809 } else { 12810 if ((err = type_resolve(ira->codegen, prev_inst->value->type, ResolveStatusSizeKnown))) 12811 return ira->codegen->builtin_types.entry_invalid; 12812 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value->type); 12813 } 12814 } 12815 } else if (any_are_null && prev_inst->value->type->id != ZigTypeIdNull) { 12816 if (prev_inst->value->type->id == ZigTypeIdOptional) { 12817 return prev_inst->value->type; 12818 } else { 12819 if ((err = type_resolve(ira->codegen, prev_inst->value->type, ResolveStatusSizeKnown))) 12820 return ira->codegen->builtin_types.entry_invalid; 12821 return get_optional_type(ira->codegen, prev_inst->value->type); 12822 } 12823 } else if (make_the_slice_const) { 12824 ZigType *slice_type; 12825 if (prev_inst->value->type->id == ZigTypeIdErrorUnion) { 12826 slice_type = prev_inst->value->type->data.error_union.payload_type; 12827 } else if (is_slice(prev_inst->value->type)) { 12828 slice_type = prev_inst->value->type; 12829 } else { 12830 zig_unreachable(); 12831 } 12832 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 12833 ZigType *adjusted_ptr_type = adjust_ptr_const(ira->codegen, slice_ptr_type, make_the_slice_const); 12834 ZigType *adjusted_slice_type = get_slice_type(ira->codegen, adjusted_ptr_type); 12835 if (prev_inst->value->type->id == ZigTypeIdErrorUnion) { 12836 return get_error_union_type(ira->codegen, prev_inst->value->type->data.error_union.err_set_type, 12837 adjusted_slice_type); 12838 } else if (is_slice(prev_inst->value->type)) { 12839 return adjusted_slice_type; 12840 } else { 12841 zig_unreachable(); 12842 } 12843 } else if (make_the_pointer_const) { 12844 return adjust_ptr_const(ira->codegen, prev_inst->value->type, make_the_pointer_const); 12845 } else { 12846 return prev_inst->value->type; 12847 } 12848 } 12849 12850 static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInst *source_instr, 12851 CastOp cast_op, 12852 ZigValue *other_val, ZigType *other_type, 12853 ZigValue *const_val, ZigType *new_type) 12854 { 12855 const_val->special = other_val->special; 12856 12857 assert(other_val != const_val); 12858 switch (cast_op) { 12859 case CastOpNoCast: 12860 zig_unreachable(); 12861 case CastOpErrSet: 12862 case CastOpBitCast: 12863 zig_panic("TODO"); 12864 case CastOpNoop: { 12865 copy_const_val(ira->codegen, const_val, other_val); 12866 const_val->type = new_type; 12867 break; 12868 } 12869 case CastOpNumLitToConcrete: 12870 if (other_val->type->id == ZigTypeIdComptimeFloat) { 12871 assert(new_type->id == ZigTypeIdFloat); 12872 switch (new_type->data.floating.bit_count) { 12873 case 16: 12874 const_val->data.x_f16 = bigfloat_to_f16(&other_val->data.x_bigfloat); 12875 break; 12876 case 32: 12877 const_val->data.x_f32 = bigfloat_to_f32(&other_val->data.x_bigfloat); 12878 break; 12879 case 64: 12880 const_val->data.x_f64 = bigfloat_to_f64(&other_val->data.x_bigfloat); 12881 break; 12882 case 80: 12883 zig_panic("TODO"); 12884 case 128: 12885 const_val->data.x_f128 = bigfloat_to_f128(&other_val->data.x_bigfloat); 12886 break; 12887 default: 12888 zig_unreachable(); 12889 } 12890 } else if (other_val->type->id == ZigTypeIdComptimeInt) { 12891 bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint); 12892 } else { 12893 zig_unreachable(); 12894 } 12895 const_val->type = new_type; 12896 break; 12897 case CastOpIntToFloat: 12898 if (new_type->id == ZigTypeIdFloat) { 12899 BigFloat bigfloat; 12900 bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint); 12901 switch (new_type->data.floating.bit_count) { 12902 case 16: 12903 const_val->data.x_f16 = bigfloat_to_f16(&bigfloat); 12904 break; 12905 case 32: 12906 const_val->data.x_f32 = bigfloat_to_f32(&bigfloat); 12907 break; 12908 case 64: 12909 const_val->data.x_f64 = bigfloat_to_f64(&bigfloat); 12910 break; 12911 case 80: 12912 zig_panic("TODO"); 12913 case 128: 12914 const_val->data.x_f128 = bigfloat_to_f128(&bigfloat); 12915 break; 12916 default: 12917 zig_unreachable(); 12918 } 12919 } else if (new_type->id == ZigTypeIdComptimeFloat) { 12920 bigfloat_init_bigint(&const_val->data.x_bigfloat, &other_val->data.x_bigint); 12921 } else { 12922 zig_unreachable(); 12923 } 12924 const_val->special = ConstValSpecialStatic; 12925 break; 12926 case CastOpFloatToInt: 12927 float_init_bigint(&const_val->data.x_bigint, other_val); 12928 if (new_type->id == ZigTypeIdInt) { 12929 if (!bigint_fits_in_bits(&const_val->data.x_bigint, new_type->data.integral.bit_count, 12930 new_type->data.integral.is_signed)) 12931 { 12932 Buf *int_buf = buf_alloc(); 12933 bigint_append_buf(int_buf, &const_val->data.x_bigint, 10); 12934 12935 ir_add_error(ira, source_instr, 12936 buf_sprintf("integer value '%s' cannot be stored in type '%s'", 12937 buf_ptr(int_buf), buf_ptr(&new_type->name))); 12938 return false; 12939 } 12940 } 12941 12942 const_val->special = ConstValSpecialStatic; 12943 break; 12944 case CastOpBoolToInt: 12945 bigint_init_unsigned(&const_val->data.x_bigint, other_val->data.x_bool ? 1 : 0); 12946 const_val->special = ConstValSpecialStatic; 12947 break; 12948 } 12949 return true; 12950 } 12951 12952 static IrInstGen *ir_const(IrAnalyze *ira, IrInst *inst, ZigType *ty) { 12953 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 12954 inst->scope, inst->source_node); 12955 IrInstGen *new_instruction = &const_instruction->base; 12956 new_instruction->value->type = ty; 12957 new_instruction->value->special = ConstValSpecialStatic; 12958 ira->new_irb.constants.append(&heap::c_allocator, const_instruction); 12959 return new_instruction; 12960 } 12961 12962 static IrInstGen *ir_const_noval(IrAnalyze *ira, IrInst *old_instruction) { 12963 IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb, 12964 old_instruction->scope, old_instruction->source_node); 12965 ira->new_irb.constants.append(&heap::c_allocator, const_instruction); 12966 return &const_instruction->base; 12967 } 12968 12969 // This function initializes the new IrInstGen with the provided ZigValue, 12970 // rather than creating a new one. 12971 static IrInstGen *ir_const_move(IrAnalyze *ira, IrInst *old_instruction, ZigValue *val) { 12972 IrInstGen *result = ir_const_noval(ira, old_instruction); 12973 result->value = val; 12974 return result; 12975 } 12976 12977 static IrInstGen *ir_resolve_cast(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, 12978 ZigType *wanted_type, CastOp cast_op) 12979 { 12980 if (instr_is_comptime(value) || !type_has_bits(ira->codegen, wanted_type)) { 12981 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 12982 if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, value->value, value->value->type, 12983 result->value, wanted_type)) 12984 { 12985 return ira->codegen->invalid_inst_gen; 12986 } 12987 return result; 12988 } else { 12989 return ir_build_cast(ira, source_instr, wanted_type, value, cast_op); 12990 } 12991 } 12992 12993 static IrInstGen *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, IrInst* source_instr, 12994 IrInstGen *value, ZigType *wanted_type) 12995 { 12996 ir_assert(value->value->type->id == ZigTypeIdPointer, source_instr); 12997 12998 Error err; 12999 13000 if ((err = type_resolve(ira->codegen, value->value->type->data.pointer.child_type, 13001 ResolveStatusAlignmentKnown))) 13002 { 13003 return ira->codegen->invalid_inst_gen; 13004 } 13005 13006 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value->type)); 13007 13008 if (instr_is_comptime(value)) { 13009 ZigValue *val = ir_resolve_const(ira, value, UndefOk); 13010 if (val == nullptr) 13011 return ira->codegen->invalid_inst_gen; 13012 if (val->special == ConstValSpecialUndef) 13013 return ir_const_undef(ira, source_instr, wanted_type); 13014 13015 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 13016 if (pointee == nullptr) 13017 return ira->codegen->invalid_inst_gen; 13018 if (pointee->special != ConstValSpecialRuntime) { 13019 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13020 result->value->data.x_ptr.special = ConstPtrSpecialBaseArray; 13021 result->value->data.x_ptr.mut = val->data.x_ptr.mut; 13022 result->value->data.x_ptr.data.base_array.array_val = pointee; 13023 result->value->data.x_ptr.data.base_array.elem_index = 0; 13024 return result; 13025 } 13026 } 13027 13028 return ir_build_cast(ira, source_instr, wanted_type, value, CastOpBitCast); 13029 } 13030 13031 static IrInstGen *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInst* source_instr, 13032 IrInstGen *array_ptr, ZigType *wanted_type, ResultLoc *result_loc) 13033 { 13034 Error err; 13035 13036 assert(array_ptr->value->type->id == ZigTypeIdPointer); 13037 assert(array_ptr->value->type->data.pointer.child_type->id == ZigTypeIdArray); 13038 13039 ZigType *array_type = array_ptr->value->type->data.pointer.child_type; 13040 size_t array_len = array_type->data.array.len; 13041 13042 // A zero-sized array can be casted regardless of the destination alignment, or 13043 // whether the pointer is undefined, and the result is always comptime known. 13044 // TODO However, this is exposing a result location bug that I failed to solve on the first try. 13045 // If you want to try to fix the bug, uncomment this block and get the tests passing. 13046 //if (array_len == 0 && array_type->data.array.sentinel == nullptr) { 13047 // ZigValue *undef_array = ira->codegen->pass1_arena->create<ZigValue>(); 13048 // undef_array->special = ConstValSpecialUndef; 13049 // undef_array->type = array_type; 13050 13051 // IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13052 // init_const_slice(ira->codegen, result->value, undef_array, 0, 0, false); 13053 // result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutComptimeConst; 13054 // result->value->type = wanted_type; 13055 // return result; 13056 //} 13057 13058 if ((err = type_resolve(ira->codegen, array_ptr->value->type, ResolveStatusAlignmentKnown))) { 13059 return ira->codegen->invalid_inst_gen; 13060 } 13061 13062 if (array_len != 0) { 13063 wanted_type = adjust_slice_align(ira->codegen, wanted_type, 13064 get_ptr_align(ira->codegen, array_ptr->value->type)); 13065 } 13066 13067 if (instr_is_comptime(array_ptr)) { 13068 UndefAllowed undef_allowed = (array_len == 0) ? UndefOk : UndefBad; 13069 ZigValue *array_ptr_val = ir_resolve_const(ira, array_ptr, undef_allowed); 13070 if (array_ptr_val == nullptr) 13071 return ira->codegen->invalid_inst_gen; 13072 ir_assert(is_slice(wanted_type), source_instr); 13073 if (array_ptr_val->special == ConstValSpecialUndef) { 13074 ZigValue *undef_array = ira->codegen->pass1_arena->create<ZigValue>(); 13075 undef_array->special = ConstValSpecialUndef; 13076 undef_array->type = array_type; 13077 13078 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13079 init_const_slice(ira->codegen, result->value, undef_array, 0, 0, false); 13080 result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutComptimeConst; 13081 result->value->type = wanted_type; 13082 return result; 13083 } 13084 bool wanted_const = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.is_const; 13085 // Optimization to avoid creating unnecessary ZigValue in const_ptr_pointee 13086 if (array_ptr_val->data.x_ptr.special == ConstPtrSpecialSubArray) { 13087 ZigValue *array_val = array_ptr_val->data.x_ptr.data.base_array.array_val; 13088 if (array_val->special != ConstValSpecialRuntime) { 13089 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13090 init_const_slice(ira->codegen, result->value, array_val, 13091 array_ptr_val->data.x_ptr.data.base_array.elem_index, 13092 array_type->data.array.len, wanted_const); 13093 result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; 13094 result->value->type = wanted_type; 13095 return result; 13096 } 13097 } else if (array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 13098 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, array_ptr_val, source_instr->source_node); 13099 if (pointee == nullptr) 13100 return ira->codegen->invalid_inst_gen; 13101 if (pointee->special != ConstValSpecialRuntime) { 13102 assert(array_ptr_val->type->id == ZigTypeIdPointer); 13103 13104 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13105 init_const_slice(ira->codegen, result->value, pointee, 0, array_type->data.array.len, wanted_const); 13106 result->value->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; 13107 result->value->type = wanted_type; 13108 return result; 13109 } 13110 } 13111 } 13112 13113 if (result_loc == nullptr) result_loc = no_result_loc(); 13114 IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); 13115 if (type_is_invalid(result_loc_inst->value->type) || 13116 result_loc_inst->value->type->id == ZigTypeIdUnreachable) 13117 { 13118 return result_loc_inst; 13119 } 13120 return ir_build_ptr_of_array_to_slice(ira, source_instr, wanted_type, array_ptr, result_loc_inst); 13121 } 13122 13123 static IrBasicBlockGen *ir_get_new_bb(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrInst *ref_old_instruction) { 13124 assert(old_bb); 13125 13126 if (old_bb->child) { 13127 if (ref_old_instruction == nullptr || old_bb->child->ref_instruction != ref_old_instruction) { 13128 return old_bb->child; 13129 } 13130 } 13131 13132 IrBasicBlockGen *new_bb = ir_build_bb_from(ira, old_bb); 13133 new_bb->ref_instruction = ref_old_instruction; 13134 13135 return new_bb; 13136 } 13137 13138 static IrBasicBlockGen *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrInst *ref_old_instruction) { 13139 assert(ref_old_instruction != nullptr); 13140 IrBasicBlockGen *new_bb = ir_get_new_bb(ira, old_bb, ref_old_instruction); 13141 if (new_bb->must_be_comptime_source_instr) { 13142 ErrorMsg *msg = ir_add_error(ira, ref_old_instruction, 13143 buf_sprintf("control flow attempts to use compile-time variable at runtime")); 13144 add_error_note(ira->codegen, msg, new_bb->must_be_comptime_source_instr->source_node, 13145 buf_sprintf("compile-time variable assigned here")); 13146 return nullptr; 13147 } 13148 return new_bb; 13149 } 13150 13151 static void ir_start_bb(IrAnalyze *ira, IrBasicBlockSrc *old_bb, IrBasicBlockSrc *const_predecessor_bb) { 13152 ir_assert(!old_bb->suspended, (old_bb->instruction_list.length != 0) ? &old_bb->instruction_list.at(0)->base : nullptr); 13153 ira->instruction_index = 0; 13154 ira->old_irb.current_basic_block = old_bb; 13155 ira->const_predecessor_bb = const_predecessor_bb; 13156 ira->old_bb_index = old_bb->index; 13157 } 13158 13159 static IrInstGen *ira_suspend(IrAnalyze *ira, IrInst *old_instruction, IrBasicBlockSrc *next_bb, 13160 IrSuspendPosition *suspend_pos) 13161 { 13162 if (ira->codegen->verbose_ir) { 13163 fprintf(stderr, "suspend %s_%" PRIu32 " %s_%" PRIu32 " #%" PRIu32 " (%zu,%zu)\n", 13164 ira->old_irb.current_basic_block->name_hint, 13165 ira->old_irb.current_basic_block->debug_id, 13166 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint, 13167 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id, 13168 ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->base.debug_id, 13169 ira->old_bb_index, ira->instruction_index); 13170 } 13171 suspend_pos->basic_block_index = ira->old_bb_index; 13172 suspend_pos->instruction_index = ira->instruction_index; 13173 13174 ira->old_irb.current_basic_block->suspended = true; 13175 13176 // null next_bb means that the caller plans to call ira_resume before returning 13177 if (next_bb != nullptr) { 13178 ira->old_bb_index = next_bb->index; 13179 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 13180 assert(ira->old_irb.current_basic_block == next_bb); 13181 ira->instruction_index = 0; 13182 ira->const_predecessor_bb = nullptr; 13183 next_bb->child = ir_get_new_bb_runtime(ira, next_bb, old_instruction); 13184 ira->new_irb.current_basic_block = next_bb->child; 13185 } 13186 return ira->codegen->unreach_instruction; 13187 } 13188 13189 static IrInstGen *ira_resume(IrAnalyze *ira) { 13190 IrSuspendPosition pos = ira->resume_stack.pop(); 13191 if (ira->codegen->verbose_ir) { 13192 fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index); 13193 } 13194 ira->old_bb_index = pos.basic_block_index; 13195 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 13196 assert(ira->old_irb.current_basic_block->in_resume_stack); 13197 ira->old_irb.current_basic_block->in_resume_stack = false; 13198 ira->old_irb.current_basic_block->suspended = false; 13199 ira->instruction_index = pos.instruction_index; 13200 assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length); 13201 if (ira->codegen->verbose_ir) { 13202 fprintf(stderr, "%s_%" PRIu32 " #%" PRIu32 "\n", ira->old_irb.current_basic_block->name_hint, 13203 ira->old_irb.current_basic_block->debug_id, 13204 ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->base.debug_id); 13205 } 13206 ira->const_predecessor_bb = nullptr; 13207 ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->child; 13208 assert(ira->new_irb.current_basic_block != nullptr); 13209 return ira->codegen->unreach_instruction; 13210 } 13211 13212 static void ir_start_next_bb(IrAnalyze *ira) { 13213 ira->old_bb_index += 1; 13214 13215 bool need_repeat = true; 13216 for (;;) { 13217 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 13218 IrBasicBlockSrc *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 13219 if (old_bb->child == nullptr && old_bb->suspend_instruction_ref == nullptr) { 13220 ira->old_bb_index += 1; 13221 continue; 13222 } 13223 // if it's already started, or 13224 // if it's a suspended block, 13225 // then skip it 13226 if (old_bb->suspended || 13227 (old_bb->child != nullptr && old_bb->child->instruction_list.length != 0) || 13228 (old_bb->child != nullptr && old_bb->child->already_appended)) 13229 { 13230 ira->old_bb_index += 1; 13231 continue; 13232 } 13233 13234 // if there is a resume_stack, pop one from there rather than moving on. 13235 // the last item of the resume stack will be a basic block that will 13236 // move on to the next one below 13237 if (ira->resume_stack.length != 0) { 13238 ira_resume(ira); 13239 return; 13240 } 13241 13242 if (old_bb->child == nullptr) { 13243 old_bb->child = ir_get_new_bb_runtime(ira, old_bb, old_bb->suspend_instruction_ref); 13244 } 13245 ira->new_irb.current_basic_block = old_bb->child; 13246 ir_start_bb(ira, old_bb, nullptr); 13247 return; 13248 } 13249 if (!need_repeat) { 13250 if (ira->resume_stack.length != 0) { 13251 ira_resume(ira); 13252 } 13253 return; 13254 } 13255 need_repeat = false; 13256 ira->old_bb_index = 0; 13257 continue; 13258 } 13259 } 13260 13261 static void ir_finish_bb(IrAnalyze *ira) { 13262 if (!ira->new_irb.current_basic_block->already_appended) { 13263 ir_append_basic_block_gen(&ira->new_irb, ira->new_irb.current_basic_block); 13264 if (ira->codegen->verbose_ir) { 13265 fprintf(stderr, "append new bb %s_%" PRIu32 "\n", ira->new_irb.current_basic_block->name_hint, 13266 ira->new_irb.current_basic_block->debug_id); 13267 } 13268 } 13269 ira->instruction_index += 1; 13270 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { 13271 IrInstSrc *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 13272 if (!next_instruction->is_gen) { 13273 ir_add_error(ira, &next_instruction->base, buf_sprintf("unreachable code")); 13274 break; 13275 } 13276 ira->instruction_index += 1; 13277 } 13278 13279 ir_start_next_bb(ira); 13280 } 13281 13282 static IrInstGen *ir_unreach_error(IrAnalyze *ira) { 13283 ira->old_bb_index = SIZE_MAX; 13284 if (ira->new_irb.exec->first_err_trace_msg == nullptr) { 13285 ira->new_irb.exec->first_err_trace_msg = ira->codegen->trace_err; 13286 } 13287 return ira->codegen->unreach_instruction; 13288 } 13289 13290 static bool ir_emit_backward_branch(IrAnalyze *ira, IrInst* source_instruction) { 13291 size_t *bbc = ira->new_irb.exec->backward_branch_count; 13292 size_t *quota = ira->new_irb.exec->backward_branch_quota; 13293 13294 // If we're already over quota, we've already given an error message for this. 13295 if (*bbc > *quota) { 13296 assert(ira->codegen->errors.length > 0); 13297 return false; 13298 } 13299 13300 *bbc += 1; 13301 if (*bbc > *quota) { 13302 ir_add_error(ira, source_instruction, 13303 buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", *quota)); 13304 return false; 13305 } 13306 return true; 13307 } 13308 13309 static IrInstGen *ir_inline_bb(IrAnalyze *ira, IrInst* source_instruction, IrBasicBlockSrc *old_bb) { 13310 if (old_bb->debug_id <= ira->old_irb.current_basic_block->debug_id) { 13311 if (!ir_emit_backward_branch(ira, source_instruction)) 13312 return ir_unreach_error(ira); 13313 } 13314 13315 old_bb->child = ira->old_irb.current_basic_block->child; 13316 ir_start_bb(ira, old_bb, ira->old_irb.current_basic_block); 13317 return ira->codegen->unreach_instruction; 13318 } 13319 13320 static IrInstGen *ir_finish_anal(IrAnalyze *ira, IrInstGen *instruction) { 13321 if (instruction->value->type->id == ZigTypeIdUnreachable) 13322 ir_finish_bb(ira); 13323 return instruction; 13324 } 13325 13326 static IrInstGen *ir_const_fn(IrAnalyze *ira, IrInst *source_instr, ZigFn *fn_entry) { 13327 IrInstGen *result = ir_const(ira, source_instr, fn_entry->type_entry); 13328 result->value->special = ConstValSpecialStatic; 13329 result->value->data.x_ptr.data.fn.fn_entry = fn_entry; 13330 result->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 13331 result->value->data.x_ptr.special = ConstPtrSpecialFunction; 13332 return result; 13333 } 13334 13335 static IrInstGen *ir_const_bound_fn(IrAnalyze *ira, IrInst *src_inst, ZigFn *fn_entry, IrInstGen *first_arg, 13336 IrInst *first_arg_src) 13337 { 13338 // This is unfortunately required to avoid improperly freeing first_arg_src 13339 ira_ref(ira); 13340 13341 IrInstGen *result = ir_const(ira, src_inst, get_bound_fn_type(ira->codegen, fn_entry)); 13342 result->value->data.x_bound_fn.fn = fn_entry; 13343 result->value->data.x_bound_fn.first_arg = first_arg; 13344 result->value->data.x_bound_fn.first_arg_src = first_arg_src; 13345 return result; 13346 } 13347 13348 static IrInstGen *ir_const_type(IrAnalyze *ira, IrInst *source_instruction, ZigType *ty) { 13349 IrInstGen *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_type); 13350 result->value->data.x_type = ty; 13351 return result; 13352 } 13353 13354 static IrInstGen *ir_const_bool(IrAnalyze *ira, IrInst *source_instruction, bool value) { 13355 IrInstGen *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_bool); 13356 result->value->data.x_bool = value; 13357 return result; 13358 } 13359 13360 static IrInstGen *ir_const_undef(IrAnalyze *ira, IrInst *source_instruction, ZigType *ty) { 13361 IrInstGen *result = ir_const(ira, source_instruction, ty); 13362 result->value->special = ConstValSpecialUndef; 13363 return result; 13364 } 13365 13366 static IrInstGen *ir_const_unreachable(IrAnalyze *ira, IrInst *source_instruction) { 13367 IrInstGen *result = ir_const_noval(ira, source_instruction); 13368 result->value = ira->codegen->intern.for_unreachable(); 13369 return result; 13370 } 13371 13372 static IrInstGen *ir_const_void(IrAnalyze *ira, IrInst *source_instruction) { 13373 IrInstGen *result = ir_const_noval(ira, source_instruction); 13374 result->value = ira->codegen->intern.for_void(); 13375 return result; 13376 } 13377 13378 static IrInstGen *ir_const_unsigned(IrAnalyze *ira, IrInst *source_instruction, uint64_t value) { 13379 IrInstGen *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_num_lit_int); 13380 bigint_init_unsigned(&result->value->data.x_bigint, value); 13381 return result; 13382 } 13383 13384 static IrInstGen *ir_get_const_ptr(IrAnalyze *ira, IrInst *instruction, 13385 ZigValue *pointee, ZigType *pointee_type, 13386 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align) 13387 { 13388 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type, 13389 ptr_is_const, ptr_is_volatile, PtrLenSingle, ptr_align, 0, 0, false); 13390 IrInstGen *const_instr = ir_const(ira, instruction, ptr_type); 13391 ZigValue *const_val = const_instr->value; 13392 const_val->data.x_ptr.special = ConstPtrSpecialRef; 13393 const_val->data.x_ptr.mut = ptr_mut; 13394 const_val->data.x_ptr.data.ref.pointee = pointee; 13395 return const_instr; 13396 } 13397 13398 static Error ir_resolve_const_val(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, 13399 ZigValue *val, UndefAllowed undef_allowed) 13400 { 13401 Error err; 13402 for (;;) { 13403 switch (val->special) { 13404 case ConstValSpecialStatic: 13405 return ErrorNone; 13406 case ConstValSpecialRuntime: 13407 if (!type_has_bits(codegen, val->type)) 13408 return ErrorNone; 13409 13410 exec_add_error_node_gen(codegen, exec, source_node, 13411 buf_sprintf("unable to evaluate constant expression")); 13412 return ErrorSemanticAnalyzeFail; 13413 case ConstValSpecialUndef: 13414 if (undef_allowed == UndefOk || undef_allowed == LazyOk) 13415 return ErrorNone; 13416 13417 exec_add_error_node_gen(codegen, exec, source_node, 13418 buf_sprintf("use of undefined value here causes undefined behavior")); 13419 return ErrorSemanticAnalyzeFail; 13420 case ConstValSpecialLazy: 13421 if (undef_allowed == LazyOk || undef_allowed == LazyOkNoUndef) 13422 return ErrorNone; 13423 13424 if ((err = ir_resolve_lazy(codegen, source_node, val))) 13425 return err; 13426 13427 continue; 13428 } 13429 } 13430 } 13431 13432 static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed undef_allowed) { 13433 Error err; 13434 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, value->base.source_node, 13435 value->value, undef_allowed))) 13436 { 13437 return nullptr; 13438 } 13439 return value->value; 13440 } 13441 13442 Error ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, 13443 ZigValue *return_ptr, size_t *backward_branch_count, size_t *backward_branch_quota, 13444 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, 13445 IrExecutableGen *parent_exec, AstNode *expected_type_source_node, UndefAllowed undef_allowed) 13446 { 13447 Error err; 13448 13449 src_assert(return_ptr->type->id == ZigTypeIdPointer, source_node); 13450 13451 if (type_is_invalid(return_ptr->type)) 13452 return ErrorSemanticAnalyzeFail; 13453 13454 IrExecutableSrc *ir_executable = heap::c_allocator.create<IrExecutableSrc>(); 13455 ir_executable->source_node = source_node; 13456 ir_executable->parent_exec = parent_exec; 13457 ir_executable->name = exec_name; 13458 ir_executable->is_inline = true; 13459 ir_executable->fn_entry = fn_entry; 13460 ir_executable->c_import_buf = c_import_buf; 13461 ir_executable->begin_scope = scope; 13462 13463 if (!ir_gen(codegen, node, scope, ir_executable)) 13464 return ErrorSemanticAnalyzeFail; 13465 13466 if (ir_executable->first_err_trace_msg != nullptr) { 13467 codegen->trace_err = ir_executable->first_err_trace_msg; 13468 return ErrorSemanticAnalyzeFail; 13469 } 13470 13471 if (codegen->verbose_ir) { 13472 fprintf(stderr, "\nSource: "); 13473 ast_render(stderr, node, 4); 13474 fprintf(stderr, "\n{ // (IR)\n"); 13475 ir_print_src(codegen, stderr, ir_executable, 2); 13476 fprintf(stderr, "}\n"); 13477 } 13478 IrExecutableGen *analyzed_executable = heap::c_allocator.create<IrExecutableGen>(); 13479 analyzed_executable->source_node = source_node; 13480 analyzed_executable->parent_exec = parent_exec; 13481 analyzed_executable->source_exec = ir_executable; 13482 analyzed_executable->name = exec_name; 13483 analyzed_executable->is_inline = true; 13484 analyzed_executable->fn_entry = fn_entry; 13485 analyzed_executable->c_import_buf = c_import_buf; 13486 analyzed_executable->backward_branch_count = backward_branch_count; 13487 analyzed_executable->backward_branch_quota = backward_branch_quota; 13488 analyzed_executable->begin_scope = scope; 13489 ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, 13490 return_ptr->type->data.pointer.child_type, expected_type_source_node, return_ptr); 13491 if (type_is_invalid(result_type)) { 13492 return ErrorSemanticAnalyzeFail; 13493 } 13494 13495 if (codegen->verbose_ir) { 13496 fprintf(stderr, "{ // (analyzed)\n"); 13497 ir_print_gen(codegen, stderr, analyzed_executable, 2); 13498 fprintf(stderr, "}\n"); 13499 } 13500 13501 if ((err = ir_exec_scan_for_side_effects(codegen, analyzed_executable))) 13502 return err; 13503 13504 ZigValue *result = const_ptr_pointee(nullptr, codegen, return_ptr, source_node); 13505 if (result == nullptr) 13506 return ErrorSemanticAnalyzeFail; 13507 if ((err = ir_resolve_const_val(codegen, analyzed_executable, node, result, undef_allowed))) 13508 return err; 13509 13510 return ErrorNone; 13511 } 13512 13513 static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstGen *err_value) { 13514 if (type_is_invalid(err_value->value->type)) 13515 return nullptr; 13516 13517 if (err_value->value->type->id != ZigTypeIdErrorSet) { 13518 ir_add_error_node(ira, err_value->base.source_node, 13519 buf_sprintf("expected error, found '%s'", buf_ptr(&err_value->value->type->name))); 13520 return nullptr; 13521 } 13522 13523 ZigValue *const_val = ir_resolve_const(ira, err_value, UndefBad); 13524 if (!const_val) 13525 return nullptr; 13526 13527 assert(const_val->data.x_err_set != nullptr); 13528 return const_val->data.x_err_set; 13529 } 13530 13531 static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, 13532 ZigValue *val) 13533 { 13534 Error err; 13535 if ((err = ir_resolve_const_val(codegen, exec, source_node, val, UndefBad))) 13536 return codegen->builtin_types.entry_invalid; 13537 13538 assert(val->data.x_type != nullptr); 13539 return val->data.x_type; 13540 } 13541 13542 static ZigValue *ir_resolve_type_lazy(IrAnalyze *ira, IrInstGen *type_value) { 13543 if (type_is_invalid(type_value->value->type)) 13544 return nullptr; 13545 13546 if (type_value->value->type->id != ZigTypeIdMetaType) { 13547 ir_add_error_node(ira, type_value->base.source_node, 13548 buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->value->type->name))); 13549 return nullptr; 13550 } 13551 13552 Error err; 13553 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, type_value->base.source_node, 13554 type_value->value, LazyOk))) 13555 { 13556 return nullptr; 13557 } 13558 13559 return type_value->value; 13560 } 13561 13562 static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstGen *type_value) { 13563 ZigValue *val = ir_resolve_type_lazy(ira, type_value); 13564 if (val == nullptr) 13565 return ira->codegen->builtin_types.entry_invalid; 13566 13567 return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->base.source_node, val); 13568 } 13569 13570 static Error ir_validate_vector_elem_type(IrAnalyze *ira, AstNode *source_node, ZigType *elem_type) { 13571 Error err; 13572 bool is_valid; 13573 if ((err = is_valid_vector_elem_type(ira->codegen, elem_type, &is_valid))) 13574 return err; 13575 if (!is_valid) { 13576 ir_add_error_node(ira, source_node, 13577 buf_sprintf("vector element type must be integer, float, bool, or pointer; '%s' is invalid", 13578 buf_ptr(&elem_type->name))); 13579 return ErrorSemanticAnalyzeFail; 13580 } 13581 return ErrorNone; 13582 } 13583 13584 static ZigType *ir_resolve_vector_elem_type(IrAnalyze *ira, IrInstGen *elem_type_value) { 13585 Error err; 13586 ZigType *elem_type = ir_resolve_type(ira, elem_type_value); 13587 if (type_is_invalid(elem_type)) 13588 return ira->codegen->builtin_types.entry_invalid; 13589 if ((err = ir_validate_vector_elem_type(ira, elem_type_value->base.source_node, elem_type))) 13590 return ira->codegen->builtin_types.entry_invalid; 13591 return elem_type; 13592 } 13593 13594 static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstGen *type_value) { 13595 ZigType *ty = ir_resolve_type(ira, type_value); 13596 if (type_is_invalid(ty)) 13597 return ira->codegen->builtin_types.entry_invalid; 13598 13599 if (ty->id != ZigTypeIdInt) { 13600 ErrorMsg *msg = ir_add_error_node(ira, type_value->base.source_node, 13601 buf_sprintf("expected integer type, found '%s'", buf_ptr(&ty->name))); 13602 if (ty->id == ZigTypeIdVector && 13603 ty->data.vector.elem_type->id == ZigTypeIdInt) 13604 { 13605 add_error_note(ira->codegen, msg, type_value->base.source_node, 13606 buf_sprintf("represent vectors with their element types, i.e. '%s'", 13607 buf_ptr(&ty->data.vector.elem_type->name))); 13608 } 13609 return ira->codegen->builtin_types.entry_invalid; 13610 } 13611 13612 return ty; 13613 } 13614 13615 static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInst *op_source, IrInstGen *type_value) { 13616 if (type_is_invalid(type_value->value->type)) 13617 return ira->codegen->builtin_types.entry_invalid; 13618 13619 if (type_value->value->type->id != ZigTypeIdMetaType) { 13620 ErrorMsg *msg = ir_add_error_node(ira, type_value->base.source_node, 13621 buf_sprintf("expected error set type, found '%s'", buf_ptr(&type_value->value->type->name))); 13622 add_error_note(ira->codegen, msg, op_source->source_node, 13623 buf_sprintf("`||` merges error sets; `or` performs boolean OR")); 13624 return ira->codegen->builtin_types.entry_invalid; 13625 } 13626 13627 ZigValue *const_val = ir_resolve_const(ira, type_value, UndefBad); 13628 if (!const_val) 13629 return ira->codegen->builtin_types.entry_invalid; 13630 13631 assert(const_val->data.x_type != nullptr); 13632 ZigType *result_type = const_val->data.x_type; 13633 if (result_type->id != ZigTypeIdErrorSet) { 13634 ErrorMsg *msg = ir_add_error_node(ira, type_value->base.source_node, 13635 buf_sprintf("expected error set type, found type '%s'", buf_ptr(&result_type->name))); 13636 add_error_note(ira->codegen, msg, op_source->source_node, 13637 buf_sprintf("`||` merges error sets; `or` performs boolean OR")); 13638 return ira->codegen->builtin_types.entry_invalid; 13639 } 13640 return result_type; 13641 } 13642 13643 static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstGen *fn_value) { 13644 if (type_is_invalid(fn_value->value->type)) 13645 return nullptr; 13646 13647 if (fn_value->value->type->id != ZigTypeIdFn) { 13648 ir_add_error_node(ira, fn_value->base.source_node, 13649 buf_sprintf("expected function type, found '%s'", buf_ptr(&fn_value->value->type->name))); 13650 return nullptr; 13651 } 13652 13653 ZigValue *const_val = ir_resolve_const(ira, fn_value, UndefBad); 13654 if (!const_val) 13655 return nullptr; 13656 13657 // May be a ConstPtrSpecialHardCodedAddr 13658 if (const_val->data.x_ptr.special != ConstPtrSpecialFunction) 13659 return nullptr; 13660 13661 return const_val->data.x_ptr.data.fn.fn_entry; 13662 } 13663 13664 static IrInstGen *ir_analyze_optional_wrap(IrAnalyze *ira, IrInst* source_instr, 13665 IrInstGen *value, ZigType *wanted_type, ResultLoc *result_loc) 13666 { 13667 assert(wanted_type->id == ZigTypeIdOptional); 13668 13669 if (instr_is_comptime(value)) { 13670 ZigType *payload_type = wanted_type->data.maybe.child_type; 13671 IrInstGen *casted_payload = ir_implicit_cast(ira, value, payload_type); 13672 if (type_is_invalid(casted_payload->value->type)) 13673 return ira->codegen->invalid_inst_gen; 13674 13675 ZigValue *val = ir_resolve_const(ira, casted_payload, UndefOk); 13676 if (!val) 13677 return ira->codegen->invalid_inst_gen; 13678 13679 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 13680 source_instr->scope, source_instr->source_node); 13681 const_instruction->base.value->special = ConstValSpecialStatic; 13682 if (types_have_same_zig_comptime_repr(ira->codegen, wanted_type, payload_type)) { 13683 copy_const_val(ira->codegen, const_instruction->base.value, val); 13684 } else { 13685 const_instruction->base.value->data.x_optional = val; 13686 } 13687 const_instruction->base.value->type = wanted_type; 13688 return &const_instruction->base; 13689 } 13690 13691 if (result_loc == nullptr && handle_is_ptr(ira->codegen, wanted_type)) { 13692 result_loc = no_result_loc(); 13693 } 13694 IrInstGen *result_loc_inst = nullptr; 13695 if (result_loc != nullptr) { 13696 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); 13697 if (type_is_invalid(result_loc_inst->value->type) || 13698 result_loc_inst->value->type->id == ZigTypeIdUnreachable) 13699 { 13700 return result_loc_inst; 13701 } 13702 } 13703 IrInstGen *result = ir_build_optional_wrap(ira, source_instr, wanted_type, value, result_loc_inst); 13704 result->value->data.rh_maybe = RuntimeHintOptionalNonNull; 13705 return result; 13706 } 13707 13708 static IrInstGen *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInst* source_instr, 13709 IrInstGen *value, ZigType *wanted_type, ResultLoc *result_loc) 13710 { 13711 assert(wanted_type->id == ZigTypeIdErrorUnion); 13712 13713 ZigType *payload_type = wanted_type->data.error_union.payload_type; 13714 ZigType *err_set_type = wanted_type->data.error_union.err_set_type; 13715 if (instr_is_comptime(value)) { 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 == nullptr) 13722 return ira->codegen->invalid_inst_gen; 13723 13724 ZigValue *err_set_val = ira->codegen->pass1_arena->create<ZigValue>(); 13725 err_set_val->type = err_set_type; 13726 err_set_val->special = ConstValSpecialStatic; 13727 err_set_val->data.x_err_set = nullptr; 13728 13729 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 13730 source_instr->scope, source_instr->source_node); 13731 const_instruction->base.value->type = wanted_type; 13732 const_instruction->base.value->special = ConstValSpecialStatic; 13733 const_instruction->base.value->data.x_err_union.error_set = err_set_val; 13734 const_instruction->base.value->data.x_err_union.payload = val; 13735 return &const_instruction->base; 13736 } 13737 13738 IrInstGen *result_loc_inst; 13739 if (handle_is_ptr(ira->codegen, wanted_type)) { 13740 if (result_loc == nullptr) result_loc = no_result_loc(); 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 return result_loc_inst; 13745 } 13746 } else { 13747 result_loc_inst = nullptr; 13748 } 13749 13750 IrInstGen *result = ir_build_err_wrap_payload(ira, source_instr, wanted_type, value, result_loc_inst); 13751 result->value->data.rh_error_union = RuntimeHintErrorUnionNonError; 13752 return result; 13753 } 13754 13755 static IrInstGen *ir_analyze_err_set_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 13756 ZigType *wanted_type) 13757 { 13758 assert(value->value->type->id == ZigTypeIdErrorSet); 13759 assert(wanted_type->id == ZigTypeIdErrorSet); 13760 13761 if (instr_is_comptime(value)) { 13762 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 13763 if (!val) 13764 return ira->codegen->invalid_inst_gen; 13765 13766 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 13767 return ira->codegen->invalid_inst_gen; 13768 } 13769 if (!type_is_global_error_set(wanted_type)) { 13770 bool subset = false; 13771 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 13772 if (wanted_type->data.error_set.errors[i]->value == val->data.x_err_set->value) { 13773 subset = true; 13774 break; 13775 } 13776 } 13777 if (!subset) { 13778 ir_add_error(ira, source_instr, 13779 buf_sprintf("error.%s not a member of error set '%s'", 13780 buf_ptr(&val->data.x_err_set->name), buf_ptr(&wanted_type->name))); 13781 return ira->codegen->invalid_inst_gen; 13782 } 13783 } 13784 13785 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 13786 source_instr->scope, source_instr->source_node); 13787 const_instruction->base.value->type = wanted_type; 13788 const_instruction->base.value->special = ConstValSpecialStatic; 13789 const_instruction->base.value->data.x_err_set = val->data.x_err_set; 13790 return &const_instruction->base; 13791 } 13792 13793 return ir_build_cast(ira, source_instr, wanted_type, value, CastOpErrSet); 13794 } 13795 13796 static IrInstGen *ir_analyze_frame_ptr_to_anyframe(IrAnalyze *ira, IrInst* source_instr, 13797 IrInstGen *frame_ptr, ZigType *wanted_type) 13798 { 13799 if (instr_is_comptime(frame_ptr)) { 13800 ZigValue *ptr_val = ir_resolve_const(ira, frame_ptr, UndefBad); 13801 if (ptr_val == nullptr) 13802 return ira->codegen->invalid_inst_gen; 13803 13804 ir_assert(ptr_val->type->id == ZigTypeIdPointer, source_instr); 13805 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 13806 zig_panic("TODO comptime frame pointer"); 13807 } 13808 } 13809 13810 return ir_build_cast(ira, source_instr, wanted_type, frame_ptr, CastOpBitCast); 13811 } 13812 13813 static IrInstGen *ir_analyze_anyframe_to_anyframe(IrAnalyze *ira, IrInst* source_instr, 13814 IrInstGen *value, ZigType *wanted_type) 13815 { 13816 if (instr_is_comptime(value)) { 13817 zig_panic("TODO comptime anyframe->T to anyframe"); 13818 } 13819 13820 return ir_build_cast(ira, source_instr, wanted_type, value, CastOpBitCast); 13821 } 13822 13823 13824 static IrInstGen *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 13825 ZigType *wanted_type, ResultLoc *result_loc) 13826 { 13827 assert(wanted_type->id == ZigTypeIdErrorUnion); 13828 13829 IrInstGen *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); 13830 13831 if (instr_is_comptime(casted_value)) { 13832 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); 13833 if (!val) 13834 return ira->codegen->invalid_inst_gen; 13835 13836 ZigValue *err_set_val = ira->codegen->pass1_arena->create<ZigValue>(); 13837 err_set_val->special = ConstValSpecialStatic; 13838 err_set_val->type = wanted_type->data.error_union.err_set_type; 13839 err_set_val->data.x_err_set = val->data.x_err_set; 13840 13841 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 13842 source_instr->scope, source_instr->source_node); 13843 const_instruction->base.value->type = wanted_type; 13844 const_instruction->base.value->special = ConstValSpecialStatic; 13845 const_instruction->base.value->data.x_err_union.error_set = err_set_val; 13846 const_instruction->base.value->data.x_err_union.payload = nullptr; 13847 return &const_instruction->base; 13848 } 13849 13850 IrInstGen *result_loc_inst; 13851 if (handle_is_ptr(ira->codegen, wanted_type)) { 13852 if (result_loc == nullptr) result_loc = no_result_loc(); 13853 result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, wanted_type, nullptr, true, true); 13854 if (type_is_invalid(result_loc_inst->value->type) || 13855 result_loc_inst->value->type->id == ZigTypeIdUnreachable) 13856 { 13857 return result_loc_inst; 13858 } 13859 } else { 13860 result_loc_inst = nullptr; 13861 } 13862 13863 13864 IrInstGen *result = ir_build_err_wrap_code(ira, source_instr, wanted_type, value, result_loc_inst); 13865 result->value->data.rh_error_union = RuntimeHintErrorUnionError; 13866 return result; 13867 } 13868 13869 static IrInstGen *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInst *source_instr, IrInstGen *value, ZigType *wanted_type) { 13870 assert(wanted_type->id == ZigTypeIdOptional); 13871 assert(instr_is_comptime(value)); 13872 13873 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 13874 assert(val != nullptr); 13875 13876 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13877 result->value->special = ConstValSpecialStatic; 13878 13879 if (get_src_ptr_type(wanted_type) != nullptr) { 13880 result->value->data.x_ptr.special = ConstPtrSpecialNull; 13881 } else if (is_opt_err_set(wanted_type)) { 13882 result->value->data.x_err_set = nullptr; 13883 } else { 13884 result->value->data.x_optional = nullptr; 13885 } 13886 return result; 13887 } 13888 13889 static IrInstGen *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInst *source_instr, 13890 IrInstGen *value, ZigType *wanted_type) 13891 { 13892 assert(wanted_type->id == ZigTypeIdPointer); 13893 assert(wanted_type->data.pointer.ptr_len == PtrLenC); 13894 assert(instr_is_comptime(value)); 13895 13896 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 13897 assert(val != nullptr); 13898 13899 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 13900 result->value->data.x_ptr.special = ConstPtrSpecialNull; 13901 result->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 13902 return result; 13903 } 13904 13905 static IrInstGen *ir_get_ref2(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value, 13906 ZigType *elem_type, bool is_const, bool is_volatile) 13907 { 13908 Error err; 13909 13910 if (type_is_invalid(elem_type)) 13911 return ira->codegen->invalid_inst_gen; 13912 13913 if (instr_is_comptime(value)) { 13914 ZigValue *val = ir_resolve_const(ira, value, LazyOk); 13915 if (!val) 13916 return ira->codegen->invalid_inst_gen; 13917 return ir_get_const_ptr(ira, source_instruction, val, elem_type, 13918 ConstPtrMutComptimeConst, is_const, is_volatile, 0); 13919 } 13920 13921 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, elem_type, 13922 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 13923 13924 if ((err = type_resolve(ira->codegen, ptr_type, ResolveStatusZeroBitsKnown))) 13925 return ira->codegen->invalid_inst_gen; 13926 13927 IrInstGen *result_loc; 13928 if (type_has_bits(ira->codegen, ptr_type) && !handle_is_ptr(ira->codegen, elem_type)) { 13929 result_loc = ir_resolve_result(ira, source_instruction, no_result_loc(), elem_type, nullptr, true, true); 13930 } else { 13931 result_loc = nullptr; 13932 } 13933 13934 IrInstGen *new_instruction = ir_build_ref_gen(ira, source_instruction, ptr_type, value, result_loc); 13935 new_instruction->value->data.rh_ptr = RuntimeHintPtrStack; 13936 return new_instruction; 13937 } 13938 13939 static IrInstGen *ir_get_ref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *value, 13940 bool is_const, bool is_volatile) 13941 { 13942 return ir_get_ref2(ira, source_instruction, value, value->value->type, is_const, is_volatile); 13943 } 13944 13945 static ZigType *ir_resolve_union_tag_type(IrAnalyze *ira, AstNode *source_node, ZigType *union_type) { 13946 assert(union_type->id == ZigTypeIdUnion); 13947 13948 Error err; 13949 if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) 13950 return ira->codegen->builtin_types.entry_invalid; 13951 13952 AstNode *decl_node = union_type->data.unionation.decl_node; 13953 if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) { 13954 assert(union_type->data.unionation.tag_type != nullptr); 13955 return union_type->data.unionation.tag_type; 13956 } else { 13957 ErrorMsg *msg = ir_add_error_node(ira, source_node, buf_sprintf("union '%s' has no tag", 13958 buf_ptr(&union_type->name))); 13959 add_error_note(ira->codegen, msg, decl_node, buf_sprintf("consider 'union(enum)' here")); 13960 return ira->codegen->builtin_types.entry_invalid; 13961 } 13962 } 13963 13964 static IrInstGen *ir_analyze_enum_to_int(IrAnalyze *ira, IrInst *source_instr, IrInstGen *target) { 13965 Error err; 13966 13967 IrInstGen *enum_target; 13968 ZigType *enum_type; 13969 if (target->value->type->id == ZigTypeIdUnion) { 13970 enum_type = ir_resolve_union_tag_type(ira, target->base.source_node, target->value->type); 13971 if (type_is_invalid(enum_type)) 13972 return ira->codegen->invalid_inst_gen; 13973 enum_target = ir_implicit_cast(ira, target, enum_type); 13974 if (type_is_invalid(enum_target->value->type)) 13975 return ira->codegen->invalid_inst_gen; 13976 } else if (target->value->type->id == ZigTypeIdEnum) { 13977 enum_target = target; 13978 enum_type = target->value->type; 13979 } else { 13980 ir_add_error_node(ira, target->base.source_node, 13981 buf_sprintf("expected enum, found type '%s'", buf_ptr(&target->value->type->name))); 13982 return ira->codegen->invalid_inst_gen; 13983 } 13984 13985 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown))) 13986 return ira->codegen->invalid_inst_gen; 13987 13988 ZigType *tag_type = enum_type->data.enumeration.tag_int_type; 13989 assert(tag_type->id == ZigTypeIdInt || tag_type->id == ZigTypeIdComptimeInt); 13990 13991 // If there is only one possible tag, then we know at comptime what it is. 13992 if (enum_type->data.enumeration.layout == ContainerLayoutAuto && 13993 enum_type->data.enumeration.src_field_count == 1) 13994 { 13995 IrInstGen *result = ir_const(ira, source_instr, tag_type); 13996 init_const_bigint(result->value, tag_type, 13997 &enum_type->data.enumeration.fields[0].value); 13998 return result; 13999 } 14000 14001 if (instr_is_comptime(enum_target)) { 14002 ZigValue *val = ir_resolve_const(ira, enum_target, UndefBad); 14003 if (!val) 14004 return ira->codegen->invalid_inst_gen; 14005 IrInstGen *result = ir_const(ira, source_instr, tag_type); 14006 init_const_bigint(result->value, tag_type, &val->data.x_enum_tag); 14007 return result; 14008 } 14009 14010 return ir_build_widen_or_shorten(ira, source_instr->scope, source_instr->source_node, enum_target, tag_type); 14011 } 14012 14013 static IrInstGen *ir_analyze_union_to_tag(IrAnalyze *ira, IrInst* source_instr, 14014 IrInstGen *target, ZigType *wanted_type) 14015 { 14016 assert(target->value->type->id == ZigTypeIdUnion); 14017 assert(wanted_type->id == ZigTypeIdEnum); 14018 assert(wanted_type == target->value->type->data.unionation.tag_type); 14019 14020 if (instr_is_comptime(target)) { 14021 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14022 if (!val) 14023 return ira->codegen->invalid_inst_gen; 14024 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14025 result->value->special = ConstValSpecialStatic; 14026 result->value->type = wanted_type; 14027 bigint_init_bigint(&result->value->data.x_enum_tag, &val->data.x_union.tag); 14028 return result; 14029 } 14030 14031 // If there is only 1 possible tag, then we know at comptime what it is. 14032 if (wanted_type->data.enumeration.layout == ContainerLayoutAuto && 14033 wanted_type->data.enumeration.src_field_count == 1) 14034 { 14035 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14036 result->value->special = ConstValSpecialStatic; 14037 result->value->type = wanted_type; 14038 TypeEnumField *enum_field = target->value->type->data.unionation.fields[0].enum_field; 14039 bigint_init_bigint(&result->value->data.x_enum_tag, &enum_field->value); 14040 return result; 14041 } 14042 14043 return ir_build_union_tag(ira, source_instr, target, wanted_type); 14044 } 14045 14046 static IrInstGen *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInst* source_instr, 14047 IrInstGen *target, ZigType *wanted_type) 14048 { 14049 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14050 result->value->special = ConstValSpecialUndef; 14051 return result; 14052 } 14053 14054 static IrInstGen *ir_analyze_enum_to_union(IrAnalyze *ira, IrInst* source_instr, 14055 IrInstGen *uncasted_target, ZigType *wanted_type) 14056 { 14057 Error err; 14058 assert(wanted_type->id == ZigTypeIdUnion); 14059 14060 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown))) 14061 return ira->codegen->invalid_inst_gen; 14062 14063 IrInstGen *target = ir_implicit_cast(ira, uncasted_target, wanted_type->data.unionation.tag_type); 14064 if (type_is_invalid(target->value->type)) 14065 return ira->codegen->invalid_inst_gen; 14066 14067 if (instr_is_comptime(target)) { 14068 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14069 if (!val) 14070 return ira->codegen->invalid_inst_gen; 14071 TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); 14072 assert(union_field != nullptr); 14073 ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); 14074 if (field_type == nullptr) 14075 return ira->codegen->invalid_inst_gen; 14076 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) 14077 return ira->codegen->invalid_inst_gen; 14078 14079 switch (type_has_one_possible_value(ira->codegen, field_type)) { 14080 case OnePossibleValueInvalid: 14081 return ira->codegen->invalid_inst_gen; 14082 case OnePossibleValueNo: { 14083 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at( 14084 union_field->enum_field->decl_index); 14085 ErrorMsg *msg = ir_add_error(ira, source_instr, 14086 buf_sprintf("cast to union '%s' must initialize '%s' field '%s'", 14087 buf_ptr(&wanted_type->name), 14088 buf_ptr(&field_type->name), 14089 buf_ptr(union_field->name))); 14090 add_error_note(ira->codegen, msg, field_node, 14091 buf_sprintf("field '%s' declared here", buf_ptr(union_field->name))); 14092 return ira->codegen->invalid_inst_gen; 14093 } 14094 case OnePossibleValueYes: 14095 break; 14096 } 14097 14098 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14099 result->value->special = ConstValSpecialStatic; 14100 result->value->type = wanted_type; 14101 bigint_init_bigint(&result->value->data.x_union.tag, &val->data.x_enum_tag); 14102 result->value->data.x_union.payload = ira->codegen->pass1_arena->create<ZigValue>(); 14103 result->value->data.x_union.payload->special = ConstValSpecialStatic; 14104 result->value->data.x_union.payload->type = field_type; 14105 return result; 14106 } 14107 14108 // if the union has all fields 0 bits, we can do it 14109 // and in fact it's a noop cast because the union value is just the enum value 14110 if (wanted_type->data.unionation.gen_field_count == 0) { 14111 return ir_build_cast(ira, &target->base, wanted_type, target, CastOpNoop); 14112 } 14113 14114 ErrorMsg *msg = ir_add_error(ira, source_instr, 14115 buf_sprintf("runtime cast to union '%s' which has non-void fields", 14116 buf_ptr(&wanted_type->name))); 14117 for (uint32_t i = 0; i < wanted_type->data.unionation.src_field_count; i += 1) { 14118 TypeUnionField *union_field = &wanted_type->data.unionation.fields[i]; 14119 ZigType *field_type = resolve_union_field_type(ira->codegen, union_field); 14120 if (field_type == nullptr) 14121 return ira->codegen->invalid_inst_gen; 14122 bool has_bits; 14123 if ((err = type_has_bits2(ira->codegen, field_type, &has_bits))) 14124 return ira->codegen->invalid_inst_gen; 14125 if (has_bits) { 14126 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i); 14127 add_error_note(ira->codegen, msg, field_node, 14128 buf_sprintf("field '%s' has type '%s'", 14129 buf_ptr(union_field->name), 14130 buf_ptr(&field_type->name))); 14131 } 14132 } 14133 return ira->codegen->invalid_inst_gen; 14134 } 14135 14136 static IrInstGen *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInst* source_instr, 14137 IrInstGen *target, ZigType *wanted_type) 14138 { 14139 assert(wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdFloat); 14140 14141 if (instr_is_comptime(target)) { 14142 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14143 if (!val) 14144 return ira->codegen->invalid_inst_gen; 14145 if (wanted_type->id == ZigTypeIdInt) { 14146 if (bigint_cmp_zero(&val->data.x_bigint) == CmpLT && !wanted_type->data.integral.is_signed) { 14147 ir_add_error(ira, source_instr, 14148 buf_sprintf("attempt to cast negative value to unsigned integer")); 14149 return ira->codegen->invalid_inst_gen; 14150 } 14151 if (!bigint_fits_in_bits(&val->data.x_bigint, wanted_type->data.integral.bit_count, 14152 wanted_type->data.integral.is_signed)) 14153 { 14154 ir_add_error(ira, source_instr, 14155 buf_sprintf("cast from '%s' to '%s' truncates bits", 14156 buf_ptr(&target->value->type->name), buf_ptr(&wanted_type->name))); 14157 return ira->codegen->invalid_inst_gen; 14158 } 14159 } 14160 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14161 result->value->type = wanted_type; 14162 if (wanted_type->id == ZigTypeIdInt) { 14163 bigint_init_bigint(&result->value->data.x_bigint, &val->data.x_bigint); 14164 } else { 14165 float_init_float(result->value, val); 14166 } 14167 return result; 14168 } 14169 14170 // If the destination integer type has no bits, then we can emit a comptime 14171 // zero. However, we still want to emit a runtime safety check to make sure 14172 // the target is zero. 14173 if (!type_has_bits(ira->codegen, wanted_type)) { 14174 assert(wanted_type->id == ZigTypeIdInt); 14175 assert(type_has_bits(ira->codegen, target->value->type)); 14176 ir_build_assert_zero(ira, source_instr, target); 14177 IrInstGen *result = ir_const_unsigned(ira, source_instr, 0); 14178 result->value->type = wanted_type; 14179 return result; 14180 } 14181 14182 return ir_build_widen_or_shorten(ira, source_instr->scope, source_instr->source_node, target, wanted_type); 14183 } 14184 14185 static IrInstGen *ir_analyze_int_to_enum(IrAnalyze *ira, IrInst* source_instr, 14186 IrInstGen *target, ZigType *wanted_type) 14187 { 14188 Error err; 14189 assert(wanted_type->id == ZigTypeIdEnum); 14190 14191 ZigType *actual_type = target->value->type; 14192 14193 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusSizeKnown))) 14194 return ira->codegen->invalid_inst_gen; 14195 14196 if (actual_type != wanted_type->data.enumeration.tag_int_type) { 14197 ir_add_error(ira, source_instr, 14198 buf_sprintf("integer to enum cast from '%s' instead of its tag type, '%s'", 14199 buf_ptr(&actual_type->name), 14200 buf_ptr(&wanted_type->data.enumeration.tag_int_type->name))); 14201 return ira->codegen->invalid_inst_gen; 14202 } 14203 14204 assert(actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt); 14205 14206 if (instr_is_comptime(target)) { 14207 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14208 if (!val) 14209 return ira->codegen->invalid_inst_gen; 14210 14211 TypeEnumField *field = find_enum_field_by_tag(wanted_type, &val->data.x_bigint); 14212 if (field == nullptr && !wanted_type->data.enumeration.non_exhaustive) { 14213 Buf *val_buf = buf_alloc(); 14214 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 14215 ErrorMsg *msg = ir_add_error(ira, source_instr, 14216 buf_sprintf("enum '%s' has no tag matching integer value %s", 14217 buf_ptr(&wanted_type->name), buf_ptr(val_buf))); 14218 add_error_note(ira->codegen, msg, wanted_type->data.enumeration.decl_node, 14219 buf_sprintf("'%s' declared here", buf_ptr(&wanted_type->name))); 14220 return ira->codegen->invalid_inst_gen; 14221 } 14222 14223 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14224 bigint_init_bigint(&result->value->data.x_enum_tag, &val->data.x_bigint); 14225 return result; 14226 } 14227 14228 return ir_build_int_to_enum_gen(ira, source_instr->scope, source_instr->source_node, wanted_type, target); 14229 } 14230 14231 static IrInstGen *ir_analyze_number_to_literal(IrAnalyze *ira, IrInst* source_instr, 14232 IrInstGen *target, ZigType *wanted_type) 14233 { 14234 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14235 if (!val) 14236 return ira->codegen->invalid_inst_gen; 14237 14238 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14239 if (wanted_type->id == ZigTypeIdComptimeFloat) { 14240 float_init_float(result->value, val); 14241 } else if (wanted_type->id == ZigTypeIdComptimeInt) { 14242 bigint_init_bigint(&result->value->data.x_bigint, &val->data.x_bigint); 14243 } else { 14244 zig_unreachable(); 14245 } 14246 return result; 14247 } 14248 14249 static IrInstGen *ir_analyze_int_to_err(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 14250 ZigType *wanted_type) 14251 { 14252 assert(target->value->type->id == ZigTypeIdInt); 14253 assert(!target->value->type->data.integral.is_signed); 14254 assert(wanted_type->id == ZigTypeIdErrorSet); 14255 14256 if (instr_is_comptime(target)) { 14257 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14258 if (!val) 14259 return ira->codegen->invalid_inst_gen; 14260 14261 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14262 14263 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 14264 return ira->codegen->invalid_inst_gen; 14265 } 14266 14267 if (type_is_global_error_set(wanted_type)) { 14268 BigInt err_count; 14269 bigint_init_unsigned(&err_count, ira->codegen->errors_by_index.length); 14270 14271 if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) { 14272 Buf *val_buf = buf_alloc(); 14273 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 14274 ir_add_error(ira, source_instr, 14275 buf_sprintf("integer value %s represents no error", buf_ptr(val_buf))); 14276 return ira->codegen->invalid_inst_gen; 14277 } 14278 14279 size_t index = bigint_as_usize(&val->data.x_bigint); 14280 result->value->data.x_err_set = ira->codegen->errors_by_index.at(index); 14281 return result; 14282 } else { 14283 ErrorTableEntry *err = nullptr; 14284 BigInt err_int; 14285 14286 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 14287 ErrorTableEntry *this_err = wanted_type->data.error_set.errors[i]; 14288 bigint_init_unsigned(&err_int, this_err->value); 14289 if (bigint_cmp(&val->data.x_bigint, &err_int) == CmpEQ) { 14290 err = this_err; 14291 break; 14292 } 14293 } 14294 14295 if (err == nullptr) { 14296 Buf *val_buf = buf_alloc(); 14297 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 14298 ir_add_error(ira, source_instr, 14299 buf_sprintf("integer value %s represents no error in '%s'", buf_ptr(val_buf), buf_ptr(&wanted_type->name))); 14300 return ira->codegen->invalid_inst_gen; 14301 } 14302 14303 result->value->data.x_err_set = err; 14304 return result; 14305 } 14306 } 14307 14308 return ir_build_int_to_err_gen(ira, source_instr->scope, source_instr->source_node, target, wanted_type); 14309 } 14310 14311 static IrInstGen *ir_analyze_err_to_int(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 14312 ZigType *wanted_type) 14313 { 14314 assert(wanted_type->id == ZigTypeIdInt); 14315 14316 ZigType *err_type = target->value->type; 14317 14318 if (instr_is_comptime(target)) { 14319 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14320 if (!val) 14321 return ira->codegen->invalid_inst_gen; 14322 14323 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14324 14325 ErrorTableEntry *err; 14326 if (err_type->id == ZigTypeIdErrorUnion) { 14327 err = val->data.x_err_union.error_set->data.x_err_set; 14328 } else if (err_type->id == ZigTypeIdErrorSet) { 14329 err = val->data.x_err_set; 14330 } else { 14331 zig_unreachable(); 14332 } 14333 result->value->type = wanted_type; 14334 uint64_t err_value = err ? err->value : 0; 14335 bigint_init_unsigned(&result->value->data.x_bigint, err_value); 14336 14337 if (!bigint_fits_in_bits(&result->value->data.x_bigint, 14338 wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) 14339 { 14340 ir_add_error_node(ira, source_instr->source_node, 14341 buf_sprintf("error code '%s' does not fit in '%s'", 14342 buf_ptr(&err->name), buf_ptr(&wanted_type->name))); 14343 return ira->codegen->invalid_inst_gen; 14344 } 14345 14346 return result; 14347 } 14348 14349 ZigType *err_set_type; 14350 if (err_type->id == ZigTypeIdErrorUnion) { 14351 err_set_type = err_type->data.error_union.err_set_type; 14352 } else if (err_type->id == ZigTypeIdErrorSet) { 14353 err_set_type = err_type; 14354 } else { 14355 zig_unreachable(); 14356 } 14357 if (!type_is_global_error_set(err_set_type)) { 14358 if (!resolve_inferred_error_set(ira->codegen, err_set_type, source_instr->source_node)) { 14359 return ira->codegen->invalid_inst_gen; 14360 } 14361 if (err_set_type->data.error_set.err_count == 0) { 14362 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14363 bigint_init_unsigned(&result->value->data.x_bigint, 0); 14364 return result; 14365 } else if (err_set_type->data.error_set.err_count == 1) { 14366 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 14367 ErrorTableEntry *err = err_set_type->data.error_set.errors[0]; 14368 bigint_init_unsigned(&result->value->data.x_bigint, err->value); 14369 return result; 14370 } 14371 } 14372 14373 BigInt bn; 14374 bigint_init_unsigned(&bn, ira->codegen->errors_by_index.length); 14375 if (!bigint_fits_in_bits(&bn, wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) { 14376 ir_add_error_node(ira, source_instr->source_node, 14377 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name))); 14378 return ira->codegen->invalid_inst_gen; 14379 } 14380 14381 return ir_build_err_to_int_gen(ira, source_instr->scope, source_instr->source_node, target, wanted_type); 14382 } 14383 14384 static IrInstGen *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 14385 ZigType *wanted_type) 14386 { 14387 assert(wanted_type->id == ZigTypeIdPointer); 14388 Error err; 14389 if ((err = type_resolve(ira->codegen, target->value->type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 14390 return ira->codegen->invalid_inst_gen; 14391 assert((wanted_type->data.pointer.is_const && target->value->type->data.pointer.is_const) || !target->value->type->data.pointer.is_const); 14392 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, target->value->type)); 14393 ZigType *array_type = wanted_type->data.pointer.child_type; 14394 assert(array_type->id == ZigTypeIdArray); 14395 assert(array_type->data.array.len == 1); 14396 14397 if (instr_is_comptime(target)) { 14398 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 14399 if (!val) 14400 return ira->codegen->invalid_inst_gen; 14401 14402 assert(val->type->id == ZigTypeIdPointer); 14403 ZigValue *pointee = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 14404 if (pointee == nullptr) 14405 return ira->codegen->invalid_inst_gen; 14406 if (pointee->special != ConstValSpecialRuntime) { 14407 ZigValue *array_val = ira->codegen->pass1_arena->create<ZigValue>(); 14408 array_val->special = ConstValSpecialStatic; 14409 array_val->type = array_type; 14410 array_val->data.x_array.special = ConstArraySpecialNone; 14411 array_val->data.x_array.data.s_none.elements = pointee; 14412 array_val->parent.id = ConstParentIdScalar; 14413 array_val->parent.data.p_scalar.scalar_val = pointee; 14414 14415 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 14416 source_instr->scope, source_instr->source_node); 14417 const_instruction->base.value->type = wanted_type; 14418 const_instruction->base.value->special = ConstValSpecialStatic; 14419 const_instruction->base.value->data.x_ptr.special = ConstPtrSpecialRef; 14420 const_instruction->base.value->data.x_ptr.data.ref.pointee = array_val; 14421 const_instruction->base.value->data.x_ptr.mut = val->data.x_ptr.mut; 14422 return &const_instruction->base; 14423 } 14424 } 14425 14426 // pointer to array and pointer to single item are represented the same way at runtime 14427 return ir_build_cast(ira, &target->base, wanted_type, target, CastOpBitCast); 14428 } 14429 14430 static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCastOnly *cast_result, 14431 ErrorMsg *parent_msg) 14432 { 14433 switch (cast_result->id) { 14434 case ConstCastResultIdOk: 14435 zig_unreachable(); 14436 case ConstCastResultIdInvalid: 14437 zig_unreachable(); 14438 case ConstCastResultIdOptionalChild: { 14439 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 14440 buf_sprintf("optional type child '%s' cannot cast into optional type child '%s'", 14441 buf_ptr(&cast_result->data.optional->actual_child->name), 14442 buf_ptr(&cast_result->data.optional->wanted_child->name))); 14443 report_recursive_error(ira, source_node, &cast_result->data.optional->child, msg); 14444 break; 14445 } 14446 case ConstCastResultIdErrorUnionErrorSet: { 14447 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 14448 buf_sprintf("error set '%s' cannot cast into error set '%s'", 14449 buf_ptr(&cast_result->data.error_union_error_set->actual_err_set->name), 14450 buf_ptr(&cast_result->data.error_union_error_set->wanted_err_set->name))); 14451 report_recursive_error(ira, source_node, &cast_result->data.error_union_error_set->child, msg); 14452 break; 14453 } 14454 case ConstCastResultIdErrSet: { 14455 ZigList<ErrorTableEntry *> *missing_errors = &cast_result->data.error_set_mismatch->missing_errors; 14456 for (size_t i = 0; i < missing_errors->length; i += 1) { 14457 ErrorTableEntry *error_entry = missing_errors->at(i); 14458 add_error_note(ira->codegen, parent_msg, ast_field_to_symbol_node(error_entry->decl_node), 14459 buf_sprintf("'error.%s' not a member of destination error set", buf_ptr(&error_entry->name))); 14460 } 14461 break; 14462 } 14463 case ConstCastResultIdErrSetGlobal: { 14464 add_error_note(ira->codegen, parent_msg, source_node, 14465 buf_sprintf("cannot cast global error set into smaller set")); 14466 break; 14467 } 14468 case ConstCastResultIdPointerChild: { 14469 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 14470 buf_sprintf("pointer type child '%s' cannot cast into pointer type child '%s'", 14471 buf_ptr(&cast_result->data.pointer_mismatch->actual_child->name), 14472 buf_ptr(&cast_result->data.pointer_mismatch->wanted_child->name))); 14473 report_recursive_error(ira, source_node, &cast_result->data.pointer_mismatch->child, msg); 14474 break; 14475 } 14476 case ConstCastResultIdSliceChild: { 14477 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 14478 buf_sprintf("slice type child '%s' cannot cast into slice type child '%s'", 14479 buf_ptr(&cast_result->data.slice_mismatch->actual_child->name), 14480 buf_ptr(&cast_result->data.slice_mismatch->wanted_child->name))); 14481 report_recursive_error(ira, source_node, &cast_result->data.slice_mismatch->child, msg); 14482 break; 14483 } 14484 case ConstCastResultIdErrorUnionPayload: { 14485 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 14486 buf_sprintf("error union payload '%s' cannot cast into error union payload '%s'", 14487 buf_ptr(&cast_result->data.error_union_payload->actual_payload->name), 14488 buf_ptr(&cast_result->data.error_union_payload->wanted_payload->name))); 14489 report_recursive_error(ira, source_node, &cast_result->data.error_union_payload->child, msg); 14490 break; 14491 } 14492 case ConstCastResultIdType: { 14493 AstNode *wanted_decl_node = type_decl_node(cast_result->data.type_mismatch->wanted_type); 14494 AstNode *actual_decl_node = type_decl_node(cast_result->data.type_mismatch->actual_type); 14495 if (wanted_decl_node != nullptr) { 14496 add_error_note(ira->codegen, parent_msg, wanted_decl_node, 14497 buf_sprintf("%s declared here", 14498 buf_ptr(&cast_result->data.type_mismatch->wanted_type->name))); 14499 } 14500 if (actual_decl_node != nullptr) { 14501 add_error_note(ira->codegen, parent_msg, actual_decl_node, 14502 buf_sprintf("%s declared here", 14503 buf_ptr(&cast_result->data.type_mismatch->actual_type->name))); 14504 } 14505 break; 14506 } 14507 case ConstCastResultIdFnArg: { 14508 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 14509 buf_sprintf("parameter %" ZIG_PRI_usize ": '%s' cannot cast into '%s'", 14510 cast_result->data.fn_arg.arg_index, 14511 buf_ptr(&cast_result->data.fn_arg.actual_param_type->name), 14512 buf_ptr(&cast_result->data.fn_arg.expected_param_type->name))); 14513 report_recursive_error(ira, source_node, cast_result->data.fn_arg.child, msg); 14514 break; 14515 } 14516 case ConstCastResultIdBadAllowsZero: { 14517 ZigType *wanted_type = cast_result->data.bad_allows_zero->wanted_type; 14518 ZigType *actual_type = cast_result->data.bad_allows_zero->actual_type; 14519 bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); 14520 bool actual_allows_zero = ptr_allows_addr_zero(actual_type); 14521 if (actual_allows_zero && !wanted_allows_zero) { 14522 add_error_note(ira->codegen, parent_msg, source_node, 14523 buf_sprintf("'%s' could have null values which are illegal in type '%s'", 14524 buf_ptr(&actual_type->name), 14525 buf_ptr(&wanted_type->name))); 14526 } else { 14527 add_error_note(ira->codegen, parent_msg, source_node, 14528 buf_sprintf("mutable '%s' allows illegal null values stored to type '%s'", 14529 buf_ptr(&wanted_type->name), 14530 buf_ptr(&actual_type->name))); 14531 } 14532 break; 14533 } 14534 case ConstCastResultIdPtrLens: { 14535 add_error_note(ira->codegen, parent_msg, source_node, 14536 buf_sprintf("pointer length mismatch")); 14537 break; 14538 } 14539 case ConstCastResultIdPtrSentinel: { 14540 ZigType *actual_type = cast_result->data.bad_ptr_sentinel->actual_type; 14541 ZigType *wanted_type = cast_result->data.bad_ptr_sentinel->wanted_type; 14542 { 14543 Buf *txt_msg = buf_sprintf("destination pointer requires a terminating '"); 14544 render_const_value(ira->codegen, txt_msg, wanted_type->data.pointer.sentinel); 14545 buf_appendf(txt_msg, "' sentinel"); 14546 if (actual_type->data.pointer.sentinel != nullptr) { 14547 buf_appendf(txt_msg, ", but source pointer has a terminating '"); 14548 render_const_value(ira->codegen, txt_msg, actual_type->data.pointer.sentinel); 14549 buf_appendf(txt_msg, "' sentinel"); 14550 } 14551 add_error_note(ira->codegen, parent_msg, source_node, txt_msg); 14552 } 14553 break; 14554 } 14555 case ConstCastResultIdSentinelArrays: { 14556 ZigType *actual_type = cast_result->data.sentinel_arrays->actual_type; 14557 ZigType *wanted_type = cast_result->data.sentinel_arrays->wanted_type; 14558 Buf *txt_msg = buf_sprintf("destination array requires a terminating '"); 14559 render_const_value(ira->codegen, txt_msg, wanted_type->data.array.sentinel); 14560 buf_appendf(txt_msg, "' sentinel"); 14561 if (actual_type->data.array.sentinel != nullptr) { 14562 buf_appendf(txt_msg, ", but source array has a terminating '"); 14563 render_const_value(ira->codegen, txt_msg, actual_type->data.array.sentinel); 14564 buf_appendf(txt_msg, "' sentinel"); 14565 } 14566 add_error_note(ira->codegen, parent_msg, source_node, txt_msg); 14567 break; 14568 } 14569 case ConstCastResultIdCV: { 14570 ZigType *wanted_type = cast_result->data.bad_cv->wanted_type; 14571 ZigType *actual_type = cast_result->data.bad_cv->actual_type; 14572 bool ok_const = !actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const; 14573 bool ok_volatile = !actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile; 14574 if (!ok_const) { 14575 add_error_note(ira->codegen, parent_msg, source_node, buf_sprintf("cast discards const qualifier")); 14576 } else if (!ok_volatile) { 14577 add_error_note(ira->codegen, parent_msg, source_node, buf_sprintf("cast discards volatile qualifier")); 14578 } else { 14579 zig_unreachable(); 14580 } 14581 break; 14582 } 14583 case ConstCastResultIdFnIsGeneric: 14584 add_error_note(ira->codegen, parent_msg, source_node, 14585 buf_sprintf("only one of the functions is generic")); 14586 break; 14587 case ConstCastResultIdFnCC: 14588 add_error_note(ira->codegen, parent_msg, source_node, 14589 buf_sprintf("calling convention mismatch")); 14590 break; 14591 case ConstCastResultIdIntShorten: { 14592 ZigType *wanted_type = cast_result->data.int_shorten->wanted_type; 14593 ZigType *actual_type = cast_result->data.int_shorten->actual_type; 14594 const char *wanted_signed = wanted_type->data.integral.is_signed ? "signed" : "unsigned"; 14595 const char *actual_signed = actual_type->data.integral.is_signed ? "signed" : "unsigned"; 14596 add_error_note(ira->codegen, parent_msg, source_node, 14597 buf_sprintf("%s %" PRIu32 "-bit int cannot represent all possible %s %" PRIu32 "-bit values", 14598 wanted_signed, wanted_type->data.integral.bit_count, 14599 actual_signed, actual_type->data.integral.bit_count)); 14600 break; 14601 } 14602 case ConstCastResultIdFnAlign: // TODO 14603 case ConstCastResultIdFnVarArgs: // TODO 14604 case ConstCastResultIdFnReturnType: // TODO 14605 case ConstCastResultIdFnArgCount: // TODO 14606 case ConstCastResultIdFnGenericArgCount: // TODO 14607 case ConstCastResultIdFnArgNoAlias: // TODO 14608 case ConstCastResultIdUnresolvedInferredErrSet: // TODO 14609 case ConstCastResultIdAsyncAllocatorType: // TODO 14610 case ConstCastResultIdArrayChild: // TODO 14611 break; 14612 } 14613 } 14614 14615 static IrInstGen *ir_analyze_array_to_vector(IrAnalyze *ira, IrInst* source_instr, 14616 IrInstGen *array, ZigType *vector_type) 14617 { 14618 if (instr_is_comptime(array)) { 14619 // arrays and vectors have the same ZigValue representation 14620 IrInstGen *result = ir_const(ira, source_instr, vector_type); 14621 copy_const_val(ira->codegen, result->value, array->value); 14622 result->value->type = vector_type; 14623 return result; 14624 } 14625 return ir_build_array_to_vector(ira, source_instr, array, vector_type); 14626 } 14627 14628 static IrInstGen *ir_analyze_vector_to_array(IrAnalyze *ira, IrInst* source_instr, 14629 IrInstGen *vector, ZigType *array_type, ResultLoc *result_loc) 14630 { 14631 if (instr_is_comptime(vector)) { 14632 // arrays and vectors have the same ZigValue representation 14633 IrInstGen *result = ir_const(ira, source_instr, array_type); 14634 copy_const_val(ira->codegen, result->value, vector->value); 14635 result->value->type = array_type; 14636 return result; 14637 } 14638 if (result_loc == nullptr) { 14639 result_loc = no_result_loc(); 14640 } 14641 IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, result_loc, array_type, nullptr, true, true); 14642 if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { 14643 return result_loc_inst; 14644 } 14645 return ir_build_vector_to_array(ira, source_instr, array_type, vector, result_loc_inst); 14646 } 14647 14648 static IrInstGen *ir_analyze_int_to_c_ptr(IrAnalyze *ira, IrInst* source_instr, 14649 IrInstGen *integer, ZigType *dest_type) 14650 { 14651 IrInstGen *unsigned_integer; 14652 if (instr_is_comptime(integer)) { 14653 unsigned_integer = integer; 14654 } else { 14655 assert(integer->value->type->id == ZigTypeIdInt); 14656 14657 if (integer->value->type->data.integral.bit_count > 14658 ira->codegen->builtin_types.entry_usize->data.integral.bit_count) 14659 { 14660 ir_add_error(ira, source_instr, 14661 buf_sprintf("integer type '%s' too big for implicit @intToPtr to type '%s'", 14662 buf_ptr(&integer->value->type->name), 14663 buf_ptr(&dest_type->name))); 14664 return ira->codegen->invalid_inst_gen; 14665 } 14666 14667 if (integer->value->type->data.integral.is_signed) { 14668 ZigType *unsigned_int_type = get_int_type(ira->codegen, false, 14669 integer->value->type->data.integral.bit_count); 14670 unsigned_integer = ir_analyze_bit_cast(ira, source_instr, integer, unsigned_int_type); 14671 if (type_is_invalid(unsigned_integer->value->type)) 14672 return ira->codegen->invalid_inst_gen; 14673 } else { 14674 unsigned_integer = integer; 14675 } 14676 } 14677 14678 return ir_analyze_int_to_ptr(ira, source_instr, unsigned_integer, dest_type); 14679 } 14680 14681 static bool is_pointery_and_elem_is_not_pointery(ZigType *ty) { 14682 if (ty->id == ZigTypeIdPointer) return ty->data.pointer.child_type->id != ZigTypeIdPointer; 14683 if (ty->id == ZigTypeIdFn) return true; 14684 if (ty->id == ZigTypeIdOptional) { 14685 ZigType *ptr_ty = ty->data.maybe.child_type; 14686 if (ptr_ty->id == ZigTypeIdPointer) return ptr_ty->data.pointer.child_type->id != ZigTypeIdPointer; 14687 if (ptr_ty->id == ZigTypeIdFn) return true; 14688 } 14689 return false; 14690 } 14691 14692 static IrInstGen *ir_analyze_enum_literal(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 14693 ZigType *enum_type) 14694 { 14695 assert(enum_type->id == ZigTypeIdEnum); 14696 14697 Error err; 14698 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusZeroBitsKnown))) 14699 return ira->codegen->invalid_inst_gen; 14700 14701 TypeEnumField *field = find_enum_type_field(enum_type, value->value->data.x_enum_literal); 14702 if (field == nullptr) { 14703 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("enum '%s' has no field named '%s'", 14704 buf_ptr(&enum_type->name), buf_ptr(value->value->data.x_enum_literal))); 14705 add_error_note(ira->codegen, msg, enum_type->data.enumeration.decl_node, 14706 buf_sprintf("'%s' declared here", buf_ptr(&enum_type->name))); 14707 return ira->codegen->invalid_inst_gen; 14708 } 14709 IrInstGen *result = ir_const(ira, source_instr, enum_type); 14710 bigint_init_bigint(&result->value->data.x_enum_tag, &field->value); 14711 14712 return result; 14713 } 14714 14715 static IrInstGen *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInst* source_instr, 14716 IrInstGen *value, ZigType *wanted_type) 14717 { 14718 ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon list literal to array")); 14719 return ira->codegen->invalid_inst_gen; 14720 } 14721 14722 static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* source_instr, 14723 IrInstGen *struct_operand, ZigType *wanted_type) 14724 { 14725 Error err; 14726 14727 IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, struct_operand, true, false); 14728 if (type_is_invalid(struct_ptr->value->type)) 14729 return ira->codegen->invalid_inst_gen; 14730 14731 if (wanted_type->data.structure.resolve_status == ResolveStatusBeingInferred) { 14732 ir_add_error(ira, source_instr, buf_sprintf("type coercion of anon struct literal to inferred struct")); 14733 return ira->codegen->invalid_inst_gen; 14734 } 14735 14736 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusSizeKnown))) 14737 return ira->codegen->invalid_inst_gen; 14738 14739 size_t actual_field_count = wanted_type->data.structure.src_field_count; 14740 size_t instr_field_count = struct_operand->value->type->data.structure.src_field_count; 14741 14742 bool need_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope) 14743 || type_requires_comptime(ira->codegen, wanted_type) == ReqCompTimeYes; 14744 bool is_comptime = true; 14745 14746 // Determine if the struct_operand will be comptime. 14747 // Also emit compile errors for missing fields and duplicate fields. 14748 AstNode **field_assign_nodes = heap::c_allocator.allocate<AstNode *>(actual_field_count); 14749 ZigValue **field_values = heap::c_allocator.allocate<ZigValue *>(actual_field_count); 14750 IrInstGen **casted_fields = heap::c_allocator.allocate<IrInstGen *>(actual_field_count); 14751 IrInstGen *const_result = ir_const(ira, source_instr, wanted_type); 14752 14753 for (size_t i = 0; i < instr_field_count; i += 1) { 14754 TypeStructField *src_field = struct_operand->value->type->data.structure.fields[i]; 14755 TypeStructField *dst_field = find_struct_type_field(wanted_type, src_field->name); 14756 if (dst_field == nullptr) { 14757 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("no field named '%s' in struct '%s'", 14758 buf_ptr(src_field->name), buf_ptr(&wanted_type->name))); 14759 if (wanted_type->data.structure.decl_node) { 14760 add_error_note(ira->codegen, msg, wanted_type->data.structure.decl_node, 14761 buf_sprintf("struct '%s' declared here", buf_ptr(&wanted_type->name))); 14762 } 14763 add_error_note(ira->codegen, msg, src_field->decl_node, 14764 buf_sprintf("field '%s' declared here", buf_ptr(src_field->name))); 14765 return ira->codegen->invalid_inst_gen; 14766 } 14767 14768 ir_assert(src_field->decl_node != nullptr, source_instr); 14769 AstNode *existing_assign_node = field_assign_nodes[dst_field->src_index]; 14770 if (existing_assign_node != nullptr) { 14771 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("duplicate field")); 14772 add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here")); 14773 return ira->codegen->invalid_inst_gen; 14774 } 14775 field_assign_nodes[dst_field->src_index] = src_field->decl_node; 14776 14777 IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, src_field, struct_ptr, 14778 struct_operand->value->type, false); 14779 if (type_is_invalid(field_ptr->value->type)) 14780 return ira->codegen->invalid_inst_gen; 14781 IrInstGen *field_value = ir_get_deref(ira, source_instr, field_ptr, nullptr); 14782 if (type_is_invalid(field_value->value->type)) 14783 return ira->codegen->invalid_inst_gen; 14784 IrInstGen *casted_value = ir_implicit_cast(ira, field_value, dst_field->type_entry); 14785 if (type_is_invalid(casted_value->value->type)) 14786 return ira->codegen->invalid_inst_gen; 14787 14788 casted_fields[dst_field->src_index] = casted_value; 14789 if (need_comptime || instr_is_comptime(casted_value)) { 14790 ZigValue *field_val = ir_resolve_const(ira, casted_value, UndefOk); 14791 if (field_val == nullptr) 14792 return ira->codegen->invalid_inst_gen; 14793 field_val->parent.id = ConstParentIdStruct; 14794 field_val->parent.data.p_struct.struct_val = const_result->value; 14795 field_val->parent.data.p_struct.field_index = dst_field->src_index; 14796 field_values[dst_field->src_index] = field_val; 14797 } else { 14798 is_comptime = false; 14799 } 14800 } 14801 14802 bool any_missing = false; 14803 for (size_t i = 0; i < actual_field_count; i += 1) { 14804 if (field_assign_nodes[i] != nullptr) continue; 14805 14806 // look for a default field value 14807 TypeStructField *field = wanted_type->data.structure.fields[i]; 14808 memoize_field_init_val(ira->codegen, wanted_type, field); 14809 if (field->init_val == nullptr) { 14810 ir_add_error(ira, source_instr, 14811 buf_sprintf("missing field: '%s'", buf_ptr(field->name))); 14812 any_missing = true; 14813 continue; 14814 } 14815 if (type_is_invalid(field->init_val->type)) 14816 return ira->codegen->invalid_inst_gen; 14817 ZigValue *init_val_copy = ira->codegen->pass1_arena->create<ZigValue>(); 14818 copy_const_val(ira->codegen, init_val_copy, field->init_val); 14819 init_val_copy->parent.id = ConstParentIdStruct; 14820 init_val_copy->parent.data.p_struct.struct_val = const_result->value; 14821 init_val_copy->parent.data.p_struct.field_index = i; 14822 field_values[i] = init_val_copy; 14823 casted_fields[i] = ir_const_move(ira, source_instr, init_val_copy); 14824 } 14825 if (any_missing) 14826 return ira->codegen->invalid_inst_gen; 14827 14828 if (is_comptime) { 14829 heap::c_allocator.deallocate(field_assign_nodes, actual_field_count); 14830 IrInstGen *const_result = ir_const(ira, source_instr, wanted_type); 14831 const_result->value->data.x_struct.fields = field_values; 14832 return const_result; 14833 } 14834 14835 IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, no_result_loc(), 14836 wanted_type, nullptr, true, true); 14837 if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { 14838 return ira->codegen->invalid_inst_gen; 14839 } 14840 14841 for (size_t i = 0; i < actual_field_count; i += 1) { 14842 TypeStructField *field = wanted_type->data.structure.fields[i]; 14843 IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, result_loc_inst, wanted_type, true); 14844 if (type_is_invalid(field_ptr->value->type)) 14845 return ira->codegen->invalid_inst_gen; 14846 IrInstGen *store_ptr_inst = ir_analyze_store_ptr(ira, source_instr, field_ptr, casted_fields[i], true); 14847 if (type_is_invalid(store_ptr_inst->value->type)) 14848 return ira->codegen->invalid_inst_gen; 14849 } 14850 14851 heap::c_allocator.deallocate(field_assign_nodes, actual_field_count); 14852 heap::c_allocator.deallocate(field_values, actual_field_count); 14853 heap::c_allocator.deallocate(casted_fields, actual_field_count); 14854 14855 return ir_get_deref(ira, source_instr, result_loc_inst, nullptr); 14856 } 14857 14858 static IrInstGen *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInst* source_instr, 14859 IrInstGen *value, ZigType *union_type) 14860 { 14861 Error err; 14862 ZigType *struct_type = value->value->type; 14863 14864 assert(struct_type->id == ZigTypeIdStruct); 14865 assert(union_type->id == ZigTypeIdUnion); 14866 assert(struct_type->data.structure.src_field_count == 1); 14867 14868 TypeStructField *only_field = struct_type->data.structure.fields[0]; 14869 14870 if ((err = type_resolve(ira->codegen, union_type, ResolveStatusZeroBitsKnown))) 14871 return ira->codegen->invalid_inst_gen; 14872 14873 TypeUnionField *union_field = find_union_type_field(union_type, only_field->name); 14874 if (union_field == nullptr) { 14875 ir_add_error_node(ira, only_field->decl_node, 14876 buf_sprintf("no field named '%s' in union '%s'", 14877 buf_ptr(only_field->name), buf_ptr(&union_type->name))); 14878 return ira->codegen->invalid_inst_gen; 14879 } 14880 14881 ZigType *payload_type = resolve_union_field_type(ira->codegen, union_field); 14882 if (payload_type == nullptr) 14883 return ira->codegen->invalid_inst_gen; 14884 14885 IrInstGen *field_value = ir_analyze_struct_value_field_value(ira, source_instr, value, only_field); 14886 if (type_is_invalid(field_value->value->type)) 14887 return ira->codegen->invalid_inst_gen; 14888 14889 IrInstGen *casted_value = ir_implicit_cast(ira, field_value, payload_type); 14890 if (type_is_invalid(casted_value->value->type)) 14891 return ira->codegen->invalid_inst_gen; 14892 14893 if (instr_is_comptime(casted_value)) { 14894 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); 14895 if (val == nullptr) 14896 return ira->codegen->invalid_inst_gen; 14897 14898 IrInstGen *result = ir_const(ira, source_instr, union_type); 14899 bigint_init_bigint(&result->value->data.x_union.tag, &union_field->enum_field->value); 14900 result->value->data.x_union.payload = val; 14901 14902 val->parent.id = ConstParentIdUnion; 14903 val->parent.data.p_union.union_val = result->value; 14904 14905 return result; 14906 } 14907 14908 IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, no_result_loc(), 14909 union_type, nullptr, true, true); 14910 if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { 14911 return ira->codegen->invalid_inst_gen; 14912 } 14913 14914 IrInstGen *payload_ptr = ir_analyze_container_field_ptr(ira, only_field->name, source_instr, 14915 result_loc_inst, source_instr, union_type, true); 14916 if (type_is_invalid(payload_ptr->value->type)) 14917 return ira->codegen->invalid_inst_gen; 14918 14919 IrInstGen *store_ptr_inst = ir_analyze_store_ptr(ira, source_instr, payload_ptr, casted_value, false); 14920 if (type_is_invalid(store_ptr_inst->value->type)) 14921 return ira->codegen->invalid_inst_gen; 14922 14923 return ir_get_deref(ira, source_instr, result_loc_inst, nullptr); 14924 } 14925 14926 // Add a compile error and return ErrorSemanticAnalyzeFail if the pointer alignment does not work, 14927 // otherwise return ErrorNone. Does not emit any instructions. 14928 // Assumes that the pointer types have element types with the same ABI alignment. Avoids resolving the 14929 // pointer types' alignments if both of the pointer types are ABI aligned. 14930 static Error ir_cast_ptr_align(IrAnalyze *ira, IrInst* source_instr, ZigType *dest_ptr_type, 14931 ZigType *src_ptr_type, AstNode *src_source_node) 14932 { 14933 Error err; 14934 14935 ir_assert(dest_ptr_type->id == ZigTypeIdPointer, source_instr); 14936 ir_assert(src_ptr_type->id == ZigTypeIdPointer, source_instr); 14937 14938 if (dest_ptr_type->data.pointer.explicit_alignment == 0 && 14939 src_ptr_type->data.pointer.explicit_alignment == 0) 14940 { 14941 return ErrorNone; 14942 } 14943 14944 if ((err = type_resolve(ira->codegen, dest_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 14945 return ErrorSemanticAnalyzeFail; 14946 14947 if ((err = type_resolve(ira->codegen, src_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 14948 return ErrorSemanticAnalyzeFail; 14949 14950 uint32_t wanted_align = get_ptr_align(ira->codegen, dest_ptr_type); 14951 uint32_t actual_align = get_ptr_align(ira->codegen, src_ptr_type); 14952 if (wanted_align > actual_align) { 14953 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 14954 add_error_note(ira->codegen, msg, src_source_node, 14955 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_ptr_type->name), actual_align)); 14956 add_error_note(ira->codegen, msg, source_instr->source_node, 14957 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&dest_ptr_type->name), wanted_align)); 14958 return ErrorSemanticAnalyzeFail; 14959 } 14960 14961 return ErrorNone; 14962 } 14963 14964 static IrInstGen *ir_analyze_struct_value_field_value(IrAnalyze *ira, IrInst* source_instr, 14965 IrInstGen *struct_operand, TypeStructField *field) 14966 { 14967 IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, struct_operand, true, false); 14968 if (type_is_invalid(struct_ptr->value->type)) 14969 return ira->codegen->invalid_inst_gen; 14970 IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, struct_ptr, 14971 struct_operand->value->type, false); 14972 if (type_is_invalid(field_ptr->value->type)) 14973 return ira->codegen->invalid_inst_gen; 14974 return ir_get_deref(ira, source_instr, field_ptr, nullptr); 14975 } 14976 14977 static IrInstGen *ir_analyze_optional_value_payload_value(IrAnalyze *ira, IrInst* source_instr, 14978 IrInstGen *optional_operand, bool safety_check_on) 14979 { 14980 IrInstGen *opt_ptr = ir_get_ref(ira, source_instr, optional_operand, true, false); 14981 IrInstGen *payload_ptr = ir_analyze_unwrap_optional_payload(ira, source_instr, opt_ptr, 14982 safety_check_on, false); 14983 return ir_get_deref(ira, source_instr, payload_ptr, nullptr); 14984 } 14985 14986 static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr, 14987 ZigType *wanted_type, IrInstGen *value) 14988 { 14989 Error err; 14990 ZigType *actual_type = value->value->type; 14991 AstNode *source_node = source_instr->source_node; 14992 14993 if (type_is_invalid(wanted_type) || type_is_invalid(actual_type)) { 14994 return ira->codegen->invalid_inst_gen; 14995 } 14996 14997 // This means the wanted type is anything. 14998 if (wanted_type == ira->codegen->builtin_types.entry_var) { 14999 return value; 15000 } 15001 15002 // perfect match or non-const to const 15003 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type, 15004 source_node, false); 15005 if (const_cast_result.id == ConstCastResultIdInvalid) 15006 return ira->codegen->invalid_inst_gen; 15007 if (const_cast_result.id == ConstCastResultIdOk) { 15008 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); 15009 } 15010 15011 if (const_cast_result.id == ConstCastResultIdFnCC) { 15012 ir_assert(value->value->type->id == ZigTypeIdFn, source_instr); 15013 // ConstCastResultIdFnCC is guaranteed to be the last one reported, meaning everything else is ok. 15014 if (wanted_type->data.fn.fn_type_id.cc == CallingConventionAsync && 15015 actual_type->data.fn.fn_type_id.cc == CallingConventionUnspecified) 15016 { 15017 ir_assert(value->value->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); 15018 ZigFn *fn = value->value->data.x_ptr.data.fn.fn_entry; 15019 if (fn->inferred_async_node == nullptr) { 15020 fn->inferred_async_node = source_instr->source_node; 15021 } 15022 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop); 15023 } 15024 } 15025 15026 // cast from T to ?T 15027 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism 15028 if (wanted_type->id == ZigTypeIdOptional) { 15029 ZigType *wanted_child_type = wanted_type->data.maybe.child_type; 15030 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, 15031 false).id == ConstCastResultIdOk) 15032 { 15033 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, nullptr); 15034 } else if (actual_type->id == ZigTypeIdComptimeInt || 15035 actual_type->id == ZigTypeIdComptimeFloat) 15036 { 15037 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { 15038 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, nullptr); 15039 } else { 15040 return ira->codegen->invalid_inst_gen; 15041 } 15042 } else if ( 15043 wanted_child_type->id == ZigTypeIdPointer && 15044 wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && 15045 actual_type->id == ZigTypeIdPointer && 15046 actual_type->data.pointer.ptr_len == PtrLenSingle && 15047 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 15048 { 15049 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 15050 return ira->codegen->invalid_inst_gen; 15051 if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 15052 return ira->codegen->invalid_inst_gen; 15053 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && 15054 types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, 15055 actual_type->data.pointer.child_type->data.array.child_type, source_node, 15056 !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) 15057 { 15058 IrInstGen *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, 15059 wanted_child_type); 15060 if (type_is_invalid(cast1->value->type)) 15061 return ira->codegen->invalid_inst_gen; 15062 return ir_analyze_optional_wrap(ira, source_instr, cast1, wanted_type, nullptr); 15063 } 15064 } 15065 } 15066 15067 // T to E!T 15068 if (wanted_type->id == ZigTypeIdErrorUnion) { 15069 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, 15070 source_node, false).id == ConstCastResultIdOk) 15071 { 15072 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, nullptr); 15073 } else if (actual_type->id == ZigTypeIdComptimeInt || 15074 actual_type->id == ZigTypeIdComptimeFloat) 15075 { 15076 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { 15077 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, nullptr); 15078 } else { 15079 return ira->codegen->invalid_inst_gen; 15080 } 15081 } 15082 } 15083 15084 // cast from T to E!?T 15085 if (wanted_type->id == ZigTypeIdErrorUnion && 15086 wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && 15087 actual_type->id != ZigTypeIdOptional) 15088 { 15089 ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; 15090 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || 15091 actual_type->id == ZigTypeIdNull || 15092 actual_type->id == ZigTypeIdComptimeInt || 15093 actual_type->id == ZigTypeIdComptimeFloat) 15094 { 15095 IrInstGen *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); 15096 if (type_is_invalid(cast1->value->type)) 15097 return ira->codegen->invalid_inst_gen; 15098 15099 IrInstGen *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 15100 if (type_is_invalid(cast2->value->type)) 15101 return ira->codegen->invalid_inst_gen; 15102 15103 return cast2; 15104 } 15105 } 15106 15107 15108 // cast from comptime-known number to another number type 15109 if (instr_is_comptime(value) && 15110 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt || 15111 actual_type->id == ZigTypeIdFloat || actual_type->id == ZigTypeIdComptimeFloat) && 15112 (wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdComptimeInt || 15113 wanted_type->id == ZigTypeIdFloat || wanted_type->id == ZigTypeIdComptimeFloat)) 15114 { 15115 if (value->value->special == ConstValSpecialUndef) { 15116 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 15117 result->value->special = ConstValSpecialUndef; 15118 return result; 15119 } 15120 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { 15121 if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) { 15122 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 15123 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { 15124 copy_const_val(ira->codegen, result->value, value->value); 15125 result->value->type = wanted_type; 15126 } else { 15127 float_init_bigint(&result->value->data.x_bigint, value->value); 15128 } 15129 return result; 15130 } else if (wanted_type->id == ZigTypeIdComptimeFloat || wanted_type->id == ZigTypeIdFloat) { 15131 IrInstGen *result = ir_const(ira, source_instr, wanted_type); 15132 if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { 15133 BigFloat bf; 15134 bigfloat_init_bigint(&bf, &value->value->data.x_bigint); 15135 float_init_bigfloat(result->value, &bf); 15136 } else { 15137 float_init_float(result->value, value->value); 15138 } 15139 return result; 15140 } 15141 zig_unreachable(); 15142 } else { 15143 return ira->codegen->invalid_inst_gen; 15144 } 15145 } 15146 15147 // widening conversion 15148 if (wanted_type->id == ZigTypeIdInt && 15149 actual_type->id == ZigTypeIdInt && 15150 wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed && 15151 wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count) 15152 { 15153 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 15154 } 15155 15156 // small enough unsigned ints can get casted to large enough signed ints 15157 if (wanted_type->id == ZigTypeIdInt && wanted_type->data.integral.is_signed && 15158 actual_type->id == ZigTypeIdInt && !actual_type->data.integral.is_signed && 15159 wanted_type->data.integral.bit_count > actual_type->data.integral.bit_count) 15160 { 15161 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 15162 } 15163 15164 // float widening conversion 15165 if (wanted_type->id == ZigTypeIdFloat && 15166 actual_type->id == ZigTypeIdFloat && 15167 wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count) 15168 { 15169 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 15170 } 15171 15172 // *[N]T to ?[]T 15173 if (wanted_type->id == ZigTypeIdOptional && 15174 is_slice(wanted_type->data.maybe.child_type) && 15175 actual_type->id == ZigTypeIdPointer && 15176 actual_type->data.pointer.ptr_len == PtrLenSingle && 15177 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 15178 { 15179 IrInstGen *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); 15180 if (type_is_invalid(cast1->value->type)) 15181 return ira->codegen->invalid_inst_gen; 15182 15183 IrInstGen *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 15184 if (type_is_invalid(cast2->value->type)) 15185 return ira->codegen->invalid_inst_gen; 15186 15187 return cast2; 15188 } 15189 15190 // *[N]T to [*]T and [*c]T 15191 if (wanted_type->id == ZigTypeIdPointer && 15192 (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC) && 15193 actual_type->id == ZigTypeIdPointer && 15194 actual_type->data.pointer.ptr_len == PtrLenSingle && 15195 actual_type->data.pointer.child_type->id == ZigTypeIdArray && 15196 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && 15197 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) 15198 { 15199 ZigType *actual_array_type = actual_type->data.pointer.child_type; 15200 if (wanted_type->data.pointer.sentinel == nullptr || 15201 (actual_array_type->data.array.sentinel != nullptr && 15202 const_values_equal(ira->codegen, wanted_type->data.pointer.sentinel, 15203 actual_array_type->data.array.sentinel))) 15204 { 15205 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 15206 return ira->codegen->invalid_inst_gen; 15207 if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 15208 return ira->codegen->invalid_inst_gen; 15209 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type) && 15210 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 15211 actual_type->data.pointer.child_type->data.array.child_type, source_node, 15212 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 15213 { 15214 return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type); 15215 } 15216 } 15217 } 15218 15219 // *[N]T to []T 15220 // *[N]T to E![]T 15221 if ((is_slice(wanted_type) || 15222 (wanted_type->id == ZigTypeIdErrorUnion && 15223 is_slice(wanted_type->data.error_union.payload_type))) && 15224 actual_type->id == ZigTypeIdPointer && 15225 actual_type->data.pointer.ptr_len == PtrLenSingle && 15226 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 15227 { 15228 ZigType *slice_type = (wanted_type->id == ZigTypeIdErrorUnion) ? 15229 wanted_type->data.error_union.payload_type : wanted_type; 15230 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 15231 assert(slice_ptr_type->id == ZigTypeIdPointer); 15232 ZigType *array_type = actual_type->data.pointer.child_type; 15233 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 15234 || !actual_type->data.pointer.is_const); 15235 if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 15236 array_type->data.array.child_type, source_node, 15237 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) 15238 { 15239 // If the pointers both have ABI align, it works. 15240 // Or if the array length is 0, alignment doesn't matter. 15241 bool ok_align = array_type->data.array.len == 0 || 15242 (slice_ptr_type->data.pointer.explicit_alignment == 0 && 15243 actual_type->data.pointer.explicit_alignment == 0); 15244 if (!ok_align) { 15245 // If either one has non ABI align, we have to resolve them both 15246 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, 15247 ResolveStatusAlignmentKnown))) 15248 { 15249 return ira->codegen->invalid_inst_gen; 15250 } 15251 if ((err = type_resolve(ira->codegen, slice_ptr_type->data.pointer.child_type, 15252 ResolveStatusAlignmentKnown))) 15253 { 15254 return ira->codegen->invalid_inst_gen; 15255 } 15256 ok_align = get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, slice_ptr_type); 15257 } 15258 if (ok_align) { 15259 if (wanted_type->id == ZigTypeIdErrorUnion) { 15260 IrInstGen *cast1 = ir_analyze_cast(ira, source_instr, slice_type, value); 15261 if (type_is_invalid(cast1->value->type)) 15262 return ira->codegen->invalid_inst_gen; 15263 15264 IrInstGen *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 15265 if (type_is_invalid(cast2->value->type)) 15266 return ira->codegen->invalid_inst_gen; 15267 15268 return cast2; 15269 } else { 15270 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, slice_type, nullptr); 15271 } 15272 } 15273 } 15274 } 15275 15276 // @Vector(N,T1) to @Vector(N,T2) 15277 if (actual_type->id == ZigTypeIdVector && wanted_type->id == ZigTypeIdVector) { 15278 if (actual_type->data.vector.len == wanted_type->data.vector.len && 15279 types_match_const_cast_only(ira, wanted_type->data.vector.elem_type, 15280 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 15281 { 15282 return ir_analyze_bit_cast(ira, source_instr, value, wanted_type); 15283 } 15284 } 15285 15286 // *@Frame(func) to anyframe->T or anyframe 15287 // *@Frame(func) to ?anyframe->T or ?anyframe 15288 // *@Frame(func) to E!anyframe->T or E!anyframe 15289 if (actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle && 15290 !actual_type->data.pointer.is_const && 15291 actual_type->data.pointer.child_type->id == ZigTypeIdFnFrame) 15292 { 15293 ZigType *anyframe_type; 15294 if (wanted_type->id == ZigTypeIdAnyFrame) { 15295 anyframe_type = wanted_type; 15296 } else if (wanted_type->id == ZigTypeIdOptional && 15297 wanted_type->data.maybe.child_type->id == ZigTypeIdAnyFrame) 15298 { 15299 anyframe_type = wanted_type->data.maybe.child_type; 15300 } else if (wanted_type->id == ZigTypeIdErrorUnion && 15301 wanted_type->data.error_union.payload_type->id == ZigTypeIdAnyFrame) 15302 { 15303 anyframe_type = wanted_type->data.error_union.payload_type; 15304 } else { 15305 anyframe_type = nullptr; 15306 } 15307 if (anyframe_type != nullptr) { 15308 bool ok = true; 15309 if (anyframe_type->data.any_frame.result_type != nullptr) { 15310 ZigFn *fn = actual_type->data.pointer.child_type->data.frame.fn; 15311 ZigType *fn_return_type = fn->type_entry->data.fn.fn_type_id.return_type; 15312 if (anyframe_type->data.any_frame.result_type != fn_return_type) { 15313 ok = false; 15314 } 15315 } 15316 if (ok) { 15317 IrInstGen *cast1 = ir_analyze_frame_ptr_to_anyframe(ira, source_instr, value, anyframe_type); 15318 if (anyframe_type == wanted_type) 15319 return cast1; 15320 return ir_analyze_cast(ira, source_instr, wanted_type, cast1); 15321 } 15322 } 15323 } 15324 15325 // anyframe->T to anyframe 15326 if (actual_type->id == ZigTypeIdAnyFrame && actual_type->data.any_frame.result_type != nullptr && 15327 wanted_type->id == ZigTypeIdAnyFrame && wanted_type->data.any_frame.result_type == nullptr) 15328 { 15329 return ir_analyze_anyframe_to_anyframe(ira, source_instr, value, wanted_type); 15330 } 15331 15332 // cast from null literal to maybe type 15333 if (wanted_type->id == ZigTypeIdOptional && 15334 actual_type->id == ZigTypeIdNull) 15335 { 15336 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type); 15337 } 15338 15339 // cast from null literal to C pointer 15340 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC && 15341 actual_type->id == ZigTypeIdNull) 15342 { 15343 return ir_analyze_null_to_c_pointer(ira, source_instr, value, wanted_type); 15344 } 15345 15346 // cast from E to E!T 15347 if (wanted_type->id == ZigTypeIdErrorUnion && 15348 actual_type->id == ZigTypeIdErrorSet) 15349 { 15350 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type, nullptr); 15351 } 15352 15353 // cast from typed number to integer or float literal. 15354 // works when the number is known at compile time 15355 if (instr_is_comptime(value) && 15356 ((actual_type->id == ZigTypeIdInt && wanted_type->id == ZigTypeIdComptimeInt) || 15357 (actual_type->id == ZigTypeIdFloat && wanted_type->id == ZigTypeIdComptimeFloat))) 15358 { 15359 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type); 15360 } 15361 15362 // cast from enum literal to enum with matching field name 15363 if (actual_type->id == ZigTypeIdEnumLiteral && wanted_type->id == ZigTypeIdEnum) 15364 { 15365 return ir_analyze_enum_literal(ira, source_instr, value, wanted_type); 15366 } 15367 15368 // cast from enum literal to optional enum 15369 if (actual_type->id == ZigTypeIdEnumLiteral && 15370 (wanted_type->id == ZigTypeIdOptional && wanted_type->data.maybe.child_type->id == ZigTypeIdEnum)) 15371 { 15372 IrInstGen *result = ir_analyze_enum_literal(ira, source_instr, value, wanted_type->data.maybe.child_type); 15373 if (type_is_invalid(result->value->type)) 15374 return result; 15375 15376 return ir_analyze_optional_wrap(ira, source_instr, value, wanted_type, nullptr); 15377 } 15378 15379 // cast from enum literal to error union when payload is an enum 15380 if (actual_type->id == ZigTypeIdEnumLiteral && 15381 (wanted_type->id == ZigTypeIdErrorUnion && wanted_type->data.error_union.payload_type->id == ZigTypeIdEnum)) 15382 { 15383 IrInstGen *result = ir_analyze_enum_literal(ira, source_instr, value, wanted_type->data.error_union.payload_type); 15384 if (type_is_invalid(result->value->type)) 15385 return result; 15386 15387 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type, nullptr); 15388 } 15389 15390 // cast from union to the enum type of the union 15391 if (actual_type->id == ZigTypeIdUnion && wanted_type->id == ZigTypeIdEnum) { 15392 if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) 15393 return ira->codegen->invalid_inst_gen; 15394 15395 if (actual_type->data.unionation.tag_type == wanted_type) { 15396 return ir_analyze_union_to_tag(ira, source_instr, value, wanted_type); 15397 } 15398 } 15399 15400 // enum to union which has the enum as the tag type, or 15401 // enum literal to union which has a matching enum as the tag type 15402 if (is_tagged_union(wanted_type) && (actual_type->id == ZigTypeIdEnum || 15403 actual_type->id == ZigTypeIdEnumLiteral)) 15404 { 15405 return ir_analyze_enum_to_union(ira, source_instr, value, wanted_type); 15406 } 15407 15408 // cast from *T to *[1]T 15409 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 15410 actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle) 15411 { 15412 ZigType *array_type = wanted_type->data.pointer.child_type; 15413 if (array_type->id == ZigTypeIdArray && array_type->data.array.len == 1 && 15414 types_match_const_cast_only(ira, array_type->data.array.child_type, 15415 actual_type->data.pointer.child_type, source_node, 15416 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk && 15417 // `types_match_const_cast_only` only gets info for child_types 15418 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && 15419 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) 15420 { 15421 if ((err = ir_cast_ptr_align(ira, source_instr, wanted_type, actual_type, value->base.source_node))) 15422 return ira->codegen->invalid_inst_gen; 15423 15424 return ir_analyze_ptr_to_array(ira, source_instr, value, wanted_type); 15425 } 15426 } 15427 15428 // [:x]T to [*:x]T 15429 // [:x]T to [*c]T 15430 if (wanted_type->id == ZigTypeIdPointer && is_slice(actual_type) && 15431 ((wanted_type->data.pointer.ptr_len == PtrLenUnknown && wanted_type->data.pointer.sentinel != nullptr) || 15432 wanted_type->data.pointer.ptr_len == PtrLenC)) 15433 { 15434 ZigType *slice_ptr_type = resolve_struct_field_type(ira->codegen, 15435 actual_type->data.structure.fields[slice_ptr_index]); 15436 if (types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 15437 slice_ptr_type->data.pointer.child_type, source_node, 15438 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk && 15439 (slice_ptr_type->data.pointer.sentinel != nullptr && 15440 (wanted_type->data.pointer.ptr_len == PtrLenC || 15441 const_values_equal(ira->codegen, wanted_type->data.pointer.sentinel, 15442 slice_ptr_type->data.pointer.sentinel)))) 15443 { 15444 TypeStructField *ptr_field = actual_type->data.structure.fields[slice_ptr_index]; 15445 IrInstGen *slice_ptr = ir_analyze_struct_value_field_value(ira, source_instr, value, ptr_field); 15446 return ir_implicit_cast2(ira, source_instr, slice_ptr, wanted_type); 15447 } 15448 } 15449 15450 // cast from *T and [*]T to *c_void and ?*c_void 15451 // but don't do it if the actual type is a double pointer 15452 if (is_pointery_and_elem_is_not_pointery(actual_type)) { 15453 ZigType *dest_ptr_type = nullptr; 15454 if (wanted_type->id == ZigTypeIdPointer && 15455 wanted_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 15456 { 15457 dest_ptr_type = wanted_type; 15458 } else if (wanted_type->id == ZigTypeIdOptional && 15459 wanted_type->data.maybe.child_type->id == ZigTypeIdPointer && 15460 wanted_type->data.maybe.child_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 15461 { 15462 dest_ptr_type = wanted_type->data.maybe.child_type; 15463 } 15464 if (dest_ptr_type != nullptr) { 15465 return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true, 15466 false); 15467 } 15468 } 15469 15470 // cast from T to *T where T is zero bits 15471 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 15472 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 15473 actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 15474 { 15475 bool has_bits; 15476 if ((err = type_has_bits2(ira->codegen, actual_type, &has_bits))) 15477 return ira->codegen->invalid_inst_gen; 15478 if (!has_bits) { 15479 return ir_get_ref(ira, source_instr, value, false, false); 15480 } 15481 } 15482 15483 // cast from @Vector(N, T) to [N]T 15484 if (wanted_type->id == ZigTypeIdArray && actual_type->id == ZigTypeIdVector && 15485 wanted_type->data.array.len == actual_type->data.vector.len && 15486 types_match_const_cast_only(ira, wanted_type->data.array.child_type, 15487 actual_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 15488 { 15489 return ir_analyze_vector_to_array(ira, source_instr, value, wanted_type, nullptr); 15490 } 15491 15492 // cast from [N]T to @Vector(N, T) 15493 if (actual_type->id == ZigTypeIdArray && wanted_type->id == ZigTypeIdVector && 15494 actual_type->data.array.len == wanted_type->data.vector.len && 15495 types_match_const_cast_only(ira, actual_type->data.array.child_type, 15496 wanted_type->data.vector.elem_type, source_node, false).id == ConstCastResultIdOk) 15497 { 15498 return ir_analyze_array_to_vector(ira, source_instr, value, wanted_type); 15499 } 15500 15501 // casting between C pointers and normal pointers 15502 if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer && 15503 (wanted_type->data.pointer.ptr_len == PtrLenC || actual_type->data.pointer.ptr_len == PtrLenC) && 15504 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 15505 actual_type->data.pointer.child_type, source_node, 15506 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 15507 { 15508 return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true, false); 15509 } 15510 15511 // cast from integer to C pointer 15512 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC && 15513 (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt)) 15514 { 15515 return ir_analyze_int_to_c_ptr(ira, source_instr, value, wanted_type); 15516 } 15517 15518 // cast from inferred struct type to array, union, or struct 15519 if (is_anon_container(actual_type)) { 15520 const bool is_array_init = 15521 actual_type->data.structure.special == StructSpecialInferredTuple; 15522 const uint32_t field_count = actual_type->data.structure.src_field_count; 15523 15524 if (wanted_type->id == ZigTypeIdArray && (is_array_init || field_count == 0) && 15525 wanted_type->data.array.len == field_count) 15526 { 15527 return ir_analyze_struct_literal_to_array(ira, source_instr, value, wanted_type); 15528 } else if (wanted_type->id == ZigTypeIdStruct && 15529 (!is_array_init || field_count == 0)) 15530 { 15531 return ir_analyze_struct_literal_to_struct(ira, source_instr, value, wanted_type); 15532 } else if (wanted_type->id == ZigTypeIdUnion && !is_array_init && field_count == 1) { 15533 return ir_analyze_struct_literal_to_union(ira, source_instr, value, wanted_type); 15534 } 15535 } 15536 15537 // cast from undefined to anything 15538 if (actual_type->id == ZigTypeIdUndefined) { 15539 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); 15540 } 15541 15542 // T to ?U, where T implicitly casts to U 15543 if (wanted_type->id == ZigTypeIdOptional && actual_type->id != ZigTypeIdOptional) { 15544 IrInstGen *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.maybe.child_type); 15545 if (type_is_invalid(cast1->value->type)) 15546 return ira->codegen->invalid_inst_gen; 15547 return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); 15548 } 15549 15550 // T to E!U, where T implicitly casts to U 15551 if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id != ZigTypeIdErrorUnion && 15552 actual_type->id != ZigTypeIdErrorSet) 15553 { 15554 IrInstGen *cast1 = ir_implicit_cast2(ira, source_instr, value, wanted_type->data.error_union.payload_type); 15555 if (type_is_invalid(cast1->value->type)) 15556 return ira->codegen->invalid_inst_gen; 15557 return ir_implicit_cast2(ira, source_instr, cast1, wanted_type); 15558 } 15559 15560 ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, 15561 buf_sprintf("expected type '%s', found '%s'", 15562 buf_ptr(&wanted_type->name), 15563 buf_ptr(&actual_type->name))); 15564 report_recursive_error(ira, source_instr->source_node, &const_cast_result, parent_msg); 15565 return ira->codegen->invalid_inst_gen; 15566 } 15567 15568 static IrInstGen *ir_implicit_cast2(IrAnalyze *ira, IrInst *value_source_instr, 15569 IrInstGen *value, ZigType *expected_type) 15570 { 15571 assert(value); 15572 assert(!expected_type || !type_is_invalid(expected_type)); 15573 assert(value->value->type); 15574 assert(!type_is_invalid(value->value->type)); 15575 if (expected_type == nullptr) 15576 return value; // anything will do 15577 if (expected_type == value->value->type) 15578 return value; // match 15579 if (value->value->type->id == ZigTypeIdUnreachable) 15580 return value; 15581 15582 return ir_analyze_cast(ira, value_source_instr, expected_type, value); 15583 } 15584 15585 static IrInstGen *ir_implicit_cast(IrAnalyze *ira, IrInstGen *value, ZigType *expected_type) { 15586 return ir_implicit_cast2(ira, &value->base, value, expected_type); 15587 } 15588 15589 static ZigType *get_ptr_elem_type(CodeGen *g, IrInstGen *ptr) { 15590 ir_assert_gen(ptr->value->type->id == ZigTypeIdPointer, ptr); 15591 ZigType *elem_type = ptr->value->type->data.pointer.child_type; 15592 if (elem_type != g->builtin_types.entry_var) 15593 return elem_type; 15594 15595 if (ir_resolve_lazy(g, ptr->base.source_node, ptr->value)) 15596 return g->builtin_types.entry_invalid; 15597 15598 assert(value_is_comptime(ptr->value)); 15599 ZigValue *pointee = const_ptr_pointee_unchecked(g, ptr->value); 15600 return pointee->type; 15601 } 15602 15603 static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst* source_instruction, IrInstGen *ptr, 15604 ResultLoc *result_loc) 15605 { 15606 Error err; 15607 ZigType *ptr_type = ptr->value->type; 15608 if (type_is_invalid(ptr_type)) 15609 return ira->codegen->invalid_inst_gen; 15610 15611 if (ptr_type->id != ZigTypeIdPointer) { 15612 ir_add_error_node(ira, source_instruction->source_node, 15613 buf_sprintf("attempt to dereference non-pointer type '%s'", 15614 buf_ptr(&ptr_type->name))); 15615 return ira->codegen->invalid_inst_gen; 15616 } 15617 15618 ZigType *child_type = ptr_type->data.pointer.child_type; 15619 if (type_is_invalid(child_type)) 15620 return ira->codegen->invalid_inst_gen; 15621 // if the child type has one possible value, the deref is comptime 15622 switch (type_has_one_possible_value(ira->codegen, child_type)) { 15623 case OnePossibleValueInvalid: 15624 return ira->codegen->invalid_inst_gen; 15625 case OnePossibleValueYes: 15626 return ir_const_move(ira, source_instruction, 15627 get_the_one_possible_value(ira->codegen, child_type)); 15628 case OnePossibleValueNo: 15629 break; 15630 } 15631 if (instr_is_comptime(ptr)) { 15632 if (ptr->value->special == ConstValSpecialUndef) { 15633 // If we are in a TypeOf call, we return an undefined value instead of erroring 15634 // since we know the type. 15635 if (get_scope_typeof(source_instruction->scope)) { 15636 return ir_const_undef(ira, source_instruction, child_type); 15637 } 15638 15639 ir_add_error(ira, &ptr->base, buf_sprintf("attempt to dereference undefined value")); 15640 return ira->codegen->invalid_inst_gen; 15641 } 15642 if (ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 15643 ZigValue *pointee = const_ptr_pointee_unchecked(ira->codegen, ptr->value); 15644 if (child_type == ira->codegen->builtin_types.entry_var) { 15645 child_type = pointee->type; 15646 } 15647 if (pointee->special != ConstValSpecialRuntime) { 15648 IrInstGen *result = ir_const(ira, source_instruction, child_type); 15649 15650 if ((err = ir_read_const_ptr(ira, ira->codegen, source_instruction->source_node, result->value, 15651 ptr->value))) 15652 { 15653 return ira->codegen->invalid_inst_gen; 15654 } 15655 result->value->type = child_type; 15656 return result; 15657 } 15658 } 15659 } 15660 15661 // if the instruction is a const ref instruction we can skip it 15662 if (ptr->id == IrInstGenIdRef) { 15663 IrInstGenRef *ref_inst = reinterpret_cast<IrInstGenRef *>(ptr); 15664 return ref_inst->operand; 15665 } 15666 15667 // If the instruction is a element pointer instruction to a vector, we emit 15668 // vector element extract instruction rather than load pointer. If the 15669 // pointer type has non-VECTOR_INDEX_RUNTIME value, it would have been 15670 // possible to implement this in the codegen for IrInstGenLoadPtr. 15671 // However if it has VECTOR_INDEX_RUNTIME then we must emit a compile error 15672 // if the vector index cannot be determined right here, right now, because 15673 // the type information does not contain enough information to actually 15674 // perform a dereference. 15675 if (ptr_type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) { 15676 if (ptr->id == IrInstGenIdElemPtr) { 15677 IrInstGenElemPtr *elem_ptr = (IrInstGenElemPtr *)ptr; 15678 IrInstGen *vector_loaded = ir_get_deref(ira, &elem_ptr->array_ptr->base, 15679 elem_ptr->array_ptr, nullptr); 15680 IrInstGen *elem_index = elem_ptr->elem_index; 15681 return ir_build_vector_extract_elem(ira, source_instruction, vector_loaded, elem_index); 15682 } 15683 ir_add_error(ira, &ptr->base, 15684 buf_sprintf("unable to determine vector element index of type '%s'", buf_ptr(&ptr_type->name))); 15685 return ira->codegen->invalid_inst_gen; 15686 } 15687 15688 IrInstGen *result_loc_inst; 15689 if (ptr_type->data.pointer.host_int_bytes != 0 && handle_is_ptr(ira->codegen, child_type)) { 15690 if (result_loc == nullptr) result_loc = no_result_loc(); 15691 result_loc_inst = ir_resolve_result(ira, source_instruction, result_loc, child_type, nullptr, true, true); 15692 if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { 15693 return result_loc_inst; 15694 } 15695 } else { 15696 result_loc_inst = nullptr; 15697 } 15698 15699 return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst); 15700 } 15701 15702 static bool ir_resolve_const_align(CodeGen *codegen, IrExecutableGen *exec, AstNode *source_node, 15703 ZigValue *const_val, uint32_t *out) 15704 { 15705 Error err; 15706 if ((err = ir_resolve_const_val(codegen, exec, source_node, const_val, UndefBad))) 15707 return false; 15708 15709 uint32_t align_bytes = bigint_as_u32(&const_val->data.x_bigint); 15710 if (align_bytes == 0) { 15711 exec_add_error_node_gen(codegen, exec, source_node, buf_sprintf("alignment must be >= 1")); 15712 return false; 15713 } 15714 15715 if (!is_power_of_2(align_bytes)) { 15716 exec_add_error_node_gen(codegen, exec, source_node, 15717 buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); 15718 return false; 15719 } 15720 15721 *out = align_bytes; 15722 return true; 15723 } 15724 15725 static bool ir_resolve_align(IrAnalyze *ira, IrInstGen *value, ZigType *elem_type, uint32_t *out) { 15726 if (type_is_invalid(value->value->type)) 15727 return false; 15728 15729 // Look for this pattern: `*align(@alignOf(T)) T`. 15730 // This can be resolved to be `*out = 0` without resolving any alignment. 15731 if (elem_type != nullptr && value->value->special == ConstValSpecialLazy && 15732 value->value->data.x_lazy->id == LazyValueIdAlignOf) 15733 { 15734 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(value->value->data.x_lazy); 15735 15736 ZigType *lazy_elem_type = ir_resolve_type(lazy_align_of->ira, lazy_align_of->target_type); 15737 if (type_is_invalid(lazy_elem_type)) 15738 return false; 15739 15740 if (elem_type == lazy_elem_type) { 15741 *out = 0; 15742 return true; 15743 } 15744 } 15745 15746 IrInstGen *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); 15747 if (type_is_invalid(casted_value->value->type)) 15748 return false; 15749 15750 return ir_resolve_const_align(ira->codegen, ira->new_irb.exec, value->base.source_node, 15751 casted_value->value, out); 15752 } 15753 15754 static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstGen *value, ZigType *int_type, uint64_t *out) { 15755 if (type_is_invalid(value->value->type)) 15756 return false; 15757 15758 IrInstGen *casted_value = ir_implicit_cast(ira, value, int_type); 15759 if (type_is_invalid(casted_value->value->type)) 15760 return false; 15761 15762 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15763 if (!const_val) 15764 return false; 15765 15766 *out = bigint_as_u64(&const_val->data.x_bigint); 15767 return true; 15768 } 15769 15770 static bool ir_resolve_usize(IrAnalyze *ira, IrInstGen *value, uint64_t *out) { 15771 return ir_resolve_unsigned(ira, value, ira->codegen->builtin_types.entry_usize, out); 15772 } 15773 15774 static bool ir_resolve_bool(IrAnalyze *ira, IrInstGen *value, bool *out) { 15775 if (type_is_invalid(value->value->type)) 15776 return false; 15777 15778 IrInstGen *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_bool); 15779 if (type_is_invalid(casted_value->value->type)) 15780 return false; 15781 15782 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15783 if (!const_val) 15784 return false; 15785 15786 *out = const_val->data.x_bool; 15787 return true; 15788 } 15789 15790 static bool ir_resolve_comptime(IrAnalyze *ira, IrInstGen *value, bool *out) { 15791 if (!value) { 15792 *out = false; 15793 return true; 15794 } 15795 return ir_resolve_bool(ira, value, out); 15796 } 15797 15798 static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstGen *value, AtomicOrder *out) { 15799 if (type_is_invalid(value->value->type)) 15800 return false; 15801 15802 ZigType *atomic_order_type = get_builtin_type(ira->codegen, "AtomicOrder"); 15803 15804 IrInstGen *casted_value = ir_implicit_cast(ira, value, atomic_order_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 = (AtomicOrder)bigint_as_u32(&const_val->data.x_enum_tag); 15813 return true; 15814 } 15815 15816 static bool ir_resolve_atomic_rmw_op(IrAnalyze *ira, IrInstGen *value, AtomicRmwOp *out) { 15817 if (type_is_invalid(value->value->type)) 15818 return false; 15819 15820 ZigType *atomic_rmw_op_type = get_builtin_type(ira->codegen, "AtomicRmwOp"); 15821 15822 IrInstGen *casted_value = ir_implicit_cast(ira, value, atomic_rmw_op_type); 15823 if (type_is_invalid(casted_value->value->type)) 15824 return false; 15825 15826 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15827 if (!const_val) 15828 return false; 15829 15830 *out = (AtomicRmwOp)bigint_as_u32(&const_val->data.x_enum_tag); 15831 return true; 15832 } 15833 15834 static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstGen *value, GlobalLinkageId *out) { 15835 if (type_is_invalid(value->value->type)) 15836 return false; 15837 15838 ZigType *global_linkage_type = get_builtin_type(ira->codegen, "GlobalLinkage"); 15839 15840 IrInstGen *casted_value = ir_implicit_cast(ira, value, global_linkage_type); 15841 if (type_is_invalid(casted_value->value->type)) 15842 return false; 15843 15844 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15845 if (!const_val) 15846 return false; 15847 15848 *out = (GlobalLinkageId)bigint_as_u32(&const_val->data.x_enum_tag); 15849 return true; 15850 } 15851 15852 static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstGen *value, FloatMode *out) { 15853 if (type_is_invalid(value->value->type)) 15854 return false; 15855 15856 ZigType *float_mode_type = get_builtin_type(ira->codegen, "FloatMode"); 15857 15858 IrInstGen *casted_value = ir_implicit_cast(ira, value, float_mode_type); 15859 if (type_is_invalid(casted_value->value->type)) 15860 return false; 15861 15862 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15863 if (!const_val) 15864 return false; 15865 15866 *out = (FloatMode)bigint_as_u32(&const_val->data.x_enum_tag); 15867 return true; 15868 } 15869 15870 static Buf *ir_resolve_str(IrAnalyze *ira, IrInstGen *value) { 15871 if (type_is_invalid(value->value->type)) 15872 return nullptr; 15873 15874 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 15875 true, false, PtrLenUnknown, 0, 0, 0, false); 15876 ZigType *str_type = get_slice_type(ira->codegen, ptr_type); 15877 IrInstGen *casted_value = ir_implicit_cast(ira, value, str_type); 15878 if (type_is_invalid(casted_value->value->type)) 15879 return nullptr; 15880 15881 ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 15882 if (!const_val) 15883 return nullptr; 15884 15885 ZigValue *ptr_field = const_val->data.x_struct.fields[slice_ptr_index]; 15886 ZigValue *len_field = const_val->data.x_struct.fields[slice_len_index]; 15887 15888 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); 15889 ZigValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; 15890 expand_undef_array(ira->codegen, array_val); 15891 size_t len = bigint_as_usize(&len_field->data.x_bigint); 15892 if (array_val->data.x_array.special == ConstArraySpecialBuf && len == buf_len(array_val->data.x_array.data.s_buf)) { 15893 return array_val->data.x_array.data.s_buf; 15894 } 15895 Buf *result = buf_alloc(); 15896 buf_resize(result, len); 15897 for (size_t i = 0; i < len; i += 1) { 15898 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; 15899 ZigValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index]; 15900 if (char_val->special == ConstValSpecialUndef) { 15901 ir_add_error(ira, &casted_value->base, buf_sprintf("use of undefined value")); 15902 return nullptr; 15903 } 15904 uint64_t big_c = bigint_as_u64(&char_val->data.x_bigint); 15905 assert(big_c <= UINT8_MAX); 15906 uint8_t c = (uint8_t)big_c; 15907 buf_ptr(result)[i] = c; 15908 } 15909 return result; 15910 } 15911 15912 static IrInstGen *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, 15913 IrInstSrcAddImplicitReturnType *instruction) 15914 { 15915 IrInstGen *value = instruction->value->child; 15916 if (type_is_invalid(value->value->type)) 15917 return ir_unreach_error(ira); 15918 15919 if (instruction->result_loc_ret == nullptr || !instruction->result_loc_ret->implicit_return_type_done) { 15920 ira->src_implicit_return_type_list.append(value); 15921 } 15922 15923 return ir_const_void(ira, &instruction->base.base); 15924 } 15925 15926 static IrInstGen *ir_analyze_instruction_return(IrAnalyze *ira, IrInstSrcReturn *instruction) { 15927 if (instruction->operand == nullptr) { 15928 // result location mechanism took care of it. 15929 IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, nullptr); 15930 return ir_finish_anal(ira, result); 15931 } 15932 15933 IrInstGen *operand = instruction->operand->child; 15934 if (type_is_invalid(operand->value->type)) 15935 return ir_unreach_error(ira); 15936 15937 IrInstGen *casted_operand = ir_implicit_cast(ira, operand, ira->explicit_return_type); 15938 if (type_is_invalid(casted_operand->value->type)) { 15939 AstNode *source_node = ira->explicit_return_type_source_node; 15940 if (source_node != nullptr) { 15941 ErrorMsg *msg = ira->codegen->errors.last(); 15942 add_error_note(ira->codegen, msg, source_node, 15943 buf_sprintf("return type declared here")); 15944 } 15945 return ir_unreach_error(ira); 15946 } 15947 15948 if (!instr_is_comptime(operand) && ira->explicit_return_type != nullptr && 15949 handle_is_ptr(ira->codegen, ira->explicit_return_type)) 15950 { 15951 // result location mechanism took care of it. 15952 IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, nullptr); 15953 return ir_finish_anal(ira, result); 15954 } 15955 15956 if (casted_operand->value->special == ConstValSpecialRuntime && 15957 casted_operand->value->type->id == ZigTypeIdPointer && 15958 casted_operand->value->data.rh_ptr == RuntimeHintPtrStack) 15959 { 15960 ir_add_error(ira, &instruction->operand->base, buf_sprintf("function returns address of local variable")); 15961 return ir_unreach_error(ira); 15962 } 15963 15964 IrInstGen *result = ir_build_return_gen(ira, &instruction->base.base, casted_operand); 15965 return ir_finish_anal(ira, result); 15966 } 15967 15968 static IrInstGen *ir_analyze_instruction_const(IrAnalyze *ira, IrInstSrcConst *instruction) { 15969 return ir_const_move(ira, &instruction->base.base, instruction->value); 15970 } 15971 15972 static IrInstGen *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { 15973 IrInstGen *op1 = bin_op_instruction->op1->child; 15974 if (type_is_invalid(op1->value->type)) 15975 return ira->codegen->invalid_inst_gen; 15976 15977 IrInstGen *op2 = bin_op_instruction->op2->child; 15978 if (type_is_invalid(op2->value->type)) 15979 return ira->codegen->invalid_inst_gen; 15980 15981 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 15982 15983 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, bool_type); 15984 if (type_is_invalid(casted_op1->value->type)) 15985 return ira->codegen->invalid_inst_gen; 15986 15987 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, bool_type); 15988 if (type_is_invalid(casted_op2->value->type)) 15989 return ira->codegen->invalid_inst_gen; 15990 15991 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 15992 ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 15993 if (op1_val == nullptr) 15994 return ira->codegen->invalid_inst_gen; 15995 15996 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 15997 if (op2_val == nullptr) 15998 return ira->codegen->invalid_inst_gen; 15999 16000 assert(casted_op1->value->type->id == ZigTypeIdBool); 16001 assert(casted_op2->value->type->id == ZigTypeIdBool); 16002 bool result_bool; 16003 if (bin_op_instruction->op_id == IrBinOpBoolOr) { 16004 result_bool = op1_val->data.x_bool || op2_val->data.x_bool; 16005 } else if (bin_op_instruction->op_id == IrBinOpBoolAnd) { 16006 result_bool = op1_val->data.x_bool && op2_val->data.x_bool; 16007 } else { 16008 zig_unreachable(); 16009 } 16010 return ir_const_bool(ira, &bin_op_instruction->base.base, result_bool); 16011 } 16012 16013 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, bool_type, 16014 bin_op_instruction->op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 16015 } 16016 16017 static bool resolve_cmp_op_id(IrBinOp op_id, Cmp cmp) { 16018 switch (op_id) { 16019 case IrBinOpCmpEq: 16020 return cmp == CmpEQ; 16021 case IrBinOpCmpNotEq: 16022 return cmp != CmpEQ; 16023 case IrBinOpCmpLessThan: 16024 return cmp == CmpLT; 16025 case IrBinOpCmpGreaterThan: 16026 return cmp == CmpGT; 16027 case IrBinOpCmpLessOrEq: 16028 return cmp != CmpGT; 16029 case IrBinOpCmpGreaterOrEq: 16030 return cmp != CmpLT; 16031 default: 16032 zig_unreachable(); 16033 } 16034 } 16035 16036 static void set_optional_value_to_null(ZigValue *val) { 16037 assert(val->special == ConstValSpecialStatic); 16038 if (val->type->id == ZigTypeIdNull) return; // nothing to do 16039 assert(val->type->id == ZigTypeIdOptional); 16040 if (get_src_ptr_type(val->type) != nullptr) { 16041 val->data.x_ptr.special = ConstPtrSpecialNull; 16042 } else if (is_opt_err_set(val->type)) { 16043 val->data.x_err_set = nullptr; 16044 } else { 16045 val->data.x_optional = nullptr; 16046 } 16047 } 16048 16049 static void set_optional_payload(ZigValue *opt_val, ZigValue *payload) { 16050 assert(opt_val->special == ConstValSpecialStatic); 16051 assert(opt_val->type->id == ZigTypeIdOptional); 16052 if (payload == nullptr) { 16053 set_optional_value_to_null(opt_val); 16054 } else if (is_opt_err_set(opt_val->type)) { 16055 assert(payload->type->id == ZigTypeIdErrorSet); 16056 opt_val->data.x_err_set = payload->data.x_err_set; 16057 } else { 16058 opt_val->data.x_optional = payload; 16059 } 16060 } 16061 16062 static IrInstGen *ir_evaluate_bin_op_cmp(IrAnalyze *ira, ZigType *resolved_type, 16063 ZigValue *op1_val, ZigValue *op2_val, IrInst *source_instr, IrBinOp op_id, 16064 bool one_possible_value) 16065 { 16066 if (op1_val->special == ConstValSpecialUndef || 16067 op2_val->special == ConstValSpecialUndef) 16068 return ir_const_undef(ira, source_instr, resolved_type); 16069 if (resolved_type->id == ZigTypeIdPointer && op_id != IrBinOpCmpEq && op_id != IrBinOpCmpNotEq) { 16070 if ((op1_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 16071 op1_val->data.x_ptr.special == ConstPtrSpecialNull) && 16072 (op2_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 16073 op2_val->data.x_ptr.special == ConstPtrSpecialNull)) 16074 { 16075 uint64_t op1_addr = op1_val->data.x_ptr.special == ConstPtrSpecialNull ? 16076 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr; 16077 uint64_t op2_addr = op2_val->data.x_ptr.special == ConstPtrSpecialNull ? 16078 0 : op2_val->data.x_ptr.data.hard_coded_addr.addr; 16079 Cmp cmp_result; 16080 if (op1_addr > op2_addr) { 16081 cmp_result = CmpGT; 16082 } else if (op1_addr < op2_addr) { 16083 cmp_result = CmpLT; 16084 } else { 16085 cmp_result = CmpEQ; 16086 } 16087 bool answer = resolve_cmp_op_id(op_id, cmp_result); 16088 return ir_const_bool(ira, source_instr, answer); 16089 } 16090 } else { 16091 bool are_equal = one_possible_value || const_values_equal(ira->codegen, op1_val, op2_val); 16092 bool answer; 16093 if (op_id == IrBinOpCmpEq) { 16094 answer = are_equal; 16095 } else if (op_id == IrBinOpCmpNotEq) { 16096 answer = !are_equal; 16097 } else { 16098 zig_unreachable(); 16099 } 16100 return ir_const_bool(ira, source_instr, answer); 16101 } 16102 zig_unreachable(); 16103 } 16104 16105 static IrInstGen *ir_try_evaluate_bin_op_cmp_const(IrAnalyze *ira, IrInst *source_instr, IrInstGen *op1, IrInstGen *op2, 16106 ZigType *resolved_type, IrBinOp op_id) 16107 { 16108 assert(op1->value->type == resolved_type && op2->value->type == resolved_type); 16109 bool one_possible_value; 16110 switch (type_has_one_possible_value(ira->codegen, resolved_type)) { 16111 case OnePossibleValueInvalid: 16112 return ira->codegen->invalid_inst_gen; 16113 case OnePossibleValueYes: 16114 one_possible_value = true; 16115 break; 16116 case OnePossibleValueNo: 16117 one_possible_value = false; 16118 break; 16119 } 16120 16121 if (one_possible_value || (instr_is_comptime(op1) && instr_is_comptime(op2))) { 16122 ZigValue *op1_val = one_possible_value ? op1->value : ir_resolve_const(ira, op1, UndefBad); 16123 if (op1_val == nullptr) 16124 return ira->codegen->invalid_inst_gen; 16125 ZigValue *op2_val = one_possible_value ? op2->value : ir_resolve_const(ira, op2, UndefBad); 16126 if (op2_val == nullptr) 16127 return ira->codegen->invalid_inst_gen; 16128 if (resolved_type->id != ZigTypeIdVector) 16129 return ir_evaluate_bin_op_cmp(ira, resolved_type, op1_val, op2_val, source_instr, op_id, one_possible_value); 16130 IrInstGen *result = ir_const(ira, source_instr, 16131 get_vector_type(ira->codegen, resolved_type->data.vector.len, ira->codegen->builtin_types.entry_bool)); 16132 result->value->data.x_array.data.s_none.elements = 16133 ira->codegen->pass1_arena->allocate<ZigValue>(resolved_type->data.vector.len); 16134 16135 expand_undef_array(ira->codegen, result->value); 16136 for (size_t i = 0;i < resolved_type->data.vector.len;i++) { 16137 IrInstGen *cur_res = ir_evaluate_bin_op_cmp(ira, resolved_type->data.vector.elem_type, 16138 &op1_val->data.x_array.data.s_none.elements[i], 16139 &op2_val->data.x_array.data.s_none.elements[i], 16140 source_instr, op_id, one_possible_value); 16141 copy_const_val(ira->codegen, &result->value->data.x_array.data.s_none.elements[i], cur_res->value); 16142 } 16143 return result; 16144 } else { 16145 return nullptr; 16146 } 16147 } 16148 16149 // Returns ErrorNotLazy when the value cannot be determined 16150 static Error lazy_cmp_zero(CodeGen *codegen, AstNode *source_node, ZigValue *val, Cmp *result) { 16151 Error err; 16152 16153 switch (type_has_one_possible_value(codegen, val->type)) { 16154 case OnePossibleValueInvalid: 16155 return ErrorSemanticAnalyzeFail; 16156 case OnePossibleValueNo: 16157 break; 16158 case OnePossibleValueYes: 16159 switch (val->type->id) { 16160 case ZigTypeIdInt: 16161 src_assert(val->type->data.integral.bit_count == 0, source_node); 16162 *result = CmpEQ; 16163 return ErrorNone; 16164 case ZigTypeIdUndefined: 16165 return ErrorNotLazy; 16166 default: 16167 zig_unreachable(); 16168 } 16169 } 16170 16171 switch (val->special) { 16172 case ConstValSpecialRuntime: 16173 case ConstValSpecialUndef: 16174 return ErrorNotLazy; 16175 case ConstValSpecialStatic: 16176 switch (val->type->id) { 16177 case ZigTypeIdComptimeInt: 16178 case ZigTypeIdInt: 16179 *result = bigint_cmp_zero(&val->data.x_bigint); 16180 return ErrorNone; 16181 case ZigTypeIdComptimeFloat: 16182 case ZigTypeIdFloat: 16183 if (float_is_nan(val)) 16184 return ErrorNotLazy; 16185 *result = float_cmp_zero(val); 16186 return ErrorNone; 16187 default: 16188 return ErrorNotLazy; 16189 } 16190 case ConstValSpecialLazy: 16191 switch (val->data.x_lazy->id) { 16192 case LazyValueIdInvalid: 16193 zig_unreachable(); 16194 case LazyValueIdAlignOf: { 16195 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy); 16196 IrAnalyze *ira = lazy_align_of->ira; 16197 16198 bool is_zero_bits; 16199 if ((err = type_val_resolve_zero_bits(ira->codegen, lazy_align_of->target_type->value, 16200 nullptr, nullptr, &is_zero_bits))) 16201 { 16202 return err; 16203 } 16204 16205 *result = is_zero_bits ? CmpEQ : CmpGT; 16206 return ErrorNone; 16207 } 16208 case LazyValueIdSizeOf: { 16209 LazyValueSizeOf *lazy_size_of = reinterpret_cast<LazyValueSizeOf *>(val->data.x_lazy); 16210 IrAnalyze *ira = lazy_size_of->ira; 16211 bool is_zero_bits; 16212 if ((err = type_val_resolve_zero_bits(ira->codegen, lazy_size_of->target_type->value, 16213 nullptr, nullptr, &is_zero_bits))) 16214 { 16215 return err; 16216 } 16217 *result = is_zero_bits ? CmpEQ : CmpGT; 16218 return ErrorNone; 16219 } 16220 default: 16221 return ErrorNotLazy; 16222 } 16223 } 16224 zig_unreachable(); 16225 } 16226 16227 static ErrorMsg *ir_eval_bin_op_cmp_scalar(IrAnalyze *ira, IrInst* source_instr, 16228 ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val, ZigValue *out_val) 16229 { 16230 Error err; 16231 { 16232 // Before resolving the values, we special case comparisons against zero. These can often 16233 // be done without resolving lazy values, preventing potential dependency loops. 16234 Cmp op1_cmp_zero; 16235 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op1_val, &op1_cmp_zero))) { 16236 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally; 16237 return ira->codegen->trace_err; 16238 } 16239 Cmp op2_cmp_zero; 16240 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op2_val, &op2_cmp_zero))) { 16241 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally; 16242 return ira->codegen->trace_err; 16243 } 16244 bool can_cmp_zero = false; 16245 Cmp cmp_result; 16246 if (op1_cmp_zero == CmpEQ && op2_cmp_zero == CmpEQ) { 16247 can_cmp_zero = true; 16248 cmp_result = CmpEQ; 16249 } else if (op1_cmp_zero == CmpGT && op2_cmp_zero == CmpEQ) { 16250 can_cmp_zero = true; 16251 cmp_result = CmpGT; 16252 } else if (op1_cmp_zero == CmpEQ && op2_cmp_zero == CmpGT) { 16253 can_cmp_zero = true; 16254 cmp_result = CmpLT; 16255 } else if (op1_cmp_zero == CmpLT && op2_cmp_zero == CmpEQ) { 16256 can_cmp_zero = true; 16257 cmp_result = CmpLT; 16258 } else if (op1_cmp_zero == CmpEQ && op2_cmp_zero == CmpLT) { 16259 can_cmp_zero = true; 16260 cmp_result = CmpGT; 16261 } else if (op1_cmp_zero == CmpLT && op2_cmp_zero == CmpGT) { 16262 can_cmp_zero = true; 16263 cmp_result = CmpLT; 16264 } else if (op1_cmp_zero == CmpGT && op2_cmp_zero == CmpLT) { 16265 can_cmp_zero = true; 16266 cmp_result = CmpGT; 16267 } 16268 if (can_cmp_zero) { 16269 bool answer = resolve_cmp_op_id(op_id, cmp_result); 16270 out_val->special = ConstValSpecialStatic; 16271 out_val->data.x_bool = answer; 16272 return nullptr; 16273 } 16274 } 16275 never_mind_just_calculate_it_normally: 16276 16277 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_instr->source_node, 16278 op1_val, UndefOk))) 16279 { 16280 return ira->codegen->trace_err; 16281 } 16282 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_instr->source_node, 16283 op2_val, UndefOk))) 16284 { 16285 return ira->codegen->trace_err; 16286 } 16287 16288 16289 if (op1_val->special == ConstValSpecialUndef || op2_val->special == ConstValSpecialUndef || 16290 op1_val->type->id == ZigTypeIdUndefined || op2_val->type->id == ZigTypeIdUndefined) 16291 { 16292 out_val->special = ConstValSpecialUndef; 16293 return nullptr; 16294 } 16295 16296 bool op1_is_float = op1_val->type->id == ZigTypeIdFloat || op1_val->type->id == ZigTypeIdComptimeFloat; 16297 bool op2_is_float = op2_val->type->id == ZigTypeIdFloat || op2_val->type->id == ZigTypeIdComptimeFloat; 16298 if (op1_is_float && op2_is_float) { 16299 if (float_is_nan(op1_val) || float_is_nan(op2_val)) { 16300 out_val->special = ConstValSpecialStatic; 16301 out_val->data.x_bool = op_id == IrBinOpCmpNotEq; 16302 return nullptr; 16303 } 16304 if (op1_val->type->id == ZigTypeIdComptimeFloat) { 16305 IrInstGen *tmp = ir_const_noval(ira, source_instr); 16306 tmp->value = op1_val; 16307 IrInstGen *casted = ir_implicit_cast(ira, tmp, op2_val->type); 16308 op1_val = casted->value; 16309 } else if (op2_val->type->id == ZigTypeIdComptimeFloat) { 16310 IrInstGen *tmp = ir_const_noval(ira, source_instr); 16311 tmp->value = op2_val; 16312 IrInstGen *casted = ir_implicit_cast(ira, tmp, op1_val->type); 16313 op2_val = casted->value; 16314 } 16315 Cmp cmp_result = float_cmp(op1_val, op2_val); 16316 out_val->special = ConstValSpecialStatic; 16317 out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result); 16318 return nullptr; 16319 } 16320 16321 bool op1_is_int = op1_val->type->id == ZigTypeIdInt || op1_val->type->id == ZigTypeIdComptimeInt; 16322 bool op2_is_int = op2_val->type->id == ZigTypeIdInt || op2_val->type->id == ZigTypeIdComptimeInt; 16323 16324 if (op1_is_int && op2_is_int) { 16325 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); 16326 out_val->special = ConstValSpecialStatic; 16327 out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result); 16328 16329 return nullptr; 16330 } 16331 16332 // Handle the case where one of the two operands is a fp value and the other 16333 // is an integer value 16334 ZigValue *float_val; 16335 if (op1_is_int && op2_is_float) { 16336 float_val = op2_val; 16337 } else if (op1_is_float && op2_is_int) { 16338 float_val = op1_val; 16339 } else { 16340 zig_unreachable(); 16341 } 16342 16343 // They can never be equal if the fp value has a non-zero decimal part 16344 if (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq) { 16345 if (float_has_fraction(float_val)) { 16346 out_val->special = ConstValSpecialStatic; 16347 out_val->data.x_bool = op_id == IrBinOpCmpNotEq; 16348 return nullptr; 16349 } 16350 } 16351 16352 // Cast the integer operand into a fp value to perform the comparison 16353 BigFloat op1_bigfloat; 16354 BigFloat op2_bigfloat; 16355 value_to_bigfloat(&op1_bigfloat, op1_val); 16356 value_to_bigfloat(&op2_bigfloat, op2_val); 16357 16358 Cmp cmp_result = bigfloat_cmp(&op1_bigfloat, &op2_bigfloat); 16359 out_val->special = ConstValSpecialStatic; 16360 out_val->data.x_bool = resolve_cmp_op_id(op_id, cmp_result); 16361 16362 return nullptr; 16363 } 16364 16365 static IrInstGen *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInst *source_instr, 16366 IrInstGen *op1, IrInstGen *op2, IrBinOp op_id) 16367 { 16368 Error err; 16369 16370 ZigType *scalar_result_type = ira->codegen->builtin_types.entry_bool; 16371 ZigType *result_type = scalar_result_type; 16372 ZigType *op1_scalar_type = op1->value->type; 16373 ZigType *op2_scalar_type = op2->value->type; 16374 if (op1->value->type->id == ZigTypeIdVector && op2->value->type->id == ZigTypeIdVector) { 16375 if (op1->value->type->data.vector.len != op2->value->type->data.vector.len) { 16376 ir_add_error(ira, source_instr, 16377 buf_sprintf("vector length mismatch: %" PRIu64 " and %" PRIu64, 16378 op1->value->type->data.vector.len, op2->value->type->data.vector.len)); 16379 return ira->codegen->invalid_inst_gen; 16380 } 16381 result_type = get_vector_type(ira->codegen, op1->value->type->data.vector.len, scalar_result_type); 16382 op1_scalar_type = op1->value->type->data.vector.elem_type; 16383 op2_scalar_type = op2->value->type->data.vector.elem_type; 16384 } else if (op1->value->type->id == ZigTypeIdVector || op2->value->type->id == ZigTypeIdVector) { 16385 ir_add_error(ira, source_instr, 16386 buf_sprintf("mixed scalar and vector operands to comparison operator: '%s' and '%s'", 16387 buf_ptr(&op1->value->type->name), buf_ptr(&op2->value->type->name))); 16388 return ira->codegen->invalid_inst_gen; 16389 } 16390 16391 bool opv_op1; 16392 switch (type_has_one_possible_value(ira->codegen, op1->value->type)) { 16393 case OnePossibleValueInvalid: 16394 return ira->codegen->invalid_inst_gen; 16395 case OnePossibleValueYes: 16396 opv_op1 = true; 16397 break; 16398 case OnePossibleValueNo: 16399 opv_op1 = false; 16400 break; 16401 } 16402 bool opv_op2; 16403 switch (type_has_one_possible_value(ira->codegen, op2->value->type)) { 16404 case OnePossibleValueInvalid: 16405 return ira->codegen->invalid_inst_gen; 16406 case OnePossibleValueYes: 16407 opv_op2 = true; 16408 break; 16409 case OnePossibleValueNo: 16410 opv_op2 = false; 16411 break; 16412 } 16413 Cmp op1_cmp_zero; 16414 bool have_op1_cmp_zero = false; 16415 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op1->value, &op1_cmp_zero))) { 16416 if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen; 16417 } else { 16418 have_op1_cmp_zero = true; 16419 } 16420 Cmp op2_cmp_zero; 16421 bool have_op2_cmp_zero = false; 16422 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op2->value, &op2_cmp_zero))) { 16423 if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen; 16424 } else { 16425 have_op2_cmp_zero = true; 16426 } 16427 if (((opv_op1 || instr_is_comptime(op1)) && (opv_op2 || instr_is_comptime(op2))) || 16428 (have_op1_cmp_zero && have_op2_cmp_zero)) 16429 { 16430 IrInstGen *result_instruction = ir_const(ira, source_instr, result_type); 16431 ZigValue *out_val = result_instruction->value; 16432 if (result_type->id == ZigTypeIdVector) { 16433 size_t len = result_type->data.vector.len; 16434 expand_undef_array(ira->codegen, op1->value); 16435 expand_undef_array(ira->codegen, op2->value); 16436 out_val->special = ConstValSpecialUndef; 16437 expand_undef_array(ira->codegen, out_val); 16438 for (size_t i = 0; i < len; i += 1) { 16439 ZigValue *scalar_op1_val = &op1->value->data.x_array.data.s_none.elements[i]; 16440 ZigValue *scalar_op2_val = &op2->value->data.x_array.data.s_none.elements[i]; 16441 ZigValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 16442 assert(scalar_out_val->type == scalar_result_type); 16443 ErrorMsg *msg = ir_eval_bin_op_cmp_scalar(ira, source_instr, 16444 scalar_op1_val, op_id, scalar_op2_val, scalar_out_val); 16445 if (msg != nullptr) { 16446 add_error_note(ira->codegen, msg, source_instr->source_node, 16447 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 16448 return ira->codegen->invalid_inst_gen; 16449 } 16450 } 16451 out_val->type = result_type; 16452 out_val->special = ConstValSpecialStatic; 16453 } else { 16454 if (ir_eval_bin_op_cmp_scalar(ira, source_instr, op1->value, op_id, 16455 op2->value, out_val) != nullptr) 16456 { 16457 return ira->codegen->invalid_inst_gen; 16458 } 16459 } 16460 return result_instruction; 16461 } 16462 16463 // If one operand has a comptime-known comparison with 0, and the other operand is unsigned, we might 16464 // know the answer, depending on the operator. 16465 // TODO make this work with vectors 16466 if (have_op1_cmp_zero && op2_scalar_type->id == ZigTypeIdInt && !op2_scalar_type->data.integral.is_signed) { 16467 if (op1_cmp_zero == CmpEQ) { 16468 // 0 <= unsigned_x // true 16469 // 0 > unsigned_x // false 16470 switch (op_id) { 16471 case IrBinOpCmpLessOrEq: 16472 return ir_const_bool(ira, source_instr, true); 16473 case IrBinOpCmpGreaterThan: 16474 return ir_const_bool(ira, source_instr, false); 16475 default: 16476 break; 16477 } 16478 } else if (op1_cmp_zero == CmpLT) { 16479 // -1 != unsigned_x // true 16480 // -1 <= unsigned_x // true 16481 // -1 < unsigned_x // true 16482 // -1 == unsigned_x // false 16483 // -1 >= unsigned_x // false 16484 // -1 > unsigned_x // false 16485 switch (op_id) { 16486 case IrBinOpCmpNotEq: 16487 case IrBinOpCmpLessOrEq: 16488 case IrBinOpCmpLessThan: 16489 return ir_const_bool(ira, source_instr, true); 16490 case IrBinOpCmpEq: 16491 case IrBinOpCmpGreaterOrEq: 16492 case IrBinOpCmpGreaterThan: 16493 return ir_const_bool(ira, source_instr, false); 16494 default: 16495 break; 16496 } 16497 } 16498 } 16499 if (have_op2_cmp_zero && op1_scalar_type->id == ZigTypeIdInt && !op1_scalar_type->data.integral.is_signed) { 16500 if (op2_cmp_zero == CmpEQ) { 16501 // unsigned_x < 0 // false 16502 // unsigned_x >= 0 // true 16503 switch (op_id) { 16504 case IrBinOpCmpLessThan: 16505 return ir_const_bool(ira, source_instr, false); 16506 case IrBinOpCmpGreaterOrEq: 16507 return ir_const_bool(ira, source_instr, true); 16508 default: 16509 break; 16510 } 16511 } else if (op2_cmp_zero == CmpLT) { 16512 // unsigned_x != -1 // true 16513 // unsigned_x >= -1 // true 16514 // unsigned_x > -1 // true 16515 // unsigned_x == -1 // false 16516 // unsigned_x < -1 // false 16517 // unsigned_x <= -1 // false 16518 switch (op_id) { 16519 case IrBinOpCmpNotEq: 16520 case IrBinOpCmpGreaterOrEq: 16521 case IrBinOpCmpGreaterThan: 16522 return ir_const_bool(ira, source_instr, true); 16523 case IrBinOpCmpEq: 16524 case IrBinOpCmpLessThan: 16525 case IrBinOpCmpLessOrEq: 16526 return ir_const_bool(ira, source_instr, false); 16527 default: 16528 break; 16529 } 16530 } 16531 } 16532 16533 // It must be a runtime comparison. 16534 // For floats, emit a float comparison instruction. 16535 bool op1_is_float = op1_scalar_type->id == ZigTypeIdFloat || op1_scalar_type->id == ZigTypeIdComptimeFloat; 16536 bool op2_is_float = op2_scalar_type->id == ZigTypeIdFloat || op2_scalar_type->id == ZigTypeIdComptimeFloat; 16537 if (op1_is_float && op2_is_float) { 16538 // Implicit cast the smaller one to the larger one. 16539 ZigType *dest_scalar_type; 16540 if (op1_scalar_type->id == ZigTypeIdComptimeFloat) { 16541 dest_scalar_type = op2_scalar_type; 16542 } else if (op2_scalar_type->id == ZigTypeIdComptimeFloat) { 16543 dest_scalar_type = op1_scalar_type; 16544 } else if (op1_scalar_type->data.floating.bit_count >= op2_scalar_type->data.floating.bit_count) { 16545 dest_scalar_type = op1_scalar_type; 16546 } else { 16547 dest_scalar_type = op2_scalar_type; 16548 } 16549 ZigType *dest_type = (result_type->id == ZigTypeIdVector) ? 16550 get_vector_type(ira->codegen, result_type->data.vector.len, dest_scalar_type) : dest_scalar_type; 16551 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 16552 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, dest_type); 16553 if (type_is_invalid(casted_op1->value->type) || type_is_invalid(casted_op2->value->type)) 16554 return ira->codegen->invalid_inst_gen; 16555 return ir_build_bin_op_gen(ira, source_instr, result_type, op_id, casted_op1, casted_op2, true); 16556 } 16557 16558 // For mixed unsigned integer sizes, implicit cast both operands to the larger integer. 16559 // For mixed signed and unsigned integers, implicit cast both operands to a signed 16560 // integer with + 1 bit. 16561 // For mixed floats and integers, extract the integer part from the float, cast that to 16562 // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float, 16563 // add/subtract 1. 16564 bool dest_int_is_signed = false; 16565 if (have_op1_cmp_zero) { 16566 if (op1_cmp_zero == CmpLT) dest_int_is_signed = true; 16567 } else if (op1_is_float) { 16568 dest_int_is_signed = true; 16569 } else if (op1_scalar_type->id == ZigTypeIdInt && op1_scalar_type->data.integral.is_signed) { 16570 dest_int_is_signed = true; 16571 } 16572 if (have_op2_cmp_zero) { 16573 if (op2_cmp_zero == CmpLT) dest_int_is_signed = true; 16574 } else if (op2_is_float) { 16575 dest_int_is_signed = true; 16576 } else if (op2->value->type->id == ZigTypeIdInt && op2->value->type->data.integral.is_signed) { 16577 dest_int_is_signed = true; 16578 } 16579 ZigType *dest_float_type = nullptr; 16580 uint32_t op1_bits; 16581 if (instr_is_comptime(op1)) { 16582 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefOk); 16583 if (op1_val == nullptr) 16584 return ira->codegen->invalid_inst_gen; 16585 if (op1_val->special == ConstValSpecialUndef) 16586 return ir_const_undef(ira, source_instr, ira->codegen->builtin_types.entry_bool); 16587 if (result_type->id == ZigTypeIdVector) { 16588 ir_add_error(ira, &op1->base, buf_sprintf("compiler bug: TODO: support comptime vector here")); 16589 return ira->codegen->invalid_inst_gen; 16590 } 16591 bool is_unsigned; 16592 if (op1_is_float) { 16593 BigInt bigint = {}; 16594 float_init_bigint(&bigint, op1_val); 16595 Cmp zcmp = float_cmp_zero(op1_val); 16596 if (float_has_fraction(op1_val)) { 16597 if (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq) { 16598 return ir_const_bool(ira, source_instr, op_id == IrBinOpCmpNotEq); 16599 } 16600 if (zcmp == CmpLT) { 16601 bigint_decr(&bigint); 16602 } else { 16603 bigint_incr(&bigint); 16604 } 16605 } 16606 op1_bits = bigint_bits_needed(&bigint); 16607 is_unsigned = zcmp != CmpLT; 16608 } else { 16609 op1_bits = bigint_bits_needed(&op1_val->data.x_bigint); 16610 is_unsigned = bigint_cmp_zero(&op1_val->data.x_bigint) != CmpLT; 16611 } 16612 if (is_unsigned && dest_int_is_signed) { 16613 op1_bits += 1; 16614 } 16615 } else if (op1_is_float) { 16616 dest_float_type = op1_scalar_type; 16617 } else { 16618 ir_assert(op1_scalar_type->id == ZigTypeIdInt, source_instr); 16619 op1_bits = op1_scalar_type->data.integral.bit_count; 16620 if (!op1_scalar_type->data.integral.is_signed && dest_int_is_signed) { 16621 op1_bits += 1; 16622 } 16623 } 16624 uint32_t op2_bits; 16625 if (instr_is_comptime(op2)) { 16626 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefOk); 16627 if (op2_val == nullptr) 16628 return ira->codegen->invalid_inst_gen; 16629 if (op2_val->special == ConstValSpecialUndef) 16630 return ir_const_undef(ira, source_instr, ira->codegen->builtin_types.entry_bool); 16631 if (result_type->id == ZigTypeIdVector) { 16632 ir_add_error(ira, &op2->base, buf_sprintf("compiler bug: TODO: support comptime vector here")); 16633 return ira->codegen->invalid_inst_gen; 16634 } 16635 bool is_unsigned; 16636 if (op2_is_float) { 16637 BigInt bigint = {}; 16638 float_init_bigint(&bigint, op2_val); 16639 Cmp zcmp = float_cmp_zero(op2_val); 16640 if (float_has_fraction(op2_val)) { 16641 if (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq) { 16642 return ir_const_bool(ira, source_instr, op_id == IrBinOpCmpNotEq); 16643 } 16644 if (zcmp == CmpLT) { 16645 bigint_decr(&bigint); 16646 } else { 16647 bigint_incr(&bigint); 16648 } 16649 } 16650 op2_bits = bigint_bits_needed(&bigint); 16651 is_unsigned = zcmp != CmpLT; 16652 } else { 16653 op2_bits = bigint_bits_needed(&op2_val->data.x_bigint); 16654 is_unsigned = bigint_cmp_zero(&op2_val->data.x_bigint) != CmpLT; 16655 } 16656 if (is_unsigned && dest_int_is_signed) { 16657 op2_bits += 1; 16658 } 16659 } else if (op2_is_float) { 16660 dest_float_type = op2_scalar_type; 16661 } else { 16662 ir_assert(op2_scalar_type->id == ZigTypeIdInt, source_instr); 16663 op2_bits = op2_scalar_type->data.integral.bit_count; 16664 if (!op2_scalar_type->data.integral.is_signed && dest_int_is_signed) { 16665 op2_bits += 1; 16666 } 16667 } 16668 ZigType *dest_scalar_type = (dest_float_type == nullptr) ? 16669 get_int_type(ira->codegen, dest_int_is_signed, (op1_bits > op2_bits) ? op1_bits : op2_bits) : 16670 dest_float_type; 16671 ZigType *dest_type = (result_type->id == ZigTypeIdVector) ? 16672 get_vector_type(ira->codegen, result_type->data.vector.len, dest_scalar_type) : dest_scalar_type; 16673 16674 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 16675 if (type_is_invalid(casted_op1->value->type)) 16676 return ira->codegen->invalid_inst_gen; 16677 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, dest_type); 16678 if (type_is_invalid(casted_op2->value->type)) 16679 return ira->codegen->invalid_inst_gen; 16680 return ir_build_bin_op_gen(ira, source_instr, result_type, op_id, casted_op1, casted_op2, true); 16681 } 16682 16683 static bool type_is_self_comparable(ZigType *ty, bool is_equality_cmp) { 16684 if (type_is_numeric(ty)) { 16685 return true; 16686 } 16687 switch (ty->id) { 16688 case ZigTypeIdInvalid: 16689 zig_unreachable(); 16690 16691 case ZigTypeIdComptimeFloat: 16692 case ZigTypeIdComptimeInt: 16693 case ZigTypeIdInt: 16694 case ZigTypeIdFloat: 16695 zig_unreachable(); // handled with the type_is_numeric check above 16696 16697 case ZigTypeIdVector: 16698 // Not every case is handled by the type_is_numeric check above, 16699 // vectors of bool trigger this code path 16700 case ZigTypeIdBool: 16701 case ZigTypeIdMetaType: 16702 case ZigTypeIdVoid: 16703 case ZigTypeIdErrorSet: 16704 case ZigTypeIdFn: 16705 case ZigTypeIdOpaque: 16706 case ZigTypeIdBoundFn: 16707 case ZigTypeIdEnum: 16708 case ZigTypeIdEnumLiteral: 16709 case ZigTypeIdAnyFrame: 16710 return is_equality_cmp; 16711 16712 case ZigTypeIdPointer: 16713 return is_equality_cmp || (ty->data.pointer.ptr_len == PtrLenC); 16714 16715 case ZigTypeIdUnreachable: 16716 case ZigTypeIdArray: 16717 case ZigTypeIdStruct: 16718 case ZigTypeIdUndefined: 16719 case ZigTypeIdNull: 16720 case ZigTypeIdErrorUnion: 16721 case ZigTypeIdUnion: 16722 case ZigTypeIdFnFrame: 16723 return false; 16724 16725 case ZigTypeIdOptional: 16726 return is_equality_cmp && get_src_ptr_type(ty) != nullptr; 16727 } 16728 zig_unreachable(); 16729 } 16730 16731 static IrInstGen *ir_try_evaluate_cmp_optional_non_optional_const(IrAnalyze *ira, IrInst *source_instr, ZigType *child_type, 16732 IrInstGen *optional, IrInstGen *non_optional, IrBinOp op_id) 16733 { 16734 assert(optional->value->type->id == ZigTypeIdOptional); 16735 assert(optional->value->type->data.maybe.child_type == non_optional->value->type); 16736 assert(non_optional->value->type == child_type); 16737 assert(op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 16738 16739 if (instr_is_comptime(optional) && instr_is_comptime(non_optional)) { 16740 ZigValue *optional_val = ir_resolve_const(ira, optional, UndefBad); 16741 if (!optional_val) { 16742 return ira->codegen->invalid_inst_gen; 16743 } 16744 16745 ZigValue *non_optional_val = ir_resolve_const(ira, non_optional, UndefBad); 16746 if (!non_optional_val) { 16747 return ira->codegen->invalid_inst_gen; 16748 } 16749 16750 if (!optional_value_is_null(optional_val)) { 16751 IrInstGen *optional_unwrapped = ir_analyze_optional_value_payload_value(ira, source_instr, optional, false); 16752 if (type_is_invalid(optional_unwrapped->value->type)) { 16753 return ira->codegen->invalid_inst_gen; 16754 } 16755 16756 IrInstGen *ret = ir_try_evaluate_bin_op_cmp_const(ira, source_instr, optional_unwrapped, non_optional, child_type, op_id); 16757 assert(ret != nullptr); 16758 return ret; 16759 } 16760 return ir_const_bool(ira, source_instr, (op_id != IrBinOpCmpEq)); 16761 } else { 16762 return nullptr; 16763 } 16764 } 16765 16766 static IrInstGen *ir_evaluate_cmp_optional_non_optional(IrAnalyze *ira, IrInst *source_instr, ZigType *child_type, 16767 IrInstGen *optional, IrInstGen *non_optional, IrBinOp op_id) 16768 { 16769 assert(optional->value->type->id == ZigTypeIdOptional); 16770 assert(optional->value->type->data.maybe.child_type == non_optional->value->type); 16771 assert(non_optional->value->type == child_type); 16772 assert(op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 16773 16774 ZigType *result_type = ira->codegen->builtin_types.entry_bool; 16775 ir_append_basic_block_gen(&ira->new_irb, ira->new_irb.current_basic_block); 16776 16777 IrBasicBlockGen *null_block = ir_create_basic_block_gen(ira, source_instr->scope, "CmpOptionalNonOptionalOptionalNull"); 16778 IrBasicBlockGen *non_null_block = ir_create_basic_block_gen(ira, source_instr->scope, "CmpOptionalNonOptionalOptionalNotNull"); 16779 IrBasicBlockGen *end_block = ir_create_basic_block_gen(ira, source_instr->scope, "CmpOptionalNonOptionalEnd"); 16780 16781 IrInstGen *is_non_null = ir_build_test_non_null_gen(ira, source_instr, optional); 16782 ir_build_cond_br_gen(ira, source_instr, is_non_null, non_null_block, null_block); 16783 16784 ir_set_cursor_at_end_and_append_block_gen(&ira->new_irb, non_null_block); 16785 IrInstGen *optional_unwrapped = ir_analyze_optional_value_payload_value(ira, source_instr, optional, false); 16786 if (type_is_invalid(optional_unwrapped->value->type)) { 16787 return ira->codegen->invalid_inst_gen; 16788 } 16789 IrInstGen *non_null_cmp_result = ir_build_bin_op_gen(ira, source_instr, result_type, op_id, 16790 optional_unwrapped, non_optional, false); // safety check unnecessary for comparison operators 16791 ir_build_br_gen(ira, source_instr, end_block); 16792 16793 16794 ir_set_cursor_at_end_and_append_block_gen(&ira->new_irb, null_block); 16795 IrInstGen *null_result = ir_const_bool(ira, source_instr, (op_id != IrBinOpCmpEq)); 16796 ir_build_br_gen(ira, source_instr, end_block); 16797 16798 ir_set_cursor_at_end_gen(&ira->new_irb, end_block); 16799 int incoming_count = 2; 16800 IrBasicBlockGen **incoming_blocks = heap::c_allocator.allocate_nonzero<IrBasicBlockGen *>(incoming_count); 16801 incoming_blocks[0] = null_block; 16802 incoming_blocks[1] = non_null_block; 16803 IrInstGen **incoming_values = heap::c_allocator.allocate_nonzero<IrInstGen *>(incoming_count); 16804 incoming_values[0] = null_result; 16805 incoming_values[1] = non_null_cmp_result; 16806 16807 return ir_build_phi_gen(ira, source_instr, incoming_count, incoming_blocks, incoming_values, result_type); 16808 } 16809 16810 static IrInstGen *ir_analyze_cmp_optional_non_optional(IrAnalyze *ira, IrInst *source_instr, 16811 IrInstGen *op1, IrInstGen *op2, IrInstGen *optional, IrBinOp op_id) 16812 { 16813 assert(op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 16814 assert(optional->value->type->id == ZigTypeIdOptional); 16815 assert(get_src_ptr_type(optional->value->type) == nullptr); 16816 16817 IrInstGen *non_optional; 16818 if (op1 == optional) { 16819 non_optional = op2; 16820 } else if (op2 == optional) { 16821 non_optional = op1; 16822 } else { 16823 zig_unreachable(); 16824 } 16825 16826 ZigType *child_type = optional->value->type->data.maybe.child_type; 16827 bool child_type_matches = (child_type == non_optional->value->type); 16828 if (!child_type_matches || !type_is_self_comparable(child_type, true)) { 16829 ErrorMsg *msg = ir_add_error_node(ira, source_instr->source_node, buf_sprintf("cannot compare types '%s' and '%s'", 16830 buf_ptr(&op1->value->type->name), 16831 buf_ptr(&op2->value->type->name))); 16832 16833 if (!child_type_matches) { 16834 if (non_optional->value->type->id == ZigTypeIdOptional) { 16835 add_error_note(ira->codegen, msg, source_instr->source_node, buf_sprintf( 16836 "optional to optional comparison is only supported for optional pointer types")); 16837 } else { 16838 add_error_note(ira->codegen, msg, source_instr->source_node, 16839 buf_sprintf("optional child type '%s' must be the same as non-optional type '%s'", 16840 buf_ptr(&child_type->name), 16841 buf_ptr(&non_optional->value->type->name))); 16842 } 16843 } else { 16844 add_error_note(ira->codegen, msg, source_instr->source_node, 16845 buf_sprintf("operator not supported for type '%s'", 16846 buf_ptr(&child_type->name))); 16847 } 16848 return ira->codegen->invalid_inst_gen; 16849 } 16850 16851 if (child_type->id == ZigTypeIdVector) { 16852 ir_add_error_node(ira, source_instr->source_node, buf_sprintf("TODO add comparison of optional vector")); 16853 return ira->codegen->invalid_inst_gen; 16854 } 16855 16856 if (IrInstGen *const_result = ir_try_evaluate_cmp_optional_non_optional_const(ira, source_instr, child_type, 16857 optional, non_optional, op_id)) 16858 { 16859 return const_result; 16860 } 16861 16862 return ir_evaluate_cmp_optional_non_optional(ira, source_instr, child_type, optional, non_optional, op_id); 16863 } 16864 16865 static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { 16866 IrInstGen *op1 = bin_op_instruction->op1->child; 16867 if (type_is_invalid(op1->value->type)) 16868 return ira->codegen->invalid_inst_gen; 16869 16870 IrInstGen *op2 = bin_op_instruction->op2->child; 16871 if (type_is_invalid(op2->value->type)) 16872 return ira->codegen->invalid_inst_gen; 16873 16874 AstNode *source_node = bin_op_instruction->base.base.source_node; 16875 16876 IrBinOp op_id = bin_op_instruction->op_id; 16877 bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 16878 if (is_equality_cmp && op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdNull) { 16879 return ir_const_bool(ira, &bin_op_instruction->base.base, (op_id == IrBinOpCmpEq)); 16880 } else if (is_equality_cmp && 16881 ((op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdOptional) || 16882 (op2->value->type->id == ZigTypeIdNull && op1->value->type->id == ZigTypeIdOptional))) 16883 { 16884 IrInstGen *maybe_op; 16885 if (op1->value->type->id == ZigTypeIdNull) { 16886 maybe_op = op2; 16887 } else if (op2->value->type->id == ZigTypeIdNull) { 16888 maybe_op = op1; 16889 } else { 16890 zig_unreachable(); 16891 } 16892 if (instr_is_comptime(maybe_op)) { 16893 ZigValue *maybe_val = ir_resolve_const(ira, maybe_op, UndefBad); 16894 if (!maybe_val) 16895 return ira->codegen->invalid_inst_gen; 16896 bool is_null = optional_value_is_null(maybe_val); 16897 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 16898 return ir_const_bool(ira, &bin_op_instruction->base.base, bool_result); 16899 } 16900 16901 IrInstGen *is_non_null = ir_build_test_non_null_gen(ira, &bin_op_instruction->base.base, maybe_op); 16902 16903 if (op_id == IrBinOpCmpEq) { 16904 return ir_build_bool_not_gen(ira, &bin_op_instruction->base.base, is_non_null); 16905 } else { 16906 return is_non_null; 16907 } 16908 } else if (is_equality_cmp && 16909 ((op1->value->type->id == ZigTypeIdNull && op2->value->type->id == ZigTypeIdPointer && 16910 op2->value->type->data.pointer.ptr_len == PtrLenC) || 16911 (op2->value->type->id == ZigTypeIdNull && op1->value->type->id == ZigTypeIdPointer && 16912 op1->value->type->data.pointer.ptr_len == PtrLenC))) 16913 { 16914 IrInstGen *c_ptr_op; 16915 if (op1->value->type->id == ZigTypeIdNull) { 16916 c_ptr_op = op2; 16917 } else if (op2->value->type->id == ZigTypeIdNull) { 16918 c_ptr_op = op1; 16919 } else { 16920 zig_unreachable(); 16921 } 16922 if (instr_is_comptime(c_ptr_op)) { 16923 ZigValue *c_ptr_val = ir_resolve_const(ira, c_ptr_op, UndefOk); 16924 if (!c_ptr_val) 16925 return ira->codegen->invalid_inst_gen; 16926 if (c_ptr_val->special == ConstValSpecialUndef) 16927 return ir_const_undef(ira, &bin_op_instruction->base.base, ira->codegen->builtin_types.entry_bool); 16928 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 16929 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 16930 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 16931 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 16932 return ir_const_bool(ira, &bin_op_instruction->base.base, bool_result); 16933 } 16934 IrInstGen *is_non_null = ir_build_test_non_null_gen(ira, &bin_op_instruction->base.base, c_ptr_op); 16935 16936 if (op_id == IrBinOpCmpEq) { 16937 return ir_build_bool_not_gen(ira, &bin_op_instruction->base.base, is_non_null); 16938 } else { 16939 return is_non_null; 16940 } 16941 } else if (is_equality_cmp && 16942 (op1->value->type->id == ZigTypeIdOptional && get_src_ptr_type(op1->value->type) == nullptr)) 16943 { 16944 return ir_analyze_cmp_optional_non_optional(ira, &bin_op_instruction->base.base, op1, op2, op1, op_id); 16945 } else if(is_equality_cmp && 16946 (op2->value->type->id == ZigTypeIdOptional && get_src_ptr_type(op2->value->type) == nullptr)) 16947 { 16948 return ir_analyze_cmp_optional_non_optional(ira, &bin_op_instruction->base.base, op1, op2, op2, op_id); 16949 } else if (op1->value->type->id == ZigTypeIdNull || op2->value->type->id == ZigTypeIdNull) { 16950 ZigType *non_null_type = (op1->value->type->id == ZigTypeIdNull) ? op2->value->type : op1->value->type; 16951 ir_add_error_node(ira, source_node, buf_sprintf("comparison of '%s' with null", 16952 buf_ptr(&non_null_type->name))); 16953 return ira->codegen->invalid_inst_gen; 16954 } else if (is_equality_cmp && ( 16955 (op1->value->type->id == ZigTypeIdEnumLiteral && op2->value->type->id == ZigTypeIdUnion) || 16956 (op2->value->type->id == ZigTypeIdEnumLiteral && op1->value->type->id == ZigTypeIdUnion))) 16957 { 16958 // Support equality comparison between a union's tag value and a enum literal 16959 IrInstGen *union_val = op1->value->type->id == ZigTypeIdUnion ? op1 : op2; 16960 IrInstGen *enum_val = op1->value->type->id == ZigTypeIdUnion ? op2 : op1; 16961 16962 if (!is_tagged_union(union_val->value->type)) { 16963 ErrorMsg *msg = ir_add_error_node(ira, source_node, 16964 buf_sprintf("comparison of union and enum literal is only valid for tagged union types")); 16965 add_error_note(ira->codegen, msg, union_val->value->type->data.unionation.decl_node, 16966 buf_sprintf("type %s is not a tagged union", 16967 buf_ptr(&union_val->value->type->name))); 16968 return ira->codegen->invalid_inst_gen; 16969 } 16970 16971 ZigType *tag_type = union_val->value->type->data.unionation.tag_type; 16972 assert(tag_type != nullptr); 16973 16974 IrInstGen *casted_union = ir_implicit_cast(ira, union_val, tag_type); 16975 if (type_is_invalid(casted_union->value->type)) 16976 return ira->codegen->invalid_inst_gen; 16977 16978 IrInstGen *casted_val = ir_implicit_cast(ira, enum_val, tag_type); 16979 if (type_is_invalid(casted_val->value->type)) 16980 return ira->codegen->invalid_inst_gen; 16981 16982 if (instr_is_comptime(casted_union)) { 16983 ZigValue *const_union_val = ir_resolve_const(ira, casted_union, UndefBad); 16984 if (!const_union_val) 16985 return ira->codegen->invalid_inst_gen; 16986 16987 ZigValue *const_enum_val = ir_resolve_const(ira, casted_val, UndefBad); 16988 if (!const_enum_val) 16989 return ira->codegen->invalid_inst_gen; 16990 16991 Cmp cmp_result = bigint_cmp(&const_union_val->data.x_union.tag, &const_enum_val->data.x_enum_tag); 16992 bool bool_result = (op_id == IrBinOpCmpEq) ? cmp_result == CmpEQ : cmp_result != CmpEQ; 16993 16994 return ir_const_bool(ira, &bin_op_instruction->base.base, bool_result); 16995 } 16996 16997 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, ira->codegen->builtin_types.entry_bool, 16998 op_id, casted_union, casted_val, bin_op_instruction->safety_check_on); 16999 } 17000 17001 if (op1->value->type->id == ZigTypeIdErrorSet && op2->value->type->id == ZigTypeIdErrorSet) { 17002 if (!is_equality_cmp) { 17003 ir_add_error_node(ira, source_node, buf_sprintf("operator not allowed for errors")); 17004 return ira->codegen->invalid_inst_gen; 17005 } 17006 ZigType *intersect_type = get_error_set_intersection(ira, op1->value->type, op2->value->type, source_node); 17007 if (type_is_invalid(intersect_type)) { 17008 return ira->codegen->invalid_inst_gen; 17009 } 17010 17011 if (!resolve_inferred_error_set(ira->codegen, intersect_type, source_node)) { 17012 return ira->codegen->invalid_inst_gen; 17013 } 17014 17015 // exception if one of the operators has the type of the empty error set, we allow the comparison 17016 // (and make it comptime known) 17017 // this is a function which is evaluated at comptime and returns an inferred error set will have an empty 17018 // error set. 17019 if (op1->value->type->data.error_set.err_count == 0 || op2->value->type->data.error_set.err_count == 0) { 17020 bool are_equal = false; 17021 bool answer; 17022 if (op_id == IrBinOpCmpEq) { 17023 answer = are_equal; 17024 } else if (op_id == IrBinOpCmpNotEq) { 17025 answer = !are_equal; 17026 } else { 17027 zig_unreachable(); 17028 } 17029 return ir_const_bool(ira, &bin_op_instruction->base.base, answer); 17030 } 17031 17032 if (!type_is_global_error_set(intersect_type)) { 17033 if (intersect_type->data.error_set.err_count == 0) { 17034 ir_add_error_node(ira, source_node, 17035 buf_sprintf("error sets '%s' and '%s' have no common errors", 17036 buf_ptr(&op1->value->type->name), buf_ptr(&op2->value->type->name))); 17037 return ira->codegen->invalid_inst_gen; 17038 } 17039 if (op1->value->type->data.error_set.err_count == 1 && op2->value->type->data.error_set.err_count == 1) { 17040 bool are_equal = true; 17041 bool answer; 17042 if (op_id == IrBinOpCmpEq) { 17043 answer = are_equal; 17044 } else if (op_id == IrBinOpCmpNotEq) { 17045 answer = !are_equal; 17046 } else { 17047 zig_unreachable(); 17048 } 17049 return ir_const_bool(ira, &bin_op_instruction->base.base, answer); 17050 } 17051 } 17052 17053 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 17054 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 17055 if (op1_val == nullptr) 17056 return ira->codegen->invalid_inst_gen; 17057 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 17058 if (op2_val == nullptr) 17059 return ira->codegen->invalid_inst_gen; 17060 17061 bool answer; 17062 bool are_equal = op1_val->data.x_err_set->value == op2_val->data.x_err_set->value; 17063 if (op_id == IrBinOpCmpEq) { 17064 answer = are_equal; 17065 } else if (op_id == IrBinOpCmpNotEq) { 17066 answer = !are_equal; 17067 } else { 17068 zig_unreachable(); 17069 } 17070 17071 return ir_const_bool(ira, &bin_op_instruction->base.base, answer); 17072 } 17073 17074 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, ira->codegen->builtin_types.entry_bool, 17075 op_id, op1, op2, bin_op_instruction->safety_check_on); 17076 } 17077 17078 if (type_is_numeric(op1->value->type) && type_is_numeric(op2->value->type)) { 17079 // This operation allows any combination of integer and float types, regardless of the 17080 // signed-ness, comptime-ness, and bit-width. So peer type resolution is incorrect for 17081 // numeric types. 17082 return ir_analyze_bin_op_cmp_numeric(ira, &bin_op_instruction->base.base, op1, op2, op_id); 17083 } 17084 17085 IrInstGen *instructions[] = {op1, op2}; 17086 ZigType *resolved_type = ir_resolve_peer_types(ira, source_node, nullptr, instructions, 2); 17087 if (type_is_invalid(resolved_type)) 17088 return ira->codegen->invalid_inst_gen; 17089 17090 bool operator_allowed = type_is_self_comparable(resolved_type, is_equality_cmp); 17091 17092 if (!operator_allowed) { 17093 ir_add_error_node(ira, source_node, 17094 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name))); 17095 return ira->codegen->invalid_inst_gen; 17096 } 17097 17098 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 17099 if (type_is_invalid(casted_op1->value->type)) 17100 return ira->codegen->invalid_inst_gen; 17101 17102 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 17103 if (type_is_invalid(casted_op2->value->type)) 17104 return ira->codegen->invalid_inst_gen; 17105 17106 IrInstGen *resolve_const_result = ir_try_evaluate_bin_op_cmp_const(ira, &bin_op_instruction->base.base, casted_op1, 17107 casted_op2, resolved_type, op_id); 17108 if (resolve_const_result != nullptr) { 17109 return resolve_const_result; 17110 } 17111 17112 ZigType *res_type = (resolved_type->id == ZigTypeIdVector) ? 17113 get_vector_type(ira->codegen, resolved_type->data.vector.len, ira->codegen->builtin_types.entry_bool) : 17114 ira->codegen->builtin_types.entry_bool; 17115 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, res_type, 17116 op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 17117 } 17118 17119 static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInst* source_instr, ZigType *type_entry, 17120 ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val, ZigValue *out_val) 17121 { 17122 bool is_int; 17123 bool is_float; 17124 Cmp op2_zcmp; 17125 if (type_entry->id == ZigTypeIdInt || type_entry->id == ZigTypeIdComptimeInt) { 17126 is_int = true; 17127 is_float = false; 17128 op2_zcmp = bigint_cmp_zero(&op2_val->data.x_bigint); 17129 } else if (type_entry->id == ZigTypeIdFloat || 17130 type_entry->id == ZigTypeIdComptimeFloat) 17131 { 17132 is_int = false; 17133 is_float = true; 17134 op2_zcmp = float_cmp_zero(op2_val); 17135 } else { 17136 zig_unreachable(); 17137 } 17138 17139 if ((op_id == IrBinOpDivUnspecified || op_id == IrBinOpRemRem || op_id == IrBinOpRemMod || 17140 op_id == IrBinOpDivTrunc || op_id == IrBinOpDivFloor) && op2_zcmp == CmpEQ) 17141 { 17142 return ir_add_error(ira, source_instr, buf_sprintf("division by zero")); 17143 } 17144 if ((op_id == IrBinOpRemRem || op_id == IrBinOpRemMod) && op2_zcmp == CmpLT) { 17145 return ir_add_error(ira, source_instr, buf_sprintf("negative denominator")); 17146 } 17147 17148 switch (op_id) { 17149 case IrBinOpInvalid: 17150 case IrBinOpBoolOr: 17151 case IrBinOpBoolAnd: 17152 case IrBinOpCmpEq: 17153 case IrBinOpCmpNotEq: 17154 case IrBinOpCmpLessThan: 17155 case IrBinOpCmpGreaterThan: 17156 case IrBinOpCmpLessOrEq: 17157 case IrBinOpCmpGreaterOrEq: 17158 case IrBinOpArrayCat: 17159 case IrBinOpArrayMult: 17160 case IrBinOpRemUnspecified: 17161 zig_unreachable(); 17162 case IrBinOpBinOr: 17163 assert(is_int); 17164 bigint_or(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17165 break; 17166 case IrBinOpBinXor: 17167 assert(is_int); 17168 bigint_xor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17169 break; 17170 case IrBinOpBinAnd: 17171 assert(is_int); 17172 bigint_and(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17173 break; 17174 case IrBinOpBitShiftLeftExact: 17175 assert(is_int); 17176 bigint_shl(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17177 break; 17178 case IrBinOpBitShiftLeftLossy: 17179 assert(type_entry->id == ZigTypeIdInt); 17180 bigint_shl_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 17181 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 17182 break; 17183 case IrBinOpBitShiftRightExact: 17184 { 17185 assert(is_int); 17186 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17187 BigInt orig_bigint; 17188 bigint_shl(&orig_bigint, &out_val->data.x_bigint, &op2_val->data.x_bigint); 17189 if (bigint_cmp(&op1_val->data.x_bigint, &orig_bigint) != CmpEQ) { 17190 return ir_add_error(ira, source_instr, buf_sprintf("exact shift shifted out 1 bits")); 17191 } 17192 break; 17193 } 17194 case IrBinOpBitShiftRightLossy: 17195 assert(is_int); 17196 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17197 break; 17198 case IrBinOpAdd: 17199 if (is_int) { 17200 bigint_add(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17201 } else { 17202 float_add(out_val, op1_val, op2_val); 17203 } 17204 break; 17205 case IrBinOpAddWrap: 17206 assert(type_entry->id == ZigTypeIdInt); 17207 bigint_add_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 17208 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 17209 break; 17210 case IrBinOpSub: 17211 if (is_int) { 17212 bigint_sub(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17213 } else { 17214 float_sub(out_val, op1_val, op2_val); 17215 } 17216 break; 17217 case IrBinOpSubWrap: 17218 assert(type_entry->id == ZigTypeIdInt); 17219 bigint_sub_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 17220 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 17221 break; 17222 case IrBinOpMult: 17223 if (is_int) { 17224 bigint_mul(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17225 } else { 17226 float_mul(out_val, op1_val, op2_val); 17227 } 17228 break; 17229 case IrBinOpMultWrap: 17230 assert(type_entry->id == ZigTypeIdInt); 17231 bigint_mul_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 17232 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 17233 break; 17234 case IrBinOpDivUnspecified: 17235 assert(is_float); 17236 float_div(out_val, op1_val, op2_val); 17237 break; 17238 case IrBinOpDivTrunc: 17239 if (is_int) { 17240 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17241 } else { 17242 float_div_trunc(out_val, op1_val, op2_val); 17243 } 17244 break; 17245 case IrBinOpDivFloor: 17246 if (is_int) { 17247 bigint_div_floor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17248 } else { 17249 float_div_floor(out_val, op1_val, op2_val); 17250 } 17251 break; 17252 case IrBinOpDivExact: 17253 if (is_int) { 17254 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17255 BigInt remainder; 17256 bigint_rem(&remainder, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17257 if (bigint_cmp_zero(&remainder) != CmpEQ) { 17258 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); 17259 } 17260 } else { 17261 float_div_trunc(out_val, op1_val, op2_val); 17262 ZigValue remainder = {}; 17263 float_rem(&remainder, op1_val, op2_val); 17264 if (float_cmp_zero(&remainder) != CmpEQ) { 17265 return ir_add_error(ira, source_instr, buf_sprintf("exact division had a remainder")); 17266 } 17267 } 17268 break; 17269 case IrBinOpRemRem: 17270 if (is_int) { 17271 bigint_rem(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17272 } else { 17273 float_rem(out_val, op1_val, op2_val); 17274 } 17275 break; 17276 case IrBinOpRemMod: 17277 if (is_int) { 17278 bigint_mod(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 17279 } else { 17280 float_mod(out_val, op1_val, op2_val); 17281 } 17282 break; 17283 } 17284 17285 if (type_entry->id == ZigTypeIdInt) { 17286 if (!bigint_fits_in_bits(&out_val->data.x_bigint, type_entry->data.integral.bit_count, 17287 type_entry->data.integral.is_signed)) 17288 { 17289 return ir_add_error(ira, source_instr, buf_sprintf("operation caused overflow")); 17290 } 17291 } 17292 17293 out_val->type = type_entry; 17294 out_val->special = ConstValSpecialStatic; 17295 return nullptr; 17296 } 17297 17298 // This works on operands that have already been checked to be comptime known. 17299 static IrInstGen *ir_analyze_math_op(IrAnalyze *ira, IrInst* source_instr, 17300 ZigType *type_entry, ZigValue *op1_val, IrBinOp op_id, ZigValue *op2_val) 17301 { 17302 IrInstGen *result_instruction = ir_const(ira, source_instr, type_entry); 17303 ZigValue *out_val = result_instruction->value; 17304 if (type_entry->id == ZigTypeIdVector) { 17305 expand_undef_array(ira->codegen, op1_val); 17306 expand_undef_array(ira->codegen, op2_val); 17307 out_val->special = ConstValSpecialUndef; 17308 expand_undef_array(ira->codegen, out_val); 17309 size_t len = type_entry->data.vector.len; 17310 ZigType *scalar_type = type_entry->data.vector.elem_type; 17311 for (size_t i = 0; i < len; i += 1) { 17312 ZigValue *scalar_op1_val = &op1_val->data.x_array.data.s_none.elements[i]; 17313 ZigValue *scalar_op2_val = &op2_val->data.x_array.data.s_none.elements[i]; 17314 ZigValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 17315 assert(scalar_op1_val->type == scalar_type); 17316 assert(scalar_out_val->type == scalar_type); 17317 ErrorMsg *msg = ir_eval_math_op_scalar(ira, source_instr, scalar_type, 17318 scalar_op1_val, op_id, scalar_op2_val, scalar_out_val); 17319 if (msg != nullptr) { 17320 add_error_note(ira->codegen, msg, source_instr->source_node, 17321 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 17322 return ira->codegen->invalid_inst_gen; 17323 } 17324 } 17325 out_val->type = type_entry; 17326 out_val->special = ConstValSpecialStatic; 17327 } else { 17328 if (ir_eval_math_op_scalar(ira, source_instr, type_entry, op1_val, op_id, op2_val, out_val) != nullptr) { 17329 return ira->codegen->invalid_inst_gen; 17330 } 17331 } 17332 return ir_implicit_cast(ira, result_instruction, type_entry); 17333 } 17334 17335 static IrInstGen *ir_analyze_bit_shift(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { 17336 IrInstGen *op1 = bin_op_instruction->op1->child; 17337 if (type_is_invalid(op1->value->type)) 17338 return ira->codegen->invalid_inst_gen; 17339 17340 IrInstGen *op2 = bin_op_instruction->op2->child; 17341 if (type_is_invalid(op2->value->type)) 17342 return ira->codegen->invalid_inst_gen; 17343 17344 ZigType *op1_type = op1->value->type; 17345 ZigType *op2_type = op2->value->type; 17346 17347 if (op1_type->id == ZigTypeIdVector && op2_type->id != ZigTypeIdVector) { 17348 ir_add_error(ira, &bin_op_instruction->op1->base, 17349 buf_sprintf("bit shifting operation expected vector type, found '%s'", 17350 buf_ptr(&op2_type->name))); 17351 return ira->codegen->invalid_inst_gen; 17352 } 17353 17354 if (op1_type->id != ZigTypeIdVector && op2_type->id == ZigTypeIdVector) { 17355 ir_add_error(ira, &bin_op_instruction->op1->base, 17356 buf_sprintf("bit shifting operation expected vector type, found '%s'", 17357 buf_ptr(&op1_type->name))); 17358 return ira->codegen->invalid_inst_gen; 17359 } 17360 17361 ZigType *op1_scalar_type = (op1_type->id == ZigTypeIdVector) ? 17362 op1_type->data.vector.elem_type : op1_type; 17363 ZigType *op2_scalar_type = (op2_type->id == ZigTypeIdVector) ? 17364 op2_type->data.vector.elem_type : op2_type; 17365 17366 if (op1_scalar_type->id != ZigTypeIdInt && op1_scalar_type->id != ZigTypeIdComptimeInt) { 17367 ir_add_error(ira, &bin_op_instruction->op1->base, 17368 buf_sprintf("bit shifting operation expected integer type, found '%s'", 17369 buf_ptr(&op1_scalar_type->name))); 17370 return ira->codegen->invalid_inst_gen; 17371 } 17372 17373 if (op2_scalar_type->id != ZigTypeIdInt && op2_scalar_type->id != ZigTypeIdComptimeInt) { 17374 ir_add_error(ira, &bin_op_instruction->op2->base, 17375 buf_sprintf("shift amount has to be an integer type, but found '%s'", 17376 buf_ptr(&op2_scalar_type->name))); 17377 return ira->codegen->invalid_inst_gen; 17378 } 17379 17380 IrInstGen *casted_op2; 17381 IrBinOp op_id = bin_op_instruction->op_id; 17382 if (op1_scalar_type->id == ZigTypeIdComptimeInt) { 17383 // comptime_int has no finite bit width 17384 casted_op2 = op2; 17385 17386 if (op_id == IrBinOpBitShiftLeftLossy) { 17387 op_id = IrBinOpBitShiftLeftExact; 17388 } 17389 17390 if (!instr_is_comptime(op2)) { 17391 ir_add_error(ira, &bin_op_instruction->base.base, 17392 buf_sprintf("LHS of shift must be a fixed-width integer type, or RHS must be compile-time known")); 17393 return ira->codegen->invalid_inst_gen; 17394 } 17395 17396 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 17397 if (op2_val == nullptr) 17398 return ira->codegen->invalid_inst_gen; 17399 17400 if (op2_val->data.x_bigint.is_negative) { 17401 Buf *val_buf = buf_alloc(); 17402 bigint_append_buf(val_buf, &op2_val->data.x_bigint, 10); 17403 ir_add_error(ira, &casted_op2->base, 17404 buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); 17405 return ira->codegen->invalid_inst_gen; 17406 } 17407 } else { 17408 const unsigned bit_count = op1_scalar_type->data.integral.bit_count; 17409 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 17410 bit_count > 0 ? bit_count - 1 : 0); 17411 17412 if (op1_type->id == ZigTypeIdVector) { 17413 shift_amt_type = get_vector_type(ira->codegen, op1_type->data.vector.len, 17414 shift_amt_type); 17415 } 17416 17417 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 17418 if (type_is_invalid(casted_op2->value->type)) 17419 return ira->codegen->invalid_inst_gen; 17420 17421 // This check is only valid iff op1 has at least one bit 17422 if (bit_count > 0 && instr_is_comptime(casted_op2)) { 17423 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 17424 if (op2_val == nullptr) 17425 return ira->codegen->invalid_inst_gen; 17426 17427 ZigValue bit_count_value = {}; 17428 init_const_usize(ira->codegen, &bit_count_value, bit_count); 17429 17430 if (!value_cmp_numeric_val_all(op2_val, CmpLT, &bit_count_value)) { 17431 ErrorMsg* msg = ir_add_error(ira, 17432 &bin_op_instruction->base.base, 17433 buf_sprintf("RHS of shift is too large for LHS type")); 17434 add_error_note(ira->codegen, msg, op1->base.source_node, 17435 buf_sprintf("type %s has only %u bits", 17436 buf_ptr(&op1->value->type->name), bit_count)); 17437 17438 return ira->codegen->invalid_inst_gen; 17439 } 17440 } 17441 } 17442 17443 // Fast path for zero RHS 17444 if (instr_is_comptime(casted_op2)) { 17445 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 17446 if (op2_val == nullptr) 17447 return ira->codegen->invalid_inst_gen; 17448 17449 if (value_cmp_numeric_val_all(op2_val, CmpEQ, nullptr)) 17450 return ir_analyze_cast(ira, &bin_op_instruction->base.base, op1->value->type, op1); 17451 } 17452 17453 if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) { 17454 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 17455 if (op1_val == nullptr) 17456 return ira->codegen->invalid_inst_gen; 17457 17458 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 17459 if (op2_val == nullptr) 17460 return ira->codegen->invalid_inst_gen; 17461 17462 return ir_analyze_math_op(ira, &bin_op_instruction->base.base, op1_type, op1_val, op_id, op2_val); 17463 } 17464 17465 return ir_build_bin_op_gen(ira, &bin_op_instruction->base.base, op1->value->type, 17466 op_id, op1, casted_op2, bin_op_instruction->safety_check_on); 17467 } 17468 17469 static bool ok_float_op(IrBinOp op) { 17470 switch (op) { 17471 case IrBinOpInvalid: 17472 zig_unreachable(); 17473 case IrBinOpAdd: 17474 case IrBinOpSub: 17475 case IrBinOpMult: 17476 case IrBinOpDivUnspecified: 17477 case IrBinOpDivTrunc: 17478 case IrBinOpDivFloor: 17479 case IrBinOpDivExact: 17480 case IrBinOpRemRem: 17481 case IrBinOpRemMod: 17482 case IrBinOpRemUnspecified: 17483 return true; 17484 17485 case IrBinOpBoolOr: 17486 case IrBinOpBoolAnd: 17487 case IrBinOpCmpEq: 17488 case IrBinOpCmpNotEq: 17489 case IrBinOpCmpLessThan: 17490 case IrBinOpCmpGreaterThan: 17491 case IrBinOpCmpLessOrEq: 17492 case IrBinOpCmpGreaterOrEq: 17493 case IrBinOpBinOr: 17494 case IrBinOpBinXor: 17495 case IrBinOpBinAnd: 17496 case IrBinOpBitShiftLeftLossy: 17497 case IrBinOpBitShiftLeftExact: 17498 case IrBinOpBitShiftRightLossy: 17499 case IrBinOpBitShiftRightExact: 17500 case IrBinOpAddWrap: 17501 case IrBinOpSubWrap: 17502 case IrBinOpMultWrap: 17503 case IrBinOpArrayCat: 17504 case IrBinOpArrayMult: 17505 return false; 17506 } 17507 zig_unreachable(); 17508 } 17509 17510 static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) { 17511 switch (op) { 17512 case IrBinOpAdd: 17513 case IrBinOpSub: 17514 break; 17515 default: 17516 return false; 17517 } 17518 if (lhs_type->id != ZigTypeIdPointer) 17519 return false; 17520 switch (lhs_type->data.pointer.ptr_len) { 17521 case PtrLenSingle: 17522 return lhs_type->data.pointer.child_type->id == ZigTypeIdArray; 17523 case PtrLenUnknown: 17524 case PtrLenC: 17525 return true; 17526 } 17527 zig_unreachable(); 17528 } 17529 17530 static bool value_cmp_numeric_val(ZigValue *left, Cmp predicate, ZigValue *right, bool any) { 17531 assert(left->special == ConstValSpecialStatic); 17532 assert(right == nullptr || right->special == ConstValSpecialStatic); 17533 17534 switch (left->type->id) { 17535 case ZigTypeIdComptimeInt: 17536 case ZigTypeIdInt: { 17537 const Cmp result = right ? 17538 bigint_cmp(&left->data.x_bigint, &right->data.x_bigint) : 17539 bigint_cmp_zero(&left->data.x_bigint); 17540 return result == predicate; 17541 } 17542 case ZigTypeIdComptimeFloat: 17543 case ZigTypeIdFloat: { 17544 if (float_is_nan(left)) 17545 return false; 17546 if (right != nullptr && float_is_nan(right)) 17547 return false; 17548 17549 const Cmp result = right ? float_cmp(left, right) : float_cmp_zero(left); 17550 return result == predicate; 17551 } 17552 case ZigTypeIdVector: { 17553 for (size_t i = 0; i < left->type->data.vector.len; i++) { 17554 ZigValue *scalar_val = &left->data.x_array.data.s_none.elements[i]; 17555 const bool result = value_cmp_numeric_val(scalar_val, predicate, right, any); 17556 17557 if (any && result) 17558 return true; // This element satisfies the predicate 17559 else if (!any && !result) 17560 return false; // This element doesn't satisfy the predicate 17561 } 17562 return any ? false : true; 17563 } 17564 default: 17565 zig_unreachable(); 17566 } 17567 } 17568 17569 static bool value_cmp_numeric_val_any(ZigValue *left, Cmp predicate, ZigValue *right) { 17570 return value_cmp_numeric_val(left, predicate, right, true); 17571 } 17572 17573 static bool value_cmp_numeric_val_all(ZigValue *left, Cmp predicate, ZigValue *right) { 17574 return value_cmp_numeric_val(left, predicate, right, false); 17575 } 17576 17577 static IrInstGen *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstSrcBinOp *instruction) { 17578 Error err; 17579 17580 IrInstGen *op1 = instruction->op1->child; 17581 if (type_is_invalid(op1->value->type)) 17582 return ira->codegen->invalid_inst_gen; 17583 17584 IrInstGen *op2 = instruction->op2->child; 17585 if (type_is_invalid(op2->value->type)) 17586 return ira->codegen->invalid_inst_gen; 17587 17588 IrBinOp op_id = instruction->op_id; 17589 17590 // look for pointer math 17591 if (is_pointer_arithmetic_allowed(op1->value->type, op_id)) { 17592 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, ira->codegen->builtin_types.entry_usize); 17593 if (type_is_invalid(casted_op2->value->type)) 17594 return ira->codegen->invalid_inst_gen; 17595 17596 // If either operand is undef, result is undef. 17597 ZigValue *op1_val = nullptr; 17598 ZigValue *op2_val = nullptr; 17599 if (instr_is_comptime(op1)) { 17600 op1_val = ir_resolve_const(ira, op1, UndefOk); 17601 if (op1_val == nullptr) 17602 return ira->codegen->invalid_inst_gen; 17603 if (op1_val->special == ConstValSpecialUndef) 17604 return ir_const_undef(ira, &instruction->base.base, op1->value->type); 17605 } 17606 if (instr_is_comptime(casted_op2)) { 17607 op2_val = ir_resolve_const(ira, casted_op2, UndefOk); 17608 if (op2_val == nullptr) 17609 return ira->codegen->invalid_inst_gen; 17610 if (op2_val->special == ConstValSpecialUndef) 17611 return ir_const_undef(ira, &instruction->base.base, op1->value->type); 17612 } 17613 17614 ZigType *elem_type = op1->value->type->data.pointer.child_type; 17615 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) 17616 return ira->codegen->invalid_inst_gen; 17617 17618 // NOTE: this variable is meaningful iff op2_val is not null! 17619 uint64_t byte_offset; 17620 if (op2_val != nullptr) { 17621 uint64_t elem_offset; 17622 if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) 17623 return ira->codegen->invalid_inst_gen; 17624 17625 byte_offset = type_size(ira->codegen, elem_type) * elem_offset; 17626 } 17627 17628 // Fast path for cases where the RHS is zero 17629 if (op2_val != nullptr && byte_offset == 0) { 17630 return op1; 17631 } 17632 17633 ZigType *result_type = op1->value->type; 17634 // Calculate the new alignment of the pointer 17635 { 17636 uint32_t align_bytes; 17637 if ((err = resolve_ptr_align(ira, op1->value->type, &align_bytes))) 17638 return ira->codegen->invalid_inst_gen; 17639 17640 // If the addend is not a comptime-known value we can still count on 17641 // it being a multiple of the type size 17642 uint32_t addend = op2_val ? byte_offset : type_size(ira->codegen, elem_type); 17643 17644 // The resulting pointer is aligned to the lcd between the 17645 // offset (an arbitrary number) and the alignment factor (always 17646 // a power of two, non zero) 17647 uint32_t new_align = 1 << ctzll(addend | align_bytes); 17648 // Rough guard to prevent overflows 17649 assert(new_align); 17650 result_type = adjust_ptr_align(ira->codegen, result_type, new_align); 17651 } 17652 17653 if (op2_val != nullptr && op1_val != nullptr && 17654 (op1->value->data.x_ptr.special == ConstPtrSpecialHardCodedAddr || 17655 op1->value->data.x_ptr.special == ConstPtrSpecialNull)) 17656 { 17657 uint64_t start_addr = (op1_val->data.x_ptr.special == ConstPtrSpecialNull) ? 17658 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr; 17659 uint64_t new_addr; 17660 if (op_id == IrBinOpAdd) { 17661 new_addr = start_addr + byte_offset; 17662 } else if (op_id == IrBinOpSub) { 17663 new_addr = start_addr - byte_offset; 17664 } else { 17665 zig_unreachable(); 17666 } 17667 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 17668 result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 17669 result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; 17670 result->value->data.x_ptr.data.hard_coded_addr.addr = new_addr; 17671 return result; 17672 } 17673 17674 return ir_build_bin_op_gen(ira, &instruction->base.base, result_type, op_id, op1, casted_op2, true); 17675 } 17676 17677 IrInstGen *instructions[] = {op1, op2}; 17678 ZigType *resolved_type = ir_resolve_peer_types(ira, instruction->base.base.source_node, nullptr, instructions, 2); 17679 if (type_is_invalid(resolved_type)) 17680 return ira->codegen->invalid_inst_gen; 17681 17682 ZigType *scalar_type = (resolved_type->id == ZigTypeIdVector) ? 17683 resolved_type->data.vector.elem_type : resolved_type; 17684 17685 bool is_int = scalar_type->id == ZigTypeIdInt || scalar_type->id == ZigTypeIdComptimeInt; 17686 bool is_float = scalar_type->id == ZigTypeIdFloat || scalar_type->id == ZigTypeIdComptimeFloat; 17687 17688 if (!is_int && !(is_float && ok_float_op(op_id))) { 17689 AstNode *source_node = instruction->base.base.source_node; 17690 ir_add_error_node(ira, source_node, 17691 buf_sprintf("invalid operands to binary expression: '%s' and '%s'", 17692 buf_ptr(&op1->value->type->name), 17693 buf_ptr(&op2->value->type->name))); 17694 return ira->codegen->invalid_inst_gen; 17695 } 17696 17697 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 17698 if (type_is_invalid(casted_op1->value->type)) 17699 return ira->codegen->invalid_inst_gen; 17700 17701 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 17702 if (type_is_invalid(casted_op2->value->type)) 17703 return ira->codegen->invalid_inst_gen; 17704 17705 // Comptime integers have no fixed size 17706 if (scalar_type->id == ZigTypeIdComptimeInt) { 17707 if (op_id == IrBinOpAddWrap) { 17708 op_id = IrBinOpAdd; 17709 } else if (op_id == IrBinOpSubWrap) { 17710 op_id = IrBinOpSub; 17711 } else if (op_id == IrBinOpMultWrap) { 17712 op_id = IrBinOpMult; 17713 } 17714 } 17715 17716 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 17717 ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 17718 if (op1_val == nullptr) 17719 return ira->codegen->invalid_inst_gen; 17720 17721 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 17722 if (op2_val == nullptr) 17723 return ira->codegen->invalid_inst_gen; 17724 17725 // Promote division with negative numbers to signed 17726 bool is_signed_div = value_cmp_numeric_val_any(op1_val, CmpLT, nullptr) || 17727 value_cmp_numeric_val_any(op2_val, CmpLT, nullptr); 17728 17729 if (op_id == IrBinOpDivUnspecified && is_int) { 17730 // Default to truncating division and check if it's valid for the 17731 // given operands if signed 17732 op_id = IrBinOpDivTrunc; 17733 17734 if (is_signed_div) { 17735 bool ok = false; 17736 17737 if (value_cmp_numeric_val_any(op2_val, CmpEQ, nullptr)) { 17738 // the division by zero error will be caught later, but we don't have a 17739 // division function ambiguity problem. 17740 ok = true; 17741 } else { 17742 IrInstGen *trunc_val = ir_analyze_math_op(ira, &instruction->base.base, resolved_type, 17743 op1_val, IrBinOpDivTrunc, op2_val); 17744 if (type_is_invalid(trunc_val->value->type)) 17745 return ira->codegen->invalid_inst_gen; 17746 17747 IrInstGen *floor_val = ir_analyze_math_op(ira, &instruction->base.base, resolved_type, 17748 op1_val, IrBinOpDivFloor, op2_val); 17749 if (type_is_invalid(floor_val->value->type)) 17750 return ira->codegen->invalid_inst_gen; 17751 17752 IrInstGen *cmp_val = ir_analyze_bin_op_cmp_numeric(ira, &instruction->base.base, 17753 trunc_val, floor_val, IrBinOpCmpEq); 17754 if (type_is_invalid(cmp_val->value->type)) 17755 return ira->codegen->invalid_inst_gen; 17756 17757 // We can "upgrade" the operator only if trunc(a/b) == floor(a/b) 17758 if (!ir_resolve_bool(ira, cmp_val, &ok)) 17759 return ira->codegen->invalid_inst_gen; 17760 } 17761 17762 if (!ok) { 17763 ir_add_error(ira, &instruction->base.base, 17764 buf_sprintf("division with '%s' and '%s': signed integers must use @divTrunc, @divFloor, or @divExact", 17765 buf_ptr(&op1->value->type->name), 17766 buf_ptr(&op2->value->type->name))); 17767 return ira->codegen->invalid_inst_gen; 17768 } 17769 } 17770 } else if (op_id == IrBinOpRemUnspecified) { 17771 op_id = IrBinOpRemRem; 17772 17773 if (is_signed_div) { 17774 bool ok = false; 17775 17776 if (value_cmp_numeric_val_any(op2_val, CmpEQ, nullptr)) { 17777 // the division by zero error will be caught later, but we don't have a 17778 // division function ambiguity problem. 17779 ok = true; 17780 } else { 17781 IrInstGen *rem_val = ir_analyze_math_op(ira, &instruction->base.base, resolved_type, 17782 op1_val, IrBinOpRemRem, op2_val); 17783 if (type_is_invalid(rem_val->value->type)) 17784 return ira->codegen->invalid_inst_gen; 17785 17786 IrInstGen *mod_val = ir_analyze_math_op(ira, &instruction->base.base, resolved_type, 17787 op1_val, IrBinOpRemMod, op2_val); 17788 if (type_is_invalid(mod_val->value->type)) 17789 return ira->codegen->invalid_inst_gen; 17790 17791 IrInstGen *cmp_val = ir_analyze_bin_op_cmp_numeric(ira, &instruction->base.base, 17792 rem_val, mod_val, IrBinOpCmpEq); 17793 if (type_is_invalid(cmp_val->value->type)) 17794 return ira->codegen->invalid_inst_gen; 17795 17796 // We can "upgrade" the operator only if mod(a,b) == rem(a,b) 17797 if (!ir_resolve_bool(ira, cmp_val, &ok)) 17798 return ira->codegen->invalid_inst_gen; 17799 } 17800 17801 if (!ok) { 17802 ir_add_error(ira, &instruction->base.base, 17803 buf_sprintf("remainder division with '%s' and '%s': signed integers and floats must use @rem or @mod", 17804 buf_ptr(&op1->value->type->name), 17805 buf_ptr(&op2->value->type->name))); 17806 return ira->codegen->invalid_inst_gen; 17807 } 17808 } 17809 } 17810 17811 return ir_analyze_math_op(ira, &instruction->base.base, resolved_type, op1_val, op_id, op2_val); 17812 } 17813 17814 const bool is_signed_div = 17815 (scalar_type->id == ZigTypeIdInt && scalar_type->data.integral.is_signed) || 17816 scalar_type->id == ZigTypeIdFloat; 17817 17818 // Warn the user to use the proper operators here 17819 if (op_id == IrBinOpDivUnspecified && is_int) { 17820 op_id = IrBinOpDivTrunc; 17821 17822 if (is_signed_div) { 17823 ir_add_error(ira, &instruction->base.base, 17824 buf_sprintf("division with '%s' and '%s': signed integers must use @divTrunc, @divFloor, or @divExact", 17825 buf_ptr(&op1->value->type->name), 17826 buf_ptr(&op2->value->type->name))); 17827 return ira->codegen->invalid_inst_gen; 17828 } 17829 } else if (op_id == IrBinOpRemUnspecified) { 17830 op_id = IrBinOpRemRem; 17831 17832 if (is_signed_div) { 17833 ir_add_error(ira, &instruction->base.base, 17834 buf_sprintf("remainder division with '%s' and '%s': signed integers and floats must use @rem or @mod", 17835 buf_ptr(&op1->value->type->name), 17836 buf_ptr(&op2->value->type->name))); 17837 return ira->codegen->invalid_inst_gen; 17838 } 17839 } 17840 17841 return ir_build_bin_op_gen(ira, &instruction->base.base, resolved_type, 17842 op_id, casted_op1, casted_op2, instruction->safety_check_on); 17843 } 17844 17845 static IrInstGen *ir_analyze_tuple_cat(IrAnalyze *ira, IrInst* source_instr, 17846 IrInstGen *op1, IrInstGen *op2) 17847 { 17848 Error err; 17849 ZigType *op1_type = op1->value->type; 17850 ZigType *op2_type = op2->value->type; 17851 17852 uint32_t op1_field_count = op1_type->data.structure.src_field_count; 17853 uint32_t op2_field_count = op2_type->data.structure.src_field_count; 17854 17855 Buf *bare_name = buf_alloc(); 17856 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), 17857 source_instr->scope, source_instr->source_node, bare_name); 17858 ZigType *new_type = get_partial_container_type(ira->codegen, source_instr->scope, 17859 ContainerKindStruct, source_instr->source_node, buf_ptr(name), bare_name, ContainerLayoutAuto); 17860 new_type->data.structure.special = StructSpecialInferredTuple; 17861 new_type->data.structure.resolve_status = ResolveStatusBeingInferred; 17862 uint32_t new_field_count = op1_field_count + op2_field_count; 17863 17864 new_type->data.structure.src_field_count = new_field_count; 17865 new_type->data.structure.fields = realloc_type_struct_fields(new_type->data.structure.fields, 17866 0, new_field_count); 17867 17868 IrInstGen *new_struct_ptr = ir_resolve_result(ira, source_instr, no_result_loc(), 17869 new_type, nullptr, false, true); 17870 17871 for (uint32_t i = 0; i < new_field_count; i += 1) { 17872 TypeStructField *src_field; 17873 if (i < op1_field_count) { 17874 src_field = op1_type->data.structure.fields[i]; 17875 } else { 17876 src_field = op2_type->data.structure.fields[i - op1_field_count]; 17877 } 17878 TypeStructField *new_field = new_type->data.structure.fields[i]; 17879 new_field->name = buf_sprintf("%" PRIu32, i); 17880 new_field->type_entry = src_field->type_entry; 17881 new_field->type_val = src_field->type_val; 17882 new_field->src_index = i; 17883 new_field->decl_node = src_field->decl_node; 17884 new_field->init_val = src_field->init_val; 17885 new_field->is_comptime = src_field->is_comptime; 17886 } 17887 if ((err = type_resolve(ira->codegen, new_type, ResolveStatusZeroBitsKnown))) 17888 return ira->codegen->invalid_inst_gen; 17889 17890 ZigList<IrInstGen *> const_ptrs = {}; 17891 for (uint32_t i = 0; i < new_field_count; i += 1) { 17892 TypeStructField *dst_field = new_type->data.structure.fields[i]; 17893 IrInstGen *src_struct_op; 17894 TypeStructField *src_field; 17895 if (i < op1_field_count) { 17896 src_field = op1_type->data.structure.fields[i]; 17897 src_struct_op = op1; 17898 } else { 17899 src_field = op2_type->data.structure.fields[i - op1_field_count]; 17900 src_struct_op = op2; 17901 } 17902 IrInstGen *field_value = ir_analyze_struct_value_field_value(ira, source_instr, 17903 src_struct_op, src_field); 17904 if (type_is_invalid(field_value->value->type)) 17905 return ira->codegen->invalid_inst_gen; 17906 IrInstGen *dest_ptr = ir_analyze_struct_field_ptr(ira, source_instr, dst_field, 17907 new_struct_ptr, new_type, true); 17908 if (type_is_invalid(dest_ptr->value->type)) 17909 return ira->codegen->invalid_inst_gen; 17910 if (instr_is_comptime(field_value)) { 17911 const_ptrs.append(dest_ptr); 17912 } 17913 IrInstGen *store_ptr_inst = ir_analyze_store_ptr(ira, source_instr, dest_ptr, field_value, 17914 true); 17915 if (type_is_invalid(store_ptr_inst->value->type)) 17916 return ira->codegen->invalid_inst_gen; 17917 } 17918 if (const_ptrs.length != new_field_count) { 17919 new_struct_ptr->value->special = ConstValSpecialRuntime; 17920 for (size_t i = 0; i < const_ptrs.length; i += 1) { 17921 IrInstGen *elem_result_loc = const_ptrs.at(i); 17922 assert(elem_result_loc->value->special == ConstValSpecialStatic); 17923 if (elem_result_loc->value->type->data.pointer.inferred_struct_field != nullptr) { 17924 // This field will be generated comptime; no need to do this. 17925 continue; 17926 } 17927 IrInstGen *deref = ir_get_deref(ira, &elem_result_loc->base, elem_result_loc, nullptr); 17928 if (!type_requires_comptime(ira->codegen, elem_result_loc->value->type->data.pointer.child_type)) { 17929 elem_result_loc->value->special = ConstValSpecialRuntime; 17930 } 17931 ir_analyze_store_ptr(ira, &elem_result_loc->base, elem_result_loc, deref, true); 17932 } 17933 } 17934 17935 const_ptrs.deinit(); 17936 17937 return ir_get_deref(ira, source_instr, new_struct_ptr, nullptr); 17938 } 17939 17940 static IrInstGen *ir_analyze_array_cat(IrAnalyze *ira, IrInstSrcBinOp *instruction) { 17941 IrInstGen *op1 = instruction->op1->child; 17942 ZigType *op1_type = op1->value->type; 17943 if (type_is_invalid(op1_type)) 17944 return ira->codegen->invalid_inst_gen; 17945 17946 IrInstGen *op2 = instruction->op2->child; 17947 ZigType *op2_type = op2->value->type; 17948 if (type_is_invalid(op2_type)) 17949 return ira->codegen->invalid_inst_gen; 17950 17951 if (is_tuple(op1_type) && is_tuple(op2_type)) { 17952 return ir_analyze_tuple_cat(ira, &instruction->base.base, op1, op2); 17953 } 17954 17955 ZigValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 17956 if (!op1_val) 17957 return ira->codegen->invalid_inst_gen; 17958 17959 ZigValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 17960 if (!op2_val) 17961 return ira->codegen->invalid_inst_gen; 17962 17963 ZigValue *sentinel1 = nullptr; 17964 ZigValue *op1_array_val; 17965 size_t op1_array_index; 17966 size_t op1_array_end; 17967 ZigType *child_type; 17968 if (op1_type->id == ZigTypeIdArray) { 17969 child_type = op1_type->data.array.child_type; 17970 op1_array_val = op1_val; 17971 op1_array_index = 0; 17972 op1_array_end = op1_type->data.array.len; 17973 sentinel1 = op1_type->data.array.sentinel; 17974 } else if (op1_type->id == ZigTypeIdPointer && 17975 op1_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && 17976 op1_type->data.pointer.sentinel != nullptr && 17977 op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray) 17978 { 17979 child_type = op1_type->data.pointer.child_type; 17980 op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; 17981 op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; 17982 op1_array_end = op1_array_val->type->data.array.len; 17983 sentinel1 = op1_type->data.pointer.sentinel; 17984 } else if (is_slice(op1_type)) { 17985 ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index]->type_entry; 17986 child_type = ptr_type->data.pointer.child_type; 17987 ZigValue *ptr_val = op1_val->data.x_struct.fields[slice_ptr_index]; 17988 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 17989 op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 17990 op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 17991 ZigValue *len_val = op1_val->data.x_struct.fields[slice_len_index]; 17992 op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint); 17993 sentinel1 = ptr_type->data.pointer.sentinel; 17994 } else if (op1_type->id == ZigTypeIdPointer && 17995 op1_type->data.pointer.ptr_len == PtrLenSingle && 17996 op1_type->data.pointer.child_type->id == ZigTypeIdArray) 17997 { 17998 ZigType *array_type = op1_type->data.pointer.child_type; 17999 child_type = array_type->data.array.child_type; 18000 op1_array_val = const_ptr_pointee(ira, ira->codegen, op1_val, op1->base.source_node); 18001 if (op1_array_val == nullptr) 18002 return ira->codegen->invalid_inst_gen; 18003 op1_array_index = 0; 18004 op1_array_end = array_type->data.array.len; 18005 sentinel1 = array_type->data.array.sentinel; 18006 } else { 18007 ir_add_error(ira, &op1->base, buf_sprintf("expected array, found '%s'", buf_ptr(&op1->value->type->name))); 18008 return ira->codegen->invalid_inst_gen; 18009 } 18010 18011 ZigValue *sentinel2 = nullptr; 18012 ZigValue *op2_array_val; 18013 size_t op2_array_index; 18014 size_t op2_array_end; 18015 bool op2_type_valid; 18016 if (op2_type->id == ZigTypeIdArray) { 18017 op2_type_valid = op2_type->data.array.child_type == child_type; 18018 op2_array_val = op2_val; 18019 op2_array_index = 0; 18020 op2_array_end = op2_array_val->type->data.array.len; 18021 sentinel2 = op2_type->data.array.sentinel; 18022 } else if (op2_type->id == ZigTypeIdPointer && 18023 op2_type->data.pointer.sentinel != nullptr && 18024 op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray) 18025 { 18026 op2_type_valid = op2_type->data.pointer.child_type == child_type; 18027 op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; 18028 op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; 18029 op2_array_end = op2_array_val->type->data.array.len; 18030 18031 sentinel2 = op2_type->data.pointer.sentinel; 18032 } else if (is_slice(op2_type)) { 18033 ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index]->type_entry; 18034 op2_type_valid = ptr_type->data.pointer.child_type == child_type; 18035 ZigValue *ptr_val = op2_val->data.x_struct.fields[slice_ptr_index]; 18036 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 18037 op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 18038 op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 18039 ZigValue *len_val = op2_val->data.x_struct.fields[slice_len_index]; 18040 op2_array_end = op2_array_index + bigint_as_usize(&len_val->data.x_bigint); 18041 18042 sentinel2 = ptr_type->data.pointer.sentinel; 18043 } else if (op2_type->id == ZigTypeIdPointer && op2_type->data.pointer.ptr_len == PtrLenSingle && 18044 op2_type->data.pointer.child_type->id == ZigTypeIdArray) 18045 { 18046 ZigType *array_type = op2_type->data.pointer.child_type; 18047 op2_type_valid = array_type->data.array.child_type == child_type; 18048 op2_array_val = const_ptr_pointee(ira, ira->codegen, op2_val, op2->base.source_node); 18049 if (op2_array_val == nullptr) 18050 return ira->codegen->invalid_inst_gen; 18051 op2_array_index = 0; 18052 op2_array_end = array_type->data.array.len; 18053 18054 sentinel2 = array_type->data.array.sentinel; 18055 } else { 18056 ir_add_error(ira, &op2->base, 18057 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value->type->name))); 18058 return ira->codegen->invalid_inst_gen; 18059 } 18060 if (!op2_type_valid) { 18061 ir_add_error(ira, &op2->base, buf_sprintf("expected array of type '%s', found '%s'", 18062 buf_ptr(&child_type->name), 18063 buf_ptr(&op2->value->type->name))); 18064 return ira->codegen->invalid_inst_gen; 18065 } 18066 18067 ZigValue *sentinel; 18068 if (sentinel1 != nullptr && sentinel2 != nullptr) { 18069 // When there is a sentinel mismatch, no sentinel on the result. The type system 18070 // will catch this if it is a problem. 18071 sentinel = const_values_equal(ira->codegen, sentinel1, sentinel2) ? sentinel1 : nullptr; 18072 } else if (sentinel1 != nullptr) { 18073 sentinel = sentinel1; 18074 } else if (sentinel2 != nullptr) { 18075 sentinel = sentinel2; 18076 } else { 18077 sentinel = nullptr; 18078 } 18079 18080 // The type of result is populated in the following if blocks 18081 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 18082 ZigValue *out_val = result->value; 18083 18084 ZigValue *out_array_val; 18085 size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); 18086 if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) { 18087 out_array_val = ira->codegen->pass1_arena->create<ZigValue>(); 18088 out_array_val->special = ConstValSpecialStatic; 18089 out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 18090 18091 out_val->data.x_ptr.special = ConstPtrSpecialRef; 18092 out_val->data.x_ptr.data.ref.pointee = out_array_val; 18093 out_val->type = get_pointer_to_type(ira->codegen, out_array_val->type, true); 18094 } else if (is_slice(op1_type) || is_slice(op2_type)) { 18095 ZigType *ptr_type = get_pointer_to_type_extra2(ira->codegen, child_type, 18096 true, false, PtrLenUnknown, 0, 0, 0, false, 18097 VECTOR_INDEX_NONE, nullptr, sentinel); 18098 result->value->type = get_slice_type(ira->codegen, ptr_type); 18099 out_array_val = ira->codegen->pass1_arena->create<ZigValue>(); 18100 out_array_val->special = ConstValSpecialStatic; 18101 out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 18102 18103 out_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, 2); 18104 18105 out_val->data.x_struct.fields[slice_ptr_index]->type = ptr_type; 18106 out_val->data.x_struct.fields[slice_ptr_index]->special = ConstValSpecialStatic; 18107 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.special = ConstPtrSpecialBaseArray; 18108 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.array_val = out_array_val; 18109 out_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.data.base_array.elem_index = 0; 18110 18111 out_val->data.x_struct.fields[slice_len_index]->type = ira->codegen->builtin_types.entry_usize; 18112 out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic; 18113 bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len); 18114 } else if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { 18115 result->value->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 18116 out_array_val = out_val; 18117 } else { 18118 result->value->type = get_pointer_to_type_extra2(ira->codegen, child_type, true, false, PtrLenUnknown, 18119 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr, sentinel); 18120 out_array_val = ira->codegen->pass1_arena->create<ZigValue>(); 18121 out_array_val->special = ConstValSpecialStatic; 18122 out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); 18123 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 18124 out_val->data.x_ptr.data.base_array.array_val = out_array_val; 18125 out_val->data.x_ptr.data.base_array.elem_index = 0; 18126 } 18127 18128 if (op1_array_val->data.x_array.special == ConstArraySpecialUndef && 18129 op2_array_val->data.x_array.special == ConstArraySpecialUndef) 18130 { 18131 out_array_val->data.x_array.special = ConstArraySpecialUndef; 18132 return result; 18133 } 18134 18135 uint64_t full_len = new_len + ((sentinel != nullptr) ? 1 : 0); 18136 out_array_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(full_len); 18137 // TODO handle the buf case here for an optimization 18138 expand_undef_array(ira->codegen, op1_array_val); 18139 expand_undef_array(ira->codegen, op2_array_val); 18140 18141 size_t next_index = 0; 18142 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { 18143 ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; 18144 copy_const_val(ira->codegen, elem_dest_val, &op1_array_val->data.x_array.data.s_none.elements[i]); 18145 elem_dest_val->parent.id = ConstParentIdArray; 18146 elem_dest_val->parent.data.p_array.array_val = out_array_val; 18147 elem_dest_val->parent.data.p_array.elem_index = next_index; 18148 } 18149 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { 18150 ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; 18151 copy_const_val(ira->codegen, elem_dest_val, &op2_array_val->data.x_array.data.s_none.elements[i]); 18152 elem_dest_val->parent.id = ConstParentIdArray; 18153 elem_dest_val->parent.data.p_array.array_val = out_array_val; 18154 elem_dest_val->parent.data.p_array.elem_index = next_index; 18155 } 18156 if (next_index < full_len) { 18157 ZigValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; 18158 copy_const_val(ira->codegen, elem_dest_val, sentinel); 18159 elem_dest_val->parent.id = ConstParentIdArray; 18160 elem_dest_val->parent.data.p_array.array_val = out_array_val; 18161 elem_dest_val->parent.data.p_array.elem_index = next_index; 18162 next_index += 1; 18163 } 18164 assert(next_index == full_len); 18165 18166 return result; 18167 } 18168 18169 static IrInstGen *ir_analyze_tuple_mult(IrAnalyze *ira, IrInst* source_instr, 18170 IrInstGen *op1, IrInstGen *op2) 18171 { 18172 Error err; 18173 ZigType *op1_type = op1->value->type; 18174 uint64_t op1_field_count = op1_type->data.structure.src_field_count; 18175 18176 uint64_t mult_amt; 18177 if (!ir_resolve_usize(ira, op2, &mult_amt)) 18178 return ira->codegen->invalid_inst_gen; 18179 18180 uint64_t new_field_count; 18181 if (mul_u64_overflow(op1_field_count, mult_amt, &new_field_count)) { 18182 ir_add_error(ira, source_instr, buf_sprintf("operation results in overflow")); 18183 return ira->codegen->invalid_inst_gen; 18184 } 18185 18186 Buf *bare_name = buf_alloc(); 18187 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), 18188 source_instr->scope, source_instr->source_node, bare_name); 18189 ZigType *new_type = get_partial_container_type(ira->codegen, source_instr->scope, 18190 ContainerKindStruct, source_instr->source_node, buf_ptr(name), bare_name, ContainerLayoutAuto); 18191 new_type->data.structure.special = StructSpecialInferredTuple; 18192 new_type->data.structure.resolve_status = ResolveStatusBeingInferred; 18193 new_type->data.structure.src_field_count = new_field_count; 18194 new_type->data.structure.fields = realloc_type_struct_fields( 18195 new_type->data.structure.fields, 0, new_field_count); 18196 18197 IrInstGen *new_struct_ptr = ir_resolve_result(ira, source_instr, no_result_loc(), 18198 new_type, nullptr, false, true); 18199 18200 for (uint64_t i = 0; i < new_field_count; i += 1) { 18201 TypeStructField *src_field = op1_type->data.structure.fields[i % op1_field_count]; 18202 TypeStructField *new_field = new_type->data.structure.fields[i]; 18203 18204 new_field->name = buf_sprintf("%" ZIG_PRI_u64, i); 18205 new_field->type_entry = src_field->type_entry; 18206 new_field->type_val = src_field->type_val; 18207 new_field->src_index = i; 18208 new_field->decl_node = src_field->decl_node; 18209 new_field->init_val = src_field->init_val; 18210 new_field->is_comptime = src_field->is_comptime; 18211 } 18212 18213 if ((err = type_resolve(ira->codegen, new_type, ResolveStatusZeroBitsKnown))) 18214 return ira->codegen->invalid_inst_gen; 18215 18216 ZigList<IrInstGen *> const_ptrs = {}; 18217 for (uint64_t i = 0; i < new_field_count; i += 1) { 18218 TypeStructField *src_field = op1_type->data.structure.fields[i % op1_field_count]; 18219 TypeStructField *dst_field = new_type->data.structure.fields[i]; 18220 18221 IrInstGen *field_value = ir_analyze_struct_value_field_value( 18222 ira, source_instr, op1, src_field); 18223 if (type_is_invalid(field_value->value->type)) 18224 return ira->codegen->invalid_inst_gen; 18225 18226 IrInstGen *dest_ptr = ir_analyze_struct_field_ptr( 18227 ira, source_instr, dst_field, new_struct_ptr, new_type, true); 18228 if (type_is_invalid(dest_ptr->value->type)) 18229 return ira->codegen->invalid_inst_gen; 18230 18231 if (instr_is_comptime(field_value)) { 18232 const_ptrs.append(dest_ptr); 18233 } 18234 18235 IrInstGen *store_ptr_inst = ir_analyze_store_ptr( 18236 ira, source_instr, dest_ptr, field_value, true); 18237 if (type_is_invalid(store_ptr_inst->value->type)) 18238 return ira->codegen->invalid_inst_gen; 18239 } 18240 18241 if (const_ptrs.length != new_field_count) { 18242 new_struct_ptr->value->special = ConstValSpecialRuntime; 18243 for (size_t i = 0; i < const_ptrs.length; i += 1) { 18244 IrInstGen *elem_result_loc = const_ptrs.at(i); 18245 assert(elem_result_loc->value->special == ConstValSpecialStatic); 18246 if (elem_result_loc->value->type->data.pointer.inferred_struct_field != nullptr) { 18247 // This field will be generated comptime; no need to do this. 18248 continue; 18249 } 18250 IrInstGen *deref = ir_get_deref(ira, &elem_result_loc->base, elem_result_loc, nullptr); 18251 if (!type_requires_comptime(ira->codegen, elem_result_loc->value->type->data.pointer.child_type)) { 18252 elem_result_loc->value->special = ConstValSpecialRuntime; 18253 } 18254 IrInstGen *store_ptr_inst = ir_analyze_store_ptr( 18255 ira, &elem_result_loc->base, elem_result_loc, deref, true); 18256 if (type_is_invalid(store_ptr_inst->value->type)) 18257 return ira->codegen->invalid_inst_gen; 18258 } 18259 } 18260 18261 const_ptrs.deinit(); 18262 18263 return ir_get_deref(ira, source_instr, new_struct_ptr, nullptr); 18264 } 18265 18266 static IrInstGen *ir_analyze_array_mult(IrAnalyze *ira, IrInstSrcBinOp *instruction) { 18267 IrInstGen *op1 = instruction->op1->child; 18268 if (type_is_invalid(op1->value->type)) 18269 return ira->codegen->invalid_inst_gen; 18270 18271 IrInstGen *op2 = instruction->op2->child; 18272 if (type_is_invalid(op2->value->type)) 18273 return ira->codegen->invalid_inst_gen; 18274 18275 bool want_ptr_to_array = false; 18276 ZigType *array_type; 18277 ZigValue *array_val; 18278 if (op1->value->type->id == ZigTypeIdArray) { 18279 array_type = op1->value->type; 18280 array_val = ir_resolve_const(ira, op1, UndefOk); 18281 if (array_val == nullptr) 18282 return ira->codegen->invalid_inst_gen; 18283 } else if (op1->value->type->id == ZigTypeIdPointer && 18284 op1->value->type->data.pointer.ptr_len == PtrLenSingle && 18285 op1->value->type->data.pointer.child_type->id == ZigTypeIdArray) 18286 { 18287 array_type = op1->value->type->data.pointer.child_type; 18288 IrInstGen *array_inst = ir_get_deref(ira, &op1->base, op1, nullptr); 18289 if (type_is_invalid(array_inst->value->type)) 18290 return ira->codegen->invalid_inst_gen; 18291 array_val = ir_resolve_const(ira, array_inst, UndefOk); 18292 if (array_val == nullptr) 18293 return ira->codegen->invalid_inst_gen; 18294 want_ptr_to_array = true; 18295 } else if (is_tuple(op1->value->type)) { 18296 return ir_analyze_tuple_mult(ira, &instruction->base.base, op1, op2); 18297 } else { 18298 ir_add_error(ira, &op1->base, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value->type->name))); 18299 return ira->codegen->invalid_inst_gen; 18300 } 18301 18302 uint64_t mult_amt; 18303 if (!ir_resolve_usize(ira, op2, &mult_amt)) 18304 return ira->codegen->invalid_inst_gen; 18305 18306 uint64_t old_array_len = array_type->data.array.len; 18307 uint64_t new_array_len; 18308 18309 if (mul_u64_overflow(old_array_len, mult_amt, &new_array_len)) { 18310 ir_add_error(ira, &instruction->base.base, buf_sprintf("operation results in overflow")); 18311 return ira->codegen->invalid_inst_gen; 18312 } 18313 18314 ZigType *child_type = array_type->data.array.child_type; 18315 ZigType *result_array_type = get_array_type(ira->codegen, child_type, new_array_len, 18316 array_type->data.array.sentinel); 18317 18318 IrInstGen *array_result; 18319 if (array_val->special == ConstValSpecialUndef || array_val->data.x_array.special == ConstArraySpecialUndef) { 18320 array_result = ir_const_undef(ira, &instruction->base.base, result_array_type); 18321 } else { 18322 array_result = ir_const(ira, &instruction->base.base, result_array_type); 18323 ZigValue *out_val = array_result->value; 18324 18325 switch (type_has_one_possible_value(ira->codegen, result_array_type)) { 18326 case OnePossibleValueInvalid: 18327 return ira->codegen->invalid_inst_gen; 18328 case OnePossibleValueYes: 18329 goto skip_computation; 18330 case OnePossibleValueNo: 18331 break; 18332 } 18333 18334 // TODO optimize the buf case 18335 expand_undef_array(ira->codegen, array_val); 18336 size_t extra_null_term = (array_type->data.array.sentinel != nullptr) ? 1 : 0; 18337 out_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(new_array_len + extra_null_term); 18338 18339 uint64_t i = 0; 18340 for (uint64_t x = 0; x < mult_amt; x += 1) { 18341 for (uint64_t y = 0; y < old_array_len; y += 1) { 18342 ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; 18343 copy_const_val(ira->codegen, elem_dest_val, &array_val->data.x_array.data.s_none.elements[y]); 18344 elem_dest_val->parent.id = ConstParentIdArray; 18345 elem_dest_val->parent.data.p_array.array_val = out_val; 18346 elem_dest_val->parent.data.p_array.elem_index = i; 18347 i += 1; 18348 } 18349 } 18350 assert(i == new_array_len); 18351 18352 if (array_type->data.array.sentinel != nullptr) { 18353 ZigValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; 18354 copy_const_val(ira->codegen, elem_dest_val, array_type->data.array.sentinel); 18355 elem_dest_val->parent.id = ConstParentIdArray; 18356 elem_dest_val->parent.data.p_array.array_val = out_val; 18357 elem_dest_val->parent.data.p_array.elem_index = i; 18358 i += 1; 18359 } 18360 } 18361 skip_computation: 18362 if (want_ptr_to_array) { 18363 return ir_get_ref(ira, &instruction->base.base, array_result, true, false); 18364 } else { 18365 return array_result; 18366 } 18367 } 18368 18369 static IrInstGen *ir_analyze_instruction_merge_err_sets(IrAnalyze *ira, 18370 IrInstSrcMergeErrSets *instruction) 18371 { 18372 ZigType *op1_type = ir_resolve_error_set_type(ira, &instruction->base.base, instruction->op1->child); 18373 if (type_is_invalid(op1_type)) 18374 return ira->codegen->invalid_inst_gen; 18375 18376 ZigType *op2_type = ir_resolve_error_set_type(ira, &instruction->base.base, instruction->op2->child); 18377 if (type_is_invalid(op2_type)) 18378 return ira->codegen->invalid_inst_gen; 18379 18380 if (!resolve_inferred_error_set(ira->codegen, op1_type, instruction->op1->child->base.source_node)) { 18381 return ira->codegen->invalid_inst_gen; 18382 } 18383 18384 if (!resolve_inferred_error_set(ira->codegen, op2_type, instruction->op2->child->base.source_node)) { 18385 return ira->codegen->invalid_inst_gen; 18386 } 18387 18388 if (type_is_global_error_set(op1_type) || 18389 type_is_global_error_set(op2_type)) 18390 { 18391 return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_global_error_set); 18392 } 18393 18394 size_t errors_count = ira->codegen->errors_by_index.length; 18395 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count); 18396 for (uint32_t i = 0, count = op1_type->data.error_set.err_count; i < count; i += 1) { 18397 ErrorTableEntry *error_entry = op1_type->data.error_set.errors[i]; 18398 assert(errors[error_entry->value] == nullptr); 18399 errors[error_entry->value] = error_entry; 18400 } 18401 ZigType *result_type = get_error_set_union(ira->codegen, errors, op1_type, op2_type, instruction->type_name); 18402 heap::c_allocator.deallocate(errors, errors_count); 18403 18404 return ir_const_type(ira, &instruction->base.base, result_type); 18405 } 18406 18407 18408 static IrInstGen *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstSrcBinOp *bin_op_instruction) { 18409 IrBinOp op_id = bin_op_instruction->op_id; 18410 switch (op_id) { 18411 case IrBinOpInvalid: 18412 zig_unreachable(); 18413 case IrBinOpBoolOr: 18414 case IrBinOpBoolAnd: 18415 return ir_analyze_bin_op_bool(ira, bin_op_instruction); 18416 case IrBinOpCmpEq: 18417 case IrBinOpCmpNotEq: 18418 case IrBinOpCmpLessThan: 18419 case IrBinOpCmpGreaterThan: 18420 case IrBinOpCmpLessOrEq: 18421 case IrBinOpCmpGreaterOrEq: 18422 return ir_analyze_bin_op_cmp(ira, bin_op_instruction); 18423 case IrBinOpBitShiftLeftLossy: 18424 case IrBinOpBitShiftLeftExact: 18425 case IrBinOpBitShiftRightLossy: 18426 case IrBinOpBitShiftRightExact: 18427 return ir_analyze_bit_shift(ira, bin_op_instruction); 18428 case IrBinOpBinOr: 18429 case IrBinOpBinXor: 18430 case IrBinOpBinAnd: 18431 case IrBinOpAdd: 18432 case IrBinOpAddWrap: 18433 case IrBinOpSub: 18434 case IrBinOpSubWrap: 18435 case IrBinOpMult: 18436 case IrBinOpMultWrap: 18437 case IrBinOpDivUnspecified: 18438 case IrBinOpDivTrunc: 18439 case IrBinOpDivFloor: 18440 case IrBinOpDivExact: 18441 case IrBinOpRemUnspecified: 18442 case IrBinOpRemRem: 18443 case IrBinOpRemMod: 18444 return ir_analyze_bin_op_math(ira, bin_op_instruction); 18445 case IrBinOpArrayCat: 18446 return ir_analyze_array_cat(ira, bin_op_instruction); 18447 case IrBinOpArrayMult: 18448 return ir_analyze_array_mult(ira, bin_op_instruction); 18449 } 18450 zig_unreachable(); 18451 } 18452 18453 static IrInstGen *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstSrcDeclVar *decl_var_instruction) { 18454 Error err; 18455 ZigVar *var = decl_var_instruction->var; 18456 18457 ZigType *explicit_type = nullptr; 18458 IrInstGen *var_type = nullptr; 18459 if (decl_var_instruction->var_type != nullptr) { 18460 var_type = decl_var_instruction->var_type->child; 18461 ZigType *proposed_type = ir_resolve_type(ira, var_type); 18462 explicit_type = validate_var_type(ira->codegen, var_type->base.source_node, proposed_type); 18463 if (type_is_invalid(explicit_type)) { 18464 var->var_type = ira->codegen->builtin_types.entry_invalid; 18465 return ira->codegen->invalid_inst_gen; 18466 } 18467 } 18468 18469 AstNode *source_node = decl_var_instruction->base.base.source_node; 18470 18471 bool is_comptime_var = ir_get_var_is_comptime(var); 18472 18473 bool var_class_requires_const = false; 18474 18475 IrInstGen *var_ptr = decl_var_instruction->ptr->child; 18476 // if this is null, a compiler error happened and did not initialize the variable. 18477 // if there are no compile errors there may be a missing ir_expr_wrap in pass1 IR generation. 18478 if (var_ptr == nullptr || type_is_invalid(var_ptr->value->type)) { 18479 ir_assert(var_ptr != nullptr || ira->codegen->errors.length != 0, &decl_var_instruction->base.base); 18480 var->var_type = ira->codegen->builtin_types.entry_invalid; 18481 return ira->codegen->invalid_inst_gen; 18482 } 18483 18484 // The ir_build_var_decl_src call is supposed to pass a pointer to the allocation, not an initialization value. 18485 ir_assert(var_ptr->value->type->id == ZigTypeIdPointer, &decl_var_instruction->base.base); 18486 18487 ZigType *result_type = var_ptr->value->type->data.pointer.child_type; 18488 if (type_is_invalid(result_type)) { 18489 result_type = ira->codegen->builtin_types.entry_invalid; 18490 } else if (result_type->id == ZigTypeIdUnreachable || result_type->id == ZigTypeIdOpaque) { 18491 zig_unreachable(); 18492 } 18493 18494 ZigValue *init_val = nullptr; 18495 if (instr_is_comptime(var_ptr) && var_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 18496 ZigValue *ptr_val = ir_resolve_const(ira, var_ptr, UndefBad); 18497 if (ptr_val == nullptr) 18498 return ira->codegen->invalid_inst_gen; 18499 18500 init_val = const_ptr_pointee(ira, ira->codegen, ptr_val, decl_var_instruction->base.base.source_node); 18501 if (init_val == nullptr) 18502 return ira->codegen->invalid_inst_gen; 18503 18504 if (is_comptime_var) { 18505 if (var->gen_is_const) { 18506 var->const_value = init_val; 18507 } else { 18508 var->const_value = ira->codegen->pass1_arena->create<ZigValue>(); 18509 copy_const_val(ira->codegen, var->const_value, init_val); 18510 } 18511 } 18512 } 18513 18514 switch (type_requires_comptime(ira->codegen, result_type)) { 18515 case ReqCompTimeInvalid: 18516 result_type = ira->codegen->builtin_types.entry_invalid; 18517 break; 18518 case ReqCompTimeYes: 18519 var_class_requires_const = true; 18520 if (!var->gen_is_const && !is_comptime_var) { 18521 ir_add_error_node(ira, source_node, 18522 buf_sprintf("variable of type '%s' must be const or comptime", 18523 buf_ptr(&result_type->name))); 18524 result_type = ira->codegen->builtin_types.entry_invalid; 18525 } 18526 break; 18527 case ReqCompTimeNo: 18528 if (init_val != nullptr && value_is_comptime(init_val)) { 18529 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 18530 decl_var_instruction->base.base.source_node, init_val, UndefOk))) 18531 { 18532 result_type = ira->codegen->builtin_types.entry_invalid; 18533 } else if (init_val->type->id == ZigTypeIdFn && 18534 init_val->special != ConstValSpecialUndef && 18535 init_val->data.x_ptr.special == ConstPtrSpecialFunction && 18536 init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) 18537 { 18538 var_class_requires_const = true; 18539 if (!var->src_is_const && !is_comptime_var) { 18540 ErrorMsg *msg = ir_add_error_node(ira, source_node, 18541 buf_sprintf("functions marked inline must be stored in const or comptime var")); 18542 AstNode *proto_node = init_val->data.x_ptr.data.fn.fn_entry->proto_node; 18543 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); 18544 result_type = ira->codegen->builtin_types.entry_invalid; 18545 } 18546 } 18547 } 18548 break; 18549 } 18550 18551 while (var->next_var != nullptr) { 18552 var = var->next_var; 18553 } 18554 18555 // This must be done after possibly creating a new variable above 18556 var->ref_count = 0; 18557 18558 var->ptr_instruction = var_ptr; 18559 var->var_type = result_type; 18560 assert(var->var_type); 18561 18562 if (type_is_invalid(result_type)) { 18563 return ir_const_void(ira, &decl_var_instruction->base.base); 18564 } 18565 18566 if (decl_var_instruction->align_value == nullptr) { 18567 if ((err = type_resolve(ira->codegen, result_type, ResolveStatusAlignmentKnown))) { 18568 var->var_type = ira->codegen->builtin_types.entry_invalid; 18569 return ir_const_void(ira, &decl_var_instruction->base.base); 18570 } 18571 var->align_bytes = get_ptr_align(ira->codegen, var_ptr->value->type); 18572 } else { 18573 if (!ir_resolve_align(ira, decl_var_instruction->align_value->child, nullptr, &var->align_bytes)) { 18574 var->var_type = ira->codegen->builtin_types.entry_invalid; 18575 } 18576 } 18577 18578 if (init_val != nullptr && value_is_comptime(init_val)) { 18579 // Resolve ConstPtrMutInfer 18580 if (var->gen_is_const) { 18581 var_ptr->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 18582 } else if (is_comptime_var) { 18583 var_ptr->value->data.x_ptr.mut = ConstPtrMutComptimeVar; 18584 } else { 18585 // we need a runtime ptr but we have a comptime val. 18586 // since it's a comptime val there are no instructions for it. 18587 // we memcpy the init value here 18588 IrInstGen *deref = ir_get_deref(ira, &var_ptr->base, var_ptr, nullptr); 18589 if (type_is_invalid(deref->value->type)) { 18590 var->var_type = ira->codegen->builtin_types.entry_invalid; 18591 return ira->codegen->invalid_inst_gen; 18592 } 18593 // If this assertion trips, something is wrong with the IR instructions, because 18594 // we expected the above deref to return a constant value, but it created a runtime 18595 // instruction. 18596 assert(deref->value->special != ConstValSpecialRuntime); 18597 var_ptr->value->special = ConstValSpecialRuntime; 18598 ir_analyze_store_ptr(ira, &var_ptr->base, var_ptr, deref, false); 18599 } 18600 if (instr_is_comptime(var_ptr) && (is_comptime_var || (var_class_requires_const && var->gen_is_const))) { 18601 return ir_const_void(ira, &decl_var_instruction->base.base); 18602 } 18603 } else if (is_comptime_var) { 18604 ir_add_error(ira, &decl_var_instruction->base.base, 18605 buf_sprintf("cannot store runtime value in compile time variable")); 18606 var->var_type = ira->codegen->builtin_types.entry_invalid; 18607 return ira->codegen->invalid_inst_gen; 18608 } 18609 18610 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 18611 if (fn_entry) 18612 fn_entry->variable_list.append(var); 18613 18614 return ir_build_var_decl_gen(ira, &decl_var_instruction->base.base, var, var_ptr); 18615 } 18616 18617 static IrInstGen *ir_analyze_instruction_export(IrAnalyze *ira, IrInstSrcExport *instruction) { 18618 IrInstGen *target = instruction->target->child; 18619 if (type_is_invalid(target->value->type)) 18620 return ira->codegen->invalid_inst_gen; 18621 18622 IrInstGen *options = instruction->options->child; 18623 if (type_is_invalid(options->value->type)) 18624 return ira->codegen->invalid_inst_gen; 18625 18626 ZigType *options_type = options->value->type; 18627 assert(options_type->id == ZigTypeIdStruct); 18628 18629 TypeStructField *name_field = find_struct_type_field(options_type, buf_create_from_str("name")); 18630 ir_assert(name_field != nullptr, &instruction->base.base); 18631 IrInstGen *name_inst = ir_analyze_struct_value_field_value(ira, &instruction->base.base, options, name_field); 18632 if (type_is_invalid(name_inst->value->type)) 18633 return ira->codegen->invalid_inst_gen; 18634 18635 TypeStructField *linkage_field = find_struct_type_field(options_type, buf_create_from_str("linkage")); 18636 ir_assert(linkage_field != nullptr, &instruction->base.base); 18637 IrInstGen *linkage_inst = ir_analyze_struct_value_field_value(ira, &instruction->base.base, options, linkage_field); 18638 if (type_is_invalid(linkage_inst->value->type)) 18639 return ira->codegen->invalid_inst_gen; 18640 18641 TypeStructField *section_field = find_struct_type_field(options_type, buf_create_from_str("section")); 18642 ir_assert(section_field != nullptr, &instruction->base.base); 18643 IrInstGen *section_inst = ir_analyze_struct_value_field_value(ira, &instruction->base.base, options, section_field); 18644 if (type_is_invalid(section_inst->value->type)) 18645 return ira->codegen->invalid_inst_gen; 18646 18647 // The `section` field is optional, we have to unwrap it first 18648 IrInstGen *non_null_check = ir_analyze_test_non_null(ira, &instruction->base.base, section_inst); 18649 bool is_non_null; 18650 if (!ir_resolve_bool(ira, non_null_check, &is_non_null)) 18651 return ira->codegen->invalid_inst_gen; 18652 18653 IrInstGen *section_str_inst = nullptr; 18654 if (is_non_null) { 18655 section_str_inst = ir_analyze_optional_value_payload_value(ira, &instruction->base.base, section_inst, false); 18656 if (type_is_invalid(section_str_inst->value->type)) 18657 return ira->codegen->invalid_inst_gen; 18658 } 18659 18660 // Resolve all the comptime values 18661 Buf *symbol_name = ir_resolve_str(ira, name_inst); 18662 if (!symbol_name) 18663 return ira->codegen->invalid_inst_gen; 18664 18665 if (buf_len(symbol_name) < 1) { 18666 ir_add_error(ira, &name_inst->base, 18667 buf_sprintf("exported symbol name cannot be empty")); 18668 return ira->codegen->invalid_inst_gen; 18669 } 18670 18671 GlobalLinkageId global_linkage_id; 18672 if (!ir_resolve_global_linkage(ira, linkage_inst, &global_linkage_id)) 18673 return ira->codegen->invalid_inst_gen; 18674 18675 Buf *section_name = nullptr; 18676 if (section_str_inst != nullptr && !(section_name = ir_resolve_str(ira, section_str_inst))) 18677 return ira->codegen->invalid_inst_gen; 18678 18679 // TODO: This function needs to be audited. 18680 // It's not clear how all the different types are supposed to be handled. 18681 // Need comprehensive tests for exporting one thing in one file and declaring an extern var 18682 // in another file. 18683 TldFn *tld_fn = heap::c_allocator.create<TldFn>(); 18684 tld_fn->base.id = TldIdFn; 18685 tld_fn->base.source_node = instruction->base.base.source_node; 18686 18687 auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, &tld_fn->base); 18688 if (entry) { 18689 AstNode *other_export_node = entry->value->source_node; 18690 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 18691 buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name))); 18692 add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here")); 18693 return ira->codegen->invalid_inst_gen; 18694 } 18695 18696 Error err; 18697 bool want_var_export = false; 18698 switch (target->value->type->id) { 18699 case ZigTypeIdInvalid: 18700 case ZigTypeIdUnreachable: 18701 zig_unreachable(); 18702 case ZigTypeIdFn: { 18703 assert(target->value->data.x_ptr.special == ConstPtrSpecialFunction); 18704 ZigFn *fn_entry = target->value->data.x_ptr.data.fn.fn_entry; 18705 tld_fn->fn_entry = fn_entry; 18706 CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc; 18707 switch (cc) { 18708 case CallingConventionUnspecified: { 18709 ErrorMsg *msg = ir_add_error(ira, &target->base, 18710 buf_sprintf("exported function must specify calling convention")); 18711 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 18712 } break; 18713 case CallingConventionAsync: { 18714 ErrorMsg *msg = ir_add_error(ira, &target->base, 18715 buf_sprintf("exported function cannot be async")); 18716 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 18717 } break; 18718 case CallingConventionC: 18719 case CallingConventionCold: 18720 case CallingConventionNaked: 18721 case CallingConventionInterrupt: 18722 case CallingConventionSignal: 18723 case CallingConventionStdcall: 18724 case CallingConventionFastcall: 18725 case CallingConventionVectorcall: 18726 case CallingConventionThiscall: 18727 case CallingConventionAPCS: 18728 case CallingConventionAAPCS: 18729 case CallingConventionAAPCSVFP: 18730 add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc); 18731 fn_entry->section_name = section_name; 18732 break; 18733 } 18734 } break; 18735 case ZigTypeIdStruct: 18736 if (is_slice(target->value->type)) { 18737 ir_add_error(ira, &target->base, 18738 buf_sprintf("unable to export value of type '%s'", buf_ptr(&target->value->type->name))); 18739 } else if (target->value->type->data.structure.layout != ContainerLayoutExtern) { 18740 ErrorMsg *msg = ir_add_error(ira, &target->base, 18741 buf_sprintf("exported struct value must be declared extern")); 18742 add_error_note(ira->codegen, msg, target->value->type->data.structure.decl_node, buf_sprintf("declared here")); 18743 } else { 18744 want_var_export = true; 18745 } 18746 break; 18747 case ZigTypeIdUnion: 18748 if (target->value->type->data.unionation.layout != ContainerLayoutExtern) { 18749 ErrorMsg *msg = ir_add_error(ira, &target->base, 18750 buf_sprintf("exported union value must be declared extern")); 18751 add_error_note(ira->codegen, msg, target->value->type->data.unionation.decl_node, buf_sprintf("declared here")); 18752 } else { 18753 want_var_export = true; 18754 } 18755 break; 18756 case ZigTypeIdEnum: 18757 if (target->value->type->data.enumeration.layout != ContainerLayoutExtern) { 18758 ErrorMsg *msg = ir_add_error(ira, &target->base, 18759 buf_sprintf("exported enum value must be declared extern")); 18760 add_error_note(ira->codegen, msg, target->value->type->data.enumeration.decl_node, buf_sprintf("declared here")); 18761 } else { 18762 want_var_export = true; 18763 } 18764 break; 18765 case ZigTypeIdArray: { 18766 bool ok_type; 18767 if ((err = type_allowed_in_extern(ira->codegen, target->value->type->data.array.child_type, &ok_type))) 18768 return ira->codegen->invalid_inst_gen; 18769 18770 if (!ok_type) { 18771 ir_add_error(ira, &target->base, 18772 buf_sprintf("array element type '%s' not extern-compatible", 18773 buf_ptr(&target->value->type->data.array.child_type->name))); 18774 } else { 18775 want_var_export = true; 18776 } 18777 break; 18778 } 18779 case ZigTypeIdMetaType: { 18780 ZigType *type_value = target->value->data.x_type; 18781 switch (type_value->id) { 18782 case ZigTypeIdInvalid: 18783 zig_unreachable(); 18784 case ZigTypeIdStruct: 18785 if (is_slice(type_value)) { 18786 ir_add_error(ira, &target->base, 18787 buf_sprintf("unable to export type '%s'", buf_ptr(&type_value->name))); 18788 } else if (type_value->data.structure.layout != ContainerLayoutExtern) { 18789 ErrorMsg *msg = ir_add_error(ira, &target->base, 18790 buf_sprintf("exported struct must be declared extern")); 18791 add_error_note(ira->codegen, msg, type_value->data.structure.decl_node, buf_sprintf("declared here")); 18792 } 18793 break; 18794 case ZigTypeIdUnion: 18795 if (type_value->data.unionation.layout != ContainerLayoutExtern) { 18796 ErrorMsg *msg = ir_add_error(ira, &target->base, 18797 buf_sprintf("exported union must be declared extern")); 18798 add_error_note(ira->codegen, msg, type_value->data.unionation.decl_node, buf_sprintf("declared here")); 18799 } 18800 break; 18801 case ZigTypeIdEnum: 18802 if (type_value->data.enumeration.layout != ContainerLayoutExtern) { 18803 ErrorMsg *msg = ir_add_error(ira, &target->base, 18804 buf_sprintf("exported enum must be declared extern")); 18805 add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here")); 18806 } 18807 break; 18808 case ZigTypeIdFn: { 18809 if (type_value->data.fn.fn_type_id.cc == CallingConventionUnspecified) { 18810 ir_add_error(ira, &target->base, 18811 buf_sprintf("exported function type must specify calling convention")); 18812 } 18813 } break; 18814 case ZigTypeIdInt: 18815 case ZigTypeIdFloat: 18816 case ZigTypeIdPointer: 18817 case ZigTypeIdArray: 18818 case ZigTypeIdBool: 18819 case ZigTypeIdVector: 18820 break; 18821 case ZigTypeIdMetaType: 18822 case ZigTypeIdVoid: 18823 case ZigTypeIdUnreachable: 18824 case ZigTypeIdComptimeFloat: 18825 case ZigTypeIdComptimeInt: 18826 case ZigTypeIdEnumLiteral: 18827 case ZigTypeIdUndefined: 18828 case ZigTypeIdNull: 18829 case ZigTypeIdOptional: 18830 case ZigTypeIdErrorUnion: 18831 case ZigTypeIdErrorSet: 18832 case ZigTypeIdBoundFn: 18833 case ZigTypeIdOpaque: 18834 case ZigTypeIdFnFrame: 18835 case ZigTypeIdAnyFrame: 18836 ir_add_error(ira, &target->base, 18837 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name))); 18838 break; 18839 } 18840 } break; 18841 case ZigTypeIdInt: 18842 want_var_export = true; 18843 break; 18844 case ZigTypeIdVoid: 18845 case ZigTypeIdBool: 18846 case ZigTypeIdFloat: 18847 case ZigTypeIdPointer: 18848 case ZigTypeIdComptimeFloat: 18849 case ZigTypeIdComptimeInt: 18850 case ZigTypeIdUndefined: 18851 case ZigTypeIdNull: 18852 case ZigTypeIdOptional: 18853 case ZigTypeIdErrorUnion: 18854 case ZigTypeIdErrorSet: 18855 case ZigTypeIdVector: 18856 zig_panic("TODO export const value of type %s", buf_ptr(&target->value->type->name)); 18857 case ZigTypeIdBoundFn: 18858 case ZigTypeIdOpaque: 18859 case ZigTypeIdEnumLiteral: 18860 case ZigTypeIdFnFrame: 18861 case ZigTypeIdAnyFrame: 18862 ir_add_error(ira, &target->base, 18863 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value->type->name))); 18864 break; 18865 } 18866 18867 // TODO audit the various ways to use @export 18868 if (want_var_export && target->id == IrInstGenIdLoadPtr) { 18869 IrInstGenLoadPtr *load_ptr = reinterpret_cast<IrInstGenLoadPtr *>(target); 18870 if (load_ptr->ptr->id == IrInstGenIdVarPtr) { 18871 IrInstGenVarPtr *var_ptr = reinterpret_cast<IrInstGenVarPtr *>(load_ptr->ptr); 18872 ZigVar *var = var_ptr->var; 18873 add_var_export(ira->codegen, var, buf_ptr(symbol_name), global_linkage_id); 18874 var->section_name = section_name; 18875 } 18876 } 18877 18878 return ir_const_void(ira, &instruction->base.base); 18879 } 18880 18881 static bool exec_has_err_ret_trace(CodeGen *g, IrExecutableSrc *exec) { 18882 ZigFn *fn_entry = exec_fn_entry(exec); 18883 return fn_entry != nullptr && fn_entry->calls_or_awaits_errorable_fn && g->have_err_ret_tracing; 18884 } 18885 18886 static IrInstGen *ir_analyze_instruction_error_return_trace(IrAnalyze *ira, 18887 IrInstSrcErrorReturnTrace *instruction) 18888 { 18889 ZigType *ptr_to_stack_trace_type = get_pointer_to_type(ira->codegen, get_stack_trace_type(ira->codegen), false); 18890 if (instruction->optional == IrInstErrorReturnTraceNull) { 18891 ZigType *optional_type = get_optional_type(ira->codegen, ptr_to_stack_trace_type); 18892 if (!exec_has_err_ret_trace(ira->codegen, ira->old_irb.exec)) { 18893 IrInstGen *result = ir_const(ira, &instruction->base.base, optional_type); 18894 ZigValue *out_val = result->value; 18895 assert(get_src_ptr_type(optional_type) != nullptr); 18896 out_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 18897 out_val->data.x_ptr.data.hard_coded_addr.addr = 0; 18898 return result; 18899 } 18900 return ir_build_error_return_trace_gen(ira, instruction->base.base.scope, 18901 instruction->base.base.source_node, instruction->optional, optional_type); 18902 } else { 18903 assert(ira->codegen->have_err_ret_tracing); 18904 return ir_build_error_return_trace_gen(ira, instruction->base.base.scope, 18905 instruction->base.base.source_node, instruction->optional, ptr_to_stack_trace_type); 18906 } 18907 } 18908 18909 static IrInstGen *ir_analyze_instruction_error_union(IrAnalyze *ira, IrInstSrcErrorUnion *instruction) { 18910 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); 18911 result->value->special = ConstValSpecialLazy; 18912 18913 LazyValueErrUnionType *lazy_err_union_type = heap::c_allocator.create<LazyValueErrUnionType>(); 18914 lazy_err_union_type->ira = ira; ira_ref(ira); 18915 result->value->data.x_lazy = &lazy_err_union_type->base; 18916 lazy_err_union_type->base.id = LazyValueIdErrUnionType; 18917 18918 lazy_err_union_type->err_set_type = instruction->err_set->child; 18919 if (ir_resolve_type_lazy(ira, lazy_err_union_type->err_set_type) == nullptr) 18920 return ira->codegen->invalid_inst_gen; 18921 18922 lazy_err_union_type->payload_type = instruction->payload->child; 18923 if (ir_resolve_type_lazy(ira, lazy_err_union_type->payload_type) == nullptr) 18924 return ira->codegen->invalid_inst_gen; 18925 18926 return result; 18927 } 18928 18929 static IrInstGen *ir_analyze_alloca(IrAnalyze *ira, IrInst *source_inst, ZigType *var_type, 18930 uint32_t align, const char *name_hint, bool force_comptime) 18931 { 18932 Error err; 18933 18934 ZigValue *pointee = ira->codegen->pass1_arena->create<ZigValue>(); 18935 pointee->special = ConstValSpecialUndef; 18936 pointee->llvm_align = align; 18937 18938 IrInstGenAlloca *result = ir_build_alloca_gen(ira, source_inst, align, name_hint); 18939 result->base.value->special = ConstValSpecialStatic; 18940 result->base.value->data.x_ptr.special = ConstPtrSpecialRef; 18941 result->base.value->data.x_ptr.mut = force_comptime ? ConstPtrMutComptimeVar : ConstPtrMutInfer; 18942 result->base.value->data.x_ptr.data.ref.pointee = pointee; 18943 18944 bool var_type_has_bits; 18945 if ((err = type_has_bits2(ira->codegen, var_type, &var_type_has_bits))) 18946 return ira->codegen->invalid_inst_gen; 18947 if (align != 0) { 18948 if ((err = type_resolve(ira->codegen, var_type, ResolveStatusAlignmentKnown))) 18949 return ira->codegen->invalid_inst_gen; 18950 if (!var_type_has_bits) { 18951 ir_add_error(ira, source_inst, 18952 buf_sprintf("variable '%s' of zero-bit type '%s' has no in-memory representation, it cannot be aligned", 18953 name_hint, buf_ptr(&var_type->name))); 18954 return ira->codegen->invalid_inst_gen; 18955 } 18956 } 18957 assert(result->base.value->data.x_ptr.special != ConstPtrSpecialInvalid); 18958 18959 pointee->type = var_type; 18960 result->base.value->type = get_pointer_to_type_extra(ira->codegen, var_type, false, false, 18961 PtrLenSingle, align, 0, 0, false); 18962 18963 if (!force_comptime) { 18964 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 18965 if (fn_entry != nullptr) { 18966 fn_entry->alloca_gen_list.append(result); 18967 } 18968 } 18969 return &result->base; 18970 } 18971 18972 static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, IrInst *suspend_source_instr, 18973 ResultLoc *result_loc) 18974 { 18975 switch (result_loc->id) { 18976 case ResultLocIdInvalid: 18977 case ResultLocIdPeerParent: 18978 zig_unreachable(); 18979 case ResultLocIdNone: 18980 case ResultLocIdVar: 18981 case ResultLocIdBitCast: 18982 case ResultLocIdCast: 18983 return nullptr; 18984 case ResultLocIdInstruction: 18985 return result_loc->source_instruction->child->value->type; 18986 case ResultLocIdReturn: 18987 return ira->explicit_return_type; 18988 case ResultLocIdPeer: 18989 return reinterpret_cast<ResultLocPeer*>(result_loc)->parent->resolved_type; 18990 } 18991 zig_unreachable(); 18992 } 18993 18994 static bool type_can_bit_cast(ZigType *t) { 18995 switch (t->id) { 18996 case ZigTypeIdInvalid: 18997 zig_unreachable(); 18998 case ZigTypeIdMetaType: 18999 case ZigTypeIdOpaque: 19000 case ZigTypeIdBoundFn: 19001 case ZigTypeIdUnreachable: 19002 case ZigTypeIdComptimeFloat: 19003 case ZigTypeIdComptimeInt: 19004 case ZigTypeIdEnumLiteral: 19005 case ZigTypeIdUndefined: 19006 case ZigTypeIdNull: 19007 case ZigTypeIdPointer: 19008 return false; 19009 default: 19010 // TODO list these types out explicitly, there are probably some other invalid ones here 19011 return true; 19012 } 19013 } 19014 19015 static void set_up_result_loc_for_inferred_comptime(IrAnalyze *ira, IrInstGen *ptr) { 19016 ZigValue *undef_child = ira->codegen->pass1_arena->create<ZigValue>(); 19017 undef_child->type = ptr->value->type->data.pointer.child_type; 19018 undef_child->special = ConstValSpecialUndef; 19019 ptr->value->special = ConstValSpecialStatic; 19020 ptr->value->data.x_ptr.mut = ConstPtrMutInfer; 19021 ptr->value->data.x_ptr.special = ConstPtrSpecialRef; 19022 ptr->value->data.x_ptr.data.ref.pointee = undef_child; 19023 } 19024 19025 static Error ir_result_has_type(IrAnalyze *ira, ResultLoc *result_loc, bool *out) { 19026 switch (result_loc->id) { 19027 case ResultLocIdInvalid: 19028 case ResultLocIdPeerParent: 19029 zig_unreachable(); 19030 case ResultLocIdNone: 19031 case ResultLocIdPeer: 19032 *out = false; 19033 return ErrorNone; 19034 case ResultLocIdReturn: 19035 case ResultLocIdInstruction: 19036 case ResultLocIdBitCast: 19037 *out = true; 19038 return ErrorNone; 19039 case ResultLocIdCast: { 19040 ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); 19041 ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); 19042 if (type_is_invalid(dest_type)) 19043 return ErrorSemanticAnalyzeFail; 19044 *out = (dest_type != ira->codegen->builtin_types.entry_var); 19045 return ErrorNone; 19046 } 19047 case ResultLocIdVar: 19048 *out = reinterpret_cast<ResultLocVar *>(result_loc)->var->decl_node->data.variable_declaration.type != nullptr; 19049 return ErrorNone; 19050 } 19051 zig_unreachable(); 19052 } 19053 19054 static IrInstGen *ir_resolve_no_result_loc(IrAnalyze *ira, IrInst *suspend_source_instr, 19055 ResultLoc *result_loc, ZigType *value_type) 19056 { 19057 if (type_is_invalid(value_type)) 19058 return ira->codegen->invalid_inst_gen; 19059 IrInstGenAlloca *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, ""); 19060 alloca_gen->base.value->type = get_pointer_to_type_extra(ira->codegen, value_type, false, false, 19061 PtrLenSingle, 0, 0, 0, false); 19062 set_up_result_loc_for_inferred_comptime(ira, &alloca_gen->base); 19063 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 19064 if (fn_entry != nullptr && get_scope_typeof(suspend_source_instr->scope) == nullptr) { 19065 fn_entry->alloca_gen_list.append(alloca_gen); 19066 } 19067 result_loc->written = true; 19068 result_loc->resolved_loc = &alloca_gen->base; 19069 return result_loc->resolved_loc; 19070 } 19071 19072 static bool result_loc_is_discard(ResultLoc *result_loc_pass1) { 19073 if (result_loc_pass1->id == ResultLocIdInstruction && 19074 result_loc_pass1->source_instruction->id == IrInstSrcIdConst) 19075 { 19076 IrInstSrcConst *const_inst = reinterpret_cast<IrInstSrcConst *>(result_loc_pass1->source_instruction); 19077 if (value_is_comptime(const_inst->value) && 19078 const_inst->value->type->id == ZigTypeIdPointer && 19079 const_inst->value->data.x_ptr.special == ConstPtrSpecialDiscard) 19080 { 19081 return true; 19082 } 19083 } 19084 return false; 19085 } 19086 19087 // when calling this function, at the callsite must check for result type noreturn and propagate it up 19088 static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_instr, 19089 ResultLoc *result_loc, ZigType *value_type, IrInstGen *value, bool force_runtime, 19090 bool allow_discard) 19091 { 19092 Error err; 19093 if (result_loc->resolved_loc != nullptr) { 19094 // allow to redo the result location if the value is known and comptime and the previous one isn't 19095 if (value == nullptr || !instr_is_comptime(value) || instr_is_comptime(result_loc->resolved_loc)) { 19096 return result_loc->resolved_loc; 19097 } 19098 } 19099 result_loc->gen_instruction = value; 19100 result_loc->implicit_elem_type = value_type; 19101 switch (result_loc->id) { 19102 case ResultLocIdInvalid: 19103 case ResultLocIdPeerParent: 19104 zig_unreachable(); 19105 case ResultLocIdNone: { 19106 if (value != nullptr) { 19107 return nullptr; 19108 } 19109 // need to return a result location and don't have one. use a stack allocation 19110 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type); 19111 } 19112 case ResultLocIdVar: { 19113 ResultLocVar *result_loc_var = reinterpret_cast<ResultLocVar *>(result_loc); 19114 assert(result_loc->source_instruction->id == IrInstSrcIdAlloca); 19115 IrInstSrcAlloca *alloca_src = reinterpret_cast<IrInstSrcAlloca *>(result_loc->source_instruction); 19116 19117 ZigVar *var = result_loc_var->var; 19118 if (var->var_type != nullptr && !ir_get_var_is_comptime(var)) { 19119 // This is at least the second time we've seen this variable declaration during analysis. 19120 // This means that this is actually a different variable due to, e.g. an inline while loop. 19121 // We make a new variable so that it can hold a different type, and so the debug info can 19122 // be distinct. 19123 ZigVar *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope, 19124 buf_create_from_str(var->name), var->src_is_const, var->gen_is_const, 19125 var->shadowable, var->is_comptime, true); 19126 new_var->align_bytes = var->align_bytes; 19127 19128 var->next_var = new_var; 19129 var = new_var; 19130 } 19131 if (value_type->id == ZigTypeIdUnreachable || value_type->id == ZigTypeIdOpaque) { 19132 ir_add_error(ira, &result_loc->source_instruction->base, 19133 buf_sprintf("variable of type '%s' not allowed", buf_ptr(&value_type->name))); 19134 return ira->codegen->invalid_inst_gen; 19135 } 19136 if (alloca_src->base.child == nullptr || var->ptr_instruction == nullptr) { 19137 bool force_comptime; 19138 if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime)) 19139 return ira->codegen->invalid_inst_gen; 19140 uint32_t align = 0; 19141 if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, nullptr, &align)) { 19142 return ira->codegen->invalid_inst_gen; 19143 } 19144 IrInstGen *alloca_gen = ir_analyze_alloca(ira, &result_loc->source_instruction->base, value_type, 19145 align, alloca_src->name_hint, force_comptime); 19146 if (force_runtime) { 19147 alloca_gen->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; 19148 alloca_gen->value->special = ConstValSpecialRuntime; 19149 } 19150 if (alloca_src->base.child != nullptr && !result_loc->written) { 19151 alloca_src->base.child->base.ref_count = 0; 19152 } 19153 alloca_src->base.child = alloca_gen; 19154 var->ptr_instruction = alloca_gen; 19155 } 19156 result_loc->written = true; 19157 result_loc->resolved_loc = alloca_src->base.child; 19158 return alloca_src->base.child; 19159 } 19160 case ResultLocIdInstruction: { 19161 result_loc->written = true; 19162 result_loc->resolved_loc = result_loc->source_instruction->child; 19163 return result_loc->resolved_loc; 19164 } 19165 case ResultLocIdReturn: { 19166 if (value != nullptr) { 19167 reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = true; 19168 ira->src_implicit_return_type_list.append(value); 19169 } 19170 result_loc->written = true; 19171 result_loc->resolved_loc = ira->return_ptr; 19172 return result_loc->resolved_loc; 19173 } 19174 case ResultLocIdPeer: { 19175 ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(result_loc); 19176 ResultLocPeerParent *peer_parent = result_peer->parent; 19177 19178 if (peer_parent->peers.length == 1) { 19179 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 19180 value_type, value, force_runtime, true); 19181 result_peer->suspend_pos.basic_block_index = SIZE_MAX; 19182 result_peer->suspend_pos.instruction_index = SIZE_MAX; 19183 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 19184 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 19185 { 19186 return parent_result_loc; 19187 } 19188 result_loc->written = true; 19189 result_loc->resolved_loc = parent_result_loc; 19190 return result_loc->resolved_loc; 19191 } 19192 19193 bool is_condition_comptime; 19194 if (!ir_resolve_comptime(ira, peer_parent->is_comptime->child, &is_condition_comptime)) 19195 return ira->codegen->invalid_inst_gen; 19196 if (is_condition_comptime) { 19197 peer_parent->skipped = true; 19198 return ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 19199 value_type, value, force_runtime, true); 19200 } 19201 bool peer_parent_has_type; 19202 if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) 19203 return ira->codegen->invalid_inst_gen; 19204 if (peer_parent_has_type) { 19205 peer_parent->skipped = true; 19206 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 19207 value_type, value, force_runtime || !is_condition_comptime, true); 19208 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 19209 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 19210 { 19211 return parent_result_loc; 19212 } 19213 peer_parent->parent->written = true; 19214 result_loc->written = true; 19215 result_loc->resolved_loc = parent_result_loc; 19216 return result_loc->resolved_loc; 19217 } 19218 19219 if (peer_parent->resolved_type == nullptr) { 19220 if (peer_parent->end_bb->suspend_instruction_ref == nullptr) { 19221 peer_parent->end_bb->suspend_instruction_ref = suspend_source_instr; 19222 } 19223 IrInstGen *unreach_inst = ira_suspend(ira, suspend_source_instr, result_peer->next_bb, 19224 &result_peer->suspend_pos); 19225 if (result_peer->next_bb == nullptr) { 19226 ir_start_next_bb(ira); 19227 } 19228 return unreach_inst; 19229 } 19230 19231 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent, 19232 peer_parent->resolved_type, nullptr, force_runtime, true); 19233 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 19234 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 19235 { 19236 return parent_result_loc; 19237 } 19238 // because is_condition_comptime is false, we mark this a runtime pointer 19239 parent_result_loc->value->special = ConstValSpecialRuntime; 19240 result_loc->written = true; 19241 result_loc->resolved_loc = parent_result_loc; 19242 return result_loc->resolved_loc; 19243 } 19244 case ResultLocIdCast: { 19245 ResultLocCast *result_cast = reinterpret_cast<ResultLocCast *>(result_loc); 19246 ZigType *dest_type = ir_resolve_type(ira, result_cast->base.source_instruction->child); 19247 if (type_is_invalid(dest_type)) 19248 return ira->codegen->invalid_inst_gen; 19249 19250 if (dest_type == ira->codegen->builtin_types.entry_var) { 19251 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type); 19252 } 19253 19254 IrInstGen *casted_value; 19255 if (value != nullptr) { 19256 casted_value = ir_implicit_cast2(ira, suspend_source_instr, value, dest_type); 19257 if (type_is_invalid(casted_value->value->type)) 19258 return ira->codegen->invalid_inst_gen; 19259 dest_type = casted_value->value->type; 19260 } else { 19261 casted_value = nullptr; 19262 } 19263 19264 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent, 19265 dest_type, casted_value, force_runtime, true); 19266 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 19267 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 19268 { 19269 return parent_result_loc; 19270 } 19271 19272 ZigType *parent_ptr_type = parent_result_loc->value->type; 19273 assert(parent_ptr_type->id == ZigTypeIdPointer); 19274 19275 if ((err = type_resolve(ira->codegen, parent_ptr_type->data.pointer.child_type, 19276 ResolveStatusAlignmentKnown))) 19277 { 19278 return ira->codegen->invalid_inst_gen; 19279 } 19280 uint64_t parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); 19281 if ((err = type_resolve(ira->codegen, value_type, ResolveStatusAlignmentKnown))) { 19282 return ira->codegen->invalid_inst_gen; 19283 } 19284 if (!type_has_bits(ira->codegen, value_type)) { 19285 parent_ptr_align = 0; 19286 } 19287 // If we're casting from a sentinel-terminated array to a non-sentinel-terminated array, 19288 // we actually need the result location pointer to *not* have a sentinel. Otherwise the generated 19289 // memcpy will write an extra byte to the destination, and THAT'S NO GOOD. 19290 ZigType *ptr_elem_type; 19291 if (value_type->id == ZigTypeIdArray && value_type->data.array.sentinel != nullptr && 19292 dest_type->id == ZigTypeIdArray && dest_type->data.array.sentinel == nullptr) 19293 { 19294 ptr_elem_type = get_array_type(ira->codegen, value_type->data.array.child_type, 19295 value_type->data.array.len, nullptr); 19296 } else { 19297 ptr_elem_type = value_type; 19298 } 19299 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ptr_elem_type, 19300 parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, 19301 parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); 19302 19303 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, 19304 parent_result_loc->value->type, ptr_type, 19305 result_cast->base.source_instruction->base.source_node, false); 19306 if (const_cast_result.id == ConstCastResultIdInvalid) 19307 return ira->codegen->invalid_inst_gen; 19308 if (const_cast_result.id != ConstCastResultIdOk) { 19309 if (allow_discard) { 19310 return parent_result_loc; 19311 } 19312 // We will not be able to provide a result location for this value. Create 19313 // a new result location. 19314 result_cast->parent->written = false; 19315 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type); 19316 } 19317 19318 result_loc->written = true; 19319 result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, 19320 &parent_result_loc->base, ptr_type, &result_cast->base.source_instruction->base, false, false); 19321 return result_loc->resolved_loc; 19322 } 19323 case ResultLocIdBitCast: { 19324 ResultLocBitCast *result_bit_cast = reinterpret_cast<ResultLocBitCast *>(result_loc); 19325 ZigType *dest_type = ir_resolve_type(ira, result_bit_cast->base.source_instruction->child); 19326 if (type_is_invalid(dest_type)) 19327 return ira->codegen->invalid_inst_gen; 19328 19329 ZigType *dest_cg_ptr_type; 19330 if ((err = get_codegen_ptr_type(ira->codegen, dest_type, &dest_cg_ptr_type))) 19331 return ira->codegen->invalid_inst_gen; 19332 if (dest_cg_ptr_type != nullptr) { 19333 ir_add_error(ira, &result_loc->source_instruction->base, 19334 buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); 19335 return ira->codegen->invalid_inst_gen; 19336 } 19337 19338 if (!type_can_bit_cast(dest_type)) { 19339 ir_add_error(ira, &result_loc->source_instruction->base, 19340 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); 19341 return ira->codegen->invalid_inst_gen; 19342 } 19343 19344 ZigType *value_cg_ptr_type; 19345 if ((err = get_codegen_ptr_type(ira->codegen, value_type, &value_cg_ptr_type))) 19346 return ira->codegen->invalid_inst_gen; 19347 if (value_cg_ptr_type != nullptr) { 19348 ir_add_error(ira, suspend_source_instr, 19349 buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&value_type->name))); 19350 return ira->codegen->invalid_inst_gen; 19351 } 19352 19353 if (!type_can_bit_cast(value_type)) { 19354 ir_add_error(ira, suspend_source_instr, 19355 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&value_type->name))); 19356 return ira->codegen->invalid_inst_gen; 19357 } 19358 19359 IrInstGen *bitcasted_value; 19360 if (value != nullptr) { 19361 bitcasted_value = ir_analyze_bit_cast(ira, &result_loc->source_instruction->base, value, dest_type); 19362 dest_type = bitcasted_value->value->type; 19363 } else { 19364 bitcasted_value = nullptr; 19365 } 19366 19367 if (bitcasted_value != nullptr && type_is_invalid(bitcasted_value->value->type)) { 19368 return bitcasted_value; 19369 } 19370 19371 bool parent_was_written = result_bit_cast->parent->written; 19372 IrInstGen *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_bit_cast->parent, 19373 dest_type, bitcasted_value, force_runtime, true); 19374 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value->type) || 19375 parent_result_loc->value->type->id == ZigTypeIdUnreachable) 19376 { 19377 return parent_result_loc; 19378 } 19379 ZigType *parent_ptr_type = parent_result_loc->value->type; 19380 assert(parent_ptr_type->id == ZigTypeIdPointer); 19381 ZigType *child_type = parent_ptr_type->data.pointer.child_type; 19382 19383 if (result_loc_is_discard(result_bit_cast->parent)) { 19384 assert(allow_discard); 19385 return parent_result_loc; 19386 } 19387 19388 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) { 19389 return ira->codegen->invalid_inst_gen; 19390 } 19391 19392 if ((err = type_resolve(ira->codegen, value_type, ResolveStatusSizeKnown))) { 19393 return ira->codegen->invalid_inst_gen; 19394 } 19395 19396 if (child_type != ira->codegen->builtin_types.entry_var) { 19397 if (type_size(ira->codegen, child_type) != type_size(ira->codegen, value_type)) { 19398 // pointer cast won't work; we need a temporary location. 19399 result_bit_cast->parent->written = parent_was_written; 19400 result_loc->written = true; 19401 result_loc->resolved_loc = ir_resolve_result(ira, suspend_source_instr, no_result_loc(), 19402 value_type, bitcasted_value, force_runtime, true); 19403 return result_loc->resolved_loc; 19404 } 19405 } 19406 uint64_t parent_ptr_align = 0; 19407 if (type_has_bits(ira->codegen, value_type)) parent_ptr_align = get_ptr_align(ira->codegen, parent_ptr_type); 19408 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value_type, 19409 parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle, 19410 parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero); 19411 19412 result_loc->written = true; 19413 result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, 19414 &parent_result_loc->base, ptr_type, &result_bit_cast->base.source_instruction->base, false, false); 19415 return result_loc->resolved_loc; 19416 } 19417 } 19418 zig_unreachable(); 19419 } 19420 19421 static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr, 19422 ResultLoc *result_loc_pass1, ZigType *value_type, IrInstGen *value, bool force_runtime, 19423 bool allow_discard) 19424 { 19425 if (!allow_discard && result_loc_is_discard(result_loc_pass1)) { 19426 result_loc_pass1 = no_result_loc(); 19427 } 19428 bool was_written = result_loc_pass1->written; 19429 IrInstGen *result_loc = ir_resolve_result_raw(ira, suspend_source_instr, result_loc_pass1, value_type, 19430 value, force_runtime, allow_discard); 19431 if (result_loc == nullptr || result_loc->value->type->id == ZigTypeIdUnreachable || 19432 type_is_invalid(result_loc->value->type)) 19433 { 19434 return result_loc; 19435 } 19436 19437 if ((force_runtime || (value != nullptr && !instr_is_comptime(value))) && 19438 result_loc_pass1->written && result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) 19439 { 19440 result_loc->value->special = ConstValSpecialRuntime; 19441 } 19442 19443 InferredStructField *isf = result_loc->value->type->data.pointer.inferred_struct_field; 19444 if (isf != nullptr) { 19445 TypeStructField *field; 19446 IrInstGen *casted_ptr; 19447 if (isf->already_resolved) { 19448 field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); 19449 casted_ptr = result_loc; 19450 } else { 19451 isf->already_resolved = true; 19452 // Now it's time to add the field to the struct type. 19453 uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count; 19454 uint32_t new_field_count = old_field_count + 1; 19455 isf->inferred_struct_type->data.structure.src_field_count = new_field_count; 19456 isf->inferred_struct_type->data.structure.fields = realloc_type_struct_fields( 19457 isf->inferred_struct_type->data.structure.fields, old_field_count, new_field_count); 19458 19459 field = isf->inferred_struct_type->data.structure.fields[old_field_count]; 19460 field->name = isf->field_name; 19461 field->type_entry = value_type; 19462 field->type_val = create_const_type(ira->codegen, field->type_entry); 19463 field->src_index = old_field_count; 19464 field->decl_node = value ? value->base.source_node : suspend_source_instr->source_node; 19465 if (value && instr_is_comptime(value)) { 19466 ZigValue *val = ir_resolve_const(ira, value, UndefOk); 19467 if (!val) 19468 return ira->codegen->invalid_inst_gen; 19469 field->is_comptime = true; 19470 field->init_val = ira->codegen->pass1_arena->create<ZigValue>(); 19471 copy_const_val(ira->codegen, field->init_val, val); 19472 return result_loc; 19473 } 19474 19475 ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false); 19476 if (instr_is_comptime(result_loc)) { 19477 casted_ptr = ir_const(ira, suspend_source_instr, struct_ptr_type); 19478 copy_const_val(ira->codegen, casted_ptr->value, result_loc->value); 19479 casted_ptr->value->type = struct_ptr_type; 19480 } else { 19481 casted_ptr = result_loc; 19482 } 19483 if (instr_is_comptime(casted_ptr)) { 19484 ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad); 19485 if (!ptr_val) 19486 return ira->codegen->invalid_inst_gen; 19487 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 19488 ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, 19489 suspend_source_instr->source_node); 19490 struct_val->special = ConstValSpecialStatic; 19491 struct_val->data.x_struct.fields = realloc_const_vals_ptrs(ira->codegen, 19492 struct_val->data.x_struct.fields, old_field_count, new_field_count); 19493 19494 ZigValue *field_val = struct_val->data.x_struct.fields[old_field_count]; 19495 field_val->special = ConstValSpecialUndef; 19496 field_val->type = field->type_entry; 19497 field_val->parent.id = ConstParentIdStruct; 19498 field_val->parent.data.p_struct.struct_val = struct_val; 19499 field_val->parent.data.p_struct.field_index = old_field_count; 19500 } 19501 } 19502 } 19503 19504 result_loc = ir_analyze_struct_field_ptr(ira, suspend_source_instr, field, casted_ptr, 19505 isf->inferred_struct_type, true); 19506 result_loc_pass1->resolved_loc = result_loc; 19507 } 19508 19509 if (was_written) { 19510 return result_loc; 19511 } 19512 19513 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, suspend_source_instr); 19514 ZigType *actual_elem_type = result_loc->value->type->data.pointer.child_type; 19515 if (actual_elem_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && 19516 value_type->id != ZigTypeIdNull && value_type->id != ZigTypeIdUndefined) 19517 { 19518 bool same_comptime_repr = types_have_same_zig_comptime_repr(ira->codegen, actual_elem_type, value_type); 19519 if (!same_comptime_repr) { 19520 result_loc_pass1->written = was_written; 19521 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, result_loc, false, true); 19522 } 19523 } else if (actual_elem_type->id == ZigTypeIdErrorUnion && value_type->id != ZigTypeIdErrorUnion && 19524 value_type->id != ZigTypeIdUndefined) 19525 { 19526 if (value_type->id == ZigTypeIdErrorSet) { 19527 return ir_analyze_unwrap_err_code(ira, suspend_source_instr, result_loc, true); 19528 } else { 19529 IrInstGen *unwrapped_err_ptr = ir_analyze_unwrap_error_payload(ira, suspend_source_instr, 19530 result_loc, false, true); 19531 ZigType *actual_payload_type = actual_elem_type->data.error_union.payload_type; 19532 if (actual_payload_type->id == ZigTypeIdOptional && value_type->id != ZigTypeIdOptional && 19533 value_type->id != ZigTypeIdNull && value_type->id != ZigTypeIdUndefined) 19534 { 19535 return ir_analyze_unwrap_optional_payload(ira, suspend_source_instr, unwrapped_err_ptr, false, true); 19536 } else { 19537 return unwrapped_err_ptr; 19538 } 19539 } 19540 } 19541 return result_loc; 19542 } 19543 19544 static IrInstGen *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstSrcResolveResult *instruction) { 19545 ZigType *implicit_elem_type; 19546 if (instruction->ty == nullptr) { 19547 if (instruction->result_loc->id == ResultLocIdCast) { 19548 implicit_elem_type = ir_resolve_type(ira, 19549 instruction->result_loc->source_instruction->child); 19550 if (type_is_invalid(implicit_elem_type)) 19551 return ira->codegen->invalid_inst_gen; 19552 } else if (instruction->result_loc->id == ResultLocIdReturn) { 19553 implicit_elem_type = ira->explicit_return_type; 19554 if (type_is_invalid(implicit_elem_type)) 19555 return ira->codegen->invalid_inst_gen; 19556 } else { 19557 implicit_elem_type = ira->codegen->builtin_types.entry_var; 19558 } 19559 if (implicit_elem_type == ira->codegen->builtin_types.entry_var) { 19560 Buf *bare_name = buf_alloc(); 19561 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct), 19562 instruction->base.base.scope, instruction->base.base.source_node, bare_name); 19563 19564 StructSpecial struct_special = StructSpecialInferredStruct; 19565 if (instruction->base.base.source_node->type == NodeTypeContainerInitExpr && 19566 instruction->base.base.source_node->data.container_init_expr.kind == ContainerInitKindArray) 19567 { 19568 struct_special = StructSpecialInferredTuple; 19569 } 19570 19571 ZigType *inferred_struct_type = get_partial_container_type(ira->codegen, 19572 instruction->base.base.scope, ContainerKindStruct, instruction->base.base.source_node, 19573 buf_ptr(name), bare_name, ContainerLayoutAuto); 19574 inferred_struct_type->data.structure.special = struct_special; 19575 inferred_struct_type->data.structure.resolve_status = ResolveStatusBeingInferred; 19576 implicit_elem_type = inferred_struct_type; 19577 } 19578 } else { 19579 implicit_elem_type = ir_resolve_type(ira, instruction->ty->child); 19580 if (type_is_invalid(implicit_elem_type)) 19581 return ira->codegen->invalid_inst_gen; 19582 } 19583 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 19584 implicit_elem_type, nullptr, false, true); 19585 if (result_loc != nullptr) 19586 return result_loc; 19587 19588 ZigFn *fn = ira->new_irb.exec->fn_entry; 19589 if (fn != nullptr && fn->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync && 19590 instruction->result_loc->id == ResultLocIdReturn) 19591 { 19592 result_loc = ir_resolve_result(ira, &instruction->base.base, no_result_loc(), 19593 implicit_elem_type, nullptr, false, true); 19594 if (result_loc != nullptr && 19595 (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) 19596 { 19597 return result_loc; 19598 } 19599 result_loc->value->special = ConstValSpecialRuntime; 19600 return result_loc; 19601 } 19602 19603 IrInstGen *result = ir_const(ira, &instruction->base.base, implicit_elem_type); 19604 result->value->special = ConstValSpecialUndef; 19605 IrInstGen *ptr = ir_get_ref(ira, &instruction->base.base, result, false, false); 19606 ptr->value->data.x_ptr.mut = ConstPtrMutComptimeVar; 19607 return ptr; 19608 } 19609 19610 static void ir_reset_result(ResultLoc *result_loc) { 19611 result_loc->written = false; 19612 result_loc->resolved_loc = nullptr; 19613 result_loc->gen_instruction = nullptr; 19614 result_loc->implicit_elem_type = nullptr; 19615 switch (result_loc->id) { 19616 case ResultLocIdInvalid: 19617 zig_unreachable(); 19618 case ResultLocIdPeerParent: { 19619 ResultLocPeerParent *peer_parent = reinterpret_cast<ResultLocPeerParent *>(result_loc); 19620 peer_parent->skipped = false; 19621 peer_parent->done_resuming = false; 19622 peer_parent->resolved_type = nullptr; 19623 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 19624 ir_reset_result(&peer_parent->peers.at(i)->base); 19625 } 19626 break; 19627 } 19628 case ResultLocIdVar: { 19629 IrInstSrcAlloca *alloca_src = reinterpret_cast<IrInstSrcAlloca *>(result_loc->source_instruction); 19630 alloca_src->base.child = nullptr; 19631 break; 19632 } 19633 case ResultLocIdReturn: 19634 reinterpret_cast<ResultLocReturn *>(result_loc)->implicit_return_type_done = false; 19635 break; 19636 case ResultLocIdPeer: 19637 case ResultLocIdNone: 19638 case ResultLocIdInstruction: 19639 case ResultLocIdBitCast: 19640 case ResultLocIdCast: 19641 break; 19642 } 19643 } 19644 19645 static IrInstGen *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInstSrcResetResult *instruction) { 19646 ir_reset_result(instruction->result_loc); 19647 return ir_const_void(ira, &instruction->base.base); 19648 } 19649 19650 static IrInstGen *get_async_call_result_loc(IrAnalyze *ira, IrInst* source_instr, 19651 ZigType *fn_ret_type, bool is_async_call_builtin, IrInstGen **args_ptr, size_t args_len, 19652 IrInstGen *ret_ptr_uncasted) 19653 { 19654 ir_assert(is_async_call_builtin, source_instr); 19655 if (type_is_invalid(ret_ptr_uncasted->value->type)) 19656 return ira->codegen->invalid_inst_gen; 19657 if (ret_ptr_uncasted->value->type->id == ZigTypeIdVoid) { 19658 // Result location will be inside the async frame. 19659 return nullptr; 19660 } 19661 return ir_implicit_cast(ira, ret_ptr_uncasted, get_pointer_to_type(ira->codegen, fn_ret_type, false)); 19662 } 19663 19664 static IrInstGen *ir_analyze_async_call(IrAnalyze *ira, IrInst* source_instr, ZigFn *fn_entry, 19665 ZigType *fn_type, IrInstGen *fn_ref, IrInstGen **casted_args, size_t arg_count, 19666 IrInstGen *casted_new_stack, bool is_async_call_builtin, IrInstGen *ret_ptr_uncasted, 19667 ResultLoc *call_result_loc) 19668 { 19669 if (fn_entry == nullptr) { 19670 if (fn_type->data.fn.fn_type_id.cc != CallingConventionAsync) { 19671 ir_add_error(ira, &fn_ref->base, 19672 buf_sprintf("expected async function, found '%s'", buf_ptr(&fn_type->name))); 19673 return ira->codegen->invalid_inst_gen; 19674 } 19675 if (casted_new_stack == nullptr) { 19676 ir_add_error(ira, &fn_ref->base, buf_sprintf("function is not comptime-known; @asyncCall required")); 19677 return ira->codegen->invalid_inst_gen; 19678 } 19679 } 19680 if (casted_new_stack != nullptr) { 19681 ZigType *fn_ret_type = fn_type->data.fn.fn_type_id.return_type; 19682 IrInstGen *ret_ptr = get_async_call_result_loc(ira, source_instr, fn_ret_type, is_async_call_builtin, 19683 casted_args, arg_count, ret_ptr_uncasted); 19684 if (ret_ptr != nullptr && type_is_invalid(ret_ptr->value->type)) 19685 return ira->codegen->invalid_inst_gen; 19686 19687 ZigType *anyframe_type = get_any_frame_type(ira->codegen, fn_ret_type); 19688 19689 IrInstGenCall *call_gen = ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, 19690 arg_count, casted_args, CallModifierAsync, casted_new_stack, 19691 is_async_call_builtin, ret_ptr, anyframe_type); 19692 return &call_gen->base; 19693 } else { 19694 ZigType *frame_type = get_fn_frame_type(ira->codegen, fn_entry); 19695 IrInstGen *result_loc = ir_resolve_result(ira, source_instr, call_result_loc, 19696 frame_type, nullptr, true, false); 19697 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 19698 return result_loc; 19699 } 19700 result_loc = ir_implicit_cast2(ira, source_instr, result_loc, 19701 get_pointer_to_type(ira->codegen, frame_type, false)); 19702 if (type_is_invalid(result_loc->value->type)) 19703 return ira->codegen->invalid_inst_gen; 19704 return &ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, arg_count, 19705 casted_args, CallModifierAsync, casted_new_stack, 19706 is_async_call_builtin, result_loc, frame_type)->base; 19707 } 19708 } 19709 static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, 19710 IrInstGen *arg, Scope **exec_scope, size_t *next_proto_i) 19711 { 19712 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 19713 assert(param_decl_node->type == NodeTypeParamDecl); 19714 19715 IrInstGen *casted_arg; 19716 if (param_decl_node->data.param_decl.var_token == nullptr) { 19717 AstNode *param_type_node = param_decl_node->data.param_decl.type; 19718 ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node); 19719 if (type_is_invalid(param_type)) 19720 return false; 19721 19722 casted_arg = ir_implicit_cast(ira, arg, param_type); 19723 if (type_is_invalid(casted_arg->value->type)) 19724 return false; 19725 } else { 19726 casted_arg = arg; 19727 } 19728 19729 ZigValue *arg_val = ir_resolve_const(ira, casted_arg, UndefOk); 19730 if (!arg_val) 19731 return false; 19732 19733 Buf *param_name = param_decl_node->data.param_decl.name; 19734 ZigVar *var = add_variable(ira->codegen, param_decl_node, 19735 *exec_scope, param_name, true, arg_val, nullptr, arg_val->type); 19736 *exec_scope = var->child_scope; 19737 *next_proto_i += 1; 19738 19739 return true; 19740 } 19741 19742 static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node, 19743 IrInstGen *arg, IrInst *arg_src, Scope **child_scope, size_t *next_proto_i, 19744 GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstGen **casted_args, 19745 ZigFn *impl_fn) 19746 { 19747 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 19748 assert(param_decl_node->type == NodeTypeParamDecl); 19749 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 19750 bool arg_part_of_generic_id = false; 19751 IrInstGen *casted_arg; 19752 if (is_var_args) { 19753 arg_part_of_generic_id = true; 19754 casted_arg = arg; 19755 } else { 19756 if (param_decl_node->data.param_decl.var_token == nullptr) { 19757 AstNode *param_type_node = param_decl_node->data.param_decl.type; 19758 ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node); 19759 if (type_is_invalid(param_type)) 19760 return false; 19761 19762 casted_arg = ir_implicit_cast2(ira, arg_src, arg, param_type); 19763 if (type_is_invalid(casted_arg->value->type)) 19764 return false; 19765 } else { 19766 arg_part_of_generic_id = true; 19767 casted_arg = arg; 19768 } 19769 } 19770 19771 bool comptime_arg = param_decl_node->data.param_decl.is_comptime; 19772 if (!comptime_arg) { 19773 switch (type_requires_comptime(ira->codegen, casted_arg->value->type)) { 19774 case ReqCompTimeInvalid: 19775 return false; 19776 case ReqCompTimeYes: 19777 comptime_arg = true; 19778 break; 19779 case ReqCompTimeNo: 19780 break; 19781 } 19782 } 19783 19784 ZigValue *arg_val; 19785 19786 if (comptime_arg) { 19787 arg_part_of_generic_id = true; 19788 arg_val = ir_resolve_const(ira, casted_arg, UndefBad); 19789 if (!arg_val) 19790 return false; 19791 } else { 19792 arg_val = create_const_runtime(ira->codegen, casted_arg->value->type); 19793 } 19794 if (arg_part_of_generic_id) { 19795 copy_const_val(ira->codegen, &generic_id->params[generic_id->param_count], arg_val); 19796 generic_id->param_count += 1; 19797 } 19798 19799 Buf *param_name = param_decl_node->data.param_decl.name; 19800 if (!param_name) return false; 19801 if (!is_var_args) { 19802 ZigVar *var = add_variable(ira->codegen, param_decl_node, 19803 *child_scope, param_name, true, arg_val, nullptr, arg_val->type); 19804 *child_scope = var->child_scope; 19805 var->shadowable = !comptime_arg; 19806 19807 *next_proto_i += 1; 19808 } else if (casted_arg->value->type->id == ZigTypeIdComptimeInt || 19809 casted_arg->value->type->id == ZigTypeIdComptimeFloat) 19810 { 19811 ir_add_error(ira, &casted_arg->base, 19812 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/ziglang/zig/issues/557")); 19813 return false; 19814 } 19815 19816 if (!comptime_arg) { 19817 casted_args[fn_type_id->param_count] = casted_arg; 19818 FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count]; 19819 param_info->type = casted_arg->value->type; 19820 param_info->is_noalias = param_decl_node->data.param_decl.is_noalias; 19821 impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node; 19822 fn_type_id->param_count += 1; 19823 } 19824 19825 return true; 19826 } 19827 19828 static IrInstGen *ir_get_var_ptr(IrAnalyze *ira, IrInst *source_instr, ZigVar *var) { 19829 while (var->next_var != nullptr) { 19830 var = var->next_var; 19831 } 19832 19833 if (var->var_type == nullptr || type_is_invalid(var->var_type)) 19834 return ira->codegen->invalid_inst_gen; 19835 19836 bool is_volatile = false; 19837 ZigType *var_ptr_type = get_pointer_to_type_extra(ira->codegen, var->var_type, 19838 var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0, false); 19839 19840 if (var->ptr_instruction != nullptr) { 19841 return ir_implicit_cast(ira, var->ptr_instruction, var_ptr_type); 19842 } 19843 19844 bool comptime_var_mem = ir_get_var_is_comptime(var); 19845 bool linkage_makes_it_runtime = var->decl_node->data.variable_declaration.is_extern; 19846 19847 IrInstGen *result = ir_build_var_ptr_gen(ira, source_instr, var); 19848 result->value->type = var_ptr_type; 19849 19850 if (!linkage_makes_it_runtime && !var->is_thread_local && value_is_comptime(var->const_value)) { 19851 ZigValue *val = var->const_value; 19852 switch (val->special) { 19853 case ConstValSpecialRuntime: 19854 break; 19855 case ConstValSpecialStatic: // fallthrough 19856 case ConstValSpecialLazy: // fallthrough 19857 case ConstValSpecialUndef: { 19858 ConstPtrMut ptr_mut; 19859 if (comptime_var_mem) { 19860 ptr_mut = ConstPtrMutComptimeVar; 19861 } else if (var->gen_is_const) { 19862 ptr_mut = ConstPtrMutComptimeConst; 19863 } else { 19864 assert(!comptime_var_mem); 19865 ptr_mut = ConstPtrMutRuntimeVar; 19866 } 19867 result->value->special = ConstValSpecialStatic; 19868 result->value->data.x_ptr.mut = ptr_mut; 19869 result->value->data.x_ptr.special = ConstPtrSpecialRef; 19870 result->value->data.x_ptr.data.ref.pointee = val; 19871 return result; 19872 } 19873 } 19874 } 19875 19876 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr); 19877 result->value->data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack; 19878 19879 return result; 19880 } 19881 19882 // This function is called when a comptime value becomes accessible at runtime. 19883 static void mark_comptime_value_escape(IrAnalyze *ira, IrInst* source_instr, ZigValue *val) { 19884 ir_assert(value_is_comptime(val), source_instr); 19885 if (val->special == ConstValSpecialUndef) 19886 return; 19887 19888 if (val->type->id == ZigTypeIdFn && val->type->data.fn.fn_type_id.cc == CallingConventionUnspecified) { 19889 ir_assert(val->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); 19890 if (val->data.x_ptr.data.fn.fn_entry->non_async_node == nullptr) { 19891 val->data.x_ptr.data.fn.fn_entry->non_async_node = source_instr->source_node; 19892 } 19893 } 19894 } 19895 19896 static IrInstGen *ir_analyze_store_ptr(IrAnalyze *ira, IrInst* source_instr, 19897 IrInstGen *ptr, IrInstGen *uncasted_value, bool allow_write_through_const) 19898 { 19899 assert(ptr->value->type->id == ZigTypeIdPointer); 19900 19901 if (ptr->value->data.x_ptr.special == ConstPtrSpecialDiscard) { 19902 if (uncasted_value->value->type->id == ZigTypeIdErrorUnion || 19903 uncasted_value->value->type->id == ZigTypeIdErrorSet) 19904 { 19905 ir_add_error(ira, source_instr, buf_sprintf("error is discarded")); 19906 return ira->codegen->invalid_inst_gen; 19907 } 19908 return ir_const_void(ira, source_instr); 19909 } 19910 19911 if (ptr->value->type->data.pointer.is_const && !allow_write_through_const) { 19912 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 19913 return ira->codegen->invalid_inst_gen; 19914 } 19915 19916 ZigType *child_type = ptr->value->type->data.pointer.child_type; 19917 IrInstGen *value = ir_implicit_cast(ira, uncasted_value, child_type); 19918 if (type_is_invalid(value->value->type)) 19919 return ira->codegen->invalid_inst_gen; 19920 19921 switch (type_has_one_possible_value(ira->codegen, child_type)) { 19922 case OnePossibleValueInvalid: 19923 return ira->codegen->invalid_inst_gen; 19924 case OnePossibleValueYes: 19925 return ir_const_void(ira, source_instr); 19926 case OnePossibleValueNo: 19927 break; 19928 } 19929 19930 if (instr_is_comptime(ptr) && ptr->value->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 19931 if (!allow_write_through_const && ptr->value->data.x_ptr.mut == ConstPtrMutComptimeConst) { 19932 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 19933 return ira->codegen->invalid_inst_gen; 19934 } 19935 if ((allow_write_through_const && ptr->value->data.x_ptr.mut == ConstPtrMutComptimeConst) || 19936 ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar || 19937 ptr->value->data.x_ptr.mut == ConstPtrMutInfer) 19938 { 19939 if (instr_is_comptime(value)) { 19940 ZigValue *dest_val = const_ptr_pointee(ira, ira->codegen, ptr->value, source_instr->source_node); 19941 if (dest_val == nullptr) 19942 return ira->codegen->invalid_inst_gen; 19943 if (dest_val->special != ConstValSpecialRuntime) { 19944 copy_const_val(ira->codegen, dest_val, value->value); 19945 19946 if (ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar && 19947 !ira->new_irb.current_basic_block->must_be_comptime_source_instr) 19948 { 19949 ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr; 19950 } 19951 return ir_const_void(ira, source_instr); 19952 } 19953 } 19954 if (ptr->value->data.x_ptr.mut == ConstPtrMutInfer) { 19955 ptr->value->special = ConstValSpecialRuntime; 19956 } else { 19957 ir_add_error(ira, source_instr, 19958 buf_sprintf("cannot store runtime value in compile time variable")); 19959 ZigValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, ptr->value); 19960 dest_val->type = ira->codegen->builtin_types.entry_invalid; 19961 19962 return ira->codegen->invalid_inst_gen; 19963 } 19964 } 19965 } 19966 19967 if (ptr->value->type->data.pointer.inferred_struct_field != nullptr && 19968 child_type == ira->codegen->builtin_types.entry_var) 19969 { 19970 child_type = ptr->value->type->data.pointer.inferred_struct_field->inferred_struct_type; 19971 } 19972 19973 switch (type_requires_comptime(ira->codegen, child_type)) { 19974 case ReqCompTimeInvalid: 19975 return ira->codegen->invalid_inst_gen; 19976 case ReqCompTimeYes: 19977 switch (type_has_one_possible_value(ira->codegen, ptr->value->type)) { 19978 case OnePossibleValueInvalid: 19979 return ira->codegen->invalid_inst_gen; 19980 case OnePossibleValueNo: 19981 ir_add_error(ira, source_instr, 19982 buf_sprintf("cannot store runtime value in type '%s'", buf_ptr(&child_type->name))); 19983 return ira->codegen->invalid_inst_gen; 19984 case OnePossibleValueYes: 19985 return ir_const_void(ira, source_instr); 19986 } 19987 zig_unreachable(); 19988 case ReqCompTimeNo: 19989 break; 19990 } 19991 19992 if (instr_is_comptime(value)) { 19993 mark_comptime_value_escape(ira, source_instr, value->value); 19994 } 19995 19996 // If this is a store to a pointer with a runtime-known vector index, 19997 // we have to figure out the IrInstGen which represents the index and 19998 // emit a IrInstGenVectorStoreElem, or emit a compile error 19999 // explaining why it is impossible for this store to work. Which is that 20000 // the pointer address is of the vector; without the element index being known 20001 // we cannot properly perform the insertion. 20002 if (ptr->value->type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) { 20003 if (ptr->id == IrInstGenIdElemPtr) { 20004 IrInstGenElemPtr *elem_ptr = (IrInstGenElemPtr *)ptr; 20005 return ir_build_vector_store_elem(ira, source_instr, elem_ptr->array_ptr, 20006 elem_ptr->elem_index, value); 20007 } 20008 ir_add_error(ira, &ptr->base, 20009 buf_sprintf("unable to determine vector element index of type '%s'", 20010 buf_ptr(&ptr->value->type->name))); 20011 return ira->codegen->invalid_inst_gen; 20012 } 20013 20014 return ir_build_store_ptr_gen(ira, source_instr, ptr, value); 20015 } 20016 20017 static IrInstGen *analyze_casted_new_stack(IrAnalyze *ira, IrInst* source_instr, 20018 IrInstGen *new_stack, IrInst *new_stack_src, bool is_async_call_builtin, ZigFn *fn_entry) 20019 { 20020 if (new_stack == nullptr) 20021 return nullptr; 20022 20023 if (!is_async_call_builtin && 20024 arch_stack_pointer_register_name(ira->codegen->zig_target->arch) == nullptr) 20025 { 20026 ir_add_error(ira, source_instr, 20027 buf_sprintf("target arch '%s' does not support calling with a new stack", 20028 target_arch_name(ira->codegen->zig_target->arch))); 20029 } 20030 20031 if (is_async_call_builtin && 20032 fn_entry != nullptr && new_stack->value->type->id == ZigTypeIdPointer && 20033 new_stack->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 20034 { 20035 ZigType *needed_frame_type = get_pointer_to_type(ira->codegen, 20036 get_fn_frame_type(ira->codegen, fn_entry), false); 20037 return ir_implicit_cast(ira, new_stack, needed_frame_type); 20038 } else { 20039 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 20040 false, false, PtrLenUnknown, target_fn_align(ira->codegen->zig_target), 0, 0, false); 20041 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 20042 ira->codegen->need_frame_size_prefix_data = true; 20043 return ir_implicit_cast2(ira, new_stack_src, new_stack, u8_slice); 20044 } 20045 } 20046 20047 static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, 20048 ZigFn *fn_entry, ZigType *fn_type, IrInstGen *fn_ref, 20049 IrInstGen *first_arg_ptr, IrInst *first_arg_ptr_src, CallModifier modifier, 20050 IrInstGen *new_stack, IrInst *new_stack_src, bool is_async_call_builtin, 20051 IrInstGen **args_ptr, size_t args_len, IrInstGen *ret_ptr, ResultLoc *call_result_loc) 20052 { 20053 Error err; 20054 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 20055 size_t first_arg_1_or_0 = first_arg_ptr ? 1 : 0; 20056 20057 // for extern functions, the var args argument is not counted. 20058 // for zig functions, it is. 20059 size_t var_args_1_or_0; 20060 if (fn_type_id->cc == CallingConventionC) { 20061 var_args_1_or_0 = 0; 20062 } else { 20063 var_args_1_or_0 = fn_type_id->is_var_args ? 1 : 0; 20064 } 20065 size_t src_param_count = fn_type_id->param_count - var_args_1_or_0; 20066 size_t call_param_count = args_len + first_arg_1_or_0; 20067 AstNode *source_node = source_instr->source_node; 20068 20069 AstNode *fn_proto_node = fn_entry ? fn_entry->proto_node : nullptr;; 20070 20071 if (fn_type_id->cc == CallingConventionNaked) { 20072 ErrorMsg *msg = ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to call function with naked calling convention")); 20073 if (fn_proto_node) { 20074 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 20075 } 20076 return ira->codegen->invalid_inst_gen; 20077 } 20078 20079 if (fn_type_id->is_var_args) { 20080 if (call_param_count < src_param_count) { 20081 ErrorMsg *msg = ir_add_error_node(ira, source_node, 20082 buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 20083 if (fn_proto_node) { 20084 add_error_note(ira->codegen, msg, fn_proto_node, 20085 buf_sprintf("declared here")); 20086 } 20087 return ira->codegen->invalid_inst_gen; 20088 } 20089 } else if (src_param_count != call_param_count) { 20090 ErrorMsg *msg = ir_add_error_node(ira, source_node, 20091 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 20092 if (fn_proto_node) { 20093 add_error_note(ira->codegen, msg, fn_proto_node, 20094 buf_sprintf("declared here")); 20095 } 20096 return ira->codegen->invalid_inst_gen; 20097 } 20098 20099 if (modifier == CallModifierCompileTime) { 20100 // If we are evaluating an extern function in a TypeOf call, we can return an undefined value 20101 // of its return type. 20102 if (fn_entry != nullptr && get_scope_typeof(source_instr->scope) != nullptr && 20103 fn_proto_node->data.fn_proto.is_extern) { 20104 20105 assert(fn_entry->body_node == nullptr); 20106 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 20107 ZigType *return_type = ir_analyze_type_expr(ira, source_instr->scope, return_type_node); 20108 if (type_is_invalid(return_type)) 20109 return ira->codegen->invalid_inst_gen; 20110 20111 return ir_const_undef(ira, source_instr, return_type); 20112 } 20113 20114 // No special handling is needed for compile time evaluation of generic functions. 20115 if (!fn_entry || fn_entry->body_node == nullptr) { 20116 ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression")); 20117 return ira->codegen->invalid_inst_gen; 20118 } 20119 20120 if (!ir_emit_backward_branch(ira, source_instr)) 20121 return ira->codegen->invalid_inst_gen; 20122 20123 // Fork a scope of the function with known values for the parameters. 20124 Scope *exec_scope = &fn_entry->fndef_scope->base; 20125 20126 size_t next_proto_i = 0; 20127 if (first_arg_ptr) { 20128 assert(first_arg_ptr->value->type->id == ZigTypeIdPointer); 20129 20130 bool first_arg_known_bare = false; 20131 if (fn_type_id->next_param_index >= 1) { 20132 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 20133 if (type_is_invalid(param_type)) 20134 return ira->codegen->invalid_inst_gen; 20135 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 20136 } 20137 20138 IrInstGen *first_arg; 20139 if (!first_arg_known_bare && handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type)) { 20140 first_arg = first_arg_ptr; 20141 } else { 20142 first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); 20143 if (type_is_invalid(first_arg->value->type)) 20144 return ira->codegen->invalid_inst_gen; 20145 } 20146 20147 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, first_arg, &exec_scope, &next_proto_i)) 20148 return ira->codegen->invalid_inst_gen; 20149 } 20150 20151 for (size_t call_i = 0; call_i < args_len; call_i += 1) { 20152 IrInstGen *old_arg = args_ptr[call_i]; 20153 20154 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_proto_i)) 20155 return ira->codegen->invalid_inst_gen; 20156 } 20157 20158 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 20159 ZigType *specified_return_type = ir_analyze_type_expr(ira, exec_scope, return_type_node); 20160 if (type_is_invalid(specified_return_type)) 20161 return ira->codegen->invalid_inst_gen; 20162 ZigType *return_type; 20163 ZigType *inferred_err_set_type = nullptr; 20164 if (fn_proto_node->data.fn_proto.auto_err_set) { 20165 inferred_err_set_type = get_auto_err_set_type(ira->codegen, fn_entry); 20166 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 20167 return ira->codegen->invalid_inst_gen; 20168 return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 20169 } else { 20170 return_type = specified_return_type; 20171 } 20172 20173 bool cacheable = fn_eval_cacheable(exec_scope, return_type); 20174 ZigValue *result = nullptr; 20175 if (cacheable) { 20176 auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope); 20177 if (entry) 20178 result = entry->value; 20179 } 20180 20181 if (result == nullptr) { 20182 // Analyze the fn body block like any other constant expression. 20183 AstNode *body_node = fn_entry->body_node; 20184 ZigValue *result_ptr; 20185 create_result_ptr(ira->codegen, return_type, &result, &result_ptr); 20186 20187 if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr, 20188 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 20189 fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node, 20190 UndefOk))) 20191 { 20192 return ira->codegen->invalid_inst_gen; 20193 } 20194 20195 if (inferred_err_set_type != nullptr) { 20196 inferred_err_set_type->data.error_set.incomplete = false; 20197 if (result->type->id == ZigTypeIdErrorUnion) { 20198 ErrorTableEntry *err = result->data.x_err_union.error_set->data.x_err_set; 20199 if (err != nullptr) { 20200 inferred_err_set_type->data.error_set.err_count = 1; 20201 inferred_err_set_type->data.error_set.errors = heap::c_allocator.create<ErrorTableEntry *>(); 20202 inferred_err_set_type->data.error_set.errors[0] = err; 20203 } 20204 ZigType *fn_inferred_err_set_type = result->type->data.error_union.err_set_type; 20205 inferred_err_set_type->data.error_set.err_count = fn_inferred_err_set_type->data.error_set.err_count; 20206 inferred_err_set_type->data.error_set.errors = fn_inferred_err_set_type->data.error_set.errors; 20207 } else if (result->type->id == ZigTypeIdErrorSet) { 20208 inferred_err_set_type->data.error_set.err_count = result->type->data.error_set.err_count; 20209 inferred_err_set_type->data.error_set.errors = result->type->data.error_set.errors; 20210 } 20211 } 20212 20213 if (cacheable) { 20214 ira->codegen->memoized_fn_eval_table.put(exec_scope, result); 20215 } 20216 20217 if (type_is_invalid(result->type)) { 20218 return ira->codegen->invalid_inst_gen; 20219 } 20220 } 20221 20222 IrInstGen *new_instruction = ir_const_move(ira, source_instr, result); 20223 return ir_finish_anal(ira, new_instruction); 20224 } 20225 20226 if (fn_type->data.fn.is_generic) { 20227 if (!fn_entry) { 20228 ir_add_error(ira, &fn_ref->base, 20229 buf_sprintf("calling a generic function requires compile-time known function value")); 20230 return ira->codegen->invalid_inst_gen; 20231 } 20232 20233 size_t new_fn_arg_count = first_arg_1_or_0 + args_len; 20234 20235 IrInstGen **casted_args = heap::c_allocator.allocate<IrInstGen *>(new_fn_arg_count); 20236 20237 // Fork a scope of the function with known values for the parameters. 20238 Scope *parent_scope = fn_entry->fndef_scope->base.parent; 20239 ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node); 20240 impl_fn->param_source_nodes = heap::c_allocator.allocate<AstNode *>(new_fn_arg_count); 20241 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); 20242 impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn); 20243 impl_fn->child_scope = &impl_fn->fndef_scope->base; 20244 FnTypeId inst_fn_type_id = {0}; 20245 init_fn_type_id(&inst_fn_type_id, fn_proto_node, fn_type_id->cc, new_fn_arg_count); 20246 inst_fn_type_id.param_count = 0; 20247 inst_fn_type_id.is_var_args = false; 20248 20249 // TODO maybe GenericFnTypeId can be replaced with using the child_scope directly 20250 // as the key in generic_table 20251 GenericFnTypeId *generic_id = heap::c_allocator.create<GenericFnTypeId>(); 20252 generic_id->fn_entry = fn_entry; 20253 generic_id->param_count = 0; 20254 generic_id->params = ira->codegen->pass1_arena->allocate<ZigValue>(new_fn_arg_count); 20255 size_t next_proto_i = 0; 20256 20257 if (first_arg_ptr) { 20258 assert(first_arg_ptr->value->type->id == ZigTypeIdPointer); 20259 20260 bool first_arg_known_bare = false; 20261 if (fn_type_id->next_param_index >= 1) { 20262 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 20263 if (type_is_invalid(param_type)) 20264 return ira->codegen->invalid_inst_gen; 20265 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 20266 } 20267 20268 IrInstGen *first_arg; 20269 if (!first_arg_known_bare && handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type)) { 20270 first_arg = first_arg_ptr; 20271 } else { 20272 first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); 20273 if (type_is_invalid(first_arg->value->type)) 20274 return ira->codegen->invalid_inst_gen; 20275 } 20276 20277 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, first_arg, first_arg_ptr_src, 20278 &impl_fn->child_scope, &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 20279 { 20280 return ira->codegen->invalid_inst_gen; 20281 } 20282 } 20283 20284 ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry; 20285 assert(parent_fn_entry); 20286 for (size_t call_i = 0; call_i < args_len; call_i += 1) { 20287 IrInstGen *arg = args_ptr[call_i]; 20288 20289 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 20290 assert(param_decl_node->type == NodeTypeParamDecl); 20291 20292 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &arg->base, &impl_fn->child_scope, 20293 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 20294 { 20295 return ira->codegen->invalid_inst_gen; 20296 } 20297 } 20298 20299 if (fn_proto_node->data.fn_proto.align_expr != nullptr) { 20300 ZigValue *align_result; 20301 ZigValue *result_ptr; 20302 create_result_ptr(ira->codegen, get_align_amt_type(ira->codegen), &align_result, &result_ptr); 20303 if ((err = ir_eval_const_value(ira->codegen, impl_fn->child_scope, 20304 fn_proto_node->data.fn_proto.align_expr, result_ptr, 20305 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 20306 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, 20307 nullptr, UndefBad))) 20308 { 20309 return ira->codegen->invalid_inst_gen; 20310 } 20311 IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb, 20312 impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); 20313 const_instruction->base.value = align_result; 20314 20315 uint32_t align_bytes = 0; 20316 ir_resolve_align(ira, &const_instruction->base, nullptr, &align_bytes); 20317 impl_fn->align_bytes = align_bytes; 20318 inst_fn_type_id.alignment = align_bytes; 20319 } 20320 20321 if (fn_proto_node->data.fn_proto.return_var_token == nullptr) { 20322 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 20323 ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node); 20324 if (type_is_invalid(specified_return_type)) 20325 return ira->codegen->invalid_inst_gen; 20326 20327 if(!is_valid_return_type(specified_return_type)){ 20328 ErrorMsg *msg = ir_add_error(ira, source_instr, 20329 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))); 20330 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("function declared here")); 20331 20332 Tld *tld = find_decl(ira->codegen, &fn_entry->fndef_scope->base, &specified_return_type->name); 20333 if (tld != nullptr) { 20334 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("type declared here")); 20335 } 20336 return ira->codegen->invalid_inst_gen; 20337 } 20338 20339 if (fn_proto_node->data.fn_proto.auto_err_set) { 20340 ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn); 20341 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 20342 return ira->codegen->invalid_inst_gen; 20343 inst_fn_type_id.return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 20344 } else { 20345 inst_fn_type_id.return_type = specified_return_type; 20346 } 20347 20348 switch (type_requires_comptime(ira->codegen, specified_return_type)) { 20349 case ReqCompTimeYes: 20350 // Throw out our work and call the function as if it were comptime. 20351 return ir_analyze_fn_call(ira, source_instr, fn_entry, fn_type, fn_ref, first_arg_ptr, 20352 first_arg_ptr_src, CallModifierCompileTime, new_stack, new_stack_src, is_async_call_builtin, 20353 args_ptr, args_len, ret_ptr, call_result_loc); 20354 case ReqCompTimeInvalid: 20355 return ira->codegen->invalid_inst_gen; 20356 case ReqCompTimeNo: 20357 break; 20358 } 20359 } 20360 20361 auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn); 20362 if (existing_entry) { 20363 // throw away all our work and use the existing function 20364 impl_fn = existing_entry->value; 20365 } else { 20366 // finish instantiating the function 20367 impl_fn->type_entry = get_fn_type(ira->codegen, &inst_fn_type_id); 20368 if (type_is_invalid(impl_fn->type_entry)) 20369 return ira->codegen->invalid_inst_gen; 20370 20371 impl_fn->ir_executable->source_node = source_instr->source_node; 20372 impl_fn->ir_executable->parent_exec = ira->new_irb.exec; 20373 impl_fn->analyzed_executable.source_node = source_instr->source_node; 20374 impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec; 20375 impl_fn->analyzed_executable.backward_branch_quota = ira->new_irb.exec->backward_branch_quota; 20376 impl_fn->analyzed_executable.is_generic_instantiation = true; 20377 20378 ira->codegen->fn_defs.append(impl_fn); 20379 } 20380 20381 FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id; 20382 20383 if (fn_type_can_fail(impl_fn_type_id)) { 20384 parent_fn_entry->calls_or_awaits_errorable_fn = true; 20385 } 20386 20387 IrInstGen *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack, 20388 new_stack_src, is_async_call_builtin, impl_fn); 20389 if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) 20390 return ira->codegen->invalid_inst_gen; 20391 20392 size_t impl_param_count = impl_fn_type_id->param_count; 20393 if (modifier == CallModifierAsync) { 20394 IrInstGen *result = ir_analyze_async_call(ira, source_instr, impl_fn, impl_fn->type_entry, 20395 nullptr, casted_args, impl_param_count, casted_new_stack, is_async_call_builtin, ret_ptr, 20396 call_result_loc); 20397 return ir_finish_anal(ira, result); 20398 } 20399 20400 IrInstGen *result_loc; 20401 if (handle_is_ptr(ira->codegen, impl_fn_type_id->return_type)) { 20402 result_loc = ir_resolve_result(ira, source_instr, call_result_loc, 20403 impl_fn_type_id->return_type, nullptr, true, false); 20404 if (result_loc != nullptr) { 20405 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 20406 return result_loc; 20407 } 20408 if (result_loc->value->type->data.pointer.is_const) { 20409 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 20410 return ira->codegen->invalid_inst_gen; 20411 } 20412 20413 IrInstGen *dummy_value = ir_const(ira, source_instr, impl_fn_type_id->return_type); 20414 dummy_value->value->special = ConstValSpecialRuntime; 20415 IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr, 20416 dummy_value, result_loc->value->type->data.pointer.child_type); 20417 if (type_is_invalid(dummy_result->value->type)) 20418 return ira->codegen->invalid_inst_gen; 20419 ZigType *res_child_type = result_loc->value->type->data.pointer.child_type; 20420 if (res_child_type == ira->codegen->builtin_types.entry_var) { 20421 res_child_type = impl_fn_type_id->return_type; 20422 } 20423 if (!handle_is_ptr(ira->codegen, res_child_type)) { 20424 ir_reset_result(call_result_loc); 20425 result_loc = nullptr; 20426 } 20427 } 20428 } else if (is_async_call_builtin) { 20429 result_loc = get_async_call_result_loc(ira, source_instr, impl_fn_type_id->return_type, 20430 is_async_call_builtin, args_ptr, args_len, ret_ptr); 20431 if (result_loc != nullptr && type_is_invalid(result_loc->value->type)) 20432 return ira->codegen->invalid_inst_gen; 20433 } else { 20434 result_loc = nullptr; 20435 } 20436 20437 if (impl_fn_type_id->cc == CallingConventionAsync && 20438 parent_fn_entry->inferred_async_node == nullptr && 20439 modifier != CallModifierNoSuspend) 20440 { 20441 parent_fn_entry->inferred_async_node = fn_ref->base.source_node; 20442 parent_fn_entry->inferred_async_fn = impl_fn; 20443 } 20444 20445 IrInstGenCall *new_call_instruction = ir_build_call_gen(ira, source_instr, 20446 impl_fn, nullptr, impl_param_count, casted_args, modifier, casted_new_stack, 20447 is_async_call_builtin, result_loc, impl_fn_type_id->return_type); 20448 20449 if (get_scope_typeof(source_instr->scope) == nullptr) { 20450 parent_fn_entry->call_list.append(new_call_instruction); 20451 } 20452 20453 return ir_finish_anal(ira, &new_call_instruction->base); 20454 } 20455 20456 ZigFn *parent_fn_entry = ira->new_irb.exec->fn_entry; 20457 assert(fn_type_id->return_type != nullptr); 20458 assert(parent_fn_entry != nullptr); 20459 if (fn_type_can_fail(fn_type_id)) { 20460 parent_fn_entry->calls_or_awaits_errorable_fn = true; 20461 } 20462 20463 20464 IrInstGen **casted_args = heap::c_allocator.allocate<IrInstGen *>(call_param_count); 20465 size_t next_arg_index = 0; 20466 if (first_arg_ptr) { 20467 assert(first_arg_ptr->value->type->id == ZigTypeIdPointer); 20468 20469 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 20470 if (type_is_invalid(param_type)) 20471 return ira->codegen->invalid_inst_gen; 20472 20473 IrInstGen *first_arg; 20474 if (param_type->id == ZigTypeIdPointer && 20475 handle_is_ptr(ira->codegen, first_arg_ptr->value->type->data.pointer.child_type)) 20476 { 20477 first_arg = first_arg_ptr; 20478 } else { 20479 first_arg = ir_get_deref(ira, &first_arg_ptr->base, first_arg_ptr, nullptr); 20480 if (type_is_invalid(first_arg->value->type)) 20481 return ira->codegen->invalid_inst_gen; 20482 } 20483 20484 IrInstGen *casted_arg = ir_implicit_cast2(ira, first_arg_ptr_src, first_arg, param_type); 20485 if (type_is_invalid(casted_arg->value->type)) 20486 return ira->codegen->invalid_inst_gen; 20487 20488 casted_args[next_arg_index] = casted_arg; 20489 next_arg_index += 1; 20490 } 20491 for (size_t call_i = 0; call_i < args_len; call_i += 1) { 20492 IrInstGen *old_arg = args_ptr[call_i]; 20493 if (type_is_invalid(old_arg->value->type)) 20494 return ira->codegen->invalid_inst_gen; 20495 20496 IrInstGen *casted_arg; 20497 if (next_arg_index < src_param_count) { 20498 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 20499 if (type_is_invalid(param_type)) 20500 return ira->codegen->invalid_inst_gen; 20501 casted_arg = ir_implicit_cast(ira, old_arg, param_type); 20502 if (type_is_invalid(casted_arg->value->type)) 20503 return ira->codegen->invalid_inst_gen; 20504 } else { 20505 casted_arg = old_arg; 20506 } 20507 20508 casted_args[next_arg_index] = casted_arg; 20509 next_arg_index += 1; 20510 } 20511 20512 assert(next_arg_index == call_param_count); 20513 20514 ZigType *return_type = fn_type_id->return_type; 20515 if (type_is_invalid(return_type)) 20516 return ira->codegen->invalid_inst_gen; 20517 20518 if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && modifier == CallModifierNeverInline) { 20519 ir_add_error(ira, source_instr, 20520 buf_sprintf("no-inline call of inline function")); 20521 return ira->codegen->invalid_inst_gen; 20522 } 20523 20524 IrInstGen *casted_new_stack = analyze_casted_new_stack(ira, source_instr, new_stack, new_stack_src, 20525 is_async_call_builtin, fn_entry); 20526 if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type)) 20527 return ira->codegen->invalid_inst_gen; 20528 20529 if (modifier == CallModifierAsync) { 20530 IrInstGen *result = ir_analyze_async_call(ira, source_instr, fn_entry, fn_type, fn_ref, 20531 casted_args, call_param_count, casted_new_stack, is_async_call_builtin, ret_ptr, call_result_loc); 20532 return ir_finish_anal(ira, result); 20533 } 20534 20535 if (fn_type_id->cc == CallingConventionAsync && 20536 parent_fn_entry->inferred_async_node == nullptr && 20537 modifier != CallModifierNoSuspend) 20538 { 20539 parent_fn_entry->inferred_async_node = fn_ref->base.source_node; 20540 parent_fn_entry->inferred_async_fn = fn_entry; 20541 } 20542 20543 IrInstGen *result_loc; 20544 if (handle_is_ptr(ira->codegen, return_type)) { 20545 result_loc = ir_resolve_result(ira, source_instr, call_result_loc, 20546 return_type, nullptr, true, false); 20547 if (result_loc != nullptr) { 20548 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 20549 return result_loc; 20550 } 20551 if (result_loc->value->type->data.pointer.is_const) { 20552 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant")); 20553 return ira->codegen->invalid_inst_gen; 20554 } 20555 20556 IrInstGen *dummy_value = ir_const(ira, source_instr, return_type); 20557 dummy_value->value->special = ConstValSpecialRuntime; 20558 IrInstGen *dummy_result = ir_implicit_cast2(ira, source_instr, 20559 dummy_value, result_loc->value->type->data.pointer.child_type); 20560 if (type_is_invalid(dummy_result->value->type)) 20561 return ira->codegen->invalid_inst_gen; 20562 ZigType *res_child_type = result_loc->value->type->data.pointer.child_type; 20563 if (res_child_type == ira->codegen->builtin_types.entry_var) { 20564 res_child_type = return_type; 20565 } 20566 if (!handle_is_ptr(ira->codegen, res_child_type)) { 20567 ir_reset_result(call_result_loc); 20568 result_loc = nullptr; 20569 } 20570 } 20571 } else if (is_async_call_builtin) { 20572 result_loc = get_async_call_result_loc(ira, source_instr, return_type, is_async_call_builtin, 20573 args_ptr, args_len, ret_ptr); 20574 if (result_loc != nullptr && type_is_invalid(result_loc->value->type)) 20575 return ira->codegen->invalid_inst_gen; 20576 } else { 20577 result_loc = nullptr; 20578 } 20579 20580 IrInstGenCall *new_call_instruction = ir_build_call_gen(ira, source_instr, fn_entry, fn_ref, 20581 call_param_count, casted_args, modifier, casted_new_stack, 20582 is_async_call_builtin, result_loc, return_type); 20583 if (get_scope_typeof(source_instr->scope) == nullptr) { 20584 parent_fn_entry->call_list.append(new_call_instruction); 20585 } 20586 return ir_finish_anal(ira, &new_call_instruction->base); 20587 } 20588 20589 static IrInstGen *ir_analyze_fn_call_src(IrAnalyze *ira, IrInstSrcCall *call_instruction, 20590 ZigFn *fn_entry, ZigType *fn_type, IrInstGen *fn_ref, 20591 IrInstGen *first_arg_ptr, IrInst *first_arg_ptr_src, CallModifier modifier) 20592 { 20593 IrInstGen *new_stack = nullptr; 20594 IrInst *new_stack_src = nullptr; 20595 if (call_instruction->new_stack) { 20596 new_stack = call_instruction->new_stack->child; 20597 if (type_is_invalid(new_stack->value->type)) 20598 return ira->codegen->invalid_inst_gen; 20599 new_stack_src = &call_instruction->new_stack->base; 20600 } 20601 IrInstGen **args_ptr = heap::c_allocator.allocate<IrInstGen *>(call_instruction->arg_count); 20602 for (size_t i = 0; i < call_instruction->arg_count; i += 1) { 20603 args_ptr[i] = call_instruction->args[i]->child; 20604 if (type_is_invalid(args_ptr[i]->value->type)) 20605 return ira->codegen->invalid_inst_gen; 20606 } 20607 IrInstGen *ret_ptr = nullptr; 20608 if (call_instruction->ret_ptr != nullptr) { 20609 ret_ptr = call_instruction->ret_ptr->child; 20610 if (type_is_invalid(ret_ptr->value->type)) 20611 return ira->codegen->invalid_inst_gen; 20612 } 20613 IrInstGen *result = ir_analyze_fn_call(ira, &call_instruction->base.base, fn_entry, fn_type, fn_ref, 20614 first_arg_ptr, first_arg_ptr_src, modifier, new_stack, new_stack_src, 20615 call_instruction->is_async_call_builtin, args_ptr, call_instruction->arg_count, ret_ptr, 20616 call_instruction->result_loc); 20617 heap::c_allocator.deallocate(args_ptr, call_instruction->arg_count); 20618 return result; 20619 } 20620 20621 static IrInstGen *ir_analyze_call_extra(IrAnalyze *ira, IrInst* source_instr, 20622 IrInstSrc *pass1_options, IrInstSrc *pass1_fn_ref, IrInstGen **args_ptr, size_t args_len, 20623 ResultLoc *result_loc) 20624 { 20625 IrInstGen *options = pass1_options->child; 20626 if (type_is_invalid(options->value->type)) 20627 return ira->codegen->invalid_inst_gen; 20628 20629 IrInstGen *fn_ref = pass1_fn_ref->child; 20630 if (type_is_invalid(fn_ref->value->type)) 20631 return ira->codegen->invalid_inst_gen; 20632 20633 TypeStructField *modifier_field = find_struct_type_field(options->value->type, buf_create_from_str("modifier")); 20634 ir_assert(modifier_field != nullptr, source_instr); 20635 IrInstGen *modifier_inst = ir_analyze_struct_value_field_value(ira, source_instr, options, modifier_field); 20636 ZigValue *modifier_val = ir_resolve_const(ira, modifier_inst, UndefBad); 20637 if (modifier_val == nullptr) 20638 return ira->codegen->invalid_inst_gen; 20639 CallModifier modifier = (CallModifier)bigint_as_u32(&modifier_val->data.x_enum_tag); 20640 20641 if (ir_should_inline(ira->old_irb.exec, source_instr->scope)) { 20642 switch (modifier) { 20643 case CallModifierBuiltin: 20644 zig_unreachable(); 20645 case CallModifierAsync: 20646 ir_add_error(ira, source_instr, buf_sprintf("TODO: comptime @call with async modifier")); 20647 return ira->codegen->invalid_inst_gen; 20648 case CallModifierCompileTime: 20649 case CallModifierNone: 20650 case CallModifierAlwaysInline: 20651 case CallModifierAlwaysTail: 20652 case CallModifierNoSuspend: 20653 modifier = CallModifierCompileTime; 20654 break; 20655 case CallModifierNeverInline: 20656 ir_add_error(ira, source_instr, 20657 buf_sprintf("unable to perform 'never_inline' call at compile-time")); 20658 return ira->codegen->invalid_inst_gen; 20659 case CallModifierNeverTail: 20660 ir_add_error(ira, source_instr, 20661 buf_sprintf("unable to perform 'never_tail' call at compile-time")); 20662 return ira->codegen->invalid_inst_gen; 20663 } 20664 } 20665 20666 IrInstGen *first_arg_ptr = nullptr; 20667 IrInst *first_arg_ptr_src = nullptr; 20668 ZigFn *fn = nullptr; 20669 if (instr_is_comptime(fn_ref)) { 20670 if (fn_ref->value->type->id == ZigTypeIdBoundFn) { 20671 assert(fn_ref->value->special == ConstValSpecialStatic); 20672 fn = fn_ref->value->data.x_bound_fn.fn; 20673 first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg; 20674 first_arg_ptr_src = fn_ref->value->data.x_bound_fn.first_arg_src; 20675 if (type_is_invalid(first_arg_ptr->value->type)) 20676 return ira->codegen->invalid_inst_gen; 20677 } else { 20678 fn = ir_resolve_fn(ira, fn_ref); 20679 } 20680 } 20681 20682 // Some modifiers require the callee to be comptime-known 20683 switch (modifier) { 20684 case CallModifierCompileTime: 20685 case CallModifierAlwaysInline: 20686 case CallModifierAsync: 20687 if (fn == nullptr) { 20688 ir_add_error(ira, &modifier_inst->base, 20689 buf_sprintf("the specified modifier requires a comptime-known function")); 20690 return ira->codegen->invalid_inst_gen; 20691 } 20692 ZIG_FALLTHROUGH; 20693 default: 20694 break; 20695 } 20696 20697 ZigType *fn_type = (fn != nullptr) ? fn->type_entry : fn_ref->value->type; 20698 20699 TypeStructField *stack_field = find_struct_type_field(options->value->type, buf_create_from_str("stack")); 20700 ir_assert(stack_field != nullptr, source_instr); 20701 IrInstGen *opt_stack = ir_analyze_struct_value_field_value(ira, source_instr, options, stack_field); 20702 if (type_is_invalid(opt_stack->value->type)) 20703 return ira->codegen->invalid_inst_gen; 20704 20705 IrInstGen *stack_is_non_null_inst = ir_analyze_test_non_null(ira, source_instr, opt_stack); 20706 bool stack_is_non_null; 20707 if (!ir_resolve_bool(ira, stack_is_non_null_inst, &stack_is_non_null)) 20708 return ira->codegen->invalid_inst_gen; 20709 20710 IrInstGen *stack = nullptr; 20711 IrInst *stack_src = nullptr; 20712 if (stack_is_non_null) { 20713 stack = ir_analyze_optional_value_payload_value(ira, source_instr, opt_stack, false); 20714 if (type_is_invalid(stack->value->type)) 20715 return ira->codegen->invalid_inst_gen; 20716 stack_src = &stack->base; 20717 } 20718 20719 return ir_analyze_fn_call(ira, source_instr, fn, fn_type, fn_ref, first_arg_ptr, first_arg_ptr_src, 20720 modifier, stack, stack_src, false, args_ptr, args_len, nullptr, result_loc); 20721 } 20722 20723 static IrInstGen *ir_analyze_instruction_call_extra(IrAnalyze *ira, IrInstSrcCallExtra *instruction) { 20724 IrInstGen *args = instruction->args->child; 20725 ZigType *args_type = args->value->type; 20726 if (type_is_invalid(args_type)) 20727 return ira->codegen->invalid_inst_gen; 20728 20729 if (args_type->id != ZigTypeIdStruct) { 20730 ir_add_error(ira, &args->base, 20731 buf_sprintf("expected tuple or struct, found '%s'", buf_ptr(&args_type->name))); 20732 return ira->codegen->invalid_inst_gen; 20733 } 20734 20735 IrInstGen **args_ptr = nullptr; 20736 size_t args_len = 0; 20737 20738 if (is_tuple(args_type)) { 20739 args_len = args_type->data.structure.src_field_count; 20740 args_ptr = heap::c_allocator.allocate<IrInstGen *>(args_len); 20741 for (size_t i = 0; i < args_len; i += 1) { 20742 TypeStructField *arg_field = args_type->data.structure.fields[i]; 20743 args_ptr[i] = ir_analyze_struct_value_field_value(ira, &instruction->base.base, args, arg_field); 20744 if (type_is_invalid(args_ptr[i]->value->type)) 20745 return ira->codegen->invalid_inst_gen; 20746 } 20747 } else { 20748 ir_add_error(ira, &args->base, buf_sprintf("TODO: struct args")); 20749 return ira->codegen->invalid_inst_gen; 20750 } 20751 IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options, 20752 instruction->fn_ref, args_ptr, args_len, instruction->result_loc); 20753 heap::c_allocator.deallocate(args_ptr, args_len); 20754 return result; 20755 } 20756 20757 static IrInstGen *ir_analyze_instruction_call_args(IrAnalyze *ira, IrInstSrcCallArgs *instruction) { 20758 IrInstGen **args_ptr = heap::c_allocator.allocate<IrInstGen *>(instruction->args_len); 20759 for (size_t i = 0; i < instruction->args_len; i += 1) { 20760 args_ptr[i] = instruction->args_ptr[i]->child; 20761 if (type_is_invalid(args_ptr[i]->value->type)) 20762 return ira->codegen->invalid_inst_gen; 20763 } 20764 20765 IrInstGen *result = ir_analyze_call_extra(ira, &instruction->base.base, instruction->options, 20766 instruction->fn_ref, args_ptr, instruction->args_len, instruction->result_loc); 20767 heap::c_allocator.deallocate(args_ptr, instruction->args_len); 20768 return result; 20769 } 20770 20771 static IrInstGen *ir_analyze_instruction_call(IrAnalyze *ira, IrInstSrcCall *call_instruction) { 20772 IrInstGen *fn_ref = call_instruction->fn_ref->child; 20773 if (type_is_invalid(fn_ref->value->type)) 20774 return ira->codegen->invalid_inst_gen; 20775 20776 bool is_comptime = (call_instruction->modifier == CallModifierCompileTime) || 20777 ir_should_inline(ira->old_irb.exec, call_instruction->base.base.scope); 20778 CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; 20779 20780 if (is_comptime || instr_is_comptime(fn_ref)) { 20781 if (fn_ref->value->type->id == ZigTypeIdMetaType) { 20782 ZigType *ty = ir_resolve_type(ira, fn_ref); 20783 if (ty == nullptr) 20784 return ira->codegen->invalid_inst_gen; 20785 ErrorMsg *msg = ir_add_error(ira, &fn_ref->base, 20786 buf_sprintf("type '%s' not a function", buf_ptr(&ty->name))); 20787 add_error_note(ira->codegen, msg, call_instruction->base.base.source_node, 20788 buf_sprintf("use @as builtin for type coercion")); 20789 return ira->codegen->invalid_inst_gen; 20790 } else if (fn_ref->value->type->id == ZigTypeIdFn) { 20791 ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref); 20792 ZigType *fn_type = fn_table_entry ? fn_table_entry->type_entry : fn_ref->value->type; 20793 CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; 20794 return ir_analyze_fn_call_src(ira, call_instruction, fn_table_entry, fn_type, 20795 fn_ref, nullptr, nullptr, modifier); 20796 } else if (fn_ref->value->type->id == ZigTypeIdBoundFn) { 20797 assert(fn_ref->value->special == ConstValSpecialStatic); 20798 ZigFn *fn_table_entry = fn_ref->value->data.x_bound_fn.fn; 20799 IrInstGen *first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg; 20800 IrInst *first_arg_ptr_src = fn_ref->value->data.x_bound_fn.first_arg_src; 20801 CallModifier modifier = is_comptime ? CallModifierCompileTime : call_instruction->modifier; 20802 return ir_analyze_fn_call_src(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, 20803 fn_ref, first_arg_ptr, first_arg_ptr_src, modifier); 20804 } else { 20805 ir_add_error(ira, &fn_ref->base, 20806 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value->type->name))); 20807 return ira->codegen->invalid_inst_gen; 20808 } 20809 } 20810 20811 if (fn_ref->value->type->id == ZigTypeIdFn) { 20812 return ir_analyze_fn_call_src(ira, call_instruction, nullptr, fn_ref->value->type, 20813 fn_ref, nullptr, nullptr, modifier); 20814 } else { 20815 ir_add_error(ira, &fn_ref->base, 20816 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value->type->name))); 20817 return ira->codegen->invalid_inst_gen; 20818 } 20819 } 20820 20821 // out_val->type must be the type to read the pointer as 20822 // if the type is different than the actual type then it does a comptime byte reinterpretation 20823 static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, 20824 ZigValue *out_val, ZigValue *ptr_val) 20825 { 20826 Error err; 20827 assert(out_val->type != nullptr); 20828 20829 ZigValue *pointee = const_ptr_pointee_unchecked(codegen, ptr_val); 20830 src_assert(pointee->type != nullptr, source_node); 20831 20832 if ((err = type_resolve(codegen, pointee->type, ResolveStatusSizeKnown))) 20833 return ErrorSemanticAnalyzeFail; 20834 if ((err = type_resolve(codegen, out_val->type, ResolveStatusSizeKnown))) 20835 return ErrorSemanticAnalyzeFail; 20836 20837 size_t src_size = type_size(codegen, pointee->type); 20838 size_t dst_size = type_size(codegen, out_val->type); 20839 20840 if (dst_size <= src_size) { 20841 if (src_size == dst_size && types_have_same_zig_comptime_repr(codegen, out_val->type, pointee->type)) { 20842 copy_const_val(codegen, out_val, pointee); 20843 return ErrorNone; 20844 } 20845 Buf buf = BUF_INIT; 20846 buf_resize(&buf, src_size); 20847 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf), pointee); 20848 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 20849 return err; 20850 buf_deinit(&buf); 20851 return ErrorNone; 20852 } 20853 20854 switch (ptr_val->data.x_ptr.special) { 20855 case ConstPtrSpecialInvalid: 20856 zig_unreachable(); 20857 case ConstPtrSpecialNull: 20858 if (dst_size == 0) 20859 return ErrorNone; 20860 opt_ir_add_error_node(ira, codegen, source_node, 20861 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from null pointer", 20862 dst_size)); 20863 return ErrorSemanticAnalyzeFail; 20864 case ConstPtrSpecialRef: { 20865 opt_ir_add_error_node(ira, codegen, source_node, 20866 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from pointer to %s which is %" ZIG_PRI_usize " bytes", 20867 dst_size, buf_ptr(&pointee->type->name), src_size)); 20868 return ErrorSemanticAnalyzeFail; 20869 } 20870 case ConstPtrSpecialSubArray: { 20871 ZigValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val; 20872 assert(array_val->type->id == ZigTypeIdArray); 20873 if (array_val->data.x_array.special != ConstArraySpecialNone) 20874 zig_panic("TODO"); 20875 if (dst_size > src_size) { 20876 size_t elem_index = ptr_val->data.x_ptr.data.base_array.elem_index; 20877 opt_ir_add_error_node(ira, codegen, source_node, 20878 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from %s at index %" ZIG_PRI_usize " which is %" ZIG_PRI_usize " bytes", 20879 dst_size, buf_ptr(&array_val->type->name), elem_index, src_size)); 20880 return ErrorSemanticAnalyzeFail; 20881 } 20882 size_t elem_size = src_size; 20883 size_t elem_count = (dst_size % elem_size == 0) ? (dst_size / elem_size) : (dst_size / elem_size + 1); 20884 Buf buf = BUF_INIT; 20885 buf_resize(&buf, elem_count * elem_size); 20886 for (size_t i = 0; i < elem_count; i += 1) { 20887 ZigValue *elem_val = &array_val->data.x_array.data.s_none.elements[i]; 20888 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val); 20889 } 20890 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 20891 return err; 20892 buf_deinit(&buf); 20893 return ErrorNone; 20894 } 20895 case ConstPtrSpecialBaseArray: { 20896 ZigValue *array_val = ptr_val->data.x_ptr.data.base_array.array_val; 20897 assert(array_val->type->id == ZigTypeIdArray); 20898 if (array_val->data.x_array.special != ConstArraySpecialNone) 20899 zig_panic("TODO"); 20900 size_t elem_size = src_size; 20901 size_t elem_index = ptr_val->data.x_ptr.data.base_array.elem_index; 20902 src_size = elem_size * (array_val->type->data.array.len - elem_index); 20903 if (dst_size > src_size) { 20904 opt_ir_add_error_node(ira, codegen, source_node, 20905 buf_sprintf("attempt to read %" ZIG_PRI_usize " bytes from %s at index %" ZIG_PRI_usize " which is %" ZIG_PRI_usize " bytes", 20906 dst_size, buf_ptr(&array_val->type->name), elem_index, src_size)); 20907 return ErrorSemanticAnalyzeFail; 20908 } 20909 size_t elem_count = (dst_size % elem_size == 0) ? (dst_size / elem_size) : (dst_size / elem_size + 1); 20910 Buf buf = BUF_INIT; 20911 buf_resize(&buf, elem_count * elem_size); 20912 for (size_t i = 0; i < elem_count; i += 1) { 20913 ZigValue *elem_val = &array_val->data.x_array.data.s_none.elements[elem_index + i]; 20914 buf_write_value_bytes(codegen, (uint8_t*)buf_ptr(&buf) + (i * elem_size), elem_val); 20915 } 20916 if ((err = buf_read_value_bytes(ira, codegen, source_node, (uint8_t*)buf_ptr(&buf), out_val))) 20917 return err; 20918 buf_deinit(&buf); 20919 return ErrorNone; 20920 } 20921 case ConstPtrSpecialBaseStruct: 20922 case ConstPtrSpecialBaseErrorUnionCode: 20923 case ConstPtrSpecialBaseErrorUnionPayload: 20924 case ConstPtrSpecialBaseOptionalPayload: 20925 case ConstPtrSpecialDiscard: 20926 case ConstPtrSpecialHardCodedAddr: 20927 case ConstPtrSpecialFunction: 20928 zig_panic("TODO"); 20929 } 20930 zig_unreachable(); 20931 } 20932 20933 static IrInstGen *ir_analyze_optional_type(IrAnalyze *ira, IrInstSrcUnOp *instruction) { 20934 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); 20935 result->value->special = ConstValSpecialLazy; 20936 20937 LazyValueOptType *lazy_opt_type = heap::c_allocator.create<LazyValueOptType>(); 20938 lazy_opt_type->ira = ira; ira_ref(ira); 20939 result->value->data.x_lazy = &lazy_opt_type->base; 20940 lazy_opt_type->base.id = LazyValueIdOptType; 20941 20942 lazy_opt_type->payload_type = instruction->value->child; 20943 if (ir_resolve_type_lazy(ira, lazy_opt_type->payload_type) == nullptr) 20944 return ira->codegen->invalid_inst_gen; 20945 20946 return result; 20947 } 20948 20949 static ErrorMsg *ir_eval_negation_scalar(IrAnalyze *ira, IrInst* source_instr, ZigType *scalar_type, 20950 ZigValue *operand_val, ZigValue *scalar_out_val, bool is_wrap_op) 20951 { 20952 bool is_float = (scalar_type->id == ZigTypeIdFloat || scalar_type->id == ZigTypeIdComptimeFloat); 20953 20954 bool ok_type = ((scalar_type->id == ZigTypeIdInt && scalar_type->data.integral.is_signed) || 20955 scalar_type->id == ZigTypeIdComptimeInt || (is_float && !is_wrap_op)); 20956 20957 if (!ok_type) { 20958 const char *fmt = is_wrap_op ? "invalid wrapping negation type: '%s'" : "invalid negation type: '%s'"; 20959 return ir_add_error(ira, source_instr, buf_sprintf(fmt, buf_ptr(&scalar_type->name))); 20960 } 20961 20962 if (is_float) { 20963 float_negate(scalar_out_val, operand_val); 20964 } else if (is_wrap_op) { 20965 bigint_negate_wrap(&scalar_out_val->data.x_bigint, &operand_val->data.x_bigint, 20966 scalar_type->data.integral.bit_count); 20967 } else { 20968 bigint_negate(&scalar_out_val->data.x_bigint, &operand_val->data.x_bigint); 20969 } 20970 20971 scalar_out_val->type = scalar_type; 20972 scalar_out_val->special = ConstValSpecialStatic; 20973 20974 if (is_wrap_op || is_float || scalar_type->id == ZigTypeIdComptimeInt) { 20975 return nullptr; 20976 } 20977 20978 if (!bigint_fits_in_bits(&scalar_out_val->data.x_bigint, scalar_type->data.integral.bit_count, true)) { 20979 return ir_add_error(ira, source_instr, buf_sprintf("negation caused overflow")); 20980 } 20981 return nullptr; 20982 } 20983 20984 static IrInstGen *ir_analyze_negation(IrAnalyze *ira, IrInstSrcUnOp *instruction) { 20985 IrInstGen *value = instruction->value->child; 20986 ZigType *expr_type = value->value->type; 20987 if (type_is_invalid(expr_type)) 20988 return ira->codegen->invalid_inst_gen; 20989 20990 bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap); 20991 20992 switch (expr_type->id) { 20993 case ZigTypeIdComptimeInt: 20994 case ZigTypeIdFloat: 20995 case ZigTypeIdComptimeFloat: 20996 case ZigTypeIdVector: 20997 break; 20998 case ZigTypeIdInt: 20999 if (is_wrap_op || expr_type->data.integral.is_signed) 21000 break; 21001 ZIG_FALLTHROUGH; 21002 default: 21003 ir_add_error(ira, &instruction->base.base, 21004 buf_sprintf("negation of type '%s'", buf_ptr(&expr_type->name))); 21005 return ira->codegen->invalid_inst_gen; 21006 } 21007 21008 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; 21009 21010 if (instr_is_comptime(value)) { 21011 ZigValue *operand_val = ir_resolve_const(ira, value, UndefBad); 21012 if (!operand_val) 21013 return ira->codegen->invalid_inst_gen; 21014 21015 IrInstGen *result_instruction = ir_const(ira, &instruction->base.base, expr_type); 21016 ZigValue *out_val = result_instruction->value; 21017 if (expr_type->id == ZigTypeIdVector) { 21018 expand_undef_array(ira->codegen, operand_val); 21019 out_val->special = ConstValSpecialUndef; 21020 expand_undef_array(ira->codegen, out_val); 21021 size_t len = expr_type->data.vector.len; 21022 for (size_t i = 0; i < len; i += 1) { 21023 ZigValue *scalar_operand_val = &operand_val->data.x_array.data.s_none.elements[i]; 21024 ZigValue *scalar_out_val = &out_val->data.x_array.data.s_none.elements[i]; 21025 assert(scalar_operand_val->type == scalar_type); 21026 assert(scalar_out_val->type == scalar_type); 21027 ErrorMsg *msg = ir_eval_negation_scalar(ira, &instruction->base.base, scalar_type, 21028 scalar_operand_val, scalar_out_val, is_wrap_op); 21029 if (msg != nullptr) { 21030 add_error_note(ira->codegen, msg, instruction->base.base.source_node, 21031 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 21032 return ira->codegen->invalid_inst_gen; 21033 } 21034 } 21035 out_val->type = expr_type; 21036 out_val->special = ConstValSpecialStatic; 21037 } else { 21038 if (ir_eval_negation_scalar(ira, &instruction->base.base, scalar_type, operand_val, out_val, 21039 is_wrap_op) != nullptr) 21040 { 21041 return ira->codegen->invalid_inst_gen; 21042 } 21043 } 21044 return result_instruction; 21045 } 21046 21047 if (is_wrap_op) { 21048 return ir_build_negation_wrapping(ira, &instruction->base.base, value, expr_type); 21049 } else { 21050 return ir_build_negation(ira, &instruction->base.base, value, expr_type); 21051 } 21052 } 21053 21054 static IrInstGen *ir_analyze_bin_not(IrAnalyze *ira, IrInstSrcUnOp *instruction) { 21055 IrInstGen *value = instruction->value->child; 21056 ZigType *expr_type = value->value->type; 21057 if (type_is_invalid(expr_type)) 21058 return ira->codegen->invalid_inst_gen; 21059 21060 ZigType *scalar_type = (expr_type->id == ZigTypeIdVector) ? 21061 expr_type->data.vector.elem_type : expr_type; 21062 21063 if (scalar_type->id != ZigTypeIdInt) { 21064 ir_add_error(ira, &instruction->base.base, 21065 buf_sprintf("unable to perform binary not operation on type '%s'", buf_ptr(&expr_type->name))); 21066 return ira->codegen->invalid_inst_gen; 21067 } 21068 21069 if (instr_is_comptime(value)) { 21070 ZigValue *expr_val = ir_resolve_const(ira, value, UndefBad); 21071 if (expr_val == nullptr) 21072 return ira->codegen->invalid_inst_gen; 21073 21074 IrInstGen *result = ir_const(ira, &instruction->base.base, expr_type); 21075 21076 if (expr_type->id == ZigTypeIdVector) { 21077 expand_undef_array(ira->codegen, expr_val); 21078 result->value->special = ConstValSpecialUndef; 21079 expand_undef_array(ira->codegen, result->value); 21080 21081 for (size_t i = 0; i < expr_type->data.vector.len; i++) { 21082 ZigValue *src_val = &expr_val->data.x_array.data.s_none.elements[i]; 21083 ZigValue *dst_val = &result->value->data.x_array.data.s_none.elements[i]; 21084 21085 dst_val->type = scalar_type; 21086 dst_val->special = ConstValSpecialStatic; 21087 bigint_not(&dst_val->data.x_bigint, &src_val->data.x_bigint, 21088 scalar_type->data.integral.bit_count, scalar_type->data.integral.is_signed); 21089 } 21090 } else { 21091 bigint_not(&result->value->data.x_bigint, &expr_val->data.x_bigint, 21092 scalar_type->data.integral.bit_count, scalar_type->data.integral.is_signed); 21093 } 21094 21095 return result; 21096 } 21097 21098 return ir_build_binary_not(ira, &instruction->base.base, value, expr_type); 21099 } 21100 21101 static IrInstGen *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstSrcUnOp *instruction) { 21102 IrUnOp op_id = instruction->op_id; 21103 switch (op_id) { 21104 case IrUnOpInvalid: 21105 zig_unreachable(); 21106 case IrUnOpBinNot: 21107 return ir_analyze_bin_not(ira, instruction); 21108 case IrUnOpNegation: 21109 case IrUnOpNegationWrap: 21110 return ir_analyze_negation(ira, instruction); 21111 case IrUnOpDereference: { 21112 IrInstGen *ptr = instruction->value->child; 21113 if (type_is_invalid(ptr->value->type)) 21114 return ira->codegen->invalid_inst_gen; 21115 ZigType *ptr_type = ptr->value->type; 21116 if (ptr_type->id == ZigTypeIdPointer && ptr_type->data.pointer.ptr_len == PtrLenUnknown) { 21117 ir_add_error_node(ira, instruction->base.base.source_node, 21118 buf_sprintf("index syntax required for unknown-length pointer type '%s'", 21119 buf_ptr(&ptr_type->name))); 21120 return ira->codegen->invalid_inst_gen; 21121 } 21122 21123 IrInstGen *result = ir_get_deref(ira, &instruction->base.base, ptr, instruction->result_loc); 21124 if (type_is_invalid(result->value->type)) 21125 return ira->codegen->invalid_inst_gen; 21126 21127 // If the result needs to be an lvalue, type check it 21128 if (instruction->lval != LValNone && result->value->type->id != ZigTypeIdPointer) { 21129 ir_add_error(ira, &instruction->base.base, 21130 buf_sprintf("attempt to dereference non-pointer type '%s'", buf_ptr(&result->value->type->name))); 21131 return ira->codegen->invalid_inst_gen; 21132 } 21133 21134 return result; 21135 } 21136 case IrUnOpOptional: 21137 return ir_analyze_optional_type(ira, instruction); 21138 } 21139 zig_unreachable(); 21140 } 21141 21142 static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) { 21143 IrBasicBlockSrc *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index); 21144 if (old_bb->in_resume_stack) return; 21145 ira->resume_stack.append(pos); 21146 old_bb->in_resume_stack = true; 21147 } 21148 21149 static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlockSrc *old_bb) { 21150 if (ira->resume_stack.length != 0) { 21151 ir_push_resume(ira, {old_bb->index, 0}); 21152 } 21153 } 21154 21155 static IrInstGen *ir_analyze_instruction_br(IrAnalyze *ira, IrInstSrcBr *br_instruction) { 21156 IrBasicBlockSrc *old_dest_block = br_instruction->dest_block; 21157 21158 bool is_comptime; 21159 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) 21160 return ir_unreach_error(ira); 21161 21162 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) 21163 return ir_inline_bb(ira, &br_instruction->base.base, old_dest_block); 21164 21165 IrBasicBlockGen *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base.base); 21166 if (new_bb == nullptr) 21167 return ir_unreach_error(ira); 21168 21169 ir_push_resume_block(ira, old_dest_block); 21170 21171 IrInstGen *result = ir_build_br_gen(ira, &br_instruction->base.base, new_bb); 21172 return ir_finish_anal(ira, result); 21173 } 21174 21175 static IrInstGen *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstSrcCondBr *cond_br_instruction) { 21176 IrInstGen *condition = cond_br_instruction->condition->child; 21177 if (type_is_invalid(condition->value->type)) 21178 return ir_unreach_error(ira); 21179 21180 bool is_comptime; 21181 if (!ir_resolve_comptime(ira, cond_br_instruction->is_comptime->child, &is_comptime)) 21182 return ir_unreach_error(ira); 21183 21184 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 21185 IrInstGen *casted_condition = ir_implicit_cast(ira, condition, bool_type); 21186 if (type_is_invalid(casted_condition->value->type)) 21187 return ir_unreach_error(ira); 21188 21189 if (is_comptime || instr_is_comptime(casted_condition)) { 21190 bool cond_is_true; 21191 if (!ir_resolve_bool(ira, casted_condition, &cond_is_true)) 21192 return ir_unreach_error(ira); 21193 21194 IrBasicBlockSrc *old_dest_block = cond_is_true ? 21195 cond_br_instruction->then_block : cond_br_instruction->else_block; 21196 21197 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr)) 21198 return ir_inline_bb(ira, &cond_br_instruction->base.base, old_dest_block); 21199 21200 IrBasicBlockGen *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base.base); 21201 if (new_dest_block == nullptr) 21202 return ir_unreach_error(ira); 21203 21204 ir_push_resume_block(ira, old_dest_block); 21205 21206 IrInstGen *result = ir_build_br_gen(ira, &cond_br_instruction->base.base, new_dest_block); 21207 return ir_finish_anal(ira, result); 21208 } 21209 21210 assert(cond_br_instruction->then_block != cond_br_instruction->else_block); 21211 IrBasicBlockGen *new_then_block = ir_get_new_bb_runtime(ira, cond_br_instruction->then_block, &cond_br_instruction->base.base); 21212 if (new_then_block == nullptr) 21213 return ir_unreach_error(ira); 21214 21215 IrBasicBlockGen *new_else_block = ir_get_new_bb_runtime(ira, cond_br_instruction->else_block, &cond_br_instruction->base.base); 21216 if (new_else_block == nullptr) 21217 return ir_unreach_error(ira); 21218 21219 ir_push_resume_block(ira, cond_br_instruction->else_block); 21220 ir_push_resume_block(ira, cond_br_instruction->then_block); 21221 21222 IrInstGen *result = ir_build_cond_br_gen(ira, &cond_br_instruction->base.base, 21223 casted_condition, new_then_block, new_else_block); 21224 return ir_finish_anal(ira, result); 21225 } 21226 21227 static IrInstGen *ir_analyze_instruction_unreachable(IrAnalyze *ira, 21228 IrInstSrcUnreachable *unreachable_instruction) 21229 { 21230 IrInstGen *result = ir_build_unreachable_gen(ira, &unreachable_instruction->base.base); 21231 return ir_finish_anal(ira, result); 21232 } 21233 21234 static IrInstGen *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstSrcPhi *phi_instruction) { 21235 Error err; 21236 21237 if (ira->const_predecessor_bb) { 21238 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 21239 IrBasicBlockSrc *predecessor = phi_instruction->incoming_blocks[i]; 21240 if (predecessor != ira->const_predecessor_bb) 21241 continue; 21242 IrInstGen *value = phi_instruction->incoming_values[i]->child; 21243 assert(value->value->type); 21244 if (type_is_invalid(value->value->type)) 21245 return ira->codegen->invalid_inst_gen; 21246 21247 if (value->value->special != ConstValSpecialRuntime) { 21248 IrInstGen *result = ir_const(ira, &phi_instruction->base.base, nullptr); 21249 copy_const_val(ira->codegen, result->value, value->value); 21250 return result; 21251 } else { 21252 return value; 21253 } 21254 } 21255 zig_unreachable(); 21256 } 21257 21258 ResultLocPeerParent *peer_parent = phi_instruction->peer_parent; 21259 if (peer_parent != nullptr && !peer_parent->skipped && !peer_parent->done_resuming && 21260 peer_parent->peers.length >= 2) 21261 { 21262 if (peer_parent->resolved_type == nullptr) { 21263 IrInstGen **instructions = heap::c_allocator.allocate<IrInstGen *>(peer_parent->peers.length); 21264 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 21265 ResultLocPeer *this_peer = peer_parent->peers.at(i); 21266 21267 IrInstGen *gen_instruction = this_peer->base.gen_instruction; 21268 if (gen_instruction == nullptr) { 21269 // unreachable instructions will cause implicit_elem_type to be null 21270 if (this_peer->base.implicit_elem_type == nullptr) { 21271 instructions[i] = ir_const_unreachable(ira, &this_peer->base.source_instruction->base); 21272 } else { 21273 instructions[i] = ir_const(ira, &this_peer->base.source_instruction->base, 21274 this_peer->base.implicit_elem_type); 21275 instructions[i]->value->special = ConstValSpecialRuntime; 21276 } 21277 } else { 21278 instructions[i] = gen_instruction; 21279 } 21280 21281 } 21282 ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base.base, peer_parent->parent); 21283 peer_parent->resolved_type = ir_resolve_peer_types(ira, 21284 peer_parent->base.source_instruction->base.source_node, expected_type, instructions, 21285 peer_parent->peers.length); 21286 if (type_is_invalid(peer_parent->resolved_type)) 21287 return ira->codegen->invalid_inst_gen; 21288 21289 // the logic below assumes there are no instructions in the new current basic block yet 21290 ir_assert(ira->new_irb.current_basic_block->instruction_list.length == 0, &phi_instruction->base.base); 21291 21292 // In case resolving the parent activates a suspend, do it now 21293 IrInstGen *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base.base, peer_parent->parent, 21294 peer_parent->resolved_type, nullptr, false, true); 21295 if (parent_result_loc != nullptr && 21296 (type_is_invalid(parent_result_loc->value->type) || parent_result_loc->value->type->id == ZigTypeIdUnreachable)) 21297 { 21298 return parent_result_loc; 21299 } 21300 // If the above code generated any instructions in the current basic block, we need 21301 // to move them to the peer parent predecessor. 21302 ZigList<IrInstGen *> instrs_to_move = {}; 21303 while (ira->new_irb.current_basic_block->instruction_list.length != 0) { 21304 instrs_to_move.append(ira->new_irb.current_basic_block->instruction_list.pop()); 21305 } 21306 if (instrs_to_move.length != 0) { 21307 IrBasicBlockGen *predecessor = peer_parent->base.source_instruction->child->owner_bb; 21308 IrInstGen *branch_instruction = predecessor->instruction_list.pop(); 21309 ir_assert(branch_instruction->value->type->id == ZigTypeIdUnreachable, &phi_instruction->base.base); 21310 while (instrs_to_move.length != 0) { 21311 predecessor->instruction_list.append(instrs_to_move.pop()); 21312 } 21313 predecessor->instruction_list.append(branch_instruction); 21314 } 21315 } 21316 21317 IrSuspendPosition suspend_pos; 21318 ira_suspend(ira, &phi_instruction->base.base, nullptr, &suspend_pos); 21319 ir_push_resume(ira, suspend_pos); 21320 21321 for (size_t i = 0; i < peer_parent->peers.length; i += 1) { 21322 ResultLocPeer *opposite_peer = peer_parent->peers.at(peer_parent->peers.length - i - 1); 21323 if (opposite_peer->base.implicit_elem_type != nullptr && 21324 opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) 21325 { 21326 ir_push_resume(ira, opposite_peer->suspend_pos); 21327 } 21328 } 21329 21330 peer_parent->done_resuming = true; 21331 return ira_resume(ira); 21332 } 21333 21334 ZigList<IrBasicBlockGen*> new_incoming_blocks = {0}; 21335 ZigList<IrInstGen*> new_incoming_values = {0}; 21336 21337 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 21338 IrBasicBlockSrc *predecessor = phi_instruction->incoming_blocks[i]; 21339 if (predecessor->ref_count == 0) 21340 continue; 21341 21342 21343 IrInstSrc *old_value = phi_instruction->incoming_values[i]; 21344 assert(old_value); 21345 IrInstGen *new_value = old_value->child; 21346 if (!new_value || new_value->value->type->id == ZigTypeIdUnreachable || predecessor->child == nullptr) 21347 continue; 21348 21349 if (type_is_invalid(new_value->value->type)) 21350 return ira->codegen->invalid_inst_gen; 21351 21352 21353 assert(predecessor->child); 21354 new_incoming_blocks.append(predecessor->child); 21355 new_incoming_values.append(new_value); 21356 } 21357 21358 if (new_incoming_blocks.length == 0) { 21359 IrInstGen *result = ir_build_unreachable_gen(ira, &phi_instruction->base.base); 21360 return ir_finish_anal(ira, result); 21361 } 21362 21363 if (new_incoming_blocks.length == 1) { 21364 return new_incoming_values.at(0); 21365 } 21366 21367 ZigType *resolved_type = nullptr; 21368 if (peer_parent != nullptr) { 21369 bool peer_parent_has_type; 21370 if ((err = ir_result_has_type(ira, peer_parent->parent, &peer_parent_has_type))) 21371 return ira->codegen->invalid_inst_gen; 21372 if (peer_parent_has_type) { 21373 if (peer_parent->parent->id == ResultLocIdReturn) { 21374 resolved_type = ira->explicit_return_type; 21375 } else if (peer_parent->parent->id == ResultLocIdCast) { 21376 resolved_type = ir_resolve_type(ira, peer_parent->parent->source_instruction->child); 21377 } else if (peer_parent->parent->resolved_loc) { 21378 ZigType *resolved_loc_ptr_type = peer_parent->parent->resolved_loc->value->type; 21379 ir_assert(resolved_loc_ptr_type->id == ZigTypeIdPointer, &phi_instruction->base.base); 21380 resolved_type = resolved_loc_ptr_type->data.pointer.child_type; 21381 } 21382 21383 if (resolved_type != nullptr && type_is_invalid(resolved_type)) 21384 return ira->codegen->invalid_inst_gen; 21385 } 21386 } 21387 21388 if (resolved_type == nullptr) { 21389 resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.base.source_node, nullptr, 21390 new_incoming_values.items, new_incoming_values.length); 21391 if (type_is_invalid(resolved_type)) 21392 return ira->codegen->invalid_inst_gen; 21393 } 21394 21395 switch (type_has_one_possible_value(ira->codegen, resolved_type)) { 21396 case OnePossibleValueInvalid: 21397 return ira->codegen->invalid_inst_gen; 21398 case OnePossibleValueYes: 21399 return ir_const_move(ira, &phi_instruction->base.base, 21400 get_the_one_possible_value(ira->codegen, resolved_type)); 21401 case OnePossibleValueNo: 21402 break; 21403 } 21404 21405 switch (type_requires_comptime(ira->codegen, resolved_type)) { 21406 case ReqCompTimeInvalid: 21407 return ira->codegen->invalid_inst_gen; 21408 case ReqCompTimeYes: 21409 ir_add_error(ira, &phi_instruction->base.base, 21410 buf_sprintf("values of type '%s' must be comptime known", buf_ptr(&resolved_type->name))); 21411 return ira->codegen->invalid_inst_gen; 21412 case ReqCompTimeNo: 21413 break; 21414 } 21415 21416 bool all_stack_ptrs = (resolved_type->id == ZigTypeIdPointer); 21417 21418 // cast all values to the resolved type. however we can't put cast instructions in front of the phi instruction. 21419 // so we go back and insert the casts as the last instruction in the corresponding predecessor blocks, and 21420 // then make sure the branch instruction is preserved. 21421 IrBasicBlockGen *cur_bb = ira->new_irb.current_basic_block; 21422 for (size_t i = 0; i < new_incoming_values.length; i += 1) { 21423 IrInstGen *new_value = new_incoming_values.at(i); 21424 IrBasicBlockGen *predecessor = new_incoming_blocks.at(i); 21425 ir_assert(predecessor->instruction_list.length != 0, &phi_instruction->base.base); 21426 IrInstGen *branch_instruction = predecessor->instruction_list.pop(); 21427 ir_set_cursor_at_end_gen(&ira->new_irb, predecessor); 21428 IrInstGen *casted_value = ir_implicit_cast(ira, new_value, resolved_type); 21429 if (type_is_invalid(casted_value->value->type)) { 21430 return ira->codegen->invalid_inst_gen; 21431 } 21432 new_incoming_values.items[i] = casted_value; 21433 predecessor->instruction_list.append(branch_instruction); 21434 21435 if (all_stack_ptrs && (casted_value->value->special != ConstValSpecialRuntime || 21436 casted_value->value->data.rh_ptr != RuntimeHintPtrStack)) 21437 { 21438 all_stack_ptrs = false; 21439 } 21440 } 21441 ir_set_cursor_at_end_gen(&ira->new_irb, cur_bb); 21442 21443 IrInstGen *result = ir_build_phi_gen(ira, &phi_instruction->base.base, 21444 new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items, resolved_type); 21445 21446 if (all_stack_ptrs) { 21447 assert(result->value->special == ConstValSpecialRuntime); 21448 result->value->data.rh_ptr = RuntimeHintPtrStack; 21449 } 21450 21451 return result; 21452 } 21453 21454 static IrInstGen *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstSrcVarPtr *instruction) { 21455 ZigVar *var = instruction->var; 21456 IrInstGen *result = ir_get_var_ptr(ira, &instruction->base.base, var); 21457 if (instruction->crossed_fndef_scope != nullptr && !instr_is_comptime(result)) { 21458 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 21459 buf_sprintf("'%s' not accessible from inner function", var->name)); 21460 add_error_note(ira->codegen, msg, instruction->crossed_fndef_scope->base.source_node, 21461 buf_sprintf("crossed function definition here")); 21462 add_error_note(ira->codegen, msg, var->decl_node, 21463 buf_sprintf("declared here")); 21464 return ira->codegen->invalid_inst_gen; 21465 } 21466 return result; 21467 } 21468 21469 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align) { 21470 assert(ptr_type->id == ZigTypeIdPointer); 21471 return get_pointer_to_type_extra2(g, 21472 ptr_type->data.pointer.child_type, 21473 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21474 ptr_type->data.pointer.ptr_len, 21475 new_align, 21476 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 21477 ptr_type->data.pointer.allow_zero, 21478 ptr_type->data.pointer.vector_index, 21479 ptr_type->data.pointer.inferred_struct_field, 21480 ptr_type->data.pointer.sentinel); 21481 } 21482 21483 static ZigType *adjust_ptr_sentinel(CodeGen *g, ZigType *ptr_type, ZigValue *new_sentinel) { 21484 assert(ptr_type->id == ZigTypeIdPointer); 21485 return get_pointer_to_type_extra2(g, 21486 ptr_type->data.pointer.child_type, 21487 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21488 ptr_type->data.pointer.ptr_len, 21489 ptr_type->data.pointer.explicit_alignment, 21490 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 21491 ptr_type->data.pointer.allow_zero, 21492 ptr_type->data.pointer.vector_index, 21493 ptr_type->data.pointer.inferred_struct_field, 21494 new_sentinel); 21495 } 21496 21497 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) { 21498 assert(is_slice(slice_type)); 21499 ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index]->type_entry, 21500 new_align); 21501 return get_slice_type(g, ptr_type); 21502 } 21503 21504 static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) { 21505 assert(ptr_type->id == ZigTypeIdPointer); 21506 return get_pointer_to_type_extra2(g, 21507 ptr_type->data.pointer.child_type, 21508 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21509 ptr_len, 21510 ptr_type->data.pointer.explicit_alignment, 21511 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 21512 ptr_type->data.pointer.allow_zero, 21513 ptr_type->data.pointer.vector_index, 21514 ptr_type->data.pointer.inferred_struct_field, 21515 (ptr_len != PtrLenUnknown) ? nullptr : ptr_type->data.pointer.sentinel); 21516 } 21517 21518 static ZigType *adjust_ptr_allow_zero(CodeGen *g, ZigType *ptr_type, bool allow_zero) { 21519 assert(ptr_type->id == ZigTypeIdPointer); 21520 return get_pointer_to_type_extra2(g, 21521 ptr_type->data.pointer.child_type, 21522 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21523 ptr_type->data.pointer.ptr_len, 21524 ptr_type->data.pointer.explicit_alignment, 21525 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 21526 allow_zero, 21527 ptr_type->data.pointer.vector_index, 21528 ptr_type->data.pointer.inferred_struct_field, 21529 ptr_type->data.pointer.sentinel); 21530 } 21531 21532 static ZigType *adjust_ptr_const(CodeGen *g, ZigType *ptr_type, bool is_const) { 21533 assert(ptr_type->id == ZigTypeIdPointer); 21534 return get_pointer_to_type_extra2(g, 21535 ptr_type->data.pointer.child_type, 21536 is_const, ptr_type->data.pointer.is_volatile, 21537 ptr_type->data.pointer.ptr_len, 21538 ptr_type->data.pointer.explicit_alignment, 21539 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, 21540 ptr_type->data.pointer.allow_zero, 21541 ptr_type->data.pointer.vector_index, 21542 ptr_type->data.pointer.inferred_struct_field, 21543 ptr_type->data.pointer.sentinel); 21544 } 21545 21546 static Error compute_elem_align(IrAnalyze *ira, ZigType *elem_type, uint32_t base_ptr_align, 21547 uint64_t elem_index, uint32_t *result) 21548 { 21549 Error err; 21550 21551 if (base_ptr_align == 0) { 21552 *result = 0; 21553 return ErrorNone; 21554 } 21555 21556 // figure out the largest alignment possible 21557 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) 21558 return err; 21559 21560 uint64_t elem_size = type_size(ira->codegen, elem_type); 21561 uint64_t abi_align = get_abi_alignment(ira->codegen, elem_type); 21562 uint64_t ptr_align = base_ptr_align; 21563 21564 uint64_t chosen_align = abi_align; 21565 if (ptr_align >= abi_align) { 21566 while (ptr_align > abi_align) { 21567 if ((elem_index * elem_size) % ptr_align == 0) { 21568 chosen_align = ptr_align; 21569 break; 21570 } 21571 ptr_align >>= 1; 21572 } 21573 } else if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 21574 chosen_align = ptr_align; 21575 } else { 21576 // can't get here because guaranteed elem_size >= abi_align 21577 zig_unreachable(); 21578 } 21579 21580 *result = chosen_align; 21581 return ErrorNone; 21582 } 21583 21584 static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemPtr *elem_ptr_instruction) { 21585 Error err; 21586 IrInstGen *array_ptr = elem_ptr_instruction->array_ptr->child; 21587 if (type_is_invalid(array_ptr->value->type)) 21588 return ira->codegen->invalid_inst_gen; 21589 21590 IrInstGen *elem_index = elem_ptr_instruction->elem_index->child; 21591 if (type_is_invalid(elem_index->value->type)) 21592 return ira->codegen->invalid_inst_gen; 21593 21594 ZigValue *orig_array_ptr_val = array_ptr->value; 21595 21596 ZigType *ptr_type = orig_array_ptr_val->type; 21597 assert(ptr_type->id == ZigTypeIdPointer); 21598 21599 ZigType *array_type = ptr_type->data.pointer.child_type; 21600 21601 // At first return_type will be the pointer type we want to return, except with an optimistic alignment. 21602 // We will adjust return_type's alignment before returning it. 21603 ZigType *return_type; 21604 21605 if (type_is_invalid(array_type)) 21606 return ira->codegen->invalid_inst_gen; 21607 21608 if (array_type->id == ZigTypeIdPointer && 21609 array_type->data.pointer.ptr_len == PtrLenSingle && 21610 array_type->data.pointer.child_type->id == ZigTypeIdArray) 21611 { 21612 IrInstGen *ptr_value = ir_get_deref(ira, &elem_ptr_instruction->base.base, 21613 array_ptr, nullptr); 21614 if (type_is_invalid(ptr_value->value->type)) 21615 return ira->codegen->invalid_inst_gen; 21616 21617 array_type = array_type->data.pointer.child_type; 21618 ptr_type = ptr_type->data.pointer.child_type; 21619 21620 orig_array_ptr_val = ptr_value->value; 21621 } 21622 21623 if (array_type->id == ZigTypeIdArray) { 21624 if(array_type->data.array.len == 0 && array_type->data.array.sentinel == nullptr){ 21625 ir_add_error(ira, &elem_ptr_instruction->base.base, buf_sprintf("accessing a zero length array is not allowed")); 21626 return ira->codegen->invalid_inst_gen; 21627 } 21628 21629 ZigType *child_type = array_type->data.array.child_type; 21630 if (ptr_type->data.pointer.host_int_bytes == 0) { 21631 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 21632 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21633 elem_ptr_instruction->ptr_len, 21634 ptr_type->data.pointer.explicit_alignment, 0, 0, false); 21635 } else { 21636 uint64_t elem_val_scalar; 21637 if (!ir_resolve_usize(ira, elem_index, &elem_val_scalar)) 21638 return ira->codegen->invalid_inst_gen; 21639 21640 size_t bit_width = type_size_bits(ira->codegen, child_type); 21641 size_t bit_offset = bit_width * elem_val_scalar; 21642 21643 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 21644 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21645 elem_ptr_instruction->ptr_len, 21646 1, (uint32_t)bit_offset, ptr_type->data.pointer.host_int_bytes, false); 21647 } 21648 } else if (array_type->id == ZigTypeIdPointer) { 21649 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 21650 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 21651 buf_sprintf("index of single-item pointer")); 21652 return ira->codegen->invalid_inst_gen; 21653 } 21654 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len); 21655 } else if (is_slice(array_type)) { 21656 return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index]->type_entry, 21657 elem_ptr_instruction->ptr_len); 21658 } else if (array_type->id == ZigTypeIdVector) { 21659 // This depends on whether the element index is comptime, so it is computed later. 21660 return_type = nullptr; 21661 } else if (elem_ptr_instruction->init_array_type_source_node != nullptr && 21662 array_type->id == ZigTypeIdStruct && 21663 array_type->data.structure.resolve_status == ResolveStatusBeingInferred) 21664 { 21665 ZigType *usize = ira->codegen->builtin_types.entry_usize; 21666 IrInstGen *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); 21667 if (type_is_invalid(casted_elem_index->value->type)) 21668 return ira->codegen->invalid_inst_gen; 21669 ir_assert(instr_is_comptime(casted_elem_index), &elem_ptr_instruction->base.base); 21670 Buf *field_name = buf_alloc(); 21671 bigint_append_buf(field_name, &casted_elem_index->value->data.x_bigint, 10); 21672 return ir_analyze_inferred_field_ptr(ira, field_name, &elem_ptr_instruction->base.base, 21673 array_ptr, array_type); 21674 } else if (is_tuple(array_type)) { 21675 uint64_t elem_index_scalar; 21676 if (!ir_resolve_usize(ira, elem_index, &elem_index_scalar)) 21677 return ira->codegen->invalid_inst_gen; 21678 if (elem_index_scalar >= array_type->data.structure.src_field_count) { 21679 ir_add_error(ira, &elem_ptr_instruction->base.base, buf_sprintf( 21680 "field index %" ZIG_PRI_u64 " outside tuple '%s' which has %" PRIu32 " fields", 21681 elem_index_scalar, buf_ptr(&array_type->name), 21682 array_type->data.structure.src_field_count)); 21683 return ira->codegen->invalid_inst_gen; 21684 } 21685 TypeStructField *field = array_type->data.structure.fields[elem_index_scalar]; 21686 return ir_analyze_struct_field_ptr(ira, &elem_ptr_instruction->base.base, field, array_ptr, 21687 array_type, false); 21688 } else { 21689 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 21690 buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name))); 21691 return ira->codegen->invalid_inst_gen; 21692 } 21693 21694 ZigType *usize = ira->codegen->builtin_types.entry_usize; 21695 IrInstGen *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); 21696 if (type_is_invalid(casted_elem_index->value->type)) 21697 return ira->codegen->invalid_inst_gen; 21698 21699 bool safety_check_on = elem_ptr_instruction->safety_check_on; 21700 if (instr_is_comptime(casted_elem_index)) { 21701 ZigValue *index_val = ir_resolve_const(ira, casted_elem_index, UndefBad); 21702 if (index_val == nullptr) 21703 return ira->codegen->invalid_inst_gen; 21704 uint64_t index = bigint_as_u64(&index_val->data.x_bigint); 21705 21706 if (array_type->id == ZigTypeIdArray) { 21707 uint64_t array_len = array_type->data.array.len + 21708 (array_type->data.array.sentinel != nullptr); 21709 if (index >= array_len) { 21710 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 21711 buf_sprintf("index %" ZIG_PRI_u64 " outside array of size %" ZIG_PRI_u64, 21712 index, array_len)); 21713 return ira->codegen->invalid_inst_gen; 21714 } 21715 safety_check_on = false; 21716 } 21717 if (array_type->id == ZigTypeIdVector) { 21718 ZigType *elem_type = array_type->data.vector.elem_type; 21719 uint32_t host_vec_len = array_type->data.vector.len; 21720 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 21721 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21722 elem_ptr_instruction->ptr_len, 21723 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, (uint32_t)index, 21724 nullptr, nullptr); 21725 } else if (return_type->data.pointer.explicit_alignment != 0) { 21726 uint32_t chosen_align; 21727 if ((err = compute_elem_align(ira, return_type->data.pointer.child_type, 21728 return_type->data.pointer.explicit_alignment, index, &chosen_align))) 21729 { 21730 return ira->codegen->invalid_inst_gen; 21731 } 21732 return_type = adjust_ptr_align(ira->codegen, return_type, chosen_align); 21733 } 21734 21735 // TODO The `array_type->id == ZigTypeIdArray` exception here should not be an exception; 21736 // the `orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar` clause should be omitted completely. 21737 // However there are bugs to fix before this improvement can be made. 21738 if (orig_array_ptr_val->special != ConstValSpecialRuntime && 21739 orig_array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && 21740 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == ZigTypeIdArray)) 21741 { 21742 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 21743 elem_ptr_instruction->base.base.source_node, orig_array_ptr_val, UndefBad))) 21744 { 21745 return ira->codegen->invalid_inst_gen; 21746 } 21747 21748 ZigValue *array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val, 21749 elem_ptr_instruction->base.base.source_node); 21750 if (array_ptr_val == nullptr) 21751 return ira->codegen->invalid_inst_gen; 21752 21753 if (array_ptr_val->special == ConstValSpecialUndef && 21754 elem_ptr_instruction->init_array_type_source_node != nullptr) 21755 { 21756 if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) { 21757 array_ptr_val->data.x_array.special = ConstArraySpecialNone; 21758 array_ptr_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(array_type->data.array.len); 21759 array_ptr_val->special = ConstValSpecialStatic; 21760 for (size_t i = 0; i < array_type->data.array.len; i += 1) { 21761 ZigValue *elem_val = &array_ptr_val->data.x_array.data.s_none.elements[i]; 21762 elem_val->special = ConstValSpecialUndef; 21763 elem_val->type = array_type->data.array.child_type; 21764 elem_val->parent.id = ConstParentIdArray; 21765 elem_val->parent.data.p_array.array_val = array_ptr_val; 21766 elem_val->parent.data.p_array.elem_index = i; 21767 } 21768 } else if (is_slice(array_type)) { 21769 ir_assert(array_ptr->value->type->id == ZigTypeIdPointer, &elem_ptr_instruction->base.base); 21770 ZigType *actual_array_type = array_ptr->value->type->data.pointer.child_type; 21771 21772 if (type_is_invalid(actual_array_type)) 21773 return ira->codegen->invalid_inst_gen; 21774 if (actual_array_type->id != ZigTypeIdArray) { 21775 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, 21776 buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", 21777 buf_ptr(&actual_array_type->name))); 21778 return ira->codegen->invalid_inst_gen; 21779 } 21780 21781 ZigValue *array_init_val = ira->codegen->pass1_arena->create<ZigValue>(); 21782 array_init_val->special = ConstValSpecialStatic; 21783 array_init_val->type = actual_array_type; 21784 array_init_val->data.x_array.special = ConstArraySpecialNone; 21785 array_init_val->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(actual_array_type->data.array.len); 21786 array_init_val->special = ConstValSpecialStatic; 21787 for (size_t i = 0; i < actual_array_type->data.array.len; i += 1) { 21788 ZigValue *elem_val = &array_init_val->data.x_array.data.s_none.elements[i]; 21789 elem_val->special = ConstValSpecialUndef; 21790 elem_val->type = actual_array_type->data.array.child_type; 21791 elem_val->parent.id = ConstParentIdArray; 21792 elem_val->parent.data.p_array.array_val = array_init_val; 21793 elem_val->parent.data.p_array.elem_index = i; 21794 } 21795 21796 init_const_slice(ira->codegen, array_ptr_val, array_init_val, 0, actual_array_type->data.array.len, 21797 false); 21798 array_ptr_val->data.x_struct.fields[slice_ptr_index]->data.x_ptr.mut = ConstPtrMutInfer; 21799 } else { 21800 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node, 21801 buf_sprintf("expected array type or [_], found '%s'", 21802 buf_ptr(&array_type->name))); 21803 return ira->codegen->invalid_inst_gen; 21804 } 21805 } 21806 21807 if (array_ptr_val->special != ConstValSpecialRuntime && 21808 (array_type->id != ZigTypeIdPointer || 21809 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) 21810 { 21811 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 21812 elem_ptr_instruction->base.base.source_node, array_ptr_val, UndefOk))) 21813 { 21814 return ira->codegen->invalid_inst_gen; 21815 } 21816 if (array_type->id == ZigTypeIdPointer) { 21817 IrInstGen *result = ir_const(ira, &elem_ptr_instruction->base.base, return_type); 21818 ZigValue *out_val = result->value; 21819 out_val->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; 21820 size_t new_index; 21821 size_t mem_size; 21822 size_t old_size; 21823 switch (array_ptr_val->data.x_ptr.special) { 21824 case ConstPtrSpecialInvalid: 21825 case ConstPtrSpecialDiscard: 21826 zig_unreachable(); 21827 case ConstPtrSpecialRef: 21828 if (array_ptr_val->data.x_ptr.data.ref.pointee->type->id == ZigTypeIdArray) { 21829 ZigValue *array_val = array_ptr_val->data.x_ptr.data.ref.pointee; 21830 new_index = index; 21831 ZigType *array_type = array_val->type; 21832 mem_size = array_type->data.array.len; 21833 if (array_type->data.array.sentinel != nullptr) { 21834 mem_size += 1; 21835 } 21836 old_size = mem_size; 21837 21838 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 21839 out_val->data.x_ptr.data.base_array.array_val = array_val; 21840 out_val->data.x_ptr.data.base_array.elem_index = new_index; 21841 } else { 21842 mem_size = 1; 21843 old_size = 1; 21844 new_index = index; 21845 21846 out_val->data.x_ptr.special = ConstPtrSpecialRef; 21847 out_val->data.x_ptr.data.ref.pointee = array_ptr_val->data.x_ptr.data.ref.pointee; 21848 } 21849 break; 21850 case ConstPtrSpecialBaseArray: 21851 case ConstPtrSpecialSubArray: 21852 { 21853 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index; 21854 new_index = offset + index; 21855 ZigType *array_type = array_ptr_val->data.x_ptr.data.base_array.array_val->type; 21856 mem_size = array_type->data.array.len; 21857 if (array_type->data.array.sentinel != nullptr) { 21858 mem_size += 1; 21859 } 21860 old_size = mem_size - offset; 21861 21862 assert(array_ptr_val->data.x_ptr.data.base_array.array_val); 21863 21864 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 21865 out_val->data.x_ptr.data.base_array.array_val = 21866 array_ptr_val->data.x_ptr.data.base_array.array_val; 21867 out_val->data.x_ptr.data.base_array.elem_index = new_index; 21868 21869 break; 21870 } 21871 case ConstPtrSpecialBaseStruct: 21872 zig_panic("TODO elem ptr on a const inner struct"); 21873 case ConstPtrSpecialBaseErrorUnionCode: 21874 zig_panic("TODO elem ptr on a const inner error union code"); 21875 case ConstPtrSpecialBaseErrorUnionPayload: 21876 zig_panic("TODO elem ptr on a const inner error union payload"); 21877 case ConstPtrSpecialBaseOptionalPayload: 21878 zig_panic("TODO elem ptr on a const inner optional payload"); 21879 case ConstPtrSpecialHardCodedAddr: 21880 zig_unreachable(); 21881 case ConstPtrSpecialFunction: 21882 zig_panic("TODO element ptr of a function casted to a ptr"); 21883 case ConstPtrSpecialNull: 21884 zig_panic("TODO elem ptr on a null pointer"); 21885 } 21886 if (new_index >= mem_size) { 21887 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 21888 buf_sprintf("index %" ZIG_PRI_u64 " outside pointer of size %" ZIG_PRI_usize "", index, old_size)); 21889 return ira->codegen->invalid_inst_gen; 21890 } 21891 return result; 21892 } else if (is_slice(array_type)) { 21893 ZigValue *ptr_field = array_ptr_val->data.x_struct.fields[slice_ptr_index]; 21894 ir_assert(ptr_field != nullptr, &elem_ptr_instruction->base.base); 21895 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 21896 return ir_build_elem_ptr_gen(ira, elem_ptr_instruction->base.base.scope, 21897 elem_ptr_instruction->base.base.source_node, array_ptr, casted_elem_index, false, 21898 return_type); 21899 } 21900 ZigValue *len_field = array_ptr_val->data.x_struct.fields[slice_len_index]; 21901 IrInstGen *result = ir_const(ira, &elem_ptr_instruction->base.base, return_type); 21902 ZigValue *out_val = result->value; 21903 ZigType *slice_ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; 21904 uint64_t slice_len = bigint_as_u64(&len_field->data.x_bigint); 21905 uint64_t full_slice_len = slice_len + 21906 ((slice_ptr_type->data.pointer.sentinel != nullptr) ? 1 : 0); 21907 if (index >= full_slice_len) { 21908 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, 21909 buf_sprintf("index %" ZIG_PRI_u64 " outside slice of size %" ZIG_PRI_u64, 21910 index, slice_len)); 21911 return ira->codegen->invalid_inst_gen; 21912 } 21913 out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut; 21914 switch (ptr_field->data.x_ptr.special) { 21915 case ConstPtrSpecialInvalid: 21916 case ConstPtrSpecialDiscard: 21917 zig_unreachable(); 21918 case ConstPtrSpecialRef: 21919 out_val->data.x_ptr.special = ConstPtrSpecialRef; 21920 out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee; 21921 break; 21922 case ConstPtrSpecialSubArray: 21923 case ConstPtrSpecialBaseArray: 21924 { 21925 size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index; 21926 uint64_t new_index = offset + index; 21927 if (ptr_field->data.x_ptr.data.base_array.array_val->data.x_array.special != 21928 ConstArraySpecialBuf) 21929 { 21930 ir_assert(new_index < 21931 ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len, 21932 &elem_ptr_instruction->base.base); 21933 } 21934 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 21935 out_val->data.x_ptr.data.base_array.array_val = 21936 ptr_field->data.x_ptr.data.base_array.array_val; 21937 out_val->data.x_ptr.data.base_array.elem_index = new_index; 21938 break; 21939 } 21940 case ConstPtrSpecialBaseStruct: 21941 zig_panic("TODO elem ptr on a slice backed by const inner struct"); 21942 case ConstPtrSpecialBaseErrorUnionCode: 21943 zig_panic("TODO elem ptr on a slice backed by const inner error union code"); 21944 case ConstPtrSpecialBaseErrorUnionPayload: 21945 zig_panic("TODO elem ptr on a slice backed by const inner error union payload"); 21946 case ConstPtrSpecialBaseOptionalPayload: 21947 zig_panic("TODO elem ptr on a slice backed by const optional payload"); 21948 case ConstPtrSpecialHardCodedAddr: 21949 zig_unreachable(); 21950 case ConstPtrSpecialFunction: 21951 zig_panic("TODO elem ptr on a slice that was ptrcast from a function"); 21952 case ConstPtrSpecialNull: 21953 zig_panic("TODO elem ptr on a slice has a null pointer"); 21954 } 21955 return result; 21956 } else if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) { 21957 IrInstGen *result; 21958 if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 21959 result = ir_build_elem_ptr_gen(ira, elem_ptr_instruction->base.base.scope, 21960 elem_ptr_instruction->base.base.source_node, array_ptr, casted_elem_index, 21961 false, return_type); 21962 result->value->special = ConstValSpecialStatic; 21963 } else { 21964 result = ir_const(ira, &elem_ptr_instruction->base.base, return_type); 21965 } 21966 ZigValue *out_val = result->value; 21967 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 21968 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; 21969 out_val->data.x_ptr.data.base_array.array_val = array_ptr_val; 21970 out_val->data.x_ptr.data.base_array.elem_index = index; 21971 return result; 21972 } else { 21973 zig_unreachable(); 21974 } 21975 } 21976 } 21977 } else if (array_type->id == ZigTypeIdVector) { 21978 // runtime known element index 21979 ZigType *elem_type = array_type->data.vector.elem_type; 21980 uint32_t host_vec_len = array_type->data.vector.len; 21981 return_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 21982 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 21983 elem_ptr_instruction->ptr_len, 21984 get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, VECTOR_INDEX_RUNTIME, 21985 nullptr, nullptr); 21986 } else { 21987 // runtime known element index 21988 switch (type_requires_comptime(ira->codegen, return_type)) { 21989 case ReqCompTimeYes: 21990 ir_add_error(ira, &elem_index->base, 21991 buf_sprintf("values of type '%s' must be comptime known, but index value is runtime known", 21992 buf_ptr(&return_type->data.pointer.child_type->name))); 21993 return ira->codegen->invalid_inst_gen; 21994 case ReqCompTimeInvalid: 21995 return ira->codegen->invalid_inst_gen; 21996 case ReqCompTimeNo: 21997 break; 21998 } 21999 22000 if (return_type->data.pointer.explicit_alignment != 0) { 22001 if ((err = type_resolve(ira->codegen, return_type->data.pointer.child_type, ResolveStatusSizeKnown))) 22002 return ira->codegen->invalid_inst_gen; 22003 22004 uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); 22005 uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); 22006 uint64_t ptr_align = get_ptr_align(ira->codegen, return_type); 22007 if (ptr_align < abi_align) { 22008 if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 22009 return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align); 22010 } else { 22011 // can't get here because guaranteed elem_size >= abi_align 22012 zig_unreachable(); 22013 } 22014 } else { 22015 return_type = adjust_ptr_align(ira->codegen, return_type, abi_align); 22016 } 22017 } 22018 } 22019 22020 return ir_build_elem_ptr_gen(ira, elem_ptr_instruction->base.base.scope, 22021 elem_ptr_instruction->base.base.source_node, array_ptr, casted_elem_index, safety_check_on, return_type); 22022 } 22023 22024 static IrInstGen *ir_analyze_container_member_access_inner(IrAnalyze *ira, 22025 ZigType *bare_struct_type, Buf *field_name, IrInst* source_instr, 22026 IrInstGen *container_ptr, IrInst *container_ptr_src, ZigType *container_type) 22027 { 22028 if (!is_slice(bare_struct_type)) { 22029 ScopeDecls *container_scope = get_container_scope(bare_struct_type); 22030 assert(container_scope != nullptr); 22031 auto tld = find_container_decl(ira->codegen, container_scope, field_name); 22032 if (tld) { 22033 if (tld->id == TldIdFn) { 22034 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); 22035 if (tld->resolution == TldResolutionInvalid) 22036 return ira->codegen->invalid_inst_gen; 22037 if (tld->resolution == TldResolutionResolving) 22038 return ir_error_dependency_loop(ira, source_instr); 22039 22040 if (tld->visib_mod == VisibModPrivate && 22041 tld->import != get_scope_import(source_instr->scope)) 22042 { 22043 ErrorMsg *msg = ir_add_error(ira, source_instr, 22044 buf_sprintf("'%s' is private", buf_ptr(field_name))); 22045 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); 22046 return ira->codegen->invalid_inst_gen; 22047 } 22048 22049 TldFn *tld_fn = (TldFn *)tld; 22050 ZigFn *fn_entry = tld_fn->fn_entry; 22051 assert(fn_entry != nullptr); 22052 22053 if (type_is_invalid(fn_entry->type_entry)) 22054 return ira->codegen->invalid_inst_gen; 22055 22056 IrInstGen *bound_fn_value = ir_const_bound_fn(ira, source_instr, fn_entry, container_ptr, 22057 container_ptr_src); 22058 return ir_get_ref(ira, source_instr, bound_fn_value, true, false); 22059 } else if (tld->id == TldIdVar) { 22060 resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); 22061 if (tld->resolution == TldResolutionInvalid) 22062 return ira->codegen->invalid_inst_gen; 22063 if (tld->resolution == TldResolutionResolving) 22064 return ir_error_dependency_loop(ira, source_instr); 22065 22066 TldVar *tld_var = (TldVar *)tld; 22067 ZigVar *var = tld_var->var; 22068 assert(var != nullptr); 22069 22070 if (type_is_invalid(var->var_type)) 22071 return ira->codegen->invalid_inst_gen; 22072 22073 if (var->const_value->type->id == ZigTypeIdFn) { 22074 ir_assert(var->const_value->data.x_ptr.special == ConstPtrSpecialFunction, source_instr); 22075 ZigFn *fn = var->const_value->data.x_ptr.data.fn.fn_entry; 22076 IrInstGen *bound_fn_value = ir_const_bound_fn(ira, source_instr, fn, container_ptr, 22077 container_ptr_src); 22078 return ir_get_ref(ira, source_instr, bound_fn_value, true, false); 22079 } 22080 } 22081 } 22082 } 22083 const char *prefix_name; 22084 if (is_slice(bare_struct_type)) { 22085 prefix_name = ""; 22086 } else if (bare_struct_type->id == ZigTypeIdStruct) { 22087 prefix_name = "struct "; 22088 } else if (bare_struct_type->id == ZigTypeIdEnum) { 22089 prefix_name = "enum "; 22090 } else if (bare_struct_type->id == ZigTypeIdUnion) { 22091 prefix_name = "union "; 22092 } else { 22093 prefix_name = ""; 22094 } 22095 ir_add_error_node(ira, source_instr->source_node, 22096 buf_sprintf("no member named '%s' in %s'%s'", buf_ptr(field_name), prefix_name, buf_ptr(&bare_struct_type->name))); 22097 return ira->codegen->invalid_inst_gen; 22098 } 22099 22100 static void memoize_field_init_val(CodeGen *codegen, ZigType *container_type, TypeStructField *field) { 22101 if (field->init_val != nullptr) return; 22102 if (field->decl_node->type != NodeTypeStructField) return; 22103 AstNode *init_node = field->decl_node->data.struct_field.value; 22104 if (init_node == nullptr) return; 22105 // scope is not the scope of the struct init, it's the scope of the struct type decl 22106 Scope *analyze_scope = &get_container_scope(container_type)->base; 22107 // memoize it 22108 field->init_val = analyze_const_value(codegen, analyze_scope, init_node, 22109 field->type_entry, nullptr, UndefOk); 22110 } 22111 22112 static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_instr, 22113 TypeStructField *field, IrInstGen *struct_ptr, ZigType *struct_type, bool initializing) 22114 { 22115 Error err; 22116 ZigType *field_type = resolve_struct_field_type(ira->codegen, field); 22117 if (field_type == nullptr) 22118 return ira->codegen->invalid_inst_gen; 22119 if (field->is_comptime) { 22120 IrInstGen *elem = ir_const(ira, source_instr, field_type); 22121 memoize_field_init_val(ira->codegen, struct_type, field); 22122 if(field->init_val != nullptr && type_is_invalid(field->init_val->type)){ 22123 return ira->codegen->invalid_inst_gen; 22124 } 22125 copy_const_val(ira->codegen, elem->value, field->init_val); 22126 return ir_get_ref2(ira, source_instr, elem, field_type, true, false); 22127 } 22128 switch (type_has_one_possible_value(ira->codegen, field_type)) { 22129 case OnePossibleValueInvalid: 22130 return ira->codegen->invalid_inst_gen; 22131 case OnePossibleValueYes: { 22132 IrInstGen *elem = ir_const_move(ira, source_instr, 22133 get_the_one_possible_value(ira->codegen, field_type)); 22134 return ir_get_ref(ira, source_instr, elem, 22135 struct_ptr->value->type->data.pointer.is_const, 22136 struct_ptr->value->type->data.pointer.is_volatile); 22137 } 22138 case OnePossibleValueNo: 22139 break; 22140 } 22141 bool is_const = struct_ptr->value->type->data.pointer.is_const; 22142 bool is_volatile = struct_ptr->value->type->data.pointer.is_volatile; 22143 ZigType *ptr_type; 22144 if (is_anon_container(struct_type)) { 22145 ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 22146 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 22147 } else { 22148 ResolveStatus needed_resolve_status = 22149 (struct_type->data.structure.layout == ContainerLayoutAuto) ? 22150 ResolveStatusZeroBitsKnown : ResolveStatusSizeKnown; 22151 if ((err = type_resolve(ira->codegen, struct_type, needed_resolve_status))) 22152 return ira->codegen->invalid_inst_gen; 22153 assert(struct_ptr->value->type->id == ZigTypeIdPointer); 22154 uint32_t ptr_bit_offset = struct_ptr->value->type->data.pointer.bit_offset_in_host; 22155 uint32_t ptr_host_int_bytes = struct_ptr->value->type->data.pointer.host_int_bytes; 22156 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? 22157 get_host_int_bytes(ira->codegen, struct_type, field) : ptr_host_int_bytes; 22158 ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 22159 is_const, is_volatile, PtrLenSingle, field->align, 22160 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), 22161 (uint32_t)host_int_bytes_for_result_type, false); 22162 } 22163 if (instr_is_comptime(struct_ptr)) { 22164 ZigValue *ptr_val = ir_resolve_const(ira, struct_ptr, UndefBad); 22165 if (!ptr_val) 22166 return ira->codegen->invalid_inst_gen; 22167 22168 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 22169 ZigValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 22170 if (struct_val == nullptr) 22171 return ira->codegen->invalid_inst_gen; 22172 if (type_is_invalid(struct_val->type)) 22173 return ira->codegen->invalid_inst_gen; 22174 22175 // This to allow lazy values to be resolved. 22176 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 22177 source_instr->source_node, struct_val, UndefOk))) 22178 { 22179 return ira->codegen->invalid_inst_gen; 22180 } 22181 if (initializing && struct_val->special == ConstValSpecialUndef) { 22182 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count); 22183 struct_val->special = ConstValSpecialStatic; 22184 for (size_t i = 0; i < struct_type->data.structure.src_field_count; i += 1) { 22185 ZigValue *field_val = struct_val->data.x_struct.fields[i]; 22186 field_val->special = ConstValSpecialUndef; 22187 field_val->type = resolve_struct_field_type(ira->codegen, 22188 struct_type->data.structure.fields[i]); 22189 field_val->parent.id = ConstParentIdStruct; 22190 field_val->parent.data.p_struct.struct_val = struct_val; 22191 field_val->parent.data.p_struct.field_index = i; 22192 } 22193 } 22194 IrInstGen *result; 22195 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 22196 result = ir_build_struct_field_ptr(ira, source_instr, struct_ptr, field, ptr_type); 22197 result->value->special = ConstValSpecialStatic; 22198 } else { 22199 result = ir_const(ira, source_instr, ptr_type); 22200 } 22201 ZigValue *const_val = result->value; 22202 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; 22203 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 22204 const_val->data.x_ptr.data.base_struct.struct_val = struct_val; 22205 const_val->data.x_ptr.data.base_struct.field_index = field->src_index; 22206 return result; 22207 } 22208 } 22209 return ir_build_struct_field_ptr(ira, source_instr, struct_ptr, field, ptr_type); 22210 } 22211 22212 static IrInstGen *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, 22213 IrInst* source_instr, IrInstGen *container_ptr, ZigType *container_type) 22214 { 22215 // The type of the field is not available until a store using this pointer happens. 22216 // So, here we create a special pointer type which has the inferred struct type and 22217 // field name encoded in the type. Later, when there is a store via this pointer, 22218 // the field type will then be available, and the field will be added to the inferred 22219 // struct. 22220 22221 ZigType *container_ptr_type = container_ptr->value->type; 22222 ir_assert(container_ptr_type->id == ZigTypeIdPointer, source_instr); 22223 22224 InferredStructField *inferred_struct_field = heap::c_allocator.create<InferredStructField>(); 22225 inferred_struct_field->inferred_struct_type = container_type; 22226 inferred_struct_field->field_name = field_name; 22227 22228 ZigType *elem_type = ira->codegen->builtin_types.entry_var; 22229 ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 22230 container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile, 22231 PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field, nullptr); 22232 22233 if (instr_is_comptime(container_ptr)) { 22234 ZigValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 22235 if (ptr_val == nullptr) 22236 return ira->codegen->invalid_inst_gen; 22237 22238 IrInstGen *result; 22239 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 22240 result = ir_build_cast(ira, source_instr, container_ptr_type, container_ptr, CastOpNoop); 22241 } else { 22242 result = ir_const(ira, source_instr, field_ptr_type); 22243 } 22244 copy_const_val(ira->codegen, result->value, ptr_val); 22245 result->value->type = field_ptr_type; 22246 return result; 22247 } 22248 22249 return ir_build_cast(ira, source_instr, field_ptr_type, container_ptr, CastOpNoop); 22250 } 22251 22252 static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 22253 IrInst* source_instr, IrInstGen *container_ptr, IrInst *container_ptr_src, 22254 ZigType *container_type, bool initializing) 22255 { 22256 Error err; 22257 22258 ZigType *bare_type = container_ref_type(container_type); 22259 22260 if (initializing && bare_type->id == ZigTypeIdStruct && 22261 bare_type->data.structure.resolve_status == ResolveStatusBeingInferred) 22262 { 22263 return ir_analyze_inferred_field_ptr(ira, field_name, source_instr, container_ptr, bare_type); 22264 } 22265 22266 // Tracks wether we should return an undefined value of the correct type. 22267 // We do this if the container pointer is undefined and we are in a TypeOf call. 22268 bool return_undef = container_ptr->value->special == ConstValSpecialUndef && \ 22269 get_scope_typeof(source_instr->scope) != nullptr; 22270 22271 if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown))) 22272 return ira->codegen->invalid_inst_gen; 22273 22274 assert(container_ptr->value->type->id == ZigTypeIdPointer); 22275 if (bare_type->id == ZigTypeIdStruct) { 22276 TypeStructField *field = find_struct_type_field(bare_type, field_name); 22277 if (field != nullptr) { 22278 if (return_undef) { 22279 ZigType *field_ptr_type = get_pointer_to_type(ira->codegen, resolve_struct_field_type(ira->codegen, field), 22280 container_ptr->value->type->data.pointer.is_const); 22281 return ir_const_undef(ira, source_instr, field_ptr_type); 22282 } 22283 22284 return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); 22285 } else { 22286 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 22287 source_instr, container_ptr, container_ptr_src, container_type); 22288 } 22289 } 22290 22291 if (bare_type->id == ZigTypeIdEnum) { 22292 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 22293 source_instr, container_ptr, container_ptr_src, container_type); 22294 } 22295 22296 if (bare_type->id == ZigTypeIdUnion) { 22297 bool is_const = container_ptr->value->type->data.pointer.is_const; 22298 bool is_volatile = container_ptr->value->type->data.pointer.is_volatile; 22299 22300 TypeUnionField *field = find_union_type_field(bare_type, field_name); 22301 if (field == nullptr) { 22302 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 22303 source_instr, container_ptr, container_ptr_src, container_type); 22304 } 22305 22306 ZigType *field_type = resolve_union_field_type(ira->codegen, field); 22307 if (field_type == nullptr) 22308 return ira->codegen->invalid_inst_gen; 22309 22310 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 22311 is_const, is_volatile, PtrLenSingle, 0, 0, 0, false); 22312 if (instr_is_comptime(container_ptr)) { 22313 ZigValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 22314 if (!ptr_val) 22315 return ira->codegen->invalid_inst_gen; 22316 22317 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && 22318 ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 22319 ZigValue *union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 22320 if (union_val == nullptr) 22321 return ira->codegen->invalid_inst_gen; 22322 if (type_is_invalid(union_val->type)) 22323 return ira->codegen->invalid_inst_gen; 22324 22325 if (initializing) { 22326 ZigValue *payload_val = ira->codegen->pass1_arena->create<ZigValue>(); 22327 payload_val->special = ConstValSpecialUndef; 22328 payload_val->type = field_type; 22329 payload_val->parent.id = ConstParentIdUnion; 22330 payload_val->parent.data.p_union.union_val = union_val; 22331 22332 union_val->special = ConstValSpecialStatic; 22333 bigint_init_bigint(&union_val->data.x_union.tag, &field->enum_field->value); 22334 union_val->data.x_union.payload = payload_val; 22335 } else if (bare_type->data.unionation.layout != ContainerLayoutExtern) { 22336 TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); 22337 if (actual_field == nullptr) 22338 zig_unreachable(); 22339 22340 if (field != actual_field) { 22341 ir_add_error_node(ira, source_instr->source_node, 22342 buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), 22343 buf_ptr(actual_field->name))); 22344 return ira->codegen->invalid_inst_gen; 22345 } 22346 } 22347 22348 ZigValue *payload_val = union_val->data.x_union.payload; 22349 22350 IrInstGen *result; 22351 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 22352 result = ir_build_union_field_ptr(ira, source_instr, container_ptr, field, true, 22353 initializing, ptr_type); 22354 result->value->special = ConstValSpecialStatic; 22355 } else { 22356 result = ir_const(ira, source_instr, ptr_type); 22357 } 22358 ZigValue *const_val = result->value; 22359 const_val->data.x_ptr.special = ConstPtrSpecialRef; 22360 const_val->data.x_ptr.mut = container_ptr->value->data.x_ptr.mut; 22361 const_val->data.x_ptr.data.ref.pointee = payload_val; 22362 return result; 22363 } 22364 } 22365 22366 return ir_build_union_field_ptr(ira, source_instr, container_ptr, field, true, initializing, ptr_type); 22367 } 22368 22369 zig_unreachable(); 22370 } 22371 22372 static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { 22373 bool is_libc = target_is_libc_lib_name(ira->codegen->zig_target, buf_ptr(lib_name)); 22374 if (is_libc && ira->codegen->libc_link_lib == nullptr && !ira->codegen->reported_bad_link_libc_error) { 22375 ir_add_error_node(ira, source_node, 22376 buf_sprintf("dependency on library c must be explicitly specified in the build command")); 22377 ira->codegen->reported_bad_link_libc_error = true; 22378 } 22379 22380 LinkLib *link_lib = add_link_lib(ira->codegen, lib_name); 22381 for (size_t i = 0; i < link_lib->symbols.length; i += 1) { 22382 Buf *existing_symbol_name = link_lib->symbols.at(i); 22383 if (buf_eql_buf(existing_symbol_name, symbol_name)) { 22384 return; 22385 } 22386 } 22387 22388 if (!is_libc && !target_is_wasm(ira->codegen->zig_target) && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) { 22389 ErrorMsg *msg = ir_add_error_node(ira, source_node, 22390 buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code", 22391 buf_ptr(lib_name))); 22392 add_error_note(ira->codegen, msg, source_node, 22393 buf_sprintf("fixed by `--library %s` or `-fPIC`", buf_ptr(lib_name))); 22394 ira->codegen->reported_bad_link_libc_error = true; 22395 } 22396 22397 for (size_t i = 0; i < ira->codegen->forbidden_libs.length; i += 1) { 22398 Buf *forbidden_lib_name = ira->codegen->forbidden_libs.at(i); 22399 if (buf_eql_buf(lib_name, forbidden_lib_name)) { 22400 ir_add_error_node(ira, source_node, 22401 buf_sprintf("linking against forbidden library '%s'", buf_ptr(symbol_name))); 22402 } 22403 } 22404 link_lib->symbols.append(symbol_name); 22405 } 22406 22407 static IrInstGen *ir_error_dependency_loop(IrAnalyze *ira, IrInst* source_instr) { 22408 ir_add_error(ira, source_instr, buf_sprintf("dependency loop detected")); 22409 return ira->codegen->invalid_inst_gen; 22410 } 22411 22412 static IrInstGen *ir_analyze_decl_ref(IrAnalyze *ira, IrInst* source_instruction, Tld *tld) { 22413 resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node, true); 22414 if (tld->resolution == TldResolutionInvalid) { 22415 return ira->codegen->invalid_inst_gen; 22416 } 22417 if (tld->resolution == TldResolutionResolving) 22418 return ir_error_dependency_loop(ira, source_instruction); 22419 22420 switch (tld->id) { 22421 case TldIdContainer: 22422 case TldIdCompTime: 22423 case TldIdUsingNamespace: 22424 zig_unreachable(); 22425 case TldIdVar: { 22426 TldVar *tld_var = (TldVar *)tld; 22427 ZigVar *var = tld_var->var; 22428 assert(var != nullptr); 22429 22430 if (tld_var->extern_lib_name != nullptr) { 22431 add_link_lib_symbol(ira, tld_var->extern_lib_name, buf_create_from_str(var->name), 22432 source_instruction->source_node); 22433 } 22434 22435 return ir_get_var_ptr(ira, source_instruction, var); 22436 } 22437 case TldIdFn: { 22438 TldFn *tld_fn = (TldFn *)tld; 22439 ZigFn *fn_entry = tld_fn->fn_entry; 22440 assert(fn_entry->type_entry != nullptr); 22441 22442 if (type_is_invalid(fn_entry->type_entry)) 22443 return ira->codegen->invalid_inst_gen; 22444 22445 if (tld_fn->extern_lib_name != nullptr) { 22446 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); 22447 } 22448 22449 IrInstGen *fn_inst = ir_const_fn(ira, source_instruction, fn_entry); 22450 return ir_get_ref(ira, source_instruction, fn_inst, true, false); 22451 } 22452 } 22453 zig_unreachable(); 22454 } 22455 22456 static ErrorTableEntry *find_err_table_entry(ZigType *err_set_type, Buf *field_name) { 22457 assert(err_set_type->id == ZigTypeIdErrorSet); 22458 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 22459 ErrorTableEntry *err_table_entry = err_set_type->data.error_set.errors[i]; 22460 if (buf_eql_buf(&err_table_entry->name, field_name)) { 22461 return err_table_entry; 22462 } 22463 } 22464 return nullptr; 22465 } 22466 22467 static IrInstGen *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstSrcFieldPtr *field_ptr_instruction) { 22468 Error err; 22469 IrInstGen *container_ptr = field_ptr_instruction->container_ptr->child; 22470 if (type_is_invalid(container_ptr->value->type)) 22471 return ira->codegen->invalid_inst_gen; 22472 22473 ZigType *container_type = container_ptr->value->type->data.pointer.child_type; 22474 22475 Buf *field_name = field_ptr_instruction->field_name_buffer; 22476 if (!field_name) { 22477 IrInstGen *field_name_expr = field_ptr_instruction->field_name_expr->child; 22478 field_name = ir_resolve_str(ira, field_name_expr); 22479 if (!field_name) 22480 return ira->codegen->invalid_inst_gen; 22481 } 22482 22483 22484 AstNode *source_node = field_ptr_instruction->base.base.source_node; 22485 22486 if (type_is_invalid(container_type)) { 22487 return ira->codegen->invalid_inst_gen; 22488 } else if (is_tuple(container_type) && !field_ptr_instruction->initializing && buf_eql_str(field_name, "len")) { 22489 IrInstGen *len_inst = ir_const_unsigned(ira, &field_ptr_instruction->base.base, 22490 container_type->data.structure.src_field_count); 22491 return ir_get_ref(ira, &field_ptr_instruction->base.base, len_inst, true, false); 22492 } else if (is_slice(container_type) || is_container_ref(container_type)) { 22493 assert(container_ptr->value->type->id == ZigTypeIdPointer); 22494 if (container_type->id == ZigTypeIdPointer) { 22495 ZigType *bare_type = container_ref_type(container_type); 22496 IrInstGen *container_child = ir_get_deref(ira, &field_ptr_instruction->base.base, container_ptr, nullptr); 22497 IrInstGen *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base.base, 22498 container_child, &field_ptr_instruction->container_ptr->base, bare_type, 22499 field_ptr_instruction->initializing); 22500 return result; 22501 } else { 22502 IrInstGen *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base.base, 22503 container_ptr, &field_ptr_instruction->container_ptr->base, container_type, 22504 field_ptr_instruction->initializing); 22505 return result; 22506 } 22507 } else if (is_array_ref(container_type) && !field_ptr_instruction->initializing) { 22508 if (buf_eql_str(field_name, "len")) { 22509 ZigValue *len_val = ira->codegen->pass1_arena->create<ZigValue>(); 22510 if (container_type->id == ZigTypeIdPointer) { 22511 init_const_usize(ira->codegen, len_val, container_type->data.pointer.child_type->data.array.len); 22512 } else { 22513 init_const_usize(ira->codegen, len_val, container_type->data.array.len); 22514 } 22515 22516 ZigType *usize = ira->codegen->builtin_types.entry_usize; 22517 bool ptr_is_const = true; 22518 bool ptr_is_volatile = false; 22519 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, len_val, 22520 usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22521 } else { 22522 ir_add_error_node(ira, source_node, 22523 buf_sprintf("no field named '%s' in '%s'", buf_ptr(field_name), 22524 buf_ptr(&container_type->name))); 22525 return ira->codegen->invalid_inst_gen; 22526 } 22527 } else if (container_type->id == ZigTypeIdMetaType) { 22528 ZigValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 22529 if (!container_ptr_val) 22530 return ira->codegen->invalid_inst_gen; 22531 22532 assert(container_ptr->value->type->id == ZigTypeIdPointer); 22533 ZigValue *child_val = const_ptr_pointee(ira, ira->codegen, container_ptr_val, source_node); 22534 if (child_val == nullptr) 22535 return ira->codegen->invalid_inst_gen; 22536 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 22537 field_ptr_instruction->base.base.source_node, child_val, UndefBad))) 22538 { 22539 return ira->codegen->invalid_inst_gen; 22540 } 22541 ZigType *child_type = child_val->data.x_type; 22542 22543 if (type_is_invalid(child_type)) { 22544 return ira->codegen->invalid_inst_gen; 22545 } else if (is_container(child_type)) { 22546 if (child_type->id == ZigTypeIdEnum) { 22547 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) 22548 return ira->codegen->invalid_inst_gen; 22549 22550 TypeEnumField *field = find_enum_type_field(child_type, field_name); 22551 if (field) { 22552 bool ptr_is_const = true; 22553 bool ptr_is_volatile = false; 22554 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22555 create_const_enum(ira->codegen, child_type, &field->value), child_type, 22556 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22557 } 22558 } 22559 ScopeDecls *container_scope = get_container_scope(child_type); 22560 Tld *tld = find_container_decl(ira->codegen, container_scope, field_name); 22561 if (tld) { 22562 if (tld->visib_mod == VisibModPrivate && 22563 tld->import != get_scope_import(field_ptr_instruction->base.base.scope)) 22564 { 22565 ErrorMsg *msg = ir_add_error(ira, &field_ptr_instruction->base.base, 22566 buf_sprintf("'%s' is private", buf_ptr(field_name))); 22567 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); 22568 return ira->codegen->invalid_inst_gen; 22569 } 22570 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base.base, tld); 22571 } 22572 if (child_type->id == ZigTypeIdUnion && 22573 (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr || 22574 child_type->data.unionation.decl_node->data.container_decl.auto_enum)) 22575 { 22576 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) 22577 return ira->codegen->invalid_inst_gen; 22578 TypeUnionField *field = find_union_type_field(child_type, field_name); 22579 if (field) { 22580 ZigType *enum_type = child_type->data.unionation.tag_type; 22581 bool ptr_is_const = true; 22582 bool ptr_is_volatile = false; 22583 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22584 create_const_enum(ira->codegen, enum_type, &field->enum_field->value), enum_type, 22585 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22586 } 22587 } 22588 const char *container_name = (child_type == ira->codegen->root_import) ? 22589 "root source file" : buf_ptr(buf_sprintf("container '%s'", buf_ptr(&child_type->name))); 22590 ir_add_error(ira, &field_ptr_instruction->base.base, 22591 buf_sprintf("%s has no member called '%s'", 22592 container_name, buf_ptr(field_name))); 22593 return ira->codegen->invalid_inst_gen; 22594 } else if (child_type->id == ZigTypeIdErrorSet) { 22595 ErrorTableEntry *err_entry; 22596 ZigType *err_set_type; 22597 if (type_is_global_error_set(child_type)) { 22598 auto existing_entry = ira->codegen->error_table.maybe_get(field_name); 22599 if (existing_entry) { 22600 err_entry = existing_entry->value; 22601 } else { 22602 err_entry = heap::c_allocator.create<ErrorTableEntry>(); 22603 err_entry->decl_node = field_ptr_instruction->base.base.source_node; 22604 buf_init_from_buf(&err_entry->name, field_name); 22605 size_t error_value_count = ira->codegen->errors_by_index.length; 22606 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count)); 22607 err_entry->value = error_value_count; 22608 ira->codegen->errors_by_index.append(err_entry); 22609 ira->codegen->error_table.put(field_name, err_entry); 22610 } 22611 if (err_entry->set_with_only_this_in_it == nullptr) { 22612 err_entry->set_with_only_this_in_it = make_err_set_with_one_item(ira->codegen, 22613 field_ptr_instruction->base.base.scope, field_ptr_instruction->base.base.source_node, 22614 err_entry); 22615 } 22616 err_set_type = err_entry->set_with_only_this_in_it; 22617 } else { 22618 if (!resolve_inferred_error_set(ira->codegen, child_type, field_ptr_instruction->base.base.source_node)) { 22619 return ira->codegen->invalid_inst_gen; 22620 } 22621 err_entry = find_err_table_entry(child_type, field_name); 22622 if (err_entry == nullptr) { 22623 ir_add_error(ira, &field_ptr_instruction->base.base, 22624 buf_sprintf("no error named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&child_type->name))); 22625 return ira->codegen->invalid_inst_gen; 22626 } 22627 err_set_type = child_type; 22628 } 22629 ZigValue *const_val = ira->codegen->pass1_arena->create<ZigValue>(); 22630 const_val->special = ConstValSpecialStatic; 22631 const_val->type = err_set_type; 22632 const_val->data.x_err_set = err_entry; 22633 22634 bool ptr_is_const = true; 22635 bool ptr_is_volatile = false; 22636 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, const_val, 22637 err_set_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22638 } else if (child_type->id == ZigTypeIdInt) { 22639 if (buf_eql_str(field_name, "bit_count")) { 22640 bool ptr_is_const = true; 22641 bool ptr_is_volatile = false; 22642 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22643 create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int, 22644 child_type->data.integral.bit_count, false), 22645 ira->codegen->builtin_types.entry_num_lit_int, 22646 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22647 } else if (buf_eql_str(field_name, "is_signed")) { 22648 bool ptr_is_const = true; 22649 bool ptr_is_volatile = false; 22650 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22651 create_const_bool(ira->codegen, child_type->data.integral.is_signed), 22652 ira->codegen->builtin_types.entry_bool, 22653 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22654 } else { 22655 ir_add_error(ira, &field_ptr_instruction->base.base, 22656 buf_sprintf("type '%s' has no member called '%s'", 22657 buf_ptr(&child_type->name), buf_ptr(field_name))); 22658 return ira->codegen->invalid_inst_gen; 22659 } 22660 } else if (child_type->id == ZigTypeIdFloat) { 22661 if (buf_eql_str(field_name, "bit_count")) { 22662 bool ptr_is_const = true; 22663 bool ptr_is_volatile = false; 22664 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22665 create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int, 22666 child_type->data.floating.bit_count, false), 22667 ira->codegen->builtin_types.entry_num_lit_int, 22668 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22669 } else { 22670 ir_add_error(ira, &field_ptr_instruction->base.base, 22671 buf_sprintf("type '%s' has no member called '%s'", 22672 buf_ptr(&child_type->name), buf_ptr(field_name))); 22673 return ira->codegen->invalid_inst_gen; 22674 } 22675 } else if (child_type->id == ZigTypeIdPointer) { 22676 if (buf_eql_str(field_name, "Child")) { 22677 bool ptr_is_const = true; 22678 bool ptr_is_volatile = false; 22679 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22680 create_const_type(ira->codegen, child_type->data.pointer.child_type), 22681 ira->codegen->builtin_types.entry_type, 22682 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22683 } else if (buf_eql_str(field_name, "alignment")) { 22684 bool ptr_is_const = true; 22685 bool ptr_is_volatile = false; 22686 if ((err = type_resolve(ira->codegen, child_type->data.pointer.child_type, 22687 ResolveStatusAlignmentKnown))) 22688 { 22689 return ira->codegen->invalid_inst_gen; 22690 } 22691 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22692 create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int, 22693 get_ptr_align(ira->codegen, child_type), false), 22694 ira->codegen->builtin_types.entry_num_lit_int, 22695 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22696 } else { 22697 ir_add_error(ira, &field_ptr_instruction->base.base, 22698 buf_sprintf("type '%s' has no member called '%s'", 22699 buf_ptr(&child_type->name), buf_ptr(field_name))); 22700 return ira->codegen->invalid_inst_gen; 22701 } 22702 } else if (child_type->id == ZigTypeIdArray) { 22703 if (buf_eql_str(field_name, "Child")) { 22704 bool ptr_is_const = true; 22705 bool ptr_is_volatile = false; 22706 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22707 create_const_type(ira->codegen, child_type->data.array.child_type), 22708 ira->codegen->builtin_types.entry_type, 22709 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22710 } else if (buf_eql_str(field_name, "len")) { 22711 bool ptr_is_const = true; 22712 bool ptr_is_volatile = false; 22713 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22714 create_const_unsigned_negative(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int, 22715 child_type->data.array.len, false), 22716 ira->codegen->builtin_types.entry_num_lit_int, 22717 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22718 } else { 22719 ir_add_error(ira, &field_ptr_instruction->base.base, 22720 buf_sprintf("type '%s' has no member called '%s'", 22721 buf_ptr(&child_type->name), buf_ptr(field_name))); 22722 return ira->codegen->invalid_inst_gen; 22723 } 22724 } else if (child_type->id == ZigTypeIdErrorUnion) { 22725 if (buf_eql_str(field_name, "Payload")) { 22726 bool ptr_is_const = true; 22727 bool ptr_is_volatile = false; 22728 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22729 create_const_type(ira->codegen, child_type->data.error_union.payload_type), 22730 ira->codegen->builtin_types.entry_type, 22731 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22732 } else if (buf_eql_str(field_name, "ErrorSet")) { 22733 bool ptr_is_const = true; 22734 bool ptr_is_volatile = false; 22735 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22736 create_const_type(ira->codegen, child_type->data.error_union.err_set_type), 22737 ira->codegen->builtin_types.entry_type, 22738 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22739 } else { 22740 ir_add_error(ira, &field_ptr_instruction->base.base, 22741 buf_sprintf("type '%s' has no member called '%s'", 22742 buf_ptr(&child_type->name), buf_ptr(field_name))); 22743 return ira->codegen->invalid_inst_gen; 22744 } 22745 } else if (child_type->id == ZigTypeIdOptional) { 22746 if (buf_eql_str(field_name, "Child")) { 22747 bool ptr_is_const = true; 22748 bool ptr_is_volatile = false; 22749 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22750 create_const_type(ira->codegen, child_type->data.maybe.child_type), 22751 ira->codegen->builtin_types.entry_type, 22752 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22753 } else { 22754 ir_add_error(ira, &field_ptr_instruction->base.base, 22755 buf_sprintf("type '%s' has no member called '%s'", 22756 buf_ptr(&child_type->name), buf_ptr(field_name))); 22757 return ira->codegen->invalid_inst_gen; 22758 } 22759 } else if (child_type->id == ZigTypeIdFn) { 22760 if (buf_eql_str(field_name, "ReturnType")) { 22761 if (child_type->data.fn.fn_type_id.return_type == nullptr) { 22762 // Return type can only ever be null, if the function is generic 22763 assert(child_type->data.fn.is_generic); 22764 22765 ir_add_error(ira, &field_ptr_instruction->base.base, 22766 buf_sprintf("ReturnType has not been resolved because '%s' is generic", buf_ptr(&child_type->name))); 22767 return ira->codegen->invalid_inst_gen; 22768 } 22769 22770 bool ptr_is_const = true; 22771 bool ptr_is_volatile = false; 22772 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22773 create_const_type(ira->codegen, child_type->data.fn.fn_type_id.return_type), 22774 ira->codegen->builtin_types.entry_type, 22775 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22776 } else if (buf_eql_str(field_name, "is_var_args")) { 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_bool(ira->codegen, child_type->data.fn.fn_type_id.is_var_args), 22781 ira->codegen->builtin_types.entry_bool, 22782 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22783 } else if (buf_eql_str(field_name, "arg_count")) { 22784 bool ptr_is_const = true; 22785 bool ptr_is_volatile = false; 22786 return ir_get_const_ptr(ira, &field_ptr_instruction->base.base, 22787 create_const_usize(ira->codegen, child_type->data.fn.fn_type_id.param_count), 22788 ira->codegen->builtin_types.entry_usize, 22789 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 22790 } else { 22791 ir_add_error(ira, &field_ptr_instruction->base.base, 22792 buf_sprintf("type '%s' has no member called '%s'", 22793 buf_ptr(&child_type->name), buf_ptr(field_name))); 22794 return ira->codegen->invalid_inst_gen; 22795 } 22796 } else { 22797 ir_add_error(ira, &field_ptr_instruction->base.base, 22798 buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); 22799 return ira->codegen->invalid_inst_gen; 22800 } 22801 } else if (field_ptr_instruction->initializing) { 22802 ir_add_error(ira, &field_ptr_instruction->base.base, 22803 buf_sprintf("type '%s' does not support struct initialization syntax", buf_ptr(&container_type->name))); 22804 return ira->codegen->invalid_inst_gen; 22805 } else { 22806 ir_add_error_node(ira, field_ptr_instruction->base.base.source_node, 22807 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); 22808 return ira->codegen->invalid_inst_gen; 22809 } 22810 } 22811 22812 static IrInstGen *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstSrcStorePtr *instruction) { 22813 IrInstGen *ptr = instruction->ptr->child; 22814 if (type_is_invalid(ptr->value->type)) 22815 return ira->codegen->invalid_inst_gen; 22816 22817 IrInstGen *value = instruction->value->child; 22818 if (type_is_invalid(value->value->type)) 22819 return ira->codegen->invalid_inst_gen; 22820 22821 return ir_analyze_store_ptr(ira, &instruction->base.base, ptr, value, instruction->allow_write_through_const); 22822 } 22823 22824 static IrInstGen *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstSrcLoadPtr *instruction) { 22825 IrInstGen *ptr = instruction->ptr->child; 22826 if (type_is_invalid(ptr->value->type)) 22827 return ira->codegen->invalid_inst_gen; 22828 return ir_get_deref(ira, &instruction->base.base, ptr, nullptr); 22829 } 22830 22831 static IrInstGen *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstSrcTypeOf *typeof_instruction) { 22832 ZigType *type_entry; 22833 22834 const size_t value_count = typeof_instruction->value_count; 22835 22836 // Fast path for the common case of TypeOf with a single argument 22837 if (value_count < 2) { 22838 type_entry = typeof_instruction->value.scalar->child->value->type; 22839 } else { 22840 IrInstGen **args = heap::c_allocator.allocate<IrInstGen*>(value_count); 22841 for (size_t i = 0; i < value_count; i += 1) { 22842 IrInstGen *value = typeof_instruction->value.list[i]->child; 22843 if (type_is_invalid(value->value->type)) 22844 return ira->codegen->invalid_inst_gen; 22845 args[i] = value; 22846 } 22847 22848 type_entry = ir_resolve_peer_types(ira, typeof_instruction->base.base.source_node, 22849 nullptr, args, value_count); 22850 22851 heap::c_allocator.deallocate(args, value_count); 22852 } 22853 22854 if (type_is_invalid(type_entry)) 22855 return ira->codegen->invalid_inst_gen; 22856 22857 return ir_const_type(ira, &typeof_instruction->base.base, type_entry); 22858 } 22859 22860 static IrInstGen *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstSrcSetCold *instruction) { 22861 if (ira->new_irb.exec->is_inline) { 22862 // ignore setCold when running functions at compile time 22863 return ir_const_void(ira, &instruction->base.base); 22864 } 22865 22866 IrInstGen *is_cold_value = instruction->is_cold->child; 22867 bool want_cold; 22868 if (!ir_resolve_bool(ira, is_cold_value, &want_cold)) 22869 return ira->codegen->invalid_inst_gen; 22870 22871 ZigFn *fn_entry = scope_fn_entry(instruction->base.base.scope); 22872 if (fn_entry == nullptr) { 22873 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setCold outside function")); 22874 return ira->codegen->invalid_inst_gen; 22875 } 22876 22877 if (fn_entry->set_cold_node != nullptr) { 22878 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, buf_sprintf("cold set twice in same function")); 22879 add_error_note(ira->codegen, msg, fn_entry->set_cold_node, buf_sprintf("first set here")); 22880 return ira->codegen->invalid_inst_gen; 22881 } 22882 22883 fn_entry->set_cold_node = instruction->base.base.source_node; 22884 fn_entry->is_cold = want_cold; 22885 22886 return ir_const_void(ira, &instruction->base.base); 22887 } 22888 22889 static IrInstGen *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira, 22890 IrInstSrcSetRuntimeSafety *set_runtime_safety_instruction) 22891 { 22892 if (ira->new_irb.exec->is_inline) { 22893 // ignore setRuntimeSafety when running functions at compile time 22894 return ir_const_void(ira, &set_runtime_safety_instruction->base.base); 22895 } 22896 22897 bool *safety_off_ptr; 22898 AstNode **safety_set_node_ptr; 22899 22900 Scope *scope = set_runtime_safety_instruction->base.base.scope; 22901 while (scope != nullptr) { 22902 if (scope->id == ScopeIdBlock) { 22903 ScopeBlock *block_scope = (ScopeBlock *)scope; 22904 safety_off_ptr = &block_scope->safety_off; 22905 safety_set_node_ptr = &block_scope->safety_set_node; 22906 break; 22907 } else if (scope->id == ScopeIdFnDef) { 22908 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 22909 ZigFn *target_fn = def_scope->fn_entry; 22910 assert(target_fn->def_scope != nullptr); 22911 safety_off_ptr = &target_fn->def_scope->safety_off; 22912 safety_set_node_ptr = &target_fn->def_scope->safety_set_node; 22913 break; 22914 } else if (scope->id == ScopeIdDecls) { 22915 ScopeDecls *decls_scope = (ScopeDecls *)scope; 22916 safety_off_ptr = &decls_scope->safety_off; 22917 safety_set_node_ptr = &decls_scope->safety_set_node; 22918 break; 22919 } else { 22920 scope = scope->parent; 22921 continue; 22922 } 22923 } 22924 assert(scope != nullptr); 22925 22926 IrInstGen *safety_on_value = set_runtime_safety_instruction->safety_on->child; 22927 bool want_runtime_safety; 22928 if (!ir_resolve_bool(ira, safety_on_value, &want_runtime_safety)) 22929 return ira->codegen->invalid_inst_gen; 22930 22931 AstNode *source_node = set_runtime_safety_instruction->base.base.source_node; 22932 if (*safety_set_node_ptr) { 22933 ErrorMsg *msg = ir_add_error_node(ira, source_node, 22934 buf_sprintf("runtime safety set twice for same scope")); 22935 add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here")); 22936 return ira->codegen->invalid_inst_gen; 22937 } 22938 *safety_set_node_ptr = source_node; 22939 *safety_off_ptr = !want_runtime_safety; 22940 22941 return ir_const_void(ira, &set_runtime_safety_instruction->base.base); 22942 } 22943 22944 static IrInstGen *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, 22945 IrInstSrcSetFloatMode *instruction) 22946 { 22947 if (ira->new_irb.exec->is_inline) { 22948 // ignore setFloatMode when running functions at compile time 22949 return ir_const_void(ira, &instruction->base.base); 22950 } 22951 22952 bool *fast_math_on_ptr; 22953 AstNode **fast_math_set_node_ptr; 22954 22955 Scope *scope = instruction->base.base.scope; 22956 while (scope != nullptr) { 22957 if (scope->id == ScopeIdBlock) { 22958 ScopeBlock *block_scope = (ScopeBlock *)scope; 22959 fast_math_on_ptr = &block_scope->fast_math_on; 22960 fast_math_set_node_ptr = &block_scope->fast_math_set_node; 22961 break; 22962 } else if (scope->id == ScopeIdFnDef) { 22963 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 22964 ZigFn *target_fn = def_scope->fn_entry; 22965 assert(target_fn->def_scope != nullptr); 22966 fast_math_on_ptr = &target_fn->def_scope->fast_math_on; 22967 fast_math_set_node_ptr = &target_fn->def_scope->fast_math_set_node; 22968 break; 22969 } else if (scope->id == ScopeIdDecls) { 22970 ScopeDecls *decls_scope = (ScopeDecls *)scope; 22971 fast_math_on_ptr = &decls_scope->fast_math_on; 22972 fast_math_set_node_ptr = &decls_scope->fast_math_set_node; 22973 break; 22974 } else { 22975 scope = scope->parent; 22976 continue; 22977 } 22978 } 22979 assert(scope != nullptr); 22980 22981 IrInstGen *float_mode_value = instruction->mode_value->child; 22982 FloatMode float_mode_scalar; 22983 if (!ir_resolve_float_mode(ira, float_mode_value, &float_mode_scalar)) 22984 return ira->codegen->invalid_inst_gen; 22985 22986 AstNode *source_node = instruction->base.base.source_node; 22987 if (*fast_math_set_node_ptr) { 22988 ErrorMsg *msg = ir_add_error_node(ira, source_node, 22989 buf_sprintf("float mode set twice for same scope")); 22990 add_error_note(ira->codegen, msg, *fast_math_set_node_ptr, buf_sprintf("first set here")); 22991 return ira->codegen->invalid_inst_gen; 22992 } 22993 *fast_math_set_node_ptr = source_node; 22994 *fast_math_on_ptr = (float_mode_scalar == FloatModeOptimized); 22995 22996 return ir_const_void(ira, &instruction->base.base); 22997 } 22998 22999 static IrInstGen *ir_analyze_instruction_any_frame_type(IrAnalyze *ira, IrInstSrcAnyFrameType *instruction) { 23000 ZigType *payload_type = nullptr; 23001 if (instruction->payload_type != nullptr) { 23002 payload_type = ir_resolve_type(ira, instruction->payload_type->child); 23003 if (type_is_invalid(payload_type)) 23004 return ira->codegen->invalid_inst_gen; 23005 } 23006 23007 ZigType *any_frame_type = get_any_frame_type(ira->codegen, payload_type); 23008 return ir_const_type(ira, &instruction->base.base, any_frame_type); 23009 } 23010 23011 static IrInstGen *ir_analyze_instruction_slice_type(IrAnalyze *ira, IrInstSrcSliceType *slice_type_instruction) { 23012 IrInstGen *result = ir_const(ira, &slice_type_instruction->base.base, ira->codegen->builtin_types.entry_type); 23013 result->value->special = ConstValSpecialLazy; 23014 23015 LazyValueSliceType *lazy_slice_type = heap::c_allocator.create<LazyValueSliceType>(); 23016 lazy_slice_type->ira = ira; ira_ref(ira); 23017 result->value->data.x_lazy = &lazy_slice_type->base; 23018 lazy_slice_type->base.id = LazyValueIdSliceType; 23019 23020 if (slice_type_instruction->align_value != nullptr) { 23021 lazy_slice_type->align_inst = slice_type_instruction->align_value->child; 23022 if (ir_resolve_const(ira, lazy_slice_type->align_inst, LazyOk) == nullptr) 23023 return ira->codegen->invalid_inst_gen; 23024 } 23025 23026 if (slice_type_instruction->sentinel != nullptr) { 23027 lazy_slice_type->sentinel = slice_type_instruction->sentinel->child; 23028 if (ir_resolve_const(ira, lazy_slice_type->sentinel, LazyOk) == nullptr) 23029 return ira->codegen->invalid_inst_gen; 23030 } 23031 23032 lazy_slice_type->elem_type = slice_type_instruction->child_type->child; 23033 if (ir_resolve_type_lazy(ira, lazy_slice_type->elem_type) == nullptr) 23034 return ira->codegen->invalid_inst_gen; 23035 23036 lazy_slice_type->is_const = slice_type_instruction->is_const; 23037 lazy_slice_type->is_volatile = slice_type_instruction->is_volatile; 23038 lazy_slice_type->is_allowzero = slice_type_instruction->is_allow_zero; 23039 23040 return result; 23041 } 23042 23043 static IrInstGen *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstSrcAsm *asm_instruction) { 23044 Error err; 23045 23046 assert(asm_instruction->base.base.source_node->type == NodeTypeAsmExpr); 23047 23048 AstNode *node = asm_instruction->base.base.source_node; 23049 AstNodeAsmExpr *asm_expr = &asm_instruction->base.base.source_node->data.asm_expr; 23050 23051 Buf *template_buf = ir_resolve_str(ira, asm_instruction->asm_template->child); 23052 if (template_buf == nullptr) 23053 return ira->codegen->invalid_inst_gen; 23054 23055 if (asm_instruction->is_global) { 23056 buf_append_char(&ira->codegen->global_asm, '\n'); 23057 buf_append_buf(&ira->codegen->global_asm, template_buf); 23058 23059 return ir_const_void(ira, &asm_instruction->base.base); 23060 } 23061 23062 if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base.base)) 23063 return ira->codegen->invalid_inst_gen; 23064 23065 ZigList<AsmToken> tok_list = {}; 23066 if ((err = parse_asm_template(ira, node, template_buf, &tok_list))) { 23067 return ira->codegen->invalid_inst_gen; 23068 } 23069 23070 for (size_t token_i = 0; token_i < tok_list.length; token_i += 1) { 23071 AsmToken asm_token = tok_list.at(token_i); 23072 if (asm_token.id == AsmTokenIdVar) { 23073 size_t index = find_asm_index(ira->codegen, node, &asm_token, template_buf); 23074 if (index == SIZE_MAX) { 23075 const char *ptr = buf_ptr(template_buf) + asm_token.start + 2; 23076 uint32_t len = asm_token.end - asm_token.start - 2; 23077 23078 add_node_error(ira->codegen, node, 23079 buf_sprintf("could not find '%.*s' in the inputs or outputs", 23080 len, ptr)); 23081 return ira->codegen->invalid_inst_gen; 23082 } 23083 } 23084 } 23085 23086 // TODO validate the output types and variable types 23087 23088 IrInstGen **input_list = heap::c_allocator.allocate<IrInstGen *>(asm_expr->input_list.length); 23089 IrInstGen **output_types = heap::c_allocator.allocate<IrInstGen *>(asm_expr->output_list.length); 23090 23091 ZigType *return_type = ira->codegen->builtin_types.entry_void; 23092 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 23093 AsmOutput *asm_output = asm_expr->output_list.at(i); 23094 if (asm_output->return_type) { 23095 output_types[i] = asm_instruction->output_types[i]->child; 23096 return_type = ir_resolve_type(ira, output_types[i]); 23097 if (type_is_invalid(return_type)) 23098 return ira->codegen->invalid_inst_gen; 23099 } 23100 } 23101 23102 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 23103 IrInstGen *const input_value = asm_instruction->input_list[i]->child; 23104 if (type_is_invalid(input_value->value->type)) 23105 return ira->codegen->invalid_inst_gen; 23106 23107 if (instr_is_comptime(input_value) && 23108 (input_value->value->type->id == ZigTypeIdComptimeInt || 23109 input_value->value->type->id == ZigTypeIdComptimeFloat)) { 23110 ir_add_error(ira, &input_value->base, 23111 buf_sprintf("expected sized integer or sized float, found %s", buf_ptr(&input_value->value->type->name))); 23112 return ira->codegen->invalid_inst_gen; 23113 } 23114 23115 input_list[i] = input_value; 23116 } 23117 23118 return ir_build_asm_gen(ira, &asm_instruction->base.base, 23119 template_buf, tok_list.items, tok_list.length, 23120 input_list, output_types, asm_instruction->output_vars, asm_instruction->return_count, 23121 asm_instruction->has_side_effects, return_type); 23122 } 23123 23124 static IrInstGen *ir_analyze_instruction_array_type(IrAnalyze *ira, IrInstSrcArrayType *array_type_instruction) { 23125 IrInstGen *result = ir_const(ira, &array_type_instruction->base.base, ira->codegen->builtin_types.entry_type); 23126 result->value->special = ConstValSpecialLazy; 23127 23128 LazyValueArrayType *lazy_array_type = heap::c_allocator.create<LazyValueArrayType>(); 23129 lazy_array_type->ira = ira; ira_ref(ira); 23130 result->value->data.x_lazy = &lazy_array_type->base; 23131 lazy_array_type->base.id = LazyValueIdArrayType; 23132 23133 lazy_array_type->elem_type = array_type_instruction->child_type->child; 23134 if (ir_resolve_type_lazy(ira, lazy_array_type->elem_type) == nullptr) 23135 return ira->codegen->invalid_inst_gen; 23136 23137 if (!ir_resolve_usize(ira, array_type_instruction->size->child, &lazy_array_type->length)) 23138 return ira->codegen->invalid_inst_gen; 23139 23140 if (array_type_instruction->sentinel != nullptr) { 23141 lazy_array_type->sentinel = array_type_instruction->sentinel->child; 23142 if (ir_resolve_const(ira, lazy_array_type->sentinel, LazyOk) == nullptr) 23143 return ira->codegen->invalid_inst_gen; 23144 } 23145 23146 return result; 23147 } 23148 23149 static IrInstGen *ir_analyze_instruction_size_of(IrAnalyze *ira, IrInstSrcSizeOf *instruction) { 23150 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 23151 result->value->special = ConstValSpecialLazy; 23152 23153 LazyValueSizeOf *lazy_size_of = heap::c_allocator.create<LazyValueSizeOf>(); 23154 lazy_size_of->ira = ira; ira_ref(ira); 23155 result->value->data.x_lazy = &lazy_size_of->base; 23156 lazy_size_of->base.id = LazyValueIdSizeOf; 23157 lazy_size_of->bit_size = instruction->bit_size; 23158 23159 lazy_size_of->target_type = instruction->type_value->child; 23160 if (ir_resolve_type_lazy(ira, lazy_size_of->target_type) == nullptr) 23161 return ira->codegen->invalid_inst_gen; 23162 23163 return result; 23164 } 23165 23166 static IrInstGen *ir_analyze_test_non_null(IrAnalyze *ira, IrInst *source_inst, IrInstGen *value) { 23167 ZigType *type_entry = value->value->type; 23168 23169 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.allow_zero) { 23170 if (instr_is_comptime(value)) { 23171 ZigValue *c_ptr_val = ir_resolve_const(ira, value, UndefOk); 23172 if (c_ptr_val == nullptr) 23173 return ira->codegen->invalid_inst_gen; 23174 if (c_ptr_val->special == ConstValSpecialUndef) 23175 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); 23176 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 23177 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 23178 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 23179 return ir_const_bool(ira, source_inst, !is_null); 23180 } 23181 23182 return ir_build_test_non_null_gen(ira, source_inst, value); 23183 } else if (type_entry->id == ZigTypeIdOptional) { 23184 if (instr_is_comptime(value)) { 23185 ZigValue *maybe_val = ir_resolve_const(ira, value, UndefOk); 23186 if (maybe_val == nullptr) 23187 return ira->codegen->invalid_inst_gen; 23188 if (maybe_val->special == ConstValSpecialUndef) 23189 return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool); 23190 23191 return ir_const_bool(ira, source_inst, !optional_value_is_null(maybe_val)); 23192 } 23193 23194 return ir_build_test_non_null_gen(ira, source_inst, value); 23195 } else if (type_entry->id == ZigTypeIdNull) { 23196 return ir_const_bool(ira, source_inst, false); 23197 } else { 23198 return ir_const_bool(ira, source_inst, true); 23199 } 23200 } 23201 23202 static IrInstGen *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrInstSrcTestNonNull *instruction) { 23203 IrInstGen *value = instruction->value->child; 23204 if (type_is_invalid(value->value->type)) 23205 return ira->codegen->invalid_inst_gen; 23206 23207 return ir_analyze_test_non_null(ira, &instruction->base.base, value); 23208 } 23209 23210 static IrInstGen *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInst* source_instr, 23211 IrInstGen *base_ptr, bool safety_check_on, bool initializing) 23212 { 23213 Error err; 23214 23215 ZigType *type_entry = get_ptr_elem_type(ira->codegen, base_ptr); 23216 if (type_is_invalid(type_entry)) 23217 return ira->codegen->invalid_inst_gen; 23218 23219 if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.ptr_len == PtrLenC) { 23220 if (instr_is_comptime(base_ptr)) { 23221 ZigValue *val = ir_resolve_const(ira, base_ptr, UndefBad); 23222 if (!val) 23223 return ira->codegen->invalid_inst_gen; 23224 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 23225 ZigValue *c_ptr_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node); 23226 if (c_ptr_val == nullptr) 23227 return ira->codegen->invalid_inst_gen; 23228 bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull || 23229 (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 23230 c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0); 23231 if (is_null) { 23232 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); 23233 return ira->codegen->invalid_inst_gen; 23234 } 23235 return base_ptr; 23236 } 23237 } 23238 if (!safety_check_on) 23239 return base_ptr; 23240 IrInstGen *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr, nullptr); 23241 ir_build_assert_non_null(ira, source_instr, c_ptr_val); 23242 return base_ptr; 23243 } 23244 23245 if (type_entry->id != ZigTypeIdOptional) { 23246 ir_add_error(ira, &base_ptr->base, 23247 buf_sprintf("expected optional type, found '%s'", buf_ptr(&type_entry->name))); 23248 return ira->codegen->invalid_inst_gen; 23249 } 23250 23251 ZigType *child_type = type_entry->data.maybe.child_type; 23252 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, 23253 base_ptr->value->type->data.pointer.is_const, base_ptr->value->type->data.pointer.is_volatile, 23254 PtrLenSingle, 0, 0, 0, false); 23255 23256 bool same_comptime_repr = types_have_same_zig_comptime_repr(ira->codegen, child_type, type_entry); 23257 23258 if (instr_is_comptime(base_ptr)) { 23259 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 23260 if (ptr_val == nullptr) 23261 return ira->codegen->invalid_inst_gen; 23262 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 23263 ZigValue *optional_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 23264 if (optional_val == nullptr) 23265 return ira->codegen->invalid_inst_gen; 23266 23267 if (initializing) { 23268 switch (type_has_one_possible_value(ira->codegen, child_type)) { 23269 case OnePossibleValueInvalid: 23270 return ira->codegen->invalid_inst_gen; 23271 case OnePossibleValueNo: 23272 if (!same_comptime_repr) { 23273 ZigValue *payload_val = ira->codegen->pass1_arena->create<ZigValue>(); 23274 payload_val->type = child_type; 23275 payload_val->special = ConstValSpecialUndef; 23276 payload_val->parent.id = ConstParentIdOptionalPayload; 23277 payload_val->parent.data.p_optional_payload.optional_val = optional_val; 23278 23279 optional_val->data.x_optional = payload_val; 23280 optional_val->special = ConstValSpecialStatic; 23281 } 23282 break; 23283 case OnePossibleValueYes: { 23284 optional_val->special = ConstValSpecialStatic; 23285 optional_val->data.x_optional = get_the_one_possible_value(ira->codegen, child_type); 23286 break; 23287 } 23288 } 23289 } else { 23290 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, 23291 source_instr->source_node, optional_val, UndefBad))) 23292 return ira->codegen->invalid_inst_gen; 23293 if (optional_value_is_null(optional_val)) { 23294 ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null")); 23295 return ira->codegen->invalid_inst_gen; 23296 } 23297 } 23298 23299 IrInstGen *result; 23300 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 23301 result = ir_build_optional_unwrap_ptr_gen(ira, source_instr, base_ptr, false, 23302 initializing, result_type); 23303 result->value->special = ConstValSpecialStatic; 23304 } else { 23305 result = ir_const(ira, source_instr, result_type); 23306 } 23307 ZigValue *result_val = result->value; 23308 result_val->data.x_ptr.special = ConstPtrSpecialRef; 23309 result_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 23310 switch (type_has_one_possible_value(ira->codegen, child_type)) { 23311 case OnePossibleValueInvalid: 23312 return ira->codegen->invalid_inst_gen; 23313 case OnePossibleValueNo: 23314 if (same_comptime_repr) { 23315 result_val->data.x_ptr.data.ref.pointee = optional_val; 23316 } else { 23317 assert(optional_val->data.x_optional != nullptr); 23318 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; 23319 } 23320 break; 23321 case OnePossibleValueYes: 23322 assert(optional_val->data.x_optional != nullptr); 23323 result_val->data.x_ptr.data.ref.pointee = optional_val->data.x_optional; 23324 break; 23325 } 23326 return result; 23327 } 23328 } 23329 23330 return ir_build_optional_unwrap_ptr_gen(ira, source_instr, base_ptr, safety_check_on, 23331 initializing, result_type); 23332 } 23333 23334 static IrInstGen *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, 23335 IrInstSrcOptionalUnwrapPtr *instruction) 23336 { 23337 IrInstGen *base_ptr = instruction->base_ptr->child; 23338 if (type_is_invalid(base_ptr->value->type)) 23339 return ira->codegen->invalid_inst_gen; 23340 23341 return ir_analyze_unwrap_optional_payload(ira, &instruction->base.base, base_ptr, 23342 instruction->safety_check_on, false); 23343 } 23344 23345 static IrInstGen *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstSrcCtz *instruction) { 23346 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 23347 if (type_is_invalid(int_type)) 23348 return ira->codegen->invalid_inst_gen; 23349 23350 IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); 23351 if (type_is_invalid(op->value->type)) 23352 return ira->codegen->invalid_inst_gen; 23353 23354 if (int_type->data.integral.bit_count == 0) 23355 return ir_const_unsigned(ira, &instruction->base.base, 0); 23356 23357 if (instr_is_comptime(op)) { 23358 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 23359 if (val == nullptr) 23360 return ira->codegen->invalid_inst_gen; 23361 if (val->special == ConstValSpecialUndef) 23362 return ir_const_undef(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 23363 size_t result_usize = bigint_ctz(&op->value->data.x_bigint, int_type->data.integral.bit_count); 23364 return ir_const_unsigned(ira, &instruction->base.base, result_usize); 23365 } 23366 23367 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 23368 return ir_build_ctz_gen(ira, &instruction->base.base, return_type, op); 23369 } 23370 23371 static IrInstGen *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstSrcClz *instruction) { 23372 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 23373 if (type_is_invalid(int_type)) 23374 return ira->codegen->invalid_inst_gen; 23375 23376 IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); 23377 if (type_is_invalid(op->value->type)) 23378 return ira->codegen->invalid_inst_gen; 23379 23380 if (int_type->data.integral.bit_count == 0) 23381 return ir_const_unsigned(ira, &instruction->base.base, 0); 23382 23383 if (instr_is_comptime(op)) { 23384 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 23385 if (val == nullptr) 23386 return ira->codegen->invalid_inst_gen; 23387 if (val->special == ConstValSpecialUndef) 23388 return ir_const_undef(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 23389 size_t result_usize = bigint_clz(&op->value->data.x_bigint, int_type->data.integral.bit_count); 23390 return ir_const_unsigned(ira, &instruction->base.base, result_usize); 23391 } 23392 23393 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 23394 return ir_build_clz_gen(ira, &instruction->base.base, return_type, op); 23395 } 23396 23397 static IrInstGen *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstSrcPopCount *instruction) { 23398 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 23399 if (type_is_invalid(int_type)) 23400 return ira->codegen->invalid_inst_gen; 23401 23402 IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); 23403 if (type_is_invalid(op->value->type)) 23404 return ira->codegen->invalid_inst_gen; 23405 23406 if (int_type->data.integral.bit_count == 0) 23407 return ir_const_unsigned(ira, &instruction->base.base, 0); 23408 23409 if (instr_is_comptime(op)) { 23410 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 23411 if (val == nullptr) 23412 return ira->codegen->invalid_inst_gen; 23413 if (val->special == ConstValSpecialUndef) 23414 return ir_const_undef(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 23415 23416 if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { 23417 size_t result = bigint_popcount_unsigned(&val->data.x_bigint); 23418 return ir_const_unsigned(ira, &instruction->base.base, result); 23419 } 23420 size_t result = bigint_popcount_signed(&val->data.x_bigint, int_type->data.integral.bit_count); 23421 return ir_const_unsigned(ira, &instruction->base.base, result); 23422 } 23423 23424 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); 23425 return ir_build_pop_count_gen(ira, &instruction->base.base, return_type, op); 23426 } 23427 23428 static IrInstGen *ir_analyze_union_tag(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, bool is_gen) { 23429 if (type_is_invalid(value->value->type)) 23430 return ira->codegen->invalid_inst_gen; 23431 23432 if (value->value->type->id != ZigTypeIdUnion) { 23433 ir_add_error(ira, &value->base, 23434 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value->type->name))); 23435 return ira->codegen->invalid_inst_gen; 23436 } 23437 if (!value->value->type->data.unionation.have_explicit_tag_type && !is_gen) { 23438 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum")); 23439 if (value->value->type->data.unionation.decl_node != nullptr) { 23440 add_error_note(ira->codegen, msg, value->value->type->data.unionation.decl_node, 23441 buf_sprintf("declared here")); 23442 } 23443 return ira->codegen->invalid_inst_gen; 23444 } 23445 23446 ZigType *tag_type = value->value->type->data.unionation.tag_type; 23447 assert(tag_type->id == ZigTypeIdEnum); 23448 23449 if (instr_is_comptime(value)) { 23450 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 23451 if (!val) 23452 return ira->codegen->invalid_inst_gen; 23453 23454 IrInstGenConst *const_instruction = ir_create_inst_gen<IrInstGenConst>(&ira->new_irb, 23455 source_instr->scope, source_instr->source_node); 23456 const_instruction->base.value->type = tag_type; 23457 const_instruction->base.value->special = ConstValSpecialStatic; 23458 bigint_init_bigint(&const_instruction->base.value->data.x_enum_tag, &val->data.x_union.tag); 23459 return &const_instruction->base; 23460 } 23461 23462 return ir_build_union_tag(ira, source_instr, value, tag_type); 23463 } 23464 23465 static IrInstGen *ir_analyze_instruction_switch_br(IrAnalyze *ira, 23466 IrInstSrcSwitchBr *switch_br_instruction) 23467 { 23468 IrInstGen *target_value = switch_br_instruction->target_value->child; 23469 if (type_is_invalid(target_value->value->type)) 23470 return ir_unreach_error(ira); 23471 23472 if (switch_br_instruction->switch_prongs_void != nullptr) { 23473 if (type_is_invalid(switch_br_instruction->switch_prongs_void->child->value->type)) { 23474 return ir_unreach_error(ira); 23475 } 23476 } 23477 23478 23479 size_t case_count = switch_br_instruction->case_count; 23480 23481 bool is_comptime; 23482 if (!ir_resolve_comptime(ira, switch_br_instruction->is_comptime->child, &is_comptime)) 23483 return ira->codegen->invalid_inst_gen; 23484 23485 if (is_comptime || instr_is_comptime(target_value)) { 23486 ZigValue *target_val = ir_resolve_const(ira, target_value, UndefBad); 23487 if (!target_val) 23488 return ir_unreach_error(ira); 23489 23490 IrBasicBlockSrc *old_dest_block = switch_br_instruction->else_block; 23491 for (size_t i = 0; i < case_count; i += 1) { 23492 IrInstSrcSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 23493 IrInstGen *case_value = old_case->value->child; 23494 if (type_is_invalid(case_value->value->type)) 23495 return ir_unreach_error(ira); 23496 23497 IrInstGen *casted_case_value = ir_implicit_cast(ira, case_value, target_value->value->type); 23498 if (type_is_invalid(casted_case_value->value->type)) 23499 return ir_unreach_error(ira); 23500 23501 ZigValue *case_val = ir_resolve_const(ira, casted_case_value, UndefBad); 23502 if (!case_val) 23503 return ir_unreach_error(ira); 23504 23505 if (const_values_equal(ira->codegen, target_val, case_val)) { 23506 old_dest_block = old_case->block; 23507 break; 23508 } 23509 } 23510 23511 if (is_comptime || old_dest_block->ref_count == 1) { 23512 return ir_inline_bb(ira, &switch_br_instruction->base.base, old_dest_block); 23513 } else { 23514 IrBasicBlockGen *new_dest_block = ir_get_new_bb(ira, old_dest_block, &switch_br_instruction->base.base); 23515 IrInstGen *result = ir_build_br_gen(ira, &switch_br_instruction->base.base, new_dest_block); 23516 return ir_finish_anal(ira, result); 23517 } 23518 } 23519 23520 IrInstGenSwitchBrCase *cases = heap::c_allocator.allocate<IrInstGenSwitchBrCase>(case_count); 23521 for (size_t i = 0; i < case_count; i += 1) { 23522 IrInstSrcSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 23523 IrInstGenSwitchBrCase *new_case = &cases[i]; 23524 new_case->block = ir_get_new_bb(ira, old_case->block, &switch_br_instruction->base.base); 23525 new_case->value = ira->codegen->invalid_inst_gen; 23526 23527 // Calling ir_get_new_bb set the ref_instruction on the new basic block. 23528 // However a switch br may branch to the same basic block which would trigger an 23529 // incorrect re-generation of the block. So we set it to null here and assign 23530 // it back after the loop. 23531 new_case->block->ref_instruction = nullptr; 23532 23533 IrInstSrc *old_value = old_case->value; 23534 IrInstGen *new_value = old_value->child; 23535 if (type_is_invalid(new_value->value->type)) 23536 continue; 23537 23538 IrInstGen *casted_new_value = ir_implicit_cast(ira, new_value, target_value->value->type); 23539 if (type_is_invalid(casted_new_value->value->type)) 23540 continue; 23541 23542 if (!ir_resolve_const(ira, casted_new_value, UndefBad)) 23543 continue; 23544 23545 new_case->value = casted_new_value; 23546 } 23547 23548 for (size_t i = 0; i < case_count; i += 1) { 23549 IrInstGenSwitchBrCase *new_case = &cases[i]; 23550 if (type_is_invalid(new_case->value->value->type)) 23551 return ir_unreach_error(ira); 23552 new_case->block->ref_instruction = &switch_br_instruction->base.base; 23553 } 23554 23555 IrBasicBlockGen *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base.base); 23556 IrInstGenSwitchBr *switch_br = ir_build_switch_br_gen(ira, &switch_br_instruction->base.base, 23557 target_value, new_else_block, case_count, cases); 23558 return ir_finish_anal(ira, &switch_br->base); 23559 } 23560 23561 static IrInstGen *ir_analyze_instruction_switch_target(IrAnalyze *ira, 23562 IrInstSrcSwitchTarget *switch_target_instruction) 23563 { 23564 Error err; 23565 IrInstGen *target_value_ptr = switch_target_instruction->target_value_ptr->child; 23566 if (type_is_invalid(target_value_ptr->value->type)) 23567 return ira->codegen->invalid_inst_gen; 23568 23569 if (target_value_ptr->value->type->id == ZigTypeIdMetaType) { 23570 assert(instr_is_comptime(target_value_ptr)); 23571 ZigType *ptr_type = target_value_ptr->value->data.x_type; 23572 assert(ptr_type->id == ZigTypeIdPointer); 23573 return ir_const_type(ira, &switch_target_instruction->base.base, ptr_type->data.pointer.child_type); 23574 } 23575 23576 ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; 23577 ZigValue *pointee_val = nullptr; 23578 if (instr_is_comptime(target_value_ptr) && target_value_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 23579 pointee_val = const_ptr_pointee(ira, ira->codegen, target_value_ptr->value, target_value_ptr->base.source_node); 23580 if (pointee_val == nullptr) 23581 return ira->codegen->invalid_inst_gen; 23582 23583 if (pointee_val->special == ConstValSpecialRuntime) 23584 pointee_val = nullptr; 23585 } 23586 if ((err = type_resolve(ira->codegen, target_type, ResolveStatusSizeKnown))) 23587 return ira->codegen->invalid_inst_gen; 23588 23589 switch (target_type->id) { 23590 case ZigTypeIdInvalid: 23591 zig_unreachable(); 23592 case ZigTypeIdMetaType: 23593 case ZigTypeIdVoid: 23594 case ZigTypeIdBool: 23595 case ZigTypeIdInt: 23596 case ZigTypeIdFloat: 23597 case ZigTypeIdComptimeFloat: 23598 case ZigTypeIdComptimeInt: 23599 case ZigTypeIdEnumLiteral: 23600 case ZigTypeIdPointer: 23601 case ZigTypeIdFn: 23602 case ZigTypeIdErrorSet: { 23603 if (pointee_val) { 23604 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, nullptr); 23605 copy_const_val(ira->codegen, result->value, pointee_val); 23606 result->value->type = target_type; 23607 return result; 23608 } 23609 23610 IrInstGen *result = ir_get_deref(ira, &switch_target_instruction->base.base, target_value_ptr, nullptr); 23611 result->value->type = target_type; 23612 return result; 23613 } 23614 case ZigTypeIdUnion: { 23615 AstNode *decl_node = target_type->data.unionation.decl_node; 23616 if (!decl_node->data.container_decl.auto_enum && 23617 decl_node->data.container_decl.init_arg_expr == nullptr) 23618 { 23619 ErrorMsg *msg = ir_add_error(ira, &target_value_ptr->base, 23620 buf_sprintf("switch on union which has no attached enum")); 23621 add_error_note(ira->codegen, msg, decl_node, 23622 buf_sprintf("consider 'union(enum)' here")); 23623 return ira->codegen->invalid_inst_gen; 23624 } 23625 ZigType *tag_type = target_type->data.unionation.tag_type; 23626 assert(tag_type != nullptr); 23627 assert(tag_type->id == ZigTypeIdEnum); 23628 if (pointee_val) { 23629 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, tag_type); 23630 bigint_init_bigint(&result->value->data.x_enum_tag, &pointee_val->data.x_union.tag); 23631 return result; 23632 } 23633 if (tag_type->data.enumeration.src_field_count == 1) { 23634 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, tag_type); 23635 TypeEnumField *only_field = &tag_type->data.enumeration.fields[0]; 23636 bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value); 23637 return result; 23638 } 23639 23640 IrInstGen *union_value = ir_get_deref(ira, &switch_target_instruction->base.base, target_value_ptr, nullptr); 23641 union_value->value->type = target_type; 23642 23643 return ir_build_union_tag(ira, &switch_target_instruction->base.base, union_value, tag_type); 23644 } 23645 case ZigTypeIdEnum: { 23646 if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown))) 23647 return ira->codegen->invalid_inst_gen; 23648 if (target_type->data.enumeration.src_field_count == 1) { 23649 TypeEnumField *only_field = &target_type->data.enumeration.fields[0]; 23650 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, target_type); 23651 bigint_init_bigint(&result->value->data.x_enum_tag, &only_field->value); 23652 return result; 23653 } 23654 23655 if (pointee_val) { 23656 IrInstGen *result = ir_const(ira, &switch_target_instruction->base.base, target_type); 23657 bigint_init_bigint(&result->value->data.x_enum_tag, &pointee_val->data.x_enum_tag); 23658 return result; 23659 } 23660 23661 IrInstGen *enum_value = ir_get_deref(ira, &switch_target_instruction->base.base, target_value_ptr, nullptr); 23662 enum_value->value->type = target_type; 23663 return enum_value; 23664 } 23665 case ZigTypeIdErrorUnion: 23666 case ZigTypeIdUnreachable: 23667 case ZigTypeIdArray: 23668 case ZigTypeIdStruct: 23669 case ZigTypeIdUndefined: 23670 case ZigTypeIdNull: 23671 case ZigTypeIdOptional: 23672 case ZigTypeIdBoundFn: 23673 case ZigTypeIdOpaque: 23674 case ZigTypeIdVector: 23675 case ZigTypeIdFnFrame: 23676 case ZigTypeIdAnyFrame: 23677 ir_add_error(ira, &switch_target_instruction->base.base, 23678 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name))); 23679 return ira->codegen->invalid_inst_gen; 23680 } 23681 zig_unreachable(); 23682 } 23683 23684 static IrInstGen *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstSrcSwitchVar *instruction) { 23685 IrInstGen *target_value_ptr = instruction->target_value_ptr->child; 23686 if (type_is_invalid(target_value_ptr->value->type)) 23687 return ira->codegen->invalid_inst_gen; 23688 23689 ZigType *ref_type = target_value_ptr->value->type; 23690 assert(ref_type->id == ZigTypeIdPointer); 23691 ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; 23692 if (target_type->id == ZigTypeIdUnion) { 23693 ZigType *enum_type = target_type->data.unionation.tag_type; 23694 assert(enum_type != nullptr); 23695 assert(enum_type->id == ZigTypeIdEnum); 23696 assert(instruction->prongs_len > 0); 23697 23698 IrInstGen *first_prong_value = instruction->prongs_ptr[0]->child; 23699 if (type_is_invalid(first_prong_value->value->type)) 23700 return ira->codegen->invalid_inst_gen; 23701 23702 IrInstGen *first_casted_prong_value = ir_implicit_cast(ira, first_prong_value, enum_type); 23703 if (type_is_invalid(first_casted_prong_value->value->type)) 23704 return ira->codegen->invalid_inst_gen; 23705 23706 ZigValue *first_prong_val = ir_resolve_const(ira, first_casted_prong_value, UndefBad); 23707 if (first_prong_val == nullptr) 23708 return ira->codegen->invalid_inst_gen; 23709 23710 TypeUnionField *first_field = find_union_field_by_tag(target_type, &first_prong_val->data.x_enum_tag); 23711 23712 ErrorMsg *invalid_payload_msg = nullptr; 23713 for (size_t prong_i = 1; prong_i < instruction->prongs_len; prong_i += 1) { 23714 IrInstGen *this_prong_inst = instruction->prongs_ptr[prong_i]->child; 23715 if (type_is_invalid(this_prong_inst->value->type)) 23716 return ira->codegen->invalid_inst_gen; 23717 23718 IrInstGen *this_casted_prong_value = ir_implicit_cast(ira, this_prong_inst, enum_type); 23719 if (type_is_invalid(this_casted_prong_value->value->type)) 23720 return ira->codegen->invalid_inst_gen; 23721 23722 ZigValue *this_prong = ir_resolve_const(ira, this_casted_prong_value, UndefBad); 23723 if (this_prong == nullptr) 23724 return ira->codegen->invalid_inst_gen; 23725 23726 TypeUnionField *payload_field = find_union_field_by_tag(target_type, &this_prong->data.x_enum_tag); 23727 ZigType *payload_type = payload_field->type_entry; 23728 if (first_field->type_entry != payload_type) { 23729 if (invalid_payload_msg == nullptr) { 23730 invalid_payload_msg = ir_add_error(ira, &instruction->base.base, 23731 buf_sprintf("capture group with incompatible types")); 23732 add_error_note(ira->codegen, invalid_payload_msg, first_prong_value->base.source_node, 23733 buf_sprintf("type '%s' here", buf_ptr(&first_field->type_entry->name))); 23734 } 23735 add_error_note(ira->codegen, invalid_payload_msg, this_prong_inst->base.source_node, 23736 buf_sprintf("type '%s' here", buf_ptr(&payload_field->type_entry->name))); 23737 } 23738 } 23739 23740 if (invalid_payload_msg != nullptr) { 23741 return ira->codegen->invalid_inst_gen; 23742 } 23743 23744 if (instr_is_comptime(target_value_ptr)) { 23745 ZigValue *target_val_ptr = ir_resolve_const(ira, target_value_ptr, UndefBad); 23746 if (!target_value_ptr) 23747 return ira->codegen->invalid_inst_gen; 23748 23749 ZigValue *pointee_val = const_ptr_pointee(ira, ira->codegen, target_val_ptr, instruction->base.base.source_node); 23750 if (pointee_val == nullptr) 23751 return ira->codegen->invalid_inst_gen; 23752 23753 IrInstGen *result = ir_const(ira, &instruction->base.base, 23754 get_pointer_to_type(ira->codegen, first_field->type_entry, 23755 target_val_ptr->type->data.pointer.is_const)); 23756 ZigValue *out_val = result->value; 23757 out_val->data.x_ptr.special = ConstPtrSpecialRef; 23758 out_val->data.x_ptr.mut = target_val_ptr->data.x_ptr.mut; 23759 out_val->data.x_ptr.data.ref.pointee = pointee_val->data.x_union.payload; 23760 return result; 23761 } 23762 23763 ZigType *result_type = get_pointer_to_type(ira->codegen, first_field->type_entry, 23764 target_value_ptr->value->type->data.pointer.is_const); 23765 return ir_build_union_field_ptr(ira, &instruction->base.base, target_value_ptr, first_field, 23766 false, false, result_type); 23767 } else if (target_type->id == ZigTypeIdErrorSet) { 23768 // construct an error set from the prong values 23769 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 23770 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 23771 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 23772 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 23773 ZigList<ErrorTableEntry *> error_list = {}; 23774 buf_resize(&err_set_type->name, 0); 23775 buf_appendf(&err_set_type->name, "error{"); 23776 for (size_t i = 0; i < instruction->prongs_len; i += 1) { 23777 ErrorTableEntry *err = ir_resolve_error(ira, instruction->prongs_ptr[i]->child); 23778 if (err == nullptr) 23779 return ira->codegen->invalid_inst_gen; 23780 error_list.append(err); 23781 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&err->name)); 23782 } 23783 err_set_type->data.error_set.errors = error_list.items; 23784 err_set_type->data.error_set.err_count = error_list.length; 23785 buf_appendf(&err_set_type->name, "}"); 23786 23787 23788 ZigType *new_target_value_ptr_type = get_pointer_to_type_extra(ira->codegen, 23789 err_set_type, 23790 ref_type->data.pointer.is_const, ref_type->data.pointer.is_volatile, 23791 ref_type->data.pointer.ptr_len, 23792 ref_type->data.pointer.explicit_alignment, 23793 ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, 23794 ref_type->data.pointer.allow_zero); 23795 return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, 23796 &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false, false); 23797 } else { 23798 ir_add_error(ira, &instruction->base.base, 23799 buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); 23800 return ira->codegen->invalid_inst_gen; 23801 } 23802 } 23803 23804 static IrInstGen *ir_analyze_instruction_switch_else_var(IrAnalyze *ira, 23805 IrInstSrcSwitchElseVar *instruction) 23806 { 23807 IrInstGen *target_value_ptr = instruction->target_value_ptr->child; 23808 if (type_is_invalid(target_value_ptr->value->type)) 23809 return ira->codegen->invalid_inst_gen; 23810 23811 ZigType *ref_type = target_value_ptr->value->type; 23812 assert(ref_type->id == ZigTypeIdPointer); 23813 ZigType *target_type = target_value_ptr->value->type->data.pointer.child_type; 23814 if (target_type->id == ZigTypeIdErrorSet) { 23815 // make a new set that has the other cases removed 23816 if (!resolve_inferred_error_set(ira->codegen, target_type, instruction->base.base.source_node)) { 23817 return ira->codegen->invalid_inst_gen; 23818 } 23819 if (type_is_global_error_set(target_type)) { 23820 // the type of the else capture variable still has to be the global error set. 23821 // once the runtime hint system is more sophisticated, we could add some hint information here. 23822 return target_value_ptr; 23823 } 23824 // Make note of the errors handled by other cases 23825 ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); 23826 // We may not have any case in the switch if this is a lone else 23827 const size_t switch_cases = instruction->switch_br ? instruction->switch_br->case_count : 0; 23828 for (size_t case_i = 0; case_i < switch_cases; case_i += 1) { 23829 IrInstSrcSwitchBrCase *br_case = &instruction->switch_br->cases[case_i]; 23830 IrInstGen *case_expr = br_case->value->child; 23831 if (case_expr->value->type->id == ZigTypeIdErrorSet) { 23832 ErrorTableEntry *err = ir_resolve_error(ira, case_expr); 23833 if (err == nullptr) 23834 return ira->codegen->invalid_inst_gen; 23835 errors[err->value] = err; 23836 } else if (case_expr->value->type->id == ZigTypeIdMetaType) { 23837 ZigType *err_set_type = ir_resolve_type(ira, case_expr); 23838 if (type_is_invalid(err_set_type)) 23839 return ira->codegen->invalid_inst_gen; 23840 populate_error_set_table(errors, err_set_type); 23841 } else { 23842 zig_unreachable(); 23843 } 23844 } 23845 ZigList<ErrorTableEntry *> result_list = {}; 23846 23847 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 23848 buf_resize(&err_set_type->name, 0); 23849 buf_appendf(&err_set_type->name, "error{"); 23850 23851 // Look at all the errors in the type switched on and add them to the result_list 23852 // if they are not handled by cases. 23853 for (uint32_t i = 0; i < target_type->data.error_set.err_count; i += 1) { 23854 ErrorTableEntry *error_entry = target_type->data.error_set.errors[i]; 23855 ErrorTableEntry *existing_entry = errors[error_entry->value]; 23856 if (existing_entry == nullptr) { 23857 result_list.append(error_entry); 23858 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); 23859 } 23860 } 23861 heap::c_allocator.deallocate(errors, ira->codegen->errors_by_index.length); 23862 23863 err_set_type->data.error_set.err_count = result_list.length; 23864 err_set_type->data.error_set.errors = result_list.items; 23865 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 23866 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 23867 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 23868 23869 buf_appendf(&err_set_type->name, "}"); 23870 23871 ZigType *new_target_value_ptr_type = get_pointer_to_type_extra(ira->codegen, 23872 err_set_type, 23873 ref_type->data.pointer.is_const, ref_type->data.pointer.is_volatile, 23874 ref_type->data.pointer.ptr_len, 23875 ref_type->data.pointer.explicit_alignment, 23876 ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, 23877 ref_type->data.pointer.allow_zero); 23878 return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, 23879 &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false, false); 23880 } 23881 23882 return target_value_ptr; 23883 } 23884 23885 static IrInstGen *ir_analyze_instruction_import(IrAnalyze *ira, IrInstSrcImport *import_instruction) { 23886 Error err; 23887 23888 IrInstGen *name_value = import_instruction->name->child; 23889 Buf *import_target_str = ir_resolve_str(ira, name_value); 23890 if (!import_target_str) 23891 return ira->codegen->invalid_inst_gen; 23892 23893 AstNode *source_node = import_instruction->base.base.source_node; 23894 ZigType *import = source_node->owner; 23895 23896 ZigType *target_import; 23897 Buf *import_target_path; 23898 Buf full_path = BUF_INIT; 23899 if ((err = analyze_import(ira->codegen, import, import_target_str, &target_import, 23900 &import_target_path, &full_path))) 23901 { 23902 if (err == ErrorImportOutsidePkgPath) { 23903 ir_add_error_node(ira, source_node, 23904 buf_sprintf("import of file outside package path: '%s'", 23905 buf_ptr(import_target_path))); 23906 return ira->codegen->invalid_inst_gen; 23907 } else if (err == ErrorFileNotFound) { 23908 ir_add_error_node(ira, source_node, 23909 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); 23910 return ira->codegen->invalid_inst_gen; 23911 } else { 23912 ir_add_error_node(ira, source_node, 23913 buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); 23914 return ira->codegen->invalid_inst_gen; 23915 } 23916 } 23917 23918 return ir_const_type(ira, &import_instruction->base.base, target_import); 23919 } 23920 23921 static IrInstGen *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstSrcRef *ref_instruction) { 23922 IrInstGen *value = ref_instruction->value->child; 23923 if (type_is_invalid(value->value->type)) 23924 return ira->codegen->invalid_inst_gen; 23925 23926 bool is_const = false; 23927 bool is_volatile = false; 23928 23929 ZigValue *child_value = value->value; 23930 if (child_value->special == ConstValSpecialStatic) { 23931 is_const = true; 23932 } 23933 23934 return ir_get_ref(ira, &ref_instruction->base.base, value, is_const, is_volatile); 23935 } 23936 23937 static IrInstGen *ir_analyze_union_init(IrAnalyze *ira, IrInst* source_instruction, 23938 AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstGen *field_result_loc, 23939 IrInstGen *result_loc) 23940 { 23941 Error err; 23942 assert(union_type->id == ZigTypeIdUnion); 23943 23944 if ((err = type_resolve(ira->codegen, union_type, ResolveStatusZeroBitsKnown))) 23945 return ira->codegen->invalid_inst_gen; 23946 23947 TypeUnionField *type_field = find_union_type_field(union_type, field_name); 23948 if (type_field == nullptr) { 23949 ir_add_error_node(ira, field_source_node, 23950 buf_sprintf("no field named '%s' in union '%s'", 23951 buf_ptr(field_name), buf_ptr(&union_type->name))); 23952 return ira->codegen->invalid_inst_gen; 23953 } 23954 23955 if (type_is_invalid(type_field->type_entry)) 23956 return ira->codegen->invalid_inst_gen; 23957 23958 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { 23959 if (instr_is_comptime(field_result_loc) && 23960 field_result_loc->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 23961 { 23962 // nothing 23963 } else { 23964 result_loc->value->special = ConstValSpecialRuntime; 23965 } 23966 } 23967 23968 bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instruction->scope) 23969 || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes; 23970 23971 IrInstGen *result = ir_get_deref(ira, source_instruction, result_loc, nullptr); 23972 if (is_comptime && !instr_is_comptime(result)) { 23973 ir_add_error(ira, &field_result_loc->base, 23974 buf_sprintf("unable to evaluate constant expression")); 23975 return ira->codegen->invalid_inst_gen; 23976 } 23977 return result; 23978 } 23979 23980 static IrInstGen *ir_analyze_container_init_fields(IrAnalyze *ira, IrInst *source_instr, 23981 ZigType *container_type, size_t instr_field_count, IrInstSrcContainerInitFieldsField *fields, 23982 IrInstGen *result_loc) 23983 { 23984 Error err; 23985 if (container_type->id == ZigTypeIdUnion) { 23986 if (instr_field_count != 1) { 23987 ir_add_error(ira, source_instr, 23988 buf_sprintf("union initialization expects exactly one field")); 23989 return ira->codegen->invalid_inst_gen; 23990 } 23991 IrInstSrcContainerInitFieldsField *field = &fields[0]; 23992 IrInstGen *field_result_loc = field->result_loc->child; 23993 if (type_is_invalid(field_result_loc->value->type)) 23994 return ira->codegen->invalid_inst_gen; 23995 23996 return ir_analyze_union_init(ira, source_instr, field->source_node, container_type, field->name, 23997 field_result_loc, result_loc); 23998 } 23999 if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { 24000 ir_add_error(ira, source_instr, 24001 buf_sprintf("type '%s' does not support struct initialization syntax", 24002 buf_ptr(&container_type->name))); 24003 return ira->codegen->invalid_inst_gen; 24004 } 24005 24006 if (container_type->data.structure.resolve_status == ResolveStatusBeingInferred) { 24007 // We're now done inferring the type. 24008 container_type->data.structure.resolve_status = ResolveStatusUnstarted; 24009 } 24010 24011 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 24012 return ira->codegen->invalid_inst_gen; 24013 24014 size_t actual_field_count = container_type->data.structure.src_field_count; 24015 24016 IrInstGen *first_non_const_instruction = nullptr; 24017 24018 AstNode **field_assign_nodes = heap::c_allocator.allocate<AstNode *>(actual_field_count); 24019 ZigList<IrInstGen *> const_ptrs = {}; 24020 24021 bool is_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope) 24022 || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; 24023 24024 24025 // Here we iterate over the fields that have been initialized, and emit 24026 // compile errors for missing fields and duplicate fields. 24027 // It is only now that we find out whether the struct initialization can be a comptime 24028 // value, but we have already emitted runtime instructions for the fields that 24029 // were initialized with runtime values, and have omitted instructions that would have 24030 // initialized fields with comptime values. 24031 // So now we must clean up this situation. If it turns out the struct initialization can 24032 // be a comptime value, overwrite ConstPtrMutInfer with ConstPtrMutComptimeConst. 24033 // Otherwise, we must emit instructions to runtime-initialize the fields that have 24034 // comptime-known values. 24035 24036 for (size_t i = 0; i < instr_field_count; i += 1) { 24037 IrInstSrcContainerInitFieldsField *field = &fields[i]; 24038 24039 IrInstGen *field_result_loc = field->result_loc->child; 24040 if (type_is_invalid(field_result_loc->value->type)) 24041 return ira->codegen->invalid_inst_gen; 24042 24043 TypeStructField *type_field = find_struct_type_field(container_type, field->name); 24044 if (!type_field) { 24045 ir_add_error_node(ira, field->source_node, 24046 buf_sprintf("no field named '%s' in struct '%s'", 24047 buf_ptr(field->name), buf_ptr(&container_type->name))); 24048 return ira->codegen->invalid_inst_gen; 24049 } 24050 24051 if (type_is_invalid(type_field->type_entry)) 24052 return ira->codegen->invalid_inst_gen; 24053 24054 size_t field_index = type_field->src_index; 24055 AstNode *existing_assign_node = field_assign_nodes[field_index]; 24056 if (existing_assign_node) { 24057 ErrorMsg *msg = ir_add_error_node(ira, field->source_node, buf_sprintf("duplicate field")); 24058 add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here")); 24059 return ira->codegen->invalid_inst_gen; 24060 } 24061 field_assign_nodes[field_index] = field->source_node; 24062 24063 if (instr_is_comptime(field_result_loc) && 24064 field_result_loc->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 24065 { 24066 const_ptrs.append(field_result_loc); 24067 } else { 24068 first_non_const_instruction = field_result_loc; 24069 } 24070 } 24071 24072 bool any_missing = false; 24073 for (size_t i = 0; i < actual_field_count; i += 1) { 24074 if (field_assign_nodes[i] != nullptr) continue; 24075 24076 // look for a default field value 24077 TypeStructField *field = container_type->data.structure.fields[i]; 24078 memoize_field_init_val(ira->codegen, container_type, field); 24079 if (field->init_val == nullptr) { 24080 ir_add_error(ira, source_instr, 24081 buf_sprintf("missing field: '%s'", buf_ptr(field->name))); 24082 any_missing = true; 24083 continue; 24084 } 24085 if (type_is_invalid(field->init_val->type)) 24086 return ira->codegen->invalid_inst_gen; 24087 24088 IrInstGen *runtime_inst = ir_const(ira, source_instr, field->init_val->type); 24089 copy_const_val(ira->codegen, runtime_inst->value, field->init_val); 24090 24091 IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, field, result_loc, 24092 container_type, true); 24093 ir_analyze_store_ptr(ira, source_instr, field_ptr, runtime_inst, false); 24094 if (instr_is_comptime(field_ptr) && field_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 24095 const_ptrs.append(field_ptr); 24096 } else { 24097 first_non_const_instruction = result_loc; 24098 } 24099 } 24100 if (any_missing) 24101 return ira->codegen->invalid_inst_gen; 24102 24103 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { 24104 if (const_ptrs.length != actual_field_count) { 24105 result_loc->value->special = ConstValSpecialRuntime; 24106 for (size_t i = 0; i < const_ptrs.length; i += 1) { 24107 IrInstGen *field_result_loc = const_ptrs.at(i); 24108 IrInstGen *deref = ir_get_deref(ira, &field_result_loc->base, field_result_loc, nullptr); 24109 field_result_loc->value->special = ConstValSpecialRuntime; 24110 ir_analyze_store_ptr(ira, &field_result_loc->base, field_result_loc, deref, false); 24111 } 24112 } 24113 } 24114 24115 IrInstGen *result = ir_get_deref(ira, source_instr, result_loc, nullptr); 24116 24117 if (is_comptime && !instr_is_comptime(result)) { 24118 ir_add_error_node(ira, first_non_const_instruction->base.source_node, 24119 buf_sprintf("unable to evaluate constant expression")); 24120 return ira->codegen->invalid_inst_gen; 24121 } 24122 24123 return result; 24124 } 24125 24126 static IrInstGen *ir_analyze_instruction_container_init_list(IrAnalyze *ira, 24127 IrInstSrcContainerInitList *instruction) 24128 { 24129 ir_assert(instruction->result_loc != nullptr, &instruction->base.base); 24130 IrInstGen *result_loc = instruction->result_loc->child; 24131 if (type_is_invalid(result_loc->value->type)) 24132 return result_loc; 24133 24134 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); 24135 if (result_loc->value->type->data.pointer.is_const) { 24136 ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant")); 24137 return ira->codegen->invalid_inst_gen; 24138 } 24139 24140 ZigType *container_type = result_loc->value->type->data.pointer.child_type; 24141 size_t elem_count = instruction->item_count; 24142 24143 if (is_slice(container_type)) { 24144 ir_add_error_node(ira, instruction->init_array_type_source_node, 24145 buf_sprintf("array literal requires address-of operator to coerce to slice type '%s'", 24146 buf_ptr(&container_type->name))); 24147 return ira->codegen->invalid_inst_gen; 24148 } 24149 24150 if (container_type->id == ZigTypeIdVoid) { 24151 if (elem_count != 0) { 24152 ir_add_error_node(ira, instruction->base.base.source_node, 24153 buf_sprintf("void expression expects no arguments")); 24154 return ira->codegen->invalid_inst_gen; 24155 } 24156 return ir_const_void(ira, &instruction->base.base); 24157 } 24158 24159 if (container_type->id == ZigTypeIdStruct && elem_count == 0) { 24160 ir_assert(instruction->result_loc != nullptr, &instruction->base.base); 24161 IrInstGen *result_loc = instruction->result_loc->child; 24162 if (type_is_invalid(result_loc->value->type)) 24163 return result_loc; 24164 return ir_analyze_container_init_fields(ira, &instruction->base.base, container_type, 0, nullptr, result_loc); 24165 } 24166 24167 if (container_type->id == ZigTypeIdArray) { 24168 ZigType *child_type = container_type->data.array.child_type; 24169 if (container_type->data.array.len != elem_count) { 24170 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count, nullptr); 24171 24172 ir_add_error(ira, &instruction->base.base, 24173 buf_sprintf("expected %s literal, found %s literal", 24174 buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); 24175 return ira->codegen->invalid_inst_gen; 24176 } 24177 } else if (container_type->id == ZigTypeIdStruct && 24178 container_type->data.structure.resolve_status == ResolveStatusBeingInferred) 24179 { 24180 // We're now done inferring the type. 24181 container_type->data.structure.resolve_status = ResolveStatusUnstarted; 24182 } else if (container_type->id == ZigTypeIdVector) { 24183 // OK 24184 } else { 24185 ir_add_error(ira, &instruction->base.base, 24186 buf_sprintf("type '%s' does not support array initialization", 24187 buf_ptr(&container_type->name))); 24188 return ira->codegen->invalid_inst_gen; 24189 } 24190 24191 switch (type_has_one_possible_value(ira->codegen, container_type)) { 24192 case OnePossibleValueInvalid: 24193 return ira->codegen->invalid_inst_gen; 24194 case OnePossibleValueYes: 24195 return ir_const_move(ira, &instruction->base.base, 24196 get_the_one_possible_value(ira->codegen, container_type)); 24197 case OnePossibleValueNo: 24198 break; 24199 } 24200 24201 bool is_comptime; 24202 switch (type_requires_comptime(ira->codegen, container_type)) { 24203 case ReqCompTimeInvalid: 24204 return ira->codegen->invalid_inst_gen; 24205 case ReqCompTimeNo: 24206 is_comptime = ir_should_inline(ira->old_irb.exec, instruction->base.base.scope); 24207 break; 24208 case ReqCompTimeYes: 24209 is_comptime = true; 24210 break; 24211 } 24212 24213 IrInstGen *first_non_const_instruction = nullptr; 24214 24215 // The Result Location Mechanism has already emitted runtime instructions to 24216 // initialize runtime elements and has omitted instructions for the comptime 24217 // elements. However it is only now that we find out whether the array initialization 24218 // can be a comptime value. So we must clean up the situation. If it turns out 24219 // array initialization can be a comptime value, overwrite ConstPtrMutInfer with 24220 // ConstPtrMutComptimeConst. Otherwise, emit instructions to runtime-initialize the 24221 // elements that have comptime-known values. 24222 ZigList<IrInstGen *> const_ptrs = {}; 24223 24224 for (size_t i = 0; i < elem_count; i += 1) { 24225 IrInstGen *elem_result_loc = instruction->elem_result_loc_list[i]->child; 24226 if (type_is_invalid(elem_result_loc->value->type)) 24227 return ira->codegen->invalid_inst_gen; 24228 24229 assert(elem_result_loc->value->type->id == ZigTypeIdPointer); 24230 24231 if (instr_is_comptime(elem_result_loc) && 24232 elem_result_loc->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 24233 { 24234 const_ptrs.append(elem_result_loc); 24235 } else { 24236 first_non_const_instruction = elem_result_loc; 24237 } 24238 } 24239 24240 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer) { 24241 if (const_ptrs.length != elem_count) { 24242 result_loc->value->special = ConstValSpecialRuntime; 24243 for (size_t i = 0; i < const_ptrs.length; i += 1) { 24244 IrInstGen *elem_result_loc = const_ptrs.at(i); 24245 assert(elem_result_loc->value->special == ConstValSpecialStatic); 24246 if (elem_result_loc->value->type->data.pointer.inferred_struct_field != nullptr) { 24247 // This field will be generated comptime; no need to do this. 24248 continue; 24249 } 24250 IrInstGen *deref = ir_get_deref(ira, &elem_result_loc->base, elem_result_loc, nullptr); 24251 elem_result_loc->value->special = ConstValSpecialRuntime; 24252 ir_analyze_store_ptr(ira, &elem_result_loc->base, elem_result_loc, deref, false); 24253 } 24254 } 24255 } 24256 24257 const_ptrs.deinit(); 24258 24259 IrInstGen *result = ir_get_deref(ira, &instruction->base.base, result_loc, nullptr); 24260 // If the result is a tuple, we are allowed to return a struct that uses ConstValSpecialRuntime fields at comptime. 24261 if (instr_is_comptime(result) || is_tuple(container_type)) 24262 return result; 24263 24264 if (is_comptime) { 24265 ir_add_error(ira, &first_non_const_instruction->base, 24266 buf_sprintf("unable to evaluate constant expression")); 24267 return ira->codegen->invalid_inst_gen; 24268 } 24269 24270 ZigType *result_elem_type = result_loc->value->type->data.pointer.child_type; 24271 if (is_slice(result_elem_type)) { 24272 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 24273 buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'", 24274 buf_ptr(&result_elem_type->name))); 24275 add_error_note(ira->codegen, msg, first_non_const_instruction->base.source_node, 24276 buf_sprintf("this value is not comptime-known")); 24277 return ira->codegen->invalid_inst_gen; 24278 } 24279 return result; 24280 } 24281 24282 static IrInstGen *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, 24283 IrInstSrcContainerInitFields *instruction) 24284 { 24285 ir_assert(instruction->result_loc != nullptr, &instruction->base.base); 24286 IrInstGen *result_loc = instruction->result_loc->child; 24287 if (type_is_invalid(result_loc->value->type)) 24288 return result_loc; 24289 24290 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); 24291 if (result_loc->value->type->data.pointer.is_const) { 24292 ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant")); 24293 return ira->codegen->invalid_inst_gen; 24294 } 24295 24296 ZigType *container_type = result_loc->value->type->data.pointer.child_type; 24297 24298 return ir_analyze_container_init_fields(ira, &instruction->base.base, container_type, 24299 instruction->field_count, instruction->fields, result_loc); 24300 } 24301 24302 static IrInstGen *ir_analyze_instruction_compile_err(IrAnalyze *ira, IrInstSrcCompileErr *instruction) { 24303 IrInstGen *msg_value = instruction->msg->child; 24304 Buf *msg_buf = ir_resolve_str(ira, msg_value); 24305 if (!msg_buf) 24306 return ira->codegen->invalid_inst_gen; 24307 24308 ir_add_error(ira, &instruction->base.base, msg_buf); 24309 24310 return ira->codegen->invalid_inst_gen; 24311 } 24312 24313 static IrInstGen *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInstSrcCompileLog *instruction) { 24314 Buf buf = BUF_INIT; 24315 fprintf(stderr, "| "); 24316 for (size_t i = 0; i < instruction->msg_count; i += 1) { 24317 IrInstGen *msg = instruction->msg_list[i]->child; 24318 if (type_is_invalid(msg->value->type)) 24319 return ira->codegen->invalid_inst_gen; 24320 buf_resize(&buf, 0); 24321 if (msg->value->special == ConstValSpecialLazy) { 24322 // Resolve any lazy value that's passed, we need its value 24323 if (ir_resolve_lazy(ira->codegen, msg->base.source_node, msg->value)) 24324 return ira->codegen->invalid_inst_gen; 24325 } 24326 render_const_value(ira->codegen, &buf, msg->value); 24327 const char *comma_str = (i != 0) ? ", " : ""; 24328 fprintf(stderr, "%s%s", comma_str, buf_ptr(&buf)); 24329 } 24330 fprintf(stderr, "\n"); 24331 24332 auto *expr = &instruction->base.base.source_node->data.fn_call_expr; 24333 if (!expr->seen) { 24334 // Here we bypass higher level functions such as ir_add_error because we do not want 24335 // invalidate_exec to be called. 24336 add_node_error(ira->codegen, instruction->base.base.source_node, buf_sprintf("found compile log statement")); 24337 } 24338 expr->seen = true; 24339 24340 return ir_const_void(ira, &instruction->base.base); 24341 } 24342 24343 static IrInstGen *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstSrcErrName *instruction) { 24344 IrInstGen *value = instruction->value->child; 24345 if (type_is_invalid(value->value->type)) 24346 return ira->codegen->invalid_inst_gen; 24347 24348 IrInstGen *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_global_error_set); 24349 if (type_is_invalid(casted_value->value->type)) 24350 return ira->codegen->invalid_inst_gen; 24351 24352 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 24353 true, false, PtrLenUnknown, 0, 0, 0, false); 24354 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 24355 if (instr_is_comptime(casted_value)) { 24356 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad); 24357 if (val == nullptr) 24358 return ira->codegen->invalid_inst_gen; 24359 ErrorTableEntry *err = casted_value->value->data.x_err_set; 24360 if (!err->cached_error_name_val) { 24361 ZigValue *array_val = create_const_str_lit(ira->codegen, &err->name)->data.x_ptr.data.ref.pointee; 24362 err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); 24363 } 24364 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 24365 copy_const_val(ira->codegen, result->value, err->cached_error_name_val); 24366 result->value->type = str_type; 24367 return result; 24368 } 24369 24370 ira->codegen->generate_error_name_table = true; 24371 24372 return ir_build_err_name_gen(ira, &instruction->base.base, value, str_type); 24373 } 24374 24375 static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrcTagName *instruction) { 24376 Error err; 24377 IrInstGen *target = instruction->target->child; 24378 if (type_is_invalid(target->value->type)) 24379 return ira->codegen->invalid_inst_gen; 24380 24381 if (target->value->type->id == ZigTypeIdEnumLiteral) { 24382 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 24383 Buf *field_name = target->value->data.x_enum_literal; 24384 ZigValue *array_val = create_const_str_lit(ira->codegen, field_name)->data.x_ptr.data.ref.pointee; 24385 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field_name), true); 24386 return result; 24387 } 24388 24389 if (target->value->type->id == ZigTypeIdUnion) { 24390 target = ir_analyze_union_tag(ira, &instruction->base.base, target, instruction->base.is_gen); 24391 if (type_is_invalid(target->value->type)) 24392 return ira->codegen->invalid_inst_gen; 24393 } 24394 24395 if (target->value->type->id != ZigTypeIdEnum) { 24396 ir_add_error(ira, &target->base, 24397 buf_sprintf("expected enum tag, found '%s'", buf_ptr(&target->value->type->name))); 24398 return ira->codegen->invalid_inst_gen; 24399 } 24400 24401 if (target->value->type->data.enumeration.src_field_count == 1 && 24402 !target->value->type->data.enumeration.non_exhaustive) { 24403 TypeEnumField *only_field = &target->value->type->data.enumeration.fields[0]; 24404 ZigValue *array_val = create_const_str_lit(ira->codegen, only_field->name)->data.x_ptr.data.ref.pointee; 24405 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 24406 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(only_field->name), true); 24407 return result; 24408 } 24409 24410 if (instr_is_comptime(target)) { 24411 if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusZeroBitsKnown))) 24412 return ira->codegen->invalid_inst_gen; 24413 TypeEnumField *field = find_enum_field_by_tag(target->value->type, &target->value->data.x_bigint); 24414 if (field == nullptr) { 24415 Buf *int_buf = buf_alloc(); 24416 bigint_append_buf(int_buf, &target->value->data.x_bigint, 10); 24417 24418 ir_add_error(ira, &target->base, 24419 buf_sprintf("no tag by value %s", buf_ptr(int_buf))); 24420 return ira->codegen->invalid_inst_gen; 24421 } 24422 ZigValue *array_val = create_const_str_lit(ira->codegen, field->name)->data.x_ptr.data.ref.pointee; 24423 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 24424 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field->name), true); 24425 return result; 24426 } 24427 24428 ZigType *u8_ptr_type = get_pointer_to_type_extra( 24429 ira->codegen, ira->codegen->builtin_types.entry_u8, 24430 true, false, PtrLenUnknown, 24431 0, 0, 0, false); 24432 ZigType *result_type = get_slice_type(ira->codegen, u8_ptr_type); 24433 return ir_build_tag_name_gen(ira, &instruction->base.base, target, result_type); 24434 } 24435 24436 static IrInstGen *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, 24437 IrInstSrcFieldParentPtr *instruction) 24438 { 24439 Error err; 24440 IrInstGen *type_value = instruction->type_value->child; 24441 ZigType *container_type = ir_resolve_type(ira, type_value); 24442 if (type_is_invalid(container_type)) 24443 return ira->codegen->invalid_inst_gen; 24444 24445 IrInstGen *field_name_value = instruction->field_name->child; 24446 Buf *field_name = ir_resolve_str(ira, field_name_value); 24447 if (!field_name) 24448 return ira->codegen->invalid_inst_gen; 24449 24450 IrInstGen *field_ptr = instruction->field_ptr->child; 24451 if (type_is_invalid(field_ptr->value->type)) 24452 return ira->codegen->invalid_inst_gen; 24453 24454 if (container_type->id != ZigTypeIdStruct) { 24455 ir_add_error(ira, &type_value->base, 24456 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 24457 return ira->codegen->invalid_inst_gen; 24458 } 24459 24460 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 24461 return ira->codegen->invalid_inst_gen; 24462 24463 TypeStructField *field = find_struct_type_field(container_type, field_name); 24464 if (field == nullptr) { 24465 ir_add_error(ira, &field_name_value->base, 24466 buf_sprintf("struct '%s' has no field '%s'", 24467 buf_ptr(&container_type->name), buf_ptr(field_name))); 24468 return ira->codegen->invalid_inst_gen; 24469 } 24470 24471 if (field_ptr->value->type->id != ZigTypeIdPointer) { 24472 ir_add_error(ira, &field_ptr->base, 24473 buf_sprintf("expected pointer, found '%s'", buf_ptr(&field_ptr->value->type->name))); 24474 return ira->codegen->invalid_inst_gen; 24475 } 24476 24477 bool is_packed = (container_type->data.structure.layout == ContainerLayoutPacked); 24478 uint32_t field_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); 24479 uint32_t parent_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, container_type); 24480 24481 ZigType *field_ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, 24482 field_ptr->value->type->data.pointer.is_const, 24483 field_ptr->value->type->data.pointer.is_volatile, 24484 PtrLenSingle, 24485 field_ptr_align, 0, 0, false); 24486 IrInstGen *casted_field_ptr = ir_implicit_cast(ira, field_ptr, field_ptr_type); 24487 if (type_is_invalid(casted_field_ptr->value->type)) 24488 return ira->codegen->invalid_inst_gen; 24489 24490 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, container_type, 24491 casted_field_ptr->value->type->data.pointer.is_const, 24492 casted_field_ptr->value->type->data.pointer.is_volatile, 24493 PtrLenSingle, 24494 parent_ptr_align, 0, 0, false); 24495 24496 if (instr_is_comptime(casted_field_ptr)) { 24497 ZigValue *field_ptr_val = ir_resolve_const(ira, casted_field_ptr, UndefBad); 24498 if (!field_ptr_val) 24499 return ira->codegen->invalid_inst_gen; 24500 24501 if (field_ptr_val->data.x_ptr.special != ConstPtrSpecialBaseStruct) { 24502 ir_add_error(ira, &field_ptr->base, buf_sprintf("pointer value not based on parent struct")); 24503 return ira->codegen->invalid_inst_gen; 24504 } 24505 24506 size_t ptr_field_index = field_ptr_val->data.x_ptr.data.base_struct.field_index; 24507 if (ptr_field_index != field->src_index) { 24508 ir_add_error(ira, &instruction->base.base, 24509 buf_sprintf("field '%s' has index %" ZIG_PRI_usize " but pointer value is index %" ZIG_PRI_usize " of struct '%s'", 24510 buf_ptr(field->name), field->src_index, 24511 ptr_field_index, buf_ptr(&container_type->name))); 24512 return ira->codegen->invalid_inst_gen; 24513 } 24514 24515 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 24516 ZigValue *out_val = result->value; 24517 out_val->data.x_ptr.special = ConstPtrSpecialRef; 24518 out_val->data.x_ptr.data.ref.pointee = field_ptr_val->data.x_ptr.data.base_struct.struct_val; 24519 out_val->data.x_ptr.mut = field_ptr_val->data.x_ptr.mut; 24520 return result; 24521 } 24522 24523 return ir_build_field_parent_ptr_gen(ira, &instruction->base.base, casted_field_ptr, field, result_type); 24524 } 24525 24526 static TypeStructField *validate_byte_offset(IrAnalyze *ira, 24527 IrInstGen *type_value, 24528 IrInstGen *field_name_value, 24529 size_t *byte_offset) 24530 { 24531 ZigType *container_type = ir_resolve_type(ira, type_value); 24532 if (type_is_invalid(container_type)) 24533 return nullptr; 24534 24535 Error err; 24536 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) 24537 return nullptr; 24538 24539 Buf *field_name = ir_resolve_str(ira, field_name_value); 24540 if (!field_name) 24541 return nullptr; 24542 24543 if (container_type->id != ZigTypeIdStruct) { 24544 ir_add_error(ira, &type_value->base, 24545 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 24546 return nullptr; 24547 } 24548 24549 TypeStructField *field = find_struct_type_field(container_type, field_name); 24550 if (field == nullptr) { 24551 ir_add_error(ira, &field_name_value->base, 24552 buf_sprintf("struct '%s' has no field '%s'", 24553 buf_ptr(&container_type->name), buf_ptr(field_name))); 24554 return nullptr; 24555 } 24556 24557 if (!type_has_bits(ira->codegen, field->type_entry)) { 24558 ir_add_error(ira, &field_name_value->base, 24559 buf_sprintf("zero-bit field '%s' in struct '%s' has no offset", 24560 buf_ptr(field_name), buf_ptr(&container_type->name))); 24561 return nullptr; 24562 } 24563 24564 *byte_offset = field->offset; 24565 return field; 24566 } 24567 24568 static IrInstGen *ir_analyze_instruction_byte_offset_of(IrAnalyze *ira, IrInstSrcByteOffsetOf *instruction) { 24569 IrInstGen *type_value = instruction->type_value->child; 24570 if (type_is_invalid(type_value->value->type)) 24571 return ira->codegen->invalid_inst_gen; 24572 24573 IrInstGen *field_name_value = instruction->field_name->child; 24574 size_t byte_offset = 0; 24575 if (!validate_byte_offset(ira, type_value, field_name_value, &byte_offset)) 24576 return ira->codegen->invalid_inst_gen; 24577 24578 24579 return ir_const_unsigned(ira, &instruction->base.base, byte_offset); 24580 } 24581 24582 static IrInstGen *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, IrInstSrcBitOffsetOf *instruction) { 24583 IrInstGen *type_value = instruction->type_value->child; 24584 if (type_is_invalid(type_value->value->type)) 24585 return ira->codegen->invalid_inst_gen; 24586 IrInstGen *field_name_value = instruction->field_name->child; 24587 size_t byte_offset = 0; 24588 TypeStructField *field = nullptr; 24589 if (!(field = validate_byte_offset(ira, type_value, field_name_value, &byte_offset))) 24590 return ira->codegen->invalid_inst_gen; 24591 24592 size_t bit_offset = byte_offset * 8 + field->bit_offset_in_host; 24593 return ir_const_unsigned(ira, &instruction->base.base, bit_offset); 24594 } 24595 24596 static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { 24597 Buf *field_name_buf; 24598 24599 assert(type != nullptr && !type_is_invalid(type)); 24600 field_name_buf = buf_create_from_str(field_name); 24601 TypeStructField *field = find_struct_type_field(type, field_name_buf); 24602 buf_deinit(field_name_buf); 24603 24604 if (field == nullptr || field->src_index != index) 24605 zig_panic("reference to unknown field %s", field_name); 24606 } 24607 24608 static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, ZigType *root) { 24609 Error err; 24610 ZigType *type_info_type = get_builtin_type(ira->codegen, "TypeInfo"); 24611 assert(type_info_type->id == ZigTypeIdUnion); 24612 if ((err = type_resolve(ira->codegen, type_info_type, ResolveStatusSizeKnown))) { 24613 zig_unreachable(); 24614 } 24615 24616 if (type_name == nullptr && root == nullptr) 24617 return type_info_type; 24618 else if (type_name == nullptr) 24619 return root; 24620 24621 ZigType *root_type = (root == nullptr) ? type_info_type : root; 24622 24623 ScopeDecls *type_info_scope = get_container_scope(root_type); 24624 assert(type_info_scope != nullptr); 24625 24626 Buf field_name = BUF_INIT; 24627 buf_init_from_str(&field_name, type_name); 24628 auto entry = type_info_scope->decl_table.get(&field_name); 24629 buf_deinit(&field_name); 24630 24631 TldVar *tld = (TldVar *)entry; 24632 assert(tld->base.id == TldIdVar); 24633 24634 ZigVar *var = tld->var; 24635 24636 assert(var->const_value->type->id == ZigTypeIdMetaType); 24637 24638 return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, nullptr, var->const_value); 24639 } 24640 24641 static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigValue *out_val, 24642 ScopeDecls *decls_scope, bool resolve_types) 24643 { 24644 Error err; 24645 ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr); 24646 if ((err = type_resolve(ira->codegen, type_info_declaration_type, ResolveStatusSizeKnown))) 24647 return err; 24648 24649 ensure_field_index(type_info_declaration_type, "name", 0); 24650 ensure_field_index(type_info_declaration_type, "is_pub", 1); 24651 ensure_field_index(type_info_declaration_type, "data", 2); 24652 24653 if (!resolve_types) { 24654 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, type_info_declaration_type, 24655 false, false, PtrLenUnknown, 0, 0, 0, false); 24656 24657 out_val->special = ConstValSpecialLazy; 24658 out_val->type = get_slice_type(ira->codegen, ptr_type); 24659 24660 LazyValueTypeInfoDecls *lazy_type_info_decls = heap::c_allocator.create<LazyValueTypeInfoDecls>(); 24661 lazy_type_info_decls->ira = ira; ira_ref(ira); 24662 out_val->data.x_lazy = &lazy_type_info_decls->base; 24663 lazy_type_info_decls->base.id = LazyValueIdTypeInfoDecls; 24664 24665 lazy_type_info_decls->source_instr = source_instr; 24666 lazy_type_info_decls->decls_scope = decls_scope; 24667 24668 return ErrorNone; 24669 } 24670 24671 ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type); 24672 if ((err = type_resolve(ira->codegen, type_info_declaration_data_type, ResolveStatusSizeKnown))) 24673 return err; 24674 24675 ZigType *type_info_fn_decl_type = ir_type_info_get_type(ira, "FnDecl", type_info_declaration_data_type); 24676 if ((err = type_resolve(ira->codegen, type_info_fn_decl_type, ResolveStatusSizeKnown))) 24677 return err; 24678 24679 ZigType *type_info_fn_decl_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_decl_type); 24680 if ((err = type_resolve(ira->codegen, type_info_fn_decl_inline_type, ResolveStatusSizeKnown))) 24681 return err; 24682 24683 // The unresolved declarations are collected in a separate queue to avoid 24684 // modifying decl_table while iterating over it 24685 ZigList<Tld*> resolve_decl_queue{}; 24686 24687 auto decl_it = decls_scope->decl_table.entry_iterator(); 24688 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; 24689 while ((curr_entry = decl_it.next()) != nullptr) { 24690 if (curr_entry->value->resolution == TldResolutionInvalid) { 24691 return ErrorSemanticAnalyzeFail; 24692 } 24693 24694 if (curr_entry->value->resolution == TldResolutionResolving) { 24695 ir_error_dependency_loop(ira, source_instr); 24696 return ErrorSemanticAnalyzeFail; 24697 } 24698 24699 // If the declaration is unresolved, force it to be resolved again. 24700 if (curr_entry->value->resolution == TldResolutionUnresolved) 24701 resolve_decl_queue.append(curr_entry->value); 24702 } 24703 24704 for (size_t i = 0; i < resolve_decl_queue.length; i++) { 24705 Tld *decl = resolve_decl_queue.at(i); 24706 resolve_top_level_decl(ira->codegen, decl, decl->source_node, false); 24707 if (decl->resolution == TldResolutionInvalid) { 24708 return ErrorSemanticAnalyzeFail; 24709 } 24710 } 24711 24712 resolve_decl_queue.deinit(); 24713 24714 // Loop through our declarations once to figure out how many declarations we will generate info for. 24715 int declaration_count = 0; 24716 decl_it = decls_scope->decl_table.entry_iterator(); 24717 while ((curr_entry = decl_it.next()) != nullptr) { 24718 // Skip comptime blocks and test functions. 24719 if (curr_entry->value->id == TldIdCompTime) 24720 continue; 24721 24722 if (curr_entry->value->id == TldIdFn) { 24723 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 24724 if (fn_entry->is_test) 24725 continue; 24726 } 24727 24728 declaration_count += 1; 24729 } 24730 24731 ZigValue *declaration_array = ira->codegen->pass1_arena->create<ZigValue>(); 24732 declaration_array->special = ConstValSpecialStatic; 24733 declaration_array->type = get_array_type(ira->codegen, type_info_declaration_type, declaration_count, nullptr); 24734 declaration_array->data.x_array.special = ConstArraySpecialNone; 24735 declaration_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(declaration_count); 24736 init_const_slice(ira->codegen, out_val, declaration_array, 0, declaration_count, false); 24737 24738 // Loop through the declarations and generate info. 24739 decl_it = decls_scope->decl_table.entry_iterator(); 24740 curr_entry = nullptr; 24741 int declaration_index = 0; 24742 while ((curr_entry = decl_it.next()) != nullptr) { 24743 // Skip comptime blocks and test functions. 24744 if (curr_entry->value->id == TldIdCompTime) { 24745 continue; 24746 } else if (curr_entry->value->id == TldIdFn) { 24747 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 24748 if (fn_entry->is_test) 24749 continue; 24750 } 24751 24752 ZigValue *declaration_val = &declaration_array->data.x_array.data.s_none.elements[declaration_index]; 24753 24754 declaration_val->special = ConstValSpecialStatic; 24755 declaration_val->type = type_info_declaration_type; 24756 24757 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3); 24758 ZigValue *name = create_const_str_lit(ira->codegen, curr_entry->key)->data.x_ptr.data.ref.pointee; 24759 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(curr_entry->key), true); 24760 inner_fields[1]->special = ConstValSpecialStatic; 24761 inner_fields[1]->type = ira->codegen->builtin_types.entry_bool; 24762 inner_fields[1]->data.x_bool = curr_entry->value->visib_mod == VisibModPub; 24763 inner_fields[2]->special = ConstValSpecialStatic; 24764 inner_fields[2]->type = type_info_declaration_data_type; 24765 inner_fields[2]->parent.id = ConstParentIdStruct; 24766 inner_fields[2]->parent.data.p_struct.struct_val = declaration_val; 24767 inner_fields[2]->parent.data.p_struct.field_index = 1; 24768 24769 switch (curr_entry->value->id) { 24770 case TldIdVar: 24771 { 24772 ZigVar *var = ((TldVar *)curr_entry->value)->var; 24773 assert(var != nullptr); 24774 24775 if ((err = type_resolve(ira->codegen, var->const_value->type, ResolveStatusSizeKnown))) 24776 return ErrorSemanticAnalyzeFail; 24777 24778 if (var->const_value->type->id == ZigTypeIdMetaType) { 24779 // We have a variable of type 'type', so it's actually a type declaration. 24780 // 0: Data.Type: type 24781 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0); 24782 inner_fields[2]->data.x_union.payload = var->const_value; 24783 } else { 24784 // We have a variable of another type, so we store the type of the variable. 24785 // 1: Data.Var: type 24786 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 1); 24787 24788 ZigValue *payload = ira->codegen->pass1_arena->create<ZigValue>(); 24789 payload->special = ConstValSpecialStatic; 24790 payload->type = ira->codegen->builtin_types.entry_type; 24791 payload->data.x_type = var->const_value->type; 24792 24793 inner_fields[2]->data.x_union.payload = payload; 24794 } 24795 24796 break; 24797 } 24798 case TldIdFn: 24799 { 24800 // 2: Data.Fn: Data.FnDecl 24801 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 2); 24802 24803 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 24804 assert(!fn_entry->is_test); 24805 assert(fn_entry->type_entry != nullptr); 24806 24807 AstNodeFnProto *fn_node = &fn_entry->proto_node->data.fn_proto; 24808 24809 ZigValue *fn_decl_val = ira->codegen->pass1_arena->create<ZigValue>(); 24810 fn_decl_val->special = ConstValSpecialStatic; 24811 fn_decl_val->type = type_info_fn_decl_type; 24812 fn_decl_val->parent.id = ConstParentIdUnion; 24813 fn_decl_val->parent.data.p_union.union_val = inner_fields[2]; 24814 24815 ZigValue **fn_decl_fields = alloc_const_vals_ptrs(ira->codegen, 9); 24816 fn_decl_val->data.x_struct.fields = fn_decl_fields; 24817 24818 // fn_type: type 24819 ensure_field_index(fn_decl_val->type, "fn_type", 0); 24820 fn_decl_fields[0]->special = ConstValSpecialStatic; 24821 fn_decl_fields[0]->type = ira->codegen->builtin_types.entry_type; 24822 fn_decl_fields[0]->data.x_type = fn_entry->type_entry; 24823 // inline_type: Data.FnDecl.Inline 24824 ensure_field_index(fn_decl_val->type, "inline_type", 1); 24825 fn_decl_fields[1]->special = ConstValSpecialStatic; 24826 fn_decl_fields[1]->type = type_info_fn_decl_inline_type; 24827 bigint_init_unsigned(&fn_decl_fields[1]->data.x_enum_tag, fn_entry->fn_inline); 24828 // is_var_args: bool 24829 ensure_field_index(fn_decl_val->type, "is_var_args", 2); 24830 bool is_varargs = fn_node->is_var_args; 24831 fn_decl_fields[2]->special = ConstValSpecialStatic; 24832 fn_decl_fields[2]->type = ira->codegen->builtin_types.entry_bool; 24833 fn_decl_fields[2]->data.x_bool = is_varargs; 24834 // is_extern: bool 24835 ensure_field_index(fn_decl_val->type, "is_extern", 3); 24836 fn_decl_fields[3]->special = ConstValSpecialStatic; 24837 fn_decl_fields[3]->type = ira->codegen->builtin_types.entry_bool; 24838 fn_decl_fields[3]->data.x_bool = fn_node->is_extern; 24839 // is_export: bool 24840 ensure_field_index(fn_decl_val->type, "is_export", 4); 24841 fn_decl_fields[4]->special = ConstValSpecialStatic; 24842 fn_decl_fields[4]->type = ira->codegen->builtin_types.entry_bool; 24843 fn_decl_fields[4]->data.x_bool = fn_node->is_export; 24844 // lib_name: ?[]const u8 24845 ensure_field_index(fn_decl_val->type, "lib_name", 5); 24846 fn_decl_fields[5]->special = ConstValSpecialStatic; 24847 ZigType *u8_ptr = get_pointer_to_type_extra( 24848 ira->codegen, ira->codegen->builtin_types.entry_u8, 24849 true, false, PtrLenUnknown, 24850 0, 0, 0, false); 24851 fn_decl_fields[5]->type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); 24852 if (fn_node->is_extern && fn_node->lib_name != nullptr && buf_len(fn_node->lib_name) > 0) { 24853 fn_decl_fields[5]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>(); 24854 ZigValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name)->data.x_ptr.data.ref.pointee; 24855 init_const_slice(ira->codegen, fn_decl_fields[5]->data.x_optional, lib_name, 0, 24856 buf_len(fn_node->lib_name), true); 24857 } else { 24858 fn_decl_fields[5]->data.x_optional = nullptr; 24859 } 24860 // return_type: type 24861 ensure_field_index(fn_decl_val->type, "return_type", 6); 24862 fn_decl_fields[6]->special = ConstValSpecialStatic; 24863 fn_decl_fields[6]->type = ira->codegen->builtin_types.entry_type; 24864 fn_decl_fields[6]->data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; 24865 // arg_names: [][] const u8 24866 ensure_field_index(fn_decl_val->type, "arg_names", 7); 24867 size_t fn_arg_count = fn_entry->variable_list.length; 24868 ZigValue *fn_arg_name_array = ira->codegen->pass1_arena->create<ZigValue>(); 24869 fn_arg_name_array->special = ConstValSpecialStatic; 24870 fn_arg_name_array->type = get_array_type(ira->codegen, 24871 get_slice_type(ira->codegen, u8_ptr), fn_arg_count, nullptr); 24872 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; 24873 fn_arg_name_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(fn_arg_count); 24874 24875 init_const_slice(ira->codegen, fn_decl_fields[7], fn_arg_name_array, 0, fn_arg_count, false); 24876 24877 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { 24878 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index); 24879 ZigValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index]; 24880 ZigValue *arg_name = create_const_str_lit(ira->codegen, 24881 buf_create_from_str(arg_var->name))->data.x_ptr.data.ref.pointee; 24882 init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, strlen(arg_var->name), true); 24883 fn_arg_name_val->parent.id = ConstParentIdArray; 24884 fn_arg_name_val->parent.data.p_array.array_val = fn_arg_name_array; 24885 fn_arg_name_val->parent.data.p_array.elem_index = fn_arg_index; 24886 } 24887 24888 inner_fields[2]->data.x_union.payload = fn_decl_val; 24889 break; 24890 } 24891 case TldIdContainer: 24892 { 24893 ZigType *type_entry = ((TldContainer *)curr_entry->value)->type_entry; 24894 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) 24895 return ErrorSemanticAnalyzeFail; 24896 24897 // This is a type. 24898 bigint_init_unsigned(&inner_fields[2]->data.x_union.tag, 0); 24899 24900 ZigValue *payload = ira->codegen->pass1_arena->create<ZigValue>(); 24901 payload->special = ConstValSpecialStatic; 24902 payload->type = ira->codegen->builtin_types.entry_type; 24903 payload->data.x_type = type_entry; 24904 24905 inner_fields[2]->data.x_union.payload = payload; 24906 24907 break; 24908 } 24909 default: 24910 zig_unreachable(); 24911 } 24912 24913 declaration_val->data.x_struct.fields = inner_fields; 24914 declaration_index += 1; 24915 } 24916 24917 assert(declaration_index == declaration_count); 24918 return ErrorNone; 24919 } 24920 24921 static BuiltinPtrSize ptr_len_to_size_enum_index(PtrLen ptr_len) { 24922 switch (ptr_len) { 24923 case PtrLenSingle: 24924 return BuiltinPtrSizeOne; 24925 case PtrLenUnknown: 24926 return BuiltinPtrSizeMany; 24927 case PtrLenC: 24928 return BuiltinPtrSizeC; 24929 } 24930 zig_unreachable(); 24931 } 24932 24933 static PtrLen size_enum_index_to_ptr_len(BuiltinPtrSize size_enum_index) { 24934 switch (size_enum_index) { 24935 case BuiltinPtrSizeOne: 24936 return PtrLenSingle; 24937 case BuiltinPtrSizeMany: 24938 case BuiltinPtrSizeSlice: 24939 return PtrLenUnknown; 24940 case BuiltinPtrSizeC: 24941 return PtrLenC; 24942 } 24943 zig_unreachable(); 24944 } 24945 24946 static ZigValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_entry) { 24947 Error err; 24948 ZigType *attrs_type; 24949 BuiltinPtrSize size_enum_index; 24950 if (is_slice(ptr_type_entry)) { 24951 attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index]->type_entry; 24952 size_enum_index = BuiltinPtrSizeSlice; 24953 } else if (ptr_type_entry->id == ZigTypeIdPointer) { 24954 attrs_type = ptr_type_entry; 24955 size_enum_index = ptr_len_to_size_enum_index(ptr_type_entry->data.pointer.ptr_len); 24956 } else { 24957 zig_unreachable(); 24958 } 24959 24960 if ((err = type_resolve(ira->codegen, attrs_type->data.pointer.child_type, ResolveStatusSizeKnown))) 24961 return nullptr; 24962 24963 ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); 24964 assertNoError(type_resolve(ira->codegen, type_info_pointer_type, ResolveStatusSizeKnown)); 24965 24966 ZigValue *result = ira->codegen->pass1_arena->create<ZigValue>(); 24967 result->special = ConstValSpecialStatic; 24968 result->type = type_info_pointer_type; 24969 24970 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 7); 24971 result->data.x_struct.fields = fields; 24972 24973 // size: Size 24974 ensure_field_index(result->type, "size", 0); 24975 ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type); 24976 assertNoError(type_resolve(ira->codegen, type_info_pointer_size_type, ResolveStatusSizeKnown)); 24977 fields[0]->special = ConstValSpecialStatic; 24978 fields[0]->type = type_info_pointer_size_type; 24979 bigint_init_unsigned(&fields[0]->data.x_enum_tag, size_enum_index); 24980 24981 // is_const: bool 24982 ensure_field_index(result->type, "is_const", 1); 24983 fields[1]->special = ConstValSpecialStatic; 24984 fields[1]->type = ira->codegen->builtin_types.entry_bool; 24985 fields[1]->data.x_bool = attrs_type->data.pointer.is_const; 24986 // is_volatile: bool 24987 ensure_field_index(result->type, "is_volatile", 2); 24988 fields[2]->special = ConstValSpecialStatic; 24989 fields[2]->type = ira->codegen->builtin_types.entry_bool; 24990 fields[2]->data.x_bool = attrs_type->data.pointer.is_volatile; 24991 // alignment: u32 24992 ensure_field_index(result->type, "alignment", 3); 24993 fields[3]->special = ConstValSpecialStatic; 24994 fields[3]->type = ira->codegen->builtin_types.entry_num_lit_int; 24995 bigint_init_unsigned(&fields[3]->data.x_bigint, get_ptr_align(ira->codegen, attrs_type)); 24996 // child: type 24997 ensure_field_index(result->type, "child", 4); 24998 fields[4]->special = ConstValSpecialStatic; 24999 fields[4]->type = ira->codegen->builtin_types.entry_type; 25000 fields[4]->data.x_type = attrs_type->data.pointer.child_type; 25001 // is_allowzero: bool 25002 ensure_field_index(result->type, "is_allowzero", 5); 25003 fields[5]->special = ConstValSpecialStatic; 25004 fields[5]->type = ira->codegen->builtin_types.entry_bool; 25005 fields[5]->data.x_bool = attrs_type->data.pointer.allow_zero; 25006 // sentinel: var 25007 ensure_field_index(result->type, "sentinel", 6); 25008 fields[6]->special = ConstValSpecialStatic; 25009 if (attrs_type->data.pointer.child_type->id != ZigTypeIdOpaque) { 25010 fields[6]->type = get_optional_type(ira->codegen, attrs_type->data.pointer.child_type); 25011 set_optional_payload(fields[6], attrs_type->data.pointer.sentinel); 25012 } else { 25013 fields[6]->type = ira->codegen->builtin_types.entry_null; 25014 } 25015 25016 return result; 25017 }; 25018 25019 static void make_enum_field_val(IrAnalyze *ira, ZigValue *enum_field_val, TypeEnumField *enum_field, 25020 ZigType *type_info_enum_field_type) 25021 { 25022 enum_field_val->special = ConstValSpecialStatic; 25023 enum_field_val->type = type_info_enum_field_type; 25024 25025 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 2); 25026 inner_fields[1]->special = ConstValSpecialStatic; 25027 inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; 25028 25029 ZigValue *name = create_const_str_lit(ira->codegen, enum_field->name)->data.x_ptr.data.ref.pointee; 25030 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(enum_field->name), true); 25031 25032 bigint_init_bigint(&inner_fields[1]->data.x_bigint, &enum_field->value); 25033 25034 enum_field_val->data.x_struct.fields = inner_fields; 25035 } 25036 25037 static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigType *type_entry, 25038 ZigValue **out) 25039 { 25040 Error err; 25041 assert(type_entry != nullptr); 25042 assert(!type_is_invalid(type_entry)); 25043 25044 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusSizeKnown))) 25045 return err; 25046 25047 auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); 25048 if (entry != nullptr) { 25049 *out = entry->value; 25050 return ErrorNone; 25051 } 25052 25053 ZigValue *result = nullptr; 25054 switch (type_entry->id) { 25055 case ZigTypeIdInvalid: 25056 zig_unreachable(); 25057 case ZigTypeIdMetaType: 25058 case ZigTypeIdVoid: 25059 case ZigTypeIdBool: 25060 case ZigTypeIdUnreachable: 25061 case ZigTypeIdComptimeFloat: 25062 case ZigTypeIdComptimeInt: 25063 case ZigTypeIdEnumLiteral: 25064 case ZigTypeIdUndefined: 25065 case ZigTypeIdNull: 25066 case ZigTypeIdOpaque: 25067 result = ira->codegen->intern.for_void(); 25068 break; 25069 case ZigTypeIdInt: 25070 { 25071 result = ira->codegen->pass1_arena->create<ZigValue>(); 25072 result->special = ConstValSpecialStatic; 25073 result->type = ir_type_info_get_type(ira, "Int", nullptr); 25074 25075 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2); 25076 result->data.x_struct.fields = fields; 25077 25078 // is_signed: bool 25079 ensure_field_index(result->type, "is_signed", 0); 25080 fields[0]->special = ConstValSpecialStatic; 25081 fields[0]->type = ira->codegen->builtin_types.entry_bool; 25082 fields[0]->data.x_bool = type_entry->data.integral.is_signed; 25083 // bits: u8 25084 ensure_field_index(result->type, "bits", 1); 25085 fields[1]->special = ConstValSpecialStatic; 25086 fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; 25087 bigint_init_unsigned(&fields[1]->data.x_bigint, type_entry->data.integral.bit_count); 25088 25089 break; 25090 } 25091 case ZigTypeIdFloat: 25092 { 25093 result = ira->codegen->pass1_arena->create<ZigValue>(); 25094 result->special = ConstValSpecialStatic; 25095 result->type = ir_type_info_get_type(ira, "Float", nullptr); 25096 25097 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); 25098 result->data.x_struct.fields = fields; 25099 25100 // bits: u8 25101 ensure_field_index(result->type, "bits", 0); 25102 fields[0]->special = ConstValSpecialStatic; 25103 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; 25104 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.floating.bit_count); 25105 25106 break; 25107 } 25108 case ZigTypeIdPointer: 25109 { 25110 result = create_ptr_like_type_info(ira, type_entry); 25111 if (result == nullptr) 25112 return ErrorSemanticAnalyzeFail; 25113 break; 25114 } 25115 case ZigTypeIdArray: 25116 { 25117 result = ira->codegen->pass1_arena->create<ZigValue>(); 25118 result->special = ConstValSpecialStatic; 25119 result->type = ir_type_info_get_type(ira, "Array", nullptr); 25120 25121 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 3); 25122 result->data.x_struct.fields = fields; 25123 25124 // len: usize 25125 ensure_field_index(result->type, "len", 0); 25126 fields[0]->special = ConstValSpecialStatic; 25127 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; 25128 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.array.len); 25129 // child: type 25130 ensure_field_index(result->type, "child", 1); 25131 fields[1]->special = ConstValSpecialStatic; 25132 fields[1]->type = ira->codegen->builtin_types.entry_type; 25133 fields[1]->data.x_type = type_entry->data.array.child_type; 25134 // sentinel: var 25135 fields[2]->special = ConstValSpecialStatic; 25136 fields[2]->type = get_optional_type(ira->codegen, type_entry->data.array.child_type); 25137 fields[2]->data.x_optional = type_entry->data.array.sentinel; 25138 break; 25139 } 25140 case ZigTypeIdVector: { 25141 result = ira->codegen->pass1_arena->create<ZigValue>(); 25142 result->special = ConstValSpecialStatic; 25143 result->type = ir_type_info_get_type(ira, "Vector", nullptr); 25144 25145 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2); 25146 result->data.x_struct.fields = fields; 25147 25148 // len: usize 25149 ensure_field_index(result->type, "len", 0); 25150 fields[0]->special = ConstValSpecialStatic; 25151 fields[0]->type = ira->codegen->builtin_types.entry_num_lit_int; 25152 bigint_init_unsigned(&fields[0]->data.x_bigint, type_entry->data.vector.len); 25153 // child: type 25154 ensure_field_index(result->type, "child", 1); 25155 fields[1]->special = ConstValSpecialStatic; 25156 fields[1]->type = ira->codegen->builtin_types.entry_type; 25157 fields[1]->data.x_type = type_entry->data.vector.elem_type; 25158 25159 break; 25160 } 25161 case ZigTypeIdOptional: 25162 { 25163 result = ira->codegen->pass1_arena->create<ZigValue>(); 25164 result->special = ConstValSpecialStatic; 25165 result->type = ir_type_info_get_type(ira, "Optional", nullptr); 25166 25167 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); 25168 result->data.x_struct.fields = fields; 25169 25170 // child: type 25171 ensure_field_index(result->type, "child", 0); 25172 fields[0]->special = ConstValSpecialStatic; 25173 fields[0]->type = ira->codegen->builtin_types.entry_type; 25174 fields[0]->data.x_type = type_entry->data.maybe.child_type; 25175 25176 break; 25177 } 25178 case ZigTypeIdAnyFrame: { 25179 result = ira->codegen->pass1_arena->create<ZigValue>(); 25180 result->special = ConstValSpecialStatic; 25181 result->type = ir_type_info_get_type(ira, "AnyFrame", nullptr); 25182 25183 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); 25184 result->data.x_struct.fields = fields; 25185 25186 // child: ?type 25187 ensure_field_index(result->type, "child", 0); 25188 fields[0]->special = ConstValSpecialStatic; 25189 fields[0]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 25190 fields[0]->data.x_optional = (type_entry->data.any_frame.result_type == nullptr) ? nullptr : 25191 create_const_type(ira->codegen, type_entry->data.any_frame.result_type); 25192 break; 25193 } 25194 case ZigTypeIdEnum: 25195 { 25196 result = ira->codegen->pass1_arena->create<ZigValue>(); 25197 result->special = ConstValSpecialStatic; 25198 result->type = ir_type_info_get_type(ira, "Enum", nullptr); 25199 25200 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 5); 25201 result->data.x_struct.fields = fields; 25202 25203 // layout: ContainerLayout 25204 ensure_field_index(result->type, "layout", 0); 25205 fields[0]->special = ConstValSpecialStatic; 25206 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 25207 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.enumeration.layout); 25208 // tag_type: type 25209 ensure_field_index(result->type, "tag_type", 1); 25210 fields[1]->special = ConstValSpecialStatic; 25211 fields[1]->type = ira->codegen->builtin_types.entry_type; 25212 fields[1]->data.x_type = type_entry->data.enumeration.tag_int_type; 25213 // fields: []TypeInfo.EnumField 25214 ensure_field_index(result->type, "fields", 2); 25215 25216 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 25217 if ((err = type_resolve(ira->codegen, type_info_enum_field_type, ResolveStatusSizeKnown))) { 25218 zig_unreachable(); 25219 } 25220 uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; 25221 25222 ZigValue *enum_field_array = ira->codegen->pass1_arena->create<ZigValue>(); 25223 enum_field_array->special = ConstValSpecialStatic; 25224 enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count, nullptr); 25225 enum_field_array->data.x_array.special = ConstArraySpecialNone; 25226 enum_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(enum_field_count); 25227 25228 init_const_slice(ira->codegen, fields[2], enum_field_array, 0, enum_field_count, false); 25229 25230 for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) 25231 { 25232 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index]; 25233 ZigValue *enum_field_val = &enum_field_array->data.x_array.data.s_none.elements[enum_field_index]; 25234 make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type); 25235 enum_field_val->parent.id = ConstParentIdArray; 25236 enum_field_val->parent.data.p_array.array_val = enum_field_array; 25237 enum_field_val->parent.data.p_array.elem_index = enum_field_index; 25238 } 25239 // decls: []TypeInfo.Declaration 25240 ensure_field_index(result->type, "decls", 3); 25241 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3], 25242 type_entry->data.enumeration.decls_scope, false))) 25243 { 25244 return err; 25245 } 25246 // is_exhaustive: bool 25247 ensure_field_index(result->type, "is_exhaustive", 4); 25248 fields[4]->special = ConstValSpecialStatic; 25249 fields[4]->type = ira->codegen->builtin_types.entry_bool; 25250 fields[4]->data.x_bool = !type_entry->data.enumeration.non_exhaustive; 25251 25252 break; 25253 } 25254 case ZigTypeIdErrorSet: 25255 { 25256 result = ira->codegen->pass1_arena->create<ZigValue>(); 25257 result->special = ConstValSpecialStatic; 25258 result->type = ir_type_info_get_type(ira, "ErrorSet", nullptr); 25259 25260 ZigType *type_info_error_type = ir_type_info_get_type(ira, "Error", nullptr); 25261 if (!resolve_inferred_error_set(ira->codegen, type_entry, source_instr->source_node)) { 25262 return ErrorSemanticAnalyzeFail; 25263 } 25264 if (type_is_global_error_set(type_entry)) { 25265 result->data.x_optional = nullptr; 25266 break; 25267 } 25268 if ((err = type_resolve(ira->codegen, type_info_error_type, ResolveStatusSizeKnown))) { 25269 zig_unreachable(); 25270 } 25271 ZigValue *slice_val = ira->codegen->pass1_arena->create<ZigValue>(); 25272 result->data.x_optional = slice_val; 25273 25274 uint32_t error_count = type_entry->data.error_set.err_count; 25275 ZigValue *error_array = ira->codegen->pass1_arena->create<ZigValue>(); 25276 error_array->special = ConstValSpecialStatic; 25277 error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count, nullptr); 25278 error_array->data.x_array.special = ConstArraySpecialNone; 25279 error_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(error_count); 25280 25281 init_const_slice(ira->codegen, slice_val, error_array, 0, error_count, false); 25282 for (uint32_t error_index = 0; error_index < error_count; error_index++) { 25283 ErrorTableEntry *error = type_entry->data.error_set.errors[error_index]; 25284 ZigValue *error_val = &error_array->data.x_array.data.s_none.elements[error_index]; 25285 25286 error_val->special = ConstValSpecialStatic; 25287 error_val->type = type_info_error_type; 25288 25289 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 2); 25290 inner_fields[1]->special = ConstValSpecialStatic; 25291 inner_fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int; 25292 25293 ZigValue *name = nullptr; 25294 if (error->cached_error_name_val != nullptr) 25295 name = error->cached_error_name_val; 25296 if (name == nullptr) 25297 name = create_const_str_lit(ira->codegen, &error->name)->data.x_ptr.data.ref.pointee; 25298 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(&error->name), true); 25299 bigint_init_unsigned(&inner_fields[1]->data.x_bigint, error->value); 25300 25301 error_val->data.x_struct.fields = inner_fields; 25302 error_val->parent.id = ConstParentIdArray; 25303 error_val->parent.data.p_array.array_val = error_array; 25304 error_val->parent.data.p_array.elem_index = error_index; 25305 } 25306 25307 break; 25308 } 25309 case ZigTypeIdErrorUnion: 25310 { 25311 result = ira->codegen->pass1_arena->create<ZigValue>(); 25312 result->special = ConstValSpecialStatic; 25313 result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr); 25314 25315 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 2); 25316 result->data.x_struct.fields = fields; 25317 25318 // error_set: type 25319 ensure_field_index(result->type, "error_set", 0); 25320 fields[0]->special = ConstValSpecialStatic; 25321 fields[0]->type = ira->codegen->builtin_types.entry_type; 25322 fields[0]->data.x_type = type_entry->data.error_union.err_set_type; 25323 25324 // payload: type 25325 ensure_field_index(result->type, "payload", 1); 25326 fields[1]->special = ConstValSpecialStatic; 25327 fields[1]->type = ira->codegen->builtin_types.entry_type; 25328 fields[1]->data.x_type = type_entry->data.error_union.payload_type; 25329 25330 break; 25331 } 25332 case ZigTypeIdUnion: 25333 { 25334 result = ira->codegen->pass1_arena->create<ZigValue>(); 25335 result->special = ConstValSpecialStatic; 25336 result->type = ir_type_info_get_type(ira, "Union", nullptr); 25337 25338 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 4); 25339 result->data.x_struct.fields = fields; 25340 25341 // layout: ContainerLayout 25342 ensure_field_index(result->type, "layout", 0); 25343 fields[0]->special = ConstValSpecialStatic; 25344 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 25345 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.unionation.layout); 25346 // tag_type: ?type 25347 ensure_field_index(result->type, "tag_type", 1); 25348 fields[1]->special = ConstValSpecialStatic; 25349 fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 25350 25351 AstNode *union_decl_node = type_entry->data.unionation.decl_node; 25352 if (union_decl_node->data.container_decl.auto_enum || 25353 union_decl_node->data.container_decl.init_arg_expr != nullptr) 25354 { 25355 ZigValue *tag_type = ira->codegen->pass1_arena->create<ZigValue>(); 25356 tag_type->special = ConstValSpecialStatic; 25357 tag_type->type = ira->codegen->builtin_types.entry_type; 25358 tag_type->data.x_type = type_entry->data.unionation.tag_type; 25359 fields[1]->data.x_optional = tag_type; 25360 } else { 25361 fields[1]->data.x_optional = nullptr; 25362 } 25363 // fields: []TypeInfo.UnionField 25364 ensure_field_index(result->type, "fields", 2); 25365 25366 ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr); 25367 if ((err = type_resolve(ira->codegen, type_info_union_field_type, ResolveStatusSizeKnown))) 25368 zig_unreachable(); 25369 uint32_t union_field_count = type_entry->data.unionation.src_field_count; 25370 25371 ZigValue *union_field_array = ira->codegen->pass1_arena->create<ZigValue>(); 25372 union_field_array->special = ConstValSpecialStatic; 25373 union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count, nullptr); 25374 union_field_array->data.x_array.special = ConstArraySpecialNone; 25375 union_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(union_field_count); 25376 25377 init_const_slice(ira->codegen, fields[2], union_field_array, 0, union_field_count, false); 25378 25379 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 25380 25381 for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) { 25382 TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index]; 25383 ZigValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index]; 25384 25385 union_field_val->special = ConstValSpecialStatic; 25386 union_field_val->type = type_info_union_field_type; 25387 25388 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3); 25389 inner_fields[1]->special = ConstValSpecialStatic; 25390 inner_fields[1]->type = get_optional_type(ira->codegen, type_info_enum_field_type); 25391 25392 if (fields[1]->data.x_optional == nullptr) { 25393 inner_fields[1]->data.x_optional = nullptr; 25394 } else { 25395 inner_fields[1]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>(); 25396 make_enum_field_val(ira, inner_fields[1]->data.x_optional, union_field->enum_field, type_info_enum_field_type); 25397 } 25398 25399 inner_fields[2]->special = ConstValSpecialStatic; 25400 inner_fields[2]->type = ira->codegen->builtin_types.entry_type; 25401 inner_fields[2]->data.x_type = union_field->type_entry; 25402 25403 ZigValue *name = create_const_str_lit(ira->codegen, union_field->name)->data.x_ptr.data.ref.pointee; 25404 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true); 25405 25406 union_field_val->data.x_struct.fields = inner_fields; 25407 union_field_val->parent.id = ConstParentIdArray; 25408 union_field_val->parent.data.p_array.array_val = union_field_array; 25409 union_field_val->parent.data.p_array.elem_index = union_field_index; 25410 } 25411 // decls: []TypeInfo.Declaration 25412 ensure_field_index(result->type, "decls", 3); 25413 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3], 25414 type_entry->data.unionation.decls_scope, false))) 25415 { 25416 return err; 25417 } 25418 25419 break; 25420 } 25421 case ZigTypeIdStruct: 25422 { 25423 if (type_entry->data.structure.special == StructSpecialSlice) { 25424 result = create_ptr_like_type_info(ira, type_entry); 25425 if (result == nullptr) 25426 return ErrorSemanticAnalyzeFail; 25427 break; 25428 } 25429 25430 result = ira->codegen->pass1_arena->create<ZigValue>(); 25431 result->special = ConstValSpecialStatic; 25432 result->type = ir_type_info_get_type(ira, "Struct", nullptr); 25433 25434 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 3); 25435 result->data.x_struct.fields = fields; 25436 25437 // layout: ContainerLayout 25438 ensure_field_index(result->type, "layout", 0); 25439 fields[0]->special = ConstValSpecialStatic; 25440 fields[0]->type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 25441 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.structure.layout); 25442 // fields: []TypeInfo.StructField 25443 ensure_field_index(result->type, "fields", 1); 25444 25445 ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr); 25446 if ((err = type_resolve(ira->codegen, type_info_struct_field_type, ResolveStatusSizeKnown))) { 25447 zig_unreachable(); 25448 } 25449 uint32_t struct_field_count = type_entry->data.structure.src_field_count; 25450 25451 ZigValue *struct_field_array = ira->codegen->pass1_arena->create<ZigValue>(); 25452 struct_field_array->special = ConstValSpecialStatic; 25453 struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count, nullptr); 25454 struct_field_array->data.x_array.special = ConstArraySpecialNone; 25455 struct_field_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(struct_field_count); 25456 25457 init_const_slice(ira->codegen, fields[1], struct_field_array, 0, struct_field_count, false); 25458 25459 for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) { 25460 TypeStructField *struct_field = type_entry->data.structure.fields[struct_field_index]; 25461 ZigValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index]; 25462 25463 struct_field_val->special = ConstValSpecialStatic; 25464 struct_field_val->type = type_info_struct_field_type; 25465 25466 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 4); 25467 inner_fields[1]->special = ConstValSpecialStatic; 25468 inner_fields[1]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_num_lit_int); 25469 25470 ZigType *field_type = resolve_struct_field_type(ira->codegen, struct_field); 25471 if (field_type == nullptr) 25472 return ErrorSemanticAnalyzeFail; 25473 if ((err = type_resolve(ira->codegen, field_type, ResolveStatusZeroBitsKnown))) 25474 return err; 25475 if (!type_has_bits(ira->codegen, struct_field->type_entry)) { 25476 inner_fields[1]->data.x_optional = nullptr; 25477 } else { 25478 size_t byte_offset = struct_field->offset; 25479 inner_fields[1]->data.x_optional = ira->codegen->pass1_arena->create<ZigValue>(); 25480 inner_fields[1]->data.x_optional->special = ConstValSpecialStatic; 25481 inner_fields[1]->data.x_optional->type = ira->codegen->builtin_types.entry_num_lit_int; 25482 bigint_init_unsigned(&inner_fields[1]->data.x_optional->data.x_bigint, byte_offset); 25483 } 25484 25485 inner_fields[2]->special = ConstValSpecialStatic; 25486 inner_fields[2]->type = ira->codegen->builtin_types.entry_type; 25487 inner_fields[2]->data.x_type = struct_field->type_entry; 25488 25489 // default_value: var 25490 inner_fields[3]->special = ConstValSpecialStatic; 25491 inner_fields[3]->type = get_optional_type2(ira->codegen, struct_field->type_entry); 25492 if (inner_fields[3]->type == nullptr) return ErrorSemanticAnalyzeFail; 25493 memoize_field_init_val(ira->codegen, type_entry, struct_field); 25494 if(struct_field->init_val != nullptr && type_is_invalid(struct_field->init_val->type)){ 25495 return ErrorSemanticAnalyzeFail; 25496 } 25497 set_optional_payload(inner_fields[3], struct_field->init_val); 25498 25499 ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee; 25500 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true); 25501 25502 struct_field_val->data.x_struct.fields = inner_fields; 25503 struct_field_val->parent.id = ConstParentIdArray; 25504 struct_field_val->parent.data.p_array.array_val = struct_field_array; 25505 struct_field_val->parent.data.p_array.elem_index = struct_field_index; 25506 } 25507 // decls: []TypeInfo.Declaration 25508 ensure_field_index(result->type, "decls", 2); 25509 if ((err = ir_make_type_info_decls(ira, source_instr, fields[2], 25510 type_entry->data.structure.decls_scope, false))) 25511 { 25512 return err; 25513 } 25514 25515 break; 25516 } 25517 case ZigTypeIdFn: 25518 { 25519 result = ira->codegen->pass1_arena->create<ZigValue>(); 25520 result->special = ConstValSpecialStatic; 25521 result->type = ir_type_info_get_type(ira, "Fn", nullptr); 25522 25523 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 5); 25524 result->data.x_struct.fields = fields; 25525 25526 // calling_convention: TypeInfo.CallingConvention 25527 ensure_field_index(result->type, "calling_convention", 0); 25528 fields[0]->special = ConstValSpecialStatic; 25529 fields[0]->type = get_builtin_type(ira->codegen, "CallingConvention"); 25530 bigint_init_unsigned(&fields[0]->data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); 25531 // is_generic: bool 25532 ensure_field_index(result->type, "is_generic", 1); 25533 bool is_generic = type_entry->data.fn.is_generic; 25534 fields[1]->special = ConstValSpecialStatic; 25535 fields[1]->type = ira->codegen->builtin_types.entry_bool; 25536 fields[1]->data.x_bool = is_generic; 25537 // is_varargs: bool 25538 ensure_field_index(result->type, "is_var_args", 2); 25539 bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; 25540 fields[2]->special = ConstValSpecialStatic; 25541 fields[2]->type = ira->codegen->builtin_types.entry_bool; 25542 fields[2]->data.x_bool = type_entry->data.fn.fn_type_id.is_var_args; 25543 // return_type: ?type 25544 ensure_field_index(result->type, "return_type", 3); 25545 fields[3]->special = ConstValSpecialStatic; 25546 fields[3]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 25547 if (type_entry->data.fn.fn_type_id.return_type == nullptr) 25548 fields[3]->data.x_optional = nullptr; 25549 else { 25550 ZigValue *return_type = ira->codegen->pass1_arena->create<ZigValue>(); 25551 return_type->special = ConstValSpecialStatic; 25552 return_type->type = ira->codegen->builtin_types.entry_type; 25553 return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; 25554 fields[3]->data.x_optional = return_type; 25555 } 25556 // args: []TypeInfo.FnArg 25557 ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); 25558 if ((err = type_resolve(ira->codegen, type_info_fn_arg_type, ResolveStatusSizeKnown))) { 25559 zig_unreachable(); 25560 } 25561 size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - 25562 (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); 25563 25564 ZigValue *fn_arg_array = ira->codegen->pass1_arena->create<ZigValue>(); 25565 fn_arg_array->special = ConstValSpecialStatic; 25566 fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count, nullptr); 25567 fn_arg_array->data.x_array.special = ConstArraySpecialNone; 25568 fn_arg_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(fn_arg_count); 25569 25570 init_const_slice(ira->codegen, fields[4], fn_arg_array, 0, fn_arg_count, false); 25571 25572 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) { 25573 FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; 25574 ZigValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index]; 25575 25576 fn_arg_val->special = ConstValSpecialStatic; 25577 fn_arg_val->type = type_info_fn_arg_type; 25578 25579 bool arg_is_generic = fn_param_info->type == nullptr; 25580 if (arg_is_generic) assert(is_generic); 25581 25582 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3); 25583 inner_fields[0]->special = ConstValSpecialStatic; 25584 inner_fields[0]->type = ira->codegen->builtin_types.entry_bool; 25585 inner_fields[0]->data.x_bool = arg_is_generic; 25586 inner_fields[1]->special = ConstValSpecialStatic; 25587 inner_fields[1]->type = ira->codegen->builtin_types.entry_bool; 25588 inner_fields[1]->data.x_bool = fn_param_info->is_noalias; 25589 inner_fields[2]->special = ConstValSpecialStatic; 25590 inner_fields[2]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 25591 25592 if (arg_is_generic) 25593 inner_fields[2]->data.x_optional = nullptr; 25594 else { 25595 ZigValue *arg_type = ira->codegen->pass1_arena->create<ZigValue>(); 25596 arg_type->special = ConstValSpecialStatic; 25597 arg_type->type = ira->codegen->builtin_types.entry_type; 25598 arg_type->data.x_type = fn_param_info->type; 25599 inner_fields[2]->data.x_optional = arg_type; 25600 } 25601 25602 fn_arg_val->data.x_struct.fields = inner_fields; 25603 fn_arg_val->parent.id = ConstParentIdArray; 25604 fn_arg_val->parent.data.p_array.array_val = fn_arg_array; 25605 fn_arg_val->parent.data.p_array.elem_index = fn_arg_index; 25606 } 25607 25608 break; 25609 } 25610 case ZigTypeIdBoundFn: 25611 { 25612 ZigType *fn_type = type_entry->data.bound_fn.fn_type; 25613 assert(fn_type->id == ZigTypeIdFn); 25614 if ((err = ir_make_type_info_value(ira, source_instr, fn_type, &result))) 25615 return err; 25616 25617 break; 25618 } 25619 case ZigTypeIdFnFrame: 25620 { 25621 result = ira->codegen->pass1_arena->create<ZigValue>(); 25622 result->special = ConstValSpecialStatic; 25623 result->type = ir_type_info_get_type(ira, "Frame", nullptr); 25624 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 1); 25625 result->data.x_struct.fields = fields; 25626 ZigFn *fn = type_entry->data.frame.fn; 25627 // function: var 25628 ensure_field_index(result->type, "function", 0); 25629 fields[0] = create_const_fn(ira->codegen, fn); 25630 break; 25631 } 25632 } 25633 25634 assert(result != nullptr); 25635 ira->codegen->type_info_cache.put(type_entry, result); 25636 *out = result; 25637 return ErrorNone; 25638 } 25639 25640 static IrInstGen *ir_analyze_instruction_type_info(IrAnalyze *ira, IrInstSrcTypeInfo *instruction) { 25641 Error err; 25642 IrInstGen *type_value = instruction->type_value->child; 25643 ZigType *type_entry = ir_resolve_type(ira, type_value); 25644 if (type_is_invalid(type_entry)) 25645 return ira->codegen->invalid_inst_gen; 25646 25647 ZigType *result_type = ir_type_info_get_type(ira, nullptr, nullptr); 25648 25649 ZigValue *payload; 25650 if ((err = ir_make_type_info_value(ira, &instruction->base.base, type_entry, &payload))) 25651 return ira->codegen->invalid_inst_gen; 25652 25653 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 25654 ZigValue *out_val = result->value; 25655 bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry)); 25656 out_val->data.x_union.payload = payload; 25657 25658 if (payload != nullptr) { 25659 payload->parent.id = ConstParentIdUnion; 25660 payload->parent.data.p_union.union_val = out_val; 25661 } 25662 25663 return result; 25664 } 25665 25666 static ZigValue *get_const_field(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, 25667 const char *name, size_t field_index) 25668 { 25669 Error err; 25670 ensure_field_index(struct_value->type, name, field_index); 25671 ZigValue *val = struct_value->data.x_struct.fields[field_index]; 25672 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, source_node, val, UndefBad))) 25673 return nullptr; 25674 return val; 25675 } 25676 25677 static Error get_const_field_sentinel(IrAnalyze *ira, IrInst* source_instr, ZigValue *struct_value, 25678 const char *name, size_t field_index, ZigType *elem_type, ZigValue **result) 25679 { 25680 ZigValue *field_val = get_const_field(ira, source_instr->source_node, struct_value, name, field_index); 25681 if (field_val == nullptr) 25682 return ErrorSemanticAnalyzeFail; 25683 25684 IrInstGen *field_inst = ir_const_move(ira, source_instr, field_val); 25685 IrInstGen *casted_field_inst = ir_implicit_cast(ira, field_inst, 25686 get_optional_type(ira->codegen, elem_type)); 25687 if (type_is_invalid(casted_field_inst->value->type)) 25688 return ErrorSemanticAnalyzeFail; 25689 25690 if (optional_value_is_null(casted_field_inst->value)) { 25691 *result = nullptr; 25692 } else { 25693 assert(type_has_optional_repr(casted_field_inst->value->type)); 25694 *result = casted_field_inst->value->data.x_optional; 25695 } 25696 25697 return ErrorNone; 25698 } 25699 25700 static Error get_const_field_bool(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, 25701 const char *name, size_t field_index, bool *out) 25702 { 25703 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 25704 if (value == nullptr) 25705 return ErrorSemanticAnalyzeFail; 25706 assert(value->type == ira->codegen->builtin_types.entry_bool); 25707 *out = value->data.x_bool; 25708 return ErrorNone; 25709 } 25710 25711 static BigInt *get_const_field_lit_int(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) 25712 { 25713 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 25714 if (value == nullptr) 25715 return nullptr; 25716 assert(value->type == ira->codegen->builtin_types.entry_num_lit_int); 25717 return &value->data.x_bigint; 25718 } 25719 25720 static ZigType *get_const_field_meta_type(IrAnalyze *ira, AstNode *source_node, ZigValue *struct_value, const char *name, size_t field_index) 25721 { 25722 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 25723 if (value == nullptr) 25724 return ira->codegen->invalid_inst_gen->value->type; 25725 assert(value->type == ira->codegen->builtin_types.entry_type); 25726 return value->data.x_type; 25727 } 25728 25729 static ZigType *get_const_field_meta_type_optional(IrAnalyze *ira, AstNode *source_node, 25730 ZigValue *struct_value, const char *name, size_t field_index) 25731 { 25732 ZigValue *value = get_const_field(ira, source_node, struct_value, name, field_index); 25733 if (value == nullptr) 25734 return ira->codegen->invalid_inst_gen->value->type; 25735 assert(value->type->id == ZigTypeIdOptional); 25736 assert(value->type->data.maybe.child_type == ira->codegen->builtin_types.entry_type); 25737 if (value->data.x_optional == nullptr) 25738 return nullptr; 25739 return value->data.x_optional->data.x_type; 25740 } 25741 25742 static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeId tagTypeId, ZigValue *payload) { 25743 Error err; 25744 switch (tagTypeId) { 25745 case ZigTypeIdInvalid: 25746 zig_unreachable(); 25747 case ZigTypeIdMetaType: 25748 return ira->codegen->builtin_types.entry_type; 25749 case ZigTypeIdVoid: 25750 return ira->codegen->builtin_types.entry_void; 25751 case ZigTypeIdBool: 25752 return ira->codegen->builtin_types.entry_bool; 25753 case ZigTypeIdUnreachable: 25754 return ira->codegen->builtin_types.entry_unreachable; 25755 case ZigTypeIdInt: { 25756 assert(payload->special == ConstValSpecialStatic); 25757 assert(payload->type == ir_type_info_get_type(ira, "Int", nullptr)); 25758 BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "bits", 1); 25759 if (bi == nullptr) 25760 return ira->codegen->invalid_inst_gen->value->type; 25761 bool is_signed; 25762 if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_signed", 0, &is_signed))) 25763 return ira->codegen->invalid_inst_gen->value->type; 25764 return get_int_type(ira->codegen, is_signed, bigint_as_u32(bi)); 25765 } 25766 case ZigTypeIdFloat: 25767 { 25768 assert(payload->special == ConstValSpecialStatic); 25769 assert(payload->type == ir_type_info_get_type(ira, "Float", nullptr)); 25770 BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "bits", 0); 25771 if (bi == nullptr) 25772 return ira->codegen->invalid_inst_gen->value->type; 25773 uint32_t bits = bigint_as_u32(bi); 25774 switch (bits) { 25775 case 16: return ira->codegen->builtin_types.entry_f16; 25776 case 32: return ira->codegen->builtin_types.entry_f32; 25777 case 64: return ira->codegen->builtin_types.entry_f64; 25778 case 128: return ira->codegen->builtin_types.entry_f128; 25779 } 25780 ir_add_error(ira, source_instr, buf_sprintf("%d-bit float unsupported", bits)); 25781 return ira->codegen->invalid_inst_gen->value->type; 25782 } 25783 case ZigTypeIdPointer: 25784 { 25785 ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); 25786 assert(payload->special == ConstValSpecialStatic); 25787 assert(payload->type == type_info_pointer_type); 25788 ZigValue *size_value = get_const_field(ira, source_instr->source_node, payload, "size", 0); 25789 assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type)); 25790 BuiltinPtrSize size_enum_index = (BuiltinPtrSize)bigint_as_u32(&size_value->data.x_enum_tag); 25791 PtrLen ptr_len = size_enum_index_to_ptr_len(size_enum_index); 25792 ZigType *elem_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 4); 25793 if (type_is_invalid(elem_type)) 25794 return ira->codegen->invalid_inst_gen->value->type; 25795 ZigValue *sentinel; 25796 if ((err = get_const_field_sentinel(ira, source_instr, payload, "sentinel", 6, 25797 elem_type, &sentinel))) 25798 { 25799 return ira->codegen->invalid_inst_gen->value->type; 25800 } 25801 BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "alignment", 3); 25802 if (bi == nullptr) 25803 return ira->codegen->invalid_inst_gen->value->type; 25804 25805 bool is_const; 25806 if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_const", 1, &is_const))) 25807 return ira->codegen->invalid_inst_gen->value->type; 25808 25809 bool is_volatile; 25810 if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_volatile", 2, 25811 &is_volatile))) 25812 { 25813 return ira->codegen->invalid_inst_gen->value->type; 25814 } 25815 25816 bool is_allowzero; 25817 if ((err = get_const_field_bool(ira, source_instr->source_node, payload, "is_allowzero", 5, 25818 &is_allowzero))) 25819 { 25820 return ira->codegen->invalid_inst_gen->value->type; 25821 } 25822 25823 25824 ZigType *ptr_type = get_pointer_to_type_extra2(ira->codegen, 25825 elem_type, 25826 is_const, 25827 is_volatile, 25828 ptr_len, 25829 bigint_as_u32(bi), 25830 0, // bit_offset_in_host 25831 0, // host_int_bytes 25832 is_allowzero, 25833 VECTOR_INDEX_NONE, nullptr, sentinel); 25834 if (size_enum_index != 2) 25835 return ptr_type; 25836 return get_slice_type(ira->codegen, ptr_type); 25837 } 25838 case ZigTypeIdArray: { 25839 assert(payload->special == ConstValSpecialStatic); 25840 assert(payload->type == ir_type_info_get_type(ira, "Array", nullptr)); 25841 ZigType *elem_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 1); 25842 if (type_is_invalid(elem_type)) 25843 return ira->codegen->invalid_inst_gen->value->type; 25844 ZigValue *sentinel; 25845 if ((err = get_const_field_sentinel(ira, source_instr, payload, "sentinel", 2, 25846 elem_type, &sentinel))) 25847 { 25848 return ira->codegen->invalid_inst_gen->value->type; 25849 } 25850 BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "len", 0); 25851 if (bi == nullptr) 25852 return ira->codegen->invalid_inst_gen->value->type; 25853 return get_array_type(ira->codegen, elem_type, bigint_as_u64(bi), sentinel); 25854 } 25855 case ZigTypeIdComptimeFloat: 25856 return ira->codegen->builtin_types.entry_num_lit_float; 25857 case ZigTypeIdComptimeInt: 25858 return ira->codegen->builtin_types.entry_num_lit_int; 25859 case ZigTypeIdUndefined: 25860 return ira->codegen->builtin_types.entry_undef; 25861 case ZigTypeIdNull: 25862 return ira->codegen->builtin_types.entry_null; 25863 case ZigTypeIdOptional: { 25864 assert(payload->special == ConstValSpecialStatic); 25865 assert(payload->type == ir_type_info_get_type(ira, "Optional", nullptr)); 25866 ZigType *child_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 0); 25867 return get_optional_type(ira->codegen, child_type); 25868 } 25869 case ZigTypeIdErrorUnion: { 25870 assert(payload->special == ConstValSpecialStatic); 25871 assert(payload->type == ir_type_info_get_type(ira, "ErrorUnion", nullptr)); 25872 ZigType *err_set_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "error_set", 0); 25873 ZigType *payload_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "payload", 1); 25874 return get_error_union_type(ira->codegen, err_set_type, payload_type); 25875 } 25876 case ZigTypeIdOpaque: { 25877 Buf *bare_name = buf_alloc(); 25878 Buf *full_name = get_anon_type_name(ira->codegen, 25879 ira->old_irb.exec, "opaque", source_instr->scope, source_instr->source_node, bare_name); 25880 return get_opaque_type(ira->codegen, 25881 source_instr->scope, source_instr->source_node, buf_ptr(full_name), bare_name); 25882 } 25883 case ZigTypeIdVector: { 25884 assert(payload->special == ConstValSpecialStatic); 25885 assert(payload->type == ir_type_info_get_type(ira, "Vector", nullptr)); 25886 BigInt *len = get_const_field_lit_int(ira, source_instr->source_node, payload, "len", 0); 25887 ZigType *child_type = get_const_field_meta_type(ira, source_instr->source_node, payload, "child", 1); 25888 Error err; 25889 if ((err = ir_validate_vector_elem_type(ira, source_instr->source_node, child_type))) { 25890 return ira->codegen->invalid_inst_gen->value->type; 25891 } 25892 return get_vector_type(ira->codegen, bigint_as_u32(len), child_type); 25893 } 25894 case ZigTypeIdAnyFrame: { 25895 assert(payload->special == ConstValSpecialStatic); 25896 assert(payload->type == ir_type_info_get_type(ira, "AnyFrame", nullptr)); 25897 ZigType *child_type = get_const_field_meta_type_optional(ira, source_instr->source_node, payload, "child", 0); 25898 return get_any_frame_type(ira->codegen, child_type); 25899 } 25900 case ZigTypeIdEnumLiteral: 25901 return ira->codegen->builtin_types.entry_enum_literal; 25902 case ZigTypeIdFnFrame: { 25903 assert(payload->special == ConstValSpecialStatic); 25904 assert(payload->type == ir_type_info_get_type(ira, "Frame", nullptr)); 25905 ZigValue *function = get_const_field(ira, source_instr->source_node, payload, "function", 0); 25906 assert(function->type->id == ZigTypeIdFn); 25907 ZigFn *fn = function->data.x_ptr.data.fn.fn_entry; 25908 return get_fn_frame_type(ira->codegen, fn); 25909 } 25910 case ZigTypeIdErrorSet: { 25911 assert(payload->special == ConstValSpecialStatic); 25912 assert(payload->type->id == ZigTypeIdOptional); 25913 ZigValue *slice = payload->data.x_optional; 25914 if (slice == nullptr) 25915 return ira->codegen->builtin_types.entry_global_error_set; 25916 assert(slice->special == ConstValSpecialStatic); 25917 assert(is_slice(slice->type)); 25918 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 25919 Buf bare_name = BUF_INIT; 25920 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)); 25921 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; 25922 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; 25923 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size; 25924 ZigValue *ptr = slice->data.x_struct.fields[slice_ptr_index]; 25925 assert(ptr->data.x_ptr.special == ConstPtrSpecialBaseArray);; 25926 assert(ptr->data.x_ptr.data.base_array.elem_index == 0); 25927 ZigValue *arr = ptr->data.x_ptr.data.base_array.array_val; 25928 assert(arr->special == ConstValSpecialStatic); 25929 assert(arr->data.x_array.special == ConstArraySpecialNone); 25930 ZigValue *len = slice->data.x_struct.fields[slice_len_index]; 25931 size_t count = bigint_as_usize(&len->data.x_bigint); 25932 err_set_type->data.error_set.err_count = count; 25933 err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(count); 25934 bool *already_set = heap::c_allocator.allocate<bool>(ira->codegen->errors_by_index.length + count); 25935 for (size_t i = 0; i < count; i++) { 25936 ZigValue *error = &arr->data.x_array.data.s_none.elements[i]; 25937 assert(error->type == ir_type_info_get_type(ira, "Error", nullptr)); 25938 ErrorTableEntry *err_entry = heap::c_allocator.create<ErrorTableEntry>(); 25939 err_entry->decl_node = source_instr->source_node; 25940 ZigValue *name_slice = get_const_field(ira, source_instr->source_node, error, "name", 0); 25941 ZigValue *name_ptr = name_slice->data.x_struct.fields[slice_ptr_index]; 25942 ZigValue *name_len = name_slice->data.x_struct.fields[slice_len_index]; 25943 assert(name_ptr->data.x_ptr.special == ConstPtrSpecialBaseArray); 25944 assert(name_ptr->data.x_ptr.data.base_array.elem_index == 0); 25945 ZigValue *name_arr = name_ptr->data.x_ptr.data.base_array.array_val; 25946 assert(name_arr->special == ConstValSpecialStatic); 25947 switch (name_arr->data.x_array.special) { 25948 case ConstArraySpecialUndef: 25949 return ira->codegen->invalid_inst_gen->value->type; 25950 case ConstArraySpecialNone: { 25951 buf_resize(&err_entry->name, 0); 25952 size_t name_count = bigint_as_usize(&name_len->data.x_bigint); 25953 for (size_t j = 0; j < name_count; j++) { 25954 ZigValue *ch_val = &name_arr->data.x_array.data.s_none.elements[j]; 25955 unsigned ch = bigint_as_u32(&ch_val->data.x_bigint); 25956 buf_append_char(&err_entry->name, ch); 25957 } 25958 break; 25959 } 25960 case ConstArraySpecialBuf: 25961 buf_init_from_buf(&err_entry->name, name_arr->data.x_array.data.s_buf); 25962 break; 25963 } 25964 auto existing_entry = ira->codegen->error_table.put_unique(&err_entry->name, err_entry); 25965 if (existing_entry) { 25966 err_entry->value = existing_entry->value->value; 25967 } else { 25968 size_t error_value_count = ira->codegen->errors_by_index.length; 25969 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count)); 25970 err_entry->value = error_value_count; 25971 ira->codegen->errors_by_index.append(err_entry); 25972 } 25973 if (already_set[err_entry->value]) { 25974 ir_add_error(ira, source_instr, buf_sprintf("duplicate error: %s", buf_ptr(&err_entry->name))); 25975 return ira->codegen->invalid_inst_gen->value->type; 25976 } else { 25977 already_set[err_entry->value] = true; 25978 } 25979 err_set_type->data.error_set.errors[i] = err_entry; 25980 } 25981 return err_set_type; 25982 } 25983 case ZigTypeIdEnum: 25984 ir_add_error(ira, source_instr, buf_sprintf( 25985 "TODO implement @Type for 'TypeInfo.%s': see https://github.com/ziglang/zig/issues/2907", type_id_name(tagTypeId))); 25986 return ira->codegen->invalid_inst_gen->value->type; 25987 case ZigTypeIdUnion: 25988 case ZigTypeIdFn: 25989 case ZigTypeIdBoundFn: 25990 case ZigTypeIdStruct: 25991 ir_add_error(ira, source_instr, buf_sprintf( 25992 "@Type not available for 'TypeInfo.%s'", type_id_name(tagTypeId))); 25993 return ira->codegen->invalid_inst_gen->value->type; 25994 } 25995 zig_unreachable(); 25996 } 25997 25998 static IrInstGen *ir_analyze_instruction_type(IrAnalyze *ira, IrInstSrcType *instruction) { 25999 IrInstGen *uncasted_type_info = instruction->type_info->child; 26000 if (type_is_invalid(uncasted_type_info->value->type)) 26001 return ira->codegen->invalid_inst_gen; 26002 26003 IrInstGen *type_info = ir_implicit_cast(ira, uncasted_type_info, ir_type_info_get_type(ira, nullptr, nullptr)); 26004 if (type_is_invalid(type_info->value->type)) 26005 return ira->codegen->invalid_inst_gen; 26006 26007 ZigValue *type_info_val = ir_resolve_const(ira, type_info, UndefBad); 26008 if (type_info_val == nullptr) 26009 return ira->codegen->invalid_inst_gen; 26010 ZigTypeId type_id_tag = type_id_at_index(bigint_as_usize(&type_info_val->data.x_union.tag)); 26011 ZigType *type = type_info_to_type(ira, &uncasted_type_info->base, type_id_tag, 26012 type_info_val->data.x_union.payload); 26013 if (type_is_invalid(type)) 26014 return ira->codegen->invalid_inst_gen; 26015 return ir_const_type(ira, &instruction->base.base, type); 26016 } 26017 26018 static IrInstGen *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira, 26019 IrInstSrcSetEvalBranchQuota *instruction) 26020 { 26021 uint64_t new_quota; 26022 if (!ir_resolve_usize(ira, instruction->new_quota->child, &new_quota)) 26023 return ira->codegen->invalid_inst_gen; 26024 26025 if (new_quota > *ira->new_irb.exec->backward_branch_quota) { 26026 *ira->new_irb.exec->backward_branch_quota = new_quota; 26027 } 26028 26029 return ir_const_void(ira, &instruction->base.base); 26030 } 26031 26032 static IrInstGen *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstSrcTypeName *instruction) { 26033 IrInstGen *type_value = instruction->type_value->child; 26034 ZigType *type_entry = ir_resolve_type(ira, type_value); 26035 if (type_is_invalid(type_entry)) 26036 return ira->codegen->invalid_inst_gen; 26037 26038 if (!type_entry->cached_const_name_val) { 26039 type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, type_bare_name(type_entry)); 26040 } 26041 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 26042 copy_const_val(ira->codegen, result->value, type_entry->cached_const_name_val); 26043 return result; 26044 } 26045 26046 static void ir_cimport_cache_paths(Buf *cache_dir, Buf *tmp_c_file_digest, Buf *out_zig_dir, Buf *out_zig_path) { 26047 buf_resize(out_zig_dir, 0); 26048 buf_resize(out_zig_path, 0); 26049 buf_appendf(out_zig_dir, "%s" OS_SEP "o" OS_SEP "%s", 26050 buf_ptr(cache_dir), buf_ptr(tmp_c_file_digest)); 26051 buf_appendf(out_zig_path, "%s" OS_SEP "cimport.zig", buf_ptr(out_zig_dir)); 26052 } 26053 static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImport *instruction) { 26054 Error err; 26055 AstNode *node = instruction->base.base.source_node; 26056 assert(node->type == NodeTypeFnCallExpr); 26057 AstNode *block_node = node->data.fn_call_expr.params.at(0); 26058 26059 ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.base.scope); 26060 26061 // Execute the C import block like an inline function 26062 ZigType *void_type = ira->codegen->builtin_types.entry_void; 26063 ZigValue *cimport_result; 26064 ZigValue *result_ptr; 26065 create_result_ptr(ira->codegen, void_type, &cimport_result, &result_ptr); 26066 if ((err = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, result_ptr, 26067 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, 26068 &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, UndefBad))) 26069 { 26070 return ira->codegen->invalid_inst_gen; 26071 } 26072 if (type_is_invalid(cimport_result->type)) 26073 return ira->codegen->invalid_inst_gen; 26074 26075 ZigPackage *cur_scope_pkg = scope_package(instruction->base.base.scope); 26076 Buf *namespace_name = buf_sprintf("%s.cimport:%" ZIG_PRI_usize ":%" ZIG_PRI_usize, 26077 buf_ptr(&cur_scope_pkg->pkg_path), node->line + 1, node->column + 1); 26078 26079 ZigPackage *cimport_pkg = new_anonymous_package(); 26080 cimport_pkg->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package); 26081 cimport_pkg->package_table.put(buf_create_from_str("std"), ira->codegen->std_package); 26082 buf_init_from_buf(&cimport_pkg->pkg_path, namespace_name); 26083 26084 CacheHash *cache_hash; 26085 if ((err = create_c_object_cache(ira->codegen, &cache_hash, false))) { 26086 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to create cache: %s", err_str(err))); 26087 return ira->codegen->invalid_inst_gen; 26088 } 26089 cache_buf(cache_hash, &cimport_scope->buf); 26090 26091 // Set this because we're not adding any files before checking for a hit. 26092 cache_hash->force_check_manifest = true; 26093 26094 Buf tmp_c_file_digest = BUF_INIT; 26095 buf_resize(&tmp_c_file_digest, 0); 26096 if ((err = cache_hit(cache_hash, &tmp_c_file_digest))) { 26097 if (err != ErrorInvalidFormat) { 26098 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to check cache: %s", err_str(err))); 26099 return ira->codegen->invalid_inst_gen; 26100 } 26101 } 26102 ira->codegen->caches_to_release.append(cache_hash); 26103 26104 Buf *out_zig_dir = buf_alloc(); 26105 Buf *out_zig_path = buf_alloc(); 26106 if (buf_len(&tmp_c_file_digest) == 0 || cache_hash->files.length == 0) { 26107 // Cache Miss 26108 Buf *tmp_c_file_dir = buf_sprintf("%s" OS_SEP "o" OS_SEP "%s", 26109 buf_ptr(ira->codegen->cache_dir), buf_ptr(&cache_hash->b64_digest)); 26110 Buf *resolve_paths[] = { 26111 tmp_c_file_dir, 26112 buf_create_from_str("cimport.h"), 26113 }; 26114 Buf tmp_c_file_path = os_path_resolve(resolve_paths, 2); 26115 26116 if ((err = os_make_path(tmp_c_file_dir))) { 26117 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); 26118 return ira->codegen->invalid_inst_gen; 26119 } 26120 26121 if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { 26122 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); 26123 return ira->codegen->invalid_inst_gen; 26124 } 26125 if (ira->codegen->verbose_cimport) { 26126 fprintf(stderr, "@cImport source: %s\n", buf_ptr(&tmp_c_file_path)); 26127 } 26128 26129 Buf *tmp_dep_file = buf_sprintf("%s.d", buf_ptr(&tmp_c_file_path)); 26130 26131 ZigList<const char *> clang_argv = {0}; 26132 26133 add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true, FileExtC); 26134 26135 clang_argv.append(buf_ptr(&tmp_c_file_path)); 26136 26137 if (ira->codegen->verbose_cc) { 26138 fprintf(stderr, "clang"); 26139 for (size_t i = 0; i < clang_argv.length; i += 1) { 26140 fprintf(stderr, " %s", clang_argv.at(i)); 26141 } 26142 fprintf(stderr, "\n"); 26143 } 26144 26145 clang_argv.append(nullptr); // to make the [start...end] argument work 26146 26147 Stage2ErrorMsg *errors_ptr; 26148 size_t errors_len; 26149 Stage2Ast *ast; 26150 26151 const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir); 26152 26153 if ((err = stage2_translate_c(&ast, &errors_ptr, &errors_len, 26154 &clang_argv.at(0), &clang_argv.last(), resources_path))) 26155 { 26156 if (err != ErrorCCompileErrors) { 26157 ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err))); 26158 return ira->codegen->invalid_inst_gen; 26159 } 26160 26161 ErrorMsg *parent_err_msg = ir_add_error_node(ira, node, buf_sprintf("C import failed")); 26162 if (ira->codegen->libc_link_lib == nullptr) { 26163 add_error_note(ira->codegen, parent_err_msg, node, 26164 buf_sprintf("libc headers not available; compilation does not link against libc")); 26165 } 26166 for (size_t i = 0; i < errors_len; i += 1) { 26167 Stage2ErrorMsg *clang_err = &errors_ptr[i]; 26168 // Clang can emit "too many errors, stopping now", in which case `source` and `filename_ptr` are null 26169 if (clang_err->source && clang_err->filename_ptr) { 26170 ErrorMsg *err_msg = err_msg_create_with_offset( 26171 clang_err->filename_ptr ? 26172 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(), 26173 clang_err->line, clang_err->column, clang_err->offset, clang_err->source, 26174 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); 26175 err_msg_add_note(parent_err_msg, err_msg); 26176 } 26177 } 26178 26179 return ira->codegen->invalid_inst_gen; 26180 } 26181 if (ira->codegen->verbose_cimport) { 26182 fprintf(stderr, "@cImport .d file: %s\n", buf_ptr(tmp_dep_file)); 26183 } 26184 26185 if ((err = cache_add_dep_file(cache_hash, tmp_dep_file, false))) { 26186 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to parse .d file: %s", err_str(err))); 26187 return ira->codegen->invalid_inst_gen; 26188 } 26189 if ((err = cache_final(cache_hash, &tmp_c_file_digest))) { 26190 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to finalize cache: %s", err_str(err))); 26191 return ira->codegen->invalid_inst_gen; 26192 } 26193 26194 ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); 26195 if ((err = os_make_path(out_zig_dir))) { 26196 ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make output dir: %s", err_str(err))); 26197 return ira->codegen->invalid_inst_gen; 26198 } 26199 FILE *out_file = fopen(buf_ptr(out_zig_path), "wb"); 26200 if (out_file == nullptr) { 26201 ir_add_error_node(ira, node, 26202 buf_sprintf("C import failed: unable to open output file: %s", strerror(errno))); 26203 return ira->codegen->invalid_inst_gen; 26204 } 26205 stage2_render_ast(ast, out_file); 26206 if (fclose(out_file) != 0) { 26207 ir_add_error_node(ira, node, 26208 buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno))); 26209 return ira->codegen->invalid_inst_gen; 26210 } 26211 26212 if (ira->codegen->verbose_cimport) { 26213 fprintf(stderr, "@cImport output: %s\n", buf_ptr(out_zig_path)); 26214 } 26215 26216 } else { 26217 // Cache Hit 26218 ir_cimport_cache_paths(ira->codegen->cache_dir, &tmp_c_file_digest, out_zig_dir, out_zig_path); 26219 if (ira->codegen->verbose_cimport) { 26220 fprintf(stderr, "@cImport cache hit: %s\n", buf_ptr(out_zig_path)); 26221 } 26222 } 26223 26224 Buf *import_code = buf_alloc(); 26225 if ((err = file_fetch(ira->codegen, out_zig_path, import_code))) { 26226 ir_add_error_node(ira, node, 26227 buf_sprintf("unable to open '%s': %s", buf_ptr(out_zig_path), err_str(err))); 26228 return ira->codegen->invalid_inst_gen; 26229 } 26230 ZigType *child_import = add_source_file(ira->codegen, cimport_pkg, out_zig_path, 26231 import_code, SourceKindCImport); 26232 return ir_const_type(ira, &instruction->base.base, child_import); 26233 } 26234 26235 static IrInstGen *ir_analyze_instruction_c_include(IrAnalyze *ira, IrInstSrcCInclude *instruction) { 26236 IrInstGen *name_value = instruction->name->child; 26237 if (type_is_invalid(name_value->value->type)) 26238 return ira->codegen->invalid_inst_gen; 26239 26240 Buf *include_name = ir_resolve_str(ira, name_value); 26241 if (!include_name) 26242 return ira->codegen->invalid_inst_gen; 26243 26244 Buf *c_import_buf = ira->new_irb.exec->c_import_buf; 26245 // We check for this error in pass1 26246 assert(c_import_buf); 26247 26248 buf_appendf(c_import_buf, "#include <%s>\n", buf_ptr(include_name)); 26249 26250 return ir_const_void(ira, &instruction->base.base); 26251 } 26252 26253 static IrInstGen *ir_analyze_instruction_c_define(IrAnalyze *ira, IrInstSrcCDefine *instruction) { 26254 IrInstGen *name = instruction->name->child; 26255 if (type_is_invalid(name->value->type)) 26256 return ira->codegen->invalid_inst_gen; 26257 26258 Buf *define_name = ir_resolve_str(ira, name); 26259 if (!define_name) 26260 return ira->codegen->invalid_inst_gen; 26261 26262 IrInstGen *value = instruction->value->child; 26263 if (type_is_invalid(value->value->type)) 26264 return ira->codegen->invalid_inst_gen; 26265 26266 Buf *define_value = nullptr; 26267 // The second parameter is either a string or void (equivalent to "") 26268 if (value->value->type->id != ZigTypeIdVoid) { 26269 define_value = ir_resolve_str(ira, value); 26270 if (!define_value) 26271 return ira->codegen->invalid_inst_gen; 26272 } 26273 26274 Buf *c_import_buf = ira->new_irb.exec->c_import_buf; 26275 // We check for this error in pass1 26276 assert(c_import_buf); 26277 26278 buf_appendf(c_import_buf, "#define %s %s\n", buf_ptr(define_name), 26279 define_value ? buf_ptr(define_value) : ""); 26280 26281 return ir_const_void(ira, &instruction->base.base); 26282 } 26283 26284 static IrInstGen *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstSrcCUndef *instruction) { 26285 IrInstGen *name = instruction->name->child; 26286 if (type_is_invalid(name->value->type)) 26287 return ira->codegen->invalid_inst_gen; 26288 26289 Buf *undef_name = ir_resolve_str(ira, name); 26290 if (!undef_name) 26291 return ira->codegen->invalid_inst_gen; 26292 26293 Buf *c_import_buf = ira->new_irb.exec->c_import_buf; 26294 // We check for this error in pass1 26295 assert(c_import_buf); 26296 26297 buf_appendf(c_import_buf, "#undef %s\n", buf_ptr(undef_name)); 26298 26299 return ir_const_void(ira, &instruction->base.base); 26300 } 26301 26302 static IrInstGen *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstSrcEmbedFile *instruction) { 26303 IrInstGen *name = instruction->name->child; 26304 if (type_is_invalid(name->value->type)) 26305 return ira->codegen->invalid_inst_gen; 26306 26307 Buf *rel_file_path = ir_resolve_str(ira, name); 26308 if (!rel_file_path) 26309 return ira->codegen->invalid_inst_gen; 26310 26311 ZigType *import = get_scope_import(instruction->base.base.scope); 26312 // figure out absolute path to resource 26313 Buf source_dir_path = BUF_INIT; 26314 os_path_dirname(import->data.structure.root_struct->path, &source_dir_path); 26315 26316 Buf *resolve_paths[] = { 26317 &source_dir_path, 26318 rel_file_path, 26319 }; 26320 Buf *file_path = buf_alloc(); 26321 *file_path = os_path_resolve(resolve_paths, 2); 26322 26323 // load from file system into const expr 26324 Buf *file_contents = buf_alloc(); 26325 Error err; 26326 if ((err = file_fetch(ira->codegen, file_path, file_contents))) { 26327 if (err == ErrorFileNotFound) { 26328 ir_add_error(ira, &instruction->name->base, 26329 buf_sprintf("unable to find '%s'", buf_ptr(file_path))); 26330 return ira->codegen->invalid_inst_gen; 26331 } else { 26332 ir_add_error(ira, &instruction->name->base, 26333 buf_sprintf("unable to open '%s': %s", buf_ptr(file_path), err_str(err))); 26334 return ira->codegen->invalid_inst_gen; 26335 } 26336 } 26337 26338 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr); 26339 init_const_str_lit(ira->codegen, result->value, file_contents); 26340 return result; 26341 } 26342 26343 static IrInstGen *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstSrcCmpxchg *instruction) { 26344 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->type_value->child); 26345 if (type_is_invalid(operand_type)) 26346 return ira->codegen->invalid_inst_gen; 26347 26348 if (operand_type->id == ZigTypeIdFloat) { 26349 ir_add_error(ira, &instruction->type_value->child->base, 26350 buf_sprintf("expected integer, enum or pointer type, found '%s'", buf_ptr(&operand_type->name))); 26351 return ira->codegen->invalid_inst_gen; 26352 } 26353 26354 IrInstGen *ptr = instruction->ptr->child; 26355 if (type_is_invalid(ptr->value->type)) 26356 return ira->codegen->invalid_inst_gen; 26357 26358 // TODO let this be volatile 26359 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 26360 IrInstGen *casted_ptr = ir_implicit_cast2(ira, &instruction->ptr->base, ptr, ptr_type); 26361 if (type_is_invalid(casted_ptr->value->type)) 26362 return ira->codegen->invalid_inst_gen; 26363 26364 IrInstGen *cmp_value = instruction->cmp_value->child; 26365 if (type_is_invalid(cmp_value->value->type)) 26366 return ira->codegen->invalid_inst_gen; 26367 26368 IrInstGen *new_value = instruction->new_value->child; 26369 if (type_is_invalid(new_value->value->type)) 26370 return ira->codegen->invalid_inst_gen; 26371 26372 IrInstGen *success_order_value = instruction->success_order_value->child; 26373 if (type_is_invalid(success_order_value->value->type)) 26374 return ira->codegen->invalid_inst_gen; 26375 26376 AtomicOrder success_order; 26377 if (!ir_resolve_atomic_order(ira, success_order_value, &success_order)) 26378 return ira->codegen->invalid_inst_gen; 26379 26380 IrInstGen *failure_order_value = instruction->failure_order_value->child; 26381 if (type_is_invalid(failure_order_value->value->type)) 26382 return ira->codegen->invalid_inst_gen; 26383 26384 AtomicOrder failure_order; 26385 if (!ir_resolve_atomic_order(ira, failure_order_value, &failure_order)) 26386 return ira->codegen->invalid_inst_gen; 26387 26388 IrInstGen *casted_cmp_value = ir_implicit_cast2(ira, &instruction->cmp_value->base, cmp_value, operand_type); 26389 if (type_is_invalid(casted_cmp_value->value->type)) 26390 return ira->codegen->invalid_inst_gen; 26391 26392 IrInstGen *casted_new_value = ir_implicit_cast2(ira, &instruction->new_value->base, new_value, operand_type); 26393 if (type_is_invalid(casted_new_value->value->type)) 26394 return ira->codegen->invalid_inst_gen; 26395 26396 if (success_order < AtomicOrderMonotonic) { 26397 ir_add_error(ira, &success_order_value->base, 26398 buf_sprintf("success atomic ordering must be Monotonic or stricter")); 26399 return ira->codegen->invalid_inst_gen; 26400 } 26401 if (failure_order < AtomicOrderMonotonic) { 26402 ir_add_error(ira, &failure_order_value->base, 26403 buf_sprintf("failure atomic ordering must be Monotonic or stricter")); 26404 return ira->codegen->invalid_inst_gen; 26405 } 26406 if (failure_order > success_order) { 26407 ir_add_error(ira, &failure_order_value->base, 26408 buf_sprintf("failure atomic ordering must be no stricter than success")); 26409 return ira->codegen->invalid_inst_gen; 26410 } 26411 if (failure_order == AtomicOrderRelease || failure_order == AtomicOrderAcqRel) { 26412 ir_add_error(ira, &failure_order_value->base, 26413 buf_sprintf("failure atomic ordering must not be Release or AcqRel")); 26414 return ira->codegen->invalid_inst_gen; 26415 } 26416 26417 ZigType *result_type = get_optional_type(ira->codegen, operand_type); 26418 26419 // special case zero bit types 26420 switch (type_has_one_possible_value(ira->codegen, operand_type)) { 26421 case OnePossibleValueInvalid: 26422 return ira->codegen->invalid_inst_gen; 26423 case OnePossibleValueYes: { 26424 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 26425 set_optional_value_to_null(result->value); 26426 return result; 26427 } 26428 case OnePossibleValueNo: 26429 break; 26430 } 26431 26432 if (instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar && 26433 instr_is_comptime(casted_cmp_value) && instr_is_comptime(casted_new_value)) { 26434 ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad); 26435 if (ptr_val == nullptr) 26436 return ira->codegen->invalid_inst_gen; 26437 26438 ZigValue *stored_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.base.source_node); 26439 if (stored_val == nullptr) 26440 return ira->codegen->invalid_inst_gen; 26441 26442 ZigValue *expected_val = ir_resolve_const(ira, casted_cmp_value, UndefBad); 26443 if (expected_val == nullptr) 26444 return ira->codegen->invalid_inst_gen; 26445 26446 ZigValue *new_val = ir_resolve_const(ira, casted_new_value, UndefBad); 26447 if (new_val == nullptr) 26448 return ira->codegen->invalid_inst_gen; 26449 26450 bool eql = const_values_equal(ira->codegen, stored_val, expected_val); 26451 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type); 26452 if (eql) { 26453 copy_const_val(ira->codegen, stored_val, new_val); 26454 set_optional_value_to_null(result->value); 26455 } else { 26456 set_optional_payload(result->value, stored_val); 26457 } 26458 return result; 26459 } 26460 26461 IrInstGen *result_loc; 26462 if (handle_is_ptr(ira->codegen, result_type)) { 26463 result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 26464 result_type, nullptr, true, true); 26465 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 26466 return result_loc; 26467 } 26468 } else { 26469 result_loc = nullptr; 26470 } 26471 26472 return ir_build_cmpxchg_gen(ira, &instruction->base.base, result_type, 26473 casted_ptr, casted_cmp_value, casted_new_value, 26474 success_order, failure_order, instruction->is_weak, result_loc); 26475 } 26476 26477 static IrInstGen *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstSrcFence *instruction) { 26478 IrInstGen *order_inst = instruction->order->child; 26479 if (type_is_invalid(order_inst->value->type)) 26480 return ira->codegen->invalid_inst_gen; 26481 26482 AtomicOrder order; 26483 if (!ir_resolve_atomic_order(ira, order_inst, &order)) 26484 return ira->codegen->invalid_inst_gen; 26485 26486 if (order < AtomicOrderAcquire) { 26487 ir_add_error(ira, &order_inst->base, 26488 buf_sprintf("atomic ordering must be Acquire or stricter")); 26489 return ira->codegen->invalid_inst_gen; 26490 } 26491 26492 return ir_build_fence_gen(ira, &instruction->base.base, order); 26493 } 26494 26495 static IrInstGen *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstSrcTruncate *instruction) { 26496 IrInstGen *dest_type_value = instruction->dest_type->child; 26497 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 26498 if (type_is_invalid(dest_type)) 26499 return ira->codegen->invalid_inst_gen; 26500 26501 if (dest_type->id != ZigTypeIdInt && 26502 dest_type->id != ZigTypeIdComptimeInt) 26503 { 26504 ir_add_error(ira, &dest_type_value->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 26505 return ira->codegen->invalid_inst_gen; 26506 } 26507 26508 IrInstGen *target = instruction->target->child; 26509 ZigType *src_type = target->value->type; 26510 if (type_is_invalid(src_type)) 26511 return ira->codegen->invalid_inst_gen; 26512 26513 if (src_type->id != ZigTypeIdInt && 26514 src_type->id != ZigTypeIdComptimeInt) 26515 { 26516 ir_add_error(ira, &target->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&src_type->name))); 26517 return ira->codegen->invalid_inst_gen; 26518 } 26519 26520 if (dest_type->id == ZigTypeIdComptimeInt) { 26521 return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); 26522 } 26523 26524 if (instr_is_comptime(target)) { 26525 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 26526 if (val == nullptr) 26527 return ira->codegen->invalid_inst_gen; 26528 26529 IrInstGen *result = ir_const(ira, &instruction->base.base, dest_type); 26530 bigint_truncate(&result->value->data.x_bigint, &val->data.x_bigint, 26531 dest_type->data.integral.bit_count, dest_type->data.integral.is_signed); 26532 return result; 26533 } 26534 26535 if (src_type->data.integral.bit_count == 0 || dest_type->data.integral.bit_count == 0) { 26536 IrInstGen *result = ir_const(ira, &instruction->base.base, dest_type); 26537 bigint_init_unsigned(&result->value->data.x_bigint, 0); 26538 return result; 26539 } 26540 26541 if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) { 26542 const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned"; 26543 ir_add_error(ira, &target->base, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name))); 26544 return ira->codegen->invalid_inst_gen; 26545 } else if (src_type->data.integral.bit_count < dest_type->data.integral.bit_count) { 26546 ir_add_error(ira, &target->base, buf_sprintf("type '%s' has fewer bits than destination type '%s'", 26547 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 26548 return ira->codegen->invalid_inst_gen; 26549 } 26550 26551 return ir_build_truncate_gen(ira, &instruction->base.base, dest_type, target); 26552 } 26553 26554 static IrInstGen *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstSrcIntCast *instruction) { 26555 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 26556 if (type_is_invalid(dest_type)) 26557 return ira->codegen->invalid_inst_gen; 26558 26559 if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { 26560 ir_add_error(ira, &instruction->dest_type->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 26561 return ira->codegen->invalid_inst_gen; 26562 } 26563 26564 IrInstGen *target = instruction->target->child; 26565 if (type_is_invalid(target->value->type)) 26566 return ira->codegen->invalid_inst_gen; 26567 26568 if (target->value->type->id != ZigTypeIdInt && target->value->type->id != ZigTypeIdComptimeInt) { 26569 ir_add_error(ira, &instruction->target->base, buf_sprintf("expected integer type, found '%s'", 26570 buf_ptr(&target->value->type->name))); 26571 return ira->codegen->invalid_inst_gen; 26572 } 26573 26574 if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeInt) { 26575 return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); 26576 } 26577 26578 return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type); 26579 } 26580 26581 static IrInstGen *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstSrcFloatCast *instruction) { 26582 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 26583 if (type_is_invalid(dest_type)) 26584 return ira->codegen->invalid_inst_gen; 26585 26586 if (dest_type->id != ZigTypeIdFloat && dest_type->id != ZigTypeIdComptimeFloat) { 26587 ir_add_error(ira, &instruction->dest_type->base, 26588 buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); 26589 return ira->codegen->invalid_inst_gen; 26590 } 26591 26592 IrInstGen *target = instruction->target->child; 26593 if (type_is_invalid(target->value->type)) 26594 return ira->codegen->invalid_inst_gen; 26595 26596 if (target->value->type->id == ZigTypeIdComptimeInt || 26597 target->value->type->id == ZigTypeIdComptimeFloat) 26598 { 26599 if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { 26600 CastOp op; 26601 if (target->value->type->id == ZigTypeIdComptimeInt) { 26602 op = CastOpIntToFloat; 26603 } else { 26604 op = CastOpNumLitToConcrete; 26605 } 26606 return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, op); 26607 } else { 26608 return ira->codegen->invalid_inst_gen; 26609 } 26610 } 26611 26612 if (instr_is_comptime(target) || dest_type->id == ZigTypeIdComptimeFloat) { 26613 return ir_implicit_cast2(ira, &instruction->target->base, target, dest_type); 26614 } 26615 26616 if (target->value->type->id != ZigTypeIdFloat) { 26617 ir_add_error(ira, &instruction->target->base, buf_sprintf("expected float type, found '%s'", 26618 buf_ptr(&target->value->type->name))); 26619 return ira->codegen->invalid_inst_gen; 26620 } 26621 26622 return ir_analyze_widen_or_shorten(ira, &instruction->base.base, target, dest_type); 26623 } 26624 26625 static IrInstGen *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstSrcErrSetCast *instruction) { 26626 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 26627 if (type_is_invalid(dest_type)) 26628 return ira->codegen->invalid_inst_gen; 26629 26630 if (dest_type->id != ZigTypeIdErrorSet) { 26631 ir_add_error(ira, &instruction->dest_type->base, 26632 buf_sprintf("expected error set type, found '%s'", buf_ptr(&dest_type->name))); 26633 return ira->codegen->invalid_inst_gen; 26634 } 26635 26636 IrInstGen *target = instruction->target->child; 26637 if (type_is_invalid(target->value->type)) 26638 return ira->codegen->invalid_inst_gen; 26639 26640 if (target->value->type->id != ZigTypeIdErrorSet) { 26641 ir_add_error(ira, &instruction->target->base, 26642 buf_sprintf("expected error set type, found '%s'", buf_ptr(&target->value->type->name))); 26643 return ira->codegen->invalid_inst_gen; 26644 } 26645 26646 return ir_analyze_err_set_cast(ira, &instruction->base.base, target, dest_type); 26647 } 26648 26649 static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { 26650 Error err; 26651 26652 ZigType *ptr_type; 26653 if (is_slice(ty)) { 26654 TypeStructField *ptr_field = ty->data.structure.fields[slice_ptr_index]; 26655 ptr_type = resolve_struct_field_type(ira->codegen, ptr_field); 26656 } else { 26657 ptr_type = get_src_ptr_type(ty); 26658 } 26659 assert(ptr_type != nullptr); 26660 if (ptr_type->id == ZigTypeIdPointer) { 26661 if ((err = type_resolve(ira->codegen, ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 26662 return err; 26663 } else if (is_slice(ptr_type)) { 26664 TypeStructField *ptr_field = ptr_type->data.structure.fields[slice_ptr_index]; 26665 ZigType *slice_ptr_type = resolve_struct_field_type(ira->codegen, ptr_field); 26666 if ((err = type_resolve(ira->codegen, slice_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 26667 return err; 26668 } 26669 26670 *result_align = get_ptr_align(ira->codegen, ty); 26671 return ErrorNone; 26672 } 26673 26674 static IrInstGen *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstSrcIntToFloat *instruction) { 26675 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 26676 if (type_is_invalid(dest_type)) 26677 return ira->codegen->invalid_inst_gen; 26678 26679 if (dest_type->id != ZigTypeIdFloat && dest_type->id != ZigTypeIdComptimeFloat) { 26680 ir_add_error(ira, &instruction->dest_type->base, 26681 buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); 26682 return ira->codegen->invalid_inst_gen; 26683 } 26684 26685 IrInstGen *target = instruction->target->child; 26686 if (type_is_invalid(target->value->type)) 26687 return ira->codegen->invalid_inst_gen; 26688 26689 if (target->value->type->id != ZigTypeIdInt && target->value->type->id != ZigTypeIdComptimeInt) { 26690 ir_add_error(ira, &instruction->target->base, buf_sprintf("expected int type, found '%s'", 26691 buf_ptr(&target->value->type->name))); 26692 return ira->codegen->invalid_inst_gen; 26693 } 26694 26695 return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, CastOpIntToFloat); 26696 } 26697 26698 static IrInstGen *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstSrcFloatToInt *instruction) { 26699 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 26700 if (type_is_invalid(dest_type)) 26701 return ira->codegen->invalid_inst_gen; 26702 26703 if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { 26704 ir_add_error(ira, &instruction->dest_type->base, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 26705 return ira->codegen->invalid_inst_gen; 26706 } 26707 26708 IrInstGen *target = instruction->target->child; 26709 if (type_is_invalid(target->value->type)) 26710 return ira->codegen->invalid_inst_gen; 26711 26712 if (target->value->type->id == ZigTypeIdComptimeInt) { 26713 return ir_implicit_cast(ira, target, dest_type); 26714 } 26715 26716 if (target->value->type->id != ZigTypeIdFloat && target->value->type->id != ZigTypeIdComptimeFloat) { 26717 ir_add_error_node(ira, target->base.source_node, buf_sprintf("expected float type, found '%s'", 26718 buf_ptr(&target->value->type->name))); 26719 return ira->codegen->invalid_inst_gen; 26720 } 26721 26722 return ir_resolve_cast(ira, &instruction->base.base, target, dest_type, CastOpFloatToInt); 26723 } 26724 26725 static IrInstGen *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstSrcErrToInt *instruction) { 26726 IrInstGen *target = instruction->target->child; 26727 if (type_is_invalid(target->value->type)) 26728 return ira->codegen->invalid_inst_gen; 26729 26730 IrInstGen *casted_target; 26731 if (target->value->type->id == ZigTypeIdErrorSet) { 26732 casted_target = target; 26733 } else { 26734 casted_target = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_global_error_set); 26735 if (type_is_invalid(casted_target->value->type)) 26736 return ira->codegen->invalid_inst_gen; 26737 } 26738 26739 return ir_analyze_err_to_int(ira, &instruction->base.base, casted_target, ira->codegen->err_tag_type); 26740 } 26741 26742 static IrInstGen *ir_analyze_instruction_int_to_err(IrAnalyze *ira, IrInstSrcIntToErr *instruction) { 26743 IrInstGen *target = instruction->target->child; 26744 if (type_is_invalid(target->value->type)) 26745 return ira->codegen->invalid_inst_gen; 26746 26747 IrInstGen *casted_target = ir_implicit_cast(ira, target, ira->codegen->err_tag_type); 26748 if (type_is_invalid(casted_target->value->type)) 26749 return ira->codegen->invalid_inst_gen; 26750 26751 return ir_analyze_int_to_err(ira, &instruction->base.base, casted_target, ira->codegen->builtin_types.entry_global_error_set); 26752 } 26753 26754 static IrInstGen *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstSrcBoolToInt *instruction) { 26755 IrInstGen *target = instruction->target->child; 26756 if (type_is_invalid(target->value->type)) 26757 return ira->codegen->invalid_inst_gen; 26758 26759 if (target->value->type->id != ZigTypeIdBool) { 26760 ir_add_error(ira, &instruction->target->base, buf_sprintf("expected bool, found '%s'", 26761 buf_ptr(&target->value->type->name))); 26762 return ira->codegen->invalid_inst_gen; 26763 } 26764 26765 if (instr_is_comptime(target)) { 26766 bool is_true; 26767 if (!ir_resolve_bool(ira, target, &is_true)) 26768 return ira->codegen->invalid_inst_gen; 26769 26770 return ir_const_unsigned(ira, &instruction->base.base, is_true ? 1 : 0); 26771 } 26772 26773 ZigType *u1_type = get_int_type(ira->codegen, false, 1); 26774 return ir_resolve_cast(ira, &instruction->base.base, target, u1_type, CastOpBoolToInt); 26775 } 26776 26777 static IrInstGen *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstSrcVectorType *instruction) { 26778 uint64_t len; 26779 if (!ir_resolve_unsigned(ira, instruction->len->child, ira->codegen->builtin_types.entry_u32, &len)) 26780 return ira->codegen->invalid_inst_gen; 26781 26782 ZigType *elem_type = ir_resolve_vector_elem_type(ira, instruction->elem_type->child); 26783 if (type_is_invalid(elem_type)) 26784 return ira->codegen->invalid_inst_gen; 26785 26786 ZigType *vector_type = get_vector_type(ira->codegen, len, elem_type); 26787 26788 return ir_const_type(ira, &instruction->base.base, vector_type); 26789 } 26790 26791 static IrInstGen *ir_analyze_shuffle_vector(IrAnalyze *ira, IrInst* source_instr, 26792 ZigType *scalar_type, IrInstGen *a, IrInstGen *b, IrInstGen *mask) 26793 { 26794 Error err; 26795 ir_assert(source_instr && scalar_type && a && b && mask, source_instr); 26796 26797 if ((err = ir_validate_vector_elem_type(ira, source_instr->source_node, scalar_type))) 26798 return ira->codegen->invalid_inst_gen; 26799 26800 uint32_t len_mask; 26801 if (mask->value->type->id == ZigTypeIdVector) { 26802 len_mask = mask->value->type->data.vector.len; 26803 } else if (mask->value->type->id == ZigTypeIdArray) { 26804 len_mask = mask->value->type->data.array.len; 26805 } else { 26806 ir_add_error(ira, &mask->base, 26807 buf_sprintf("expected vector or array, found '%s'", 26808 buf_ptr(&mask->value->type->name))); 26809 return ira->codegen->invalid_inst_gen; 26810 } 26811 mask = ir_implicit_cast(ira, mask, get_vector_type(ira->codegen, len_mask, 26812 ira->codegen->builtin_types.entry_i32)); 26813 if (type_is_invalid(mask->value->type)) 26814 return ira->codegen->invalid_inst_gen; 26815 26816 uint32_t len_a; 26817 if (a->value->type->id == ZigTypeIdVector) { 26818 len_a = a->value->type->data.vector.len; 26819 } else if (a->value->type->id == ZigTypeIdArray) { 26820 len_a = a->value->type->data.array.len; 26821 } else if (a->value->type->id == ZigTypeIdUndefined) { 26822 len_a = UINT32_MAX; 26823 } else { 26824 ir_add_error(ira, &a->base, 26825 buf_sprintf("expected vector or array with element type '%s', found '%s'", 26826 buf_ptr(&scalar_type->name), 26827 buf_ptr(&a->value->type->name))); 26828 return ira->codegen->invalid_inst_gen; 26829 } 26830 26831 uint32_t len_b; 26832 if (b->value->type->id == ZigTypeIdVector) { 26833 len_b = b->value->type->data.vector.len; 26834 } else if (b->value->type->id == ZigTypeIdArray) { 26835 len_b = b->value->type->data.array.len; 26836 } else if (b->value->type->id == ZigTypeIdUndefined) { 26837 len_b = UINT32_MAX; 26838 } else { 26839 ir_add_error(ira, &b->base, 26840 buf_sprintf("expected vector or array with element type '%s', found '%s'", 26841 buf_ptr(&scalar_type->name), 26842 buf_ptr(&b->value->type->name))); 26843 return ira->codegen->invalid_inst_gen; 26844 } 26845 26846 if (len_a == UINT32_MAX && len_b == UINT32_MAX) { 26847 return ir_const_undef(ira, &a->base, get_vector_type(ira->codegen, len_mask, scalar_type)); 26848 } 26849 26850 if (len_a == UINT32_MAX) { 26851 len_a = len_b; 26852 a = ir_const_undef(ira, &a->base, get_vector_type(ira->codegen, len_a, scalar_type)); 26853 } else { 26854 a = ir_implicit_cast(ira, a, get_vector_type(ira->codegen, len_a, scalar_type)); 26855 if (type_is_invalid(a->value->type)) 26856 return ira->codegen->invalid_inst_gen; 26857 } 26858 26859 if (len_b == UINT32_MAX) { 26860 len_b = len_a; 26861 b = ir_const_undef(ira, &b->base, get_vector_type(ira->codegen, len_b, scalar_type)); 26862 } else { 26863 b = ir_implicit_cast(ira, b, get_vector_type(ira->codegen, len_b, scalar_type)); 26864 if (type_is_invalid(b->value->type)) 26865 return ira->codegen->invalid_inst_gen; 26866 } 26867 26868 ZigValue *mask_val = ir_resolve_const(ira, mask, UndefOk); 26869 if (mask_val == nullptr) 26870 return ira->codegen->invalid_inst_gen; 26871 26872 expand_undef_array(ira->codegen, mask_val); 26873 26874 for (uint32_t i = 0; i < len_mask; i += 1) { 26875 ZigValue *mask_elem_val = &mask_val->data.x_array.data.s_none.elements[i]; 26876 if (mask_elem_val->special == ConstValSpecialUndef) 26877 continue; 26878 int32_t v_i32 = bigint_as_signed(&mask_elem_val->data.x_bigint); 26879 uint32_t v; 26880 IrInstGen *chosen_operand; 26881 if (v_i32 >= 0) { 26882 v = (uint32_t)v_i32; 26883 chosen_operand = a; 26884 } else { 26885 v = (uint32_t)~v_i32; 26886 chosen_operand = b; 26887 } 26888 if (v >= chosen_operand->value->type->data.vector.len) { 26889 ErrorMsg *msg = ir_add_error(ira, &mask->base, 26890 buf_sprintf("mask index '%u' has out-of-bounds selection", i)); 26891 add_error_note(ira->codegen, msg, chosen_operand->base.source_node, 26892 buf_sprintf("selected index '%u' out of bounds of %s", v, 26893 buf_ptr(&chosen_operand->value->type->name))); 26894 if (chosen_operand == a && v < len_a + len_b) { 26895 add_error_note(ira->codegen, msg, b->base.source_node, 26896 buf_create_from_str("selections from the second vector are specified with negative numbers")); 26897 } 26898 return ira->codegen->invalid_inst_gen; 26899 } 26900 } 26901 26902 ZigType *result_type = get_vector_type(ira->codegen, len_mask, scalar_type); 26903 if (instr_is_comptime(a) && instr_is_comptime(b)) { 26904 ZigValue *a_val = ir_resolve_const(ira, a, UndefOk); 26905 if (a_val == nullptr) 26906 return ira->codegen->invalid_inst_gen; 26907 26908 ZigValue *b_val = ir_resolve_const(ira, b, UndefOk); 26909 if (b_val == nullptr) 26910 return ira->codegen->invalid_inst_gen; 26911 26912 expand_undef_array(ira->codegen, a_val); 26913 expand_undef_array(ira->codegen, b_val); 26914 26915 IrInstGen *result = ir_const(ira, source_instr, result_type); 26916 result->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(len_mask); 26917 for (uint32_t i = 0; i < mask_val->type->data.vector.len; i += 1) { 26918 ZigValue *mask_elem_val = &mask_val->data.x_array.data.s_none.elements[i]; 26919 ZigValue *result_elem_val = &result->value->data.x_array.data.s_none.elements[i]; 26920 if (mask_elem_val->special == ConstValSpecialUndef) { 26921 result_elem_val->special = ConstValSpecialUndef; 26922 continue; 26923 } 26924 int32_t v = bigint_as_signed(&mask_elem_val->data.x_bigint); 26925 // We've already checked for and emitted compile errors for index out of bounds here. 26926 ZigValue *src_elem_val = (v >= 0) ? 26927 &a->value->data.x_array.data.s_none.elements[v] : 26928 &b->value->data.x_array.data.s_none.elements[~v]; 26929 copy_const_val(ira->codegen, result_elem_val, src_elem_val); 26930 26931 ir_assert(result_elem_val->special == ConstValSpecialStatic, source_instr); 26932 } 26933 result->value->special = ConstValSpecialStatic; 26934 return result; 26935 } 26936 26937 // All static analysis passed, and not comptime. 26938 // For runtime codegen, vectors a and b must be the same length. Here we 26939 // recursively @shuffle the smaller vector to append undefined elements 26940 // to it up to the length of the longer vector. This recursion terminates 26941 // in 1 call because these calls to ir_analyze_shuffle_vector guarantee 26942 // len_a == len_b. 26943 if (len_a != len_b) { 26944 uint32_t len_min = min(len_a, len_b); 26945 uint32_t len_max = max(len_a, len_b); 26946 26947 IrInstGen *expand_mask = ir_const(ira, &mask->base, 26948 get_vector_type(ira->codegen, len_max, ira->codegen->builtin_types.entry_i32)); 26949 expand_mask->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(len_max); 26950 uint32_t i = 0; 26951 for (; i < len_min; i += 1) 26952 bigint_init_unsigned(&expand_mask->value->data.x_array.data.s_none.elements[i].data.x_bigint, i); 26953 for (; i < len_max; i += 1) 26954 bigint_init_signed(&expand_mask->value->data.x_array.data.s_none.elements[i].data.x_bigint, -1); 26955 26956 IrInstGen *undef = ir_const_undef(ira, source_instr, 26957 get_vector_type(ira->codegen, len_min, scalar_type)); 26958 26959 if (len_b < len_a) { 26960 b = ir_analyze_shuffle_vector(ira, source_instr, scalar_type, b, undef, expand_mask); 26961 } else { 26962 a = ir_analyze_shuffle_vector(ira, source_instr, scalar_type, a, undef, expand_mask); 26963 } 26964 } 26965 26966 return ir_build_shuffle_vector_gen(ira, source_instr->scope, source_instr->source_node, 26967 result_type, a, b, mask); 26968 } 26969 26970 static IrInstGen *ir_analyze_instruction_shuffle_vector(IrAnalyze *ira, IrInstSrcShuffleVector *instruction) { 26971 ZigType *scalar_type = ir_resolve_vector_elem_type(ira, instruction->scalar_type->child); 26972 if (type_is_invalid(scalar_type)) 26973 return ira->codegen->invalid_inst_gen; 26974 26975 IrInstGen *a = instruction->a->child; 26976 if (type_is_invalid(a->value->type)) 26977 return ira->codegen->invalid_inst_gen; 26978 26979 IrInstGen *b = instruction->b->child; 26980 if (type_is_invalid(b->value->type)) 26981 return ira->codegen->invalid_inst_gen; 26982 26983 IrInstGen *mask = instruction->mask->child; 26984 if (type_is_invalid(mask->value->type)) 26985 return ira->codegen->invalid_inst_gen; 26986 26987 return ir_analyze_shuffle_vector(ira, &instruction->base.base, scalar_type, a, b, mask); 26988 } 26989 26990 static IrInstGen *ir_analyze_instruction_splat(IrAnalyze *ira, IrInstSrcSplat *instruction) { 26991 Error err; 26992 26993 IrInstGen *len = instruction->len->child; 26994 if (type_is_invalid(len->value->type)) 26995 return ira->codegen->invalid_inst_gen; 26996 26997 IrInstGen *scalar = instruction->scalar->child; 26998 if (type_is_invalid(scalar->value->type)) 26999 return ira->codegen->invalid_inst_gen; 27000 27001 uint64_t len_u64; 27002 if (!ir_resolve_unsigned(ira, len, ira->codegen->builtin_types.entry_u32, &len_u64)) 27003 return ira->codegen->invalid_inst_gen; 27004 uint32_t len_int = len_u64; 27005 27006 if ((err = ir_validate_vector_elem_type(ira, scalar->base.source_node, scalar->value->type))) 27007 return ira->codegen->invalid_inst_gen; 27008 27009 ZigType *return_type = get_vector_type(ira->codegen, len_int, scalar->value->type); 27010 27011 if (instr_is_comptime(scalar)) { 27012 ZigValue *scalar_val = ir_resolve_const(ira, scalar, UndefOk); 27013 if (scalar_val == nullptr) 27014 return ira->codegen->invalid_inst_gen; 27015 if (scalar_val->special == ConstValSpecialUndef) 27016 return ir_const_undef(ira, &instruction->base.base, return_type); 27017 27018 IrInstGen *result = ir_const(ira, &instruction->base.base, return_type); 27019 result->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(len_int); 27020 for (uint32_t i = 0; i < len_int; i += 1) { 27021 copy_const_val(ira->codegen, &result->value->data.x_array.data.s_none.elements[i], scalar_val); 27022 } 27023 return result; 27024 } 27025 27026 return ir_build_splat_gen(ira, &instruction->base.base, return_type, scalar); 27027 } 27028 27029 static IrInstGen *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstSrcBoolNot *instruction) { 27030 IrInstGen *value = instruction->value->child; 27031 if (type_is_invalid(value->value->type)) 27032 return ira->codegen->invalid_inst_gen; 27033 27034 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 27035 27036 IrInstGen *casted_value = ir_implicit_cast(ira, value, bool_type); 27037 if (type_is_invalid(casted_value->value->type)) 27038 return ira->codegen->invalid_inst_gen; 27039 27040 if (instr_is_comptime(casted_value)) { 27041 ZigValue *value = ir_resolve_const(ira, casted_value, UndefBad); 27042 if (value == nullptr) 27043 return ira->codegen->invalid_inst_gen; 27044 27045 return ir_const_bool(ira, &instruction->base.base, !value->data.x_bool); 27046 } 27047 27048 return ir_build_bool_not_gen(ira, &instruction->base.base, casted_value); 27049 } 27050 27051 static IrInstGen *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstSrcMemset *instruction) { 27052 Error err; 27053 27054 IrInstGen *dest_ptr = instruction->dest_ptr->child; 27055 if (type_is_invalid(dest_ptr->value->type)) 27056 return ira->codegen->invalid_inst_gen; 27057 27058 IrInstGen *byte_value = instruction->byte->child; 27059 if (type_is_invalid(byte_value->value->type)) 27060 return ira->codegen->invalid_inst_gen; 27061 27062 IrInstGen *count_value = instruction->count->child; 27063 if (type_is_invalid(count_value->value->type)) 27064 return ira->codegen->invalid_inst_gen; 27065 27066 ZigType *dest_uncasted_type = dest_ptr->value->type; 27067 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 27068 dest_uncasted_type->data.pointer.is_volatile; 27069 27070 ZigType *usize = ira->codegen->builtin_types.entry_usize; 27071 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 27072 uint32_t dest_align; 27073 if (dest_uncasted_type->id == ZigTypeIdPointer) { 27074 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 27075 return ira->codegen->invalid_inst_gen; 27076 } else { 27077 dest_align = get_abi_alignment(ira->codegen, u8); 27078 } 27079 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 27080 PtrLenUnknown, dest_align, 0, 0, false); 27081 27082 IrInstGen *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr); 27083 if (type_is_invalid(casted_dest_ptr->value->type)) 27084 return ira->codegen->invalid_inst_gen; 27085 27086 IrInstGen *casted_byte = ir_implicit_cast(ira, byte_value, u8); 27087 if (type_is_invalid(casted_byte->value->type)) 27088 return ira->codegen->invalid_inst_gen; 27089 27090 IrInstGen *casted_count = ir_implicit_cast(ira, count_value, usize); 27091 if (type_is_invalid(casted_count->value->type)) 27092 return ira->codegen->invalid_inst_gen; 27093 27094 // TODO test this at comptime with u8 and non-u8 types 27095 if (instr_is_comptime(casted_dest_ptr) && 27096 instr_is_comptime(casted_byte) && 27097 instr_is_comptime(casted_count)) 27098 { 27099 ZigValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); 27100 if (dest_ptr_val == nullptr) 27101 return ira->codegen->invalid_inst_gen; 27102 27103 ZigValue *byte_val = ir_resolve_const(ira, casted_byte, UndefOk); 27104 if (byte_val == nullptr) 27105 return ira->codegen->invalid_inst_gen; 27106 27107 ZigValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); 27108 if (count_val == nullptr) 27109 return ira->codegen->invalid_inst_gen; 27110 27111 if (casted_dest_ptr->value->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && 27112 casted_dest_ptr->value->data.x_ptr.mut != ConstPtrMutRuntimeVar) 27113 { 27114 ZigValue *dest_elements; 27115 size_t start; 27116 size_t bound_end; 27117 switch (dest_ptr_val->data.x_ptr.special) { 27118 case ConstPtrSpecialInvalid: 27119 case ConstPtrSpecialDiscard: 27120 zig_unreachable(); 27121 case ConstPtrSpecialRef: 27122 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 27123 start = 0; 27124 bound_end = 1; 27125 break; 27126 case ConstPtrSpecialSubArray: 27127 case ConstPtrSpecialBaseArray: 27128 { 27129 ZigValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 27130 expand_undef_array(ira->codegen, array_val); 27131 dest_elements = array_val->data.x_array.data.s_none.elements; 27132 start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 27133 bound_end = array_val->type->data.array.len; 27134 break; 27135 } 27136 case ConstPtrSpecialBaseStruct: 27137 zig_panic("TODO memset on const inner struct"); 27138 case ConstPtrSpecialBaseErrorUnionCode: 27139 zig_panic("TODO memset on const inner error union code"); 27140 case ConstPtrSpecialBaseErrorUnionPayload: 27141 zig_panic("TODO memset on const inner error union payload"); 27142 case ConstPtrSpecialBaseOptionalPayload: 27143 zig_panic("TODO memset on const inner optional payload"); 27144 case ConstPtrSpecialHardCodedAddr: 27145 zig_unreachable(); 27146 case ConstPtrSpecialFunction: 27147 zig_panic("TODO memset on ptr cast from function"); 27148 case ConstPtrSpecialNull: 27149 zig_panic("TODO memset on null ptr"); 27150 } 27151 27152 size_t count = bigint_as_usize(&count_val->data.x_bigint); 27153 size_t end = start + count; 27154 if (end > bound_end) { 27155 ir_add_error(ira, &count_value->base, buf_sprintf("out of bounds pointer access")); 27156 return ira->codegen->invalid_inst_gen; 27157 } 27158 27159 for (size_t i = start; i < end; i += 1) { 27160 copy_const_val(ira->codegen, &dest_elements[i], byte_val); 27161 } 27162 27163 return ir_const_void(ira, &instruction->base.base); 27164 } 27165 } 27166 27167 return ir_build_memset_gen(ira, &instruction->base.base, casted_dest_ptr, casted_byte, casted_count); 27168 } 27169 27170 static IrInstGen *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstSrcMemcpy *instruction) { 27171 Error err; 27172 27173 IrInstGen *dest_ptr = instruction->dest_ptr->child; 27174 if (type_is_invalid(dest_ptr->value->type)) 27175 return ira->codegen->invalid_inst_gen; 27176 27177 IrInstGen *src_ptr = instruction->src_ptr->child; 27178 if (type_is_invalid(src_ptr->value->type)) 27179 return ira->codegen->invalid_inst_gen; 27180 27181 IrInstGen *count_value = instruction->count->child; 27182 if (type_is_invalid(count_value->value->type)) 27183 return ira->codegen->invalid_inst_gen; 27184 27185 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 27186 ZigType *dest_uncasted_type = dest_ptr->value->type; 27187 ZigType *src_uncasted_type = src_ptr->value->type; 27188 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 27189 dest_uncasted_type->data.pointer.is_volatile; 27190 bool src_is_volatile = (src_uncasted_type->id == ZigTypeIdPointer) && 27191 src_uncasted_type->data.pointer.is_volatile; 27192 27193 uint32_t dest_align; 27194 if (dest_uncasted_type->id == ZigTypeIdPointer) { 27195 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 27196 return ira->codegen->invalid_inst_gen; 27197 } else { 27198 dest_align = get_abi_alignment(ira->codegen, u8); 27199 } 27200 27201 uint32_t src_align; 27202 if (src_uncasted_type->id == ZigTypeIdPointer) { 27203 if ((err = resolve_ptr_align(ira, src_uncasted_type, &src_align))) 27204 return ira->codegen->invalid_inst_gen; 27205 } else { 27206 src_align = get_abi_alignment(ira->codegen, u8); 27207 } 27208 27209 ZigType *usize = ira->codegen->builtin_types.entry_usize; 27210 ZigType *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 27211 PtrLenUnknown, dest_align, 0, 0, false); 27212 ZigType *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, src_is_volatile, 27213 PtrLenUnknown, src_align, 0, 0, false); 27214 27215 IrInstGen *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut); 27216 if (type_is_invalid(casted_dest_ptr->value->type)) 27217 return ira->codegen->invalid_inst_gen; 27218 27219 IrInstGen *casted_src_ptr = ir_implicit_cast(ira, src_ptr, u8_ptr_const); 27220 if (type_is_invalid(casted_src_ptr->value->type)) 27221 return ira->codegen->invalid_inst_gen; 27222 27223 IrInstGen *casted_count = ir_implicit_cast(ira, count_value, usize); 27224 if (type_is_invalid(casted_count->value->type)) 27225 return ira->codegen->invalid_inst_gen; 27226 27227 // TODO test this at comptime with u8 and non-u8 types 27228 // TODO test with dest ptr being a global runtime variable 27229 if (instr_is_comptime(casted_dest_ptr) && 27230 instr_is_comptime(casted_src_ptr) && 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 *src_ptr_val = ir_resolve_const(ira, casted_src_ptr, UndefBad); 27238 if (src_ptr_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 (dest_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 27246 size_t count = bigint_as_usize(&count_val->data.x_bigint); 27247 27248 ZigValue *dest_elements; 27249 size_t dest_start; 27250 size_t dest_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 dest_start = 0; 27258 dest_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 dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 27267 dest_end = array_val->type->data.array.len; 27268 break; 27269 } 27270 case ConstPtrSpecialBaseStruct: 27271 zig_panic("TODO memcpy on const inner struct"); 27272 case ConstPtrSpecialBaseErrorUnionCode: 27273 zig_panic("TODO memcpy on const inner error union code"); 27274 case ConstPtrSpecialBaseErrorUnionPayload: 27275 zig_panic("TODO memcpy on const inner error union payload"); 27276 case ConstPtrSpecialBaseOptionalPayload: 27277 zig_panic("TODO memcpy on const inner optional payload"); 27278 case ConstPtrSpecialHardCodedAddr: 27279 zig_unreachable(); 27280 case ConstPtrSpecialFunction: 27281 zig_panic("TODO memcpy on ptr cast from function"); 27282 case ConstPtrSpecialNull: 27283 zig_panic("TODO memcpy on null ptr"); 27284 } 27285 27286 if (dest_start + count > dest_end) { 27287 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds pointer access")); 27288 return ira->codegen->invalid_inst_gen; 27289 } 27290 27291 ZigValue *src_elements; 27292 size_t src_start; 27293 size_t src_end; 27294 27295 switch (src_ptr_val->data.x_ptr.special) { 27296 case ConstPtrSpecialInvalid: 27297 case ConstPtrSpecialDiscard: 27298 zig_unreachable(); 27299 case ConstPtrSpecialRef: 27300 src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; 27301 src_start = 0; 27302 src_end = 1; 27303 break; 27304 case ConstPtrSpecialSubArray: 27305 case ConstPtrSpecialBaseArray: 27306 { 27307 ZigValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; 27308 expand_undef_array(ira->codegen, array_val); 27309 src_elements = array_val->data.x_array.data.s_none.elements; 27310 src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; 27311 src_end = array_val->type->data.array.len; 27312 break; 27313 } 27314 case ConstPtrSpecialBaseStruct: 27315 zig_panic("TODO memcpy on const inner struct"); 27316 case ConstPtrSpecialBaseErrorUnionCode: 27317 zig_panic("TODO memcpy on const inner error union code"); 27318 case ConstPtrSpecialBaseErrorUnionPayload: 27319 zig_panic("TODO memcpy on const inner error union payload"); 27320 case ConstPtrSpecialBaseOptionalPayload: 27321 zig_panic("TODO memcpy on const inner optional payload"); 27322 case ConstPtrSpecialHardCodedAddr: 27323 zig_unreachable(); 27324 case ConstPtrSpecialFunction: 27325 zig_panic("TODO memcpy on ptr cast from function"); 27326 case ConstPtrSpecialNull: 27327 zig_panic("TODO memcpy on null ptr"); 27328 } 27329 27330 if (src_start + count > src_end) { 27331 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds pointer access")); 27332 return ira->codegen->invalid_inst_gen; 27333 } 27334 27335 // TODO check for noalias violations - this should be generalized to work for any function 27336 27337 for (size_t i = 0; i < count; i += 1) { 27338 copy_const_val(ira->codegen, &dest_elements[dest_start + i], &src_elements[src_start + i]); 27339 } 27340 27341 return ir_const_void(ira, &instruction->base.base); 27342 } 27343 } 27344 27345 return ir_build_memcpy_gen(ira, &instruction->base.base, casted_dest_ptr, casted_src_ptr, casted_count); 27346 } 27347 27348 static ZigType *get_result_loc_type(IrAnalyze *ira, ResultLoc *result_loc) { 27349 if (result_loc == nullptr) return nullptr; 27350 27351 if (result_loc->id == ResultLocIdCast) { 27352 return ir_resolve_type(ira, result_loc->source_instruction->child); 27353 } 27354 27355 return nullptr; 27356 } 27357 27358 static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *instruction) { 27359 Error err; 27360 27361 IrInstGen *ptr_ptr = instruction->ptr->child; 27362 if (type_is_invalid(ptr_ptr->value->type)) 27363 return ira->codegen->invalid_inst_gen; 27364 27365 ZigType *ptr_ptr_type = ptr_ptr->value->type; 27366 assert(ptr_ptr_type->id == ZigTypeIdPointer); 27367 ZigType *array_type = ptr_ptr_type->data.pointer.child_type; 27368 27369 IrInstGen *start = instruction->start->child; 27370 if (type_is_invalid(start->value->type)) 27371 return ira->codegen->invalid_inst_gen; 27372 27373 ZigType *usize = ira->codegen->builtin_types.entry_usize; 27374 IrInstGen *casted_start = ir_implicit_cast(ira, start, usize); 27375 if (type_is_invalid(casted_start->value->type)) 27376 return ira->codegen->invalid_inst_gen; 27377 27378 IrInstGen *end; 27379 if (instruction->end) { 27380 end = instruction->end->child; 27381 if (type_is_invalid(end->value->type)) 27382 return ira->codegen->invalid_inst_gen; 27383 end = ir_implicit_cast(ira, end, usize); 27384 if (type_is_invalid(end->value->type)) 27385 return ira->codegen->invalid_inst_gen; 27386 } else { 27387 end = nullptr; 27388 } 27389 27390 ZigValue *slice_sentinel_val = nullptr; 27391 ZigType *non_sentinel_slice_ptr_type; 27392 ZigType *elem_type; 27393 27394 bool generate_non_null_assert = false; 27395 27396 if (array_type->id == ZigTypeIdArray) { 27397 elem_type = array_type->data.array.child_type; 27398 non_sentinel_slice_ptr_type = get_pointer_to_type_extra(ira->codegen, elem_type, 27399 ptr_ptr_type->data.pointer.is_const, 27400 ptr_ptr_type->data.pointer.is_volatile, 27401 PtrLenUnknown, 27402 ptr_ptr_type->data.pointer.explicit_alignment, 0, 0, false); 27403 } else if (array_type->id == ZigTypeIdPointer) { 27404 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 27405 ZigType *main_type = array_type->data.pointer.child_type; 27406 if (main_type->id == ZigTypeIdArray) { 27407 elem_type = main_type->data.pointer.child_type; 27408 non_sentinel_slice_ptr_type = get_pointer_to_type_extra(ira->codegen, 27409 elem_type, 27410 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile, 27411 PtrLenUnknown, 27412 array_type->data.pointer.explicit_alignment, 0, 0, false); 27413 } else { 27414 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of single-item pointer")); 27415 return ira->codegen->invalid_inst_gen; 27416 } 27417 } else { 27418 elem_type = array_type->data.pointer.child_type; 27419 if (array_type->data.pointer.ptr_len == PtrLenC) { 27420 array_type = adjust_ptr_len(ira->codegen, array_type, PtrLenUnknown); 27421 27422 // C pointers are allowzero by default. 27423 // However, we want to be able to slice them without generating an allowzero slice (see issue #4401). 27424 // To achieve this, we generate a runtime safety check and make the slice type non-allowzero. 27425 if (array_type->data.pointer.allow_zero) { 27426 array_type = adjust_ptr_allow_zero(ira->codegen, array_type, false); 27427 generate_non_null_assert = true; 27428 } 27429 } 27430 ZigType *maybe_sentineled_slice_ptr_type = array_type; 27431 non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr); 27432 if (!end) { 27433 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of pointer must include end value")); 27434 return ira->codegen->invalid_inst_gen; 27435 } 27436 } 27437 } else if (is_slice(array_type)) { 27438 ZigType *maybe_sentineled_slice_ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; 27439 slice_sentinel_val = maybe_sentineled_slice_ptr_type->data.pointer.sentinel; 27440 non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr); 27441 elem_type = non_sentinel_slice_ptr_type->data.pointer.child_type; 27442 } else { 27443 ir_add_error(ira, &instruction->base.base, 27444 buf_sprintf("slice of non-array type '%s'", buf_ptr(&array_type->name))); 27445 return ira->codegen->invalid_inst_gen; 27446 } 27447 27448 ZigValue *sentinel_val = nullptr; 27449 if (instruction->sentinel) { 27450 IrInstGen *uncasted_sentinel = instruction->sentinel->child; 27451 if (type_is_invalid(uncasted_sentinel->value->type)) 27452 return ira->codegen->invalid_inst_gen; 27453 IrInstGen *sentinel = ir_implicit_cast(ira, uncasted_sentinel, elem_type); 27454 if (type_is_invalid(sentinel->value->type)) 27455 return ira->codegen->invalid_inst_gen; 27456 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 27457 if (sentinel_val == nullptr) 27458 return ira->codegen->invalid_inst_gen; 27459 } 27460 27461 ZigType *child_array_type = (array_type->id == ZigTypeIdPointer && 27462 array_type->data.pointer.ptr_len == PtrLenSingle) ? array_type->data.pointer.child_type : array_type; 27463 27464 ZigType *return_type; 27465 27466 // If start index and end index are both comptime known, then the result type is a pointer to array 27467 // not a slice. However, if the start or end index is a lazy value, and the result location is a slice, 27468 // then the pointer-to-array would be casted to a slice anyway. So, we preserve the laziness of these 27469 // values by making the return type a slice. 27470 ZigType *res_loc_type = get_result_loc_type(ira, instruction->result_loc); 27471 bool result_loc_is_slice = (res_loc_type != nullptr && is_slice(res_loc_type)); 27472 bool end_is_known = !result_loc_is_slice && 27473 ((end != nullptr && value_is_comptime(end->value)) || 27474 (end == nullptr && child_array_type->id == ZigTypeIdArray)); 27475 27476 ZigValue *array_sentinel = sentinel_val; 27477 if (end_is_known) { 27478 uint64_t end_scalar; 27479 if (end != nullptr) { 27480 ZigValue *end_val = ir_resolve_const(ira, end, UndefBad); 27481 if (!end_val) 27482 return ira->codegen->invalid_inst_gen; 27483 end_scalar = bigint_as_u64(&end_val->data.x_bigint); 27484 } else { 27485 end_scalar = child_array_type->data.array.len; 27486 } 27487 array_sentinel = (child_array_type->id == ZigTypeIdArray && end_scalar == child_array_type->data.array.len) 27488 ? child_array_type->data.array.sentinel : sentinel_val; 27489 27490 if (value_is_comptime(casted_start->value)) { 27491 ZigValue *start_val = ir_resolve_const(ira, casted_start, UndefBad); 27492 if (!start_val) 27493 return ira->codegen->invalid_inst_gen; 27494 27495 uint64_t start_scalar = bigint_as_u64(&start_val->data.x_bigint); 27496 27497 if (start_scalar > end_scalar) { 27498 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds slice")); 27499 return ira->codegen->invalid_inst_gen; 27500 } 27501 27502 uint32_t base_ptr_align = non_sentinel_slice_ptr_type->data.pointer.explicit_alignment; 27503 uint32_t ptr_byte_alignment = 0; 27504 if (end_scalar > start_scalar) { 27505 if ((err = compute_elem_align(ira, elem_type, base_ptr_align, start_scalar, &ptr_byte_alignment))) 27506 return ira->codegen->invalid_inst_gen; 27507 } 27508 27509 ZigType *return_array_type = get_array_type(ira->codegen, elem_type, end_scalar - start_scalar, 27510 array_sentinel); 27511 return_type = get_pointer_to_type_extra(ira->codegen, return_array_type, 27512 non_sentinel_slice_ptr_type->data.pointer.is_const, 27513 non_sentinel_slice_ptr_type->data.pointer.is_volatile, 27514 PtrLenSingle, ptr_byte_alignment, 0, 0, false); 27515 goto done_with_return_type; 27516 } 27517 } else if (array_sentinel == nullptr && end == nullptr) { 27518 array_sentinel = slice_sentinel_val; 27519 } 27520 if (array_sentinel != nullptr) { 27521 // TODO deal with non-abi-alignment here 27522 ZigType *slice_ptr_type = adjust_ptr_sentinel(ira->codegen, non_sentinel_slice_ptr_type, array_sentinel); 27523 return_type = get_slice_type(ira->codegen, slice_ptr_type); 27524 } else { 27525 // TODO deal with non-abi-alignment here 27526 return_type = get_slice_type(ira->codegen, non_sentinel_slice_ptr_type); 27527 } 27528 done_with_return_type: 27529 27530 if (instr_is_comptime(ptr_ptr) && 27531 value_is_comptime(casted_start->value) && 27532 (!end || value_is_comptime(end->value))) 27533 { 27534 ZigValue *array_val; 27535 ZigValue *parent_ptr; 27536 size_t abs_offset; 27537 size_t rel_end; 27538 bool ptr_is_undef = false; 27539 if (child_array_type->id == ZigTypeIdArray) { 27540 if (array_type->id == ZigTypeIdPointer) { 27541 parent_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 27542 if (parent_ptr == nullptr) 27543 return ira->codegen->invalid_inst_gen; 27544 27545 if (parent_ptr->special == ConstValSpecialUndef) { 27546 array_val = nullptr; 27547 abs_offset = 0; 27548 rel_end = SIZE_MAX; 27549 ptr_is_undef = true; 27550 } else if (parent_ptr->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 27551 array_val = nullptr; 27552 abs_offset = 0; 27553 rel_end = SIZE_MAX; 27554 } else { 27555 array_val = const_ptr_pointee(ira, ira->codegen, parent_ptr, instruction->base.base.source_node); 27556 if (array_val == nullptr) 27557 return ira->codegen->invalid_inst_gen; 27558 27559 rel_end = child_array_type->data.array.len; 27560 abs_offset = 0; 27561 } 27562 } else { 27563 array_val = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 27564 if (array_val == nullptr) 27565 return ira->codegen->invalid_inst_gen; 27566 rel_end = array_type->data.array.len; 27567 parent_ptr = nullptr; 27568 abs_offset = 0; 27569 } 27570 } else if (array_type->id == ZigTypeIdPointer) { 27571 assert(array_type->data.pointer.ptr_len == PtrLenUnknown); 27572 parent_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 27573 if (parent_ptr == nullptr) 27574 return ira->codegen->invalid_inst_gen; 27575 27576 if (parent_ptr->special == ConstValSpecialUndef) { 27577 array_val = nullptr; 27578 abs_offset = 0; 27579 rel_end = SIZE_MAX; 27580 ptr_is_undef = true; 27581 } else switch (parent_ptr->data.x_ptr.special) { 27582 case ConstPtrSpecialInvalid: 27583 case ConstPtrSpecialDiscard: 27584 zig_unreachable(); 27585 case ConstPtrSpecialRef: 27586 if (parent_ptr->data.x_ptr.data.ref.pointee->type->id == ZigTypeIdArray) { 27587 array_val = parent_ptr->data.x_ptr.data.ref.pointee; 27588 abs_offset = 0; 27589 rel_end = array_val->type->data.array.len; 27590 } else { 27591 array_val = nullptr; 27592 abs_offset = SIZE_MAX; 27593 rel_end = 1; 27594 } 27595 break; 27596 case ConstPtrSpecialSubArray: 27597 case ConstPtrSpecialBaseArray: 27598 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 27599 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 27600 rel_end = array_val->type->data.array.len - abs_offset; 27601 break; 27602 case ConstPtrSpecialBaseStruct: 27603 zig_panic("TODO slice const inner struct"); 27604 case ConstPtrSpecialBaseErrorUnionCode: 27605 zig_panic("TODO slice const inner error union code"); 27606 case ConstPtrSpecialBaseErrorUnionPayload: 27607 zig_panic("TODO slice const inner error union payload"); 27608 case ConstPtrSpecialBaseOptionalPayload: 27609 zig_panic("TODO slice const inner optional payload"); 27610 case ConstPtrSpecialHardCodedAddr: 27611 array_val = nullptr; 27612 abs_offset = 0; 27613 rel_end = SIZE_MAX; 27614 break; 27615 case ConstPtrSpecialFunction: 27616 zig_panic("TODO slice of ptr cast from function"); 27617 case ConstPtrSpecialNull: 27618 zig_panic("TODO slice of null ptr"); 27619 } 27620 } else if (is_slice(array_type)) { 27621 ZigValue *slice_ptr = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 27622 if (slice_ptr == nullptr) 27623 return ira->codegen->invalid_inst_gen; 27624 27625 if (slice_ptr->special == ConstValSpecialUndef) { 27626 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of undefined")); 27627 return ira->codegen->invalid_inst_gen; 27628 } 27629 27630 parent_ptr = slice_ptr->data.x_struct.fields[slice_ptr_index]; 27631 if (parent_ptr->special == ConstValSpecialUndef) { 27632 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice of undefined")); 27633 return ira->codegen->invalid_inst_gen; 27634 } 27635 27636 ZigValue *len_val = slice_ptr->data.x_struct.fields[slice_len_index]; 27637 27638 switch (parent_ptr->data.x_ptr.special) { 27639 case ConstPtrSpecialInvalid: 27640 case ConstPtrSpecialDiscard: 27641 zig_unreachable(); 27642 case ConstPtrSpecialRef: 27643 array_val = nullptr; 27644 abs_offset = SIZE_MAX; 27645 rel_end = 1; 27646 break; 27647 case ConstPtrSpecialSubArray: 27648 case ConstPtrSpecialBaseArray: 27649 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 27650 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 27651 rel_end = bigint_as_usize(&len_val->data.x_bigint); 27652 break; 27653 case ConstPtrSpecialBaseStruct: 27654 zig_panic("TODO slice const inner struct"); 27655 case ConstPtrSpecialBaseErrorUnionCode: 27656 zig_panic("TODO slice const inner error union code"); 27657 case ConstPtrSpecialBaseErrorUnionPayload: 27658 zig_panic("TODO slice const inner error union payload"); 27659 case ConstPtrSpecialBaseOptionalPayload: 27660 zig_panic("TODO slice const inner optional payload"); 27661 case ConstPtrSpecialHardCodedAddr: 27662 array_val = nullptr; 27663 abs_offset = 0; 27664 rel_end = bigint_as_usize(&len_val->data.x_bigint); 27665 break; 27666 case ConstPtrSpecialFunction: 27667 zig_panic("TODO slice of slice cast from function"); 27668 case ConstPtrSpecialNull: 27669 zig_panic("TODO slice of null"); 27670 } 27671 } else { 27672 zig_unreachable(); 27673 } 27674 27675 ZigValue *start_val = ir_resolve_const(ira, casted_start, UndefBad); 27676 if (!start_val) 27677 return ira->codegen->invalid_inst_gen; 27678 27679 uint64_t start_scalar = bigint_as_u64(&start_val->data.x_bigint); 27680 if (!ptr_is_undef && start_scalar > rel_end) { 27681 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds slice")); 27682 return ira->codegen->invalid_inst_gen; 27683 } 27684 27685 uint64_t end_scalar = rel_end; 27686 if (end) { 27687 ZigValue *end_val = ir_resolve_const(ira, end, UndefBad); 27688 if (!end_val) 27689 return ira->codegen->invalid_inst_gen; 27690 end_scalar = bigint_as_u64(&end_val->data.x_bigint); 27691 } 27692 if (!ptr_is_undef) { 27693 if (end_scalar > rel_end) { 27694 ir_add_error(ira, &instruction->base.base, buf_sprintf("out of bounds slice")); 27695 return ira->codegen->invalid_inst_gen; 27696 } 27697 if (start_scalar > end_scalar) { 27698 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice start is greater than end")); 27699 return ira->codegen->invalid_inst_gen; 27700 } 27701 } 27702 if (ptr_is_undef && start_scalar != end_scalar) { 27703 ir_add_error(ira, &instruction->base.base, buf_sprintf("non-zero length slice of undefined pointer")); 27704 return ira->codegen->invalid_inst_gen; 27705 } 27706 27707 // check sentinel when target is comptime-known 27708 { 27709 if (!sentinel_val) 27710 goto exit_check_sentinel; 27711 27712 switch (ptr_ptr->value->data.x_ptr.mut) { 27713 case ConstPtrMutComptimeConst: 27714 case ConstPtrMutComptimeVar: 27715 break; 27716 case ConstPtrMutRuntimeVar: 27717 case ConstPtrMutInfer: 27718 goto exit_check_sentinel; 27719 } 27720 27721 // prepare check parameters 27722 ZigValue *target = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node); 27723 if (target == nullptr) 27724 return ira->codegen->invalid_inst_gen; 27725 27726 uint64_t target_len = 0; 27727 ZigValue *target_sentinel = nullptr; 27728 ZigValue *target_elements = nullptr; 27729 27730 for (;;) { 27731 if (target->type->id == ZigTypeIdArray) { 27732 // handle `[N]T` 27733 target_len = target->type->data.array.len; 27734 target_sentinel = target->type->data.array.sentinel; 27735 target_elements = target->data.x_array.data.s_none.elements; 27736 break; 27737 } else if (target->type->id == ZigTypeIdPointer && target->type->data.pointer.child_type->id == ZigTypeIdArray) { 27738 // handle `*[N]T` 27739 target = const_ptr_pointee(ira, ira->codegen, target, instruction->base.base.source_node); 27740 if (target == nullptr) 27741 return ira->codegen->invalid_inst_gen; 27742 assert(target->type->id == ZigTypeIdArray); 27743 continue; 27744 } else if (target->type->id == ZigTypeIdPointer) { 27745 // handle `[*]T` 27746 // handle `[*c]T` 27747 switch (target->data.x_ptr.special) { 27748 case ConstPtrSpecialInvalid: 27749 case ConstPtrSpecialDiscard: 27750 zig_unreachable(); 27751 case ConstPtrSpecialRef: 27752 target = target->data.x_ptr.data.ref.pointee; 27753 assert(target->type->id == ZigTypeIdArray); 27754 continue; 27755 case ConstPtrSpecialBaseArray: 27756 case ConstPtrSpecialSubArray: 27757 target = target->data.x_ptr.data.base_array.array_val; 27758 assert(target->type->id == ZigTypeIdArray); 27759 continue; 27760 case ConstPtrSpecialBaseStruct: 27761 zig_panic("TODO slice const inner struct"); 27762 case ConstPtrSpecialBaseErrorUnionCode: 27763 zig_panic("TODO slice const inner error union code"); 27764 case ConstPtrSpecialBaseErrorUnionPayload: 27765 zig_panic("TODO slice const inner error union payload"); 27766 case ConstPtrSpecialBaseOptionalPayload: 27767 zig_panic("TODO slice const inner optional payload"); 27768 case ConstPtrSpecialHardCodedAddr: 27769 // skip check 27770 goto exit_check_sentinel; 27771 case ConstPtrSpecialFunction: 27772 zig_panic("TODO slice of ptr cast from function"); 27773 case ConstPtrSpecialNull: 27774 zig_panic("TODO slice of null ptr"); 27775 } 27776 break; 27777 } else if (is_slice(target->type)) { 27778 // handle `[]T` 27779 target = target->data.x_struct.fields[slice_ptr_index]; 27780 assert(target->type->id == ZigTypeIdPointer); 27781 continue; 27782 } 27783 27784 zig_unreachable(); 27785 } 27786 27787 // perform check 27788 if (target_sentinel == nullptr) { 27789 if (end_scalar >= target_len) { 27790 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel is out of bounds")); 27791 return ira->codegen->invalid_inst_gen; 27792 } 27793 if (!const_values_equal(ira->codegen, sentinel_val, &target_elements[end_scalar])) { 27794 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel does not match memory at target index")); 27795 return ira->codegen->invalid_inst_gen; 27796 } 27797 } else { 27798 assert(end_scalar <= target_len); 27799 if (end_scalar == target_len) { 27800 if (!const_values_equal(ira->codegen, sentinel_val, target_sentinel)) { 27801 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel does not match target-sentinel")); 27802 return ira->codegen->invalid_inst_gen; 27803 } 27804 } else { 27805 if (!const_values_equal(ira->codegen, sentinel_val, &target_elements[end_scalar])) { 27806 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel does not match memory at target index")); 27807 return ira->codegen->invalid_inst_gen; 27808 } 27809 } 27810 } 27811 } 27812 exit_check_sentinel: 27813 27814 IrInstGen *result = ir_const(ira, &instruction->base.base, return_type); 27815 27816 ZigValue *ptr_val; 27817 if (return_type->id == ZigTypeIdPointer) { 27818 // pointer to array 27819 ptr_val = result->value; 27820 } else { 27821 // slice 27822 result->value->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, 2); 27823 27824 ptr_val = result->value->data.x_struct.fields[slice_ptr_index]; 27825 27826 ZigValue *len_val = result->value->data.x_struct.fields[slice_len_index]; 27827 init_const_usize(ira->codegen, len_val, end_scalar - start_scalar); 27828 } 27829 27830 bool return_type_is_const = non_sentinel_slice_ptr_type->data.pointer.is_const; 27831 if (array_val) { 27832 size_t index = abs_offset + start_scalar; 27833 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, return_type_is_const, PtrLenUnknown); 27834 if (return_type->id == ZigTypeIdPointer) { 27835 ptr_val->data.x_ptr.special = ConstPtrSpecialSubArray; 27836 } 27837 if (array_type->id == ZigTypeIdArray) { 27838 ptr_val->data.x_ptr.mut = ptr_ptr->value->data.x_ptr.mut; 27839 } else if (is_slice(array_type)) { 27840 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 27841 } else if (array_type->id == ZigTypeIdPointer) { 27842 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 27843 } 27844 } else if (ptr_is_undef) { 27845 ptr_val->type = get_pointer_to_type(ira->codegen, parent_ptr->type->data.pointer.child_type, 27846 return_type_is_const); 27847 ptr_val->special = ConstValSpecialUndef; 27848 } else switch (parent_ptr->data.x_ptr.special) { 27849 case ConstPtrSpecialInvalid: 27850 case ConstPtrSpecialDiscard: 27851 zig_unreachable(); 27852 case ConstPtrSpecialRef: 27853 init_const_ptr_ref(ira->codegen, ptr_val, parent_ptr->data.x_ptr.data.ref.pointee, 27854 return_type_is_const); 27855 break; 27856 case ConstPtrSpecialSubArray: 27857 case ConstPtrSpecialBaseArray: 27858 zig_unreachable(); 27859 case ConstPtrSpecialBaseStruct: 27860 zig_panic("TODO"); 27861 case ConstPtrSpecialBaseErrorUnionCode: 27862 zig_panic("TODO"); 27863 case ConstPtrSpecialBaseErrorUnionPayload: 27864 zig_panic("TODO"); 27865 case ConstPtrSpecialBaseOptionalPayload: 27866 zig_panic("TODO"); 27867 case ConstPtrSpecialHardCodedAddr: 27868 init_const_ptr_hard_coded_addr(ira->codegen, ptr_val, 27869 parent_ptr->type->data.pointer.child_type, 27870 parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar, 27871 return_type_is_const); 27872 break; 27873 case ConstPtrSpecialFunction: 27874 zig_panic("TODO"); 27875 case ConstPtrSpecialNull: 27876 zig_panic("TODO"); 27877 } 27878 27879 // In the case of pointer-to-array, we must restore this because above it overwrites ptr_val->type 27880 result->value->type = return_type; 27881 return result; 27882 } 27883 27884 if (generate_non_null_assert) { 27885 IrInstGen *ptr_val = ir_get_deref(ira, &instruction->base.base, ptr_ptr, nullptr); 27886 27887 if (type_is_invalid(ptr_val->value->type)) 27888 return ira->codegen->invalid_inst_gen; 27889 27890 ir_build_assert_non_null(ira, &instruction->base.base, ptr_val); 27891 } 27892 27893 IrInstGen *result_loc = nullptr; 27894 27895 if (return_type->id != ZigTypeIdPointer) { 27896 result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 27897 return_type, nullptr, true, true); 27898 if (result_loc != nullptr) { 27899 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { 27900 return result_loc; 27901 } 27902 27903 ir_assert(result_loc->value->type->id == ZigTypeIdPointer, &instruction->base.base); 27904 if (result_loc->value->type->data.pointer.is_const) { 27905 ir_add_error(ira, &instruction->base.base, buf_sprintf("cannot assign to constant")); 27906 return ira->codegen->invalid_inst_gen; 27907 } 27908 27909 IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type); 27910 dummy_value->value->special = ConstValSpecialRuntime; 27911 IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base, 27912 dummy_value, result_loc->value->type->data.pointer.child_type); 27913 if (type_is_invalid(dummy_result->value->type)) 27914 return ira->codegen->invalid_inst_gen; 27915 } 27916 } 27917 27918 return ir_build_slice_gen(ira, &instruction->base.base, return_type, ptr_ptr, 27919 casted_start, end, instruction->safety_check_on, result_loc, sentinel_val); 27920 } 27921 27922 static IrInstGen *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstSrcHasField *instruction) { 27923 Error err; 27924 ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); 27925 if (type_is_invalid(container_type)) 27926 return ira->codegen->invalid_inst_gen; 27927 27928 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusZeroBitsKnown))) 27929 return ira->codegen->invalid_inst_gen; 27930 27931 Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); 27932 if (field_name == nullptr) 27933 return ira->codegen->invalid_inst_gen; 27934 27935 bool result; 27936 if (container_type->id == ZigTypeIdStruct) { 27937 result = find_struct_type_field(container_type, field_name) != nullptr; 27938 } else if (container_type->id == ZigTypeIdEnum) { 27939 result = find_enum_type_field(container_type, field_name) != nullptr; 27940 } else if (container_type->id == ZigTypeIdUnion) { 27941 result = find_union_type_field(container_type, field_name) != nullptr; 27942 } else { 27943 ir_add_error(ira, &instruction->container_type->base, 27944 buf_sprintf("type '%s' does not support @hasField", buf_ptr(&container_type->name))); 27945 return ira->codegen->invalid_inst_gen; 27946 } 27947 return ir_const_bool(ira, &instruction->base.base, result); 27948 } 27949 27950 static IrInstGen *ir_analyze_instruction_wasm_memory_size(IrAnalyze *ira, IrInstSrcWasmMemorySize *instruction) { 27951 // TODO generate compile error for target_arch different than 32bit 27952 if (!target_is_wasm(ira->codegen->zig_target)) { 27953 ir_add_error_node(ira, instruction->base.base.source_node, 27954 buf_sprintf("@wasmMemorySize is a wasm32 feature only")); 27955 return ira->codegen->invalid_inst_gen; 27956 } 27957 27958 IrInstGen *index = instruction->index->child; 27959 if (type_is_invalid(index->value->type)) 27960 return ira->codegen->invalid_inst_gen; 27961 27962 ZigType *u32 = ira->codegen->builtin_types.entry_u32; 27963 27964 IrInstGen *casted_index = ir_implicit_cast(ira, index, u32); 27965 if (type_is_invalid(casted_index->value->type)) 27966 return ira->codegen->invalid_inst_gen; 27967 27968 return ir_build_wasm_memory_size_gen(ira, &instruction->base.base, casted_index); 27969 } 27970 27971 static IrInstGen *ir_analyze_instruction_wasm_memory_grow(IrAnalyze *ira, IrInstSrcWasmMemoryGrow *instruction) { 27972 // TODO generate compile error for target_arch different than 32bit 27973 if (!target_is_wasm(ira->codegen->zig_target)) { 27974 ir_add_error_node(ira, instruction->base.base.source_node, 27975 buf_sprintf("@wasmMemoryGrow is a wasm32 feature only")); 27976 return ira->codegen->invalid_inst_gen; 27977 } 27978 27979 IrInstGen *index = instruction->index->child; 27980 if (type_is_invalid(index->value->type)) 27981 return ira->codegen->invalid_inst_gen; 27982 27983 ZigType *u32 = ira->codegen->builtin_types.entry_u32; 27984 27985 IrInstGen *casted_index = ir_implicit_cast(ira, index, u32); 27986 if (type_is_invalid(casted_index->value->type)) 27987 return ira->codegen->invalid_inst_gen; 27988 27989 IrInstGen *delta = instruction->delta->child; 27990 if (type_is_invalid(delta->value->type)) 27991 return ira->codegen->invalid_inst_gen; 27992 27993 IrInstGen *casted_delta = ir_implicit_cast(ira, delta, u32); 27994 if (type_is_invalid(casted_delta->value->type)) 27995 return ira->codegen->invalid_inst_gen; 27996 27997 return ir_build_wasm_memory_grow_gen(ira, &instruction->base.base, casted_index, casted_delta); 27998 } 27999 28000 static IrInstGen *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstSrcBreakpoint *instruction) { 28001 return ir_build_breakpoint_gen(ira, &instruction->base.base); 28002 } 28003 28004 static IrInstGen *ir_analyze_instruction_return_address(IrAnalyze *ira, IrInstSrcReturnAddress *instruction) { 28005 return ir_build_return_address_gen(ira, &instruction->base.base); 28006 } 28007 28008 static IrInstGen *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstSrcFrameAddress *instruction) { 28009 return ir_build_frame_address_gen(ira, &instruction->base.base); 28010 } 28011 28012 static IrInstGen *ir_analyze_instruction_frame_handle(IrAnalyze *ira, IrInstSrcFrameHandle *instruction) { 28013 ZigFn *fn = ira->new_irb.exec->fn_entry; 28014 ir_assert(fn != nullptr, &instruction->base.base); 28015 28016 if (fn->inferred_async_node == nullptr) { 28017 fn->inferred_async_node = instruction->base.base.source_node; 28018 } 28019 28020 ZigType *frame_type = get_fn_frame_type(ira->codegen, fn); 28021 ZigType *ptr_frame_type = get_pointer_to_type(ira->codegen, frame_type, false); 28022 28023 return ir_build_handle_gen(ira, &instruction->base.base, ptr_frame_type); 28024 } 28025 28026 static IrInstGen *ir_analyze_instruction_frame_type(IrAnalyze *ira, IrInstSrcFrameType *instruction) { 28027 ZigFn *fn = ir_resolve_fn(ira, instruction->fn->child); 28028 if (fn == nullptr) 28029 return ira->codegen->invalid_inst_gen; 28030 28031 if (fn->type_entry->data.fn.is_generic) { 28032 ir_add_error(ira, &instruction->base.base, 28033 buf_sprintf("@Frame() of generic function")); 28034 return ira->codegen->invalid_inst_gen; 28035 } 28036 28037 ZigType *ty = get_fn_frame_type(ira->codegen, fn); 28038 return ir_const_type(ira, &instruction->base.base, ty); 28039 } 28040 28041 static IrInstGen *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstSrcFrameSize *instruction) { 28042 IrInstGen *fn = instruction->fn->child; 28043 if (type_is_invalid(fn->value->type)) 28044 return ira->codegen->invalid_inst_gen; 28045 28046 if (fn->value->type->id != ZigTypeIdFn) { 28047 ir_add_error(ira, &fn->base, 28048 buf_sprintf("expected function, found '%s'", buf_ptr(&fn->value->type->name))); 28049 return ira->codegen->invalid_inst_gen; 28050 } 28051 28052 ira->codegen->need_frame_size_prefix_data = true; 28053 28054 return ir_build_frame_size_gen(ira, &instruction->base.base, fn); 28055 } 28056 28057 static IrInstGen *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstSrcAlignOf *instruction) { 28058 // Here we create a lazy value in order to avoid resolving the alignment of the type 28059 // immediately. This avoids false positive dependency loops such as: 28060 // const Node = struct { 28061 // field: []align(@alignOf(Node)) Node, 28062 // }; 28063 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_num_lit_int); 28064 result->value->special = ConstValSpecialLazy; 28065 28066 LazyValueAlignOf *lazy_align_of = heap::c_allocator.create<LazyValueAlignOf>(); 28067 lazy_align_of->ira = ira; ira_ref(ira); 28068 result->value->data.x_lazy = &lazy_align_of->base; 28069 lazy_align_of->base.id = LazyValueIdAlignOf; 28070 28071 lazy_align_of->target_type = instruction->type_value->child; 28072 if (ir_resolve_type_lazy(ira, lazy_align_of->target_type) == nullptr) 28073 return ira->codegen->invalid_inst_gen; 28074 28075 return result; 28076 } 28077 28078 static IrInstGen *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstSrcOverflowOp *instruction) { 28079 Error err; 28080 28081 IrInstGen *type_value = instruction->type_value->child; 28082 if (type_is_invalid(type_value->value->type)) 28083 return ira->codegen->invalid_inst_gen; 28084 28085 ZigType *dest_type = ir_resolve_type(ira, type_value); 28086 if (type_is_invalid(dest_type)) 28087 return ira->codegen->invalid_inst_gen; 28088 28089 if (dest_type->id != ZigTypeIdInt) { 28090 ir_add_error(ira, &type_value->base, 28091 buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 28092 return ira->codegen->invalid_inst_gen; 28093 } 28094 28095 IrInstGen *op1 = instruction->op1->child; 28096 if (type_is_invalid(op1->value->type)) 28097 return ira->codegen->invalid_inst_gen; 28098 28099 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 28100 if (type_is_invalid(casted_op1->value->type)) 28101 return ira->codegen->invalid_inst_gen; 28102 28103 IrInstGen *op2 = instruction->op2->child; 28104 if (type_is_invalid(op2->value->type)) 28105 return ira->codegen->invalid_inst_gen; 28106 28107 IrInstGen *casted_op2; 28108 if (instruction->op == IrOverflowOpShl) { 28109 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 28110 dest_type->data.integral.bit_count - 1); 28111 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 28112 } else { 28113 casted_op2 = ir_implicit_cast(ira, op2, dest_type); 28114 } 28115 if (type_is_invalid(casted_op2->value->type)) 28116 return ira->codegen->invalid_inst_gen; 28117 28118 IrInstGen *result_ptr = instruction->result_ptr->child; 28119 if (type_is_invalid(result_ptr->value->type)) 28120 return ira->codegen->invalid_inst_gen; 28121 28122 ZigType *expected_ptr_type; 28123 if (result_ptr->value->type->id == ZigTypeIdPointer) { 28124 uint32_t alignment; 28125 if ((err = resolve_ptr_align(ira, result_ptr->value->type, &alignment))) 28126 return ira->codegen->invalid_inst_gen; 28127 expected_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_type, 28128 false, result_ptr->value->type->data.pointer.is_volatile, 28129 PtrLenSingle, 28130 alignment, 0, 0, false); 28131 } else { 28132 expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false); 28133 } 28134 28135 IrInstGen *casted_result_ptr = ir_implicit_cast(ira, result_ptr, expected_ptr_type); 28136 if (type_is_invalid(casted_result_ptr->value->type)) 28137 return ira->codegen->invalid_inst_gen; 28138 28139 if (instr_is_comptime(casted_op1) && 28140 instr_is_comptime(casted_op2) && 28141 instr_is_comptime(casted_result_ptr)) 28142 { 28143 ZigValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 28144 if (op1_val == nullptr) 28145 return ira->codegen->invalid_inst_gen; 28146 28147 ZigValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 28148 if (op2_val == nullptr) 28149 return ira->codegen->invalid_inst_gen; 28150 28151 ZigValue *result_val = ir_resolve_const(ira, casted_result_ptr, UndefBad); 28152 if (result_val == nullptr) 28153 return ira->codegen->invalid_inst_gen; 28154 28155 BigInt *op1_bigint = &op1_val->data.x_bigint; 28156 BigInt *op2_bigint = &op2_val->data.x_bigint; 28157 ZigValue *pointee_val = const_ptr_pointee(ira, ira->codegen, result_val, 28158 casted_result_ptr->base.source_node); 28159 if (pointee_val == nullptr) 28160 return ira->codegen->invalid_inst_gen; 28161 BigInt *dest_bigint = &pointee_val->data.x_bigint; 28162 switch (instruction->op) { 28163 case IrOverflowOpAdd: 28164 bigint_add(dest_bigint, op1_bigint, op2_bigint); 28165 break; 28166 case IrOverflowOpSub: 28167 bigint_sub(dest_bigint, op1_bigint, op2_bigint); 28168 break; 28169 case IrOverflowOpMul: 28170 bigint_mul(dest_bigint, op1_bigint, op2_bigint); 28171 break; 28172 case IrOverflowOpShl: 28173 bigint_shl(dest_bigint, op1_bigint, op2_bigint); 28174 break; 28175 } 28176 bool result_bool = false; 28177 if (!bigint_fits_in_bits(dest_bigint, dest_type->data.integral.bit_count, 28178 dest_type->data.integral.is_signed)) 28179 { 28180 result_bool = true; 28181 BigInt tmp_bigint; 28182 bigint_init_bigint(&tmp_bigint, dest_bigint); 28183 bigint_truncate(dest_bigint, &tmp_bigint, dest_type->data.integral.bit_count, 28184 dest_type->data.integral.is_signed); 28185 } 28186 pointee_val->special = ConstValSpecialStatic; 28187 return ir_const_bool(ira, &instruction->base.base, result_bool); 28188 } 28189 28190 return ir_build_overflow_op_gen(ira, &instruction->base.base, instruction->op, 28191 casted_op1, casted_op2, casted_result_ptr, dest_type); 28192 } 28193 28194 static void ir_eval_mul_add(IrAnalyze *ira, IrInstSrcMulAdd *source_instr, ZigType *float_type, 28195 ZigValue *op1, ZigValue *op2, ZigValue *op3, ZigValue *out_val) { 28196 if (float_type->id == ZigTypeIdComptimeFloat) { 28197 f128M_mulAdd(&out_val->data.x_bigfloat.value, &op1->data.x_bigfloat.value, &op2->data.x_bigfloat.value, 28198 &op3->data.x_bigfloat.value); 28199 } else if (float_type->id == ZigTypeIdFloat) { 28200 switch (float_type->data.floating.bit_count) { 28201 case 16: 28202 out_val->data.x_f16 = f16_mulAdd(op1->data.x_f16, op2->data.x_f16, op3->data.x_f16); 28203 break; 28204 case 32: 28205 out_val->data.x_f32 = fmaf(op1->data.x_f32, op2->data.x_f32, op3->data.x_f32); 28206 break; 28207 case 64: 28208 out_val->data.x_f64 = fma(op1->data.x_f64, op2->data.x_f64, op3->data.x_f64); 28209 break; 28210 case 128: 28211 f128M_mulAdd(&op1->data.x_f128, &op2->data.x_f128, &op3->data.x_f128, &out_val->data.x_f128); 28212 break; 28213 default: 28214 zig_unreachable(); 28215 } 28216 } else { 28217 zig_unreachable(); 28218 } 28219 } 28220 28221 static IrInstGen *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstSrcMulAdd *instruction) { 28222 IrInstGen *type_value = instruction->type_value->child; 28223 if (type_is_invalid(type_value->value->type)) 28224 return ira->codegen->invalid_inst_gen; 28225 28226 ZigType *expr_type = ir_resolve_type(ira, type_value); 28227 if (type_is_invalid(expr_type)) 28228 return ira->codegen->invalid_inst_gen; 28229 28230 // Only allow float types, and vectors of floats. 28231 ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; 28232 if (float_type->id != ZigTypeIdFloat) { 28233 ir_add_error(ira, &type_value->base, 28234 buf_sprintf("expected float or vector of float type, found '%s'", buf_ptr(&float_type->name))); 28235 return ira->codegen->invalid_inst_gen; 28236 } 28237 28238 IrInstGen *op1 = instruction->op1->child; 28239 if (type_is_invalid(op1->value->type)) 28240 return ira->codegen->invalid_inst_gen; 28241 28242 IrInstGen *casted_op1 = ir_implicit_cast(ira, op1, expr_type); 28243 if (type_is_invalid(casted_op1->value->type)) 28244 return ira->codegen->invalid_inst_gen; 28245 28246 IrInstGen *op2 = instruction->op2->child; 28247 if (type_is_invalid(op2->value->type)) 28248 return ira->codegen->invalid_inst_gen; 28249 28250 IrInstGen *casted_op2 = ir_implicit_cast(ira, op2, expr_type); 28251 if (type_is_invalid(casted_op2->value->type)) 28252 return ira->codegen->invalid_inst_gen; 28253 28254 IrInstGen *op3 = instruction->op3->child; 28255 if (type_is_invalid(op3->value->type)) 28256 return ira->codegen->invalid_inst_gen; 28257 28258 IrInstGen *casted_op3 = ir_implicit_cast(ira, op3, expr_type); 28259 if (type_is_invalid(casted_op3->value->type)) 28260 return ira->codegen->invalid_inst_gen; 28261 28262 if (instr_is_comptime(casted_op1) && 28263 instr_is_comptime(casted_op2) && 28264 instr_is_comptime(casted_op3)) { 28265 ZigValue *op1_const = ir_resolve_const(ira, casted_op1, UndefBad); 28266 if (!op1_const) 28267 return ira->codegen->invalid_inst_gen; 28268 ZigValue *op2_const = ir_resolve_const(ira, casted_op2, UndefBad); 28269 if (!op2_const) 28270 return ira->codegen->invalid_inst_gen; 28271 ZigValue *op3_const = ir_resolve_const(ira, casted_op3, UndefBad); 28272 if (!op3_const) 28273 return ira->codegen->invalid_inst_gen; 28274 28275 IrInstGen *result = ir_const(ira, &instruction->base.base, expr_type); 28276 ZigValue *out_val = result->value; 28277 28278 if (expr_type->id == ZigTypeIdVector) { 28279 expand_undef_array(ira->codegen, op1_const); 28280 expand_undef_array(ira->codegen, op2_const); 28281 expand_undef_array(ira->codegen, op3_const); 28282 out_val->special = ConstValSpecialUndef; 28283 expand_undef_array(ira->codegen, out_val); 28284 size_t len = expr_type->data.vector.len; 28285 for (size_t i = 0; i < len; i += 1) { 28286 ZigValue *float_operand_op1 = &op1_const->data.x_array.data.s_none.elements[i]; 28287 ZigValue *float_operand_op2 = &op2_const->data.x_array.data.s_none.elements[i]; 28288 ZigValue *float_operand_op3 = &op3_const->data.x_array.data.s_none.elements[i]; 28289 ZigValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; 28290 assert(float_operand_op1->type == float_type); 28291 assert(float_operand_op2->type == float_type); 28292 assert(float_operand_op3->type == float_type); 28293 assert(float_out_val->type == float_type); 28294 ir_eval_mul_add(ira, instruction, float_type, 28295 op1_const, op2_const, op3_const, float_out_val); 28296 float_out_val->type = float_type; 28297 } 28298 out_val->type = expr_type; 28299 out_val->special = ConstValSpecialStatic; 28300 } else { 28301 ir_eval_mul_add(ira, instruction, float_type, op1_const, op2_const, op3_const, out_val); 28302 } 28303 return result; 28304 } 28305 28306 return ir_build_mul_add_gen(ira, &instruction->base.base, casted_op1, casted_op2, casted_op3, expr_type); 28307 } 28308 28309 static IrInstGen *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstSrcTestErr *instruction) { 28310 IrInstGen *base_ptr = instruction->base_ptr->child; 28311 if (type_is_invalid(base_ptr->value->type)) 28312 return ira->codegen->invalid_inst_gen; 28313 28314 IrInstGen *value; 28315 if (instruction->base_ptr_is_payload) { 28316 value = base_ptr; 28317 } else { 28318 value = ir_get_deref(ira, &instruction->base.base, base_ptr, nullptr); 28319 } 28320 28321 ZigType *type_entry = value->value->type; 28322 if (type_is_invalid(type_entry)) 28323 return ira->codegen->invalid_inst_gen; 28324 if (type_entry->id == ZigTypeIdErrorUnion) { 28325 if (instr_is_comptime(value)) { 28326 ZigValue *err_union_val = ir_resolve_const(ira, value, UndefBad); 28327 if (!err_union_val) 28328 return ira->codegen->invalid_inst_gen; 28329 28330 if (err_union_val->special != ConstValSpecialRuntime) { 28331 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; 28332 return ir_const_bool(ira, &instruction->base.base, (err != nullptr)); 28333 } 28334 } 28335 28336 if (instruction->resolve_err_set) { 28337 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 28338 if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.base.source_node)) { 28339 return ira->codegen->invalid_inst_gen; 28340 } 28341 if (!type_is_global_error_set(err_set_type) && 28342 err_set_type->data.error_set.err_count == 0) 28343 { 28344 assert(!err_set_type->data.error_set.incomplete); 28345 return ir_const_bool(ira, &instruction->base.base, false); 28346 } 28347 } 28348 28349 return ir_build_test_err_gen(ira, &instruction->base.base, value); 28350 } else if (type_entry->id == ZigTypeIdErrorSet) { 28351 return ir_const_bool(ira, &instruction->base.base, true); 28352 } else { 28353 return ir_const_bool(ira, &instruction->base.base, false); 28354 } 28355 } 28356 28357 static IrInstGen *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInst* source_instr, 28358 IrInstGen *base_ptr, bool initializing) 28359 { 28360 ZigType *ptr_type = base_ptr->value->type; 28361 28362 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 28363 assert(ptr_type->id == ZigTypeIdPointer); 28364 28365 ZigType *type_entry = ptr_type->data.pointer.child_type; 28366 if (type_is_invalid(type_entry)) 28367 return ira->codegen->invalid_inst_gen; 28368 28369 if (type_entry->id != ZigTypeIdErrorUnion) { 28370 ir_add_error(ira, &base_ptr->base, 28371 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 28372 return ira->codegen->invalid_inst_gen; 28373 } 28374 28375 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 28376 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, err_set_type, 28377 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 28378 ptr_type->data.pointer.explicit_alignment, 0, 0, false); 28379 28380 if (instr_is_comptime(base_ptr)) { 28381 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 28382 if (!ptr_val) 28383 return ira->codegen->invalid_inst_gen; 28384 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar && 28385 ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) 28386 { 28387 ZigValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 28388 if (err_union_val == nullptr) 28389 return ira->codegen->invalid_inst_gen; 28390 28391 if (initializing && err_union_val->special == ConstValSpecialUndef) { 28392 ZigValue *vals = ira->codegen->pass1_arena->allocate<ZigValue>(2); 28393 ZigValue *err_set_val = &vals[0]; 28394 ZigValue *payload_val = &vals[1]; 28395 28396 err_set_val->special = ConstValSpecialUndef; 28397 err_set_val->type = err_set_type; 28398 err_set_val->parent.id = ConstParentIdErrUnionCode; 28399 err_set_val->parent.data.p_err_union_code.err_union_val = err_union_val; 28400 28401 payload_val->special = ConstValSpecialUndef; 28402 payload_val->type = type_entry->data.error_union.payload_type; 28403 payload_val->parent.id = ConstParentIdErrUnionPayload; 28404 payload_val->parent.data.p_err_union_payload.err_union_val = err_union_val; 28405 28406 err_union_val->special = ConstValSpecialStatic; 28407 err_union_val->data.x_err_union.error_set = err_set_val; 28408 err_union_val->data.x_err_union.payload = payload_val; 28409 } 28410 ir_assert(err_union_val->special != ConstValSpecialRuntime, source_instr); 28411 28412 IrInstGen *result; 28413 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 28414 result = ir_build_unwrap_err_code_gen(ira, source_instr->scope, 28415 source_instr->source_node, base_ptr, result_type); 28416 result->value->special = ConstValSpecialStatic; 28417 } else { 28418 result = ir_const(ira, source_instr, result_type); 28419 } 28420 ZigValue *const_val = result->value; 28421 const_val->data.x_ptr.special = ConstPtrSpecialBaseErrorUnionCode; 28422 const_val->data.x_ptr.data.base_err_union_code.err_union_val = err_union_val; 28423 const_val->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 28424 return result; 28425 } 28426 } 28427 28428 return ir_build_unwrap_err_code_gen(ira, source_instr->scope, source_instr->source_node, base_ptr, result_type); 28429 } 28430 28431 static IrInstGen *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrInstSrcUnwrapErrCode *instruction) { 28432 IrInstGen *base_ptr = instruction->err_union_ptr->child; 28433 if (type_is_invalid(base_ptr->value->type)) 28434 return ira->codegen->invalid_inst_gen; 28435 return ir_analyze_unwrap_err_code(ira, &instruction->base.base, base_ptr, false); 28436 } 28437 28438 static IrInstGen *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInst* source_instr, 28439 IrInstGen *base_ptr, bool safety_check_on, bool initializing) 28440 { 28441 ZigType *ptr_type = base_ptr->value->type; 28442 28443 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 28444 assert(ptr_type->id == ZigTypeIdPointer); 28445 28446 ZigType *type_entry = ptr_type->data.pointer.child_type; 28447 if (type_is_invalid(type_entry)) 28448 return ira->codegen->invalid_inst_gen; 28449 28450 if (type_entry->id != ZigTypeIdErrorUnion) { 28451 ir_add_error(ira, &base_ptr->base, 28452 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 28453 return ira->codegen->invalid_inst_gen; 28454 } 28455 28456 ZigType *payload_type = type_entry->data.error_union.payload_type; 28457 if (type_is_invalid(payload_type)) 28458 return ira->codegen->invalid_inst_gen; 28459 28460 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, 28461 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 28462 PtrLenSingle, 0, 0, 0, false); 28463 28464 if (instr_is_comptime(base_ptr)) { 28465 ZigValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); 28466 if (!ptr_val) 28467 return ira->codegen->invalid_inst_gen; 28468 if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 28469 ZigValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, source_instr->source_node); 28470 if (err_union_val == nullptr) 28471 return ira->codegen->invalid_inst_gen; 28472 if (initializing && err_union_val->special == ConstValSpecialUndef) { 28473 ZigValue *vals = ira->codegen->pass1_arena->allocate<ZigValue>(2); 28474 ZigValue *err_set_val = &vals[0]; 28475 ZigValue *payload_val = &vals[1]; 28476 28477 err_set_val->special = ConstValSpecialStatic; 28478 err_set_val->type = type_entry->data.error_union.err_set_type; 28479 err_set_val->data.x_err_set = nullptr; 28480 28481 payload_val->special = ConstValSpecialUndef; 28482 payload_val->type = payload_type; 28483 28484 err_union_val->special = ConstValSpecialStatic; 28485 err_union_val->data.x_err_union.error_set = err_set_val; 28486 err_union_val->data.x_err_union.payload = payload_val; 28487 } 28488 28489 if (err_union_val->special != ConstValSpecialRuntime) { 28490 ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set; 28491 if (err != nullptr) { 28492 ir_add_error(ira, source_instr, 28493 buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); 28494 return ira->codegen->invalid_inst_gen; 28495 } 28496 28497 IrInstGen *result; 28498 if (ptr_val->data.x_ptr.mut == ConstPtrMutInfer) { 28499 result = ir_build_unwrap_err_payload_gen(ira, source_instr->scope, 28500 source_instr->source_node, base_ptr, safety_check_on, initializing, result_type); 28501 result->value->special = ConstValSpecialStatic; 28502 } else { 28503 result = ir_const(ira, source_instr, result_type); 28504 } 28505 result->value->data.x_ptr.special = ConstPtrSpecialRef; 28506 result->value->data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; 28507 result->value->data.x_ptr.mut = ptr_val->data.x_ptr.mut; 28508 return result; 28509 } 28510 } 28511 } 28512 28513 return ir_build_unwrap_err_payload_gen(ira, source_instr->scope, source_instr->source_node, 28514 base_ptr, safety_check_on, initializing, result_type); 28515 } 28516 28517 static IrInstGen *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, 28518 IrInstSrcUnwrapErrPayload *instruction) 28519 { 28520 assert(instruction->value->child); 28521 IrInstGen *value = instruction->value->child; 28522 if (type_is_invalid(value->value->type)) 28523 return ira->codegen->invalid_inst_gen; 28524 28525 return ir_analyze_unwrap_error_payload(ira, &instruction->base.base, value, instruction->safety_check_on, false); 28526 } 28527 28528 static IrInstGen *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstSrcFnProto *instruction) { 28529 AstNode *proto_node = instruction->base.base.source_node; 28530 assert(proto_node->type == NodeTypeFnProto); 28531 28532 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); 28533 result->value->special = ConstValSpecialLazy; 28534 28535 LazyValueFnType *lazy_fn_type = heap::c_allocator.create<LazyValueFnType>(); 28536 lazy_fn_type->ira = ira; ira_ref(ira); 28537 result->value->data.x_lazy = &lazy_fn_type->base; 28538 lazy_fn_type->base.id = LazyValueIdFnType; 28539 28540 if (proto_node->data.fn_proto.auto_err_set) { 28541 ir_add_error(ira, &instruction->base.base, 28542 buf_sprintf("inferring error set of return type valid only for function definitions")); 28543 return ira->codegen->invalid_inst_gen; 28544 } 28545 28546 lazy_fn_type->cc = cc_from_fn_proto(&proto_node->data.fn_proto); 28547 if (instruction->callconv_value != nullptr) { 28548 ZigType *cc_enum_type = get_builtin_type(ira->codegen, "CallingConvention"); 28549 28550 IrInstGen *casted_value = ir_implicit_cast(ira, instruction->callconv_value->child, cc_enum_type); 28551 if (type_is_invalid(casted_value->value->type)) 28552 return ira->codegen->invalid_inst_gen; 28553 28554 ZigValue *const_value = ir_resolve_const(ira, casted_value, UndefBad); 28555 if (const_value == nullptr) 28556 return ira->codegen->invalid_inst_gen; 28557 28558 lazy_fn_type->cc = (CallingConvention)bigint_as_u32(&const_value->data.x_enum_tag); 28559 } 28560 28561 size_t param_count = proto_node->data.fn_proto.params.length; 28562 lazy_fn_type->proto_node = proto_node; 28563 lazy_fn_type->param_types = heap::c_allocator.allocate<IrInstGen *>(param_count); 28564 28565 for (size_t param_index = 0; param_index < param_count; param_index += 1) { 28566 AstNode *param_node = proto_node->data.fn_proto.params.at(param_index); 28567 assert(param_node->type == NodeTypeParamDecl); 28568 28569 bool param_is_var_args = param_node->data.param_decl.is_var_args; 28570 if (param_is_var_args) { 28571 const CallingConvention cc = lazy_fn_type->cc; 28572 28573 if (cc == CallingConventionC) { 28574 break; 28575 } else { 28576 ir_add_error(ira, &instruction->base.base, 28577 buf_sprintf("var args only allowed in functions with C calling convention")); 28578 return ira->codegen->invalid_inst_gen; 28579 } 28580 } 28581 28582 if (instruction->param_types[param_index] == nullptr) { 28583 lazy_fn_type->is_generic = true; 28584 return result; 28585 } 28586 28587 IrInstGen *param_type_value = instruction->param_types[param_index]->child; 28588 if (type_is_invalid(param_type_value->value->type)) 28589 return ira->codegen->invalid_inst_gen; 28590 if (ir_resolve_const(ira, param_type_value, LazyOk) == nullptr) 28591 return ira->codegen->invalid_inst_gen; 28592 lazy_fn_type->param_types[param_index] = param_type_value; 28593 } 28594 28595 if (instruction->align_value != nullptr) { 28596 lazy_fn_type->align_inst = instruction->align_value->child; 28597 if (ir_resolve_const(ira, lazy_fn_type->align_inst, LazyOk) == nullptr) 28598 return ira->codegen->invalid_inst_gen; 28599 } 28600 28601 lazy_fn_type->return_type = instruction->return_type->child; 28602 if (ir_resolve_const(ira, lazy_fn_type->return_type, LazyOk) == nullptr) 28603 return ira->codegen->invalid_inst_gen; 28604 28605 return result; 28606 } 28607 28608 static IrInstGen *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstSrcTestComptime *instruction) { 28609 IrInstGen *value = instruction->value->child; 28610 if (type_is_invalid(value->value->type)) 28611 return ira->codegen->invalid_inst_gen; 28612 28613 return ir_const_bool(ira, &instruction->base.base, instr_is_comptime(value)); 28614 } 28615 28616 static IrInstGen *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, 28617 IrInstSrcCheckSwitchProngs *instruction) 28618 { 28619 IrInstGen *target_value = instruction->target_value->child; 28620 ZigType *switch_type = target_value->value->type; 28621 if (type_is_invalid(switch_type)) 28622 return ira->codegen->invalid_inst_gen; 28623 28624 if (switch_type->id == ZigTypeIdEnum) { 28625 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> field_prev_uses = {}; 28626 field_prev_uses.init(switch_type->data.enumeration.src_field_count); 28627 28628 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 28629 IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 28630 28631 IrInstGen *start_value_uncasted = range->start->child; 28632 if (type_is_invalid(start_value_uncasted->value->type)) 28633 return ira->codegen->invalid_inst_gen; 28634 IrInstGen *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); 28635 if (type_is_invalid(start_value->value->type)) 28636 return ira->codegen->invalid_inst_gen; 28637 28638 IrInstGen *end_value_uncasted = range->end->child; 28639 if (type_is_invalid(end_value_uncasted->value->type)) 28640 return ira->codegen->invalid_inst_gen; 28641 IrInstGen *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); 28642 if (type_is_invalid(end_value->value->type)) 28643 return ira->codegen->invalid_inst_gen; 28644 28645 assert(start_value->value->type->id == ZigTypeIdEnum); 28646 BigInt start_index; 28647 bigint_init_bigint(&start_index, &start_value->value->data.x_enum_tag); 28648 28649 assert(end_value->value->type->id == ZigTypeIdEnum); 28650 BigInt end_index; 28651 bigint_init_bigint(&end_index, &end_value->value->data.x_enum_tag); 28652 28653 if (bigint_cmp(&start_index, &end_index) == CmpGT) { 28654 ir_add_error(ira, &start_value->base, 28655 buf_sprintf("range start value is greater than the end value")); 28656 } 28657 28658 BigInt field_index; 28659 bigint_init_bigint(&field_index, &start_index); 28660 for (;;) { 28661 Cmp cmp = bigint_cmp(&field_index, &end_index); 28662 if (cmp == CmpGT) { 28663 break; 28664 } 28665 auto entry = field_prev_uses.put_unique(field_index, start_value->base.source_node); 28666 if (entry) { 28667 AstNode *prev_node = entry->value; 28668 TypeEnumField *enum_field = find_enum_field_by_tag(switch_type, &field_index); 28669 assert(enum_field != nullptr); 28670 ErrorMsg *msg = ir_add_error(ira, &start_value->base, 28671 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), 28672 buf_ptr(enum_field->name))); 28673 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 28674 } 28675 bigint_incr(&field_index); 28676 } 28677 } 28678 if (instruction->have_underscore_prong) { 28679 if (!switch_type->data.enumeration.non_exhaustive){ 28680 ir_add_error(ira, &instruction->base.base, 28681 buf_sprintf("switch on non-exhaustive enum has `_` prong")); 28682 } 28683 for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { 28684 TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i]; 28685 if (buf_eql_str(enum_field->name, "_")) 28686 continue; 28687 28688 auto entry = field_prev_uses.maybe_get(enum_field->value); 28689 if (!entry) { 28690 ir_add_error(ira, &instruction->base.base, 28691 buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name), 28692 buf_ptr(enum_field->name))); 28693 } 28694 } 28695 } else if (!instruction->have_else_prong) { 28696 if (switch_type->data.enumeration.non_exhaustive) { 28697 ir_add_error(ira, &instruction->base.base, 28698 buf_sprintf("switch on non-exhaustive enum must include `else` or `_` prong")); 28699 } 28700 for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { 28701 TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i]; 28702 28703 auto entry = field_prev_uses.maybe_get(enum_field->value); 28704 if (!entry) { 28705 ir_add_error(ira, &instruction->base.base, 28706 buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name), 28707 buf_ptr(enum_field->name))); 28708 } 28709 } 28710 } 28711 } else if (switch_type->id == ZigTypeIdErrorSet) { 28712 if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->base.source_node)) { 28713 return ira->codegen->invalid_inst_gen; 28714 } 28715 28716 size_t field_prev_uses_count = ira->codegen->errors_by_index.length; 28717 AstNode **field_prev_uses = heap::c_allocator.allocate<AstNode *>(field_prev_uses_count); 28718 28719 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 28720 IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 28721 28722 IrInstGen *start_value_uncasted = range->start->child; 28723 if (type_is_invalid(start_value_uncasted->value->type)) 28724 return ira->codegen->invalid_inst_gen; 28725 IrInstGen *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type); 28726 if (type_is_invalid(start_value->value->type)) 28727 return ira->codegen->invalid_inst_gen; 28728 28729 IrInstGen *end_value_uncasted = range->end->child; 28730 if (type_is_invalid(end_value_uncasted->value->type)) 28731 return ira->codegen->invalid_inst_gen; 28732 IrInstGen *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type); 28733 if (type_is_invalid(end_value->value->type)) 28734 return ira->codegen->invalid_inst_gen; 28735 28736 ir_assert(start_value->value->type->id == ZigTypeIdErrorSet, &instruction->base.base); 28737 uint32_t start_index = start_value->value->data.x_err_set->value; 28738 28739 ir_assert(end_value->value->type->id == ZigTypeIdErrorSet, &instruction->base.base); 28740 uint32_t end_index = end_value->value->data.x_err_set->value; 28741 28742 if (start_index != end_index) { 28743 ir_add_error(ira, &end_value->base, buf_sprintf("ranges not allowed when switching on errors")); 28744 return ira->codegen->invalid_inst_gen; 28745 } 28746 28747 AstNode *prev_node = field_prev_uses[start_index]; 28748 if (prev_node != nullptr) { 28749 Buf *err_name = &ira->codegen->errors_by_index.at(start_index)->name; 28750 ErrorMsg *msg = ir_add_error(ira, &start_value->base, 28751 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), buf_ptr(err_name))); 28752 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 28753 } 28754 field_prev_uses[start_index] = start_value->base.source_node; 28755 } 28756 if (!instruction->have_else_prong) { 28757 if (type_is_global_error_set(switch_type)) { 28758 ir_add_error(ira, &instruction->base.base, 28759 buf_sprintf("else prong required when switching on type 'anyerror'")); 28760 return ira->codegen->invalid_inst_gen; 28761 } else { 28762 for (uint32_t i = 0; i < switch_type->data.error_set.err_count; i += 1) { 28763 ErrorTableEntry *err_entry = switch_type->data.error_set.errors[i]; 28764 28765 AstNode *prev_node = field_prev_uses[err_entry->value]; 28766 if (prev_node == nullptr) { 28767 ir_add_error(ira, &instruction->base.base, 28768 buf_sprintf("error.%s not handled in switch", buf_ptr(&err_entry->name))); 28769 } 28770 } 28771 } 28772 } 28773 28774 heap::c_allocator.deallocate(field_prev_uses, field_prev_uses_count); 28775 } else if (switch_type->id == ZigTypeIdInt) { 28776 RangeSet rs = {0}; 28777 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 28778 IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 28779 28780 IrInstGen *start_value = range->start->child; 28781 if (type_is_invalid(start_value->value->type)) 28782 return ira->codegen->invalid_inst_gen; 28783 IrInstGen *casted_start_value = ir_implicit_cast(ira, start_value, switch_type); 28784 if (type_is_invalid(casted_start_value->value->type)) 28785 return ira->codegen->invalid_inst_gen; 28786 28787 IrInstGen *end_value = range->end->child; 28788 if (type_is_invalid(end_value->value->type)) 28789 return ira->codegen->invalid_inst_gen; 28790 IrInstGen *casted_end_value = ir_implicit_cast(ira, end_value, switch_type); 28791 if (type_is_invalid(casted_end_value->value->type)) 28792 return ira->codegen->invalid_inst_gen; 28793 28794 ZigValue *start_val = ir_resolve_const(ira, casted_start_value, UndefBad); 28795 if (!start_val) 28796 return ira->codegen->invalid_inst_gen; 28797 28798 ZigValue *end_val = ir_resolve_const(ira, casted_end_value, UndefBad); 28799 if (!end_val) 28800 return ira->codegen->invalid_inst_gen; 28801 28802 assert(start_val->type->id == ZigTypeIdInt || start_val->type->id == ZigTypeIdComptimeInt); 28803 assert(end_val->type->id == ZigTypeIdInt || end_val->type->id == ZigTypeIdComptimeInt); 28804 28805 if (bigint_cmp(&start_val->data.x_bigint, &end_val->data.x_bigint) == CmpGT) { 28806 ir_add_error(ira, &start_value->base, 28807 buf_sprintf("range start value is greater than the end value")); 28808 } 28809 28810 AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint, 28811 start_value->base.source_node); 28812 if (prev_node != nullptr) { 28813 ErrorMsg *msg = ir_add_error(ira, &start_value->base, buf_sprintf("duplicate switch value")); 28814 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("previous value is here")); 28815 return ira->codegen->invalid_inst_gen; 28816 } 28817 } 28818 if (!instruction->have_else_prong) { 28819 BigInt min_val; 28820 eval_min_max_value_int(ira->codegen, switch_type, &min_val, false); 28821 BigInt max_val; 28822 eval_min_max_value_int(ira->codegen, switch_type, &max_val, true); 28823 if (!rangeset_spans(&rs, &min_val, &max_val)) { 28824 ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities")); 28825 return ira->codegen->invalid_inst_gen; 28826 } 28827 } 28828 } else if (switch_type->id == ZigTypeIdBool) { 28829 int seenTrue = 0; 28830 int seenFalse = 0; 28831 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 28832 IrInstSrcCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 28833 28834 IrInstGen *value = range->start->child; 28835 28836 IrInstGen *casted_value = ir_implicit_cast(ira, value, switch_type); 28837 if (type_is_invalid(casted_value->value->type)) 28838 return ira->codegen->invalid_inst_gen; 28839 28840 ZigValue *const_expr_val = ir_resolve_const(ira, casted_value, UndefBad); 28841 if (!const_expr_val) 28842 return ira->codegen->invalid_inst_gen; 28843 28844 assert(const_expr_val->type->id == ZigTypeIdBool); 28845 28846 if (const_expr_val->data.x_bool == true) { 28847 seenTrue += 1; 28848 } else { 28849 seenFalse += 1; 28850 } 28851 28852 if ((seenTrue > 1) || (seenFalse > 1)) { 28853 ir_add_error(ira, &value->base, buf_sprintf("duplicate switch value")); 28854 return ira->codegen->invalid_inst_gen; 28855 } 28856 } 28857 if (((seenTrue < 1) || (seenFalse < 1)) && !instruction->have_else_prong) { 28858 ir_add_error(ira, &instruction->base.base, buf_sprintf("switch must handle all possibilities")); 28859 return ira->codegen->invalid_inst_gen; 28860 } 28861 } else if (!instruction->have_else_prong) { 28862 ir_add_error(ira, &instruction->base.base, 28863 buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name))); 28864 return ira->codegen->invalid_inst_gen; 28865 } 28866 return ir_const_void(ira, &instruction->base.base); 28867 } 28868 28869 static IrInstGen *ir_analyze_instruction_check_statement_is_void(IrAnalyze *ira, 28870 IrInstSrcCheckStatementIsVoid *instruction) 28871 { 28872 IrInstGen *statement_value = instruction->statement_value->child; 28873 ZigType *statement_type = statement_value->value->type; 28874 if (type_is_invalid(statement_type)) 28875 return ira->codegen->invalid_inst_gen; 28876 28877 if (statement_type->id != ZigTypeIdVoid && statement_type->id != ZigTypeIdUnreachable) { 28878 ir_add_error(ira, &instruction->base.base, buf_sprintf("expression value is ignored")); 28879 } 28880 28881 return ir_const_void(ira, &instruction->base.base); 28882 } 28883 28884 static IrInstGen *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstSrcPanic *instruction) { 28885 IrInstGen *msg = instruction->msg->child; 28886 if (type_is_invalid(msg->value->type)) 28887 return ir_unreach_error(ira); 28888 28889 if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope)) { 28890 ir_add_error(ira, &instruction->base.base, buf_sprintf("encountered @panic at compile-time")); 28891 return ir_unreach_error(ira); 28892 } 28893 28894 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 28895 true, false, PtrLenUnknown, 0, 0, 0, false); 28896 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 28897 IrInstGen *casted_msg = ir_implicit_cast(ira, msg, str_type); 28898 if (type_is_invalid(casted_msg->value->type)) 28899 return ir_unreach_error(ira); 28900 28901 IrInstGen *new_instruction = ir_build_panic_gen(ira, &instruction->base.base, casted_msg); 28902 return ir_finish_anal(ira, new_instruction); 28903 } 28904 28905 static IrInstGen *ir_align_cast(IrAnalyze *ira, IrInstGen *target, uint32_t align_bytes, bool safety_check_on) { 28906 Error err; 28907 28908 ZigType *target_type = target->value->type; 28909 assert(!type_is_invalid(target_type)); 28910 28911 ZigType *result_type; 28912 uint32_t old_align_bytes; 28913 28914 if (target_type->id == ZigTypeIdPointer) { 28915 result_type = adjust_ptr_align(ira->codegen, target_type, align_bytes); 28916 if ((err = resolve_ptr_align(ira, target_type, &old_align_bytes))) 28917 return ira->codegen->invalid_inst_gen; 28918 } else if (target_type->id == ZigTypeIdFn) { 28919 FnTypeId fn_type_id = target_type->data.fn.fn_type_id; 28920 old_align_bytes = fn_type_id.alignment; 28921 fn_type_id.alignment = align_bytes; 28922 result_type = get_fn_type(ira->codegen, &fn_type_id); 28923 } else if (target_type->id == ZigTypeIdAnyFrame) { 28924 if (align_bytes >= target_fn_align(ira->codegen->zig_target)) { 28925 result_type = target_type; 28926 } else { 28927 ir_add_error(ira, &target->base, buf_sprintf("sub-aligned anyframe not allowed")); 28928 return ira->codegen->invalid_inst_gen; 28929 } 28930 } else if (target_type->id == ZigTypeIdOptional && 28931 target_type->data.maybe.child_type->id == ZigTypeIdPointer) 28932 { 28933 ZigType *ptr_type = target_type->data.maybe.child_type; 28934 if ((err = resolve_ptr_align(ira, ptr_type, &old_align_bytes))) 28935 return ira->codegen->invalid_inst_gen; 28936 ZigType *better_ptr_type = adjust_ptr_align(ira->codegen, ptr_type, align_bytes); 28937 28938 result_type = get_optional_type(ira->codegen, better_ptr_type); 28939 } else if (target_type->id == ZigTypeIdOptional && 28940 target_type->data.maybe.child_type->id == ZigTypeIdFn) 28941 { 28942 FnTypeId fn_type_id = target_type->data.maybe.child_type->data.fn.fn_type_id; 28943 old_align_bytes = fn_type_id.alignment; 28944 fn_type_id.alignment = align_bytes; 28945 ZigType *fn_type = get_fn_type(ira->codegen, &fn_type_id); 28946 result_type = get_optional_type(ira->codegen, fn_type); 28947 } else if (is_slice(target_type)) { 28948 ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry; 28949 if ((err = resolve_ptr_align(ira, slice_ptr_type, &old_align_bytes))) 28950 return ira->codegen->invalid_inst_gen; 28951 ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes); 28952 result_type = get_slice_type(ira->codegen, result_ptr_type); 28953 } else { 28954 ir_add_error(ira, &target->base, 28955 buf_sprintf("expected pointer or slice, found '%s'", buf_ptr(&target_type->name))); 28956 return ira->codegen->invalid_inst_gen; 28957 } 28958 28959 if (instr_is_comptime(target)) { 28960 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 28961 if (!val) 28962 return ira->codegen->invalid_inst_gen; 28963 28964 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 28965 val->data.x_ptr.data.hard_coded_addr.addr % align_bytes != 0) 28966 { 28967 ir_add_error(ira, &target->base, 28968 buf_sprintf("pointer address 0x%" ZIG_PRI_x64 " is not aligned to %" PRIu32 " bytes", 28969 val->data.x_ptr.data.hard_coded_addr.addr, align_bytes)); 28970 return ira->codegen->invalid_inst_gen; 28971 } 28972 28973 IrInstGen *result = ir_const(ira, &target->base, result_type); 28974 copy_const_val(ira->codegen, result->value, val); 28975 result->value->type = result_type; 28976 return result; 28977 } 28978 28979 if (safety_check_on && align_bytes > old_align_bytes && align_bytes != 1) { 28980 return ir_build_align_cast_gen(ira, target->base.scope, target->base.source_node, target, result_type); 28981 } else { 28982 return ir_build_cast(ira, &target->base, result_type, target, CastOpNoop); 28983 } 28984 } 28985 28986 static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr, 28987 IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on, 28988 bool keep_bigger_alignment) 28989 { 28990 Error err; 28991 28992 ZigType *src_type = ptr->value->type; 28993 assert(!type_is_invalid(src_type)); 28994 28995 if (src_type == dest_type) { 28996 return ptr; 28997 } 28998 28999 // We have a check for zero bits later so we use get_src_ptr_type to 29000 // validate src_type and dest_type. 29001 29002 ZigType *if_slice_ptr_type; 29003 if (is_slice(src_type)) { 29004 TypeStructField *ptr_field = src_type->data.structure.fields[slice_ptr_index]; 29005 if_slice_ptr_type = resolve_struct_field_type(ira->codegen, ptr_field); 29006 } else { 29007 if_slice_ptr_type = src_type; 29008 29009 ZigType *src_ptr_type = get_src_ptr_type(src_type); 29010 if (src_ptr_type == nullptr) { 29011 ir_add_error(ira, ptr_src, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name))); 29012 return ira->codegen->invalid_inst_gen; 29013 } 29014 } 29015 29016 ZigType *dest_ptr_type = get_src_ptr_type(dest_type); 29017 if (dest_ptr_type == nullptr) { 29018 ir_add_error(ira, dest_type_src, 29019 buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 29020 return ira->codegen->invalid_inst_gen; 29021 } 29022 29023 if (get_ptr_const(ira->codegen, src_type) && !get_ptr_const(ira->codegen, dest_type)) { 29024 ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); 29025 return ira->codegen->invalid_inst_gen; 29026 } 29027 uint32_t dest_align_bytes; 29028 if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) 29029 return ira->codegen->invalid_inst_gen; 29030 29031 uint32_t src_align_bytes = 0; 29032 if (keep_bigger_alignment || dest_align_bytes != 1) { 29033 if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) 29034 return ira->codegen->invalid_inst_gen; 29035 } 29036 29037 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 29038 return ira->codegen->invalid_inst_gen; 29039 29040 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusZeroBitsKnown))) 29041 return ira->codegen->invalid_inst_gen; 29042 29043 if (safety_check_on && 29044 type_has_bits(ira->codegen, dest_type) && 29045 !type_has_bits(ira->codegen, if_slice_ptr_type)) 29046 { 29047 ErrorMsg *msg = ir_add_error(ira, source_instr, 29048 buf_sprintf("'%s' and '%s' do not have the same in-memory representation", 29049 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 29050 add_error_note(ira->codegen, msg, ptr_src->source_node, 29051 buf_sprintf("'%s' has no in-memory bits", buf_ptr(&src_type->name))); 29052 add_error_note(ira->codegen, msg, dest_type_src->source_node, 29053 buf_sprintf("'%s' has in-memory bits", buf_ptr(&dest_type->name))); 29054 return ira->codegen->invalid_inst_gen; 29055 } 29056 29057 // For slices, follow the `ptr` field. 29058 if (is_slice(src_type)) { 29059 TypeStructField *ptr_field = src_type->data.structure.fields[slice_ptr_index]; 29060 IrInstGen *ptr_ref = ir_get_ref(ira, source_instr, ptr, true, false); 29061 IrInstGen *ptr_ptr = ir_analyze_struct_field_ptr(ira, source_instr, ptr_field, ptr_ref, src_type, false); 29062 ptr = ir_get_deref(ira, source_instr, ptr_ptr, nullptr); 29063 } 29064 29065 if (instr_is_comptime(ptr)) { 29066 bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type); 29067 UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad; 29068 ZigValue *val = ir_resolve_const(ira, ptr, is_undef_allowed); 29069 if (val == nullptr) 29070 return ira->codegen->invalid_inst_gen; 29071 29072 if (value_is_comptime(val) && val->special != ConstValSpecialUndef) { 29073 bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull || 29074 (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 29075 val->data.x_ptr.data.hard_coded_addr.addr == 0); 29076 if (is_addr_zero && !dest_allows_addr_zero) { 29077 ir_add_error(ira, source_instr, 29078 buf_sprintf("null pointer casted to type '%s'", buf_ptr(&dest_type->name))); 29079 return ira->codegen->invalid_inst_gen; 29080 } 29081 } 29082 29083 IrInstGen *result; 29084 if (val->data.x_ptr.mut == ConstPtrMutInfer) { 29085 result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); 29086 } else { 29087 result = ir_const(ira, source_instr, dest_type); 29088 } 29089 InferredStructField *isf = (val->type->id == ZigTypeIdPointer) ? 29090 val->type->data.pointer.inferred_struct_field : nullptr; 29091 if (isf == nullptr) { 29092 copy_const_val(ira->codegen, result->value, val); 29093 } else { 29094 // The destination value should have x_ptr struct pointing to underlying struct value 29095 result->value->data.x_ptr.mut = val->data.x_ptr.mut; 29096 TypeStructField *field = find_struct_type_field(isf->inferred_struct_type, isf->field_name); 29097 assert(field != nullptr); 29098 if (field->is_comptime) { 29099 result->value->data.x_ptr.special = ConstPtrSpecialRef; 29100 result->value->data.x_ptr.data.ref.pointee = field->init_val; 29101 } else { 29102 assert(val->data.x_ptr.special == ConstPtrSpecialRef); 29103 result->value->data.x_ptr.special = ConstPtrSpecialBaseStruct; 29104 result->value->data.x_ptr.data.base_struct.struct_val = val->data.x_ptr.data.ref.pointee; 29105 result->value->data.x_ptr.data.base_struct.field_index = field->src_index; 29106 } 29107 result->value->special = ConstValSpecialStatic; 29108 } 29109 result->value->type = dest_type; 29110 29111 // Keep the bigger alignment, it can only help- unless the target is zero bits. 29112 if (keep_bigger_alignment && src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { 29113 result = ir_align_cast(ira, result, src_align_bytes, false); 29114 } 29115 29116 return result; 29117 } 29118 29119 if (src_align_bytes != 0 && dest_align_bytes > src_align_bytes) { 29120 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 29121 add_error_note(ira->codegen, msg, ptr_src->source_node, 29122 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_type->name), src_align_bytes)); 29123 add_error_note(ira->codegen, msg, dest_type_src->source_node, 29124 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&dest_type->name), dest_align_bytes)); 29125 return ira->codegen->invalid_inst_gen; 29126 } 29127 29128 IrInstGen *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); 29129 29130 // Keep the bigger alignment, it can only help- unless the target is zero bits. 29131 IrInstGen *result; 29132 if (keep_bigger_alignment && src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { 29133 result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); 29134 if (type_is_invalid(result->value->type)) 29135 return ira->codegen->invalid_inst_gen; 29136 } else { 29137 result = casted_ptr; 29138 } 29139 return result; 29140 } 29141 29142 static IrInstGen *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstSrcPtrCast *instruction) { 29143 IrInstGen *dest_type_value = instruction->dest_type->child; 29144 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 29145 if (type_is_invalid(dest_type)) 29146 return ira->codegen->invalid_inst_gen; 29147 29148 IrInstGen *ptr = instruction->ptr->child; 29149 ZigType *src_type = ptr->value->type; 29150 if (type_is_invalid(src_type)) 29151 return ira->codegen->invalid_inst_gen; 29152 29153 bool keep_bigger_alignment = true; 29154 return ir_analyze_ptr_cast(ira, &instruction->base.base, ptr, &instruction->ptr->base, 29155 dest_type, &dest_type_value->base, instruction->safety_check_on, keep_bigger_alignment); 29156 } 29157 29158 static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ZigValue *val, size_t len) { 29159 size_t buf_i = 0; 29160 // TODO optimize the buf case 29161 expand_undef_array(codegen, val); 29162 for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) { 29163 ZigValue *elem = &val->data.x_array.data.s_none.elements[elem_i]; 29164 buf_write_value_bytes(codegen, &buf[buf_i], elem); 29165 buf_i += type_size(codegen, elem->type); 29166 } 29167 if (val->type->id == ZigTypeIdArray && val->type->data.array.sentinel != nullptr) { 29168 buf_write_value_bytes(codegen, &buf[buf_i], val->type->data.array.sentinel); 29169 } 29170 } 29171 29172 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val) { 29173 if (val->special == ConstValSpecialUndef) { 29174 expand_undef_struct(codegen, val); 29175 val->special = ConstValSpecialStatic; 29176 } 29177 assert(val->special == ConstValSpecialStatic); 29178 switch (val->type->id) { 29179 case ZigTypeIdInvalid: 29180 case ZigTypeIdMetaType: 29181 case ZigTypeIdOpaque: 29182 case ZigTypeIdBoundFn: 29183 case ZigTypeIdUnreachable: 29184 case ZigTypeIdComptimeFloat: 29185 case ZigTypeIdComptimeInt: 29186 case ZigTypeIdEnumLiteral: 29187 case ZigTypeIdUndefined: 29188 case ZigTypeIdNull: 29189 case ZigTypeIdErrorUnion: 29190 case ZigTypeIdErrorSet: 29191 zig_unreachable(); 29192 case ZigTypeIdVoid: 29193 return; 29194 case ZigTypeIdBool: 29195 buf[0] = val->data.x_bool ? 1 : 0; 29196 return; 29197 case ZigTypeIdInt: 29198 bigint_write_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 29199 codegen->is_big_endian); 29200 return; 29201 case ZigTypeIdEnum: 29202 bigint_write_twos_complement(&val->data.x_enum_tag, buf, 29203 val->type->data.enumeration.tag_int_type->data.integral.bit_count, 29204 codegen->is_big_endian); 29205 return; 29206 case ZigTypeIdFloat: 29207 float_write_ieee597(val, buf, codegen->is_big_endian); 29208 return; 29209 case ZigTypeIdPointer: 29210 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 29211 BigInt bn; 29212 bigint_init_unsigned(&bn, val->data.x_ptr.data.hard_coded_addr.addr); 29213 bigint_write_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, codegen->is_big_endian); 29214 return; 29215 } else { 29216 zig_unreachable(); 29217 } 29218 case ZigTypeIdArray: 29219 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.array.len); 29220 case ZigTypeIdVector: 29221 return buf_write_value_bytes_array(codegen, buf, val, val->type->data.vector.len); 29222 case ZigTypeIdStruct: 29223 switch (val->type->data.structure.layout) { 29224 case ContainerLayoutAuto: 29225 zig_unreachable(); 29226 case ContainerLayoutExtern: { 29227 size_t src_field_count = val->type->data.structure.src_field_count; 29228 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { 29229 TypeStructField *struct_field = val->type->data.structure.fields[field_i]; 29230 if (struct_field->gen_index == SIZE_MAX) 29231 continue; 29232 ZigValue *field_val = val->data.x_struct.fields[field_i]; 29233 size_t offset = struct_field->offset; 29234 buf_write_value_bytes(codegen, buf + offset, field_val); 29235 } 29236 return; 29237 } 29238 case ContainerLayoutPacked: { 29239 size_t src_field_count = val->type->data.structure.src_field_count; 29240 size_t gen_field_count = val->type->data.structure.gen_field_count; 29241 size_t gen_i = 0; 29242 size_t src_i = 0; 29243 size_t offset = 0; 29244 bool is_big_endian = codegen->is_big_endian; 29245 uint8_t child_buf_prealloc[16]; 29246 size_t child_buf_len = 16; 29247 uint8_t *child_buf = child_buf_prealloc; 29248 while (gen_i < gen_field_count) { 29249 size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i]; 29250 if (big_int_byte_count > child_buf_len) { 29251 child_buf = heap::c_allocator.allocate_nonzero<uint8_t>(big_int_byte_count); 29252 child_buf_len = big_int_byte_count; 29253 } 29254 BigInt big_int; 29255 bigint_init_unsigned(&big_int, 0); 29256 size_t used_bits = 0; 29257 while (src_i < src_field_count) { 29258 TypeStructField *field = val->type->data.structure.fields[src_i]; 29259 assert(field->gen_index != SIZE_MAX); 29260 if (field->gen_index != gen_i) 29261 break; 29262 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); 29263 buf_write_value_bytes(codegen, child_buf, val->data.x_struct.fields[src_i]); 29264 BigInt child_val; 29265 bigint_read_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian, 29266 false); 29267 if (is_big_endian) { 29268 BigInt shift_amt; 29269 bigint_init_unsigned(&shift_amt, packed_bits_size); 29270 BigInt shifted; 29271 bigint_shl(&shifted, &big_int, &shift_amt); 29272 bigint_or(&big_int, &shifted, &child_val); 29273 } else { 29274 BigInt shift_amt; 29275 bigint_init_unsigned(&shift_amt, used_bits); 29276 BigInt child_val_shifted; 29277 bigint_shl(&child_val_shifted, &child_val, &shift_amt); 29278 BigInt tmp; 29279 bigint_or(&tmp, &big_int, &child_val_shifted); 29280 big_int = tmp; 29281 used_bits += packed_bits_size; 29282 } 29283 src_i += 1; 29284 } 29285 bigint_write_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian); 29286 offset += big_int_byte_count; 29287 gen_i += 1; 29288 } 29289 return; 29290 } 29291 } 29292 zig_unreachable(); 29293 case ZigTypeIdOptional: 29294 zig_panic("TODO buf_write_value_bytes maybe type"); 29295 case ZigTypeIdFn: 29296 zig_panic("TODO buf_write_value_bytes fn type"); 29297 case ZigTypeIdUnion: 29298 zig_panic("TODO buf_write_value_bytes union type"); 29299 case ZigTypeIdFnFrame: 29300 zig_panic("TODO buf_write_value_bytes async fn frame type"); 29301 case ZigTypeIdAnyFrame: 29302 zig_panic("TODO buf_write_value_bytes anyframe type"); 29303 } 29304 zig_unreachable(); 29305 } 29306 29307 static Error buf_read_value_bytes_array(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, 29308 ZigValue *val, ZigType *elem_type, size_t len) 29309 { 29310 Error err; 29311 uint64_t elem_size = type_size(codegen, elem_type); 29312 29313 switch (val->data.x_array.special) { 29314 case ConstArraySpecialNone: 29315 val->data.x_array.data.s_none.elements = codegen->pass1_arena->allocate<ZigValue>(len); 29316 for (size_t i = 0; i < len; i++) { 29317 ZigValue *elem = &val->data.x_array.data.s_none.elements[i]; 29318 elem->special = ConstValSpecialStatic; 29319 elem->type = elem_type; 29320 if ((err = buf_read_value_bytes(ira, codegen, source_node, buf + (elem_size * i), elem))) 29321 return err; 29322 } 29323 return ErrorNone; 29324 case ConstArraySpecialUndef: 29325 zig_panic("TODO buf_read_value_bytes ConstArraySpecialUndef array type"); 29326 case ConstArraySpecialBuf: 29327 zig_panic("TODO buf_read_value_bytes ConstArraySpecialBuf array type"); 29328 } 29329 zig_unreachable(); 29330 } 29331 29332 static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ZigValue *val) { 29333 Error err; 29334 src_assert(val->special == ConstValSpecialStatic, source_node); 29335 switch (val->type->id) { 29336 case ZigTypeIdInvalid: 29337 case ZigTypeIdMetaType: 29338 case ZigTypeIdOpaque: 29339 case ZigTypeIdBoundFn: 29340 case ZigTypeIdUnreachable: 29341 case ZigTypeIdComptimeFloat: 29342 case ZigTypeIdComptimeInt: 29343 case ZigTypeIdEnumLiteral: 29344 case ZigTypeIdUndefined: 29345 case ZigTypeIdNull: 29346 zig_unreachable(); 29347 case ZigTypeIdVoid: 29348 return ErrorNone; 29349 case ZigTypeIdBool: 29350 val->data.x_bool = (buf[0] != 0); 29351 return ErrorNone; 29352 case ZigTypeIdInt: 29353 bigint_read_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 29354 codegen->is_big_endian, val->type->data.integral.is_signed); 29355 return ErrorNone; 29356 case ZigTypeIdFloat: 29357 float_read_ieee597(val, buf, codegen->is_big_endian); 29358 return ErrorNone; 29359 case ZigTypeIdPointer: 29360 { 29361 val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 29362 BigInt bn; 29363 bigint_read_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, 29364 codegen->is_big_endian, false); 29365 val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_usize(&bn); 29366 return ErrorNone; 29367 } 29368 case ZigTypeIdArray: 29369 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.array.child_type, 29370 val->type->data.array.len); 29371 case ZigTypeIdVector: 29372 return buf_read_value_bytes_array(ira, codegen, source_node, buf, val, val->type->data.vector.elem_type, 29373 val->type->data.vector.len); 29374 case ZigTypeIdEnum: 29375 switch (val->type->data.enumeration.layout) { 29376 case ContainerLayoutAuto: 29377 zig_panic("TODO buf_read_value_bytes enum auto"); 29378 case ContainerLayoutPacked: 29379 zig_panic("TODO buf_read_value_bytes enum packed"); 29380 case ContainerLayoutExtern: { 29381 ZigType *tag_int_type = val->type->data.enumeration.tag_int_type; 29382 src_assert(tag_int_type->id == ZigTypeIdInt, source_node); 29383 bigint_read_twos_complement(&val->data.x_enum_tag, buf, tag_int_type->data.integral.bit_count, 29384 codegen->is_big_endian, tag_int_type->data.integral.is_signed); 29385 return ErrorNone; 29386 } 29387 } 29388 zig_unreachable(); 29389 case ZigTypeIdStruct: 29390 switch (val->type->data.structure.layout) { 29391 case ContainerLayoutAuto: { 29392 switch(val->type->data.structure.special){ 29393 case StructSpecialNone: 29394 case StructSpecialInferredTuple: 29395 case StructSpecialInferredStruct: { 29396 ErrorMsg *msg = opt_ir_add_error_node(ira, codegen, source_node, 29397 buf_sprintf("non-extern, non-packed struct '%s' cannot have its bytes reinterpreted", 29398 buf_ptr(&val->type->name))); 29399 add_error_note(codegen, msg, val->type->data.structure.decl_node, 29400 buf_sprintf("declared here")); 29401 break; 29402 } 29403 case StructSpecialSlice: { 29404 opt_ir_add_error_node(ira, codegen, source_node, 29405 buf_sprintf("slice '%s' cannot have its bytes reinterpreted", 29406 buf_ptr(&val->type->name))); 29407 break; 29408 } 29409 } 29410 return ErrorSemanticAnalyzeFail; 29411 } 29412 case ContainerLayoutExtern: { 29413 size_t src_field_count = val->type->data.structure.src_field_count; 29414 val->data.x_struct.fields = alloc_const_vals_ptrs(codegen, src_field_count); 29415 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) { 29416 ZigValue *field_val = val->data.x_struct.fields[field_i]; 29417 field_val->special = ConstValSpecialStatic; 29418 TypeStructField *struct_field = val->type->data.structure.fields[field_i]; 29419 field_val->type = struct_field->type_entry; 29420 if (struct_field->gen_index == SIZE_MAX) 29421 continue; 29422 size_t offset = struct_field->offset; 29423 uint8_t *new_buf = buf + offset; 29424 if ((err = buf_read_value_bytes(ira, codegen, source_node, new_buf, field_val))) 29425 return err; 29426 } 29427 return ErrorNone; 29428 } 29429 case ContainerLayoutPacked: { 29430 size_t src_field_count = val->type->data.structure.src_field_count; 29431 val->data.x_struct.fields = alloc_const_vals_ptrs(codegen, src_field_count); 29432 size_t gen_field_count = val->type->data.structure.gen_field_count; 29433 size_t gen_i = 0; 29434 size_t src_i = 0; 29435 size_t offset = 0; 29436 bool is_big_endian = codegen->is_big_endian; 29437 uint8_t child_buf_prealloc[16]; 29438 size_t child_buf_len = 16; 29439 uint8_t *child_buf = child_buf_prealloc; 29440 while (gen_i < gen_field_count) { 29441 size_t big_int_byte_count = val->type->data.structure.host_int_bytes[gen_i]; 29442 if (big_int_byte_count > child_buf_len) { 29443 child_buf = heap::c_allocator.allocate_nonzero<uint8_t>(big_int_byte_count); 29444 child_buf_len = big_int_byte_count; 29445 } 29446 BigInt big_int; 29447 bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false); 29448 uint64_t bit_offset = 0; 29449 while (src_i < src_field_count) { 29450 TypeStructField *field = val->type->data.structure.fields[src_i]; 29451 src_assert(field->gen_index != SIZE_MAX, source_node); 29452 if (field->gen_index != gen_i) 29453 break; 29454 ZigValue *field_val = val->data.x_struct.fields[src_i]; 29455 field_val->special = ConstValSpecialStatic; 29456 field_val->type = field->type_entry; 29457 uint32_t packed_bits_size = type_size_bits(codegen, field->type_entry); 29458 29459 BigInt child_val; 29460 if (is_big_endian) { 29461 BigInt packed_bits_size_bi; 29462 bigint_init_unsigned(&packed_bits_size_bi, big_int_byte_count * 8 - packed_bits_size - bit_offset); 29463 BigInt tmp; 29464 bigint_shr(&tmp, &big_int, &packed_bits_size_bi); 29465 bigint_truncate(&child_val, &tmp, packed_bits_size, false); 29466 } else { 29467 BigInt packed_bits_size_bi; 29468 bigint_init_unsigned(&packed_bits_size_bi, packed_bits_size); 29469 bigint_truncate(&child_val, &big_int, packed_bits_size, false); 29470 BigInt tmp; 29471 bigint_shr(&tmp, &big_int, &packed_bits_size_bi); 29472 big_int = tmp; 29473 } 29474 29475 bigint_write_twos_complement(&child_val, child_buf, packed_bits_size, is_big_endian); 29476 if ((err = buf_read_value_bytes(ira, codegen, source_node, child_buf, field_val))) { 29477 return err; 29478 } 29479 29480 bit_offset += packed_bits_size; 29481 src_i += 1; 29482 } 29483 offset += big_int_byte_count; 29484 gen_i += 1; 29485 } 29486 return ErrorNone; 29487 } 29488 } 29489 zig_unreachable(); 29490 case ZigTypeIdOptional: 29491 zig_panic("TODO buf_read_value_bytes maybe type"); 29492 case ZigTypeIdErrorUnion: 29493 zig_panic("TODO buf_read_value_bytes error union"); 29494 case ZigTypeIdErrorSet: 29495 zig_panic("TODO buf_read_value_bytes pure error type"); 29496 case ZigTypeIdFn: 29497 zig_panic("TODO buf_read_value_bytes fn type"); 29498 case ZigTypeIdUnion: 29499 zig_panic("TODO buf_read_value_bytes union type"); 29500 case ZigTypeIdFnFrame: 29501 zig_panic("TODO buf_read_value_bytes async fn frame type"); 29502 case ZigTypeIdAnyFrame: 29503 zig_panic("TODO buf_read_value_bytes anyframe type"); 29504 } 29505 zig_unreachable(); 29506 } 29507 29508 static IrInstGen *ir_analyze_bit_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *value, 29509 ZigType *dest_type) 29510 { 29511 Error err; 29512 29513 ZigType *src_type = value->value->type; 29514 ir_assert(type_can_bit_cast(src_type), source_instr); 29515 ir_assert(type_can_bit_cast(dest_type), source_instr); 29516 29517 if (dest_type->id == ZigTypeIdEnum) { 29518 ErrorMsg *msg = ir_add_error_node(ira, source_instr->source_node, 29519 buf_sprintf("cannot cast a value of type '%s'", buf_ptr(&dest_type->name))); 29520 add_error_note(ira->codegen, msg, source_instr->source_node, 29521 buf_sprintf("use @intToEnum for type coercion")); 29522 return ira->codegen->invalid_inst_gen; 29523 } 29524 29525 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown))) 29526 return ira->codegen->invalid_inst_gen; 29527 29528 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusSizeKnown))) 29529 return ira->codegen->invalid_inst_gen; 29530 29531 const bool src_is_ptr = handle_is_ptr(ira->codegen, src_type); 29532 const bool dest_is_ptr = handle_is_ptr(ira->codegen, dest_type); 29533 29534 const uint64_t dest_size_bytes = type_size(ira->codegen, dest_type); 29535 const uint64_t src_size_bytes = type_size(ira->codegen, src_type); 29536 if (dest_size_bytes != src_size_bytes) { 29537 ir_add_error(ira, source_instr, 29538 buf_sprintf("destination type '%s' has size %" ZIG_PRI_u64 " but source type '%s' has size %" ZIG_PRI_u64, 29539 buf_ptr(&dest_type->name), dest_size_bytes, 29540 buf_ptr(&src_type->name), src_size_bytes)); 29541 return ira->codegen->invalid_inst_gen; 29542 } 29543 29544 const uint64_t dest_size_bits = type_size_bits(ira->codegen, dest_type); 29545 const uint64_t src_size_bits = type_size_bits(ira->codegen, src_type); 29546 if (dest_size_bits != src_size_bits) { 29547 ir_add_error(ira, source_instr, 29548 buf_sprintf("destination type '%s' has %" ZIG_PRI_u64 " bits but source type '%s' has %" ZIG_PRI_u64 " bits", 29549 buf_ptr(&dest_type->name), dest_size_bits, 29550 buf_ptr(&src_type->name), src_size_bits)); 29551 return ira->codegen->invalid_inst_gen; 29552 } 29553 29554 if (instr_is_comptime(value)) { 29555 ZigValue *val = ir_resolve_const(ira, value, UndefBad); 29556 if (!val) 29557 return ira->codegen->invalid_inst_gen; 29558 29559 IrInstGen *result = ir_const(ira, source_instr, dest_type); 29560 uint8_t *buf = heap::c_allocator.allocate_nonzero<uint8_t>(src_size_bytes); 29561 buf_write_value_bytes(ira->codegen, buf, val); 29562 if ((err = buf_read_value_bytes(ira, ira->codegen, source_instr->source_node, buf, result->value))) 29563 return ira->codegen->invalid_inst_gen; 29564 return result; 29565 } 29566 29567 if (dest_is_ptr && !src_is_ptr) { 29568 // Spill the scalar into a local memory location and take its address 29569 value = ir_get_ref(ira, source_instr, value, false, false); 29570 } 29571 29572 return ir_build_bit_cast_gen(ira, source_instr, value, dest_type); 29573 } 29574 29575 static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, 29576 ZigType *ptr_type) 29577 { 29578 Error err; 29579 29580 ir_assert(get_src_ptr_type(ptr_type) != nullptr, source_instr); 29581 ir_assert(type_has_bits(ira->codegen, ptr_type), source_instr); 29582 29583 IrInstGen *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize); 29584 if (type_is_invalid(casted_int->value->type)) 29585 return ira->codegen->invalid_inst_gen; 29586 29587 if (instr_is_comptime(casted_int)) { 29588 ZigValue *val = ir_resolve_const(ira, casted_int, UndefBad); 29589 if (!val) 29590 return ira->codegen->invalid_inst_gen; 29591 29592 uint64_t addr = bigint_as_u64(&val->data.x_bigint); 29593 if (!ptr_allows_addr_zero(ptr_type) && addr == 0) { 29594 ir_add_error(ira, source_instr, 29595 buf_sprintf("pointer type '%s' does not allow address zero", buf_ptr(&ptr_type->name))); 29596 return ira->codegen->invalid_inst_gen; 29597 } 29598 29599 uint32_t align_bytes; 29600 if ((err = resolve_ptr_align(ira, ptr_type, &align_bytes))) 29601 return ira->codegen->invalid_inst_gen; 29602 29603 if (addr != 0 && addr % align_bytes != 0) { 29604 ir_add_error(ira, source_instr, 29605 buf_sprintf("pointer type '%s' requires aligned address", 29606 buf_ptr(&ptr_type->name))); 29607 return ira->codegen->invalid_inst_gen; 29608 } 29609 29610 IrInstGen *result = ir_const(ira, source_instr, ptr_type); 29611 if (ptr_type->id == ZigTypeIdOptional && addr == 0) { 29612 result->value->data.x_ptr.special = ConstPtrSpecialNull; 29613 result->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 29614 } else { 29615 result->value->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 29616 result->value->data.x_ptr.mut = ConstPtrMutRuntimeVar; 29617 result->value->data.x_ptr.data.hard_coded_addr.addr = addr; 29618 } 29619 29620 return result; 29621 } 29622 29623 return ir_build_int_to_ptr_gen(ira, source_instr->scope, source_instr->source_node, casted_int, ptr_type); 29624 } 29625 29626 static IrInstGen *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstSrcIntToPtr *instruction) { 29627 Error err; 29628 IrInstGen *dest_type_value = instruction->dest_type->child; 29629 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 29630 if (type_is_invalid(dest_type)) 29631 return ira->codegen->invalid_inst_gen; 29632 29633 // We explicitly check for the size, so we can use get_src_ptr_type 29634 if (get_src_ptr_type(dest_type) == nullptr) { 29635 ir_add_error(ira, &dest_type_value->base, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 29636 return ira->codegen->invalid_inst_gen; 29637 } 29638 29639 bool has_bits; 29640 if ((err = type_has_bits2(ira->codegen, dest_type, &has_bits))) 29641 return ira->codegen->invalid_inst_gen; 29642 29643 if (!has_bits) { 29644 ir_add_error(ira, &dest_type_value->base, 29645 buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name))); 29646 return ira->codegen->invalid_inst_gen; 29647 } 29648 29649 IrInstGen *target = instruction->target->child; 29650 if (type_is_invalid(target->value->type)) 29651 return ira->codegen->invalid_inst_gen; 29652 29653 return ir_analyze_int_to_ptr(ira, &instruction->base.base, target, dest_type); 29654 } 29655 29656 static IrInstGen *ir_analyze_instruction_decl_ref(IrAnalyze *ira, IrInstSrcDeclRef *instruction) { 29657 IrInstGen *ref_instruction = ir_analyze_decl_ref(ira, &instruction->base.base, instruction->tld); 29658 if (type_is_invalid(ref_instruction->value->type)) { 29659 return ira->codegen->invalid_inst_gen; 29660 } 29661 29662 if (instruction->lval == LValPtr || instruction->lval == LValAssign) { 29663 return ref_instruction; 29664 } else { 29665 return ir_get_deref(ira, &instruction->base.base, ref_instruction, nullptr); 29666 } 29667 } 29668 29669 static IrInstGen *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstSrcPtrToInt *instruction) { 29670 Error err; 29671 IrInstGen *target = instruction->target->child; 29672 if (type_is_invalid(target->value->type)) 29673 return ira->codegen->invalid_inst_gen; 29674 29675 ZigType *usize = ira->codegen->builtin_types.entry_usize; 29676 29677 ZigType *src_ptr_type = get_src_ptr_type(target->value->type); 29678 if (src_ptr_type == nullptr) { 29679 ir_add_error(ira, &target->base, 29680 buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value->type->name))); 29681 return ira->codegen->invalid_inst_gen; 29682 } 29683 29684 bool has_bits; 29685 if ((err = type_has_bits2(ira->codegen, src_ptr_type, &has_bits))) 29686 return ira->codegen->invalid_inst_gen; 29687 29688 if (!has_bits) { 29689 ir_add_error(ira, &target->base, 29690 buf_sprintf("pointer to size 0 type has no address")); 29691 return ira->codegen->invalid_inst_gen; 29692 } 29693 29694 if (instr_is_comptime(target)) { 29695 ZigValue *val = ir_resolve_const(ira, target, UndefBad); 29696 if (!val) 29697 return ira->codegen->invalid_inst_gen; 29698 29699 // Since we've already run this type trough get_src_ptr_type it is 29700 // safe to access the x_ptr fields 29701 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 29702 IrInstGen *result = ir_const(ira, &instruction->base.base, usize); 29703 bigint_init_unsigned(&result->value->data.x_bigint, val->data.x_ptr.data.hard_coded_addr.addr); 29704 result->value->type = usize; 29705 return result; 29706 } else if (val->data.x_ptr.special == ConstPtrSpecialNull) { 29707 IrInstGen *result = ir_const(ira, &instruction->base.base, usize); 29708 bigint_init_unsigned(&result->value->data.x_bigint, 0); 29709 result->value->type = usize; 29710 return result; 29711 } 29712 } 29713 29714 return ir_build_ptr_to_int_gen(ira, &instruction->base.base, target); 29715 } 29716 29717 static IrInstGen *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstSrcPtrType *instruction) { 29718 IrInstGen *result = ir_const(ira, &instruction->base.base, ira->codegen->builtin_types.entry_type); 29719 result->value->special = ConstValSpecialLazy; 29720 29721 LazyValuePtrType *lazy_ptr_type = heap::c_allocator.create<LazyValuePtrType>(); 29722 lazy_ptr_type->ira = ira; ira_ref(ira); 29723 result->value->data.x_lazy = &lazy_ptr_type->base; 29724 lazy_ptr_type->base.id = LazyValueIdPtrType; 29725 29726 if (instruction->sentinel != nullptr) { 29727 if (instruction->ptr_len != PtrLenUnknown) { 29728 ir_add_error(ira, &instruction->base.base, 29729 buf_sprintf("sentinels are only allowed on unknown-length pointers")); 29730 return ira->codegen->invalid_inst_gen; 29731 } 29732 29733 lazy_ptr_type->sentinel = instruction->sentinel->child; 29734 if (ir_resolve_const(ira, lazy_ptr_type->sentinel, LazyOk) == nullptr) 29735 return ira->codegen->invalid_inst_gen; 29736 } 29737 29738 lazy_ptr_type->elem_type = instruction->child_type->child; 29739 if (ir_resolve_type_lazy(ira, lazy_ptr_type->elem_type) == nullptr) 29740 return ira->codegen->invalid_inst_gen; 29741 29742 if (instruction->align_value != nullptr) { 29743 lazy_ptr_type->align_inst = instruction->align_value->child; 29744 if (ir_resolve_const(ira, lazy_ptr_type->align_inst, LazyOk) == nullptr) 29745 return ira->codegen->invalid_inst_gen; 29746 } 29747 29748 lazy_ptr_type->ptr_len = instruction->ptr_len; 29749 lazy_ptr_type->is_const = instruction->is_const; 29750 lazy_ptr_type->is_volatile = instruction->is_volatile; 29751 lazy_ptr_type->is_allowzero = instruction->is_allow_zero; 29752 lazy_ptr_type->bit_offset_in_host = instruction->bit_offset_start; 29753 lazy_ptr_type->host_int_bytes = instruction->host_int_bytes; 29754 29755 return result; 29756 } 29757 29758 static IrInstGen *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstSrcAlignCast *instruction) { 29759 IrInstGen *target = instruction->target->child; 29760 if (type_is_invalid(target->value->type)) 29761 return ira->codegen->invalid_inst_gen; 29762 29763 ZigType *elem_type = nullptr; 29764 if (is_slice(target->value->type)) { 29765 ZigType *slice_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry; 29766 elem_type = slice_ptr_type->data.pointer.child_type; 29767 } else if (target->value->type->id == ZigTypeIdPointer) { 29768 elem_type = target->value->type->data.pointer.child_type; 29769 } 29770 29771 uint32_t align_bytes; 29772 IrInstGen *align_bytes_inst = instruction->align_bytes->child; 29773 if (!ir_resolve_align(ira, align_bytes_inst, elem_type, &align_bytes)) 29774 return ira->codegen->invalid_inst_gen; 29775 29776 IrInstGen *result = ir_align_cast(ira, target, align_bytes, true); 29777 if (type_is_invalid(result->value->type)) 29778 return ira->codegen->invalid_inst_gen; 29779 29780 return result; 29781 } 29782 29783 static IrInstGen *ir_analyze_instruction_opaque_type(IrAnalyze *ira, IrInstSrcOpaqueType *instruction) { 29784 Buf *bare_name = buf_alloc(); 29785 Buf *full_name = get_anon_type_name(ira->codegen, ira->old_irb.exec, "opaque", 29786 instruction->base.base.scope, instruction->base.base.source_node, bare_name); 29787 ZigType *result_type = get_opaque_type(ira->codegen, instruction->base.base.scope, 29788 instruction->base.base.source_node, buf_ptr(full_name), bare_name); 29789 return ir_const_type(ira, &instruction->base.base, result_type); 29790 } 29791 29792 static IrInstGen *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstSrcSetAlignStack *instruction) { 29793 uint32_t align_bytes; 29794 IrInstGen *align_bytes_inst = instruction->align_bytes->child; 29795 if (!ir_resolve_align(ira, align_bytes_inst, nullptr, &align_bytes)) 29796 return ira->codegen->invalid_inst_gen; 29797 29798 if (align_bytes > 256) { 29799 ir_add_error(ira, &instruction->base.base, buf_sprintf("attempt to @setAlignStack(%" PRIu32 "); maximum is 256", align_bytes)); 29800 return ira->codegen->invalid_inst_gen; 29801 } 29802 29803 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 29804 if (fn_entry == nullptr) { 29805 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack outside function")); 29806 return ira->codegen->invalid_inst_gen; 29807 } 29808 if (fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionNaked) { 29809 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack in naked function")); 29810 return ira->codegen->invalid_inst_gen; 29811 } 29812 29813 if (fn_entry->fn_inline == FnInlineAlways) { 29814 ir_add_error(ira, &instruction->base.base, buf_sprintf("@setAlignStack in inline function")); 29815 return ira->codegen->invalid_inst_gen; 29816 } 29817 29818 if (fn_entry->set_alignstack_node != nullptr) { 29819 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 29820 buf_sprintf("alignstack set twice")); 29821 add_error_note(ira->codegen, msg, fn_entry->set_alignstack_node, buf_sprintf("first set here")); 29822 return ira->codegen->invalid_inst_gen; 29823 } 29824 29825 fn_entry->set_alignstack_node = instruction->base.base.source_node; 29826 fn_entry->alignstack_value = align_bytes; 29827 29828 return ir_const_void(ira, &instruction->base.base); 29829 } 29830 29831 static IrInstGen *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstSrcArgType *instruction) { 29832 IrInstGen *fn_type_inst = instruction->fn_type->child; 29833 ZigType *fn_type = ir_resolve_type(ira, fn_type_inst); 29834 if (type_is_invalid(fn_type)) 29835 return ira->codegen->invalid_inst_gen; 29836 29837 IrInstGen *arg_index_inst = instruction->arg_index->child; 29838 uint64_t arg_index; 29839 if (!ir_resolve_usize(ira, arg_index_inst, &arg_index)) 29840 return ira->codegen->invalid_inst_gen; 29841 29842 if (fn_type->id == ZigTypeIdBoundFn) { 29843 fn_type = fn_type->data.bound_fn.fn_type; 29844 arg_index += 1; 29845 } 29846 if (fn_type->id != ZigTypeIdFn) { 29847 ir_add_error(ira, &fn_type_inst->base, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); 29848 return ira->codegen->invalid_inst_gen; 29849 } 29850 29851 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 29852 if (arg_index >= fn_type_id->param_count) { 29853 if (instruction->allow_var) { 29854 // TODO remove this with var args 29855 return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_var); 29856 } 29857 ir_add_error(ira, &arg_index_inst->base, 29858 buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments", 29859 arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count)); 29860 return ira->codegen->invalid_inst_gen; 29861 } 29862 29863 ZigType *result_type = fn_type_id->param_info[arg_index].type; 29864 if (result_type == nullptr) { 29865 // Args are only unresolved if our function is generic. 29866 ir_assert(fn_type->data.fn.is_generic, &instruction->base.base); 29867 29868 if (instruction->allow_var) { 29869 return ir_const_type(ira, &instruction->base.base, ira->codegen->builtin_types.entry_var); 29870 } else { 29871 ir_add_error(ira, &arg_index_inst->base, 29872 buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", 29873 arg_index, buf_ptr(&fn_type->name))); 29874 return ira->codegen->invalid_inst_gen; 29875 } 29876 } 29877 return ir_const_type(ira, &instruction->base.base, result_type); 29878 } 29879 29880 static IrInstGen *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstSrcTagType *instruction) { 29881 Error err; 29882 IrInstGen *target_inst = instruction->target->child; 29883 ZigType *enum_type = ir_resolve_type(ira, target_inst); 29884 if (type_is_invalid(enum_type)) 29885 return ira->codegen->invalid_inst_gen; 29886 29887 if (enum_type->id == ZigTypeIdEnum) { 29888 if ((err = type_resolve(ira->codegen, enum_type, ResolveStatusSizeKnown))) 29889 return ira->codegen->invalid_inst_gen; 29890 29891 return ir_const_type(ira, &instruction->base.base, enum_type->data.enumeration.tag_int_type); 29892 } else if (enum_type->id == ZigTypeIdUnion) { 29893 ZigType *tag_type = ir_resolve_union_tag_type(ira, instruction->target->base.source_node, enum_type); 29894 if (type_is_invalid(tag_type)) 29895 return ira->codegen->invalid_inst_gen; 29896 return ir_const_type(ira, &instruction->base.base, tag_type); 29897 } else { 29898 ir_add_error(ira, &target_inst->base, buf_sprintf("expected enum or union, found '%s'", 29899 buf_ptr(&enum_type->name))); 29900 return ira->codegen->invalid_inst_gen; 29901 } 29902 } 29903 29904 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstGen *op) { 29905 ZigType *operand_type = ir_resolve_type(ira, op); 29906 if (type_is_invalid(operand_type)) 29907 return ira->codegen->builtin_types.entry_invalid; 29908 29909 if (operand_type->id == ZigTypeIdInt || operand_type->id == ZigTypeIdEnum) { 29910 ZigType *int_type; 29911 if (operand_type->id == ZigTypeIdEnum) { 29912 int_type = operand_type->data.enumeration.tag_int_type; 29913 } else { 29914 int_type = operand_type; 29915 } 29916 auto bit_count = int_type->data.integral.bit_count; 29917 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); 29918 29919 if (bit_count > max_atomic_bits) { 29920 ir_add_error(ira, &op->base, 29921 buf_sprintf("expected %" PRIu32 "-bit integer type or smaller, found %" PRIu32 "-bit integer type", 29922 max_atomic_bits, bit_count)); 29923 return ira->codegen->builtin_types.entry_invalid; 29924 } 29925 } else if (operand_type->id == ZigTypeIdFloat) { 29926 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch); 29927 if (operand_type->data.floating.bit_count > max_atomic_bits) { 29928 ir_add_error(ira, &op->base, 29929 buf_sprintf("expected %" PRIu32 "-bit float or smaller, found %" PRIu32 "-bit float", 29930 max_atomic_bits, (uint32_t) operand_type->data.floating.bit_count)); 29931 return ira->codegen->builtin_types.entry_invalid; 29932 } 29933 } else if (operand_type->id == ZigTypeIdBool) { 29934 // will be treated as u8 29935 } else { 29936 Error err; 29937 ZigType *operand_ptr_type; 29938 if ((err = get_codegen_ptr_type(ira->codegen, operand_type, &operand_ptr_type))) 29939 return ira->codegen->builtin_types.entry_invalid; 29940 if (operand_ptr_type == nullptr) { 29941 ir_add_error(ira, &op->base, 29942 buf_sprintf("expected integer, float, enum or pointer type, found '%s'", 29943 buf_ptr(&operand_type->name))); 29944 return ira->codegen->builtin_types.entry_invalid; 29945 } 29946 } 29947 29948 return operand_type; 29949 } 29950 29951 static IrInstGen *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstSrcAtomicRmw *instruction) { 29952 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 29953 if (type_is_invalid(operand_type)) 29954 return ira->codegen->invalid_inst_gen; 29955 29956 IrInstGen *ptr_inst = instruction->ptr->child; 29957 if (type_is_invalid(ptr_inst->value->type)) 29958 return ira->codegen->invalid_inst_gen; 29959 29960 // TODO let this be volatile 29961 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 29962 IrInstGen *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 29963 if (type_is_invalid(casted_ptr->value->type)) 29964 return ira->codegen->invalid_inst_gen; 29965 29966 AtomicRmwOp op; 29967 if (!ir_resolve_atomic_rmw_op(ira, instruction->op->child, &op)) { 29968 return ira->codegen->invalid_inst_gen; 29969 } 29970 29971 if (operand_type->id == ZigTypeIdEnum && op != AtomicRmwOp_xchg) { 29972 ir_add_error(ira, &instruction->op->base, 29973 buf_sprintf("@atomicRmw with enum only allowed with .Xchg")); 29974 return ira->codegen->invalid_inst_gen; 29975 } else if (operand_type->id == ZigTypeIdBool && op != AtomicRmwOp_xchg) { 29976 ir_add_error(ira, &instruction->op->base, 29977 buf_sprintf("@atomicRmw with bool only allowed with .Xchg")); 29978 return ira->codegen->invalid_inst_gen; 29979 } else if (operand_type->id == ZigTypeIdFloat && op > AtomicRmwOp_sub) { 29980 ir_add_error(ira, &instruction->op->base, 29981 buf_sprintf("@atomicRmw with float only allowed with .Xchg, .Add and .Sub")); 29982 return ira->codegen->invalid_inst_gen; 29983 } 29984 29985 IrInstGen *operand = instruction->operand->child; 29986 if (type_is_invalid(operand->value->type)) 29987 return ira->codegen->invalid_inst_gen; 29988 29989 IrInstGen *casted_operand = ir_implicit_cast(ira, operand, operand_type); 29990 if (type_is_invalid(casted_operand->value->type)) 29991 return ira->codegen->invalid_inst_gen; 29992 29993 AtomicOrder ordering; 29994 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 29995 return ira->codegen->invalid_inst_gen; 29996 if (ordering == AtomicOrderUnordered) { 29997 ir_add_error(ira, &instruction->ordering->base, 29998 buf_sprintf("@atomicRmw atomic ordering must not be Unordered")); 29999 return ira->codegen->invalid_inst_gen; 30000 } 30001 30002 // special case zero bit types 30003 switch (type_has_one_possible_value(ira->codegen, operand_type)) { 30004 case OnePossibleValueInvalid: 30005 return ira->codegen->invalid_inst_gen; 30006 case OnePossibleValueYes: 30007 return ir_const_move(ira, &instruction->base.base, get_the_one_possible_value(ira->codegen, operand_type)); 30008 case OnePossibleValueNo: 30009 break; 30010 } 30011 30012 IrInst *source_inst = &instruction->base.base; 30013 if (instr_is_comptime(casted_operand) && instr_is_comptime(casted_ptr) && casted_ptr->value->data.x_ptr.mut == ConstPtrMutComptimeVar) { 30014 ZigValue *ptr_val = ir_resolve_const(ira, casted_ptr, UndefBad); 30015 if (ptr_val == nullptr) 30016 return ira->codegen->invalid_inst_gen; 30017 30018 ZigValue *op1_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.base.source_node); 30019 if (op1_val == nullptr) 30020 return ira->codegen->invalid_inst_gen; 30021 30022 ZigValue *op2_val = ir_resolve_const(ira, casted_operand, UndefBad); 30023 if (op2_val == nullptr) 30024 return ira->codegen->invalid_inst_gen; 30025 30026 IrInstGen *result = ir_const(ira, source_inst, operand_type); 30027 copy_const_val(ira->codegen, result->value, op1_val); 30028 if (op == AtomicRmwOp_xchg) { 30029 copy_const_val(ira->codegen, op1_val, op2_val); 30030 return result; 30031 } 30032 30033 if (operand_type->id == ZigTypeIdPointer || operand_type->id == ZigTypeIdOptional) { 30034 ir_add_error(ira, &instruction->ordering->base, 30035 buf_sprintf("TODO comptime @atomicRmw with pointers other than .Xchg")); 30036 return ira->codegen->invalid_inst_gen; 30037 } 30038 30039 ErrorMsg *msg; 30040 if (op == AtomicRmwOp_min || op == AtomicRmwOp_max) { 30041 IrBinOp bin_op; 30042 if (op == AtomicRmwOp_min) 30043 // store op2 if op2 < op1 30044 bin_op = IrBinOpCmpGreaterThan; 30045 else 30046 // store op2 if op2 > op1 30047 bin_op = IrBinOpCmpLessThan; 30048 30049 IrInstGen *dummy_value = ir_const(ira, source_inst, operand_type); 30050 msg = ir_eval_bin_op_cmp_scalar(ira, source_inst, op1_val, bin_op, op2_val, dummy_value->value); 30051 if (msg != nullptr) { 30052 return ira->codegen->invalid_inst_gen; 30053 } 30054 if (dummy_value->value->data.x_bool) 30055 copy_const_val(ira->codegen, op1_val, op2_val); 30056 } else { 30057 IrBinOp bin_op; 30058 switch (op) { 30059 case AtomicRmwOp_xchg: 30060 case AtomicRmwOp_max: 30061 case AtomicRmwOp_min: 30062 zig_unreachable(); 30063 case AtomicRmwOp_add: 30064 if (operand_type->id == ZigTypeIdFloat) 30065 bin_op = IrBinOpAdd; 30066 else 30067 bin_op = IrBinOpAddWrap; 30068 break; 30069 case AtomicRmwOp_sub: 30070 if (operand_type->id == ZigTypeIdFloat) 30071 bin_op = IrBinOpSub; 30072 else 30073 bin_op = IrBinOpSubWrap; 30074 break; 30075 case AtomicRmwOp_and: 30076 case AtomicRmwOp_nand: 30077 bin_op = IrBinOpBinAnd; 30078 break; 30079 case AtomicRmwOp_or: 30080 bin_op = IrBinOpBinOr; 30081 break; 30082 case AtomicRmwOp_xor: 30083 bin_op = IrBinOpBinXor; 30084 break; 30085 } 30086 msg = ir_eval_math_op_scalar(ira, source_inst, operand_type, op1_val, bin_op, op2_val, op1_val); 30087 if (msg != nullptr) { 30088 return ira->codegen->invalid_inst_gen; 30089 } 30090 if (op == AtomicRmwOp_nand) { 30091 bigint_not(&op1_val->data.x_bigint, &op1_val->data.x_bigint, 30092 operand_type->data.integral.bit_count, operand_type->data.integral.is_signed); 30093 } 30094 } 30095 return result; 30096 } 30097 30098 return ir_build_atomic_rmw_gen(ira, source_inst, casted_ptr, casted_operand, op, 30099 ordering, operand_type); 30100 } 30101 30102 static IrInstGen *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstSrcAtomicLoad *instruction) { 30103 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 30104 if (type_is_invalid(operand_type)) 30105 return ira->codegen->invalid_inst_gen; 30106 30107 IrInstGen *ptr_inst = instruction->ptr->child; 30108 if (type_is_invalid(ptr_inst->value->type)) 30109 return ira->codegen->invalid_inst_gen; 30110 30111 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, true); 30112 IrInstGen *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 30113 if (type_is_invalid(casted_ptr->value->type)) 30114 return ira->codegen->invalid_inst_gen; 30115 30116 AtomicOrder ordering; 30117 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 30118 return ira->codegen->invalid_inst_gen; 30119 30120 if (ordering == AtomicOrderRelease || ordering == AtomicOrderAcqRel) { 30121 ir_assert(instruction->ordering != nullptr, &instruction->base.base); 30122 ir_add_error(ira, &instruction->ordering->base, 30123 buf_sprintf("@atomicLoad atomic ordering must not be Release or AcqRel")); 30124 return ira->codegen->invalid_inst_gen; 30125 } 30126 30127 if (instr_is_comptime(casted_ptr)) { 30128 IrInstGen *result = ir_get_deref(ira, &instruction->base.base, casted_ptr, nullptr); 30129 ir_assert(result->value->type != nullptr, &instruction->base.base); 30130 return result; 30131 } 30132 30133 return ir_build_atomic_load_gen(ira, &instruction->base.base, casted_ptr, ordering, operand_type); 30134 } 30135 30136 static IrInstGen *ir_analyze_instruction_atomic_store(IrAnalyze *ira, IrInstSrcAtomicStore *instruction) { 30137 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 30138 if (type_is_invalid(operand_type)) 30139 return ira->codegen->invalid_inst_gen; 30140 30141 IrInstGen *ptr_inst = instruction->ptr->child; 30142 if (type_is_invalid(ptr_inst->value->type)) 30143 return ira->codegen->invalid_inst_gen; 30144 30145 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 30146 IrInstGen *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 30147 if (type_is_invalid(casted_ptr->value->type)) 30148 return ira->codegen->invalid_inst_gen; 30149 30150 IrInstGen *value = instruction->value->child; 30151 if (type_is_invalid(value->value->type)) 30152 return ira->codegen->invalid_inst_gen; 30153 30154 IrInstGen *casted_value = ir_implicit_cast(ira, value, operand_type); 30155 if (type_is_invalid(casted_value->value->type)) 30156 return ira->codegen->invalid_inst_gen; 30157 30158 30159 AtomicOrder ordering; 30160 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 30161 return ira->codegen->invalid_inst_gen; 30162 30163 if (ordering == AtomicOrderAcquire || ordering == AtomicOrderAcqRel) { 30164 ir_assert(instruction->ordering != nullptr, &instruction->base.base); 30165 ir_add_error(ira, &instruction->ordering->base, 30166 buf_sprintf("@atomicStore atomic ordering must not be Acquire or AcqRel")); 30167 return ira->codegen->invalid_inst_gen; 30168 } 30169 30170 // special case zero bit types 30171 switch (type_has_one_possible_value(ira->codegen, operand_type)) { 30172 case OnePossibleValueInvalid: 30173 return ira->codegen->invalid_inst_gen; 30174 case OnePossibleValueYes: 30175 return ir_const_void(ira, &instruction->base.base); 30176 case OnePossibleValueNo: 30177 break; 30178 } 30179 30180 if (instr_is_comptime(casted_value) && instr_is_comptime(casted_ptr)) { 30181 IrInstGen *result = ir_analyze_store_ptr(ira, &instruction->base.base, casted_ptr, value, false); 30182 result->value->type = ira->codegen->builtin_types.entry_void; 30183 return result; 30184 } 30185 30186 return ir_build_atomic_store_gen(ira, &instruction->base.base, casted_ptr, casted_value, ordering); 30187 } 30188 30189 static IrInstGen *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstSrcSaveErrRetAddr *instruction) { 30190 return ir_build_save_err_ret_addr_gen(ira, &instruction->base.base); 30191 } 30192 30193 static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, IrInst* source_instr, BuiltinFnId fop, ZigType *float_type, 30194 ZigValue *op, ZigValue *out_val) 30195 { 30196 assert(ira && source_instr && float_type && out_val && op); 30197 assert(float_type->id == ZigTypeIdFloat || 30198 float_type->id == ZigTypeIdComptimeFloat); 30199 30200 unsigned bits; 30201 30202 switch (float_type->id) { 30203 case ZigTypeIdComptimeFloat: 30204 bits = 128; 30205 break; 30206 case ZigTypeIdFloat: 30207 bits = float_type->data.floating.bit_count; 30208 break; 30209 default: 30210 zig_unreachable(); 30211 } 30212 30213 switch (bits) { 30214 case 16: { 30215 switch (fop) { 30216 case BuiltinFnIdSqrt: 30217 out_val->data.x_f16 = f16_sqrt(op->data.x_f16); 30218 break; 30219 case BuiltinFnIdSin: 30220 out_val->data.x_f16 = zig_double_to_f16(sin(zig_f16_to_double(op->data.x_f16))); 30221 break; 30222 case BuiltinFnIdCos: 30223 out_val->data.x_f16 = zig_double_to_f16(cos(zig_f16_to_double(op->data.x_f16))); 30224 break; 30225 case BuiltinFnIdExp: 30226 out_val->data.x_f16 = zig_double_to_f16(exp(zig_f16_to_double(op->data.x_f16))); 30227 break; 30228 case BuiltinFnIdExp2: 30229 out_val->data.x_f16 = zig_double_to_f16(exp2(zig_f16_to_double(op->data.x_f16))); 30230 break; 30231 case BuiltinFnIdLog: 30232 out_val->data.x_f16 = zig_double_to_f16(log(zig_f16_to_double(op->data.x_f16))); 30233 break; 30234 case BuiltinFnIdLog10: 30235 out_val->data.x_f16 = zig_double_to_f16(log10(zig_f16_to_double(op->data.x_f16))); 30236 break; 30237 case BuiltinFnIdLog2: 30238 out_val->data.x_f16 = zig_double_to_f16(log2(zig_f16_to_double(op->data.x_f16))); 30239 break; 30240 case BuiltinFnIdFabs: 30241 out_val->data.x_f16 = zig_double_to_f16(fabs(zig_f16_to_double(op->data.x_f16))); 30242 break; 30243 case BuiltinFnIdFloor: 30244 out_val->data.x_f16 = zig_double_to_f16(floor(zig_f16_to_double(op->data.x_f16))); 30245 break; 30246 case BuiltinFnIdCeil: 30247 out_val->data.x_f16 = zig_double_to_f16(ceil(zig_f16_to_double(op->data.x_f16))); 30248 break; 30249 case BuiltinFnIdTrunc: 30250 out_val->data.x_f16 = zig_double_to_f16(trunc(zig_f16_to_double(op->data.x_f16))); 30251 break; 30252 case BuiltinFnIdNearbyInt: 30253 out_val->data.x_f16 = zig_double_to_f16(nearbyint(zig_f16_to_double(op->data.x_f16))); 30254 break; 30255 case BuiltinFnIdRound: 30256 out_val->data.x_f16 = zig_double_to_f16(round(zig_f16_to_double(op->data.x_f16))); 30257 break; 30258 default: 30259 zig_unreachable(); 30260 }; 30261 break; 30262 } 30263 case 32: { 30264 switch (fop) { 30265 case BuiltinFnIdSqrt: 30266 out_val->data.x_f32 = sqrtf(op->data.x_f32); 30267 break; 30268 case BuiltinFnIdSin: 30269 out_val->data.x_f32 = sinf(op->data.x_f32); 30270 break; 30271 case BuiltinFnIdCos: 30272 out_val->data.x_f32 = cosf(op->data.x_f32); 30273 break; 30274 case BuiltinFnIdExp: 30275 out_val->data.x_f32 = expf(op->data.x_f32); 30276 break; 30277 case BuiltinFnIdExp2: 30278 out_val->data.x_f32 = exp2f(op->data.x_f32); 30279 break; 30280 case BuiltinFnIdLog: 30281 out_val->data.x_f32 = logf(op->data.x_f32); 30282 break; 30283 case BuiltinFnIdLog10: 30284 out_val->data.x_f32 = log10f(op->data.x_f32); 30285 break; 30286 case BuiltinFnIdLog2: 30287 out_val->data.x_f32 = log2f(op->data.x_f32); 30288 break; 30289 case BuiltinFnIdFabs: 30290 out_val->data.x_f32 = fabsf(op->data.x_f32); 30291 break; 30292 case BuiltinFnIdFloor: 30293 out_val->data.x_f32 = floorf(op->data.x_f32); 30294 break; 30295 case BuiltinFnIdCeil: 30296 out_val->data.x_f32 = ceilf(op->data.x_f32); 30297 break; 30298 case BuiltinFnIdTrunc: 30299 out_val->data.x_f32 = truncf(op->data.x_f32); 30300 break; 30301 case BuiltinFnIdNearbyInt: 30302 out_val->data.x_f32 = nearbyintf(op->data.x_f32); 30303 break; 30304 case BuiltinFnIdRound: 30305 out_val->data.x_f32 = roundf(op->data.x_f32); 30306 break; 30307 default: 30308 zig_unreachable(); 30309 }; 30310 break; 30311 } 30312 case 64: { 30313 switch (fop) { 30314 case BuiltinFnIdSqrt: 30315 out_val->data.x_f64 = sqrt(op->data.x_f64); 30316 break; 30317 case BuiltinFnIdSin: 30318 out_val->data.x_f64 = sin(op->data.x_f64); 30319 break; 30320 case BuiltinFnIdCos: 30321 out_val->data.x_f64 = cos(op->data.x_f64); 30322 break; 30323 case BuiltinFnIdExp: 30324 out_val->data.x_f64 = exp(op->data.x_f64); 30325 break; 30326 case BuiltinFnIdExp2: 30327 out_val->data.x_f64 = exp2(op->data.x_f64); 30328 break; 30329 case BuiltinFnIdLog: 30330 out_val->data.x_f64 = log(op->data.x_f64); 30331 break; 30332 case BuiltinFnIdLog10: 30333 out_val->data.x_f64 = log10(op->data.x_f64); 30334 break; 30335 case BuiltinFnIdLog2: 30336 out_val->data.x_f64 = log2(op->data.x_f64); 30337 break; 30338 case BuiltinFnIdFabs: 30339 out_val->data.x_f64 = fabs(op->data.x_f64); 30340 break; 30341 case BuiltinFnIdFloor: 30342 out_val->data.x_f64 = floor(op->data.x_f64); 30343 break; 30344 case BuiltinFnIdCeil: 30345 out_val->data.x_f64 = ceil(op->data.x_f64); 30346 break; 30347 case BuiltinFnIdTrunc: 30348 out_val->data.x_f64 = trunc(op->data.x_f64); 30349 break; 30350 case BuiltinFnIdNearbyInt: 30351 out_val->data.x_f64 = nearbyint(op->data.x_f64); 30352 break; 30353 case BuiltinFnIdRound: 30354 out_val->data.x_f64 = round(op->data.x_f64); 30355 break; 30356 default: 30357 zig_unreachable(); 30358 } 30359 break; 30360 } 30361 case 80: 30362 return ir_add_error(ira, source_instr, 30363 buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026", 30364 float_op_to_name(fop), buf_ptr(&float_type->name))); 30365 case 128: { 30366 float128_t *out, *in; 30367 if (float_type->id == ZigTypeIdComptimeFloat) { 30368 out = &out_val->data.x_bigfloat.value; 30369 in = &op->data.x_bigfloat.value; 30370 } else { 30371 out = &out_val->data.x_f128; 30372 in = &op->data.x_f128; 30373 } 30374 switch (fop) { 30375 case BuiltinFnIdSqrt: 30376 f128M_sqrt(in, out); 30377 break; 30378 case BuiltinFnIdFabs: 30379 f128M_abs(in, out); 30380 break; 30381 case BuiltinFnIdFloor: 30382 f128M_roundToInt(in, softfloat_round_min, false, out); 30383 break; 30384 case BuiltinFnIdCeil: 30385 f128M_roundToInt(in, softfloat_round_max, false, out); 30386 break; 30387 case BuiltinFnIdTrunc: 30388 f128M_trunc(in, out); 30389 break; 30390 case BuiltinFnIdRound: 30391 f128M_roundToInt(in, softfloat_round_near_maxMag, false, out); 30392 break; 30393 case BuiltinFnIdNearbyInt: 30394 case BuiltinFnIdSin: 30395 case BuiltinFnIdCos: 30396 case BuiltinFnIdExp: 30397 case BuiltinFnIdExp2: 30398 case BuiltinFnIdLog: 30399 case BuiltinFnIdLog10: 30400 case BuiltinFnIdLog2: 30401 return ir_add_error(ira, source_instr, 30402 buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026", 30403 float_op_to_name(fop), buf_ptr(&float_type->name))); 30404 default: 30405 zig_unreachable(); 30406 } 30407 break; 30408 } 30409 default: 30410 zig_unreachable(); 30411 } 30412 out_val->special = ConstValSpecialStatic; 30413 return nullptr; 30414 } 30415 30416 static IrInstGen *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstSrcFloatOp *instruction) { 30417 IrInstGen *operand = instruction->operand->child; 30418 ZigType *operand_type = operand->value->type; 30419 if (type_is_invalid(operand_type)) 30420 return ira->codegen->invalid_inst_gen; 30421 30422 // This instruction accepts floats and vectors of floats. 30423 ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ? 30424 operand_type->data.vector.elem_type : operand_type; 30425 30426 if (scalar_type->id != ZigTypeIdFloat && scalar_type->id != ZigTypeIdComptimeFloat) { 30427 ir_add_error(ira, &operand->base, 30428 buf_sprintf("expected float type, found '%s'", buf_ptr(&scalar_type->name))); 30429 return ira->codegen->invalid_inst_gen; 30430 } 30431 30432 if (instr_is_comptime(operand)) { 30433 ZigValue *operand_val = ir_resolve_const(ira, operand, UndefOk); 30434 if (operand_val == nullptr) 30435 return ira->codegen->invalid_inst_gen; 30436 if (operand_val->special == ConstValSpecialUndef) 30437 return ir_const_undef(ira, &instruction->base.base, operand_type); 30438 30439 IrInstGen *result = ir_const(ira, &instruction->base.base, operand_type); 30440 ZigValue *out_val = result->value; 30441 30442 if (operand_type->id == ZigTypeIdVector) { 30443 expand_undef_array(ira->codegen, operand_val); 30444 out_val->special = ConstValSpecialUndef; 30445 expand_undef_array(ira->codegen, out_val); 30446 size_t len = operand_type->data.vector.len; 30447 for (size_t i = 0; i < len; i += 1) { 30448 ZigValue *elem_operand = &operand_val->data.x_array.data.s_none.elements[i]; 30449 ZigValue *float_out_val = &out_val->data.x_array.data.s_none.elements[i]; 30450 ir_assert(elem_operand->type == scalar_type, &instruction->base.base); 30451 ir_assert(float_out_val->type == scalar_type, &instruction->base.base); 30452 ErrorMsg *msg = ir_eval_float_op(ira, &instruction->base.base, instruction->fn_id, scalar_type, 30453 elem_operand, float_out_val); 30454 if (msg != nullptr) { 30455 add_error_note(ira->codegen, msg, instruction->base.base.source_node, 30456 buf_sprintf("when computing vector element at index %" ZIG_PRI_usize, i)); 30457 return ira->codegen->invalid_inst_gen; 30458 } 30459 float_out_val->type = scalar_type; 30460 } 30461 out_val->type = operand_type; 30462 out_val->special = ConstValSpecialStatic; 30463 } else { 30464 if (ir_eval_float_op(ira, &instruction->base.base, instruction->fn_id, scalar_type, 30465 operand_val, out_val) != nullptr) 30466 { 30467 return ira->codegen->invalid_inst_gen; 30468 } 30469 } 30470 return result; 30471 } 30472 30473 ir_assert(scalar_type->id == ZigTypeIdFloat, &instruction->base.base); 30474 30475 return ir_build_float_op_gen(ira, &instruction->base.base, operand, instruction->fn_id, operand_type); 30476 } 30477 30478 static IrInstGen *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstSrcBswap *instruction) { 30479 Error err; 30480 30481 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 30482 if (type_is_invalid(int_type)) 30483 return ira->codegen->invalid_inst_gen; 30484 30485 IrInstGen *uncasted_op = instruction->op->child; 30486 if (type_is_invalid(uncasted_op->value->type)) 30487 return ira->codegen->invalid_inst_gen; 30488 30489 uint32_t vector_len = UINT32_MAX; // means not a vector 30490 if (uncasted_op->value->type->id == ZigTypeIdArray) { 30491 bool can_be_vec_elem; 30492 if ((err = is_valid_vector_elem_type(ira->codegen, uncasted_op->value->type->data.array.child_type, 30493 &can_be_vec_elem))) 30494 { 30495 return ira->codegen->invalid_inst_gen; 30496 } 30497 if (can_be_vec_elem) { 30498 vector_len = uncasted_op->value->type->data.array.len; 30499 } 30500 } else if (uncasted_op->value->type->id == ZigTypeIdVector) { 30501 vector_len = uncasted_op->value->type->data.vector.len; 30502 } 30503 30504 bool is_vector = (vector_len != UINT32_MAX); 30505 ZigType *op_type = is_vector ? get_vector_type(ira->codegen, vector_len, int_type) : int_type; 30506 30507 IrInstGen *op = ir_implicit_cast(ira, uncasted_op, op_type); 30508 if (type_is_invalid(op->value->type)) 30509 return ira->codegen->invalid_inst_gen; 30510 30511 if (int_type->data.integral.bit_count == 8 || int_type->data.integral.bit_count == 0) 30512 return op; 30513 30514 if (int_type->data.integral.bit_count % 8 != 0) { 30515 ir_add_error(ira, &instruction->op->base, 30516 buf_sprintf("@byteSwap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8", 30517 buf_ptr(&int_type->name), int_type->data.integral.bit_count)); 30518 return ira->codegen->invalid_inst_gen; 30519 } 30520 30521 if (instr_is_comptime(op)) { 30522 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 30523 if (val == nullptr) 30524 return ira->codegen->invalid_inst_gen; 30525 if (val->special == ConstValSpecialUndef) 30526 return ir_const_undef(ira, &instruction->base.base, op_type); 30527 30528 IrInstGen *result = ir_const(ira, &instruction->base.base, op_type); 30529 const size_t buf_size = int_type->data.integral.bit_count / 8; 30530 uint8_t *buf = heap::c_allocator.allocate_nonzero<uint8_t>(buf_size); 30531 if (is_vector) { 30532 expand_undef_array(ira->codegen, val); 30533 result->value->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(op_type->data.vector.len); 30534 for (unsigned i = 0; i < op_type->data.vector.len; i += 1) { 30535 ZigValue *op_elem_val = &val->data.x_array.data.s_none.elements[i]; 30536 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, instruction->base.base.source_node, 30537 op_elem_val, UndefOk))) 30538 { 30539 return ira->codegen->invalid_inst_gen; 30540 } 30541 ZigValue *result_elem_val = &result->value->data.x_array.data.s_none.elements[i]; 30542 result_elem_val->type = int_type; 30543 result_elem_val->special = op_elem_val->special; 30544 if (op_elem_val->special == ConstValSpecialUndef) 30545 continue; 30546 30547 bigint_write_twos_complement(&op_elem_val->data.x_bigint, buf, int_type->data.integral.bit_count, true); 30548 bigint_read_twos_complement(&result->value->data.x_array.data.s_none.elements[i].data.x_bigint, 30549 buf, int_type->data.integral.bit_count, false, 30550 int_type->data.integral.is_signed); 30551 } 30552 } else { 30553 bigint_write_twos_complement(&val->data.x_bigint, buf, int_type->data.integral.bit_count, true); 30554 bigint_read_twos_complement(&result->value->data.x_bigint, buf, int_type->data.integral.bit_count, false, 30555 int_type->data.integral.is_signed); 30556 } 30557 heap::c_allocator.deallocate(buf, buf_size); 30558 return result; 30559 } 30560 30561 return ir_build_bswap_gen(ira, &instruction->base.base, op_type, op); 30562 } 30563 30564 static IrInstGen *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstSrcBitReverse *instruction) { 30565 ZigType *int_type = ir_resolve_int_type(ira, instruction->type->child); 30566 if (type_is_invalid(int_type)) 30567 return ira->codegen->invalid_inst_gen; 30568 30569 IrInstGen *op = ir_implicit_cast(ira, instruction->op->child, int_type); 30570 if (type_is_invalid(op->value->type)) 30571 return ira->codegen->invalid_inst_gen; 30572 30573 if (int_type->data.integral.bit_count == 0) { 30574 IrInstGen *result = ir_const(ira, &instruction->base.base, int_type); 30575 bigint_init_unsigned(&result->value->data.x_bigint, 0); 30576 return result; 30577 } 30578 30579 if (instr_is_comptime(op)) { 30580 ZigValue *val = ir_resolve_const(ira, op, UndefOk); 30581 if (val == nullptr) 30582 return ira->codegen->invalid_inst_gen; 30583 if (val->special == ConstValSpecialUndef) 30584 return ir_const_undef(ira, &instruction->base.base, int_type); 30585 30586 IrInstGen *result = ir_const(ira, &instruction->base.base, int_type); 30587 size_t num_bits = int_type->data.integral.bit_count; 30588 size_t buf_size = (num_bits + 7) / 8; 30589 uint8_t *comptime_buf = heap::c_allocator.allocate_nonzero<uint8_t>(buf_size); 30590 uint8_t *result_buf = heap::c_allocator.allocate_nonzero<uint8_t>(buf_size); 30591 memset(comptime_buf,0,buf_size); 30592 memset(result_buf,0,buf_size); 30593 30594 bigint_write_twos_complement(&val->data.x_bigint,comptime_buf,num_bits,ira->codegen->is_big_endian); 30595 30596 size_t bit_i = 0; 30597 size_t bit_rev_i = num_bits - 1; 30598 for (; bit_i < num_bits; bit_i++, bit_rev_i--) { 30599 if (comptime_buf[bit_i / 8] & (1 << (bit_i % 8))) { 30600 result_buf[bit_rev_i / 8] |= (1 << (bit_rev_i % 8)); 30601 } 30602 } 30603 30604 bigint_read_twos_complement(&result->value->data.x_bigint, 30605 result_buf, 30606 int_type->data.integral.bit_count, 30607 ira->codegen->is_big_endian, 30608 int_type->data.integral.is_signed); 30609 30610 return result; 30611 } 30612 30613 return ir_build_bit_reverse_gen(ira, &instruction->base.base, int_type, op); 30614 } 30615 30616 30617 static IrInstGen *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstSrcEnumToInt *instruction) { 30618 IrInstGen *target = instruction->target->child; 30619 if (type_is_invalid(target->value->type)) 30620 return ira->codegen->invalid_inst_gen; 30621 30622 return ir_analyze_enum_to_int(ira, &instruction->base.base, target); 30623 } 30624 30625 static IrInstGen *ir_analyze_instruction_int_to_enum(IrAnalyze *ira, IrInstSrcIntToEnum *instruction) { 30626 Error err; 30627 IrInstGen *dest_type_value = instruction->dest_type->child; 30628 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 30629 if (type_is_invalid(dest_type)) 30630 return ira->codegen->invalid_inst_gen; 30631 30632 if (dest_type->id != ZigTypeIdEnum) { 30633 ir_add_error(ira, &instruction->dest_type->base, 30634 buf_sprintf("expected enum, found type '%s'", buf_ptr(&dest_type->name))); 30635 return ira->codegen->invalid_inst_gen; 30636 } 30637 30638 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 30639 return ira->codegen->invalid_inst_gen; 30640 30641 ZigType *tag_type = dest_type->data.enumeration.tag_int_type; 30642 30643 IrInstGen *target = instruction->target->child; 30644 if (type_is_invalid(target->value->type)) 30645 return ira->codegen->invalid_inst_gen; 30646 30647 IrInstGen *casted_target = ir_implicit_cast(ira, target, tag_type); 30648 if (type_is_invalid(casted_target->value->type)) 30649 return ira->codegen->invalid_inst_gen; 30650 30651 return ir_analyze_int_to_enum(ira, &instruction->base.base, casted_target, dest_type); 30652 } 30653 30654 static IrInstGen *ir_analyze_instruction_check_runtime_scope(IrAnalyze *ira, IrInstSrcCheckRuntimeScope *instruction) { 30655 IrInstGen *block_comptime_inst = instruction->scope_is_comptime->child; 30656 bool scope_is_comptime; 30657 if (!ir_resolve_bool(ira, block_comptime_inst, &scope_is_comptime)) 30658 return ira->codegen->invalid_inst_gen; 30659 30660 IrInstGen *is_comptime_inst = instruction->is_comptime->child; 30661 bool is_comptime; 30662 if (!ir_resolve_bool(ira, is_comptime_inst, &is_comptime)) 30663 return ira->codegen->invalid_inst_gen; 30664 30665 if (!scope_is_comptime && is_comptime) { 30666 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base, 30667 buf_sprintf("comptime control flow inside runtime block")); 30668 add_error_note(ira->codegen, msg, block_comptime_inst->base.source_node, 30669 buf_sprintf("runtime block created here")); 30670 return ira->codegen->invalid_inst_gen; 30671 } 30672 30673 return ir_const_void(ira, &instruction->base.base); 30674 } 30675 30676 static IrInstGen *ir_analyze_instruction_has_decl(IrAnalyze *ira, IrInstSrcHasDecl *instruction) { 30677 ZigType *container_type = ir_resolve_type(ira, instruction->container->child); 30678 if (type_is_invalid(container_type)) 30679 return ira->codegen->invalid_inst_gen; 30680 30681 Buf *name = ir_resolve_str(ira, instruction->name->child); 30682 if (name == nullptr) 30683 return ira->codegen->invalid_inst_gen; 30684 30685 if (!is_container(container_type)) { 30686 ir_add_error(ira, &instruction->container->base, 30687 buf_sprintf("expected struct, enum, or union; found '%s'", buf_ptr(&container_type->name))); 30688 return ira->codegen->invalid_inst_gen; 30689 } 30690 30691 ScopeDecls *container_scope = get_container_scope(container_type); 30692 Tld *tld = find_container_decl(ira->codegen, container_scope, name); 30693 if (tld == nullptr) 30694 return ir_const_bool(ira, &instruction->base.base, false); 30695 30696 if (tld->visib_mod == VisibModPrivate && tld->import != get_scope_import(instruction->base.base.scope)) { 30697 return ir_const_bool(ira, &instruction->base.base, false); 30698 } 30699 30700 return ir_const_bool(ira, &instruction->base.base, true); 30701 } 30702 30703 static IrInstGen *ir_analyze_instruction_undeclared_ident(IrAnalyze *ira, IrInstSrcUndeclaredIdent *instruction) { 30704 // put a variable of same name with invalid type in global scope 30705 // so that future references to this same name will find a variable with an invalid type 30706 populate_invalid_variable_in_scope(ira->codegen, instruction->base.base.scope, 30707 instruction->base.base.source_node, instruction->name); 30708 ir_add_error(ira, &instruction->base.base, 30709 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(instruction->name))); 30710 return ira->codegen->invalid_inst_gen; 30711 } 30712 30713 static IrInstGen *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstSrcEndExpr *instruction) { 30714 IrInstGen *value = instruction->value->child; 30715 if (type_is_invalid(value->value->type)) 30716 return ira->codegen->invalid_inst_gen; 30717 30718 bool was_written = instruction->result_loc->written; 30719 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 30720 value->value->type, value, false, true); 30721 if (result_loc != nullptr) { 30722 if (type_is_invalid(result_loc->value->type)) 30723 return ira->codegen->invalid_inst_gen; 30724 if (result_loc->value->type->id == ZigTypeIdUnreachable) 30725 return result_loc; 30726 30727 if (!was_written || instruction->result_loc->id == ResultLocIdPeer) { 30728 IrInstGen *store_ptr = ir_analyze_store_ptr(ira, &instruction->base.base, result_loc, value, 30729 instruction->result_loc->allow_write_through_const); 30730 if (type_is_invalid(store_ptr->value->type)) { 30731 return ira->codegen->invalid_inst_gen; 30732 } 30733 } 30734 30735 if (result_loc->value->data.x_ptr.mut == ConstPtrMutInfer && 30736 instruction->result_loc->id != ResultLocIdPeer) 30737 { 30738 if (instr_is_comptime(value)) { 30739 result_loc->value->data.x_ptr.mut = ConstPtrMutComptimeConst; 30740 } else { 30741 result_loc->value->special = ConstValSpecialRuntime; 30742 } 30743 } 30744 } 30745 30746 return ir_const_void(ira, &instruction->base.base); 30747 } 30748 30749 static IrInstGen *ir_analyze_instruction_implicit_cast(IrAnalyze *ira, IrInstSrcImplicitCast *instruction) { 30750 IrInstGen *operand = instruction->operand->child; 30751 if (type_is_invalid(operand->value->type)) 30752 return operand; 30753 30754 ZigType *dest_type = ir_resolve_type(ira, instruction->result_loc_cast->base.source_instruction->child); 30755 if (type_is_invalid(dest_type)) 30756 return ira->codegen->invalid_inst_gen; 30757 return ir_implicit_cast2(ira, &instruction->base.base, operand, dest_type); 30758 } 30759 30760 static IrInstGen *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInstSrcBitCast *instruction) { 30761 IrInstGen *operand = instruction->operand->child; 30762 if (type_is_invalid(operand->value->type)) 30763 return operand; 30764 30765 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, 30766 &instruction->result_loc_bit_cast->base, operand->value->type, operand, false, true); 30767 if (result_loc != nullptr && 30768 (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) 30769 { 30770 return result_loc; 30771 } 30772 30773 ZigType *dest_type = ir_resolve_type(ira, 30774 instruction->result_loc_bit_cast->base.source_instruction->child); 30775 if (type_is_invalid(dest_type)) 30776 return ira->codegen->invalid_inst_gen; 30777 return ir_analyze_bit_cast(ira, &instruction->base.base, operand, dest_type); 30778 } 30779 30780 static IrInstGen *ir_analyze_instruction_union_init_named_field(IrAnalyze *ira, 30781 IrInstSrcUnionInitNamedField *instruction) 30782 { 30783 ZigType *union_type = ir_resolve_type(ira, instruction->union_type->child); 30784 if (type_is_invalid(union_type)) 30785 return ira->codegen->invalid_inst_gen; 30786 30787 if (union_type->id != ZigTypeIdUnion) { 30788 ir_add_error(ira, &instruction->union_type->base, 30789 buf_sprintf("non-union type '%s' passed to @unionInit", buf_ptr(&union_type->name))); 30790 return ira->codegen->invalid_inst_gen; 30791 } 30792 30793 Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); 30794 if (field_name == nullptr) 30795 return ira->codegen->invalid_inst_gen; 30796 30797 IrInstGen *field_result_loc = instruction->field_result_loc->child; 30798 if (type_is_invalid(field_result_loc->value->type)) 30799 return ira->codegen->invalid_inst_gen; 30800 30801 IrInstGen *result_loc = instruction->result_loc->child; 30802 if (type_is_invalid(result_loc->value->type)) 30803 return ira->codegen->invalid_inst_gen; 30804 30805 return ir_analyze_union_init(ira, &instruction->base.base, instruction->base.base.source_node, 30806 union_type, field_name, field_result_loc, result_loc); 30807 } 30808 30809 static IrInstGen *ir_analyze_instruction_suspend_begin(IrAnalyze *ira, IrInstSrcSuspendBegin *instruction) { 30810 return ir_build_suspend_begin_gen(ira, &instruction->base.base); 30811 } 30812 30813 static IrInstGen *ir_analyze_instruction_suspend_finish(IrAnalyze *ira, IrInstSrcSuspendFinish *instruction) { 30814 IrInstGen *begin_base = instruction->begin->base.child; 30815 if (type_is_invalid(begin_base->value->type)) 30816 return ira->codegen->invalid_inst_gen; 30817 ir_assert(begin_base->id == IrInstGenIdSuspendBegin, &instruction->base.base); 30818 IrInstGenSuspendBegin *begin = reinterpret_cast<IrInstGenSuspendBegin *>(begin_base); 30819 30820 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 30821 ir_assert(fn_entry != nullptr, &instruction->base.base); 30822 30823 if (fn_entry->inferred_async_node == nullptr) { 30824 fn_entry->inferred_async_node = instruction->base.base.source_node; 30825 } 30826 30827 return ir_build_suspend_finish_gen(ira, &instruction->base.base, begin); 30828 } 30829 30830 static IrInstGen *analyze_frame_ptr_to_anyframe_T(IrAnalyze *ira, IrInst* source_instr, 30831 IrInstGen *frame_ptr, ZigFn **target_fn) 30832 { 30833 if (type_is_invalid(frame_ptr->value->type)) 30834 return ira->codegen->invalid_inst_gen; 30835 30836 *target_fn = nullptr; 30837 30838 ZigType *result_type; 30839 IrInstGen *frame; 30840 if (frame_ptr->value->type->id == ZigTypeIdPointer && 30841 frame_ptr->value->type->data.pointer.ptr_len == PtrLenSingle && 30842 frame_ptr->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 30843 { 30844 ZigFn *func = frame_ptr->value->type->data.pointer.child_type->data.frame.fn; 30845 result_type = func->type_entry->data.fn.fn_type_id.return_type; 30846 *target_fn = func; 30847 frame = frame_ptr; 30848 } else { 30849 frame = ir_get_deref(ira, source_instr, frame_ptr, nullptr); 30850 if (frame->value->type->id == ZigTypeIdPointer && 30851 frame->value->type->data.pointer.ptr_len == PtrLenSingle && 30852 frame->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 30853 { 30854 ZigFn *func = frame->value->type->data.pointer.child_type->data.frame.fn; 30855 result_type = func->type_entry->data.fn.fn_type_id.return_type; 30856 *target_fn = func; 30857 } else if (frame->value->type->id != ZigTypeIdAnyFrame || 30858 frame->value->type->data.any_frame.result_type == nullptr) 30859 { 30860 ir_add_error(ira, source_instr, 30861 buf_sprintf("expected anyframe->T, found '%s'", buf_ptr(&frame->value->type->name))); 30862 return ira->codegen->invalid_inst_gen; 30863 } else { 30864 result_type = frame->value->type->data.any_frame.result_type; 30865 } 30866 } 30867 30868 ZigType *any_frame_type = get_any_frame_type(ira->codegen, result_type); 30869 IrInstGen *casted_frame = ir_implicit_cast(ira, frame, any_frame_type); 30870 if (type_is_invalid(casted_frame->value->type)) 30871 return ira->codegen->invalid_inst_gen; 30872 30873 return casted_frame; 30874 } 30875 30876 static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *instruction) { 30877 IrInstGen *operand = instruction->frame->child; 30878 if (type_is_invalid(operand->value->type)) 30879 return ira->codegen->invalid_inst_gen; 30880 ZigFn *target_fn; 30881 IrInstGen *frame = analyze_frame_ptr_to_anyframe_T(ira, &instruction->base.base, operand, &target_fn); 30882 if (type_is_invalid(frame->value->type)) 30883 return ira->codegen->invalid_inst_gen; 30884 30885 ZigType *result_type = frame->value->type->data.any_frame.result_type; 30886 30887 ZigFn *fn_entry = ira->new_irb.exec->fn_entry; 30888 ir_assert(fn_entry != nullptr, &instruction->base.base); 30889 30890 // If it's not @Frame(func) then it's definitely a suspend point 30891 if (target_fn == nullptr && !instruction->is_nosuspend) { 30892 if (fn_entry->inferred_async_node == nullptr) { 30893 fn_entry->inferred_async_node = instruction->base.base.source_node; 30894 } 30895 } 30896 30897 if (type_can_fail(result_type)) { 30898 fn_entry->calls_or_awaits_errorable_fn = true; 30899 } 30900 30901 IrInstGen *result_loc; 30902 if (type_has_bits(ira->codegen, result_type)) { 30903 result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, 30904 result_type, nullptr, true, true); 30905 if (result_loc != nullptr && 30906 (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) 30907 { 30908 return result_loc; 30909 } 30910 } else { 30911 result_loc = nullptr; 30912 } 30913 30914 IrInstGenAwait *result = ir_build_await_gen(ira, &instruction->base.base, frame, result_type, result_loc, 30915 instruction->is_nosuspend); 30916 result->target_fn = target_fn; 30917 fn_entry->await_list.append(result); 30918 return ir_finish_anal(ira, &result->base); 30919 } 30920 30921 static IrInstGen *ir_analyze_instruction_resume(IrAnalyze *ira, IrInstSrcResume *instruction) { 30922 IrInstGen *frame_ptr = instruction->frame->child; 30923 if (type_is_invalid(frame_ptr->value->type)) 30924 return ira->codegen->invalid_inst_gen; 30925 30926 IrInstGen *frame; 30927 if (frame_ptr->value->type->id == ZigTypeIdPointer && 30928 frame_ptr->value->type->data.pointer.ptr_len == PtrLenSingle && 30929 frame_ptr->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 30930 { 30931 frame = frame_ptr; 30932 } else { 30933 frame = ir_get_deref(ira, &instruction->base.base, frame_ptr, nullptr); 30934 } 30935 30936 ZigType *any_frame_type = get_any_frame_type(ira->codegen, nullptr); 30937 IrInstGen *casted_frame = ir_implicit_cast2(ira, &instruction->frame->base, frame, any_frame_type); 30938 if (type_is_invalid(casted_frame->value->type)) 30939 return ira->codegen->invalid_inst_gen; 30940 30941 return ir_build_resume_gen(ira, &instruction->base.base, casted_frame); 30942 } 30943 30944 static IrInstGen *ir_analyze_instruction_spill_begin(IrAnalyze *ira, IrInstSrcSpillBegin *instruction) { 30945 if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope)) 30946 return ir_const_void(ira, &instruction->base.base); 30947 30948 IrInstGen *operand = instruction->operand->child; 30949 if (type_is_invalid(operand->value->type)) 30950 return ira->codegen->invalid_inst_gen; 30951 30952 if (!type_has_bits(ira->codegen, operand->value->type)) 30953 return ir_const_void(ira, &instruction->base.base); 30954 30955 switch (instruction->spill_id) { 30956 case SpillIdInvalid: 30957 zig_unreachable(); 30958 case SpillIdRetErrCode: 30959 ira->new_irb.exec->need_err_code_spill = true; 30960 break; 30961 } 30962 30963 return ir_build_spill_begin_gen(ira, &instruction->base.base, operand, instruction->spill_id); 30964 } 30965 30966 static IrInstGen *ir_analyze_instruction_spill_end(IrAnalyze *ira, IrInstSrcSpillEnd *instruction) { 30967 IrInstGen *operand = instruction->begin->operand->child; 30968 if (type_is_invalid(operand->value->type)) 30969 return ira->codegen->invalid_inst_gen; 30970 30971 if (ir_should_inline(ira->old_irb.exec, instruction->base.base.scope) || 30972 !type_has_bits(ira->codegen, operand->value->type) || 30973 instr_is_comptime(operand)) 30974 { 30975 return operand; 30976 } 30977 30978 ir_assert(instruction->begin->base.child->id == IrInstGenIdSpillBegin, &instruction->base.base); 30979 IrInstGenSpillBegin *begin = reinterpret_cast<IrInstGenSpillBegin *>(instruction->begin->base.child); 30980 30981 return ir_build_spill_end_gen(ira, &instruction->base.base, begin, operand->value->type); 30982 } 30983 30984 static IrInstGen *ir_analyze_instruction_src(IrAnalyze *ira, IrInstSrcSrc *instruction) { 30985 ZigFn *fn_entry = scope_fn_entry(instruction->base.base.scope); 30986 if (fn_entry == nullptr) { 30987 ir_add_error(ira, &instruction->base.base, buf_sprintf("@src outside function")); 30988 return ira->codegen->invalid_inst_gen; 30989 } 30990 30991 ZigType *u8_ptr = get_pointer_to_type_extra2( 30992 ira->codegen, ira->codegen->builtin_types.entry_u8, 30993 true, false, PtrLenUnknown, 30994 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr, ira->codegen->intern.for_zero_byte()); 30995 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 30996 30997 ZigType *source_location_type = get_builtin_type(ira->codegen, "SourceLocation"); 30998 if (type_resolve(ira->codegen, source_location_type, ResolveStatusSizeKnown)) { 30999 zig_unreachable(); 31000 } 31001 31002 ZigValue *result = ira->codegen->pass1_arena->create<ZigValue>(); 31003 result->special = ConstValSpecialStatic; 31004 result->type = source_location_type; 31005 31006 ZigValue **fields = alloc_const_vals_ptrs(ira->codegen, 4); 31007 result->data.x_struct.fields = fields; 31008 31009 // file: [:0]const u8 31010 ensure_field_index(source_location_type, "file", 0); 31011 fields[0]->special = ConstValSpecialStatic; 31012 31013 ZigType *import = instruction->base.base.source_node->owner; 31014 Buf *path = import->data.structure.root_struct->path; 31015 ZigValue *file_name = create_const_str_lit(ira->codegen, path)->data.x_ptr.data.ref.pointee; 31016 init_const_slice(ira->codegen, fields[0], file_name, 0, buf_len(path), true); 31017 fields[0]->type = u8_slice; 31018 31019 // fn_name: [:0]const u8 31020 ensure_field_index(source_location_type, "fn_name", 1); 31021 fields[1]->special = ConstValSpecialStatic; 31022 31023 ZigValue *fn_name = create_const_str_lit(ira->codegen, &fn_entry->symbol_name)->data.x_ptr.data.ref.pointee; 31024 init_const_slice(ira->codegen, fields[1], fn_name, 0, buf_len(&fn_entry->symbol_name), true); 31025 fields[1]->type = u8_slice; 31026 31027 // line: u32 31028 ensure_field_index(source_location_type, "line", 2); 31029 fields[2]->special = ConstValSpecialStatic; 31030 fields[2]->type = ira->codegen->builtin_types.entry_u32; 31031 bigint_init_unsigned(&fields[2]->data.x_bigint, instruction->base.base.source_node->line + 1); 31032 31033 // column: u32 31034 ensure_field_index(source_location_type, "column", 3); 31035 fields[3]->special = ConstValSpecialStatic; 31036 fields[3]->type = ira->codegen->builtin_types.entry_u32; 31037 bigint_init_unsigned(&fields[3]->data.x_bigint, instruction->base.base.source_node->column + 1); 31038 31039 return ir_const_move(ira, &instruction->base.base, result); 31040 } 31041 31042 static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruction) { 31043 switch (instruction->id) { 31044 case IrInstSrcIdInvalid: 31045 zig_unreachable(); 31046 31047 case IrInstSrcIdReturn: 31048 return ir_analyze_instruction_return(ira, (IrInstSrcReturn *)instruction); 31049 case IrInstSrcIdConst: 31050 return ir_analyze_instruction_const(ira, (IrInstSrcConst *)instruction); 31051 case IrInstSrcIdUnOp: 31052 return ir_analyze_instruction_un_op(ira, (IrInstSrcUnOp *)instruction); 31053 case IrInstSrcIdBinOp: 31054 return ir_analyze_instruction_bin_op(ira, (IrInstSrcBinOp *)instruction); 31055 case IrInstSrcIdMergeErrSets: 31056 return ir_analyze_instruction_merge_err_sets(ira, (IrInstSrcMergeErrSets *)instruction); 31057 case IrInstSrcIdDeclVar: 31058 return ir_analyze_instruction_decl_var(ira, (IrInstSrcDeclVar *)instruction); 31059 case IrInstSrcIdLoadPtr: 31060 return ir_analyze_instruction_load_ptr(ira, (IrInstSrcLoadPtr *)instruction); 31061 case IrInstSrcIdStorePtr: 31062 return ir_analyze_instruction_store_ptr(ira, (IrInstSrcStorePtr *)instruction); 31063 case IrInstSrcIdElemPtr: 31064 return ir_analyze_instruction_elem_ptr(ira, (IrInstSrcElemPtr *)instruction); 31065 case IrInstSrcIdVarPtr: 31066 return ir_analyze_instruction_var_ptr(ira, (IrInstSrcVarPtr *)instruction); 31067 case IrInstSrcIdFieldPtr: 31068 return ir_analyze_instruction_field_ptr(ira, (IrInstSrcFieldPtr *)instruction); 31069 case IrInstSrcIdCall: 31070 return ir_analyze_instruction_call(ira, (IrInstSrcCall *)instruction); 31071 case IrInstSrcIdCallArgs: 31072 return ir_analyze_instruction_call_args(ira, (IrInstSrcCallArgs *)instruction); 31073 case IrInstSrcIdCallExtra: 31074 return ir_analyze_instruction_call_extra(ira, (IrInstSrcCallExtra *)instruction); 31075 case IrInstSrcIdBr: 31076 return ir_analyze_instruction_br(ira, (IrInstSrcBr *)instruction); 31077 case IrInstSrcIdCondBr: 31078 return ir_analyze_instruction_cond_br(ira, (IrInstSrcCondBr *)instruction); 31079 case IrInstSrcIdUnreachable: 31080 return ir_analyze_instruction_unreachable(ira, (IrInstSrcUnreachable *)instruction); 31081 case IrInstSrcIdPhi: 31082 return ir_analyze_instruction_phi(ira, (IrInstSrcPhi *)instruction); 31083 case IrInstSrcIdTypeOf: 31084 return ir_analyze_instruction_typeof(ira, (IrInstSrcTypeOf *)instruction); 31085 case IrInstSrcIdSetCold: 31086 return ir_analyze_instruction_set_cold(ira, (IrInstSrcSetCold *)instruction); 31087 case IrInstSrcIdSetRuntimeSafety: 31088 return ir_analyze_instruction_set_runtime_safety(ira, (IrInstSrcSetRuntimeSafety *)instruction); 31089 case IrInstSrcIdSetFloatMode: 31090 return ir_analyze_instruction_set_float_mode(ira, (IrInstSrcSetFloatMode *)instruction); 31091 case IrInstSrcIdAnyFrameType: 31092 return ir_analyze_instruction_any_frame_type(ira, (IrInstSrcAnyFrameType *)instruction); 31093 case IrInstSrcIdSliceType: 31094 return ir_analyze_instruction_slice_type(ira, (IrInstSrcSliceType *)instruction); 31095 case IrInstSrcIdAsm: 31096 return ir_analyze_instruction_asm(ira, (IrInstSrcAsm *)instruction); 31097 case IrInstSrcIdArrayType: 31098 return ir_analyze_instruction_array_type(ira, (IrInstSrcArrayType *)instruction); 31099 case IrInstSrcIdSizeOf: 31100 return ir_analyze_instruction_size_of(ira, (IrInstSrcSizeOf *)instruction); 31101 case IrInstSrcIdTestNonNull: 31102 return ir_analyze_instruction_test_non_null(ira, (IrInstSrcTestNonNull *)instruction); 31103 case IrInstSrcIdOptionalUnwrapPtr: 31104 return ir_analyze_instruction_optional_unwrap_ptr(ira, (IrInstSrcOptionalUnwrapPtr *)instruction); 31105 case IrInstSrcIdClz: 31106 return ir_analyze_instruction_clz(ira, (IrInstSrcClz *)instruction); 31107 case IrInstSrcIdCtz: 31108 return ir_analyze_instruction_ctz(ira, (IrInstSrcCtz *)instruction); 31109 case IrInstSrcIdPopCount: 31110 return ir_analyze_instruction_pop_count(ira, (IrInstSrcPopCount *)instruction); 31111 case IrInstSrcIdBswap: 31112 return ir_analyze_instruction_bswap(ira, (IrInstSrcBswap *)instruction); 31113 case IrInstSrcIdBitReverse: 31114 return ir_analyze_instruction_bit_reverse(ira, (IrInstSrcBitReverse *)instruction); 31115 case IrInstSrcIdSwitchBr: 31116 return ir_analyze_instruction_switch_br(ira, (IrInstSrcSwitchBr *)instruction); 31117 case IrInstSrcIdSwitchTarget: 31118 return ir_analyze_instruction_switch_target(ira, (IrInstSrcSwitchTarget *)instruction); 31119 case IrInstSrcIdSwitchVar: 31120 return ir_analyze_instruction_switch_var(ira, (IrInstSrcSwitchVar *)instruction); 31121 case IrInstSrcIdSwitchElseVar: 31122 return ir_analyze_instruction_switch_else_var(ira, (IrInstSrcSwitchElseVar *)instruction); 31123 case IrInstSrcIdImport: 31124 return ir_analyze_instruction_import(ira, (IrInstSrcImport *)instruction); 31125 case IrInstSrcIdRef: 31126 return ir_analyze_instruction_ref(ira, (IrInstSrcRef *)instruction); 31127 case IrInstSrcIdContainerInitList: 31128 return ir_analyze_instruction_container_init_list(ira, (IrInstSrcContainerInitList *)instruction); 31129 case IrInstSrcIdContainerInitFields: 31130 return ir_analyze_instruction_container_init_fields(ira, (IrInstSrcContainerInitFields *)instruction); 31131 case IrInstSrcIdCompileErr: 31132 return ir_analyze_instruction_compile_err(ira, (IrInstSrcCompileErr *)instruction); 31133 case IrInstSrcIdCompileLog: 31134 return ir_analyze_instruction_compile_log(ira, (IrInstSrcCompileLog *)instruction); 31135 case IrInstSrcIdErrName: 31136 return ir_analyze_instruction_err_name(ira, (IrInstSrcErrName *)instruction); 31137 case IrInstSrcIdTypeName: 31138 return ir_analyze_instruction_type_name(ira, (IrInstSrcTypeName *)instruction); 31139 case IrInstSrcIdCImport: 31140 return ir_analyze_instruction_c_import(ira, (IrInstSrcCImport *)instruction); 31141 case IrInstSrcIdCInclude: 31142 return ir_analyze_instruction_c_include(ira, (IrInstSrcCInclude *)instruction); 31143 case IrInstSrcIdCDefine: 31144 return ir_analyze_instruction_c_define(ira, (IrInstSrcCDefine *)instruction); 31145 case IrInstSrcIdCUndef: 31146 return ir_analyze_instruction_c_undef(ira, (IrInstSrcCUndef *)instruction); 31147 case IrInstSrcIdEmbedFile: 31148 return ir_analyze_instruction_embed_file(ira, (IrInstSrcEmbedFile *)instruction); 31149 case IrInstSrcIdCmpxchg: 31150 return ir_analyze_instruction_cmpxchg(ira, (IrInstSrcCmpxchg *)instruction); 31151 case IrInstSrcIdFence: 31152 return ir_analyze_instruction_fence(ira, (IrInstSrcFence *)instruction); 31153 case IrInstSrcIdTruncate: 31154 return ir_analyze_instruction_truncate(ira, (IrInstSrcTruncate *)instruction); 31155 case IrInstSrcIdIntCast: 31156 return ir_analyze_instruction_int_cast(ira, (IrInstSrcIntCast *)instruction); 31157 case IrInstSrcIdFloatCast: 31158 return ir_analyze_instruction_float_cast(ira, (IrInstSrcFloatCast *)instruction); 31159 case IrInstSrcIdErrSetCast: 31160 return ir_analyze_instruction_err_set_cast(ira, (IrInstSrcErrSetCast *)instruction); 31161 case IrInstSrcIdIntToFloat: 31162 return ir_analyze_instruction_int_to_float(ira, (IrInstSrcIntToFloat *)instruction); 31163 case IrInstSrcIdFloatToInt: 31164 return ir_analyze_instruction_float_to_int(ira, (IrInstSrcFloatToInt *)instruction); 31165 case IrInstSrcIdBoolToInt: 31166 return ir_analyze_instruction_bool_to_int(ira, (IrInstSrcBoolToInt *)instruction); 31167 case IrInstSrcIdVectorType: 31168 return ir_analyze_instruction_vector_type(ira, (IrInstSrcVectorType *)instruction); 31169 case IrInstSrcIdShuffleVector: 31170 return ir_analyze_instruction_shuffle_vector(ira, (IrInstSrcShuffleVector *)instruction); 31171 case IrInstSrcIdSplat: 31172 return ir_analyze_instruction_splat(ira, (IrInstSrcSplat *)instruction); 31173 case IrInstSrcIdBoolNot: 31174 return ir_analyze_instruction_bool_not(ira, (IrInstSrcBoolNot *)instruction); 31175 case IrInstSrcIdMemset: 31176 return ir_analyze_instruction_memset(ira, (IrInstSrcMemset *)instruction); 31177 case IrInstSrcIdMemcpy: 31178 return ir_analyze_instruction_memcpy(ira, (IrInstSrcMemcpy *)instruction); 31179 case IrInstSrcIdSlice: 31180 return ir_analyze_instruction_slice(ira, (IrInstSrcSlice *)instruction); 31181 case IrInstSrcIdBreakpoint: 31182 return ir_analyze_instruction_breakpoint(ira, (IrInstSrcBreakpoint *)instruction); 31183 case IrInstSrcIdReturnAddress: 31184 return ir_analyze_instruction_return_address(ira, (IrInstSrcReturnAddress *)instruction); 31185 case IrInstSrcIdFrameAddress: 31186 return ir_analyze_instruction_frame_address(ira, (IrInstSrcFrameAddress *)instruction); 31187 case IrInstSrcIdFrameHandle: 31188 return ir_analyze_instruction_frame_handle(ira, (IrInstSrcFrameHandle *)instruction); 31189 case IrInstSrcIdFrameType: 31190 return ir_analyze_instruction_frame_type(ira, (IrInstSrcFrameType *)instruction); 31191 case IrInstSrcIdFrameSize: 31192 return ir_analyze_instruction_frame_size(ira, (IrInstSrcFrameSize *)instruction); 31193 case IrInstSrcIdAlignOf: 31194 return ir_analyze_instruction_align_of(ira, (IrInstSrcAlignOf *)instruction); 31195 case IrInstSrcIdOverflowOp: 31196 return ir_analyze_instruction_overflow_op(ira, (IrInstSrcOverflowOp *)instruction); 31197 case IrInstSrcIdTestErr: 31198 return ir_analyze_instruction_test_err(ira, (IrInstSrcTestErr *)instruction); 31199 case IrInstSrcIdUnwrapErrCode: 31200 return ir_analyze_instruction_unwrap_err_code(ira, (IrInstSrcUnwrapErrCode *)instruction); 31201 case IrInstSrcIdUnwrapErrPayload: 31202 return ir_analyze_instruction_unwrap_err_payload(ira, (IrInstSrcUnwrapErrPayload *)instruction); 31203 case IrInstSrcIdFnProto: 31204 return ir_analyze_instruction_fn_proto(ira, (IrInstSrcFnProto *)instruction); 31205 case IrInstSrcIdTestComptime: 31206 return ir_analyze_instruction_test_comptime(ira, (IrInstSrcTestComptime *)instruction); 31207 case IrInstSrcIdCheckSwitchProngs: 31208 return ir_analyze_instruction_check_switch_prongs(ira, (IrInstSrcCheckSwitchProngs *)instruction); 31209 case IrInstSrcIdCheckStatementIsVoid: 31210 return ir_analyze_instruction_check_statement_is_void(ira, (IrInstSrcCheckStatementIsVoid *)instruction); 31211 case IrInstSrcIdDeclRef: 31212 return ir_analyze_instruction_decl_ref(ira, (IrInstSrcDeclRef *)instruction); 31213 case IrInstSrcIdPanic: 31214 return ir_analyze_instruction_panic(ira, (IrInstSrcPanic *)instruction); 31215 case IrInstSrcIdPtrCast: 31216 return ir_analyze_instruction_ptr_cast(ira, (IrInstSrcPtrCast *)instruction); 31217 case IrInstSrcIdIntToPtr: 31218 return ir_analyze_instruction_int_to_ptr(ira, (IrInstSrcIntToPtr *)instruction); 31219 case IrInstSrcIdPtrToInt: 31220 return ir_analyze_instruction_ptr_to_int(ira, (IrInstSrcPtrToInt *)instruction); 31221 case IrInstSrcIdTagName: 31222 return ir_analyze_instruction_enum_tag_name(ira, (IrInstSrcTagName *)instruction); 31223 case IrInstSrcIdFieldParentPtr: 31224 return ir_analyze_instruction_field_parent_ptr(ira, (IrInstSrcFieldParentPtr *)instruction); 31225 case IrInstSrcIdByteOffsetOf: 31226 return ir_analyze_instruction_byte_offset_of(ira, (IrInstSrcByteOffsetOf *)instruction); 31227 case IrInstSrcIdBitOffsetOf: 31228 return ir_analyze_instruction_bit_offset_of(ira, (IrInstSrcBitOffsetOf *)instruction); 31229 case IrInstSrcIdTypeInfo: 31230 return ir_analyze_instruction_type_info(ira, (IrInstSrcTypeInfo *) instruction); 31231 case IrInstSrcIdType: 31232 return ir_analyze_instruction_type(ira, (IrInstSrcType *)instruction); 31233 case IrInstSrcIdHasField: 31234 return ir_analyze_instruction_has_field(ira, (IrInstSrcHasField *) instruction); 31235 case IrInstSrcIdSetEvalBranchQuota: 31236 return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstSrcSetEvalBranchQuota *)instruction); 31237 case IrInstSrcIdPtrType: 31238 return ir_analyze_instruction_ptr_type(ira, (IrInstSrcPtrType *)instruction); 31239 case IrInstSrcIdAlignCast: 31240 return ir_analyze_instruction_align_cast(ira, (IrInstSrcAlignCast *)instruction); 31241 case IrInstSrcIdImplicitCast: 31242 return ir_analyze_instruction_implicit_cast(ira, (IrInstSrcImplicitCast *)instruction); 31243 case IrInstSrcIdResolveResult: 31244 return ir_analyze_instruction_resolve_result(ira, (IrInstSrcResolveResult *)instruction); 31245 case IrInstSrcIdResetResult: 31246 return ir_analyze_instruction_reset_result(ira, (IrInstSrcResetResult *)instruction); 31247 case IrInstSrcIdOpaqueType: 31248 return ir_analyze_instruction_opaque_type(ira, (IrInstSrcOpaqueType *)instruction); 31249 case IrInstSrcIdSetAlignStack: 31250 return ir_analyze_instruction_set_align_stack(ira, (IrInstSrcSetAlignStack *)instruction); 31251 case IrInstSrcIdArgType: 31252 return ir_analyze_instruction_arg_type(ira, (IrInstSrcArgType *)instruction); 31253 case IrInstSrcIdTagType: 31254 return ir_analyze_instruction_tag_type(ira, (IrInstSrcTagType *)instruction); 31255 case IrInstSrcIdExport: 31256 return ir_analyze_instruction_export(ira, (IrInstSrcExport *)instruction); 31257 case IrInstSrcIdErrorReturnTrace: 31258 return ir_analyze_instruction_error_return_trace(ira, (IrInstSrcErrorReturnTrace *)instruction); 31259 case IrInstSrcIdErrorUnion: 31260 return ir_analyze_instruction_error_union(ira, (IrInstSrcErrorUnion *)instruction); 31261 case IrInstSrcIdAtomicRmw: 31262 return ir_analyze_instruction_atomic_rmw(ira, (IrInstSrcAtomicRmw *)instruction); 31263 case IrInstSrcIdAtomicLoad: 31264 return ir_analyze_instruction_atomic_load(ira, (IrInstSrcAtomicLoad *)instruction); 31265 case IrInstSrcIdAtomicStore: 31266 return ir_analyze_instruction_atomic_store(ira, (IrInstSrcAtomicStore *)instruction); 31267 case IrInstSrcIdSaveErrRetAddr: 31268 return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstSrcSaveErrRetAddr *)instruction); 31269 case IrInstSrcIdAddImplicitReturnType: 31270 return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstSrcAddImplicitReturnType *)instruction); 31271 case IrInstSrcIdFloatOp: 31272 return ir_analyze_instruction_float_op(ira, (IrInstSrcFloatOp *)instruction); 31273 case IrInstSrcIdMulAdd: 31274 return ir_analyze_instruction_mul_add(ira, (IrInstSrcMulAdd *)instruction); 31275 case IrInstSrcIdIntToErr: 31276 return ir_analyze_instruction_int_to_err(ira, (IrInstSrcIntToErr *)instruction); 31277 case IrInstSrcIdErrToInt: 31278 return ir_analyze_instruction_err_to_int(ira, (IrInstSrcErrToInt *)instruction); 31279 case IrInstSrcIdIntToEnum: 31280 return ir_analyze_instruction_int_to_enum(ira, (IrInstSrcIntToEnum *)instruction); 31281 case IrInstSrcIdEnumToInt: 31282 return ir_analyze_instruction_enum_to_int(ira, (IrInstSrcEnumToInt *)instruction); 31283 case IrInstSrcIdCheckRuntimeScope: 31284 return ir_analyze_instruction_check_runtime_scope(ira, (IrInstSrcCheckRuntimeScope *)instruction); 31285 case IrInstSrcIdHasDecl: 31286 return ir_analyze_instruction_has_decl(ira, (IrInstSrcHasDecl *)instruction); 31287 case IrInstSrcIdUndeclaredIdent: 31288 return ir_analyze_instruction_undeclared_ident(ira, (IrInstSrcUndeclaredIdent *)instruction); 31289 case IrInstSrcIdAlloca: 31290 return nullptr; 31291 case IrInstSrcIdEndExpr: 31292 return ir_analyze_instruction_end_expr(ira, (IrInstSrcEndExpr *)instruction); 31293 case IrInstSrcIdBitCast: 31294 return ir_analyze_instruction_bit_cast_src(ira, (IrInstSrcBitCast *)instruction); 31295 case IrInstSrcIdUnionInitNamedField: 31296 return ir_analyze_instruction_union_init_named_field(ira, (IrInstSrcUnionInitNamedField *)instruction); 31297 case IrInstSrcIdSuspendBegin: 31298 return ir_analyze_instruction_suspend_begin(ira, (IrInstSrcSuspendBegin *)instruction); 31299 case IrInstSrcIdSuspendFinish: 31300 return ir_analyze_instruction_suspend_finish(ira, (IrInstSrcSuspendFinish *)instruction); 31301 case IrInstSrcIdResume: 31302 return ir_analyze_instruction_resume(ira, (IrInstSrcResume *)instruction); 31303 case IrInstSrcIdAwait: 31304 return ir_analyze_instruction_await(ira, (IrInstSrcAwait *)instruction); 31305 case IrInstSrcIdSpillBegin: 31306 return ir_analyze_instruction_spill_begin(ira, (IrInstSrcSpillBegin *)instruction); 31307 case IrInstSrcIdSpillEnd: 31308 return ir_analyze_instruction_spill_end(ira, (IrInstSrcSpillEnd *)instruction); 31309 case IrInstSrcIdWasmMemorySize: 31310 return ir_analyze_instruction_wasm_memory_size(ira, (IrInstSrcWasmMemorySize *)instruction); 31311 case IrInstSrcIdWasmMemoryGrow: 31312 return ir_analyze_instruction_wasm_memory_grow(ira, (IrInstSrcWasmMemoryGrow *)instruction); 31313 case IrInstSrcIdSrc: 31314 return ir_analyze_instruction_src(ira, (IrInstSrcSrc *)instruction); 31315 } 31316 zig_unreachable(); 31317 } 31318 31319 // This function attempts to evaluate IR code while doing type checking and other analysis. 31320 // It emits to a new IrExecutableGen which is partially evaluated IR code. 31321 ZigType *ir_analyze(CodeGen *codegen, IrExecutableSrc *old_exec, IrExecutableGen *new_exec, 31322 ZigType *expected_type, AstNode *expected_type_source_node, ZigValue *result_ptr) 31323 { 31324 assert(old_exec->first_err_trace_msg == nullptr); 31325 assert(expected_type == nullptr || !type_is_invalid(expected_type)); 31326 31327 IrAnalyze *ira = heap::c_allocator.create<IrAnalyze>(); 31328 ira->ref_count = 1; 31329 old_exec->analysis = ira; 31330 ira->codegen = codegen; 31331 31332 ira->explicit_return_type = expected_type; 31333 ira->explicit_return_type_source_node = expected_type_source_node; 31334 31335 ira->old_irb.codegen = codegen; 31336 ira->old_irb.exec = old_exec; 31337 31338 ira->new_irb.codegen = codegen; 31339 ira->new_irb.exec = new_exec; 31340 31341 IrBasicBlockSrc *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); 31342 IrBasicBlockGen *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); 31343 ira->new_irb.current_basic_block = new_entry_bb; 31344 ira->old_bb_index = 0; 31345 31346 ir_start_bb(ira, old_entry_bb, nullptr); 31347 31348 if (result_ptr != nullptr) { 31349 assert(result_ptr->type->id == ZigTypeIdPointer); 31350 IrInstGenConst *const_inst = ir_create_inst_noval<IrInstGenConst>( 31351 &ira->new_irb, new_exec->begin_scope, new_exec->source_node); 31352 const_inst->base.value = result_ptr; 31353 ira->return_ptr = &const_inst->base; 31354 } else { 31355 assert(new_exec->begin_scope != nullptr); 31356 assert(new_exec->source_node != nullptr); 31357 ira->return_ptr = ir_build_return_ptr(ira, new_exec->begin_scope, new_exec->source_node, 31358 get_pointer_to_type(codegen, expected_type, false)); 31359 } 31360 31361 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 31362 IrInstSrc *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 31363 31364 if (old_instruction->base.ref_count == 0 && !ir_inst_src_has_side_effects(old_instruction)) { 31365 ira->instruction_index += 1; 31366 continue; 31367 } 31368 31369 if (ira->codegen->verbose_ir) { 31370 fprintf(stderr, "~ "); 31371 old_instruction->src(); 31372 fprintf(stderr, "~ "); 31373 ir_print_inst_src(codegen, stderr, old_instruction, 0); 31374 bool want_break = false; 31375 if (ira->break_debug_id == old_instruction->base.debug_id) { 31376 want_break = true; 31377 } else if (old_instruction->base.source_node != nullptr) { 31378 for (size_t i = 0; i < dbg_ir_breakpoints_count; i += 1) { 31379 if (dbg_ir_breakpoints_buf[i].line == old_instruction->base.source_node->line + 1 && 31380 buf_ends_with_str(old_instruction->base.source_node->owner->data.structure.root_struct->path, 31381 dbg_ir_breakpoints_buf[i].src_file)) 31382 { 31383 want_break = true; 31384 } 31385 } 31386 } 31387 if (want_break) BREAKPOINT; 31388 } 31389 IrInstGen *new_instruction = ir_analyze_instruction_base(ira, old_instruction); 31390 if (new_instruction != nullptr) { 31391 ir_assert(new_instruction->value->type != nullptr || new_instruction->value->type != nullptr, &old_instruction->base); 31392 old_instruction->child = new_instruction; 31393 31394 if (type_is_invalid(new_instruction->value->type)) { 31395 if (ira->codegen->verbose_ir) { 31396 fprintf(stderr, "-> (invalid)"); 31397 } 31398 31399 if (new_exec->first_err_trace_msg != nullptr) { 31400 ira->codegen->trace_err = new_exec->first_err_trace_msg; 31401 } else { 31402 new_exec->first_err_trace_msg = ira->codegen->trace_err; 31403 } 31404 if (new_exec->first_err_trace_msg != nullptr && 31405 !old_instruction->base.source_node->already_traced_this_node) 31406 { 31407 old_instruction->base.source_node->already_traced_this_node = true; 31408 new_exec->first_err_trace_msg = add_error_note(ira->codegen, new_exec->first_err_trace_msg, 31409 old_instruction->base.source_node, buf_create_from_str("referenced here")); 31410 } 31411 return ira->codegen->builtin_types.entry_invalid; 31412 } else if (ira->codegen->verbose_ir) { 31413 fprintf(stderr, "-> "); 31414 if (new_instruction->value->type->id == ZigTypeIdUnreachable) { 31415 fprintf(stderr, "(noreturn)\n"); 31416 } else { 31417 ir_print_inst_gen(codegen, stderr, new_instruction, 0); 31418 } 31419 } 31420 31421 // unreachable instructions do their own control flow. 31422 if (new_instruction->value->type->id == ZigTypeIdUnreachable) 31423 continue; 31424 } else { 31425 if (ira->codegen->verbose_ir) { 31426 fprintf(stderr, "-> (null"); 31427 } 31428 } 31429 31430 ira->instruction_index += 1; 31431 } 31432 31433 ZigType *res_type; 31434 if (new_exec->first_err_trace_msg != nullptr) { 31435 codegen->trace_err = new_exec->first_err_trace_msg; 31436 if (codegen->trace_err != nullptr && new_exec->source_node != nullptr && 31437 !new_exec->source_node->already_traced_this_node) 31438 { 31439 new_exec->source_node->already_traced_this_node = true; 31440 codegen->trace_err = add_error_note(codegen, codegen->trace_err, 31441 new_exec->source_node, buf_create_from_str("referenced here")); 31442 } 31443 res_type = ira->codegen->builtin_types.entry_invalid; 31444 } else if (ira->src_implicit_return_type_list.length == 0) { 31445 res_type = codegen->builtin_types.entry_unreachable; 31446 } else { 31447 res_type = ir_resolve_peer_types(ira, expected_type_source_node, expected_type, ira->src_implicit_return_type_list.items, 31448 ira->src_implicit_return_type_list.length); 31449 } 31450 31451 // It is now safe to free Pass 1 IR instructions. 31452 ira_deref(ira); 31453 31454 return res_type; 31455 } 31456 31457 bool ir_inst_gen_has_side_effects(IrInstGen *instruction) { 31458 switch (instruction->id) { 31459 case IrInstGenIdInvalid: 31460 zig_unreachable(); 31461 case IrInstGenIdBr: 31462 case IrInstGenIdCondBr: 31463 case IrInstGenIdSwitchBr: 31464 case IrInstGenIdDeclVar: 31465 case IrInstGenIdStorePtr: 31466 case IrInstGenIdVectorStoreElem: 31467 case IrInstGenIdCall: 31468 case IrInstGenIdReturn: 31469 case IrInstGenIdUnreachable: 31470 case IrInstGenIdFence: 31471 case IrInstGenIdMemset: 31472 case IrInstGenIdMemcpy: 31473 case IrInstGenIdBreakpoint: 31474 case IrInstGenIdOverflowOp: // TODO when we support multiple returns this can be side effect free 31475 case IrInstGenIdPanic: 31476 case IrInstGenIdSaveErrRetAddr: 31477 case IrInstGenIdAtomicRmw: 31478 case IrInstGenIdAtomicStore: 31479 case IrInstGenIdCmpxchg: 31480 case IrInstGenIdAssertZero: 31481 case IrInstGenIdAssertNonNull: 31482 case IrInstGenIdPtrOfArrayToSlice: 31483 case IrInstGenIdSlice: 31484 case IrInstGenIdOptionalWrap: 31485 case IrInstGenIdVectorToArray: 31486 case IrInstGenIdSuspendBegin: 31487 case IrInstGenIdSuspendFinish: 31488 case IrInstGenIdResume: 31489 case IrInstGenIdAwait: 31490 case IrInstGenIdSpillBegin: 31491 case IrInstGenIdWasmMemoryGrow: 31492 return true; 31493 31494 case IrInstGenIdPhi: 31495 case IrInstGenIdBinOp: 31496 case IrInstGenIdConst: 31497 case IrInstGenIdCast: 31498 case IrInstGenIdElemPtr: 31499 case IrInstGenIdVarPtr: 31500 case IrInstGenIdReturnPtr: 31501 case IrInstGenIdStructFieldPtr: 31502 case IrInstGenIdTestNonNull: 31503 case IrInstGenIdClz: 31504 case IrInstGenIdCtz: 31505 case IrInstGenIdPopCount: 31506 case IrInstGenIdBswap: 31507 case IrInstGenIdBitReverse: 31508 case IrInstGenIdUnionTag: 31509 case IrInstGenIdTruncate: 31510 case IrInstGenIdShuffleVector: 31511 case IrInstGenIdSplat: 31512 case IrInstGenIdBoolNot: 31513 case IrInstGenIdReturnAddress: 31514 case IrInstGenIdFrameAddress: 31515 case IrInstGenIdFrameHandle: 31516 case IrInstGenIdFrameSize: 31517 case IrInstGenIdTestErr: 31518 case IrInstGenIdPtrCast: 31519 case IrInstGenIdBitCast: 31520 case IrInstGenIdWidenOrShorten: 31521 case IrInstGenIdPtrToInt: 31522 case IrInstGenIdIntToPtr: 31523 case IrInstGenIdIntToEnum: 31524 case IrInstGenIdIntToErr: 31525 case IrInstGenIdErrToInt: 31526 case IrInstGenIdErrName: 31527 case IrInstGenIdTagName: 31528 case IrInstGenIdFieldParentPtr: 31529 case IrInstGenIdAlignCast: 31530 case IrInstGenIdErrorReturnTrace: 31531 case IrInstGenIdFloatOp: 31532 case IrInstGenIdMulAdd: 31533 case IrInstGenIdAtomicLoad: 31534 case IrInstGenIdArrayToVector: 31535 case IrInstGenIdAlloca: 31536 case IrInstGenIdSpillEnd: 31537 case IrInstGenIdVectorExtractElem: 31538 case IrInstGenIdBinaryNot: 31539 case IrInstGenIdNegation: 31540 case IrInstGenIdNegationWrapping: 31541 case IrInstGenIdWasmMemorySize: 31542 return false; 31543 31544 case IrInstGenIdAsm: 31545 { 31546 IrInstGenAsm *asm_instruction = (IrInstGenAsm *)instruction; 31547 return asm_instruction->has_side_effects; 31548 } 31549 case IrInstGenIdUnwrapErrPayload: 31550 { 31551 IrInstGenUnwrapErrPayload *unwrap_err_payload_instruction = 31552 (IrInstGenUnwrapErrPayload *)instruction; 31553 return unwrap_err_payload_instruction->safety_check_on || 31554 unwrap_err_payload_instruction->initializing; 31555 } 31556 case IrInstGenIdUnwrapErrCode: 31557 return reinterpret_cast<IrInstGenUnwrapErrCode *>(instruction)->initializing; 31558 case IrInstGenIdUnionFieldPtr: 31559 return reinterpret_cast<IrInstGenUnionFieldPtr *>(instruction)->initializing; 31560 case IrInstGenIdOptionalUnwrapPtr: 31561 return reinterpret_cast<IrInstGenOptionalUnwrapPtr *>(instruction)->initializing; 31562 case IrInstGenIdErrWrapPayload: 31563 return reinterpret_cast<IrInstGenErrWrapPayload *>(instruction)->result_loc != nullptr; 31564 case IrInstGenIdErrWrapCode: 31565 return reinterpret_cast<IrInstGenErrWrapCode *>(instruction)->result_loc != nullptr; 31566 case IrInstGenIdLoadPtr: 31567 return reinterpret_cast<IrInstGenLoadPtr *>(instruction)->result_loc != nullptr; 31568 case IrInstGenIdRef: 31569 return reinterpret_cast<IrInstGenRef *>(instruction)->result_loc != nullptr; 31570 } 31571 zig_unreachable(); 31572 } 31573 31574 bool ir_inst_src_has_side_effects(IrInstSrc *instruction) { 31575 switch (instruction->id) { 31576 case IrInstSrcIdInvalid: 31577 zig_unreachable(); 31578 case IrInstSrcIdBr: 31579 case IrInstSrcIdCondBr: 31580 case IrInstSrcIdSwitchBr: 31581 case IrInstSrcIdDeclVar: 31582 case IrInstSrcIdStorePtr: 31583 case IrInstSrcIdCallExtra: 31584 case IrInstSrcIdCall: 31585 case IrInstSrcIdCallArgs: 31586 case IrInstSrcIdReturn: 31587 case IrInstSrcIdUnreachable: 31588 case IrInstSrcIdSetCold: 31589 case IrInstSrcIdSetRuntimeSafety: 31590 case IrInstSrcIdSetFloatMode: 31591 case IrInstSrcIdImport: 31592 case IrInstSrcIdCompileErr: 31593 case IrInstSrcIdCompileLog: 31594 case IrInstSrcIdCImport: 31595 case IrInstSrcIdCInclude: 31596 case IrInstSrcIdCDefine: 31597 case IrInstSrcIdCUndef: 31598 case IrInstSrcIdFence: 31599 case IrInstSrcIdMemset: 31600 case IrInstSrcIdMemcpy: 31601 case IrInstSrcIdBreakpoint: 31602 case IrInstSrcIdOverflowOp: // TODO when we support multiple returns this can be side effect free 31603 case IrInstSrcIdCheckSwitchProngs: 31604 case IrInstSrcIdCheckStatementIsVoid: 31605 case IrInstSrcIdCheckRuntimeScope: 31606 case IrInstSrcIdPanic: 31607 case IrInstSrcIdSetEvalBranchQuota: 31608 case IrInstSrcIdPtrType: 31609 case IrInstSrcIdSetAlignStack: 31610 case IrInstSrcIdExport: 31611 case IrInstSrcIdSaveErrRetAddr: 31612 case IrInstSrcIdAddImplicitReturnType: 31613 case IrInstSrcIdAtomicRmw: 31614 case IrInstSrcIdAtomicStore: 31615 case IrInstSrcIdCmpxchg: 31616 case IrInstSrcIdUndeclaredIdent: 31617 case IrInstSrcIdEndExpr: 31618 case IrInstSrcIdResetResult: 31619 case IrInstSrcIdSuspendBegin: 31620 case IrInstSrcIdSuspendFinish: 31621 case IrInstSrcIdResume: 31622 case IrInstSrcIdAwait: 31623 case IrInstSrcIdSpillBegin: 31624 case IrInstSrcIdWasmMemoryGrow: 31625 return true; 31626 31627 case IrInstSrcIdPhi: 31628 case IrInstSrcIdUnOp: 31629 case IrInstSrcIdBinOp: 31630 case IrInstSrcIdMergeErrSets: 31631 case IrInstSrcIdLoadPtr: 31632 case IrInstSrcIdConst: 31633 case IrInstSrcIdContainerInitList: 31634 case IrInstSrcIdContainerInitFields: 31635 case IrInstSrcIdUnionInitNamedField: 31636 case IrInstSrcIdFieldPtr: 31637 case IrInstSrcIdElemPtr: 31638 case IrInstSrcIdVarPtr: 31639 case IrInstSrcIdTypeOf: 31640 case IrInstSrcIdArrayType: 31641 case IrInstSrcIdSliceType: 31642 case IrInstSrcIdAnyFrameType: 31643 case IrInstSrcIdSizeOf: 31644 case IrInstSrcIdTestNonNull: 31645 case IrInstSrcIdOptionalUnwrapPtr: 31646 case IrInstSrcIdClz: 31647 case IrInstSrcIdCtz: 31648 case IrInstSrcIdPopCount: 31649 case IrInstSrcIdBswap: 31650 case IrInstSrcIdBitReverse: 31651 case IrInstSrcIdSwitchVar: 31652 case IrInstSrcIdSwitchElseVar: 31653 case IrInstSrcIdSwitchTarget: 31654 case IrInstSrcIdRef: 31655 case IrInstSrcIdEmbedFile: 31656 case IrInstSrcIdTruncate: 31657 case IrInstSrcIdVectorType: 31658 case IrInstSrcIdShuffleVector: 31659 case IrInstSrcIdSplat: 31660 case IrInstSrcIdBoolNot: 31661 case IrInstSrcIdSlice: 31662 case IrInstSrcIdAlignOf: 31663 case IrInstSrcIdReturnAddress: 31664 case IrInstSrcIdFrameAddress: 31665 case IrInstSrcIdFrameHandle: 31666 case IrInstSrcIdFrameType: 31667 case IrInstSrcIdFrameSize: 31668 case IrInstSrcIdTestErr: 31669 case IrInstSrcIdFnProto: 31670 case IrInstSrcIdTestComptime: 31671 case IrInstSrcIdPtrCast: 31672 case IrInstSrcIdBitCast: 31673 case IrInstSrcIdPtrToInt: 31674 case IrInstSrcIdIntToPtr: 31675 case IrInstSrcIdIntToEnum: 31676 case IrInstSrcIdIntToErr: 31677 case IrInstSrcIdErrToInt: 31678 case IrInstSrcIdDeclRef: 31679 case IrInstSrcIdErrName: 31680 case IrInstSrcIdTypeName: 31681 case IrInstSrcIdTagName: 31682 case IrInstSrcIdFieldParentPtr: 31683 case IrInstSrcIdByteOffsetOf: 31684 case IrInstSrcIdBitOffsetOf: 31685 case IrInstSrcIdTypeInfo: 31686 case IrInstSrcIdType: 31687 case IrInstSrcIdHasField: 31688 case IrInstSrcIdAlignCast: 31689 case IrInstSrcIdImplicitCast: 31690 case IrInstSrcIdResolveResult: 31691 case IrInstSrcIdOpaqueType: 31692 case IrInstSrcIdArgType: 31693 case IrInstSrcIdTagType: 31694 case IrInstSrcIdErrorReturnTrace: 31695 case IrInstSrcIdErrorUnion: 31696 case IrInstSrcIdFloatOp: 31697 case IrInstSrcIdMulAdd: 31698 case IrInstSrcIdAtomicLoad: 31699 case IrInstSrcIdIntCast: 31700 case IrInstSrcIdFloatCast: 31701 case IrInstSrcIdErrSetCast: 31702 case IrInstSrcIdIntToFloat: 31703 case IrInstSrcIdFloatToInt: 31704 case IrInstSrcIdBoolToInt: 31705 case IrInstSrcIdEnumToInt: 31706 case IrInstSrcIdHasDecl: 31707 case IrInstSrcIdAlloca: 31708 case IrInstSrcIdSpillEnd: 31709 case IrInstSrcIdWasmMemorySize: 31710 case IrInstSrcIdSrc: 31711 return false; 31712 31713 case IrInstSrcIdAsm: 31714 { 31715 IrInstSrcAsm *asm_instruction = (IrInstSrcAsm *)instruction; 31716 return asm_instruction->has_side_effects; 31717 } 31718 31719 case IrInstSrcIdUnwrapErrPayload: 31720 { 31721 IrInstSrcUnwrapErrPayload *unwrap_err_payload_instruction = 31722 (IrInstSrcUnwrapErrPayload *)instruction; 31723 return unwrap_err_payload_instruction->safety_check_on || 31724 unwrap_err_payload_instruction->initializing; 31725 } 31726 case IrInstSrcIdUnwrapErrCode: 31727 return reinterpret_cast<IrInstSrcUnwrapErrCode *>(instruction)->initializing; 31728 } 31729 zig_unreachable(); 31730 } 31731 31732 static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, LazyValueFnType *lazy_fn_type) { 31733 Error err; 31734 AstNode *proto_node = lazy_fn_type->proto_node; 31735 31736 FnTypeId fn_type_id = {0}; 31737 init_fn_type_id(&fn_type_id, proto_node, lazy_fn_type->cc, proto_node->data.fn_proto.params.length); 31738 31739 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { 31740 AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); 31741 assert(param_node->type == NodeTypeParamDecl); 31742 31743 bool param_is_var_args = param_node->data.param_decl.is_var_args; 31744 if (param_is_var_args) { 31745 if (fn_type_id.cc == CallingConventionC) { 31746 fn_type_id.param_count = fn_type_id.next_param_index; 31747 break; 31748 } else { 31749 ir_add_error_node(ira, param_node, 31750 buf_sprintf("var args only allowed in functions with C calling convention")); 31751 return nullptr; 31752 } 31753 } 31754 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; 31755 param_info->is_noalias = param_node->data.param_decl.is_noalias; 31756 31757 if (lazy_fn_type->param_types[fn_type_id.next_param_index] == nullptr) { 31758 param_info->type = nullptr; 31759 return get_generic_fn_type(ira->codegen, &fn_type_id); 31760 } else { 31761 IrInstGen *param_type_inst = lazy_fn_type->param_types[fn_type_id.next_param_index]; 31762 ZigType *param_type = ir_resolve_type(ira, param_type_inst); 31763 if (type_is_invalid(param_type)) 31764 return nullptr; 31765 31766 if(!is_valid_param_type(param_type)){ 31767 if(param_type->id == ZigTypeIdOpaque){ 31768 ir_add_error(ira, ¶m_type_inst->base, 31769 buf_sprintf("parameter of opaque type '%s' not allowed", buf_ptr(¶m_type->name))); 31770 } else { 31771 ir_add_error(ira, ¶m_type_inst->base, 31772 buf_sprintf("parameter of type '%s' not allowed", buf_ptr(¶m_type->name))); 31773 } 31774 31775 return nullptr; 31776 } 31777 31778 switch (type_requires_comptime(ira->codegen, param_type)) { 31779 case ReqCompTimeYes: 31780 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 31781 ir_add_error(ira, ¶m_type_inst->base, 31782 buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", 31783 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 31784 return nullptr; 31785 } 31786 param_info->type = param_type; 31787 fn_type_id.next_param_index += 1; 31788 return get_generic_fn_type(ira->codegen, &fn_type_id); 31789 case ReqCompTimeInvalid: 31790 return nullptr; 31791 case ReqCompTimeNo: 31792 break; 31793 } 31794 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 31795 bool has_bits; 31796 if ((err = type_has_bits2(ira->codegen, param_type, &has_bits))) 31797 return nullptr; 31798 if (!has_bits) { 31799 ir_add_error(ira, ¶m_type_inst->base, 31800 buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", 31801 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 31802 return nullptr; 31803 } 31804 } 31805 param_info->type = param_type; 31806 } 31807 } 31808 31809 if (lazy_fn_type->align_inst != nullptr) { 31810 if (!ir_resolve_align(ira, lazy_fn_type->align_inst, nullptr, &fn_type_id.alignment)) 31811 return nullptr; 31812 } 31813 31814 fn_type_id.return_type = ir_resolve_type(ira, lazy_fn_type->return_type); 31815 if (type_is_invalid(fn_type_id.return_type)) 31816 return nullptr; 31817 if (fn_type_id.return_type->id == ZigTypeIdOpaque) { 31818 ir_add_error(ira, &lazy_fn_type->return_type->base, buf_create_from_str("return type cannot be opaque")); 31819 return nullptr; 31820 } 31821 31822 return get_fn_type(ira->codegen, &fn_type_id); 31823 } 31824 31825 static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) { 31826 Error err; 31827 if (val->special != ConstValSpecialLazy) 31828 return ErrorNone; 31829 switch (val->data.x_lazy->id) { 31830 case LazyValueIdInvalid: 31831 zig_unreachable(); 31832 case LazyValueIdTypeInfoDecls: { 31833 LazyValueTypeInfoDecls *type_info_decls = reinterpret_cast<LazyValueTypeInfoDecls *>(val->data.x_lazy); 31834 IrAnalyze *ira = type_info_decls->ira; 31835 31836 if ((err = ir_make_type_info_decls(ira, type_info_decls->source_instr, val, type_info_decls->decls_scope, true))) 31837 { 31838 return err; 31839 }; 31840 31841 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 31842 return ErrorNone; 31843 } 31844 case LazyValueIdAlignOf: { 31845 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy); 31846 IrAnalyze *ira = lazy_align_of->ira; 31847 31848 if (lazy_align_of->target_type->value->special == ConstValSpecialStatic) { 31849 switch (lazy_align_of->target_type->value->data.x_type->id) { 31850 case ZigTypeIdInvalid: 31851 zig_unreachable(); 31852 case ZigTypeIdMetaType: 31853 case ZigTypeIdUnreachable: 31854 case ZigTypeIdComptimeFloat: 31855 case ZigTypeIdComptimeInt: 31856 case ZigTypeIdEnumLiteral: 31857 case ZigTypeIdUndefined: 31858 case ZigTypeIdNull: 31859 case ZigTypeIdBoundFn: 31860 case ZigTypeIdVoid: 31861 case ZigTypeIdOpaque: 31862 ir_add_error(ira, &lazy_align_of->target_type->base, 31863 buf_sprintf("no align available for type '%s'", 31864 buf_ptr(&lazy_align_of->target_type->value->data.x_type->name))); 31865 return ErrorSemanticAnalyzeFail; 31866 case ZigTypeIdBool: 31867 case ZigTypeIdInt: 31868 case ZigTypeIdFloat: 31869 case ZigTypeIdPointer: 31870 case ZigTypeIdArray: 31871 case ZigTypeIdStruct: 31872 case ZigTypeIdOptional: 31873 case ZigTypeIdErrorUnion: 31874 case ZigTypeIdErrorSet: 31875 case ZigTypeIdEnum: 31876 case ZigTypeIdUnion: 31877 case ZigTypeIdFn: 31878 case ZigTypeIdVector: 31879 case ZigTypeIdFnFrame: 31880 case ZigTypeIdAnyFrame: 31881 break; 31882 } 31883 } 31884 31885 uint32_t align_in_bytes; 31886 if ((err = type_val_resolve_abi_align(ira->codegen, source_node, 31887 lazy_align_of->target_type->value, &align_in_bytes))) 31888 { 31889 return err; 31890 } 31891 31892 val->special = ConstValSpecialStatic; 31893 assert(val->type->id == ZigTypeIdComptimeInt || val->type->id == ZigTypeIdInt); 31894 bigint_init_unsigned(&val->data.x_bigint, align_in_bytes); 31895 31896 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 31897 return ErrorNone; 31898 } 31899 case LazyValueIdSizeOf: { 31900 LazyValueSizeOf *lazy_size_of = reinterpret_cast<LazyValueSizeOf *>(val->data.x_lazy); 31901 IrAnalyze *ira = lazy_size_of->ira; 31902 31903 if (lazy_size_of->target_type->value->special == ConstValSpecialStatic) { 31904 switch (lazy_size_of->target_type->value->data.x_type->id) { 31905 case ZigTypeIdInvalid: // handled above 31906 zig_unreachable(); 31907 case ZigTypeIdUnreachable: 31908 case ZigTypeIdUndefined: 31909 case ZigTypeIdNull: 31910 case ZigTypeIdBoundFn: 31911 case ZigTypeIdOpaque: 31912 ir_add_error(ira, &lazy_size_of->target_type->base, 31913 buf_sprintf("no size available for type '%s'", 31914 buf_ptr(&lazy_size_of->target_type->value->data.x_type->name))); 31915 return ErrorSemanticAnalyzeFail; 31916 case ZigTypeIdMetaType: 31917 case ZigTypeIdEnumLiteral: 31918 case ZigTypeIdComptimeFloat: 31919 case ZigTypeIdComptimeInt: 31920 case ZigTypeIdVoid: 31921 case ZigTypeIdBool: 31922 case ZigTypeIdInt: 31923 case ZigTypeIdFloat: 31924 case ZigTypeIdPointer: 31925 case ZigTypeIdArray: 31926 case ZigTypeIdStruct: 31927 case ZigTypeIdOptional: 31928 case ZigTypeIdErrorUnion: 31929 case ZigTypeIdErrorSet: 31930 case ZigTypeIdEnum: 31931 case ZigTypeIdUnion: 31932 case ZigTypeIdFn: 31933 case ZigTypeIdVector: 31934 case ZigTypeIdFnFrame: 31935 case ZigTypeIdAnyFrame: 31936 break; 31937 } 31938 } 31939 31940 size_t abi_size; 31941 size_t size_in_bits; 31942 if ((err = type_val_resolve_abi_size(ira->codegen, source_node, lazy_size_of->target_type->value, 31943 &abi_size, &size_in_bits))) 31944 { 31945 return err; 31946 } 31947 31948 val->special = ConstValSpecialStatic; 31949 assert(val->type->id == ZigTypeIdComptimeInt || val->type->id == ZigTypeIdInt); 31950 if (lazy_size_of->bit_size) 31951 bigint_init_unsigned(&val->data.x_bigint, size_in_bits); 31952 else 31953 bigint_init_unsigned(&val->data.x_bigint, abi_size); 31954 31955 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 31956 return ErrorNone; 31957 } 31958 case LazyValueIdSliceType: { 31959 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(val->data.x_lazy); 31960 IrAnalyze *ira = lazy_slice_type->ira; 31961 31962 ZigType *elem_type = ir_resolve_type(ira, lazy_slice_type->elem_type); 31963 if (type_is_invalid(elem_type)) 31964 return ErrorSemanticAnalyzeFail; 31965 31966 ZigValue *sentinel_val; 31967 if (lazy_slice_type->sentinel != nullptr) { 31968 if (type_is_invalid(lazy_slice_type->sentinel->value->type)) 31969 return ErrorSemanticAnalyzeFail; 31970 IrInstGen *sentinel = ir_implicit_cast(ira, lazy_slice_type->sentinel, elem_type); 31971 if (type_is_invalid(sentinel->value->type)) 31972 return ErrorSemanticAnalyzeFail; 31973 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 31974 if (sentinel_val == nullptr) 31975 return ErrorSemanticAnalyzeFail; 31976 } else { 31977 sentinel_val = nullptr; 31978 } 31979 31980 uint32_t align_bytes = 0; 31981 if (lazy_slice_type->align_inst != nullptr) { 31982 if (!ir_resolve_align(ira, lazy_slice_type->align_inst, elem_type, &align_bytes)) 31983 return ErrorSemanticAnalyzeFail; 31984 } 31985 31986 switch (elem_type->id) { 31987 case ZigTypeIdInvalid: // handled above 31988 zig_unreachable(); 31989 case ZigTypeIdUnreachable: 31990 case ZigTypeIdUndefined: 31991 case ZigTypeIdNull: 31992 case ZigTypeIdOpaque: 31993 ir_add_error(ira, &lazy_slice_type->elem_type->base, 31994 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&elem_type->name))); 31995 return ErrorSemanticAnalyzeFail; 31996 case ZigTypeIdMetaType: 31997 case ZigTypeIdVoid: 31998 case ZigTypeIdBool: 31999 case ZigTypeIdInt: 32000 case ZigTypeIdFloat: 32001 case ZigTypeIdPointer: 32002 case ZigTypeIdArray: 32003 case ZigTypeIdStruct: 32004 case ZigTypeIdComptimeFloat: 32005 case ZigTypeIdComptimeInt: 32006 case ZigTypeIdEnumLiteral: 32007 case ZigTypeIdOptional: 32008 case ZigTypeIdErrorUnion: 32009 case ZigTypeIdErrorSet: 32010 case ZigTypeIdEnum: 32011 case ZigTypeIdUnion: 32012 case ZigTypeIdFn: 32013 case ZigTypeIdBoundFn: 32014 case ZigTypeIdVector: 32015 case ZigTypeIdFnFrame: 32016 case ZigTypeIdAnyFrame: 32017 break; 32018 } 32019 32020 ResolveStatus needed_status = (align_bytes == 0) ? 32021 ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; 32022 if ((err = type_resolve(ira->codegen, elem_type, needed_status))) 32023 return err; 32024 ZigType *slice_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 32025 lazy_slice_type->is_const, lazy_slice_type->is_volatile, 32026 PtrLenUnknown, 32027 align_bytes, 32028 0, 0, lazy_slice_type->is_allowzero, 32029 VECTOR_INDEX_NONE, nullptr, sentinel_val); 32030 val->special = ConstValSpecialStatic; 32031 assert(val->type->id == ZigTypeIdMetaType); 32032 val->data.x_type = get_slice_type(ira->codegen, slice_ptr_type); 32033 32034 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32035 return ErrorNone; 32036 } 32037 case LazyValueIdPtrType: { 32038 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(val->data.x_lazy); 32039 IrAnalyze *ira = lazy_ptr_type->ira; 32040 32041 ZigType *elem_type = ir_resolve_type(ira, lazy_ptr_type->elem_type); 32042 if (type_is_invalid(elem_type)) 32043 return ErrorSemanticAnalyzeFail; 32044 32045 ZigValue *sentinel_val; 32046 if (lazy_ptr_type->sentinel != nullptr) { 32047 if (type_is_invalid(lazy_ptr_type->sentinel->value->type)) 32048 return ErrorSemanticAnalyzeFail; 32049 IrInstGen *sentinel = ir_implicit_cast(ira, lazy_ptr_type->sentinel, elem_type); 32050 if (type_is_invalid(sentinel->value->type)) 32051 return ErrorSemanticAnalyzeFail; 32052 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 32053 if (sentinel_val == nullptr) 32054 return ErrorSemanticAnalyzeFail; 32055 } else { 32056 sentinel_val = nullptr; 32057 } 32058 32059 uint32_t align_bytes = 0; 32060 if (lazy_ptr_type->align_inst != nullptr) { 32061 if (!ir_resolve_align(ira, lazy_ptr_type->align_inst, elem_type, &align_bytes)) 32062 return ErrorSemanticAnalyzeFail; 32063 } 32064 32065 if (elem_type->id == ZigTypeIdUnreachable) { 32066 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 32067 buf_create_from_str("pointer to noreturn not allowed")); 32068 return ErrorSemanticAnalyzeFail; 32069 } else if (elem_type->id == ZigTypeIdOpaque && lazy_ptr_type->ptr_len == PtrLenUnknown) { 32070 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 32071 buf_create_from_str("unknown-length pointer to opaque")); 32072 return ErrorSemanticAnalyzeFail; 32073 } else if (lazy_ptr_type->ptr_len == PtrLenC) { 32074 bool ok_type; 32075 if ((err = type_allowed_in_extern(ira->codegen, elem_type, &ok_type))) 32076 return err; 32077 if (!ok_type) { 32078 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 32079 buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", 32080 buf_ptr(&elem_type->name))); 32081 return ErrorSemanticAnalyzeFail; 32082 } else if (elem_type->id == ZigTypeIdOpaque) { 32083 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 32084 buf_sprintf("C pointers cannot point to opaque types")); 32085 return ErrorSemanticAnalyzeFail; 32086 } else if (lazy_ptr_type->is_allowzero) { 32087 ir_add_error(ira, &lazy_ptr_type->elem_type->base, 32088 buf_sprintf("C pointers always allow address zero")); 32089 return ErrorSemanticAnalyzeFail; 32090 } 32091 } 32092 32093 if (align_bytes != 0) { 32094 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusAlignmentKnown))) 32095 return err; 32096 if (!type_has_bits(ira->codegen, elem_type)) 32097 align_bytes = 0; 32098 } 32099 bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC; 32100 assert(val->type->id == ZigTypeIdMetaType); 32101 val->data.x_type = get_pointer_to_type_extra2(ira->codegen, elem_type, 32102 lazy_ptr_type->is_const, lazy_ptr_type->is_volatile, lazy_ptr_type->ptr_len, align_bytes, 32103 lazy_ptr_type->bit_offset_in_host, lazy_ptr_type->host_int_bytes, 32104 allow_zero, VECTOR_INDEX_NONE, nullptr, sentinel_val); 32105 val->special = ConstValSpecialStatic; 32106 32107 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32108 return ErrorNone; 32109 } 32110 case LazyValueIdArrayType: { 32111 LazyValueArrayType *lazy_array_type = reinterpret_cast<LazyValueArrayType *>(val->data.x_lazy); 32112 IrAnalyze *ira = lazy_array_type->ira; 32113 32114 ZigType *elem_type = ir_resolve_type(ira, lazy_array_type->elem_type); 32115 if (type_is_invalid(elem_type)) 32116 return ErrorSemanticAnalyzeFail; 32117 32118 switch (elem_type->id) { 32119 case ZigTypeIdInvalid: // handled above 32120 zig_unreachable(); 32121 case ZigTypeIdUnreachable: 32122 case ZigTypeIdUndefined: 32123 case ZigTypeIdNull: 32124 case ZigTypeIdOpaque: 32125 ir_add_error(ira, &lazy_array_type->elem_type->base, 32126 buf_sprintf("array of type '%s' not allowed", 32127 buf_ptr(&elem_type->name))); 32128 return ErrorSemanticAnalyzeFail; 32129 case ZigTypeIdMetaType: 32130 case ZigTypeIdVoid: 32131 case ZigTypeIdBool: 32132 case ZigTypeIdInt: 32133 case ZigTypeIdFloat: 32134 case ZigTypeIdPointer: 32135 case ZigTypeIdArray: 32136 case ZigTypeIdStruct: 32137 case ZigTypeIdComptimeFloat: 32138 case ZigTypeIdComptimeInt: 32139 case ZigTypeIdEnumLiteral: 32140 case ZigTypeIdOptional: 32141 case ZigTypeIdErrorUnion: 32142 case ZigTypeIdErrorSet: 32143 case ZigTypeIdEnum: 32144 case ZigTypeIdUnion: 32145 case ZigTypeIdFn: 32146 case ZigTypeIdBoundFn: 32147 case ZigTypeIdVector: 32148 case ZigTypeIdFnFrame: 32149 case ZigTypeIdAnyFrame: 32150 break; 32151 } 32152 32153 if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) 32154 return err; 32155 32156 ZigValue *sentinel_val = nullptr; 32157 if (lazy_array_type->sentinel != nullptr) { 32158 if (type_is_invalid(lazy_array_type->sentinel->value->type)) 32159 return ErrorSemanticAnalyzeFail; 32160 IrInstGen *sentinel = ir_implicit_cast(ira, lazy_array_type->sentinel, elem_type); 32161 if (type_is_invalid(sentinel->value->type)) 32162 return ErrorSemanticAnalyzeFail; 32163 sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); 32164 if (sentinel_val == nullptr) 32165 return ErrorSemanticAnalyzeFail; 32166 } 32167 32168 assert(val->type->id == ZigTypeIdMetaType); 32169 val->data.x_type = get_array_type(ira->codegen, elem_type, lazy_array_type->length, sentinel_val); 32170 val->special = ConstValSpecialStatic; 32171 32172 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32173 return ErrorNone; 32174 } 32175 case LazyValueIdOptType: { 32176 LazyValueOptType *lazy_opt_type = reinterpret_cast<LazyValueOptType *>(val->data.x_lazy); 32177 IrAnalyze *ira = lazy_opt_type->ira; 32178 32179 ZigType *payload_type = ir_resolve_type(ira, lazy_opt_type->payload_type); 32180 if (type_is_invalid(payload_type)) 32181 return ErrorSemanticAnalyzeFail; 32182 32183 if (payload_type->id == ZigTypeIdOpaque || payload_type->id == ZigTypeIdUnreachable) { 32184 ir_add_error(ira, &lazy_opt_type->payload_type->base, 32185 buf_sprintf("type '%s' cannot be optional", buf_ptr(&payload_type->name))); 32186 return ErrorSemanticAnalyzeFail; 32187 } 32188 32189 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 32190 return err; 32191 32192 assert(val->type->id == ZigTypeIdMetaType); 32193 val->data.x_type = get_optional_type(ira->codegen, payload_type); 32194 val->special = ConstValSpecialStatic; 32195 32196 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32197 return ErrorNone; 32198 } 32199 case LazyValueIdFnType: { 32200 LazyValueFnType *lazy_fn_type = reinterpret_cast<LazyValueFnType *>(val->data.x_lazy); 32201 IrAnalyze *ira = lazy_fn_type->ira; 32202 ZigType *fn_type = ir_resolve_lazy_fn_type(ira, source_node, lazy_fn_type); 32203 if (fn_type == nullptr) 32204 return ErrorSemanticAnalyzeFail; 32205 val->special = ConstValSpecialStatic; 32206 assert(val->type->id == ZigTypeIdMetaType); 32207 val->data.x_type = fn_type; 32208 32209 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32210 return ErrorNone; 32211 } 32212 case LazyValueIdErrUnionType: { 32213 LazyValueErrUnionType *lazy_err_union_type = 32214 reinterpret_cast<LazyValueErrUnionType *>(val->data.x_lazy); 32215 IrAnalyze *ira = lazy_err_union_type->ira; 32216 32217 ZigType *err_set_type = ir_resolve_type(ira, lazy_err_union_type->err_set_type); 32218 if (type_is_invalid(err_set_type)) 32219 return ErrorSemanticAnalyzeFail; 32220 32221 ZigType *payload_type = ir_resolve_type(ira, lazy_err_union_type->payload_type); 32222 if (type_is_invalid(payload_type)) 32223 return ErrorSemanticAnalyzeFail; 32224 32225 if (err_set_type->id != ZigTypeIdErrorSet) { 32226 ir_add_error(ira, &lazy_err_union_type->err_set_type->base, 32227 buf_sprintf("expected error set type, found type '%s'", 32228 buf_ptr(&err_set_type->name))); 32229 return ErrorSemanticAnalyzeFail; 32230 } 32231 32232 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 32233 return ErrorSemanticAnalyzeFail; 32234 32235 assert(val->type->id == ZigTypeIdMetaType); 32236 val->data.x_type = get_error_union_type(ira->codegen, err_set_type, payload_type); 32237 val->special = ConstValSpecialStatic; 32238 32239 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it. 32240 return ErrorNone; 32241 } 32242 } 32243 zig_unreachable(); 32244 } 32245 32246 Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ZigValue *val) { 32247 Error err; 32248 if ((err = ir_resolve_lazy_raw(source_node, val))) { 32249 if (codegen->trace_err != nullptr && source_node != nullptr && !source_node->already_traced_this_node) { 32250 source_node->already_traced_this_node = true; 32251 codegen->trace_err = add_error_note(codegen, codegen->trace_err, source_node, 32252 buf_create_from_str("referenced here")); 32253 } 32254 return err; 32255 } 32256 if (type_is_invalid(val->type)) { 32257 return ErrorSemanticAnalyzeFail; 32258 } 32259 return ErrorNone; 32260 } 32261 32262 void IrInst::src() { 32263 IrInst *inst = this; 32264 if (inst->source_node != nullptr) { 32265 inst->source_node->src(); 32266 } else { 32267 fprintf(stderr, "(null source node)\n"); 32268 } 32269 } 32270 32271 void IrInst::dump() { 32272 this->src(); 32273 fprintf(stderr, "IrInst(#%" PRIu32 ")\n", this->debug_id); 32274 } 32275 32276 void IrInstSrc::src() { 32277 this->base.src(); 32278 } 32279 32280 void IrInstGen::src() { 32281 this->base.src(); 32282 } 32283 32284 void IrInstSrc::dump() { 32285 IrInstSrc *inst = this; 32286 inst->src(); 32287 if (inst->base.scope == nullptr) { 32288 fprintf(stderr, "(null scope)\n"); 32289 } else { 32290 ir_print_inst_src(inst->base.scope->codegen, stderr, inst, 0); 32291 fprintf(stderr, "-> "); 32292 ir_print_inst_gen(inst->base.scope->codegen, stderr, inst->child, 0); 32293 } 32294 } 32295 void IrInstGen::dump() { 32296 IrInstGen *inst = this; 32297 inst->src(); 32298 if (inst->base.scope == nullptr) { 32299 fprintf(stderr, "(null scope)\n"); 32300 } else { 32301 ir_print_inst_gen(inst->base.scope->codegen, stderr, inst, 0); 32302 } 32303 } 32304 32305 void IrAnalyze::dump() { 32306 ir_print_gen(this->codegen, stderr, this->new_irb.exec, 0); 32307 if (this->new_irb.current_basic_block != nullptr) { 32308 fprintf(stderr, "Current basic block:\n"); 32309 ir_print_basic_block_gen(this->codegen, stderr, this->new_irb.current_basic_block, 1); 32310 } 32311 } 32312 32313 void dbg_ir_break(const char *src_file, uint32_t line) { 32314 dbg_ir_breakpoints_buf[dbg_ir_breakpoints_count] = {src_file, line}; 32315 dbg_ir_breakpoints_count += 1; 32316 } 32317 void dbg_ir_clear(void) { 32318 dbg_ir_breakpoints_count = 0; 32319 }