blob 798f406c (486773B) - Raw
1 /* 2 * Copyright (c) 2015 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 "codegen.hpp" 11 #include "compiler.hpp" 12 #include "config.h" 13 #include "errmsg.hpp" 14 #include "error.hpp" 15 #include "hash_map.hpp" 16 #include "ir.hpp" 17 #include "os.hpp" 18 #include "target.hpp" 19 #include "util.hpp" 20 #include "zig_llvm.h" 21 #include "userland.h" 22 #include "dump_analysis.hpp" 23 24 #include <stdio.h> 25 #include <errno.h> 26 27 enum ResumeId { 28 ResumeIdManual, 29 ResumeIdReturn, 30 ResumeIdCall, 31 }; 32 33 // TODO https://github.com/ziglang/zig/issues/2883 34 // Until then we have this same default as Clang. 35 // This avoids https://github.com/ziglang/zig/issues/3275 36 static const char *riscv_default_features = "+a,+c,+d,+f,+m,+relax"; 37 38 static void init_darwin_native(CodeGen *g) { 39 char *osx_target = getenv("MACOSX_DEPLOYMENT_TARGET"); 40 char *ios_target = getenv("IPHONEOS_DEPLOYMENT_TARGET"); 41 42 // Allow conflicts among OSX and iOS, but choose the default platform. 43 if (osx_target && ios_target) { 44 if (g->zig_target->arch == ZigLLVM_arm || 45 g->zig_target->arch == ZigLLVM_aarch64 || 46 g->zig_target->arch == ZigLLVM_thumb) 47 { 48 osx_target = nullptr; 49 } else { 50 ios_target = nullptr; 51 } 52 } 53 54 if (osx_target) { 55 g->mmacosx_version_min = buf_create_from_str(osx_target); 56 } else if (ios_target) { 57 g->mios_version_min = buf_create_from_str(ios_target); 58 } else if (g->zig_target->os != OsIOS) { 59 g->mmacosx_version_min = buf_create_from_str("10.14"); 60 } 61 } 62 63 static ZigPackage *new_package(const char *root_src_dir, const char *root_src_path, const char *pkg_path) { 64 ZigPackage *entry = allocate<ZigPackage>(1); 65 entry->package_table.init(4); 66 buf_init_from_str(&entry->root_src_dir, root_src_dir); 67 buf_init_from_str(&entry->root_src_path, root_src_path); 68 buf_init_from_str(&entry->pkg_path, pkg_path); 69 return entry; 70 } 71 72 ZigPackage *new_anonymous_package() { 73 return new_package("", "", ""); 74 } 75 76 static const char *symbols_that_llvm_depends_on[] = { 77 "memcpy", 78 "memset", 79 "sqrt", 80 "powi", 81 "sin", 82 "cos", 83 "pow", 84 "exp", 85 "exp2", 86 "log", 87 "log10", 88 "log2", 89 "fma", 90 "fabs", 91 "minnum", 92 "maxnum", 93 "copysign", 94 "floor", 95 "ceil", 96 "trunc", 97 "rint", 98 "nearbyint", 99 "round", 100 // TODO probably all of compiler-rt needs to go here 101 }; 102 103 void codegen_set_clang_argv(CodeGen *g, const char **args, size_t len) { 104 g->clang_argv = args; 105 g->clang_argv_len = len; 106 } 107 108 void codegen_set_llvm_argv(CodeGen *g, const char **args, size_t len) { 109 g->llvm_argv = args; 110 g->llvm_argv_len = len; 111 } 112 113 void codegen_set_test_filter(CodeGen *g, Buf *filter) { 114 g->test_filter = filter; 115 } 116 117 void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix) { 118 g->test_name_prefix = prefix; 119 } 120 121 void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch) { 122 g->version_major = major; 123 g->version_minor = minor; 124 g->version_patch = patch; 125 } 126 127 void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type) { 128 g->emit_file_type = emit_file_type; 129 } 130 131 void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) { 132 g->each_lib_rpath = each_lib_rpath; 133 } 134 135 void codegen_set_errmsg_color(CodeGen *g, ErrColor err_color) { 136 g->err_color = err_color; 137 } 138 139 void codegen_set_strip(CodeGen *g, bool strip) { 140 g->strip_debug_symbols = strip; 141 if (!target_has_debug_info(g->zig_target)) { 142 g->strip_debug_symbols = true; 143 } 144 } 145 146 void codegen_set_out_name(CodeGen *g, Buf *out_name) { 147 g->root_out_name = out_name; 148 } 149 150 void codegen_add_lib_dir(CodeGen *g, const char *dir) { 151 g->lib_dirs.append(dir); 152 } 153 154 void codegen_add_rpath(CodeGen *g, const char *name) { 155 g->rpath_list.append(buf_create_from_str(name)); 156 } 157 158 LinkLib *codegen_add_link_lib(CodeGen *g, Buf *name) { 159 return add_link_lib(g, name); 160 } 161 162 void codegen_add_forbidden_lib(CodeGen *codegen, Buf *lib) { 163 codegen->forbidden_libs.append(lib); 164 } 165 166 void codegen_add_framework(CodeGen *g, const char *framework) { 167 g->darwin_frameworks.append(buf_create_from_str(framework)); 168 } 169 170 void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min) { 171 g->mmacosx_version_min = mmacosx_version_min; 172 } 173 174 void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min) { 175 g->mios_version_min = mios_version_min; 176 } 177 178 void codegen_set_rdynamic(CodeGen *g, bool rdynamic) { 179 g->linker_rdynamic = rdynamic; 180 } 181 182 void codegen_set_linker_script(CodeGen *g, const char *linker_script) { 183 g->linker_script = linker_script; 184 } 185 186 187 static void render_const_val(CodeGen *g, ZigValue *const_val, const char *name); 188 static void render_const_val_global(CodeGen *g, ZigValue *const_val, const char *name); 189 static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *name); 190 static void generate_error_name_table(CodeGen *g); 191 static bool value_is_all_undef(CodeGen *g, ZigValue *const_val); 192 static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr); 193 static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment); 194 static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstruction *source_instr, 195 LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type, 196 LLVMValueRef result_loc, bool non_async); 197 static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix); 198 199 static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) { 200 unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name)); 201 assert(kind_id != 0); 202 LLVMAttributeRef llvm_attr = LLVMCreateEnumAttribute(LLVMGetGlobalContext(), kind_id, 0); 203 LLVMAddAttributeAtIndex(val, attr_index, llvm_attr); 204 } 205 206 static void addLLVMAttrStr(LLVMValueRef val, LLVMAttributeIndex attr_index, 207 const char *attr_name, const char *attr_val) 208 { 209 LLVMAttributeRef llvm_attr = LLVMCreateStringAttribute(LLVMGetGlobalContext(), 210 attr_name, (unsigned)strlen(attr_name), attr_val, (unsigned)strlen(attr_val)); 211 LLVMAddAttributeAtIndex(val, attr_index, llvm_attr); 212 } 213 214 static void addLLVMAttrInt(LLVMValueRef val, LLVMAttributeIndex attr_index, 215 const char *attr_name, uint64_t attr_val) 216 { 217 unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name)); 218 assert(kind_id != 0); 219 LLVMAttributeRef llvm_attr = LLVMCreateEnumAttribute(LLVMGetGlobalContext(), kind_id, attr_val); 220 LLVMAddAttributeAtIndex(val, attr_index, llvm_attr); 221 } 222 223 static void addLLVMFnAttr(LLVMValueRef fn_val, const char *attr_name) { 224 return addLLVMAttr(fn_val, -1, attr_name); 225 } 226 227 static void addLLVMFnAttrStr(LLVMValueRef fn_val, const char *attr_name, const char *attr_val) { 228 return addLLVMAttrStr(fn_val, -1, attr_name, attr_val); 229 } 230 231 static void addLLVMFnAttrInt(LLVMValueRef fn_val, const char *attr_name, uint64_t attr_val) { 232 return addLLVMAttrInt(fn_val, -1, attr_name, attr_val); 233 } 234 235 static void addLLVMArgAttr(LLVMValueRef fn_val, unsigned param_index, const char *attr_name) { 236 return addLLVMAttr(fn_val, param_index + 1, attr_name); 237 } 238 239 static void addLLVMArgAttrInt(LLVMValueRef fn_val, unsigned param_index, const char *attr_name, uint64_t attr_val) { 240 return addLLVMAttrInt(fn_val, param_index + 1, attr_name, attr_val); 241 } 242 243 static bool is_symbol_available(CodeGen *g, const char *name) { 244 Buf *buf_name = buf_create_from_str(name); 245 bool result = 246 g->exported_symbol_names.maybe_get(buf_name) == nullptr && 247 g->external_prototypes.maybe_get(buf_name) == nullptr; 248 buf_destroy(buf_name); 249 return result; 250 } 251 252 static const char *get_mangled_name(CodeGen *g, const char *original_name, bool external_linkage) { 253 if (external_linkage || is_symbol_available(g, original_name)) { 254 return original_name; 255 } 256 257 int n = 0; 258 for (;; n += 1) { 259 const char *new_name = buf_ptr(buf_sprintf("%s.%d", original_name, n)); 260 if (is_symbol_available(g, new_name)) { 261 return new_name; 262 } 263 } 264 } 265 266 static ZigLLVM_CallingConv get_llvm_cc(CodeGen *g, CallingConvention cc) { 267 switch (cc) { 268 case CallingConventionUnspecified: 269 return ZigLLVM_Fast; 270 case CallingConventionC: 271 return ZigLLVM_C; 272 case CallingConventionCold: 273 if ((g->zig_target->arch == ZigLLVM_x86 || 274 g->zig_target->arch == ZigLLVM_x86_64) && 275 g->zig_target->os != OsWindows) 276 return ZigLLVM_Cold; 277 return ZigLLVM_C; 278 case CallingConventionNaked: 279 zig_unreachable(); 280 case CallingConventionStdcall: 281 if (g->zig_target->arch == ZigLLVM_x86) 282 return ZigLLVM_X86_StdCall; 283 return ZigLLVM_C; 284 case CallingConventionFastcall: 285 if (g->zig_target->arch == ZigLLVM_x86) 286 return ZigLLVM_X86_FastCall; 287 return ZigLLVM_C; 288 case CallingConventionVectorcall: 289 if (g->zig_target->arch == ZigLLVM_x86) 290 return ZigLLVM_X86_VectorCall; 291 if (target_is_arm(g->zig_target) && 292 target_arch_pointer_bit_width(g->zig_target->arch) == 64) 293 return ZigLLVM_AArch64_VectorCall; 294 return ZigLLVM_C; 295 case CallingConventionThiscall: 296 if (g->zig_target->arch == ZigLLVM_x86) 297 return ZigLLVM_X86_ThisCall; 298 return ZigLLVM_C; 299 case CallingConventionAsync: 300 return ZigLLVM_Fast; 301 case CallingConventionAPCS: 302 if (target_is_arm(g->zig_target)) 303 return ZigLLVM_ARM_APCS; 304 return ZigLLVM_C; 305 case CallingConventionAAPCS: 306 if (target_is_arm(g->zig_target)) 307 return ZigLLVM_ARM_AAPCS; 308 return ZigLLVM_C; 309 case CallingConventionAAPCSVFP: 310 if (target_is_arm(g->zig_target)) 311 return ZigLLVM_ARM_AAPCS_VFP; 312 return ZigLLVM_C; 313 case CallingConventionInterrupt: 314 if (g->zig_target->arch == ZigLLVM_x86 || 315 g->zig_target->arch == ZigLLVM_x86_64) 316 return ZigLLVM_X86_INTR; 317 if (g->zig_target->arch == ZigLLVM_avr) 318 return ZigLLVM_AVR_INTR; 319 if (g->zig_target->arch == ZigLLVM_msp430) 320 return ZigLLVM_MSP430_INTR; 321 return ZigLLVM_C; 322 case CallingConventionSignal: 323 if (g->zig_target->arch == ZigLLVM_avr) 324 return ZigLLVM_AVR_SIGNAL; 325 return ZigLLVM_C; 326 } 327 zig_unreachable(); 328 } 329 330 static void add_uwtable_attr(CodeGen *g, LLVMValueRef fn_val) { 331 if (g->zig_target->os == OsWindows) { 332 addLLVMFnAttr(fn_val, "uwtable"); 333 } 334 } 335 336 static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) { 337 switch (id) { 338 case GlobalLinkageIdInternal: 339 return LLVMInternalLinkage; 340 case GlobalLinkageIdStrong: 341 return LLVMExternalLinkage; 342 case GlobalLinkageIdWeak: 343 return LLVMWeakODRLinkage; 344 case GlobalLinkageIdLinkOnce: 345 return LLVMLinkOnceODRLinkage; 346 } 347 zig_unreachable(); 348 } 349 350 // label (grep this): [fn_frame_struct_layout] 351 static uint32_t frame_index_trace_arg(CodeGen *g, ZigType *return_type) { 352 // [0] *ReturnType (callee's) 353 // [1] *ReturnType (awaiter's) 354 // [2] ReturnType 355 uint32_t return_field_count = type_has_bits(return_type) ? 3 : 0; 356 return frame_ret_start + return_field_count; 357 } 358 359 // label (grep this): [fn_frame_struct_layout] 360 static uint32_t frame_index_arg(CodeGen *g, ZigType *return_type) { 361 bool have_stack_trace = codegen_fn_has_err_ret_tracing_arg(g, return_type); 362 // [0] *StackTrace (callee's) 363 // [1] *StackTrace (awaiter's) 364 uint32_t trace_field_count = have_stack_trace ? 2 : 0; 365 return frame_index_trace_arg(g, return_type) + trace_field_count; 366 } 367 368 // label (grep this): [fn_frame_struct_layout] 369 static uint32_t frame_index_trace_stack(CodeGen *g, FnTypeId *fn_type_id) { 370 uint32_t result = frame_index_arg(g, fn_type_id->return_type); 371 for (size_t i = 0; i < fn_type_id->param_count; i += 1) { 372 if (type_has_bits(fn_type_id->param_info->type)) { 373 result += 1; 374 } 375 } 376 return result; 377 } 378 379 380 static uint32_t get_err_ret_trace_arg_index(CodeGen *g, ZigFn *fn_table_entry) { 381 if (!g->have_err_ret_tracing) { 382 return UINT32_MAX; 383 } 384 if (fn_is_async(fn_table_entry)) { 385 return UINT32_MAX; 386 } 387 ZigType *fn_type = fn_table_entry->type_entry; 388 if (!fn_type_can_fail(&fn_type->data.fn.fn_type_id)) { 389 return UINT32_MAX; 390 } 391 ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; 392 bool first_arg_ret = type_has_bits(return_type) && handle_is_ptr(return_type); 393 return first_arg_ret ? 1 : 0; 394 } 395 396 static void maybe_export_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) { 397 if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows && g->is_dynamic) { 398 LLVMSetDLLStorageClass(global_value, LLVMDLLExportStorageClass); 399 } 400 } 401 402 static void maybe_import_dll(CodeGen *g, LLVMValueRef global_value, GlobalLinkageId linkage) { 403 if (linkage != GlobalLinkageIdInternal && g->zig_target->os == OsWindows) { 404 // TODO come up with a good explanation/understanding for why we never do 405 // DLLImportStorageClass. Empirically it only causes problems. But let's have 406 // this documented and then clean up the code accordingly. 407 //LLVMSetDLLStorageClass(global_value, LLVMDLLImportStorageClass); 408 } 409 } 410 411 static bool cc_want_sret_attr(CallingConvention cc) { 412 switch (cc) { 413 case CallingConventionNaked: 414 zig_unreachable(); 415 case CallingConventionC: 416 case CallingConventionCold: 417 case CallingConventionInterrupt: 418 case CallingConventionSignal: 419 case CallingConventionStdcall: 420 case CallingConventionFastcall: 421 case CallingConventionVectorcall: 422 case CallingConventionThiscall: 423 case CallingConventionAPCS: 424 case CallingConventionAAPCS: 425 case CallingConventionAAPCSVFP: 426 return true; 427 case CallingConventionAsync: 428 case CallingConventionUnspecified: 429 return false; 430 } 431 zig_unreachable(); 432 } 433 434 static bool codegen_have_frame_pointer(CodeGen *g) { 435 return g->build_mode == BuildModeDebug; 436 } 437 438 static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { 439 const char *unmangled_name = buf_ptr(&fn->symbol_name); 440 const char *symbol_name; 441 GlobalLinkageId linkage; 442 if (fn->body_node == nullptr) { 443 symbol_name = unmangled_name; 444 linkage = GlobalLinkageIdStrong; 445 } else if (fn->export_list.length == 0) { 446 symbol_name = get_mangled_name(g, unmangled_name, false); 447 linkage = GlobalLinkageIdInternal; 448 } else { 449 GlobalExport *fn_export = &fn->export_list.items[0]; 450 symbol_name = buf_ptr(&fn_export->name); 451 linkage = fn_export->linkage; 452 } 453 454 CallingConvention cc = fn->type_entry->data.fn.fn_type_id.cc; 455 bool is_async = fn_is_async(fn); 456 457 ZigType *fn_type = fn->type_entry; 458 // Make the raw_type_ref populated 459 resolve_llvm_types_fn(g, fn); 460 LLVMTypeRef fn_llvm_type = fn->raw_type_ref; 461 LLVMValueRef llvm_fn = nullptr; 462 if (fn->body_node == nullptr) { 463 const unsigned fn_addrspace = ZigLLVMDataLayoutGetProgramAddressSpace(g->target_data_ref); 464 LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, symbol_name); 465 if (existing_llvm_fn) { 466 return LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, fn_addrspace)); 467 } else { 468 Buf *buf_symbol_name = buf_create_from_str(symbol_name); 469 auto entry = g->exported_symbol_names.maybe_get(buf_symbol_name); 470 buf_destroy(buf_symbol_name); 471 472 if (entry == nullptr) { 473 llvm_fn = LLVMAddFunction(g->module, symbol_name, fn_llvm_type); 474 475 if (target_is_wasm(g->zig_target)) { 476 assert(fn->proto_node->type == NodeTypeFnProto); 477 AstNodeFnProto *fn_proto = &fn->proto_node->data.fn_proto; 478 if (fn_proto-> is_extern && fn_proto->lib_name != nullptr ) { 479 addLLVMFnAttrStr(llvm_fn, "wasm-import-module", buf_ptr(fn_proto->lib_name)); 480 } 481 } 482 } else { 483 assert(entry->value->id == TldIdFn); 484 TldFn *tld_fn = reinterpret_cast<TldFn *>(entry->value); 485 // Make the raw_type_ref populated 486 resolve_llvm_types_fn(g, tld_fn->fn_entry); 487 tld_fn->fn_entry->llvm_value = LLVMAddFunction(g->module, symbol_name, 488 tld_fn->fn_entry->raw_type_ref); 489 llvm_fn = LLVMConstBitCast(tld_fn->fn_entry->llvm_value, LLVMPointerType(fn_llvm_type, fn_addrspace)); 490 return llvm_fn; 491 } 492 } 493 } else { 494 if (llvm_fn == nullptr) { 495 llvm_fn = LLVMAddFunction(g->module, symbol_name, fn_llvm_type); 496 } 497 498 for (size_t i = 1; i < fn->export_list.length; i += 1) { 499 GlobalExport *fn_export = &fn->export_list.items[i]; 500 LLVMAddAlias(g->module, LLVMTypeOf(llvm_fn), llvm_fn, buf_ptr(&fn_export->name)); 501 } 502 } 503 504 switch (fn->fn_inline) { 505 case FnInlineAlways: 506 addLLVMFnAttr(llvm_fn, "alwaysinline"); 507 g->inline_fns.append(fn); 508 break; 509 case FnInlineNever: 510 addLLVMFnAttr(llvm_fn, "noinline"); 511 break; 512 case FnInlineAuto: 513 if (fn->alignstack_value != 0) { 514 addLLVMFnAttr(llvm_fn, "noinline"); 515 } 516 break; 517 } 518 519 if (cc == CallingConventionNaked) { 520 addLLVMFnAttr(llvm_fn, "naked"); 521 } else { 522 ZigLLVMFunctionSetCallingConv(llvm_fn, get_llvm_cc(g, cc)); 523 } 524 525 bool want_cold = fn->is_cold || cc == CallingConventionCold; 526 if (want_cold) { 527 ZigLLVMAddFunctionAttrCold(llvm_fn); 528 } 529 530 531 LLVMSetLinkage(llvm_fn, to_llvm_linkage(linkage)); 532 533 if (linkage == GlobalLinkageIdInternal) { 534 LLVMSetUnnamedAddr(llvm_fn, true); 535 } 536 537 ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; 538 if (return_type->id == ZigTypeIdUnreachable) { 539 addLLVMFnAttr(llvm_fn, "noreturn"); 540 } 541 542 if (fn->body_node != nullptr) { 543 maybe_export_dll(g, llvm_fn, linkage); 544 545 bool want_fn_safety = g->build_mode != BuildModeFastRelease && 546 g->build_mode != BuildModeSmallRelease && 547 !fn->def_scope->safety_off; 548 if (want_fn_safety) { 549 if (g->libc_link_lib != nullptr) { 550 addLLVMFnAttr(llvm_fn, "sspstrong"); 551 addLLVMFnAttrStr(llvm_fn, "stack-protector-buffer-size", "4"); 552 } 553 } 554 if (g->have_stack_probing && !fn->def_scope->safety_off) { 555 addLLVMFnAttrStr(llvm_fn, "probe-stack", "__zig_probe_stack"); 556 } else if (g->zig_target->os == OsUefi) { 557 addLLVMFnAttrStr(llvm_fn, "no-stack-arg-probe", ""); 558 } 559 } else { 560 maybe_import_dll(g, llvm_fn, linkage); 561 } 562 563 if (fn->alignstack_value != 0) { 564 addLLVMFnAttrInt(llvm_fn, "alignstack", fn->alignstack_value); 565 } 566 567 addLLVMFnAttr(llvm_fn, "nounwind"); 568 add_uwtable_attr(g, llvm_fn); 569 addLLVMFnAttr(llvm_fn, "nobuiltin"); 570 if (codegen_have_frame_pointer(g) && fn->fn_inline != FnInlineAlways) { 571 ZigLLVMAddFunctionAttr(llvm_fn, "no-frame-pointer-elim", "true"); 572 ZigLLVMAddFunctionAttr(llvm_fn, "no-frame-pointer-elim-non-leaf", nullptr); 573 } 574 if (fn->section_name) { 575 LLVMSetSection(llvm_fn, buf_ptr(fn->section_name)); 576 } 577 if (fn->align_bytes > 0) { 578 LLVMSetAlignment(llvm_fn, (unsigned)fn->align_bytes); 579 } else { 580 // We'd like to set the best alignment for the function here, but on Darwin LLVM gives 581 // "Cannot getTypeInfo() on a type that is unsized!" assertion failure when calling 582 // any of the functions for getting alignment. Not specifying the alignment should 583 // use the ABI alignment, which is fine. 584 } 585 586 if (is_async) { 587 addLLVMArgAttr(llvm_fn, 0, "nonnull"); 588 } else { 589 unsigned init_gen_i = 0; 590 if (!type_has_bits(return_type)) { 591 // nothing to do 592 } else if (type_is_nonnull_ptr(return_type)) { 593 addLLVMAttr(llvm_fn, 0, "nonnull"); 594 } else if (want_first_arg_sret(g, &fn_type->data.fn.fn_type_id)) { 595 // Sret pointers must not be address 0 596 addLLVMArgAttr(llvm_fn, 0, "nonnull"); 597 addLLVMArgAttr(llvm_fn, 0, "sret"); 598 if (cc_want_sret_attr(cc)) { 599 addLLVMArgAttr(llvm_fn, 0, "noalias"); 600 } 601 init_gen_i = 1; 602 } 603 604 // set parameter attributes 605 FnWalk fn_walk = {}; 606 fn_walk.id = FnWalkIdAttrs; 607 fn_walk.data.attrs.fn = fn; 608 fn_walk.data.attrs.llvm_fn = llvm_fn; 609 fn_walk.data.attrs.gen_i = init_gen_i; 610 walk_function_params(g, fn_type, &fn_walk); 611 612 uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn); 613 if (err_ret_trace_arg_index != UINT32_MAX) { 614 // Error return trace memory is in the stack, which is impossible to be at address 0 615 // on any architecture. 616 addLLVMArgAttr(llvm_fn, (unsigned)err_ret_trace_arg_index, "nonnull"); 617 } 618 } 619 620 return llvm_fn; 621 } 622 623 static LLVMValueRef fn_llvm_value(CodeGen *g, ZigFn *fn) { 624 if (fn->llvm_value) 625 return fn->llvm_value; 626 627 fn->llvm_value = make_fn_llvm_value(g, fn); 628 fn->llvm_name = strdup(LLVMGetValueName(fn->llvm_value)); 629 return fn->llvm_value; 630 } 631 632 static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) { 633 if (scope->di_scope) 634 return scope->di_scope; 635 636 ZigType *import = get_scope_import(scope); 637 switch (scope->id) { 638 case ScopeIdCImport: 639 zig_unreachable(); 640 case ScopeIdFnDef: 641 { 642 assert(scope->parent); 643 ScopeFnDef *fn_scope = (ScopeFnDef *)scope; 644 ZigFn *fn_table_entry = fn_scope->fn_entry; 645 if (!fn_table_entry->proto_node) 646 return get_di_scope(g, scope->parent); 647 unsigned line_number = (unsigned)(fn_table_entry->proto_node->line == 0) ? 648 0 : (fn_table_entry->proto_node->line + 1); 649 unsigned scope_line = line_number; 650 bool is_definition = fn_table_entry->body_node != nullptr; 651 bool is_optimized = g->build_mode != BuildModeDebug; 652 bool is_internal_linkage = (fn_table_entry->body_node != nullptr && 653 fn_table_entry->export_list.length == 0); 654 unsigned flags = ZigLLVM_DIFlags_StaticMember; 655 ZigLLVMDIScope *fn_di_scope = get_di_scope(g, scope->parent); 656 assert(fn_di_scope != nullptr); 657 assert(fn_table_entry->raw_di_type != nullptr); 658 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder, 659 fn_di_scope, buf_ptr(&fn_table_entry->symbol_name), "", 660 import->data.structure.root_struct->di_file, line_number, 661 fn_table_entry->raw_di_type, is_internal_linkage, 662 is_definition, scope_line, flags, is_optimized, nullptr); 663 664 scope->di_scope = ZigLLVMSubprogramToScope(subprogram); 665 if (!g->strip_debug_symbols) { 666 ZigLLVMFnSetSubprogram(fn_llvm_value(g, fn_table_entry), subprogram); 667 } 668 return scope->di_scope; 669 } 670 case ScopeIdDecls: 671 if (scope->parent) { 672 ScopeDecls *decls_scope = (ScopeDecls *)scope; 673 assert(decls_scope->container_type); 674 scope->di_scope = ZigLLVMTypeToScope(get_llvm_di_type(g, decls_scope->container_type)); 675 } else { 676 scope->di_scope = ZigLLVMFileToScope(import->data.structure.root_struct->di_file); 677 } 678 return scope->di_scope; 679 case ScopeIdBlock: 680 case ScopeIdDefer: 681 { 682 assert(scope->parent); 683 ZigLLVMDILexicalBlock *di_block = ZigLLVMCreateLexicalBlock(g->dbuilder, 684 get_di_scope(g, scope->parent), 685 import->data.structure.root_struct->di_file, 686 (unsigned)scope->source_node->line + 1, 687 (unsigned)scope->source_node->column + 1); 688 scope->di_scope = ZigLLVMLexicalBlockToScope(di_block); 689 return scope->di_scope; 690 } 691 case ScopeIdVarDecl: 692 case ScopeIdDeferExpr: 693 case ScopeIdLoop: 694 case ScopeIdSuspend: 695 case ScopeIdCompTime: 696 case ScopeIdRuntime: 697 case ScopeIdTypeOf: 698 case ScopeIdExpr: 699 return get_di_scope(g, scope->parent); 700 } 701 zig_unreachable(); 702 } 703 704 static void clear_debug_source_node(CodeGen *g) { 705 ZigLLVMClearCurrentDebugLocation(g->builder); 706 } 707 708 static LLVMValueRef get_arithmetic_overflow_fn(CodeGen *g, ZigType *operand_type, 709 const char *signed_name, const char *unsigned_name) 710 { 711 ZigType *int_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type; 712 char fn_name[64]; 713 714 assert(int_type->id == ZigTypeIdInt); 715 const char *signed_str = int_type->data.integral.is_signed ? signed_name : unsigned_name; 716 717 LLVMTypeRef param_types[] = { 718 get_llvm_type(g, operand_type), 719 get_llvm_type(g, operand_type), 720 }; 721 722 if (operand_type->id == ZigTypeIdVector) { 723 sprintf(fn_name, "llvm.%s.with.overflow.v%" PRIu32 "i%" PRIu32, signed_str, 724 operand_type->data.vector.len, int_type->data.integral.bit_count); 725 726 LLVMTypeRef return_elem_types[] = { 727 get_llvm_type(g, operand_type), 728 LLVMVectorType(LLVMInt1Type(), operand_type->data.vector.len), 729 }; 730 LLVMTypeRef return_struct_type = LLVMStructType(return_elem_types, 2, false); 731 LLVMTypeRef fn_type = LLVMFunctionType(return_struct_type, param_types, 2, false); 732 LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type); 733 assert(LLVMGetIntrinsicID(fn_val)); 734 return fn_val; 735 } else { 736 sprintf(fn_name, "llvm.%s.with.overflow.i%" PRIu32, signed_str, int_type->data.integral.bit_count); 737 738 LLVMTypeRef return_elem_types[] = { 739 get_llvm_type(g, operand_type), 740 LLVMInt1Type(), 741 }; 742 LLVMTypeRef return_struct_type = LLVMStructType(return_elem_types, 2, false); 743 LLVMTypeRef fn_type = LLVMFunctionType(return_struct_type, param_types, 2, false); 744 LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type); 745 assert(LLVMGetIntrinsicID(fn_val)); 746 return fn_val; 747 } 748 } 749 750 static LLVMValueRef get_int_overflow_fn(CodeGen *g, ZigType *operand_type, AddSubMul add_sub_mul) { 751 ZigType *int_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type; 752 assert(int_type->id == ZigTypeIdInt); 753 754 ZigLLVMFnKey key = {}; 755 key.id = ZigLLVMFnIdOverflowArithmetic; 756 key.data.overflow_arithmetic.is_signed = int_type->data.integral.is_signed; 757 key.data.overflow_arithmetic.add_sub_mul = add_sub_mul; 758 key.data.overflow_arithmetic.bit_count = (uint32_t)int_type->data.integral.bit_count; 759 key.data.overflow_arithmetic.vector_len = (operand_type->id == ZigTypeIdVector) ? 760 operand_type->data.vector.len : 0; 761 762 auto existing_entry = g->llvm_fn_table.maybe_get(key); 763 if (existing_entry) 764 return existing_entry->value; 765 766 LLVMValueRef fn_val; 767 switch (add_sub_mul) { 768 case AddSubMulAdd: 769 fn_val = get_arithmetic_overflow_fn(g, operand_type, "sadd", "uadd"); 770 break; 771 case AddSubMulSub: 772 fn_val = get_arithmetic_overflow_fn(g, operand_type, "ssub", "usub"); 773 break; 774 case AddSubMulMul: 775 fn_val = get_arithmetic_overflow_fn(g, operand_type, "smul", "umul"); 776 break; 777 } 778 779 g->llvm_fn_table.put(key, fn_val); 780 return fn_val; 781 } 782 783 static LLVMValueRef get_float_fn(CodeGen *g, ZigType *type_entry, ZigLLVMFnId fn_id, BuiltinFnId op) { 784 assert(type_entry->id == ZigTypeIdFloat || 785 type_entry->id == ZigTypeIdVector); 786 787 bool is_vector = (type_entry->id == ZigTypeIdVector); 788 ZigType *float_type = is_vector ? type_entry->data.vector.elem_type : type_entry; 789 790 ZigLLVMFnKey key = {}; 791 key.id = fn_id; 792 key.data.floating.bit_count = (uint32_t)float_type->data.floating.bit_count; 793 key.data.floating.vector_len = is_vector ? (uint32_t)type_entry->data.vector.len : 0; 794 key.data.floating.op = op; 795 796 auto existing_entry = g->llvm_fn_table.maybe_get(key); 797 if (existing_entry) 798 return existing_entry->value; 799 800 const char *name; 801 uint32_t num_args; 802 if (fn_id == ZigLLVMFnIdFMA) { 803 name = "fma"; 804 num_args = 3; 805 } else if (fn_id == ZigLLVMFnIdFloatOp) { 806 name = float_op_to_name(op); 807 num_args = 1; 808 } else { 809 zig_unreachable(); 810 } 811 812 char fn_name[64]; 813 if (is_vector) 814 sprintf(fn_name, "llvm.%s.v%" PRIu32 "f%" PRIu32, name, key.data.floating.vector_len, key.data.floating.bit_count); 815 else 816 sprintf(fn_name, "llvm.%s.f%" PRIu32, name, key.data.floating.bit_count); 817 LLVMTypeRef float_type_ref = get_llvm_type(g, type_entry); 818 LLVMTypeRef return_elem_types[3] = { 819 float_type_ref, 820 float_type_ref, 821 float_type_ref, 822 }; 823 LLVMTypeRef fn_type = LLVMFunctionType(float_type_ref, return_elem_types, num_args, false); 824 LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type); 825 assert(LLVMGetIntrinsicID(fn_val)); 826 827 g->llvm_fn_table.put(key, fn_val); 828 return fn_val; 829 } 830 831 static LLVMValueRef gen_store_untyped(CodeGen *g, LLVMValueRef value, LLVMValueRef ptr, 832 uint32_t alignment, bool is_volatile) 833 { 834 LLVMValueRef instruction = LLVMBuildStore(g->builder, value, ptr); 835 if (is_volatile) LLVMSetVolatile(instruction, true); 836 if (alignment != 0) { 837 LLVMSetAlignment(instruction, alignment); 838 } 839 return instruction; 840 } 841 842 static LLVMValueRef gen_store(CodeGen *g, LLVMValueRef value, LLVMValueRef ptr, ZigType *ptr_type) { 843 assert(ptr_type->id == ZigTypeIdPointer); 844 uint32_t alignment = get_ptr_align(g, ptr_type); 845 return gen_store_untyped(g, value, ptr, alignment, ptr_type->data.pointer.is_volatile); 846 } 847 848 static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMValueRef ptr, uint32_t alignment, bool is_volatile, 849 const char *name) 850 { 851 LLVMValueRef result = LLVMBuildLoad(g->builder, ptr, name); 852 if (is_volatile) LLVMSetVolatile(result, true); 853 if (alignment == 0) { 854 LLVMSetAlignment(result, LLVMABIAlignmentOfType(g->target_data_ref, LLVMGetElementType(LLVMTypeOf(ptr)))); 855 } else { 856 LLVMSetAlignment(result, alignment); 857 } 858 return result; 859 } 860 861 static LLVMValueRef gen_load(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, const char *name) { 862 assert(ptr_type->id == ZigTypeIdPointer); 863 uint32_t alignment = get_ptr_align(g, ptr_type); 864 return gen_load_untyped(g, ptr, alignment, ptr_type->data.pointer.is_volatile, name); 865 } 866 867 static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, ZigType *type, ZigType *ptr_type) { 868 if (type_has_bits(type)) { 869 if (handle_is_ptr(type)) { 870 return ptr; 871 } else { 872 assert(ptr_type->id == ZigTypeIdPointer); 873 return gen_load(g, ptr, ptr_type, ""); 874 } 875 } else { 876 return nullptr; 877 } 878 } 879 880 static void ir_assert(bool ok, IrInstruction *source_instruction) { 881 if (ok) return; 882 src_assert(ok, source_instruction->source_node); 883 } 884 885 static bool ir_want_fast_math(CodeGen *g, IrInstruction *instruction) { 886 // TODO memoize 887 Scope *scope = instruction->scope; 888 while (scope) { 889 if (scope->id == ScopeIdBlock) { 890 ScopeBlock *block_scope = (ScopeBlock *)scope; 891 if (block_scope->fast_math_set_node) 892 return block_scope->fast_math_on; 893 } else if (scope->id == ScopeIdDecls) { 894 ScopeDecls *decls_scope = (ScopeDecls *)scope; 895 if (decls_scope->fast_math_set_node) 896 return decls_scope->fast_math_on; 897 } 898 scope = scope->parent; 899 } 900 return false; 901 } 902 903 static bool ir_want_runtime_safety_scope(CodeGen *g, Scope *scope) { 904 // TODO memoize 905 while (scope) { 906 if (scope->id == ScopeIdBlock) { 907 ScopeBlock *block_scope = (ScopeBlock *)scope; 908 if (block_scope->safety_set_node) 909 return !block_scope->safety_off; 910 } else if (scope->id == ScopeIdDecls) { 911 ScopeDecls *decls_scope = (ScopeDecls *)scope; 912 if (decls_scope->safety_set_node) 913 return !decls_scope->safety_off; 914 } 915 scope = scope->parent; 916 } 917 918 return (g->build_mode != BuildModeFastRelease && 919 g->build_mode != BuildModeSmallRelease); 920 } 921 922 static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) { 923 return ir_want_runtime_safety_scope(g, instruction->scope); 924 } 925 926 static Buf *panic_msg_buf(PanicMsgId msg_id) { 927 switch (msg_id) { 928 case PanicMsgIdCount: 929 zig_unreachable(); 930 case PanicMsgIdBoundsCheckFailure: 931 return buf_create_from_str("index out of bounds"); 932 case PanicMsgIdCastNegativeToUnsigned: 933 return buf_create_from_str("attempt to cast negative value to unsigned integer"); 934 case PanicMsgIdCastTruncatedData: 935 return buf_create_from_str("integer cast truncated bits"); 936 case PanicMsgIdIntegerOverflow: 937 return buf_create_from_str("integer overflow"); 938 case PanicMsgIdShlOverflowedBits: 939 return buf_create_from_str("left shift overflowed bits"); 940 case PanicMsgIdShrOverflowedBits: 941 return buf_create_from_str("right shift overflowed bits"); 942 case PanicMsgIdDivisionByZero: 943 return buf_create_from_str("division by zero"); 944 case PanicMsgIdRemainderDivisionByZero: 945 return buf_create_from_str("remainder division by zero or negative value"); 946 case PanicMsgIdExactDivisionRemainder: 947 return buf_create_from_str("exact division produced remainder"); 948 case PanicMsgIdSliceWidenRemainder: 949 return buf_create_from_str("slice widening size mismatch"); 950 case PanicMsgIdUnwrapOptionalFail: 951 return buf_create_from_str("attempt to unwrap null"); 952 case PanicMsgIdUnreachable: 953 return buf_create_from_str("reached unreachable code"); 954 case PanicMsgIdInvalidErrorCode: 955 return buf_create_from_str("invalid error code"); 956 case PanicMsgIdIncorrectAlignment: 957 return buf_create_from_str("incorrect alignment"); 958 case PanicMsgIdBadUnionField: 959 return buf_create_from_str("access of inactive union field"); 960 case PanicMsgIdBadEnumValue: 961 return buf_create_from_str("invalid enum value"); 962 case PanicMsgIdFloatToInt: 963 return buf_create_from_str("integer part of floating point value out of bounds"); 964 case PanicMsgIdPtrCastNull: 965 return buf_create_from_str("cast causes pointer to be null"); 966 case PanicMsgIdBadResume: 967 return buf_create_from_str("resumed an async function which already returned"); 968 case PanicMsgIdBadAwait: 969 return buf_create_from_str("async function awaited twice"); 970 case PanicMsgIdBadReturn: 971 return buf_create_from_str("async function returned twice"); 972 case PanicMsgIdResumedAnAwaitingFn: 973 return buf_create_from_str("awaiting function resumed"); 974 case PanicMsgIdFrameTooSmall: 975 return buf_create_from_str("frame too small"); 976 case PanicMsgIdResumedFnPendingAwait: 977 return buf_create_from_str("resumed an async function which can only be awaited"); 978 case PanicMsgIdBadNoAsyncCall: 979 return buf_create_from_str("async function called with noasync suspended"); 980 case PanicMsgIdResumeNotSuspendedFn: 981 return buf_create_from_str("resumed a non-suspended function"); 982 case PanicMsgIdBadSentinel: 983 return buf_create_from_str("sentinel mismatch"); 984 } 985 zig_unreachable(); 986 } 987 988 static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) { 989 ZigValue *val = &g->panic_msg_vals[msg_id]; 990 if (!val->llvm_global) { 991 992 Buf *buf_msg = panic_msg_buf(msg_id); 993 ZigValue *array_val = create_const_str_lit(g, buf_msg)->data.x_ptr.data.ref.pointee; 994 init_const_slice(g, val, array_val, 0, buf_len(buf_msg), true); 995 996 render_const_val(g, val, ""); 997 render_const_val_global(g, val, ""); 998 999 assert(val->llvm_global); 1000 } 1001 1002 ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, 1003 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false); 1004 ZigType *str_type = get_slice_type(g, u8_ptr_type); 1005 return LLVMConstBitCast(val->llvm_global, LLVMPointerType(get_llvm_type(g, str_type), 0)); 1006 } 1007 1008 static ZigType *ptr_to_stack_trace_type(CodeGen *g) { 1009 return get_pointer_to_type(g, get_stack_trace_type(g), false); 1010 } 1011 1012 static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace_arg, 1013 bool stack_trace_is_llvm_alloca) 1014 { 1015 assert(g->panic_fn != nullptr); 1016 LLVMValueRef fn_val = fn_llvm_value(g, g->panic_fn); 1017 ZigLLVM_CallingConv llvm_cc = get_llvm_cc(g, g->panic_fn->type_entry->data.fn.fn_type_id.cc); 1018 if (stack_trace_arg == nullptr) { 1019 stack_trace_arg = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type(g))); 1020 } 1021 LLVMValueRef args[] = { 1022 msg_arg, 1023 stack_trace_arg, 1024 }; 1025 ZigLLVMBuildCall(g->builder, fn_val, args, 2, llvm_cc, ZigLLVM_CallAttrAuto, ""); 1026 if (!stack_trace_is_llvm_alloca) { 1027 // The stack trace argument is not in the stack of the caller, so 1028 // we'd like to set tail call here, but because slices (the type of msg_arg) are 1029 // still passed as pointers (see https://github.com/ziglang/zig/issues/561) we still 1030 // cannot make this a tail call. 1031 //LLVMSetTailCall(call_instruction, true); 1032 } 1033 LLVMBuildUnreachable(g->builder); 1034 } 1035 1036 // TODO update most callsites to call gen_assertion instead of this 1037 static void gen_safety_crash(CodeGen *g, PanicMsgId msg_id) { 1038 gen_panic(g, get_panic_msg_ptr_val(g, msg_id), nullptr, false); 1039 } 1040 1041 static void gen_assertion_scope(CodeGen *g, PanicMsgId msg_id, Scope *source_scope) { 1042 if (ir_want_runtime_safety_scope(g, source_scope)) { 1043 gen_safety_crash(g, msg_id); 1044 } else { 1045 LLVMBuildUnreachable(g->builder); 1046 } 1047 } 1048 1049 static void gen_assertion(CodeGen *g, PanicMsgId msg_id, IrInstruction *source_instruction) { 1050 return gen_assertion_scope(g, msg_id, source_instruction->scope); 1051 } 1052 1053 static LLVMValueRef get_stacksave_fn_val(CodeGen *g) { 1054 if (g->stacksave_fn_val) 1055 return g->stacksave_fn_val; 1056 1057 // declare i8* @llvm.stacksave() 1058 1059 LLVMTypeRef fn_type = LLVMFunctionType(LLVMPointerType(LLVMInt8Type(), 0), nullptr, 0, false); 1060 g->stacksave_fn_val = LLVMAddFunction(g->module, "llvm.stacksave", fn_type); 1061 assert(LLVMGetIntrinsicID(g->stacksave_fn_val)); 1062 1063 return g->stacksave_fn_val; 1064 } 1065 1066 static LLVMValueRef get_stackrestore_fn_val(CodeGen *g) { 1067 if (g->stackrestore_fn_val) 1068 return g->stackrestore_fn_val; 1069 1070 // declare void @llvm.stackrestore(i8* %ptr) 1071 1072 LLVMTypeRef param_type = LLVMPointerType(LLVMInt8Type(), 0); 1073 LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), ¶m_type, 1, false); 1074 g->stackrestore_fn_val = LLVMAddFunction(g->module, "llvm.stackrestore", fn_type); 1075 assert(LLVMGetIntrinsicID(g->stackrestore_fn_val)); 1076 1077 return g->stackrestore_fn_val; 1078 } 1079 1080 static LLVMValueRef get_write_register_fn_val(CodeGen *g) { 1081 if (g->write_register_fn_val) 1082 return g->write_register_fn_val; 1083 1084 // declare void @llvm.write_register.i64(metadata, i64 @value) 1085 // !0 = !{!"sp\00"} 1086 1087 LLVMTypeRef param_types[] = { 1088 LLVMMetadataTypeInContext(LLVMGetGlobalContext()), 1089 LLVMIntType(g->pointer_size_bytes * 8), 1090 }; 1091 1092 LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), param_types, 2, false); 1093 Buf *name = buf_sprintf("llvm.write_register.i%d", g->pointer_size_bytes * 8); 1094 g->write_register_fn_val = LLVMAddFunction(g->module, buf_ptr(name), fn_type); 1095 assert(LLVMGetIntrinsicID(g->write_register_fn_val)); 1096 1097 return g->write_register_fn_val; 1098 } 1099 1100 static LLVMValueRef get_return_address_fn_val(CodeGen *g) { 1101 if (g->return_address_fn_val) 1102 return g->return_address_fn_val; 1103 1104 ZigType *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true); 1105 1106 LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, return_type), 1107 &g->builtin_types.entry_i32->llvm_type, 1, false); 1108 g->return_address_fn_val = LLVMAddFunction(g->module, "llvm.returnaddress", fn_type); 1109 assert(LLVMGetIntrinsicID(g->return_address_fn_val)); 1110 1111 return g->return_address_fn_val; 1112 } 1113 1114 static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) { 1115 if (g->add_error_return_trace_addr_fn_val != nullptr) 1116 return g->add_error_return_trace_addr_fn_val; 1117 1118 LLVMTypeRef arg_types[] = { 1119 get_llvm_type(g, ptr_to_stack_trace_type(g)), 1120 g->builtin_types.entry_usize->llvm_type, 1121 }; 1122 LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 2, false); 1123 1124 const char *fn_name = get_mangled_name(g, "__zig_add_err_ret_trace_addr", false); 1125 LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); 1126 addLLVMFnAttr(fn_val, "alwaysinline"); 1127 LLVMSetLinkage(fn_val, LLVMInternalLinkage); 1128 ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); 1129 addLLVMFnAttr(fn_val, "nounwind"); 1130 add_uwtable_attr(g, fn_val); 1131 // Error return trace memory is in the stack, which is impossible to be at address 0 1132 // on any architecture. 1133 addLLVMArgAttr(fn_val, (unsigned)0, "nonnull"); 1134 if (codegen_have_frame_pointer(g)) { 1135 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); 1136 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr); 1137 } 1138 1139 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry"); 1140 LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder); 1141 LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder); 1142 LLVMPositionBuilderAtEnd(g->builder, entry_block); 1143 ZigLLVMClearCurrentDebugLocation(g->builder); 1144 1145 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 1146 1147 // stack_trace.instruction_addresses[stack_trace.index & (stack_trace.instruction_addresses.len - 1)] = return_address; 1148 1149 LLVMValueRef err_ret_trace_ptr = LLVMGetParam(fn_val, 0); 1150 LLVMValueRef address_value = LLVMGetParam(fn_val, 1); 1151 1152 size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index; 1153 LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)index_field_index, ""); 1154 size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index; 1155 LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)addresses_field_index, ""); 1156 1157 ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry; 1158 size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index; 1159 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, ""); 1160 size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index; 1161 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, ""); 1162 1163 LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, ""); 1164 LLVMValueRef index_val = gen_load_untyped(g, index_field_ptr, 0, false, ""); 1165 LLVMValueRef len_val_minus_one = LLVMBuildSub(g->builder, len_value, LLVMConstInt(usize_type_ref, 1, false), ""); 1166 LLVMValueRef masked_val = LLVMBuildAnd(g->builder, index_val, len_val_minus_one, ""); 1167 LLVMValueRef address_indices[] = { 1168 masked_val, 1169 }; 1170 1171 LLVMValueRef ptr_value = gen_load_untyped(g, ptr_field_ptr, 0, false, ""); 1172 LLVMValueRef address_slot = LLVMBuildInBoundsGEP(g->builder, ptr_value, address_indices, 1, ""); 1173 1174 gen_store_untyped(g, address_value, address_slot, 0, false); 1175 1176 // stack_trace.index += 1; 1177 LLVMValueRef index_plus_one_val = LLVMBuildNUWAdd(g->builder, index_val, LLVMConstInt(usize_type_ref, 1, false), ""); 1178 gen_store_untyped(g, index_plus_one_val, index_field_ptr, 0, false); 1179 1180 // return; 1181 LLVMBuildRetVoid(g->builder); 1182 1183 LLVMPositionBuilderAtEnd(g->builder, prev_block); 1184 if (!g->strip_debug_symbols) { 1185 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location); 1186 } 1187 1188 g->add_error_return_trace_addr_fn_val = fn_val; 1189 return fn_val; 1190 } 1191 1192 static LLVMValueRef get_return_err_fn(CodeGen *g) { 1193 if (g->return_err_fn != nullptr) 1194 return g->return_err_fn; 1195 1196 assert(g->err_tag_type != nullptr); 1197 1198 LLVMTypeRef arg_types[] = { 1199 // error return trace pointer 1200 get_llvm_type(g, ptr_to_stack_trace_type(g)), 1201 }; 1202 LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 1, false); 1203 1204 const char *fn_name = get_mangled_name(g, "__zig_return_error", false); 1205 LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); 1206 addLLVMFnAttr(fn_val, "noinline"); // so that we can look at return address 1207 addLLVMFnAttr(fn_val, "cold"); 1208 LLVMSetLinkage(fn_val, LLVMInternalLinkage); 1209 ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); 1210 addLLVMFnAttr(fn_val, "nounwind"); 1211 add_uwtable_attr(g, fn_val); 1212 if (codegen_have_frame_pointer(g)) { 1213 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); 1214 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr); 1215 } 1216 1217 // this is above the ZigLLVMClearCurrentDebugLocation 1218 LLVMValueRef add_error_return_trace_addr_fn_val = get_add_error_return_trace_addr_fn(g); 1219 1220 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry"); 1221 LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder); 1222 LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder); 1223 LLVMPositionBuilderAtEnd(g->builder, entry_block); 1224 ZigLLVMClearCurrentDebugLocation(g->builder); 1225 1226 LLVMValueRef err_ret_trace_ptr = LLVMGetParam(fn_val, 0); 1227 1228 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 1229 LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, g->builtin_types.entry_i32)); 1230 LLVMValueRef return_address_ptr = LLVMBuildCall(g->builder, get_return_address_fn_val(g), &zero, 1, ""); 1231 LLVMValueRef return_address = LLVMBuildPtrToInt(g->builder, return_address_ptr, usize_type_ref, ""); 1232 1233 LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return"); 1234 LLVMBasicBlockRef dest_non_null_block = LLVMAppendBasicBlock(fn_val, "DestNonNull"); 1235 1236 LLVMValueRef null_dest_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, err_ret_trace_ptr, 1237 LLVMConstNull(LLVMTypeOf(err_ret_trace_ptr)), ""); 1238 LLVMBuildCondBr(g->builder, null_dest_bit, return_block, dest_non_null_block); 1239 1240 LLVMPositionBuilderAtEnd(g->builder, return_block); 1241 LLVMBuildRetVoid(g->builder); 1242 1243 LLVMPositionBuilderAtEnd(g->builder, dest_non_null_block); 1244 LLVMValueRef args[] = { err_ret_trace_ptr, return_address }; 1245 ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, 1246 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAlwaysInline, ""); 1247 LLVMBuildRetVoid(g->builder); 1248 1249 LLVMPositionBuilderAtEnd(g->builder, prev_block); 1250 if (!g->strip_debug_symbols) { 1251 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location); 1252 } 1253 1254 g->return_err_fn = fn_val; 1255 return fn_val; 1256 } 1257 1258 static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { 1259 if (g->safety_crash_err_fn != nullptr) 1260 return g->safety_crash_err_fn; 1261 1262 static const char *unwrap_err_msg_text = "attempt to unwrap error: "; 1263 1264 g->generate_error_name_table = true; 1265 generate_error_name_table(g); 1266 assert(g->err_name_table != nullptr); 1267 1268 // Generate the constant part of the error message 1269 LLVMValueRef msg_prefix_init = LLVMConstString(unwrap_err_msg_text, strlen(unwrap_err_msg_text), 1); 1270 LLVMValueRef msg_prefix = LLVMAddGlobal(g->module, LLVMTypeOf(msg_prefix_init), ""); 1271 LLVMSetInitializer(msg_prefix, msg_prefix_init); 1272 LLVMSetLinkage(msg_prefix, LLVMPrivateLinkage); 1273 LLVMSetGlobalConstant(msg_prefix, true); 1274 1275 const char *fn_name = get_mangled_name(g, "__zig_fail_unwrap", false); 1276 LLVMTypeRef fn_type_ref; 1277 if (g->have_err_ret_tracing) { 1278 LLVMTypeRef arg_types[] = { 1279 get_llvm_type(g, get_pointer_to_type(g, get_stack_trace_type(g), false)), 1280 get_llvm_type(g, g->err_tag_type), 1281 }; 1282 fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 2, false); 1283 } else { 1284 LLVMTypeRef arg_types[] = { 1285 get_llvm_type(g, g->err_tag_type), 1286 }; 1287 fn_type_ref = LLVMFunctionType(LLVMVoidType(), arg_types, 1, false); 1288 } 1289 LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); 1290 addLLVMFnAttr(fn_val, "noreturn"); 1291 addLLVMFnAttr(fn_val, "cold"); 1292 LLVMSetLinkage(fn_val, LLVMInternalLinkage); 1293 ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); 1294 addLLVMFnAttr(fn_val, "nounwind"); 1295 add_uwtable_attr(g, fn_val); 1296 if (codegen_have_frame_pointer(g)) { 1297 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); 1298 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr); 1299 } 1300 // Not setting alignment here. See the comment above about 1301 // "Cannot getTypeInfo() on a type that is unsized!" 1302 // assertion failure on Darwin. 1303 1304 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry"); 1305 LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder); 1306 LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder); 1307 LLVMPositionBuilderAtEnd(g->builder, entry_block); 1308 ZigLLVMClearCurrentDebugLocation(g->builder); 1309 1310 ZigType *usize_ty = g->builtin_types.entry_usize; 1311 ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, 1312 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false); 1313 ZigType *str_type = get_slice_type(g, u8_ptr_type); 1314 1315 // Allocate a buffer to hold the fully-formatted error message 1316 const size_t err_buf_len = strlen(unwrap_err_msg_text) + g->largest_err_name_len; 1317 LLVMValueRef max_msg_len = LLVMConstInt(usize_ty->llvm_type, err_buf_len, 0); 1318 LLVMValueRef msg_buffer = LLVMBuildArrayAlloca(g->builder, LLVMInt8Type(), max_msg_len, "msg_buffer"); 1319 1320 // Allocate a []u8 slice for the message 1321 LLVMValueRef msg_slice = build_alloca(g, str_type, "msg_slice", 0); 1322 1323 LLVMValueRef err_ret_trace_arg; 1324 LLVMValueRef err_val; 1325 if (g->have_err_ret_tracing) { 1326 err_ret_trace_arg = LLVMGetParam(fn_val, 0); 1327 err_val = LLVMGetParam(fn_val, 1); 1328 } else { 1329 err_ret_trace_arg = nullptr; 1330 err_val = LLVMGetParam(fn_val, 0); 1331 } 1332 1333 // Fetch the error name from the global table 1334 LLVMValueRef err_table_indices[] = { 1335 LLVMConstNull(usize_ty->llvm_type), 1336 err_val, 1337 }; 1338 LLVMValueRef err_name_val = LLVMBuildInBoundsGEP(g->builder, g->err_name_table, err_table_indices, 2, ""); 1339 1340 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_ptr_index, ""); 1341 LLVMValueRef err_name_ptr = gen_load_untyped(g, ptr_field_ptr, 0, false, ""); 1342 1343 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_len_index, ""); 1344 LLVMValueRef err_name_len = gen_load_untyped(g, len_field_ptr, 0, false, ""); 1345 1346 LLVMValueRef msg_prefix_len = LLVMConstInt(usize_ty->llvm_type, strlen(unwrap_err_msg_text), false); 1347 // Points to the beginning of msg_buffer 1348 LLVMValueRef msg_buffer_ptr_indices[] = { 1349 LLVMConstNull(usize_ty->llvm_type), 1350 }; 1351 LLVMValueRef msg_buffer_ptr = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_indices, 1, ""); 1352 // Points to the beginning of the constant prefix message 1353 LLVMValueRef msg_prefix_ptr_indices[] = { 1354 LLVMConstNull(usize_ty->llvm_type), 1355 }; 1356 LLVMValueRef msg_prefix_ptr = LLVMConstInBoundsGEP(msg_prefix, msg_prefix_ptr_indices, 1); 1357 1358 // Build the message using the prefix... 1359 ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr, 1, msg_prefix_ptr, 1, msg_prefix_len, false); 1360 // ..and append the error name 1361 LLVMValueRef msg_buffer_ptr_after_indices[] = { 1362 msg_prefix_len, 1363 }; 1364 LLVMValueRef msg_buffer_ptr_after = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_after_indices, 1, ""); 1365 ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr_after, 1, err_name_ptr, 1, err_name_len, false); 1366 1367 // Set the slice pointer 1368 LLVMValueRef msg_slice_ptr_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_ptr_index, ""); 1369 gen_store_untyped(g, msg_buffer_ptr, msg_slice_ptr_field_ptr, 0, false); 1370 1371 // Set the slice length 1372 LLVMValueRef slice_len = LLVMBuildNUWAdd(g->builder, msg_prefix_len, err_name_len, ""); 1373 LLVMValueRef msg_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_len_index, ""); 1374 gen_store_untyped(g, slice_len, msg_slice_len_field_ptr, 0, false); 1375 1376 // Call panic() 1377 gen_panic(g, msg_slice, err_ret_trace_arg, false); 1378 1379 LLVMPositionBuilderAtEnd(g->builder, prev_block); 1380 if (!g->strip_debug_symbols) { 1381 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location); 1382 } 1383 1384 g->safety_crash_err_fn = fn_val; 1385 return fn_val; 1386 } 1387 1388 static LLVMValueRef get_cur_err_ret_trace_val(CodeGen *g, Scope *scope, bool *is_llvm_alloca) { 1389 if (!g->have_err_ret_tracing) { 1390 *is_llvm_alloca = false; 1391 return nullptr; 1392 } 1393 if (g->cur_err_ret_trace_val_stack != nullptr) { 1394 *is_llvm_alloca = !fn_is_async(g->cur_fn); 1395 return g->cur_err_ret_trace_val_stack; 1396 } 1397 *is_llvm_alloca = false; 1398 return g->cur_err_ret_trace_val_arg; 1399 } 1400 1401 static void gen_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val, Scope *scope) { 1402 LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g); 1403 LLVMValueRef call_instruction; 1404 bool is_llvm_alloca = false; 1405 if (g->have_err_ret_tracing) { 1406 LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, scope, &is_llvm_alloca); 1407 if (err_ret_trace_val == nullptr) { 1408 err_ret_trace_val = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type(g))); 1409 } 1410 LLVMValueRef args[] = { 1411 err_ret_trace_val, 1412 err_val, 1413 }; 1414 call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 2, 1415 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, ""); 1416 } else { 1417 LLVMValueRef args[] = { 1418 err_val, 1419 }; 1420 call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 1, 1421 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, ""); 1422 } 1423 if (!is_llvm_alloca) { 1424 LLVMSetTailCall(call_instruction, true); 1425 } 1426 LLVMBuildUnreachable(g->builder); 1427 } 1428 1429 static void add_bounds_check(CodeGen *g, LLVMValueRef target_val, 1430 LLVMIntPredicate lower_pred, LLVMValueRef lower_value, 1431 LLVMIntPredicate upper_pred, LLVMValueRef upper_value) 1432 { 1433 if (!lower_value && !upper_value) { 1434 return; 1435 } 1436 if (upper_value && !lower_value) { 1437 lower_value = upper_value; 1438 lower_pred = upper_pred; 1439 upper_value = nullptr; 1440 } 1441 1442 LLVMBasicBlockRef bounds_check_fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "BoundsCheckFail"); 1443 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "BoundsCheckOk"); 1444 LLVMBasicBlockRef lower_ok_block = upper_value ? 1445 LLVMAppendBasicBlock(g->cur_fn_val, "FirstBoundsCheckOk") : ok_block; 1446 1447 LLVMValueRef lower_ok_val = LLVMBuildICmp(g->builder, lower_pred, target_val, lower_value, ""); 1448 LLVMBuildCondBr(g->builder, lower_ok_val, lower_ok_block, bounds_check_fail_block); 1449 1450 LLVMPositionBuilderAtEnd(g->builder, bounds_check_fail_block); 1451 gen_safety_crash(g, PanicMsgIdBoundsCheckFailure); 1452 1453 if (upper_value) { 1454 LLVMPositionBuilderAtEnd(g->builder, lower_ok_block); 1455 LLVMValueRef upper_ok_val = LLVMBuildICmp(g->builder, upper_pred, target_val, upper_value, ""); 1456 LLVMBuildCondBr(g->builder, upper_ok_val, ok_block, bounds_check_fail_block); 1457 } 1458 1459 LLVMPositionBuilderAtEnd(g->builder, ok_block); 1460 } 1461 1462 static void add_sentinel_check(CodeGen *g, LLVMValueRef sentinel_elem_ptr, ZigValue *sentinel) { 1463 LLVMValueRef expected_sentinel = gen_const_val(g, sentinel, ""); 1464 1465 LLVMValueRef actual_sentinel = gen_load_untyped(g, sentinel_elem_ptr, 0, false, ""); 1466 LLVMValueRef ok_bit; 1467 if (sentinel->type->id == ZigTypeIdFloat) { 1468 ok_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, actual_sentinel, expected_sentinel, ""); 1469 } else { 1470 ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, actual_sentinel, expected_sentinel, ""); 1471 } 1472 1473 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SentinelFail"); 1474 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SentinelOk"); 1475 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); 1476 1477 LLVMPositionBuilderAtEnd(g->builder, fail_block); 1478 gen_safety_crash(g, PanicMsgIdBadSentinel); 1479 1480 LLVMPositionBuilderAtEnd(g->builder, ok_block); 1481 } 1482 1483 static LLVMValueRef gen_assert_zero(CodeGen *g, LLVMValueRef expr_val, ZigType *int_type) { 1484 LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, int_type)); 1485 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, expr_val, zero, ""); 1486 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenOk"); 1487 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenFail"); 1488 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); 1489 1490 LLVMPositionBuilderAtEnd(g->builder, fail_block); 1491 gen_safety_crash(g, PanicMsgIdCastTruncatedData); 1492 1493 LLVMPositionBuilderAtEnd(g->builder, ok_block); 1494 return nullptr; 1495 } 1496 1497 static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, ZigType *actual_type, 1498 ZigType *wanted_type, LLVMValueRef expr_val) 1499 { 1500 assert(actual_type->id == wanted_type->id); 1501 assert(expr_val != nullptr); 1502 1503 uint64_t actual_bits; 1504 uint64_t wanted_bits; 1505 if (actual_type->id == ZigTypeIdFloat) { 1506 actual_bits = actual_type->data.floating.bit_count; 1507 wanted_bits = wanted_type->data.floating.bit_count; 1508 } else if (actual_type->id == ZigTypeIdInt) { 1509 actual_bits = actual_type->data.integral.bit_count; 1510 wanted_bits = wanted_type->data.integral.bit_count; 1511 } else { 1512 zig_unreachable(); 1513 } 1514 1515 if (actual_type->id == ZigTypeIdInt && 1516 !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed && 1517 want_runtime_safety) 1518 { 1519 LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, actual_type)); 1520 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntSGE, expr_val, zero, ""); 1521 1522 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SignCastOk"); 1523 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SignCastFail"); 1524 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); 1525 1526 LLVMPositionBuilderAtEnd(g->builder, fail_block); 1527 gen_safety_crash(g, PanicMsgIdCastNegativeToUnsigned); 1528 1529 LLVMPositionBuilderAtEnd(g->builder, ok_block); 1530 } 1531 1532 if (actual_bits == wanted_bits) { 1533 return expr_val; 1534 } else if (actual_bits < wanted_bits) { 1535 if (actual_type->id == ZigTypeIdFloat) { 1536 return LLVMBuildFPExt(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); 1537 } else if (actual_type->id == ZigTypeIdInt) { 1538 if (actual_type->data.integral.is_signed) { 1539 return LLVMBuildSExt(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); 1540 } else { 1541 return LLVMBuildZExt(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); 1542 } 1543 } else { 1544 zig_unreachable(); 1545 } 1546 } else if (actual_bits > wanted_bits) { 1547 if (actual_type->id == ZigTypeIdFloat) { 1548 return LLVMBuildFPTrunc(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); 1549 } else if (actual_type->id == ZigTypeIdInt) { 1550 if (wanted_bits == 0) { 1551 if (!want_runtime_safety) 1552 return nullptr; 1553 1554 return gen_assert_zero(g, expr_val, actual_type); 1555 } 1556 LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); 1557 if (!want_runtime_safety) { 1558 return trunc_val; 1559 } 1560 LLVMValueRef orig_val; 1561 if (wanted_type->data.integral.is_signed) { 1562 orig_val = LLVMBuildSExt(g->builder, trunc_val, get_llvm_type(g, actual_type), ""); 1563 } else { 1564 orig_val = LLVMBuildZExt(g->builder, trunc_val, get_llvm_type(g, actual_type), ""); 1565 } 1566 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, expr_val, orig_val, ""); 1567 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenOk"); 1568 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "CastShortenFail"); 1569 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); 1570 1571 LLVMPositionBuilderAtEnd(g->builder, fail_block); 1572 gen_safety_crash(g, PanicMsgIdCastTruncatedData); 1573 1574 LLVMPositionBuilderAtEnd(g->builder, ok_block); 1575 return trunc_val; 1576 } else { 1577 zig_unreachable(); 1578 } 1579 } else { 1580 zig_unreachable(); 1581 } 1582 } 1583 1584 typedef LLVMValueRef (*BuildBinOpFunc)(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, const char *); 1585 // These are lookup table using the AddSubMul enum as the lookup. 1586 // If AddSubMul ever changes, then these tables will be out of 1587 // date. 1588 static const BuildBinOpFunc float_op[3] = { LLVMBuildFAdd, LLVMBuildFSub, LLVMBuildFMul }; 1589 static const BuildBinOpFunc wrap_op[3] = { LLVMBuildAdd, LLVMBuildSub, LLVMBuildMul }; 1590 static const BuildBinOpFunc signed_op[3] = { LLVMBuildNSWAdd, LLVMBuildNSWSub, LLVMBuildNSWMul }; 1591 static const BuildBinOpFunc unsigned_op[3] = { LLVMBuildNUWAdd, LLVMBuildNUWSub, LLVMBuildNUWMul }; 1592 1593 static LLVMValueRef gen_overflow_op(CodeGen *g, ZigType *operand_type, AddSubMul op, 1594 LLVMValueRef val1, LLVMValueRef val2) 1595 { 1596 LLVMValueRef overflow_bit; 1597 LLVMValueRef result; 1598 1599 if (operand_type->id == ZigTypeIdVector) { 1600 ZigType *int_type = operand_type->data.vector.elem_type; 1601 assert(int_type->id == ZigTypeIdInt); 1602 LLVMTypeRef one_more_bit_int = LLVMIntType(int_type->data.integral.bit_count + 1); 1603 LLVMTypeRef one_more_bit_int_vector = LLVMVectorType(one_more_bit_int, operand_type->data.vector.len); 1604 const auto buildExtFn = int_type->data.integral.is_signed ? LLVMBuildSExt : LLVMBuildZExt; 1605 LLVMValueRef extended1 = buildExtFn(g->builder, val1, one_more_bit_int_vector, ""); 1606 LLVMValueRef extended2 = buildExtFn(g->builder, val2, one_more_bit_int_vector, ""); 1607 LLVMValueRef extended_result = wrap_op[op](g->builder, extended1, extended2, ""); 1608 result = LLVMBuildTrunc(g->builder, extended_result, get_llvm_type(g, operand_type), ""); 1609 1610 LLVMValueRef re_extended_result = buildExtFn(g->builder, result, one_more_bit_int_vector, ""); 1611 LLVMValueRef overflow_vector = LLVMBuildICmp(g->builder, LLVMIntNE, extended_result, re_extended_result, ""); 1612 LLVMTypeRef bitcast_int_type = LLVMIntType(operand_type->data.vector.len); 1613 LLVMValueRef bitcasted_overflow = LLVMBuildBitCast(g->builder, overflow_vector, bitcast_int_type, ""); 1614 LLVMValueRef zero = LLVMConstNull(bitcast_int_type); 1615 overflow_bit = LLVMBuildICmp(g->builder, LLVMIntNE, bitcasted_overflow, zero, ""); 1616 } else { 1617 LLVMValueRef fn_val = get_int_overflow_fn(g, operand_type, op); 1618 LLVMValueRef params[] = { 1619 val1, 1620 val2, 1621 }; 1622 LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, ""); 1623 result = LLVMBuildExtractValue(g->builder, result_struct, 0, ""); 1624 overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, ""); 1625 } 1626 1627 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowFail"); 1628 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowOk"); 1629 LLVMBuildCondBr(g->builder, overflow_bit, fail_block, ok_block); 1630 1631 LLVMPositionBuilderAtEnd(g->builder, fail_block); 1632 gen_safety_crash(g, PanicMsgIdIntegerOverflow); 1633 1634 LLVMPositionBuilderAtEnd(g->builder, ok_block); 1635 return result; 1636 } 1637 1638 static LLVMIntPredicate cmp_op_to_int_predicate(IrBinOp cmp_op, bool is_signed) { 1639 switch (cmp_op) { 1640 case IrBinOpCmpEq: 1641 return LLVMIntEQ; 1642 case IrBinOpCmpNotEq: 1643 return LLVMIntNE; 1644 case IrBinOpCmpLessThan: 1645 return is_signed ? LLVMIntSLT : LLVMIntULT; 1646 case IrBinOpCmpGreaterThan: 1647 return is_signed ? LLVMIntSGT : LLVMIntUGT; 1648 case IrBinOpCmpLessOrEq: 1649 return is_signed ? LLVMIntSLE : LLVMIntULE; 1650 case IrBinOpCmpGreaterOrEq: 1651 return is_signed ? LLVMIntSGE : LLVMIntUGE; 1652 default: 1653 zig_unreachable(); 1654 } 1655 } 1656 1657 static LLVMRealPredicate cmp_op_to_real_predicate(IrBinOp cmp_op) { 1658 switch (cmp_op) { 1659 case IrBinOpCmpEq: 1660 return LLVMRealOEQ; 1661 case IrBinOpCmpNotEq: 1662 return LLVMRealUNE; 1663 case IrBinOpCmpLessThan: 1664 return LLVMRealOLT; 1665 case IrBinOpCmpGreaterThan: 1666 return LLVMRealOGT; 1667 case IrBinOpCmpLessOrEq: 1668 return LLVMRealOLE; 1669 case IrBinOpCmpGreaterOrEq: 1670 return LLVMRealOGE; 1671 default: 1672 zig_unreachable(); 1673 } 1674 } 1675 1676 static void gen_assign_raw(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, 1677 LLVMValueRef value) 1678 { 1679 assert(ptr_type->id == ZigTypeIdPointer); 1680 ZigType *child_type = ptr_type->data.pointer.child_type; 1681 1682 if (!type_has_bits(child_type)) 1683 return; 1684 1685 if (handle_is_ptr(child_type)) { 1686 assert(LLVMGetTypeKind(LLVMTypeOf(value)) == LLVMPointerTypeKind); 1687 assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind); 1688 1689 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); 1690 1691 LLVMValueRef src_ptr = LLVMBuildBitCast(g->builder, value, ptr_u8, ""); 1692 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, ptr, ptr_u8, ""); 1693 1694 ZigType *usize = g->builtin_types.entry_usize; 1695 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, get_llvm_type(g, child_type)); 1696 uint64_t align_bytes = get_ptr_align(g, ptr_type); 1697 assert(size_bytes > 0); 1698 assert(align_bytes > 0); 1699 1700 ZigLLVMBuildMemCpy(g->builder, dest_ptr, align_bytes, src_ptr, align_bytes, 1701 LLVMConstInt(usize->llvm_type, size_bytes, false), 1702 ptr_type->data.pointer.is_volatile); 1703 return; 1704 } 1705 1706 assert(ptr_type->data.pointer.vector_index != VECTOR_INDEX_RUNTIME); 1707 if (ptr_type->data.pointer.vector_index != VECTOR_INDEX_NONE) { 1708 LLVMValueRef index_val = LLVMConstInt(LLVMInt32Type(), 1709 ptr_type->data.pointer.vector_index, false); 1710 LLVMValueRef loaded_vector = gen_load(g, ptr, ptr_type, ""); 1711 LLVMValueRef new_vector = LLVMBuildInsertElement(g->builder, loaded_vector, value, 1712 index_val, ""); 1713 gen_store(g, new_vector, ptr, ptr_type); 1714 return; 1715 } 1716 1717 uint32_t host_int_bytes = ptr_type->data.pointer.host_int_bytes; 1718 if (host_int_bytes == 0) { 1719 gen_store(g, value, ptr, ptr_type); 1720 return; 1721 } 1722 1723 bool big_endian = g->is_big_endian; 1724 1725 LLVMTypeRef int_ptr_ty = LLVMPointerType(LLVMIntType(host_int_bytes * 8), 0); 1726 LLVMValueRef int_ptr = LLVMBuildBitCast(g->builder, ptr, int_ptr_ty, ""); 1727 LLVMValueRef containing_int = gen_load(g, int_ptr, ptr_type, ""); 1728 uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int)); 1729 assert(host_bit_count == host_int_bytes * 8); 1730 uint32_t size_in_bits = type_size_bits(g, child_type); 1731 1732 uint32_t bit_offset = ptr_type->data.pointer.bit_offset_in_host; 1733 uint32_t shift_amt = big_endian ? host_bit_count - bit_offset - size_in_bits : bit_offset; 1734 LLVMValueRef shift_amt_val = LLVMConstInt(LLVMTypeOf(containing_int), shift_amt, false); 1735 1736 // Convert to equally-sized integer type in order to perform the bit 1737 // operations on the value to store 1738 LLVMTypeRef value_bits_type = LLVMIntType(size_in_bits); 1739 LLVMValueRef value_bits = LLVMBuildBitCast(g->builder, value, value_bits_type, ""); 1740 1741 LLVMValueRef mask_val = LLVMConstAllOnes(value_bits_type); 1742 mask_val = LLVMConstZExt(mask_val, LLVMTypeOf(containing_int)); 1743 mask_val = LLVMConstShl(mask_val, shift_amt_val); 1744 mask_val = LLVMConstNot(mask_val); 1745 1746 LLVMValueRef anded_containing_int = LLVMBuildAnd(g->builder, containing_int, mask_val, ""); 1747 LLVMValueRef extended_value = LLVMBuildZExt(g->builder, value_bits, LLVMTypeOf(containing_int), ""); 1748 LLVMValueRef shifted_value = LLVMBuildShl(g->builder, extended_value, shift_amt_val, ""); 1749 LLVMValueRef ored_value = LLVMBuildOr(g->builder, shifted_value, anded_containing_int, ""); 1750 1751 gen_store(g, ored_value, int_ptr, ptr_type); 1752 } 1753 1754 static void gen_var_debug_decl(CodeGen *g, ZigVar *var) { 1755 if (g->strip_debug_symbols) return; 1756 assert(var->di_loc_var != nullptr); 1757 AstNode *source_node = var->decl_node; 1758 ZigLLVMDILocation *debug_loc = ZigLLVMGetDebugLoc((unsigned)source_node->line + 1, 1759 (unsigned)source_node->column + 1, get_di_scope(g, var->parent_scope)); 1760 ZigLLVMInsertDeclareAtEnd(g->dbuilder, var->value_ref, var->di_loc_var, debug_loc, 1761 LLVMGetInsertBlock(g->builder)); 1762 } 1763 1764 static LLVMValueRef ir_llvm_value(CodeGen *g, IrInstruction *instruction) { 1765 Error err; 1766 1767 bool value_has_bits; 1768 if ((err = type_has_bits2(g, instruction->value->type, &value_has_bits))) 1769 codegen_report_errors_and_exit(g); 1770 1771 if (!value_has_bits) 1772 return nullptr; 1773 1774 if (!instruction->llvm_value) { 1775 if (instruction->id == IrInstructionIdAwaitGen) { 1776 IrInstructionAwaitGen *await = reinterpret_cast<IrInstructionAwaitGen*>(instruction); 1777 if (await->result_loc != nullptr) { 1778 return get_handle_value(g, ir_llvm_value(g, await->result_loc), 1779 await->result_loc->value->type->data.pointer.child_type, await->result_loc->value->type); 1780 } 1781 } 1782 if (instruction->spill != nullptr) { 1783 ZigType *ptr_type = instruction->spill->value->type; 1784 ir_assert(ptr_type->id == ZigTypeIdPointer, instruction); 1785 return get_handle_value(g, ir_llvm_value(g, instruction->spill), 1786 ptr_type->data.pointer.child_type, instruction->spill->value->type); 1787 } 1788 ir_assert(instruction->value->special != ConstValSpecialRuntime, instruction); 1789 assert(instruction->value->type); 1790 render_const_val(g, instruction->value, ""); 1791 // we might have to do some pointer casting here due to the way union 1792 // values are rendered with a type other than the one we expect 1793 if (handle_is_ptr(instruction->value->type)) { 1794 render_const_val_global(g, instruction->value, ""); 1795 ZigType *ptr_type = get_pointer_to_type(g, instruction->value->type, true); 1796 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value->llvm_global, get_llvm_type(g, ptr_type), ""); 1797 } else { 1798 instruction->llvm_value = LLVMBuildBitCast(g->builder, instruction->value->llvm_value, 1799 get_llvm_type(g, instruction->value->type), ""); 1800 } 1801 assert(instruction->llvm_value); 1802 } 1803 return instruction->llvm_value; 1804 } 1805 1806 void codegen_report_errors_and_exit(CodeGen *g) { 1807 assert(g->errors.length != 0); 1808 for (size_t i = 0; i < g->errors.length; i += 1) { 1809 ErrorMsg *err = g->errors.at(i); 1810 print_err_msg(err, g->err_color); 1811 } 1812 exit(1); 1813 } 1814 1815 static void report_errors_and_maybe_exit(CodeGen *g) { 1816 if (g->errors.length != 0) { 1817 codegen_report_errors_and_exit(g); 1818 } 1819 } 1820 1821 ATTRIBUTE_NORETURN 1822 static void give_up_with_c_abi_error(CodeGen *g, AstNode *source_node) { 1823 ErrorMsg *msg = add_node_error(g, source_node, 1824 buf_sprintf("TODO: support C ABI for more targets. https://github.com/ziglang/zig/issues/1481")); 1825 add_error_note(g, msg, source_node, 1826 buf_sprintf("pointers, integers, floats, bools, and enums work on all targets")); 1827 codegen_report_errors_and_exit(g); 1828 } 1829 1830 static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment) { 1831 LLVMValueRef result = LLVMBuildAlloca(g->builder, get_llvm_type(g, type_entry), name); 1832 LLVMSetAlignment(result, (alignment == 0) ? get_abi_alignment(g, type_entry) : alignment); 1833 return result; 1834 } 1835 1836 static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk, size_t src_i) { 1837 // Initialized from the type for some walks, but because of C var args, 1838 // initialized based on callsite instructions for that one. 1839 FnTypeParamInfo *param_info = nullptr; 1840 ZigType *ty; 1841 ZigType *dest_ty = nullptr; 1842 AstNode *source_node = nullptr; 1843 LLVMValueRef val; 1844 LLVMValueRef llvm_fn; 1845 unsigned di_arg_index; 1846 ZigVar *var; 1847 switch (fn_walk->id) { 1848 case FnWalkIdAttrs: 1849 if (src_i >= fn_type->data.fn.fn_type_id.param_count) 1850 return false; 1851 param_info = &fn_type->data.fn.fn_type_id.param_info[src_i]; 1852 ty = param_info->type; 1853 source_node = fn_walk->data.attrs.fn->proto_node; 1854 llvm_fn = fn_walk->data.attrs.llvm_fn; 1855 break; 1856 case FnWalkIdCall: { 1857 if (src_i >= fn_walk->data.call.inst->arg_count) 1858 return false; 1859 IrInstruction *arg = fn_walk->data.call.inst->args[src_i]; 1860 ty = arg->value->type; 1861 source_node = arg->source_node; 1862 val = ir_llvm_value(g, arg); 1863 break; 1864 } 1865 case FnWalkIdTypes: 1866 if (src_i >= fn_type->data.fn.fn_type_id.param_count) 1867 return false; 1868 param_info = &fn_type->data.fn.fn_type_id.param_info[src_i]; 1869 ty = param_info->type; 1870 break; 1871 case FnWalkIdVars: 1872 assert(src_i < fn_type->data.fn.fn_type_id.param_count); 1873 param_info = &fn_type->data.fn.fn_type_id.param_info[src_i]; 1874 ty = param_info->type; 1875 var = fn_walk->data.vars.var; 1876 source_node = var->decl_node; 1877 llvm_fn = fn_walk->data.vars.llvm_fn; 1878 break; 1879 case FnWalkIdInits: 1880 if (src_i >= fn_type->data.fn.fn_type_id.param_count) 1881 return false; 1882 param_info = &fn_type->data.fn.fn_type_id.param_info[src_i]; 1883 ty = param_info->type; 1884 var = fn_walk->data.inits.fn->variable_list.at(src_i); 1885 source_node = fn_walk->data.inits.fn->proto_node; 1886 llvm_fn = fn_walk->data.inits.llvm_fn; 1887 break; 1888 } 1889 1890 if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat || ty->id == ZigTypeIdVector || 1891 ty->id == ZigTypeIdInt // TODO investigate if we need to change this 1892 ) { 1893 switch (fn_walk->id) { 1894 case FnWalkIdAttrs: { 1895 ZigType *ptr_type = get_codegen_ptr_type(ty); 1896 if (ptr_type != nullptr) { 1897 if (type_is_nonnull_ptr(ty)) { 1898 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); 1899 } 1900 if (ptr_type->data.pointer.is_const) { 1901 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "readonly"); 1902 } 1903 if (param_info->is_noalias) { 1904 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "noalias"); 1905 } 1906 } 1907 fn_walk->data.attrs.gen_i += 1; 1908 break; 1909 } 1910 case FnWalkIdCall: 1911 fn_walk->data.call.gen_param_values->append(val); 1912 break; 1913 case FnWalkIdTypes: 1914 fn_walk->data.types.gen_param_types->append(get_llvm_type(g, ty)); 1915 fn_walk->data.types.param_di_types->append(get_llvm_di_type(g, ty)); 1916 break; 1917 case FnWalkIdVars: { 1918 var->value_ref = build_alloca(g, ty, var->name, var->align_bytes); 1919 di_arg_index = fn_walk->data.vars.gen_i; 1920 fn_walk->data.vars.gen_i += 1; 1921 dest_ty = ty; 1922 goto var_ok; 1923 } 1924 case FnWalkIdInits: 1925 clear_debug_source_node(g); 1926 gen_store_untyped(g, LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i), var->value_ref, var->align_bytes, false); 1927 if (var->decl_node) { 1928 gen_var_debug_decl(g, var); 1929 } 1930 fn_walk->data.inits.gen_i += 1; 1931 break; 1932 } 1933 return true; 1934 } 1935 1936 { 1937 // Arrays are just pointers 1938 if (ty->id == ZigTypeIdArray) { 1939 assert(handle_is_ptr(ty)); 1940 switch (fn_walk->id) { 1941 case FnWalkIdAttrs: 1942 // arrays passed to C ABI functions may not be at address 0 1943 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); 1944 addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty)); 1945 fn_walk->data.attrs.gen_i += 1; 1946 break; 1947 case FnWalkIdCall: 1948 fn_walk->data.call.gen_param_values->append(val); 1949 break; 1950 case FnWalkIdTypes: { 1951 ZigType *gen_type = get_pointer_to_type(g, ty, true); 1952 fn_walk->data.types.gen_param_types->append(get_llvm_type(g, gen_type)); 1953 fn_walk->data.types.param_di_types->append(get_llvm_di_type(g, gen_type)); 1954 break; 1955 } 1956 case FnWalkIdVars: { 1957 var->value_ref = LLVMGetParam(llvm_fn, fn_walk->data.vars.gen_i); 1958 di_arg_index = fn_walk->data.vars.gen_i; 1959 dest_ty = get_pointer_to_type(g, ty, false); 1960 fn_walk->data.vars.gen_i += 1; 1961 goto var_ok; 1962 } 1963 case FnWalkIdInits: 1964 if (var->decl_node) { 1965 gen_var_debug_decl(g, var); 1966 } 1967 fn_walk->data.inits.gen_i += 1; 1968 break; 1969 } 1970 return true; 1971 } 1972 1973 X64CABIClass abi_class = type_c_abi_x86_64_class(g, ty); 1974 size_t ty_size = type_size(g, ty); 1975 if (abi_class == X64CABIClass_MEMORY || abi_class == X64CABIClass_MEMORY_nobyval) { 1976 assert(handle_is_ptr(ty)); 1977 switch (fn_walk->id) { 1978 case FnWalkIdAttrs: 1979 if (abi_class != X64CABIClass_MEMORY_nobyval) { 1980 ZigLLVMAddByValAttr(llvm_fn, fn_walk->data.attrs.gen_i + 1, get_llvm_type(g, ty)); 1981 addLLVMArgAttrInt(llvm_fn, fn_walk->data.attrs.gen_i, "align", get_abi_alignment(g, ty)); 1982 } else if (g->zig_target->arch == ZigLLVM_aarch64 || 1983 g->zig_target->arch == ZigLLVM_aarch64_be) 1984 { 1985 // no attrs needed 1986 } else { 1987 if (source_node != nullptr) { 1988 give_up_with_c_abi_error(g, source_node); 1989 } 1990 // otherwise allow codegen code to report a compile error 1991 return false; 1992 } 1993 1994 // Byvalue parameters must not have address 0 1995 addLLVMArgAttr(llvm_fn, fn_walk->data.attrs.gen_i, "nonnull"); 1996 fn_walk->data.attrs.gen_i += 1; 1997 break; 1998 case FnWalkIdCall: 1999 fn_walk->data.call.gen_param_values->append(val); 2000 break; 2001 case FnWalkIdTypes: { 2002 ZigType *gen_type = get_pointer_to_type(g, ty, true); 2003 fn_walk->data.types.gen_param_types->append(get_llvm_type(g, gen_type)); 2004 fn_walk->data.types.param_di_types->append(get_llvm_di_type(g, gen_type)); 2005 break; 2006 } 2007 case FnWalkIdVars: { 2008 di_arg_index = fn_walk->data.vars.gen_i; 2009 var->value_ref = LLVMGetParam(llvm_fn, fn_walk->data.vars.gen_i); 2010 dest_ty = get_pointer_to_type(g, ty, false); 2011 fn_walk->data.vars.gen_i += 1; 2012 goto var_ok; 2013 } 2014 case FnWalkIdInits: 2015 if (var->decl_node) { 2016 gen_var_debug_decl(g, var); 2017 } 2018 fn_walk->data.inits.gen_i += 1; 2019 break; 2020 } 2021 return true; 2022 } else if (abi_class == X64CABIClass_INTEGER) { 2023 switch (fn_walk->id) { 2024 case FnWalkIdAttrs: 2025 fn_walk->data.attrs.gen_i += 1; 2026 break; 2027 case FnWalkIdCall: { 2028 LLVMTypeRef ptr_to_int_type_ref = LLVMPointerType(LLVMIntType((unsigned)ty_size * 8), 0); 2029 LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, val, ptr_to_int_type_ref, ""); 2030 LLVMValueRef loaded = LLVMBuildLoad(g->builder, bitcasted, ""); 2031 fn_walk->data.call.gen_param_values->append(loaded); 2032 break; 2033 } 2034 case FnWalkIdTypes: { 2035 ZigType *gen_type = get_int_type(g, false, ty_size * 8); 2036 fn_walk->data.types.gen_param_types->append(get_llvm_type(g, gen_type)); 2037 fn_walk->data.types.param_di_types->append(get_llvm_di_type(g, gen_type)); 2038 break; 2039 } 2040 case FnWalkIdVars: { 2041 di_arg_index = fn_walk->data.vars.gen_i; 2042 var->value_ref = build_alloca(g, ty, var->name, var->align_bytes); 2043 fn_walk->data.vars.gen_i += 1; 2044 dest_ty = ty; 2045 goto var_ok; 2046 } 2047 case FnWalkIdInits: { 2048 clear_debug_source_node(g); 2049 if (!fn_is_async(fn_walk->data.inits.fn)) { 2050 LLVMValueRef arg = LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i); 2051 LLVMTypeRef ptr_to_int_type_ref = LLVMPointerType(LLVMIntType((unsigned)ty_size * 8), 0); 2052 LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, var->value_ref, ptr_to_int_type_ref, ""); 2053 gen_store_untyped(g, arg, bitcasted, var->align_bytes, false); 2054 } 2055 if (var->decl_node) { 2056 gen_var_debug_decl(g, var); 2057 } 2058 fn_walk->data.inits.gen_i += 1; 2059 break; 2060 } 2061 } 2062 return true; 2063 } 2064 } 2065 if (source_node != nullptr) { 2066 give_up_with_c_abi_error(g, source_node); 2067 } 2068 // otherwise allow codegen code to report a compile error 2069 return false; 2070 2071 var_ok: 2072 if (dest_ty != nullptr && var->decl_node) { 2073 // arg index + 1 because the 0 index is return value 2074 var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope), 2075 var->name, fn_walk->data.vars.import->data.structure.root_struct->di_file, 2076 (unsigned)(var->decl_node->line + 1), 2077 get_llvm_di_type(g, dest_ty), !g->strip_debug_symbols, 0, di_arg_index + 1); 2078 } 2079 return true; 2080 } 2081 2082 void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) { 2083 CallingConvention cc = fn_type->data.fn.fn_type_id.cc; 2084 if (cc == CallingConventionC) { 2085 size_t src_i = 0; 2086 for (;;) { 2087 if (!iter_function_params_c_abi(g, fn_type, fn_walk, src_i)) 2088 break; 2089 src_i += 1; 2090 } 2091 return; 2092 } 2093 if (fn_walk->id == FnWalkIdCall) { 2094 IrInstructionCallGen *instruction = fn_walk->data.call.inst; 2095 bool is_var_args = fn_walk->data.call.is_var_args; 2096 for (size_t call_i = 0; call_i < instruction->arg_count; call_i += 1) { 2097 IrInstruction *param_instruction = instruction->args[call_i]; 2098 ZigType *param_type = param_instruction->value->type; 2099 if (is_var_args || type_has_bits(param_type)) { 2100 LLVMValueRef param_value = ir_llvm_value(g, param_instruction); 2101 assert(param_value); 2102 fn_walk->data.call.gen_param_values->append(param_value); 2103 fn_walk->data.call.gen_param_types->append(param_type); 2104 } 2105 } 2106 return; 2107 } 2108 size_t next_var_i = 0; 2109 for (size_t param_i = 0; param_i < fn_type->data.fn.fn_type_id.param_count; param_i += 1) { 2110 FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i]; 2111 size_t gen_index = gen_info->gen_index; 2112 2113 if (gen_index == SIZE_MAX) { 2114 continue; 2115 } 2116 2117 switch (fn_walk->id) { 2118 case FnWalkIdAttrs: { 2119 LLVMValueRef llvm_fn = fn_walk->data.attrs.llvm_fn; 2120 bool is_byval = gen_info->is_byval; 2121 FnTypeParamInfo *param_info = &fn_type->data.fn.fn_type_id.param_info[param_i]; 2122 2123 ZigType *param_type = gen_info->type; 2124 if (param_info->is_noalias) { 2125 addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "noalias"); 2126 } 2127 if ((param_type->id == ZigTypeIdPointer && param_type->data.pointer.is_const) || is_byval) { 2128 addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "readonly"); 2129 } 2130 if (get_codegen_ptr_type(param_type) != nullptr) { 2131 addLLVMArgAttrInt(llvm_fn, (unsigned)gen_index, "align", get_ptr_align(g, param_type)); 2132 } 2133 if (type_is_nonnull_ptr(param_type)) { 2134 addLLVMArgAttr(llvm_fn, (unsigned)gen_index, "nonnull"); 2135 } 2136 break; 2137 } 2138 case FnWalkIdInits: { 2139 ZigFn *fn_table_entry = fn_walk->data.inits.fn; 2140 LLVMValueRef llvm_fn = fn_table_entry->llvm_value; 2141 ZigVar *variable = fn_table_entry->variable_list.at(next_var_i); 2142 assert(variable->src_arg_index != SIZE_MAX); 2143 next_var_i += 1; 2144 2145 assert(variable); 2146 assert(variable->value_ref); 2147 2148 if (!handle_is_ptr(variable->var_type) && !fn_is_async(fn_walk->data.inits.fn)) { 2149 clear_debug_source_node(g); 2150 ZigType *fn_type = fn_table_entry->type_entry; 2151 unsigned gen_arg_index = fn_type->data.fn.gen_param_info[variable->src_arg_index].gen_index; 2152 gen_store_untyped(g, LLVMGetParam(llvm_fn, gen_arg_index), 2153 variable->value_ref, variable->align_bytes, false); 2154 } 2155 2156 if (variable->decl_node) { 2157 gen_var_debug_decl(g, variable); 2158 } 2159 break; 2160 } 2161 case FnWalkIdCall: 2162 // handled before for loop 2163 zig_unreachable(); 2164 case FnWalkIdTypes: 2165 // Not called for non-c-abi 2166 zig_unreachable(); 2167 case FnWalkIdVars: 2168 // iter_function_params_c_abi is called directly for this one 2169 zig_unreachable(); 2170 } 2171 } 2172 } 2173 2174 static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) { 2175 if (g->merge_err_ret_traces_fn_val) 2176 return g->merge_err_ret_traces_fn_val; 2177 2178 assert(g->stack_trace_type != nullptr); 2179 2180 LLVMTypeRef param_types[] = { 2181 get_llvm_type(g, ptr_to_stack_trace_type(g)), 2182 get_llvm_type(g, ptr_to_stack_trace_type(g)), 2183 }; 2184 LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMVoidType(), param_types, 2, false); 2185 2186 const char *fn_name = get_mangled_name(g, "__zig_merge_error_return_traces", false); 2187 LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); 2188 LLVMSetLinkage(fn_val, LLVMInternalLinkage); 2189 ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); 2190 addLLVMFnAttr(fn_val, "nounwind"); 2191 add_uwtable_attr(g, fn_val); 2192 addLLVMArgAttr(fn_val, (unsigned)0, "noalias"); 2193 addLLVMArgAttr(fn_val, (unsigned)0, "writeonly"); 2194 2195 addLLVMArgAttr(fn_val, (unsigned)1, "noalias"); 2196 addLLVMArgAttr(fn_val, (unsigned)1, "readonly"); 2197 if (g->build_mode == BuildModeDebug) { 2198 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); 2199 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr); 2200 } 2201 2202 // this is above the ZigLLVMClearCurrentDebugLocation 2203 LLVMValueRef add_error_return_trace_addr_fn_val = get_add_error_return_trace_addr_fn(g); 2204 2205 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry"); 2206 LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder); 2207 LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder); 2208 LLVMPositionBuilderAtEnd(g->builder, entry_block); 2209 ZigLLVMClearCurrentDebugLocation(g->builder); 2210 2211 // if (dest_stack_trace == null or src_stack_trace == null) return; 2212 // var frame_index: usize = undefined; 2213 // var frames_left: usize = undefined; 2214 // if (src_stack_trace.index < src_stack_trace.instruction_addresses.len) { 2215 // frame_index = 0; 2216 // frames_left = src_stack_trace.index; 2217 // if (frames_left == 0) return; 2218 // } else { 2219 // frame_index = (src_stack_trace.index + 1) % src_stack_trace.instruction_addresses.len; 2220 // frames_left = src_stack_trace.instruction_addresses.len; 2221 // } 2222 // while (true) { 2223 // __zig_add_err_ret_trace_addr(dest_stack_trace, src_stack_trace.instruction_addresses[frame_index]); 2224 // frames_left -= 1; 2225 // if (frames_left == 0) return; 2226 // frame_index = (frame_index + 1) % src_stack_trace.instruction_addresses.len; 2227 // } 2228 LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return"); 2229 LLVMBasicBlockRef non_null_block = LLVMAppendBasicBlock(fn_val, "NonNull"); 2230 2231 LLVMValueRef frame_index_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frame_index"); 2232 LLVMValueRef frames_left_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frames_left"); 2233 2234 LLVMValueRef dest_stack_trace_ptr = LLVMGetParam(fn_val, 0); 2235 LLVMValueRef src_stack_trace_ptr = LLVMGetParam(fn_val, 1); 2236 2237 LLVMValueRef null_dest_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, dest_stack_trace_ptr, 2238 LLVMConstNull(LLVMTypeOf(dest_stack_trace_ptr)), ""); 2239 LLVMValueRef null_src_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, src_stack_trace_ptr, 2240 LLVMConstNull(LLVMTypeOf(src_stack_trace_ptr)), ""); 2241 LLVMValueRef null_bit = LLVMBuildOr(g->builder, null_dest_bit, null_src_bit, ""); 2242 LLVMBuildCondBr(g->builder, null_bit, return_block, non_null_block); 2243 2244 LLVMPositionBuilderAtEnd(g->builder, non_null_block); 2245 size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index; 2246 size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index; 2247 LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr, 2248 (unsigned)src_index_field_index, ""); 2249 LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr, 2250 (unsigned)src_addresses_field_index, ""); 2251 ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry; 2252 size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index; 2253 LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)ptr_field_index, ""); 2254 size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index; 2255 LLVMValueRef src_len_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)len_field_index, ""); 2256 LLVMValueRef src_index_val = LLVMBuildLoad(g->builder, src_index_field_ptr, ""); 2257 LLVMValueRef src_ptr_val = LLVMBuildLoad(g->builder, src_ptr_field_ptr, ""); 2258 LLVMValueRef src_len_val = LLVMBuildLoad(g->builder, src_len_field_ptr, ""); 2259 LLVMValueRef no_wrap_bit = LLVMBuildICmp(g->builder, LLVMIntULT, src_index_val, src_len_val, ""); 2260 LLVMBasicBlockRef no_wrap_block = LLVMAppendBasicBlock(fn_val, "NoWrap"); 2261 LLVMBasicBlockRef yes_wrap_block = LLVMAppendBasicBlock(fn_val, "YesWrap"); 2262 LLVMBasicBlockRef loop_block = LLVMAppendBasicBlock(fn_val, "Loop"); 2263 LLVMBuildCondBr(g->builder, no_wrap_bit, no_wrap_block, yes_wrap_block); 2264 2265 LLVMPositionBuilderAtEnd(g->builder, no_wrap_block); 2266 LLVMValueRef usize_zero = LLVMConstNull(g->builtin_types.entry_usize->llvm_type); 2267 LLVMBuildStore(g->builder, usize_zero, frame_index_ptr); 2268 LLVMBuildStore(g->builder, src_index_val, frames_left_ptr); 2269 LLVMValueRef frames_left_eq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, src_index_val, usize_zero, ""); 2270 LLVMBuildCondBr(g->builder, frames_left_eq_zero_bit, return_block, loop_block); 2271 2272 LLVMPositionBuilderAtEnd(g->builder, yes_wrap_block); 2273 LLVMValueRef usize_one = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 1, false); 2274 LLVMValueRef plus_one = LLVMBuildNUWAdd(g->builder, src_index_val, usize_one, ""); 2275 LLVMValueRef mod_len = LLVMBuildURem(g->builder, plus_one, src_len_val, ""); 2276 LLVMBuildStore(g->builder, mod_len, frame_index_ptr); 2277 LLVMBuildStore(g->builder, src_len_val, frames_left_ptr); 2278 LLVMBuildBr(g->builder, loop_block); 2279 2280 LLVMPositionBuilderAtEnd(g->builder, loop_block); 2281 LLVMValueRef ptr_index = LLVMBuildLoad(g->builder, frame_index_ptr, ""); 2282 LLVMValueRef addr_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr_val, &ptr_index, 1, ""); 2283 LLVMValueRef this_addr_val = LLVMBuildLoad(g->builder, addr_ptr, ""); 2284 LLVMValueRef args[] = {dest_stack_trace_ptr, this_addr_val}; 2285 ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAlwaysInline, ""); 2286 LLVMValueRef prev_frames_left = LLVMBuildLoad(g->builder, frames_left_ptr, ""); 2287 LLVMValueRef new_frames_left = LLVMBuildNUWSub(g->builder, prev_frames_left, usize_one, ""); 2288 LLVMValueRef done_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, new_frames_left, usize_zero, ""); 2289 LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(fn_val, "Continue"); 2290 LLVMBuildCondBr(g->builder, done_bit, return_block, continue_block); 2291 2292 LLVMPositionBuilderAtEnd(g->builder, return_block); 2293 LLVMBuildRetVoid(g->builder); 2294 2295 LLVMPositionBuilderAtEnd(g->builder, continue_block); 2296 LLVMBuildStore(g->builder, new_frames_left, frames_left_ptr); 2297 LLVMValueRef prev_index = LLVMBuildLoad(g->builder, frame_index_ptr, ""); 2298 LLVMValueRef index_plus_one = LLVMBuildNUWAdd(g->builder, prev_index, usize_one, ""); 2299 LLVMValueRef index_mod_len = LLVMBuildURem(g->builder, index_plus_one, src_len_val, ""); 2300 LLVMBuildStore(g->builder, index_mod_len, frame_index_ptr); 2301 LLVMBuildBr(g->builder, loop_block); 2302 2303 LLVMPositionBuilderAtEnd(g->builder, prev_block); 2304 if (!g->strip_debug_symbols) { 2305 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location); 2306 } 2307 2308 g->merge_err_ret_traces_fn_val = fn_val; 2309 return fn_val; 2310 2311 } 2312 static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, IrExecutable *executable, 2313 IrInstructionSaveErrRetAddr *save_err_ret_addr_instruction) 2314 { 2315 assert(g->have_err_ret_tracing); 2316 2317 LLVMValueRef return_err_fn = get_return_err_fn(g); 2318 bool is_llvm_alloca; 2319 LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, save_err_ret_addr_instruction->base.scope, 2320 &is_llvm_alloca); 2321 ZigLLVMBuildCall(g->builder, return_err_fn, &my_err_trace_val, 1, 2322 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, ""); 2323 2324 ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type; 2325 if (fn_is_async(g->cur_fn) && codegen_fn_has_err_ret_tracing_arg(g, ret_type)) { 2326 LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, 2327 frame_index_trace_arg(g, ret_type), ""); 2328 LLVMBuildStore(g->builder, my_err_trace_val, trace_ptr_ptr); 2329 } 2330 2331 return nullptr; 2332 } 2333 2334 static void gen_assert_resume_id(CodeGen *g, IrInstruction *source_instr, ResumeId resume_id, PanicMsgId msg_id, 2335 LLVMBasicBlockRef end_bb) 2336 { 2337 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 2338 2339 if (ir_want_runtime_safety(g, source_instr)) { 2340 // Write a value to the resume index which indicates the function was resumed while not suspended. 2341 LLVMBuildStore(g->builder, g->cur_bad_not_suspended_index, g->cur_async_resume_index_ptr); 2342 } 2343 2344 LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadResume"); 2345 if (end_bb == nullptr) end_bb = LLVMAppendBasicBlock(g->cur_fn_val, "OkResume"); 2346 LLVMValueRef expected_value = LLVMConstSub(LLVMConstAllOnes(usize_type_ref), 2347 LLVMConstInt(usize_type_ref, resume_id, false)); 2348 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, LLVMGetParam(g->cur_fn_val, 1), expected_value, ""); 2349 LLVMBuildCondBr(g->builder, ok_bit, end_bb, bad_resume_block); 2350 2351 LLVMPositionBuilderAtEnd(g->builder, bad_resume_block); 2352 gen_assertion(g, msg_id, source_instr); 2353 2354 LLVMPositionBuilderAtEnd(g->builder, end_bb); 2355 } 2356 2357 static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef target_frame_ptr, ResumeId resume_id) { 2358 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 2359 if (fn_val == nullptr) { 2360 LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_fn_ptr_index, ""); 2361 fn_val = LLVMBuildLoad(g->builder, fn_ptr_ptr, ""); 2362 } 2363 LLVMValueRef arg_val = LLVMConstSub(LLVMConstAllOnes(usize_type_ref), 2364 LLVMConstInt(usize_type_ref, resume_id, false)); 2365 LLVMValueRef args[] = {target_frame_ptr, arg_val}; 2366 return ZigLLVMBuildCall(g->builder, fn_val, args, 2, ZigLLVM_Fast, ZigLLVM_CallAttrAuto, ""); 2367 } 2368 2369 static LLVMBasicBlockRef gen_suspend_begin(CodeGen *g, const char *name_hint) { 2370 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 2371 LLVMBasicBlockRef resume_bb = LLVMAppendBasicBlock(g->cur_fn_val, name_hint); 2372 size_t new_block_index = g->cur_resume_block_count; 2373 g->cur_resume_block_count += 1; 2374 LLVMValueRef new_block_index_val = LLVMConstInt(usize_type_ref, new_block_index, false); 2375 LLVMAddCase(g->cur_async_switch_instr, new_block_index_val, resume_bb); 2376 LLVMBuildStore(g->builder, new_block_index_val, g->cur_async_resume_index_ptr); 2377 return resume_bb; 2378 } 2379 2380 // Be careful setting tail call. According to LLVM lang ref, 2381 // tail and musttail imply that the callee does not access allocas from the caller. 2382 // This works for async functions since the locals are spilled. 2383 // http://llvm.org/docs/LangRef.html#id320 2384 static void set_tail_call_if_appropriate(CodeGen *g, LLVMValueRef call_inst) { 2385 LLVMSetTailCall(call_inst, true); 2386 } 2387 2388 static LLVMValueRef gen_maybe_atomic_op(CodeGen *g, LLVMAtomicRMWBinOp op, LLVMValueRef ptr, LLVMValueRef val, 2389 LLVMAtomicOrdering order) 2390 { 2391 if (g->is_single_threaded) { 2392 LLVMValueRef loaded = LLVMBuildLoad(g->builder, ptr, ""); 2393 LLVMValueRef modified; 2394 switch (op) { 2395 case LLVMAtomicRMWBinOpXchg: 2396 modified = val; 2397 break; 2398 case LLVMAtomicRMWBinOpXor: 2399 modified = LLVMBuildXor(g->builder, loaded, val, ""); 2400 break; 2401 default: 2402 zig_unreachable(); 2403 } 2404 LLVMBuildStore(g->builder, modified, ptr); 2405 return loaded; 2406 } else { 2407 return LLVMBuildAtomicRMW(g->builder, op, ptr, val, order, false); 2408 } 2409 } 2410 2411 static void gen_async_return(CodeGen *g, IrInstructionReturn *instruction) { 2412 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 2413 2414 ZigType *operand_type = (instruction->operand != nullptr) ? instruction->operand->value->type : nullptr; 2415 bool operand_has_bits = (operand_type != nullptr) && type_has_bits(operand_type); 2416 ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type; 2417 bool ret_type_has_bits = type_has_bits(ret_type); 2418 2419 if (operand_has_bits && instruction->operand != nullptr) { 2420 bool need_store = instruction->operand->value->special != ConstValSpecialRuntime || !handle_is_ptr(ret_type); 2421 if (need_store) { 2422 // It didn't get written to the result ptr. We do that now. 2423 ZigType *ret_ptr_type = get_pointer_to_type(g, ret_type, true); 2424 gen_assign_raw(g, g->cur_ret_ptr, ret_ptr_type, ir_llvm_value(g, instruction->operand)); 2425 } 2426 } 2427 2428 // Whether we tail resume the awaiter, or do an early return, we are done and will not be resumed. 2429 if (ir_want_runtime_safety(g, &instruction->base)) { 2430 LLVMValueRef new_resume_index = LLVMConstAllOnes(usize_type_ref); 2431 LLVMBuildStore(g->builder, new_resume_index, g->cur_async_resume_index_ptr); 2432 } 2433 2434 LLVMValueRef zero = LLVMConstNull(usize_type_ref); 2435 LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref); 2436 2437 LLVMValueRef prev_val = gen_maybe_atomic_op(g, LLVMAtomicRMWBinOpXor, g->cur_async_awaiter_ptr, 2438 all_ones, LLVMAtomicOrderingAcquire); 2439 2440 LLVMBasicBlockRef bad_return_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadReturn"); 2441 LLVMBasicBlockRef early_return_block = LLVMAppendBasicBlock(g->cur_fn_val, "EarlyReturn"); 2442 LLVMBasicBlockRef resume_them_block = LLVMAppendBasicBlock(g->cur_fn_val, "ResumeThem"); 2443 2444 LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, prev_val, resume_them_block, 2); 2445 2446 LLVMAddCase(switch_instr, zero, early_return_block); 2447 LLVMAddCase(switch_instr, all_ones, bad_return_block); 2448 2449 // Something has gone horribly wrong, and this is an invalid second return. 2450 LLVMPositionBuilderAtEnd(g->builder, bad_return_block); 2451 gen_assertion(g, PanicMsgIdBadReturn, &instruction->base); 2452 2453 // There is no awaiter yet, but we're completely done. 2454 LLVMPositionBuilderAtEnd(g->builder, early_return_block); 2455 LLVMBuildRetVoid(g->builder); 2456 2457 // We need to resume the caller by tail calling them, 2458 // but first write through the result pointer and possibly 2459 // error return trace pointer. 2460 LLVMPositionBuilderAtEnd(g->builder, resume_them_block); 2461 2462 if (ret_type_has_bits) { 2463 // If the awaiter result pointer is non-null, we need to copy the result to there. 2464 LLVMBasicBlockRef copy_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResult"); 2465 LLVMBasicBlockRef copy_end_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResultEnd"); 2466 LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_ret_start + 1, ""); 2467 LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad(g->builder, awaiter_ret_ptr_ptr, ""); 2468 LLVMValueRef zero_ptr = LLVMConstNull(LLVMTypeOf(awaiter_ret_ptr)); 2469 LLVMValueRef need_copy_bit = LLVMBuildICmp(g->builder, LLVMIntNE, awaiter_ret_ptr, zero_ptr, ""); 2470 LLVMBuildCondBr(g->builder, need_copy_bit, copy_block, copy_end_block); 2471 2472 LLVMPositionBuilderAtEnd(g->builder, copy_block); 2473 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); 2474 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, awaiter_ret_ptr, ptr_u8, ""); 2475 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, g->cur_ret_ptr, ptr_u8, ""); 2476 bool is_volatile = false; 2477 uint32_t abi_align = get_abi_alignment(g, ret_type); 2478 LLVMValueRef byte_count_val = LLVMConstInt(usize_type_ref, type_size(g, ret_type), false); 2479 ZigLLVMBuildMemCpy(g->builder, 2480 dest_ptr_casted, abi_align, 2481 src_ptr_casted, abi_align, byte_count_val, is_volatile); 2482 LLVMBuildBr(g->builder, copy_end_block); 2483 2484 LLVMPositionBuilderAtEnd(g->builder, copy_end_block); 2485 if (codegen_fn_has_err_ret_tracing_arg(g, ret_type)) { 2486 LLVMValueRef awaiter_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, 2487 frame_index_trace_arg(g, ret_type) + 1, ""); 2488 LLVMValueRef dest_trace_ptr = LLVMBuildLoad(g->builder, awaiter_trace_ptr_ptr, ""); 2489 bool is_llvm_alloca; 2490 LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca); 2491 LLVMValueRef args[] = { dest_trace_ptr, my_err_trace_val }; 2492 ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2, 2493 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, ""); 2494 } 2495 } 2496 2497 // Resume the caller by tail calling them. 2498 ZigType *any_frame_type = get_any_frame_type(g, ret_type); 2499 LLVMValueRef their_frame_ptr = LLVMBuildIntToPtr(g->builder, prev_val, get_llvm_type(g, any_frame_type), ""); 2500 LLVMValueRef call_inst = gen_resume(g, nullptr, their_frame_ptr, ResumeIdReturn); 2501 set_tail_call_if_appropriate(g, call_inst); 2502 LLVMBuildRetVoid(g->builder); 2503 } 2504 2505 static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *instruction) { 2506 if (fn_is_async(g->cur_fn)) { 2507 gen_async_return(g, instruction); 2508 return nullptr; 2509 } 2510 2511 if (want_first_arg_sret(g, &g->cur_fn->type_entry->data.fn.fn_type_id)) { 2512 if (instruction->operand == nullptr) { 2513 LLVMBuildRetVoid(g->builder); 2514 return nullptr; 2515 } 2516 assert(g->cur_ret_ptr); 2517 ir_assert(instruction->operand->value->special != ConstValSpecialRuntime, &instruction->base); 2518 LLVMValueRef value = ir_llvm_value(g, instruction->operand); 2519 ZigType *return_type = instruction->operand->value->type; 2520 gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value); 2521 LLVMBuildRetVoid(g->builder); 2522 } else if (g->cur_fn->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync && 2523 handle_is_ptr(g->cur_fn->type_entry->data.fn.fn_type_id.return_type)) 2524 { 2525 if (instruction->operand == nullptr) { 2526 LLVMValueRef by_val_value = gen_load_untyped(g, g->cur_ret_ptr, 0, false, ""); 2527 LLVMBuildRet(g->builder, by_val_value); 2528 } else { 2529 LLVMValueRef value = ir_llvm_value(g, instruction->operand); 2530 LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, ""); 2531 LLVMBuildRet(g->builder, by_val_value); 2532 } 2533 } else if (instruction->operand == nullptr) { 2534 LLVMBuildRetVoid(g->builder); 2535 } else { 2536 LLVMValueRef value = ir_llvm_value(g, instruction->operand); 2537 LLVMBuildRet(g->builder, value); 2538 } 2539 return nullptr; 2540 } 2541 2542 static LLVMValueRef gen_overflow_shl_op(CodeGen *g, ZigType *type_entry, 2543 LLVMValueRef val1, LLVMValueRef val2) 2544 { 2545 // for unsigned left shifting, we do the lossy shift, then logically shift 2546 // right the same number of bits 2547 // if the values don't match, we have an overflow 2548 // for signed left shifting we do the same except arithmetic shift right 2549 2550 assert(type_entry->id == ZigTypeIdInt); 2551 2552 LLVMValueRef result = LLVMBuildShl(g->builder, val1, val2, ""); 2553 LLVMValueRef orig_val; 2554 if (type_entry->data.integral.is_signed) { 2555 orig_val = LLVMBuildAShr(g->builder, result, val2, ""); 2556 } else { 2557 orig_val = LLVMBuildLShr(g->builder, result, val2, ""); 2558 } 2559 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, val1, orig_val, ""); 2560 2561 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowOk"); 2562 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowFail"); 2563 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); 2564 2565 LLVMPositionBuilderAtEnd(g->builder, fail_block); 2566 gen_safety_crash(g, PanicMsgIdShlOverflowedBits); 2567 2568 LLVMPositionBuilderAtEnd(g->builder, ok_block); 2569 return result; 2570 } 2571 2572 static LLVMValueRef gen_overflow_shr_op(CodeGen *g, ZigType *type_entry, 2573 LLVMValueRef val1, LLVMValueRef val2) 2574 { 2575 assert(type_entry->id == ZigTypeIdInt); 2576 2577 LLVMValueRef result; 2578 if (type_entry->data.integral.is_signed) { 2579 result = LLVMBuildAShr(g->builder, val1, val2, ""); 2580 } else { 2581 result = LLVMBuildLShr(g->builder, val1, val2, ""); 2582 } 2583 LLVMValueRef orig_val = LLVMBuildShl(g->builder, result, val2, ""); 2584 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, val1, orig_val, ""); 2585 2586 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowOk"); 2587 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "OverflowFail"); 2588 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); 2589 2590 LLVMPositionBuilderAtEnd(g->builder, fail_block); 2591 gen_safety_crash(g, PanicMsgIdShrOverflowedBits); 2592 2593 LLVMPositionBuilderAtEnd(g->builder, ok_block); 2594 return result; 2595 } 2596 2597 static LLVMValueRef gen_float_op(CodeGen *g, LLVMValueRef val, ZigType *type_entry, BuiltinFnId op) { 2598 if ((op == BuiltinFnIdCeil || 2599 op == BuiltinFnIdFloor) && 2600 type_entry->id == ZigTypeIdInt) 2601 return val; 2602 assert(type_entry->id == ZigTypeIdFloat); 2603 2604 LLVMValueRef floor_fn = get_float_fn(g, type_entry, ZigLLVMFnIdFloatOp, op); 2605 return LLVMBuildCall(g->builder, floor_fn, &val, 1, ""); 2606 } 2607 2608 enum DivKind { 2609 DivKindFloat, 2610 DivKindTrunc, 2611 DivKindFloor, 2612 DivKindExact, 2613 }; 2614 2615 static LLVMValueRef bigint_to_llvm_const(LLVMTypeRef type_ref, BigInt *bigint) { 2616 if (bigint->digit_count == 0) { 2617 return LLVMConstNull(type_ref); 2618 } 2619 LLVMValueRef unsigned_val; 2620 if (bigint->digit_count == 1) { 2621 unsigned_val = LLVMConstInt(type_ref, bigint_ptr(bigint)[0], false); 2622 } else { 2623 unsigned_val = LLVMConstIntOfArbitraryPrecision(type_ref, bigint->digit_count, bigint_ptr(bigint)); 2624 } 2625 if (bigint->is_negative) { 2626 return LLVMConstNeg(unsigned_val); 2627 } else { 2628 return unsigned_val; 2629 } 2630 } 2631 2632 static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast_math, 2633 LLVMValueRef val1, LLVMValueRef val2, 2634 ZigType *type_entry, DivKind div_kind) 2635 { 2636 ZigLLVMSetFastMath(g->builder, want_fast_math); 2637 2638 LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, type_entry)); 2639 if (want_runtime_safety && (want_fast_math || type_entry->id != ZigTypeIdFloat)) { 2640 LLVMValueRef is_zero_bit; 2641 if (type_entry->id == ZigTypeIdInt) { 2642 is_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, ""); 2643 } else if (type_entry->id == ZigTypeIdFloat) { 2644 is_zero_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, val2, zero, ""); 2645 } else { 2646 zig_unreachable(); 2647 } 2648 LLVMBasicBlockRef div_zero_fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivZeroFail"); 2649 LLVMBasicBlockRef div_zero_ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivZeroOk"); 2650 LLVMBuildCondBr(g->builder, is_zero_bit, div_zero_fail_block, div_zero_ok_block); 2651 2652 LLVMPositionBuilderAtEnd(g->builder, div_zero_fail_block); 2653 gen_safety_crash(g, PanicMsgIdDivisionByZero); 2654 2655 LLVMPositionBuilderAtEnd(g->builder, div_zero_ok_block); 2656 2657 if (type_entry->id == ZigTypeIdInt && type_entry->data.integral.is_signed) { 2658 LLVMValueRef neg_1_value = LLVMConstInt(get_llvm_type(g, type_entry), -1, true); 2659 BigInt int_min_bi = {0}; 2660 eval_min_max_value_int(g, type_entry, &int_min_bi, false); 2661 LLVMValueRef int_min_value = bigint_to_llvm_const(get_llvm_type(g, type_entry), &int_min_bi); 2662 LLVMBasicBlockRef overflow_fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivOverflowFail"); 2663 LLVMBasicBlockRef overflow_ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivOverflowOk"); 2664 LLVMValueRef num_is_int_min = LLVMBuildICmp(g->builder, LLVMIntEQ, val1, int_min_value, ""); 2665 LLVMValueRef den_is_neg_1 = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, neg_1_value, ""); 2666 LLVMValueRef overflow_fail_bit = LLVMBuildAnd(g->builder, num_is_int_min, den_is_neg_1, ""); 2667 LLVMBuildCondBr(g->builder, overflow_fail_bit, overflow_fail_block, overflow_ok_block); 2668 2669 LLVMPositionBuilderAtEnd(g->builder, overflow_fail_block); 2670 gen_safety_crash(g, PanicMsgIdIntegerOverflow); 2671 2672 LLVMPositionBuilderAtEnd(g->builder, overflow_ok_block); 2673 } 2674 } 2675 2676 if (type_entry->id == ZigTypeIdFloat) { 2677 LLVMValueRef result = LLVMBuildFDiv(g->builder, val1, val2, ""); 2678 switch (div_kind) { 2679 case DivKindFloat: 2680 return result; 2681 case DivKindExact: 2682 if (want_runtime_safety) { 2683 LLVMValueRef floored = gen_float_op(g, result, type_entry, BuiltinFnIdFloor); 2684 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactOk"); 2685 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail"); 2686 LLVMValueRef ok_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, floored, result, ""); 2687 2688 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); 2689 2690 LLVMPositionBuilderAtEnd(g->builder, fail_block); 2691 gen_safety_crash(g, PanicMsgIdExactDivisionRemainder); 2692 2693 LLVMPositionBuilderAtEnd(g->builder, ok_block); 2694 } 2695 return result; 2696 case DivKindTrunc: 2697 { 2698 LLVMBasicBlockRef ltz_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncLTZero"); 2699 LLVMBasicBlockRef gez_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncGEZero"); 2700 LLVMBasicBlockRef end_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivTruncEnd"); 2701 LLVMValueRef ltz = LLVMBuildFCmp(g->builder, LLVMRealOLT, val1, zero, ""); 2702 LLVMBuildCondBr(g->builder, ltz, ltz_block, gez_block); 2703 2704 LLVMPositionBuilderAtEnd(g->builder, ltz_block); 2705 LLVMValueRef ceiled = gen_float_op(g, result, type_entry, BuiltinFnIdCeil); 2706 LLVMBasicBlockRef ceiled_end_block = LLVMGetInsertBlock(g->builder); 2707 LLVMBuildBr(g->builder, end_block); 2708 2709 LLVMPositionBuilderAtEnd(g->builder, gez_block); 2710 LLVMValueRef floored = gen_float_op(g, result, type_entry, BuiltinFnIdFloor); 2711 LLVMBasicBlockRef floored_end_block = LLVMGetInsertBlock(g->builder); 2712 LLVMBuildBr(g->builder, end_block); 2713 2714 LLVMPositionBuilderAtEnd(g->builder, end_block); 2715 LLVMValueRef phi = LLVMBuildPhi(g->builder, get_llvm_type(g, type_entry), ""); 2716 LLVMValueRef incoming_values[] = { ceiled, floored }; 2717 LLVMBasicBlockRef incoming_blocks[] = { ceiled_end_block, floored_end_block }; 2718 LLVMAddIncoming(phi, incoming_values, incoming_blocks, 2); 2719 return phi; 2720 } 2721 case DivKindFloor: 2722 return gen_float_op(g, result, type_entry, BuiltinFnIdFloor); 2723 } 2724 zig_unreachable(); 2725 } 2726 2727 assert(type_entry->id == ZigTypeIdInt); 2728 2729 switch (div_kind) { 2730 case DivKindFloat: 2731 zig_unreachable(); 2732 case DivKindTrunc: 2733 if (type_entry->data.integral.is_signed) { 2734 return LLVMBuildSDiv(g->builder, val1, val2, ""); 2735 } else { 2736 return LLVMBuildUDiv(g->builder, val1, val2, ""); 2737 } 2738 case DivKindExact: 2739 if (want_runtime_safety) { 2740 LLVMValueRef remainder_val; 2741 if (type_entry->data.integral.is_signed) { 2742 remainder_val = LLVMBuildSRem(g->builder, val1, val2, ""); 2743 } else { 2744 remainder_val = LLVMBuildURem(g->builder, val1, val2, ""); 2745 } 2746 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, ""); 2747 2748 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactOk"); 2749 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail"); 2750 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); 2751 2752 LLVMPositionBuilderAtEnd(g->builder, fail_block); 2753 gen_safety_crash(g, PanicMsgIdExactDivisionRemainder); 2754 2755 LLVMPositionBuilderAtEnd(g->builder, ok_block); 2756 } 2757 if (type_entry->data.integral.is_signed) { 2758 return LLVMBuildExactSDiv(g->builder, val1, val2, ""); 2759 } else { 2760 return LLVMBuildExactUDiv(g->builder, val1, val2, ""); 2761 } 2762 case DivKindFloor: 2763 { 2764 if (!type_entry->data.integral.is_signed) { 2765 return LLVMBuildUDiv(g->builder, val1, val2, ""); 2766 } 2767 // const d = @divTrunc(a, b); 2768 // const r = @rem(a, b); 2769 // return if (r == 0) d else d - ((a < 0) ^ (b < 0)); 2770 2771 LLVMValueRef div_trunc = LLVMBuildSDiv(g->builder, val1, val2, ""); 2772 LLVMValueRef rem = LLVMBuildSRem(g->builder, val1, val2, ""); 2773 LLVMValueRef rem_eq_0 = LLVMBuildICmp(g->builder, LLVMIntEQ, rem, zero, ""); 2774 LLVMValueRef a_lt_0 = LLVMBuildICmp(g->builder, LLVMIntSLT, val1, zero, ""); 2775 LLVMValueRef b_lt_0 = LLVMBuildICmp(g->builder, LLVMIntSLT, val2, zero, ""); 2776 LLVMValueRef a_b_xor = LLVMBuildXor(g->builder, a_lt_0, b_lt_0, ""); 2777 LLVMValueRef a_b_xor_ext = LLVMBuildZExt(g->builder, a_b_xor, LLVMTypeOf(div_trunc), ""); 2778 LLVMValueRef d_sub_xor = LLVMBuildSub(g->builder, div_trunc, a_b_xor_ext, ""); 2779 return LLVMBuildSelect(g->builder, rem_eq_0, div_trunc, d_sub_xor, ""); 2780 } 2781 } 2782 zig_unreachable(); 2783 } 2784 2785 enum RemKind { 2786 RemKindRem, 2787 RemKindMod, 2788 }; 2789 2790 static LLVMValueRef gen_rem(CodeGen *g, bool want_runtime_safety, bool want_fast_math, 2791 LLVMValueRef val1, LLVMValueRef val2, 2792 ZigType *type_entry, RemKind rem_kind) 2793 { 2794 ZigLLVMSetFastMath(g->builder, want_fast_math); 2795 2796 LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, type_entry)); 2797 if (want_runtime_safety) { 2798 LLVMValueRef is_zero_bit; 2799 if (type_entry->id == ZigTypeIdInt) { 2800 LLVMIntPredicate pred = type_entry->data.integral.is_signed ? LLVMIntSLE : LLVMIntEQ; 2801 is_zero_bit = LLVMBuildICmp(g->builder, pred, val2, zero, ""); 2802 } else if (type_entry->id == ZigTypeIdFloat) { 2803 is_zero_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, val2, zero, ""); 2804 } else { 2805 zig_unreachable(); 2806 } 2807 LLVMBasicBlockRef rem_zero_ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "RemZeroOk"); 2808 LLVMBasicBlockRef rem_zero_fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "RemZeroFail"); 2809 LLVMBuildCondBr(g->builder, is_zero_bit, rem_zero_fail_block, rem_zero_ok_block); 2810 2811 LLVMPositionBuilderAtEnd(g->builder, rem_zero_fail_block); 2812 gen_safety_crash(g, PanicMsgIdRemainderDivisionByZero); 2813 2814 LLVMPositionBuilderAtEnd(g->builder, rem_zero_ok_block); 2815 } 2816 2817 if (type_entry->id == ZigTypeIdFloat) { 2818 if (rem_kind == RemKindRem) { 2819 return LLVMBuildFRem(g->builder, val1, val2, ""); 2820 } else { 2821 LLVMValueRef a = LLVMBuildFRem(g->builder, val1, val2, ""); 2822 LLVMValueRef b = LLVMBuildFAdd(g->builder, a, val2, ""); 2823 LLVMValueRef c = LLVMBuildFRem(g->builder, b, val2, ""); 2824 LLVMValueRef ltz = LLVMBuildFCmp(g->builder, LLVMRealOLT, val1, zero, ""); 2825 return LLVMBuildSelect(g->builder, ltz, c, a, ""); 2826 } 2827 } else { 2828 assert(type_entry->id == ZigTypeIdInt); 2829 if (type_entry->data.integral.is_signed) { 2830 if (rem_kind == RemKindRem) { 2831 return LLVMBuildSRem(g->builder, val1, val2, ""); 2832 } else { 2833 LLVMValueRef a = LLVMBuildSRem(g->builder, val1, val2, ""); 2834 LLVMValueRef b = LLVMBuildNSWAdd(g->builder, a, val2, ""); 2835 LLVMValueRef c = LLVMBuildSRem(g->builder, b, val2, ""); 2836 LLVMValueRef ltz = LLVMBuildICmp(g->builder, LLVMIntSLT, val1, zero, ""); 2837 return LLVMBuildSelect(g->builder, ltz, c, a, ""); 2838 } 2839 } else { 2840 return LLVMBuildURem(g->builder, val1, val2, ""); 2841 } 2842 } 2843 2844 } 2845 2846 static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable, 2847 IrInstructionBinOp *bin_op_instruction) 2848 { 2849 IrBinOp op_id = bin_op_instruction->op_id; 2850 IrInstruction *op1 = bin_op_instruction->op1; 2851 IrInstruction *op2 = bin_op_instruction->op2; 2852 2853 ZigType *operand_type = op1->value->type; 2854 ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type; 2855 2856 bool want_runtime_safety = bin_op_instruction->safety_check_on && 2857 ir_want_runtime_safety(g, &bin_op_instruction->base); 2858 2859 LLVMValueRef op1_value = ir_llvm_value(g, op1); 2860 LLVMValueRef op2_value = ir_llvm_value(g, op2); 2861 2862 2863 switch (op_id) { 2864 case IrBinOpInvalid: 2865 case IrBinOpArrayCat: 2866 case IrBinOpArrayMult: 2867 case IrBinOpRemUnspecified: 2868 zig_unreachable(); 2869 case IrBinOpBoolOr: 2870 return LLVMBuildOr(g->builder, op1_value, op2_value, ""); 2871 case IrBinOpBoolAnd: 2872 return LLVMBuildAnd(g->builder, op1_value, op2_value, ""); 2873 case IrBinOpCmpEq: 2874 case IrBinOpCmpNotEq: 2875 case IrBinOpCmpLessThan: 2876 case IrBinOpCmpGreaterThan: 2877 case IrBinOpCmpLessOrEq: 2878 case IrBinOpCmpGreaterOrEq: 2879 if (scalar_type->id == ZigTypeIdFloat) { 2880 ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base)); 2881 LLVMRealPredicate pred = cmp_op_to_real_predicate(op_id); 2882 return LLVMBuildFCmp(g->builder, pred, op1_value, op2_value, ""); 2883 } else if (scalar_type->id == ZigTypeIdInt) { 2884 LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, scalar_type->data.integral.is_signed); 2885 return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, ""); 2886 } else if (scalar_type->id == ZigTypeIdEnum || 2887 scalar_type->id == ZigTypeIdErrorSet || 2888 scalar_type->id == ZigTypeIdBool || 2889 get_codegen_ptr_type(scalar_type) != nullptr) 2890 { 2891 LLVMIntPredicate pred = cmp_op_to_int_predicate(op_id, false); 2892 return LLVMBuildICmp(g->builder, pred, op1_value, op2_value, ""); 2893 } else { 2894 zig_unreachable(); 2895 } 2896 case IrBinOpMult: 2897 case IrBinOpMultWrap: 2898 case IrBinOpAdd: 2899 case IrBinOpAddWrap: 2900 case IrBinOpSub: 2901 case IrBinOpSubWrap: { 2902 bool is_wrapping = (op_id == IrBinOpSubWrap || op_id == IrBinOpAddWrap || op_id == IrBinOpMultWrap); 2903 AddSubMul add_sub_mul = 2904 op_id == IrBinOpAdd || op_id == IrBinOpAddWrap ? AddSubMulAdd : 2905 op_id == IrBinOpSub || op_id == IrBinOpSubWrap ? AddSubMulSub : 2906 AddSubMulMul; 2907 2908 if (scalar_type->id == ZigTypeIdPointer) { 2909 LLVMValueRef subscript_value; 2910 if (operand_type->id == ZigTypeIdVector) 2911 zig_panic("TODO: Implement vector operations on pointers."); 2912 2913 switch (add_sub_mul) { 2914 case AddSubMulAdd: 2915 subscript_value = op2_value; 2916 break; 2917 case AddSubMulSub: 2918 subscript_value = LLVMBuildNeg(g->builder, op2_value, ""); 2919 break; 2920 case AddSubMulMul: 2921 zig_unreachable(); 2922 } 2923 2924 // TODO runtime safety 2925 return LLVMBuildInBoundsGEP(g->builder, op1_value, &subscript_value, 1, ""); 2926 } else if (scalar_type->id == ZigTypeIdFloat) { 2927 ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base)); 2928 return float_op[add_sub_mul](g->builder, op1_value, op2_value, ""); 2929 } else if (scalar_type->id == ZigTypeIdInt) { 2930 if (is_wrapping) { 2931 return wrap_op[add_sub_mul](g->builder, op1_value, op2_value, ""); 2932 } else if (want_runtime_safety) { 2933 return gen_overflow_op(g, operand_type, add_sub_mul, op1_value, op2_value); 2934 } else if (scalar_type->data.integral.is_signed) { 2935 return signed_op[add_sub_mul](g->builder, op1_value, op2_value, ""); 2936 } else { 2937 return unsigned_op[add_sub_mul](g->builder, op1_value, op2_value, ""); 2938 } 2939 } else { 2940 zig_unreachable(); 2941 } 2942 } 2943 case IrBinOpBinOr: 2944 return LLVMBuildOr(g->builder, op1_value, op2_value, ""); 2945 case IrBinOpBinXor: 2946 return LLVMBuildXor(g->builder, op1_value, op2_value, ""); 2947 case IrBinOpBinAnd: 2948 return LLVMBuildAnd(g->builder, op1_value, op2_value, ""); 2949 case IrBinOpBitShiftLeftLossy: 2950 case IrBinOpBitShiftLeftExact: 2951 { 2952 assert(scalar_type->id == ZigTypeIdInt); 2953 LLVMValueRef op2_casted = gen_widen_or_shorten(g, false, op2->value->type, scalar_type, op2_value); 2954 bool is_sloppy = (op_id == IrBinOpBitShiftLeftLossy); 2955 if (is_sloppy) { 2956 return LLVMBuildShl(g->builder, op1_value, op2_casted, ""); 2957 } else if (want_runtime_safety) { 2958 return gen_overflow_shl_op(g, scalar_type, op1_value, op2_casted); 2959 } else if (scalar_type->data.integral.is_signed) { 2960 return ZigLLVMBuildNSWShl(g->builder, op1_value, op2_casted, ""); 2961 } else { 2962 return ZigLLVMBuildNUWShl(g->builder, op1_value, op2_casted, ""); 2963 } 2964 } 2965 case IrBinOpBitShiftRightLossy: 2966 case IrBinOpBitShiftRightExact: 2967 { 2968 assert(scalar_type->id == ZigTypeIdInt); 2969 LLVMValueRef op2_casted = gen_widen_or_shorten(g, false, op2->value->type, scalar_type, op2_value); 2970 bool is_sloppy = (op_id == IrBinOpBitShiftRightLossy); 2971 if (is_sloppy) { 2972 if (scalar_type->data.integral.is_signed) { 2973 return LLVMBuildAShr(g->builder, op1_value, op2_casted, ""); 2974 } else { 2975 return LLVMBuildLShr(g->builder, op1_value, op2_casted, ""); 2976 } 2977 } else if (want_runtime_safety) { 2978 return gen_overflow_shr_op(g, scalar_type, op1_value, op2_casted); 2979 } else if (scalar_type->data.integral.is_signed) { 2980 return ZigLLVMBuildAShrExact(g->builder, op1_value, op2_casted, ""); 2981 } else { 2982 return ZigLLVMBuildLShrExact(g->builder, op1_value, op2_casted, ""); 2983 } 2984 } 2985 case IrBinOpDivUnspecified: 2986 return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base), 2987 op1_value, op2_value, scalar_type, DivKindFloat); 2988 case IrBinOpDivExact: 2989 return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base), 2990 op1_value, op2_value, scalar_type, DivKindExact); 2991 case IrBinOpDivTrunc: 2992 return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base), 2993 op1_value, op2_value, scalar_type, DivKindTrunc); 2994 case IrBinOpDivFloor: 2995 return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base), 2996 op1_value, op2_value, scalar_type, DivKindFloor); 2997 case IrBinOpRemRem: 2998 return gen_rem(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base), 2999 op1_value, op2_value, scalar_type, RemKindRem); 3000 case IrBinOpRemMod: 3001 return gen_rem(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base), 3002 op1_value, op2_value, scalar_type, RemKindMod); 3003 } 3004 zig_unreachable(); 3005 } 3006 3007 static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *int_type, LLVMValueRef target_val) { 3008 assert(err_set_type->id == ZigTypeIdErrorSet); 3009 3010 if (type_is_global_error_set(err_set_type)) { 3011 LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, int_type)); 3012 LLVMValueRef neq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntNE, target_val, zero, ""); 3013 LLVMValueRef ok_bit; 3014 3015 BigInt biggest_possible_err_val = {0}; 3016 eval_min_max_value_int(g, int_type, &biggest_possible_err_val, true); 3017 3018 if (bigint_fits_in_bits(&biggest_possible_err_val, 64, false) && 3019 bigint_as_usize(&biggest_possible_err_val) < g->errors_by_index.length) 3020 { 3021 ok_bit = neq_zero_bit; 3022 } else { 3023 LLVMValueRef error_value_count = LLVMConstInt(get_llvm_type(g, int_type), g->errors_by_index.length, false); 3024 LLVMValueRef in_bounds_bit = LLVMBuildICmp(g->builder, LLVMIntULT, target_val, error_value_count, ""); 3025 ok_bit = LLVMBuildAnd(g->builder, neq_zero_bit, in_bounds_bit, ""); 3026 } 3027 3028 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "IntToErrOk"); 3029 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "IntToErrFail"); 3030 3031 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); 3032 3033 LLVMPositionBuilderAtEnd(g->builder, fail_block); 3034 gen_safety_crash(g, PanicMsgIdInvalidErrorCode); 3035 3036 LLVMPositionBuilderAtEnd(g->builder, ok_block); 3037 } else { 3038 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "IntToErrOk"); 3039 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "IntToErrFail"); 3040 3041 uint32_t err_count = err_set_type->data.error_set.err_count; 3042 LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, target_val, fail_block, err_count); 3043 for (uint32_t i = 0; i < err_count; i += 1) { 3044 LLVMValueRef case_value = LLVMConstInt(get_llvm_type(g, g->err_tag_type), 3045 err_set_type->data.error_set.errors[i]->value, false); 3046 LLVMAddCase(switch_instr, case_value, ok_block); 3047 } 3048 3049 LLVMPositionBuilderAtEnd(g->builder, fail_block); 3050 gen_safety_crash(g, PanicMsgIdInvalidErrorCode); 3051 3052 LLVMPositionBuilderAtEnd(g->builder, ok_block); 3053 } 3054 } 3055 3056 static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutable *executable, 3057 IrInstructionResizeSlice *instruction) 3058 { 3059 ZigType *actual_type = instruction->operand->value->type; 3060 ZigType *wanted_type = instruction->base.value->type; 3061 LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand); 3062 assert(expr_val); 3063 3064 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); 3065 assert(wanted_type->id == ZigTypeIdStruct); 3066 assert(wanted_type->data.structure.special == StructSpecialSlice); 3067 assert(actual_type->id == ZigTypeIdStruct); 3068 assert(actual_type->data.structure.special == StructSpecialSlice); 3069 3070 ZigType *actual_pointer_type = actual_type->data.structure.fields[0]->type_entry; 3071 ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type; 3072 ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0]->type_entry; 3073 ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type; 3074 3075 3076 size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index]->gen_index; 3077 size_t actual_len_index = actual_type->data.structure.fields[slice_len_index]->gen_index; 3078 size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index]->gen_index; 3079 size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index]->gen_index; 3080 3081 LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_ptr_index, ""); 3082 LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, ""); 3083 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, 3084 get_llvm_type(g, wanted_type->data.structure.fields[0]->type_entry), ""); 3085 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, result_loc, 3086 (unsigned)wanted_ptr_index, ""); 3087 gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false); 3088 3089 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_len_index, ""); 3090 LLVMValueRef src_len = gen_load_untyped(g, src_len_ptr, 0, false, ""); 3091 uint64_t src_size = type_size(g, actual_child_type); 3092 uint64_t dest_size = type_size(g, wanted_child_type); 3093 3094 LLVMValueRef new_len; 3095 if (dest_size == 1) { 3096 LLVMValueRef src_size_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, src_size, false); 3097 new_len = LLVMBuildMul(g->builder, src_len, src_size_val, ""); 3098 } else if (src_size == 1) { 3099 LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, dest_size, false); 3100 if (ir_want_runtime_safety(g, &instruction->base)) { 3101 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, ""); 3102 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->llvm_type); 3103 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, ""); 3104 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenOk"); 3105 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenFail"); 3106 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); 3107 3108 LLVMPositionBuilderAtEnd(g->builder, fail_block); 3109 gen_safety_crash(g, PanicMsgIdSliceWidenRemainder); 3110 3111 LLVMPositionBuilderAtEnd(g->builder, ok_block); 3112 } 3113 new_len = LLVMBuildExactUDiv(g->builder, src_len, dest_size_val, ""); 3114 } else { 3115 zig_unreachable(); 3116 } 3117 3118 LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, result_loc, (unsigned)wanted_len_index, ""); 3119 gen_store_untyped(g, new_len, dest_len_ptr, 0, false); 3120 3121 return result_loc; 3122 } 3123 3124 static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable, 3125 IrInstructionCast *cast_instruction) 3126 { 3127 ZigType *actual_type = cast_instruction->value->value->type; 3128 ZigType *wanted_type = cast_instruction->base.value->type; 3129 LLVMValueRef expr_val = ir_llvm_value(g, cast_instruction->value); 3130 ir_assert(expr_val, &cast_instruction->base); 3131 3132 switch (cast_instruction->cast_op) { 3133 case CastOpNoCast: 3134 case CastOpNumLitToConcrete: 3135 zig_unreachable(); 3136 case CastOpNoop: 3137 if (actual_type->id == ZigTypeIdPointer && wanted_type->id == ZigTypeIdPointer && 3138 actual_type->data.pointer.child_type->id == ZigTypeIdArray && 3139 wanted_type->data.pointer.child_type->id == ZigTypeIdArray) 3140 { 3141 return LLVMBuildBitCast(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); 3142 } else { 3143 return expr_val; 3144 } 3145 case CastOpIntToFloat: 3146 assert(actual_type->id == ZigTypeIdInt); 3147 if (actual_type->data.integral.is_signed) { 3148 return LLVMBuildSIToFP(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); 3149 } else { 3150 return LLVMBuildUIToFP(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); 3151 } 3152 case CastOpFloatToInt: { 3153 assert(wanted_type->id == ZigTypeIdInt); 3154 ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &cast_instruction->base)); 3155 3156 bool want_safety = ir_want_runtime_safety(g, &cast_instruction->base); 3157 3158 LLVMValueRef result; 3159 if (wanted_type->data.integral.is_signed) { 3160 result = LLVMBuildFPToSI(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); 3161 } else { 3162 result = LLVMBuildFPToUI(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); 3163 } 3164 3165 if (want_safety) { 3166 LLVMValueRef back_to_float; 3167 if (wanted_type->data.integral.is_signed) { 3168 back_to_float = LLVMBuildSIToFP(g->builder, result, LLVMTypeOf(expr_val), ""); 3169 } else { 3170 back_to_float = LLVMBuildUIToFP(g->builder, result, LLVMTypeOf(expr_val), ""); 3171 } 3172 LLVMValueRef difference = LLVMBuildFSub(g->builder, expr_val, back_to_float, ""); 3173 LLVMValueRef one_pos = LLVMConstReal(LLVMTypeOf(expr_val), 1.0f); 3174 LLVMValueRef one_neg = LLVMConstReal(LLVMTypeOf(expr_val), -1.0f); 3175 LLVMValueRef ok_bit_pos = LLVMBuildFCmp(g->builder, LLVMRealOLT, difference, one_pos, ""); 3176 LLVMValueRef ok_bit_neg = LLVMBuildFCmp(g->builder, LLVMRealOGT, difference, one_neg, ""); 3177 LLVMValueRef ok_bit = LLVMBuildAnd(g->builder, ok_bit_pos, ok_bit_neg, ""); 3178 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "FloatCheckOk"); 3179 LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "FloatCheckFail"); 3180 LLVMBuildCondBr(g->builder, ok_bit, ok_block, bad_block); 3181 LLVMPositionBuilderAtEnd(g->builder, bad_block); 3182 gen_safety_crash(g, PanicMsgIdFloatToInt); 3183 LLVMPositionBuilderAtEnd(g->builder, ok_block); 3184 } 3185 return result; 3186 } 3187 case CastOpBoolToInt: 3188 assert(wanted_type->id == ZigTypeIdInt); 3189 assert(actual_type->id == ZigTypeIdBool); 3190 return LLVMBuildZExt(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); 3191 case CastOpErrSet: 3192 if (ir_want_runtime_safety(g, &cast_instruction->base)) { 3193 add_error_range_check(g, wanted_type, g->err_tag_type, expr_val); 3194 } 3195 return expr_val; 3196 case CastOpBitCast: 3197 return LLVMBuildBitCast(g->builder, expr_val, get_llvm_type(g, wanted_type), ""); 3198 } 3199 zig_unreachable(); 3200 } 3201 3202 static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, IrExecutable *executable, 3203 IrInstructionPtrOfArrayToSlice *instruction) 3204 { 3205 ZigType *actual_type = instruction->operand->value->type; 3206 ZigType *slice_type = instruction->base.value->type; 3207 ZigType *slice_ptr_type = slice_type->data.structure.fields[slice_ptr_index]->type_entry; 3208 size_t ptr_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index; 3209 size_t len_index = slice_type->data.structure.fields[slice_len_index]->gen_index; 3210 3211 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); 3212 3213 assert(actual_type->id == ZigTypeIdPointer); 3214 ZigType *array_type = actual_type->data.pointer.child_type; 3215 assert(array_type->id == ZigTypeIdArray); 3216 3217 if (type_has_bits(actual_type)) { 3218 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, ""); 3219 LLVMValueRef indices[] = { 3220 LLVMConstNull(g->builtin_types.entry_usize->llvm_type), 3221 LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false), 3222 }; 3223 LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand); 3224 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, ""); 3225 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false); 3226 } else if (ir_want_runtime_safety(g, &instruction->base)) { 3227 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, ""); 3228 gen_undef_init(g, slice_ptr_type->abi_align, slice_ptr_type, ptr_field_ptr); 3229 } 3230 3231 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, len_index, ""); 3232 LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 3233 array_type->data.array.len, false); 3234 gen_store_untyped(g, len_value, len_field_ptr, 0, false); 3235 3236 return result_loc; 3237 } 3238 3239 static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable, 3240 IrInstructionPtrCastGen *instruction) 3241 { 3242 ZigType *wanted_type = instruction->base.value->type; 3243 if (!type_has_bits(wanted_type)) { 3244 return nullptr; 3245 } 3246 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); 3247 LLVMValueRef result_ptr = LLVMBuildBitCast(g->builder, ptr, get_llvm_type(g, wanted_type), ""); 3248 bool want_safety_check = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base); 3249 if (!want_safety_check || ptr_allows_addr_zero(wanted_type)) 3250 return result_ptr; 3251 3252 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(result_ptr)); 3253 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntNE, result_ptr, zero, ""); 3254 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrCastFail"); 3255 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrCastOk"); 3256 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); 3257 3258 LLVMPositionBuilderAtEnd(g->builder, fail_block); 3259 gen_safety_crash(g, PanicMsgIdPtrCastNull); 3260 3261 LLVMPositionBuilderAtEnd(g->builder, ok_block); 3262 return result_ptr; 3263 } 3264 3265 static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutable *executable, 3266 IrInstructionBitCastGen *instruction) 3267 { 3268 ZigType *wanted_type = instruction->base.value->type; 3269 ZigType *actual_type = instruction->operand->value->type; 3270 LLVMValueRef value = ir_llvm_value(g, instruction->operand); 3271 3272 bool wanted_is_ptr = handle_is_ptr(wanted_type); 3273 bool actual_is_ptr = handle_is_ptr(actual_type); 3274 if (wanted_is_ptr == actual_is_ptr) { 3275 // We either bitcast the value directly or bitcast the pointer which does a pointer cast 3276 LLVMTypeRef wanted_type_ref = wanted_is_ptr ? 3277 LLVMPointerType(get_llvm_type(g, wanted_type), 0) : get_llvm_type(g, wanted_type); 3278 return LLVMBuildBitCast(g->builder, value, wanted_type_ref, ""); 3279 } else if (actual_is_ptr) { 3280 LLVMTypeRef wanted_ptr_type_ref = LLVMPointerType(get_llvm_type(g, wanted_type), 0); 3281 LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, value, wanted_ptr_type_ref, ""); 3282 uint32_t alignment = get_abi_alignment(g, actual_type); 3283 return gen_load_untyped(g, bitcasted_ptr, alignment, false, ""); 3284 } else { 3285 zig_unreachable(); 3286 } 3287 } 3288 3289 static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable, 3290 IrInstructionWidenOrShorten *instruction) 3291 { 3292 ZigType *actual_type = instruction->target->value->type; 3293 // TODO instead of this logic, use the Noop instruction to change the type from 3294 // enum_tag to the underlying int type 3295 ZigType *int_type; 3296 if (actual_type->id == ZigTypeIdEnum) { 3297 int_type = actual_type->data.enumeration.tag_int_type; 3298 } else { 3299 int_type = actual_type; 3300 } 3301 LLVMValueRef target_val = ir_llvm_value(g, instruction->target); 3302 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base), int_type, 3303 instruction->base.value->type, target_val); 3304 } 3305 3306 static LLVMValueRef ir_render_int_to_ptr(CodeGen *g, IrExecutable *executable, IrInstructionIntToPtr *instruction) { 3307 ZigType *wanted_type = instruction->base.value->type; 3308 LLVMValueRef target_val = ir_llvm_value(g, instruction->target); 3309 3310 if (ir_want_runtime_safety(g, &instruction->base)) { 3311 ZigType *usize = g->builtin_types.entry_usize; 3312 LLVMValueRef zero = LLVMConstNull(usize->llvm_type); 3313 3314 if (!ptr_allows_addr_zero(wanted_type)) { 3315 LLVMValueRef is_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, target_val, zero, ""); 3316 LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrToIntBad"); 3317 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrToIntOk"); 3318 LLVMBuildCondBr(g->builder, is_zero_bit, bad_block, ok_block); 3319 3320 LLVMPositionBuilderAtEnd(g->builder, bad_block); 3321 gen_safety_crash(g, PanicMsgIdPtrCastNull); 3322 3323 LLVMPositionBuilderAtEnd(g->builder, ok_block); 3324 } 3325 3326 { 3327 const uint32_t align_bytes = get_ptr_align(g, wanted_type); 3328 LLVMValueRef alignment_minus_1 = LLVMConstInt(usize->llvm_type, align_bytes - 1, false); 3329 LLVMValueRef anded_val = LLVMBuildAnd(g->builder, target_val, alignment_minus_1, ""); 3330 LLVMValueRef is_ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, anded_val, zero, ""); 3331 LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrToIntAlignBad"); 3332 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "PtrToIntAlignOk"); 3333 LLVMBuildCondBr(g->builder, is_ok_bit, ok_block, bad_block); 3334 3335 LLVMPositionBuilderAtEnd(g->builder, bad_block); 3336 gen_safety_crash(g, PanicMsgIdIncorrectAlignment); 3337 3338 LLVMPositionBuilderAtEnd(g->builder, ok_block); 3339 } 3340 } 3341 return LLVMBuildIntToPtr(g->builder, target_val, get_llvm_type(g, wanted_type), ""); 3342 } 3343 3344 static LLVMValueRef ir_render_ptr_to_int(CodeGen *g, IrExecutable *executable, IrInstructionPtrToInt *instruction) { 3345 ZigType *wanted_type = instruction->base.value->type; 3346 LLVMValueRef target_val = ir_llvm_value(g, instruction->target); 3347 return LLVMBuildPtrToInt(g->builder, target_val, get_llvm_type(g, wanted_type), ""); 3348 } 3349 3350 static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable, IrInstructionIntToEnum *instruction) { 3351 ZigType *wanted_type = instruction->base.value->type; 3352 assert(wanted_type->id == ZigTypeIdEnum); 3353 ZigType *tag_int_type = wanted_type->data.enumeration.tag_int_type; 3354 3355 LLVMValueRef target_val = ir_llvm_value(g, instruction->target); 3356 LLVMValueRef tag_int_value = gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base), 3357 instruction->target->value->type, tag_int_type, target_val); 3358 3359 if (ir_want_runtime_safety(g, &instruction->base) && !wanted_type->data.enumeration.non_exhaustive) { 3360 LLVMBasicBlockRef bad_value_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadValue"); 3361 LLVMBasicBlockRef ok_value_block = LLVMAppendBasicBlock(g->cur_fn_val, "OkValue"); 3362 size_t field_count = wanted_type->data.enumeration.src_field_count; 3363 LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, tag_int_value, bad_value_block, field_count); 3364 for (size_t field_i = 0; field_i < field_count; field_i += 1) { 3365 LLVMValueRef this_tag_int_value = bigint_to_llvm_const(get_llvm_type(g, tag_int_type), 3366 &wanted_type->data.enumeration.fields[field_i].value); 3367 LLVMAddCase(switch_instr, this_tag_int_value, ok_value_block); 3368 } 3369 LLVMPositionBuilderAtEnd(g->builder, bad_value_block); 3370 gen_safety_crash(g, PanicMsgIdBadEnumValue); 3371 3372 LLVMPositionBuilderAtEnd(g->builder, ok_value_block); 3373 } 3374 return tag_int_value; 3375 } 3376 3377 static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, IrInstructionIntToErr *instruction) { 3378 ZigType *wanted_type = instruction->base.value->type; 3379 assert(wanted_type->id == ZigTypeIdErrorSet); 3380 3381 ZigType *actual_type = instruction->target->value->type; 3382 assert(actual_type->id == ZigTypeIdInt); 3383 assert(!actual_type->data.integral.is_signed); 3384 3385 LLVMValueRef target_val = ir_llvm_value(g, instruction->target); 3386 3387 if (ir_want_runtime_safety(g, &instruction->base)) { 3388 add_error_range_check(g, wanted_type, actual_type, target_val); 3389 } 3390 3391 return gen_widen_or_shorten(g, false, actual_type, g->err_tag_type, target_val); 3392 } 3393 3394 static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, IrInstructionErrToInt *instruction) { 3395 ZigType *wanted_type = instruction->base.value->type; 3396 assert(wanted_type->id == ZigTypeIdInt); 3397 assert(!wanted_type->data.integral.is_signed); 3398 3399 ZigType *actual_type = instruction->target->value->type; 3400 LLVMValueRef target_val = ir_llvm_value(g, instruction->target); 3401 3402 if (actual_type->id == ZigTypeIdErrorSet) { 3403 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base), 3404 g->err_tag_type, wanted_type, target_val); 3405 } else if (actual_type->id == ZigTypeIdErrorUnion) { 3406 // this should have been a compile time constant 3407 assert(type_has_bits(actual_type->data.error_union.err_set_type)); 3408 3409 if (!type_has_bits(actual_type->data.error_union.payload_type)) { 3410 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base), 3411 g->err_tag_type, wanted_type, target_val); 3412 } else { 3413 zig_panic("TODO err to int when error union payload type not void"); 3414 } 3415 } else { 3416 zig_unreachable(); 3417 } 3418 } 3419 3420 static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable, 3421 IrInstructionUnreachable *unreachable_instruction) 3422 { 3423 if (ir_want_runtime_safety(g, &unreachable_instruction->base)) { 3424 gen_safety_crash(g, PanicMsgIdUnreachable); 3425 } else { 3426 LLVMBuildUnreachable(g->builder); 3427 } 3428 return nullptr; 3429 } 3430 3431 static LLVMValueRef ir_render_cond_br(CodeGen *g, IrExecutable *executable, 3432 IrInstructionCondBr *cond_br_instruction) 3433 { 3434 LLVMBuildCondBr(g->builder, 3435 ir_llvm_value(g, cond_br_instruction->condition), 3436 cond_br_instruction->then_block->llvm_block, 3437 cond_br_instruction->else_block->llvm_block); 3438 return nullptr; 3439 } 3440 3441 static LLVMValueRef ir_render_br(CodeGen *g, IrExecutable *executable, IrInstructionBr *br_instruction) { 3442 LLVMBuildBr(g->builder, br_instruction->dest_block->llvm_block); 3443 return nullptr; 3444 } 3445 3446 static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInstructionUnOp *un_op_instruction) { 3447 IrUnOp op_id = un_op_instruction->op_id; 3448 LLVMValueRef expr = ir_llvm_value(g, un_op_instruction->value); 3449 ZigType *operand_type = un_op_instruction->value->value->type; 3450 ZigType *scalar_type = (operand_type->id == ZigTypeIdVector) ? operand_type->data.vector.elem_type : operand_type; 3451 3452 switch (op_id) { 3453 case IrUnOpInvalid: 3454 case IrUnOpOptional: 3455 case IrUnOpDereference: 3456 zig_unreachable(); 3457 case IrUnOpNegation: 3458 case IrUnOpNegationWrap: 3459 { 3460 if (scalar_type->id == ZigTypeIdFloat) { 3461 ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &un_op_instruction->base)); 3462 return LLVMBuildFNeg(g->builder, expr, ""); 3463 } else if (scalar_type->id == ZigTypeIdInt) { 3464 if (op_id == IrUnOpNegationWrap) { 3465 return LLVMBuildNeg(g->builder, expr, ""); 3466 } else if (ir_want_runtime_safety(g, &un_op_instruction->base)) { 3467 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr)); 3468 return gen_overflow_op(g, operand_type, AddSubMulSub, zero, expr); 3469 } else if (scalar_type->data.integral.is_signed) { 3470 return LLVMBuildNSWNeg(g->builder, expr, ""); 3471 } else { 3472 return LLVMBuildNUWNeg(g->builder, expr, ""); 3473 } 3474 } else { 3475 zig_unreachable(); 3476 } 3477 } 3478 case IrUnOpBinNot: 3479 return LLVMBuildNot(g->builder, expr, ""); 3480 } 3481 3482 zig_unreachable(); 3483 } 3484 3485 static LLVMValueRef ir_render_bool_not(CodeGen *g, IrExecutable *executable, IrInstructionBoolNot *instruction) { 3486 LLVMValueRef value = ir_llvm_value(g, instruction->value); 3487 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(value)); 3488 return LLVMBuildICmp(g->builder, LLVMIntEQ, value, zero, ""); 3489 } 3490 3491 static void render_decl_var(CodeGen *g, ZigVar *var) { 3492 if (!type_has_bits(var->var_type)) 3493 return; 3494 3495 var->value_ref = ir_llvm_value(g, var->ptr_instruction); 3496 gen_var_debug_decl(g, var); 3497 } 3498 3499 static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable, IrInstructionDeclVarGen *instruction) { 3500 instruction->var->ptr_instruction = instruction->var_ptr; 3501 render_decl_var(g, instruction->var); 3502 return nullptr; 3503 } 3504 3505 static LLVMValueRef ir_render_load_ptr(CodeGen *g, IrExecutable *executable, 3506 IrInstructionLoadPtrGen *instruction) 3507 { 3508 ZigType *child_type = instruction->base.value->type; 3509 if (!type_has_bits(child_type)) 3510 return nullptr; 3511 3512 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); 3513 ZigType *ptr_type = instruction->ptr->value->type; 3514 assert(ptr_type->id == ZigTypeIdPointer); 3515 3516 ir_assert(ptr_type->data.pointer.vector_index != VECTOR_INDEX_RUNTIME, &instruction->base); 3517 if (ptr_type->data.pointer.vector_index != VECTOR_INDEX_NONE) { 3518 LLVMValueRef index_val = LLVMConstInt(LLVMInt32Type(), 3519 ptr_type->data.pointer.vector_index, false); 3520 LLVMValueRef loaded_vector = LLVMBuildLoad(g->builder, ptr, ""); 3521 return LLVMBuildExtractElement(g->builder, loaded_vector, index_val, ""); 3522 } 3523 3524 uint32_t host_int_bytes = ptr_type->data.pointer.host_int_bytes; 3525 if (host_int_bytes == 0) 3526 return get_handle_value(g, ptr, child_type, ptr_type); 3527 3528 bool big_endian = g->is_big_endian; 3529 3530 LLVMTypeRef int_ptr_ty = LLVMPointerType(LLVMIntType(host_int_bytes * 8), 0); 3531 LLVMValueRef int_ptr = LLVMBuildBitCast(g->builder, ptr, int_ptr_ty, ""); 3532 LLVMValueRef containing_int = gen_load(g, int_ptr, ptr_type, ""); 3533 3534 uint32_t host_bit_count = LLVMGetIntTypeWidth(LLVMTypeOf(containing_int)); 3535 assert(host_bit_count == host_int_bytes * 8); 3536 uint32_t size_in_bits = type_size_bits(g, child_type); 3537 3538 uint32_t bit_offset = ptr_type->data.pointer.bit_offset_in_host; 3539 uint32_t shift_amt = big_endian ? host_bit_count - bit_offset - size_in_bits : bit_offset; 3540 3541 LLVMValueRef shift_amt_val = LLVMConstInt(LLVMTypeOf(containing_int), shift_amt, false); 3542 LLVMValueRef shifted_value = LLVMBuildLShr(g->builder, containing_int, shift_amt_val, ""); 3543 3544 if (handle_is_ptr(child_type)) { 3545 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); 3546 LLVMTypeRef same_size_int = LLVMIntType(size_in_bits); 3547 LLVMValueRef truncated_int = LLVMBuildTrunc(g->builder, shifted_value, same_size_int, ""); 3548 LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, result_loc, 3549 LLVMPointerType(same_size_int, 0), ""); 3550 LLVMBuildStore(g->builder, truncated_int, bitcasted_ptr); 3551 return result_loc; 3552 } 3553 3554 if (child_type->id == ZigTypeIdFloat) { 3555 LLVMTypeRef same_size_int = LLVMIntType(size_in_bits); 3556 LLVMValueRef truncated_int = LLVMBuildTrunc(g->builder, shifted_value, same_size_int, ""); 3557 return LLVMBuildBitCast(g->builder, truncated_int, get_llvm_type(g, child_type), ""); 3558 } 3559 3560 return LLVMBuildTrunc(g->builder, shifted_value, get_llvm_type(g, child_type), ""); 3561 } 3562 3563 static bool value_is_all_undef_array(CodeGen *g, ZigValue *const_val, size_t len) { 3564 switch (const_val->data.x_array.special) { 3565 case ConstArraySpecialUndef: 3566 return true; 3567 case ConstArraySpecialBuf: 3568 return false; 3569 case ConstArraySpecialNone: 3570 for (size_t i = 0; i < len; i += 1) { 3571 if (!value_is_all_undef(g, &const_val->data.x_array.data.s_none.elements[i])) 3572 return false; 3573 } 3574 return true; 3575 } 3576 zig_unreachable(); 3577 } 3578 3579 static bool value_is_all_undef(CodeGen *g, ZigValue *const_val) { 3580 Error err; 3581 if (const_val->special == ConstValSpecialLazy && 3582 (err = ir_resolve_lazy(g, nullptr, const_val))) 3583 codegen_report_errors_and_exit(g); 3584 3585 switch (const_val->special) { 3586 case ConstValSpecialLazy: 3587 zig_unreachable(); 3588 case ConstValSpecialRuntime: 3589 return false; 3590 case ConstValSpecialUndef: 3591 return true; 3592 case ConstValSpecialStatic: 3593 if (const_val->type->id == ZigTypeIdStruct) { 3594 for (size_t i = 0; i < const_val->type->data.structure.src_field_count; i += 1) { 3595 if (!value_is_all_undef(g, const_val->data.x_struct.fields[i])) 3596 return false; 3597 } 3598 return true; 3599 } else if (const_val->type->id == ZigTypeIdArray) { 3600 return value_is_all_undef_array(g, const_val, const_val->type->data.array.len); 3601 } else if (const_val->type->id == ZigTypeIdVector) { 3602 return value_is_all_undef_array(g, const_val, const_val->type->data.vector.len); 3603 } else { 3604 return false; 3605 } 3606 } 3607 zig_unreachable(); 3608 } 3609 3610 static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default_value, LLVMValueRef request, 3611 LLVMValueRef a1, LLVMValueRef a2, LLVMValueRef a3, LLVMValueRef a4, LLVMValueRef a5) 3612 { 3613 if (!target_has_valgrind_support(g->zig_target)) { 3614 return default_value; 3615 } 3616 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 3617 bool asm_has_side_effects = true; 3618 bool asm_is_alignstack = false; 3619 if (g->zig_target->arch == ZigLLVM_x86_64) { 3620 if (g->zig_target->os == OsLinux || target_os_is_darwin(g->zig_target->os) || g->zig_target->os == OsSolaris || 3621 (g->zig_target->os == OsWindows && g->zig_target->abi != ZigLLVM_MSVC)) 3622 { 3623 if (g->cur_fn->valgrind_client_request_array == nullptr) { 3624 LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder); 3625 LLVMBasicBlockRef entry_block = LLVMGetEntryBasicBlock(g->cur_fn->llvm_value); 3626 LLVMValueRef first_inst = LLVMGetFirstInstruction(entry_block); 3627 LLVMPositionBuilderBefore(g->builder, first_inst); 3628 LLVMTypeRef array_type_ref = LLVMArrayType(usize_type_ref, 6); 3629 g->cur_fn->valgrind_client_request_array = LLVMBuildAlloca(g->builder, array_type_ref, ""); 3630 LLVMPositionBuilderAtEnd(g->builder, prev_block); 3631 } 3632 LLVMValueRef array_ptr = g->cur_fn->valgrind_client_request_array; 3633 LLVMValueRef array_elements[] = {request, a1, a2, a3, a4, a5}; 3634 LLVMValueRef zero = LLVMConstInt(usize_type_ref, 0, false); 3635 for (unsigned i = 0; i < 6; i += 1) { 3636 LLVMValueRef indexes[] = { 3637 zero, 3638 LLVMConstInt(usize_type_ref, i, false), 3639 }; 3640 LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indexes, 2, ""); 3641 LLVMBuildStore(g->builder, array_elements[i], elem_ptr); 3642 } 3643 3644 Buf *asm_template = buf_create_from_str( 3645 "rolq $$3, %rdi ; rolq $$13, %rdi\n" 3646 "rolq $$61, %rdi ; rolq $$51, %rdi\n" 3647 "xchgq %rbx,%rbx\n" 3648 ); 3649 Buf *asm_constraints = buf_create_from_str( 3650 "={rdx},{rax},0,~{cc},~{memory}" 3651 ); 3652 unsigned input_and_output_count = 2; 3653 LLVMValueRef array_ptr_as_usize = LLVMBuildPtrToInt(g->builder, array_ptr, usize_type_ref, ""); 3654 LLVMValueRef param_values[] = { array_ptr_as_usize, default_value }; 3655 LLVMTypeRef param_types[] = {usize_type_ref, usize_type_ref}; 3656 LLVMTypeRef function_type = LLVMFunctionType(usize_type_ref, param_types, 3657 input_and_output_count, false); 3658 LLVMValueRef asm_fn = LLVMGetInlineAsm(function_type, buf_ptr(asm_template), buf_len(asm_template), 3659 buf_ptr(asm_constraints), buf_len(asm_constraints), asm_has_side_effects, asm_is_alignstack, 3660 LLVMInlineAsmDialectATT); 3661 return LLVMBuildCall(g->builder, asm_fn, param_values, input_and_output_count, ""); 3662 } 3663 } 3664 zig_unreachable(); 3665 } 3666 3667 static bool want_valgrind_support(CodeGen *g) { 3668 if (!target_has_valgrind_support(g->zig_target)) 3669 return false; 3670 switch (g->valgrind_support) { 3671 case ValgrindSupportDisabled: 3672 return false; 3673 case ValgrindSupportEnabled: 3674 return true; 3675 case ValgrindSupportAuto: 3676 return g->build_mode == BuildModeDebug; 3677 } 3678 zig_unreachable(); 3679 } 3680 3681 static void gen_valgrind_undef(CodeGen *g, LLVMValueRef dest_ptr, LLVMValueRef byte_count) { 3682 static const uint32_t VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545; 3683 ZigType *usize = g->builtin_types.entry_usize; 3684 LLVMValueRef zero = LLVMConstInt(usize->llvm_type, 0, false); 3685 LLVMValueRef req = LLVMConstInt(usize->llvm_type, VG_USERREQ__MAKE_MEM_UNDEFINED, false); 3686 LLVMValueRef ptr_as_usize = LLVMBuildPtrToInt(g->builder, dest_ptr, usize->llvm_type, ""); 3687 gen_valgrind_client_request(g, zero, req, ptr_as_usize, byte_count, zero, zero, zero); 3688 } 3689 3690 static void gen_undef_init(CodeGen *g, uint32_t ptr_align_bytes, ZigType *value_type, LLVMValueRef ptr) { 3691 assert(type_has_bits(value_type)); 3692 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, get_llvm_type(g, value_type)); 3693 assert(size_bytes > 0); 3694 assert(ptr_align_bytes > 0); 3695 // memset uninitialized memory to 0xaa 3696 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); 3697 LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false); 3698 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, ptr, ptr_u8, ""); 3699 ZigType *usize = g->builtin_types.entry_usize; 3700 LLVMValueRef byte_count = LLVMConstInt(usize->llvm_type, size_bytes, false); 3701 ZigLLVMBuildMemSet(g->builder, dest_ptr, fill_char, byte_count, ptr_align_bytes, false); 3702 // then tell valgrind that the memory is undefined even though we just memset it 3703 if (want_valgrind_support(g)) { 3704 gen_valgrind_undef(g, dest_ptr, byte_count); 3705 } 3706 } 3707 3708 static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, IrInstructionStorePtr *instruction) { 3709 Error err; 3710 3711 ZigType *ptr_type = instruction->ptr->value->type; 3712 assert(ptr_type->id == ZigTypeIdPointer); 3713 bool ptr_type_has_bits; 3714 if ((err = type_has_bits2(g, ptr_type, &ptr_type_has_bits))) 3715 codegen_report_errors_and_exit(g); 3716 if (!ptr_type_has_bits) 3717 return nullptr; 3718 if (instruction->ptr->ref_count == 0) { 3719 // In this case, this StorePtr instruction should be elided. Something happened like this: 3720 // var t = true; 3721 // const x = if (t) Num.Two else unreachable; 3722 // The if condition is a runtime value, so the StorePtr for `x = Num.Two` got generated 3723 // (this instruction being rendered) but because of `else unreachable` the result ended 3724 // up being a comptime const value. 3725 return nullptr; 3726 } 3727 3728 bool have_init_expr = !value_is_all_undef(g, instruction->value->value); 3729 if (have_init_expr) { 3730 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); 3731 LLVMValueRef value = ir_llvm_value(g, instruction->value); 3732 gen_assign_raw(g, ptr, ptr_type, value); 3733 } else if (ir_want_runtime_safety(g, &instruction->base)) { 3734 gen_undef_init(g, get_ptr_align(g, ptr_type), instruction->value->value->type, 3735 ir_llvm_value(g, instruction->ptr)); 3736 } 3737 return nullptr; 3738 } 3739 3740 static LLVMValueRef ir_render_vector_store_elem(CodeGen *g, IrExecutable *executable, 3741 IrInstructionVectorStoreElem *instruction) 3742 { 3743 LLVMValueRef vector_ptr = ir_llvm_value(g, instruction->vector_ptr); 3744 LLVMValueRef index = ir_llvm_value(g, instruction->index); 3745 LLVMValueRef value = ir_llvm_value(g, instruction->value); 3746 3747 LLVMValueRef loaded_vector = gen_load(g, vector_ptr, instruction->vector_ptr->value->type, ""); 3748 LLVMValueRef modified_vector = LLVMBuildInsertElement(g->builder, loaded_vector, value, index, ""); 3749 gen_store(g, modified_vector, vector_ptr, instruction->vector_ptr->value->type); 3750 return nullptr; 3751 } 3752 3753 static LLVMValueRef ir_render_var_ptr(CodeGen *g, IrExecutable *executable, IrInstructionVarPtr *instruction) { 3754 if (instruction->base.value->special != ConstValSpecialRuntime) 3755 return ir_llvm_value(g, &instruction->base); 3756 ZigVar *var = instruction->var; 3757 if (type_has_bits(var->var_type)) { 3758 assert(var->value_ref); 3759 return var->value_ref; 3760 } else { 3761 return nullptr; 3762 } 3763 } 3764 3765 static LLVMValueRef ir_render_return_ptr(CodeGen *g, IrExecutable *executable, 3766 IrInstructionReturnPtr *instruction) 3767 { 3768 if (!type_has_bits(instruction->base.value->type)) 3769 return nullptr; 3770 ir_assert(g->cur_ret_ptr != nullptr, &instruction->base); 3771 return g->cur_ret_ptr; 3772 } 3773 3774 static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrInstructionElemPtr *instruction) { 3775 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->array_ptr); 3776 ZigType *array_ptr_type = instruction->array_ptr->value->type; 3777 assert(array_ptr_type->id == ZigTypeIdPointer); 3778 ZigType *array_type = array_ptr_type->data.pointer.child_type; 3779 LLVMValueRef subscript_value = ir_llvm_value(g, instruction->elem_index); 3780 assert(subscript_value); 3781 3782 if (!type_has_bits(array_type)) 3783 return nullptr; 3784 3785 bool safety_check_on = ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on; 3786 3787 if (array_type->id == ZigTypeIdArray || 3788 (array_type->id == ZigTypeIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle)) 3789 { 3790 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type); 3791 if (array_type->id == ZigTypeIdPointer) { 3792 assert(array_type->data.pointer.child_type->id == ZigTypeIdArray); 3793 array_type = array_type->data.pointer.child_type; 3794 } 3795 if (safety_check_on) { 3796 uint64_t extra_len_from_sentinel = (array_type->data.array.sentinel != nullptr) ? 1 : 0; 3797 uint64_t full_len = array_type->data.array.len + extra_len_from_sentinel; 3798 LLVMValueRef end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, full_len, false); 3799 add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, end); 3800 } 3801 if (array_ptr_type->data.pointer.host_int_bytes != 0) { 3802 return array_ptr_ptr; 3803 } 3804 ZigType *child_type = array_type->data.array.child_type; 3805 if (child_type->id == ZigTypeIdStruct && 3806 child_type->data.structure.layout == ContainerLayoutPacked) 3807 { 3808 ZigType *ptr_type = instruction->base.value->type; 3809 size_t host_int_bytes = ptr_type->data.pointer.host_int_bytes; 3810 if (host_int_bytes != 0) { 3811 uint32_t size_in_bits = type_size_bits(g, ptr_type->data.pointer.child_type); 3812 LLVMTypeRef ptr_u8_type_ref = LLVMPointerType(LLVMInt8Type(), 0); 3813 LLVMValueRef u8_array_ptr = LLVMBuildBitCast(g->builder, array_ptr, ptr_u8_type_ref, ""); 3814 assert(size_in_bits % 8 == 0); 3815 LLVMValueRef elem_size_bytes = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 3816 size_in_bits / 8, false); 3817 LLVMValueRef byte_offset = LLVMBuildNUWMul(g->builder, subscript_value, elem_size_bytes, ""); 3818 LLVMValueRef indices[] = { 3819 byte_offset 3820 }; 3821 LLVMValueRef elem_byte_ptr = LLVMBuildInBoundsGEP(g->builder, u8_array_ptr, indices, 1, ""); 3822 return LLVMBuildBitCast(g->builder, elem_byte_ptr, LLVMPointerType(get_llvm_type(g, child_type), 0), ""); 3823 } 3824 } 3825 LLVMValueRef indices[] = { 3826 LLVMConstNull(g->builtin_types.entry_usize->llvm_type), 3827 subscript_value 3828 }; 3829 return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, ""); 3830 } else if (array_type->id == ZigTypeIdPointer) { 3831 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type); 3832 assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind); 3833 LLVMValueRef indices[] = { 3834 subscript_value 3835 }; 3836 return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 1, ""); 3837 } else if (array_type->id == ZigTypeIdStruct) { 3838 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type); 3839 assert(array_type->data.structure.special == StructSpecialSlice); 3840 3841 ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; 3842 if (!type_has_bits(ptr_type)) { 3843 if (safety_check_on) { 3844 assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMIntegerTypeKind); 3845 add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, LLVMIntULT, array_ptr); 3846 } 3847 return nullptr; 3848 } 3849 3850 assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind); 3851 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind); 3852 3853 if (safety_check_on) { 3854 size_t len_index = array_type->data.structure.fields[slice_len_index]->gen_index; 3855 assert(len_index != SIZE_MAX); 3856 LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, ""); 3857 LLVMValueRef len = gen_load_untyped(g, len_ptr, 0, false, ""); 3858 LLVMIntPredicate upper_op = (ptr_type->data.pointer.sentinel != nullptr) ? LLVMIntULE : LLVMIntULT; 3859 add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, upper_op, len); 3860 } 3861 3862 size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index; 3863 assert(ptr_index != SIZE_MAX); 3864 LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)ptr_index, ""); 3865 LLVMValueRef ptr = gen_load_untyped(g, ptr_ptr, 0, false, ""); 3866 return LLVMBuildInBoundsGEP(g->builder, ptr, &subscript_value, 1, ""); 3867 } else if (array_type->id == ZigTypeIdVector) { 3868 return array_ptr_ptr; 3869 } else { 3870 zig_unreachable(); 3871 } 3872 } 3873 3874 static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMValueRef new_stack) { 3875 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_ptr_index, ""); 3876 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_len_index, ""); 3877 3878 LLVMValueRef ptr_value = gen_load_untyped(g, ptr_field_ptr, 0, false, ""); 3879 LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, ""); 3880 3881 LLVMValueRef ptr_addr = LLVMBuildPtrToInt(g->builder, ptr_value, LLVMTypeOf(len_value), ""); 3882 LLVMValueRef end_addr = LLVMBuildNUWAdd(g->builder, ptr_addr, len_value, ""); 3883 const unsigned alignment_factor = ZigLLVMDataLayoutGetStackAlignment(g->target_data_ref); 3884 LLVMValueRef align_amt = LLVMConstInt(LLVMTypeOf(end_addr), alignment_factor, false); 3885 LLVMValueRef align_adj = LLVMBuildURem(g->builder, end_addr, align_amt, ""); 3886 return LLVMBuildNUWSub(g->builder, end_addr, align_adj, ""); 3887 } 3888 3889 static void gen_set_stack_pointer(CodeGen *g, LLVMValueRef aligned_end_addr) { 3890 LLVMValueRef write_register_fn_val = get_write_register_fn_val(g); 3891 3892 if (g->sp_md_node == nullptr) { 3893 Buf *sp_reg_name = buf_create_from_str(arch_stack_pointer_register_name(g->zig_target->arch)); 3894 LLVMValueRef str_node = LLVMMDString(buf_ptr(sp_reg_name), buf_len(sp_reg_name) + 1); 3895 g->sp_md_node = LLVMMDNode(&str_node, 1); 3896 } 3897 3898 LLVMValueRef params[] = { 3899 g->sp_md_node, 3900 aligned_end_addr, 3901 }; 3902 3903 LLVMBuildCall(g->builder, write_register_fn_val, params, 2, ""); 3904 } 3905 3906 static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) { 3907 unsigned attr_kind_id = LLVMGetEnumAttributeKindForName("sret", 4); 3908 LLVMAttributeRef sret_attr = LLVMCreateEnumAttribute(LLVMGetGlobalContext(), attr_kind_id, 0); 3909 LLVMAddCallSiteAttribute(call_instr, 1, sret_attr); 3910 } 3911 3912 static void render_async_spills(CodeGen *g) { 3913 ZigType *fn_type = g->cur_fn->type_entry; 3914 ZigType *import = get_scope_import(&g->cur_fn->fndef_scope->base); 3915 uint32_t async_var_index = frame_index_arg(g, fn_type->data.fn.fn_type_id.return_type); 3916 for (size_t var_i = 0; var_i < g->cur_fn->variable_list.length; var_i += 1) { 3917 ZigVar *var = g->cur_fn->variable_list.at(var_i); 3918 3919 if (!type_has_bits(var->var_type)) { 3920 continue; 3921 } 3922 if (ir_get_var_is_comptime(var)) 3923 continue; 3924 switch (type_requires_comptime(g, var->var_type)) { 3925 case ReqCompTimeInvalid: 3926 zig_unreachable(); 3927 case ReqCompTimeYes: 3928 continue; 3929 case ReqCompTimeNo: 3930 break; 3931 } 3932 if (var->src_arg_index == SIZE_MAX) { 3933 continue; 3934 } 3935 3936 var->value_ref = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, async_var_index, var->name); 3937 async_var_index += 1; 3938 if (var->decl_node) { 3939 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope), 3940 var->name, import->data.structure.root_struct->di_file, 3941 (unsigned)(var->decl_node->line + 1), 3942 get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0); 3943 gen_var_debug_decl(g, var); 3944 } 3945 } 3946 3947 ZigType *frame_type = g->cur_fn->frame_type->data.frame.locals_struct; 3948 3949 for (size_t alloca_i = 0; alloca_i < g->cur_fn->alloca_gen_list.length; alloca_i += 1) { 3950 IrInstructionAllocaGen *instruction = g->cur_fn->alloca_gen_list.at(alloca_i); 3951 if (instruction->field_index == SIZE_MAX) 3952 continue; 3953 3954 size_t gen_index = frame_type->data.structure.fields[instruction->field_index]->gen_index; 3955 instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, gen_index, 3956 instruction->name_hint); 3957 } 3958 } 3959 3960 static void render_async_var_decls(CodeGen *g, Scope *scope) { 3961 for (;;) { 3962 switch (scope->id) { 3963 case ScopeIdCImport: 3964 zig_unreachable(); 3965 case ScopeIdFnDef: 3966 return; 3967 case ScopeIdVarDecl: { 3968 ZigVar *var = reinterpret_cast<ScopeVarDecl *>(scope)->var; 3969 if (var->ptr_instruction != nullptr) { 3970 render_decl_var(g, var); 3971 } 3972 // fallthrough 3973 } 3974 case ScopeIdDecls: 3975 case ScopeIdBlock: 3976 case ScopeIdDefer: 3977 case ScopeIdDeferExpr: 3978 case ScopeIdLoop: 3979 case ScopeIdSuspend: 3980 case ScopeIdCompTime: 3981 case ScopeIdRuntime: 3982 case ScopeIdTypeOf: 3983 case ScopeIdExpr: 3984 scope = scope->parent; 3985 continue; 3986 } 3987 } 3988 } 3989 3990 static LLVMValueRef gen_frame_size(CodeGen *g, LLVMValueRef fn_val) { 3991 assert(g->need_frame_size_prefix_data); 3992 LLVMTypeRef usize_llvm_type = g->builtin_types.entry_usize->llvm_type; 3993 LLVMTypeRef ptr_usize_llvm_type = LLVMPointerType(usize_llvm_type, 0); 3994 LLVMValueRef casted_fn_val = LLVMBuildBitCast(g->builder, fn_val, ptr_usize_llvm_type, ""); 3995 LLVMValueRef negative_one = LLVMConstInt(LLVMInt32Type(), -1, true); 3996 LLVMValueRef prefix_ptr = LLVMBuildInBoundsGEP(g->builder, casted_fn_val, &negative_one, 1, ""); 3997 return LLVMBuildLoad(g->builder, prefix_ptr, ""); 3998 } 3999 4000 static void gen_init_stack_trace(CodeGen *g, LLVMValueRef trace_field_ptr, LLVMValueRef addrs_field_ptr) { 4001 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 4002 LLVMValueRef zero = LLVMConstNull(usize_type_ref); 4003 4004 LLVMValueRef index_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 0, ""); 4005 LLVMBuildStore(g->builder, zero, index_ptr); 4006 4007 LLVMValueRef addrs_slice_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 1, ""); 4008 LLVMValueRef addrs_ptr_ptr = LLVMBuildStructGEP(g->builder, addrs_slice_ptr, slice_ptr_index, ""); 4009 LLVMValueRef indices[] = { LLVMConstNull(usize_type_ref), LLVMConstNull(usize_type_ref) }; 4010 LLVMValueRef trace_field_addrs_as_ptr = LLVMBuildInBoundsGEP(g->builder, addrs_field_ptr, indices, 2, ""); 4011 LLVMBuildStore(g->builder, trace_field_addrs_as_ptr, addrs_ptr_ptr); 4012 4013 LLVMValueRef addrs_len_ptr = LLVMBuildStructGEP(g->builder, addrs_slice_ptr, slice_len_index, ""); 4014 LLVMBuildStore(g->builder, LLVMConstInt(usize_type_ref, stack_trace_ptr_count, false), addrs_len_ptr); 4015 } 4016 4017 static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCallGen *instruction) { 4018 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 4019 4020 LLVMValueRef fn_val; 4021 ZigType *fn_type; 4022 bool callee_is_async; 4023 if (instruction->fn_entry) { 4024 fn_val = fn_llvm_value(g, instruction->fn_entry); 4025 fn_type = instruction->fn_entry->type_entry; 4026 callee_is_async = fn_is_async(instruction->fn_entry); 4027 } else { 4028 assert(instruction->fn_ref); 4029 fn_val = ir_llvm_value(g, instruction->fn_ref); 4030 fn_type = instruction->fn_ref->value->type; 4031 callee_is_async = fn_type->data.fn.fn_type_id.cc == CallingConventionAsync; 4032 } 4033 4034 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 4035 4036 ZigType *src_return_type = fn_type_id->return_type; 4037 bool ret_has_bits = type_has_bits(src_return_type); 4038 4039 CallingConvention cc = fn_type->data.fn.fn_type_id.cc; 4040 4041 bool first_arg_ret = ret_has_bits && want_first_arg_sret(g, fn_type_id); 4042 bool prefix_arg_err_ret_stack = codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type); 4043 bool is_var_args = fn_type_id->is_var_args; 4044 ZigList<LLVMValueRef> gen_param_values = {}; 4045 ZigList<ZigType *> gen_param_types = {}; 4046 LLVMValueRef result_loc = instruction->result_loc ? ir_llvm_value(g, instruction->result_loc) : nullptr; 4047 LLVMValueRef zero = LLVMConstNull(usize_type_ref); 4048 LLVMValueRef frame_result_loc_uncasted = nullptr; 4049 LLVMValueRef frame_result_loc; 4050 LLVMValueRef awaiter_init_val; 4051 LLVMValueRef ret_ptr; 4052 if (callee_is_async) { 4053 if (instruction->new_stack == nullptr) { 4054 if (instruction->modifier == CallModifierAsync) { 4055 frame_result_loc = result_loc; 4056 } else { 4057 ir_assert(instruction->frame_result_loc != nullptr, &instruction->base); 4058 frame_result_loc_uncasted = ir_llvm_value(g, instruction->frame_result_loc); 4059 ir_assert(instruction->fn_entry != nullptr, &instruction->base); 4060 frame_result_loc = LLVMBuildBitCast(g->builder, frame_result_loc_uncasted, 4061 LLVMPointerType(get_llvm_type(g, instruction->fn_entry->frame_type), 0), ""); 4062 } 4063 } else { 4064 if (instruction->new_stack->value->type->id == ZigTypeIdPointer && 4065 instruction->new_stack->value->type->data.pointer.child_type->id == ZigTypeIdFnFrame) 4066 { 4067 frame_result_loc = ir_llvm_value(g, instruction->new_stack); 4068 } else { 4069 LLVMValueRef frame_slice_ptr = ir_llvm_value(g, instruction->new_stack); 4070 if (ir_want_runtime_safety(g, &instruction->base)) { 4071 LLVMValueRef given_len_ptr = LLVMBuildStructGEP(g->builder, frame_slice_ptr, slice_len_index, ""); 4072 LLVMValueRef given_frame_len = LLVMBuildLoad(g->builder, given_len_ptr, ""); 4073 LLVMValueRef actual_frame_len = gen_frame_size(g, fn_val); 4074 4075 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "FrameSizeCheckFail"); 4076 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "FrameSizeCheckOk"); 4077 4078 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntUGE, given_frame_len, actual_frame_len, ""); 4079 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); 4080 4081 LLVMPositionBuilderAtEnd(g->builder, fail_block); 4082 gen_safety_crash(g, PanicMsgIdFrameTooSmall); 4083 4084 LLVMPositionBuilderAtEnd(g->builder, ok_block); 4085 } 4086 LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_slice_ptr, slice_ptr_index, ""); 4087 LLVMValueRef frame_ptr = LLVMBuildLoad(g->builder, frame_ptr_ptr, ""); 4088 if (instruction->fn_entry == nullptr) { 4089 ZigType *anyframe_type = get_any_frame_type(g, src_return_type); 4090 frame_result_loc = LLVMBuildBitCast(g->builder, frame_ptr, get_llvm_type(g, anyframe_type), ""); 4091 } else { 4092 ZigType *ptr_frame_type = get_pointer_to_type(g, 4093 get_fn_frame_type(g, instruction->fn_entry), false); 4094 frame_result_loc = LLVMBuildBitCast(g->builder, frame_ptr, 4095 get_llvm_type(g, ptr_frame_type), ""); 4096 } 4097 } 4098 } 4099 if (instruction->modifier == CallModifierAsync) { 4100 if (instruction->new_stack == nullptr) { 4101 awaiter_init_val = zero; 4102 4103 if (ret_has_bits) { 4104 // Use the result location which is inside the frame if this is an async call. 4105 ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, ""); 4106 } 4107 } else { 4108 awaiter_init_val = zero; 4109 4110 if (ret_has_bits) { 4111 if (result_loc != nullptr) { 4112 // Use the result location provided to the @asyncCall builtin 4113 ret_ptr = result_loc; 4114 } else { 4115 // no result location provided to @asyncCall - use the one inside the frame. 4116 ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, ""); 4117 } 4118 } 4119 } 4120 4121 // even if prefix_arg_err_ret_stack is true, let the async function do its own 4122 // initialization. 4123 } else { 4124 if (instruction->modifier == CallModifierNoAsync && !fn_is_async(g->cur_fn)) { 4125 // Async function called as a normal function, and calling function is not async. 4126 // This is allowed because it was called with `noasync` which asserts that it will 4127 // never suspend. 4128 awaiter_init_val = zero; 4129 } else { 4130 // async function called as a normal function 4131 awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, ""); // caller's own frame pointer 4132 } 4133 if (ret_has_bits) { 4134 if (result_loc == nullptr) { 4135 // return type is a scalar, but we still need a pointer to it. Use the async fn frame. 4136 ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, ""); 4137 } else { 4138 // Use the call instruction's result location. 4139 ret_ptr = result_loc; 4140 } 4141 4142 // Store a zero in the awaiter's result ptr to indicate we do not need a copy made. 4143 LLVMValueRef awaiter_ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 1, ""); 4144 LLVMValueRef zero_ptr = LLVMConstNull(LLVMGetElementType(LLVMTypeOf(awaiter_ret_ptr))); 4145 LLVMBuildStore(g->builder, zero_ptr, awaiter_ret_ptr); 4146 } 4147 4148 if (prefix_arg_err_ret_stack) { 4149 LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, 4150 frame_index_trace_arg(g, src_return_type) + 1, ""); 4151 bool is_llvm_alloca; 4152 LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, 4153 &is_llvm_alloca); 4154 LLVMBuildStore(g->builder, my_err_ret_trace_val, err_ret_trace_ptr_ptr); 4155 } 4156 } 4157 4158 assert(frame_result_loc != nullptr); 4159 4160 LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_fn_ptr_index, ""); 4161 LLVMValueRef bitcasted_fn_val = LLVMBuildBitCast(g->builder, fn_val, 4162 LLVMGetElementType(LLVMTypeOf(fn_ptr_ptr)), ""); 4163 LLVMBuildStore(g->builder, bitcasted_fn_val, fn_ptr_ptr); 4164 4165 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_resume_index, ""); 4166 LLVMBuildStore(g->builder, zero, resume_index_ptr); 4167 4168 LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_awaiter_index, ""); 4169 LLVMBuildStore(g->builder, awaiter_init_val, awaiter_ptr); 4170 4171 if (ret_has_bits) { 4172 LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start, ""); 4173 LLVMBuildStore(g->builder, ret_ptr, ret_ptr_ptr); 4174 } 4175 } else if (instruction->modifier == CallModifierAsync) { 4176 // Async call of blocking function 4177 if (instruction->new_stack != nullptr) { 4178 zig_panic("TODO @asyncCall of non-async function"); 4179 } 4180 frame_result_loc = result_loc; 4181 awaiter_init_val = LLVMConstAllOnes(usize_type_ref); 4182 4183 LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_awaiter_index, ""); 4184 LLVMBuildStore(g->builder, awaiter_init_val, awaiter_ptr); 4185 4186 if (ret_has_bits) { 4187 ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, ""); 4188 LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start, ""); 4189 LLVMBuildStore(g->builder, ret_ptr, ret_ptr_ptr); 4190 4191 if (first_arg_ret) { 4192 gen_param_values.append(ret_ptr); 4193 } 4194 if (prefix_arg_err_ret_stack) { 4195 // Set up the callee stack trace pointer pointing into the frame. 4196 // Then we have to wire up the StackTrace pointers. 4197 // Await is responsible for merging error return traces. 4198 uint32_t trace_field_index_start = frame_index_trace_arg(g, src_return_type); 4199 LLVMValueRef callee_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, 4200 trace_field_index_start, ""); 4201 LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, 4202 trace_field_index_start + 2, ""); 4203 LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, 4204 trace_field_index_start + 3, ""); 4205 4206 LLVMBuildStore(g->builder, trace_field_ptr, callee_trace_ptr_ptr); 4207 4208 gen_init_stack_trace(g, trace_field_ptr, addrs_field_ptr); 4209 4210 bool is_llvm_alloca; 4211 gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca)); 4212 } 4213 } 4214 } else { 4215 if (first_arg_ret) { 4216 gen_param_values.append(result_loc); 4217 } 4218 if (prefix_arg_err_ret_stack) { 4219 bool is_llvm_alloca; 4220 gen_param_values.append(get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca)); 4221 } 4222 } 4223 FnWalk fn_walk = {}; 4224 fn_walk.id = FnWalkIdCall; 4225 fn_walk.data.call.inst = instruction; 4226 fn_walk.data.call.is_var_args = is_var_args; 4227 fn_walk.data.call.gen_param_values = &gen_param_values; 4228 fn_walk.data.call.gen_param_types = &gen_param_types; 4229 walk_function_params(g, fn_type, &fn_walk); 4230 4231 ZigLLVM_CallAttr call_attr; 4232 switch (instruction->modifier) { 4233 case CallModifierBuiltin: 4234 case CallModifierCompileTime: 4235 zig_unreachable(); 4236 case CallModifierNone: 4237 case CallModifierNoAsync: 4238 case CallModifierAsync: 4239 call_attr = ZigLLVM_CallAttrAuto; 4240 break; 4241 case CallModifierNeverTail: 4242 call_attr = ZigLLVM_CallAttrNeverTail; 4243 break; 4244 case CallModifierNeverInline: 4245 call_attr = ZigLLVM_CallAttrNeverInline; 4246 break; 4247 case CallModifierAlwaysTail: 4248 call_attr = ZigLLVM_CallAttrAlwaysTail; 4249 break; 4250 case CallModifierAlwaysInline: 4251 ir_assert(instruction->fn_entry != nullptr, &instruction->base); 4252 call_attr = ZigLLVM_CallAttrAlwaysInline; 4253 break; 4254 } 4255 4256 ZigLLVM_CallingConv llvm_cc = get_llvm_cc(g, cc); 4257 LLVMValueRef result; 4258 4259 if (callee_is_async) { 4260 uint32_t arg_start_i = frame_index_arg(g, fn_type->data.fn.fn_type_id.return_type); 4261 4262 LLVMValueRef casted_frame; 4263 if (instruction->new_stack != nullptr && instruction->fn_entry == nullptr) { 4264 // We need the frame type to be a pointer to a struct that includes the args 4265 size_t field_count = arg_start_i + gen_param_values.length; 4266 LLVMTypeRef *field_types = allocate_nonzero<LLVMTypeRef>(field_count); 4267 LLVMGetStructElementTypes(LLVMGetElementType(LLVMTypeOf(frame_result_loc)), field_types); 4268 assert(LLVMCountStructElementTypes(LLVMGetElementType(LLVMTypeOf(frame_result_loc))) == arg_start_i); 4269 for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) { 4270 field_types[arg_start_i + arg_i] = LLVMTypeOf(gen_param_values.at(arg_i)); 4271 } 4272 LLVMTypeRef frame_with_args_type = LLVMStructType(field_types, field_count, false); 4273 LLVMTypeRef ptr_frame_with_args_type = LLVMPointerType(frame_with_args_type, 0); 4274 4275 casted_frame = LLVMBuildBitCast(g->builder, frame_result_loc, ptr_frame_with_args_type, ""); 4276 } else { 4277 casted_frame = frame_result_loc; 4278 } 4279 4280 for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) { 4281 LLVMValueRef arg_ptr = LLVMBuildStructGEP(g->builder, casted_frame, arg_start_i + arg_i, ""); 4282 gen_assign_raw(g, arg_ptr, get_pointer_to_type(g, gen_param_types.at(arg_i), true), 4283 gen_param_values.at(arg_i)); 4284 } 4285 4286 if (instruction->modifier == CallModifierAsync) { 4287 gen_resume(g, fn_val, frame_result_loc, ResumeIdCall); 4288 if (instruction->new_stack != nullptr) { 4289 return LLVMBuildBitCast(g->builder, frame_result_loc, 4290 get_llvm_type(g, instruction->base.value->type), ""); 4291 } 4292 return nullptr; 4293 } else if (instruction->modifier == CallModifierNoAsync && !fn_is_async(g->cur_fn)) { 4294 gen_resume(g, fn_val, frame_result_loc, ResumeIdCall); 4295 4296 if (ir_want_runtime_safety(g, &instruction->base)) { 4297 LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, 4298 frame_awaiter_index, ""); 4299 LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref); 4300 LLVMValueRef prev_val = gen_maybe_atomic_op(g, LLVMAtomicRMWBinOpXchg, awaiter_ptr, 4301 all_ones, LLVMAtomicOrderingRelease); 4302 LLVMValueRef ok_val = LLVMBuildICmp(g->builder, LLVMIntEQ, prev_val, all_ones, ""); 4303 4304 LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoAsyncPanic"); 4305 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "NoAsyncOk"); 4306 LLVMBuildCondBr(g->builder, ok_val, ok_block, bad_block); 4307 4308 // The async function suspended, but this noasync call asserted it wouldn't. 4309 LLVMPositionBuilderAtEnd(g->builder, bad_block); 4310 gen_safety_crash(g, PanicMsgIdBadNoAsyncCall); 4311 4312 LLVMPositionBuilderAtEnd(g->builder, ok_block); 4313 } 4314 4315 ZigType *result_type = instruction->base.value->type; 4316 ZigType *ptr_result_type = get_pointer_to_type(g, result_type, true); 4317 return gen_await_early_return(g, &instruction->base, frame_result_loc, 4318 result_type, ptr_result_type, result_loc, true); 4319 } else { 4320 ZigType *ptr_result_type = get_pointer_to_type(g, src_return_type, true); 4321 4322 LLVMBasicBlockRef call_bb = gen_suspend_begin(g, "CallResume"); 4323 4324 LLVMValueRef call_inst = gen_resume(g, fn_val, frame_result_loc, ResumeIdCall); 4325 set_tail_call_if_appropriate(g, call_inst); 4326 LLVMBuildRetVoid(g->builder); 4327 4328 LLVMPositionBuilderAtEnd(g->builder, call_bb); 4329 gen_assert_resume_id(g, &instruction->base, ResumeIdReturn, PanicMsgIdResumedAnAwaitingFn, nullptr); 4330 render_async_var_decls(g, instruction->base.scope); 4331 4332 if (!type_has_bits(src_return_type)) 4333 return nullptr; 4334 4335 if (result_loc != nullptr) { 4336 if (instruction->result_loc->id == IrInstructionIdReturnPtr) { 4337 instruction->base.spill = nullptr; 4338 return g->cur_ret_ptr; 4339 } else { 4340 return get_handle_value(g, result_loc, src_return_type, ptr_result_type); 4341 } 4342 } 4343 4344 if (frame_result_loc_uncasted != nullptr && instruction->fn_entry != nullptr) { 4345 // Instead of a spill, we do the bitcast again. The uncasted LLVM IR instruction will 4346 // be an Alloca from the entry block, so it does not need to be spilled. 4347 frame_result_loc = LLVMBuildBitCast(g->builder, frame_result_loc_uncasted, 4348 LLVMPointerType(get_llvm_type(g, instruction->fn_entry->frame_type), 0), ""); 4349 } 4350 4351 LLVMValueRef result_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, ""); 4352 return LLVMBuildLoad(g->builder, result_ptr, ""); 4353 } 4354 } 4355 4356 if (instruction->new_stack == nullptr || instruction->is_async_call_builtin) { 4357 result = ZigLLVMBuildCall(g->builder, fn_val, 4358 gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, call_attr, ""); 4359 } else if (instruction->modifier == CallModifierAsync) { 4360 zig_panic("TODO @asyncCall of non-async function"); 4361 } else { 4362 LLVMValueRef new_stack_addr = get_new_stack_addr(g, ir_llvm_value(g, instruction->new_stack)); 4363 LLVMValueRef old_stack_ref; 4364 if (src_return_type->id != ZigTypeIdUnreachable) { 4365 LLVMValueRef stacksave_fn_val = get_stacksave_fn_val(g); 4366 old_stack_ref = LLVMBuildCall(g->builder, stacksave_fn_val, nullptr, 0, ""); 4367 } 4368 gen_set_stack_pointer(g, new_stack_addr); 4369 result = ZigLLVMBuildCall(g->builder, fn_val, 4370 gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, call_attr, ""); 4371 if (src_return_type->id != ZigTypeIdUnreachable) { 4372 LLVMValueRef stackrestore_fn_val = get_stackrestore_fn_val(g); 4373 LLVMBuildCall(g->builder, stackrestore_fn_val, &old_stack_ref, 1, ""); 4374 } 4375 } 4376 4377 if (src_return_type->id == ZigTypeIdUnreachable) { 4378 return LLVMBuildUnreachable(g->builder); 4379 } else if (!ret_has_bits) { 4380 return nullptr; 4381 } else if (first_arg_ret) { 4382 set_call_instr_sret(g, result); 4383 return result_loc; 4384 } else if (handle_is_ptr(src_return_type)) { 4385 LLVMValueRef store_instr = LLVMBuildStore(g->builder, result, result_loc); 4386 LLVMSetAlignment(store_instr, get_ptr_align(g, instruction->result_loc->value->type)); 4387 return result_loc; 4388 } else if (!callee_is_async && instruction->modifier == CallModifierAsync) { 4389 LLVMBuildStore(g->builder, result, ret_ptr); 4390 return result_loc; 4391 } else { 4392 return result; 4393 } 4394 } 4395 4396 static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, IrExecutable *executable, 4397 IrInstructionStructFieldPtr *instruction) 4398 { 4399 Error err; 4400 4401 if (instruction->base.value->special != ConstValSpecialRuntime) 4402 return nullptr; 4403 4404 LLVMValueRef struct_ptr = ir_llvm_value(g, instruction->struct_ptr); 4405 // not necessarily a pointer. could be ZigTypeIdStruct 4406 ZigType *struct_ptr_type = instruction->struct_ptr->value->type; 4407 TypeStructField *field = instruction->field; 4408 4409 if (!type_has_bits(field->type_entry)) 4410 return nullptr; 4411 4412 if (struct_ptr_type->id == ZigTypeIdPointer && 4413 struct_ptr_type->data.pointer.host_int_bytes != 0) 4414 { 4415 return struct_ptr; 4416 } 4417 4418 ZigType *struct_type; 4419 if (struct_ptr_type->id == ZigTypeIdPointer) { 4420 if (struct_ptr_type->data.pointer.inferred_struct_field != nullptr) { 4421 struct_type = struct_ptr_type->data.pointer.inferred_struct_field->inferred_struct_type; 4422 } else { 4423 struct_type = struct_ptr_type->data.pointer.child_type; 4424 } 4425 } else { 4426 struct_type = struct_ptr_type; 4427 } 4428 4429 if ((err = type_resolve(g, struct_type, ResolveStatusLLVMFull))) 4430 codegen_report_errors_and_exit(g); 4431 4432 ir_assert(field->gen_index != SIZE_MAX, &instruction->base); 4433 LLVMValueRef field_ptr_val = LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, ""); 4434 ZigType *res_type = instruction->base.value->type; 4435 ir_assert(res_type->id == ZigTypeIdPointer, &instruction->base); 4436 if (res_type->data.pointer.host_int_bytes != 0) { 4437 // We generate packed structs with get_llvm_type_of_n_bytes, which is 4438 // u8 for 1 byte or [n]u8 for multiple bytes. But the pointer to the type 4439 // is supposed to be a pointer to the integer. So we bitcast it here. 4440 LLVMTypeRef int_elem_type = LLVMIntType(8*res_type->data.pointer.host_int_bytes); 4441 LLVMTypeRef integer_ptr_type = LLVMPointerType(int_elem_type, 0); 4442 return LLVMBuildBitCast(g->builder, field_ptr_val, integer_ptr_type, ""); 4443 } 4444 return field_ptr_val; 4445 } 4446 4447 static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executable, 4448 IrInstructionUnionFieldPtr *instruction) 4449 { 4450 if (instruction->base.value->special != ConstValSpecialRuntime) 4451 return nullptr; 4452 4453 ZigType *union_ptr_type = instruction->union_ptr->value->type; 4454 assert(union_ptr_type->id == ZigTypeIdPointer); 4455 ZigType *union_type = union_ptr_type->data.pointer.child_type; 4456 assert(union_type->id == ZigTypeIdUnion); 4457 4458 TypeUnionField *field = instruction->field; 4459 4460 if (!type_has_bits(field->type_entry)) { 4461 ZigType *tag_type = union_type->data.unionation.tag_type; 4462 if (!instruction->initializing || !type_has_bits(tag_type)) 4463 return nullptr; 4464 4465 // The field has no bits but we still have to change the discriminant 4466 // value here 4467 LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr); 4468 4469 LLVMTypeRef tag_type_ref = get_llvm_type(g, tag_type); 4470 LLVMValueRef tag_field_ptr = nullptr; 4471 if (union_type->data.unionation.gen_field_count == 0) { 4472 assert(union_type->data.unionation.gen_tag_index == SIZE_MAX); 4473 // The whole union is collapsed into the discriminant 4474 tag_field_ptr = LLVMBuildBitCast(g->builder, union_ptr, 4475 LLVMPointerType(tag_type_ref, 0), ""); 4476 } else { 4477 assert(union_type->data.unionation.gen_tag_index != SIZE_MAX); 4478 tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, 4479 union_type->data.unionation.gen_tag_index, ""); 4480 } 4481 4482 LLVMValueRef tag_value = bigint_to_llvm_const(tag_type_ref, 4483 &field->enum_field->value); 4484 assert(tag_field_ptr != nullptr); 4485 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false); 4486 4487 return nullptr; 4488 } 4489 4490 LLVMValueRef union_ptr = ir_llvm_value(g, instruction->union_ptr); 4491 LLVMTypeRef field_type_ref = LLVMPointerType(get_llvm_type(g, field->type_entry), 0); 4492 4493 if (union_type->data.unionation.gen_tag_index == SIZE_MAX) { 4494 LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, 0, ""); 4495 LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, ""); 4496 return bitcasted_union_field_ptr; 4497 } 4498 4499 if (instruction->initializing) { 4500 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, ""); 4501 LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type), 4502 &field->enum_field->value); 4503 gen_store_untyped(g, tag_value, tag_field_ptr, 0, false); 4504 } else if (instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base)) { 4505 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, ""); 4506 LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, ""); 4507 4508 4509 LLVMValueRef expected_tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type), 4510 &field->enum_field->value); 4511 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnionCheckOk"); 4512 LLVMBasicBlockRef bad_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnionCheckFail"); 4513 LLVMValueRef ok_val = LLVMBuildICmp(g->builder, LLVMIntEQ, tag_value, expected_tag_value, ""); 4514 LLVMBuildCondBr(g->builder, ok_val, ok_block, bad_block); 4515 4516 LLVMPositionBuilderAtEnd(g->builder, bad_block); 4517 gen_safety_crash(g, PanicMsgIdBadUnionField); 4518 4519 LLVMPositionBuilderAtEnd(g->builder, ok_block); 4520 } 4521 4522 LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, 4523 union_type->data.unionation.gen_union_index, ""); 4524 LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, ""); 4525 return bitcasted_union_field_ptr; 4526 } 4527 4528 static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_template) { 4529 const char *ptr = buf_ptr(src_template) + tok->start + 2; 4530 size_t len = tok->end - tok->start - 2; 4531 size_t result = 0; 4532 for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1, result += 1) { 4533 AsmOutput *asm_output = node->data.asm_expr.output_list.at(i); 4534 if (buf_eql_mem(asm_output->asm_symbolic_name, ptr, len)) { 4535 return result; 4536 } 4537 } 4538 for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1, result += 1) { 4539 AsmInput *asm_input = node->data.asm_expr.input_list.at(i); 4540 if (buf_eql_mem(asm_input->asm_symbolic_name, ptr, len)) { 4541 return result; 4542 } 4543 } 4544 return SIZE_MAX; 4545 } 4546 4547 static LLVMValueRef ir_render_asm_gen(CodeGen *g, IrExecutable *executable, IrInstructionAsmGen *instruction) { 4548 AstNode *asm_node = instruction->base.source_node; 4549 assert(asm_node->type == NodeTypeAsmExpr); 4550 AstNodeAsmExpr *asm_expr = &asm_node->data.asm_expr; 4551 4552 Buf *src_template = instruction->asm_template; 4553 4554 Buf llvm_template = BUF_INIT; 4555 buf_resize(&llvm_template, 0); 4556 4557 for (size_t token_i = 0; token_i < instruction->token_list_len; token_i += 1) { 4558 AsmToken *asm_token = &instruction->token_list[token_i]; 4559 switch (asm_token->id) { 4560 case AsmTokenIdTemplate: 4561 for (size_t offset = asm_token->start; offset < asm_token->end; offset += 1) { 4562 uint8_t c = *((uint8_t*)(buf_ptr(src_template) + offset)); 4563 if (c == '$') { 4564 buf_append_str(&llvm_template, "$$"); 4565 } else { 4566 buf_append_char(&llvm_template, c); 4567 } 4568 } 4569 break; 4570 case AsmTokenIdPercent: 4571 buf_append_char(&llvm_template, '%'); 4572 break; 4573 case AsmTokenIdVar: 4574 { 4575 size_t index = find_asm_index(g, asm_node, asm_token, src_template); 4576 assert(index < SIZE_MAX); 4577 buf_appendf(&llvm_template, "$%" ZIG_PRI_usize "", index); 4578 break; 4579 } 4580 case AsmTokenIdUniqueId: 4581 buf_append_str(&llvm_template, "${:uid}"); 4582 break; 4583 } 4584 } 4585 4586 Buf constraint_buf = BUF_INIT; 4587 buf_resize(&constraint_buf, 0); 4588 4589 assert(instruction->return_count == 0 || instruction->return_count == 1); 4590 4591 size_t total_constraint_count = asm_expr->output_list.length + 4592 asm_expr->input_list.length + 4593 asm_expr->clobber_list.length; 4594 size_t input_and_output_count = asm_expr->output_list.length + 4595 asm_expr->input_list.length - 4596 instruction->return_count; 4597 size_t total_index = 0; 4598 size_t param_index = 0; 4599 LLVMTypeRef *param_types = allocate<LLVMTypeRef>(input_and_output_count); 4600 LLVMValueRef *param_values = allocate<LLVMValueRef>(input_and_output_count); 4601 for (size_t i = 0; i < asm_expr->output_list.length; i += 1, total_index += 1) { 4602 AsmOutput *asm_output = asm_expr->output_list.at(i); 4603 bool is_return = (asm_output->return_type != nullptr); 4604 assert(*buf_ptr(asm_output->constraint) == '='); 4605 // LLVM uses commas internally to separate different constraints, 4606 // alternative constraints are achieved with pipes. 4607 // We still allow the user to use commas in a way that is similar 4608 // to GCC's inline assembly. 4609 // http://llvm.org/docs/LangRef.html#constraint-codes 4610 buf_replace(asm_output->constraint, ',', '|'); 4611 4612 if (is_return) { 4613 buf_appendf(&constraint_buf, "=%s", buf_ptr(asm_output->constraint) + 1); 4614 } else { 4615 buf_appendf(&constraint_buf, "=*%s", buf_ptr(asm_output->constraint) + 1); 4616 } 4617 if (total_index + 1 < total_constraint_count) { 4618 buf_append_char(&constraint_buf, ','); 4619 } 4620 4621 if (!is_return) { 4622 ZigVar *variable = instruction->output_vars[i]; 4623 assert(variable); 4624 param_types[param_index] = LLVMTypeOf(variable->value_ref); 4625 param_values[param_index] = variable->value_ref; 4626 param_index += 1; 4627 } 4628 } 4629 for (size_t i = 0; i < asm_expr->input_list.length; i += 1, total_index += 1, param_index += 1) { 4630 AsmInput *asm_input = asm_expr->input_list.at(i); 4631 buf_replace(asm_input->constraint, ',', '|'); 4632 IrInstruction *ir_input = instruction->input_list[i]; 4633 buf_append_buf(&constraint_buf, asm_input->constraint); 4634 if (total_index + 1 < total_constraint_count) { 4635 buf_append_char(&constraint_buf, ','); 4636 } 4637 4638 ZigType *const type = ir_input->value->type; 4639 LLVMTypeRef type_ref = get_llvm_type(g, type); 4640 LLVMValueRef value_ref = ir_llvm_value(g, ir_input); 4641 // Handle integers of non pot bitsize by widening them. 4642 if (type->id == ZigTypeIdInt) { 4643 const size_t bitsize = type->data.integral.bit_count; 4644 if (bitsize < 8 || !is_power_of_2(bitsize)) { 4645 const bool is_signed = type->data.integral.is_signed; 4646 const size_t wider_bitsize = bitsize < 8 ? 8 : round_to_next_power_of_2(bitsize); 4647 ZigType *const wider_type = get_int_type(g, is_signed, wider_bitsize); 4648 type_ref = get_llvm_type(g, wider_type); 4649 value_ref = gen_widen_or_shorten(g, false, type, wider_type, value_ref); 4650 } 4651 } 4652 4653 param_types[param_index] = type_ref; 4654 param_values[param_index] = value_ref; 4655 } 4656 for (size_t i = 0; i < asm_expr->clobber_list.length; i += 1, total_index += 1) { 4657 Buf *clobber_buf = asm_expr->clobber_list.at(i); 4658 buf_appendf(&constraint_buf, "~{%s}", buf_ptr(clobber_buf)); 4659 if (total_index + 1 < total_constraint_count) { 4660 buf_append_char(&constraint_buf, ','); 4661 } 4662 } 4663 4664 LLVMTypeRef ret_type; 4665 if (instruction->return_count == 0) { 4666 ret_type = LLVMVoidType(); 4667 } else { 4668 ret_type = get_llvm_type(g, instruction->base.value->type); 4669 } 4670 LLVMTypeRef function_type = LLVMFunctionType(ret_type, param_types, (unsigned)input_and_output_count, false); 4671 4672 bool is_volatile = instruction->has_side_effects || (asm_expr->output_list.length == 0); 4673 LLVMValueRef asm_fn = LLVMGetInlineAsm(function_type, buf_ptr(&llvm_template), buf_len(&llvm_template), 4674 buf_ptr(&constraint_buf), buf_len(&constraint_buf), is_volatile, false, LLVMInlineAsmDialectATT); 4675 4676 return LLVMBuildCall(g->builder, asm_fn, param_values, (unsigned)input_and_output_count, ""); 4677 } 4678 4679 static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueRef maybe_handle) { 4680 assert(maybe_type->id == ZigTypeIdOptional || 4681 (maybe_type->id == ZigTypeIdPointer && maybe_type->data.pointer.allow_zero)); 4682 4683 ZigType *child_type = maybe_type->data.maybe.child_type; 4684 if (!type_has_bits(child_type)) 4685 return maybe_handle; 4686 4687 bool is_scalar = !handle_is_ptr(maybe_type); 4688 if (is_scalar) 4689 return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(get_llvm_type(g, maybe_type)), ""); 4690 4691 LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_handle, maybe_null_index, ""); 4692 return gen_load_untyped(g, maybe_field_ptr, 0, false, ""); 4693 } 4694 4695 static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutable *executable, 4696 IrInstructionTestNonNull *instruction) 4697 { 4698 return gen_non_null_bit(g, instruction->value->value->type, ir_llvm_value(g, instruction->value)); 4699 } 4700 4701 static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *executable, 4702 IrInstructionOptionalUnwrapPtr *instruction) 4703 { 4704 if (instruction->base.value->special != ConstValSpecialRuntime) 4705 return nullptr; 4706 4707 ZigType *ptr_type = instruction->base_ptr->value->type; 4708 assert(ptr_type->id == ZigTypeIdPointer); 4709 ZigType *maybe_type = ptr_type->data.pointer.child_type; 4710 assert(maybe_type->id == ZigTypeIdOptional); 4711 ZigType *child_type = maybe_type->data.maybe.child_type; 4712 LLVMValueRef base_ptr = ir_llvm_value(g, instruction->base_ptr); 4713 if (instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base)) { 4714 LLVMValueRef maybe_handle = get_handle_value(g, base_ptr, maybe_type, ptr_type); 4715 LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle); 4716 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalFail"); 4717 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalOk"); 4718 LLVMBuildCondBr(g->builder, non_null_bit, ok_block, fail_block); 4719 4720 LLVMPositionBuilderAtEnd(g->builder, fail_block); 4721 gen_safety_crash(g, PanicMsgIdUnwrapOptionalFail); 4722 4723 LLVMPositionBuilderAtEnd(g->builder, ok_block); 4724 } 4725 if (!type_has_bits(child_type)) { 4726 return nullptr; 4727 } else { 4728 bool is_scalar = !handle_is_ptr(maybe_type); 4729 if (is_scalar) { 4730 return base_ptr; 4731 } else { 4732 LLVMValueRef optional_struct_ref = get_handle_value(g, base_ptr, maybe_type, ptr_type); 4733 if (instruction->initializing) { 4734 LLVMValueRef non_null_bit_ptr = LLVMBuildStructGEP(g->builder, optional_struct_ref, 4735 maybe_null_index, ""); 4736 LLVMValueRef non_null_bit = LLVMConstInt(LLVMInt1Type(), 1, false); 4737 gen_store_untyped(g, non_null_bit, non_null_bit_ptr, 0, false); 4738 } 4739 return LLVMBuildStructGEP(g->builder, optional_struct_ref, maybe_child_index, ""); 4740 } 4741 } 4742 } 4743 4744 static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *expr_type, BuiltinFnId fn_id) { 4745 bool is_vector = expr_type->id == ZigTypeIdVector; 4746 ZigType *int_type = is_vector ? expr_type->data.vector.elem_type : expr_type; 4747 assert(int_type->id == ZigTypeIdInt); 4748 uint32_t vector_len = is_vector ? expr_type->data.vector.len : 0; 4749 ZigLLVMFnKey key = {}; 4750 const char *fn_name; 4751 uint32_t n_args; 4752 if (fn_id == BuiltinFnIdCtz) { 4753 fn_name = "cttz"; 4754 n_args = 2; 4755 key.id = ZigLLVMFnIdCtz; 4756 key.data.ctz.bit_count = (uint32_t)int_type->data.integral.bit_count; 4757 } else if (fn_id == BuiltinFnIdClz) { 4758 fn_name = "ctlz"; 4759 n_args = 2; 4760 key.id = ZigLLVMFnIdClz; 4761 key.data.clz.bit_count = (uint32_t)int_type->data.integral.bit_count; 4762 } else if (fn_id == BuiltinFnIdPopCount) { 4763 fn_name = "ctpop"; 4764 n_args = 1; 4765 key.id = ZigLLVMFnIdPopCount; 4766 key.data.pop_count.bit_count = (uint32_t)int_type->data.integral.bit_count; 4767 } else if (fn_id == BuiltinFnIdBswap) { 4768 fn_name = "bswap"; 4769 n_args = 1; 4770 key.id = ZigLLVMFnIdBswap; 4771 key.data.bswap.bit_count = (uint32_t)int_type->data.integral.bit_count; 4772 key.data.bswap.vector_len = vector_len; 4773 } else if (fn_id == BuiltinFnIdBitReverse) { 4774 fn_name = "bitreverse"; 4775 n_args = 1; 4776 key.id = ZigLLVMFnIdBitReverse; 4777 key.data.bit_reverse.bit_count = (uint32_t)int_type->data.integral.bit_count; 4778 } else { 4779 zig_unreachable(); 4780 } 4781 4782 auto existing_entry = g->llvm_fn_table.maybe_get(key); 4783 if (existing_entry) 4784 return existing_entry->value; 4785 4786 char llvm_name[64]; 4787 if (is_vector) 4788 sprintf(llvm_name, "llvm.%s.v%" PRIu32 "i%" PRIu32, fn_name, vector_len, int_type->data.integral.bit_count); 4789 else 4790 sprintf(llvm_name, "llvm.%s.i%" PRIu32, fn_name, int_type->data.integral.bit_count); 4791 LLVMTypeRef param_types[] = { 4792 get_llvm_type(g, expr_type), 4793 LLVMInt1Type(), 4794 }; 4795 LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, expr_type), param_types, n_args, false); 4796 LLVMValueRef fn_val = LLVMAddFunction(g->module, llvm_name, fn_type); 4797 assert(LLVMGetIntrinsicID(fn_val)); 4798 4799 g->llvm_fn_table.put(key, fn_val); 4800 4801 return fn_val; 4802 } 4803 4804 static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstructionClz *instruction) { 4805 ZigType *int_type = instruction->op->value->type; 4806 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdClz); 4807 LLVMValueRef operand = ir_llvm_value(g, instruction->op); 4808 LLVMValueRef params[] { 4809 operand, 4810 LLVMConstNull(LLVMInt1Type()), 4811 }; 4812 LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, params, 2, ""); 4813 return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int); 4814 } 4815 4816 static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstructionCtz *instruction) { 4817 ZigType *int_type = instruction->op->value->type; 4818 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdCtz); 4819 LLVMValueRef operand = ir_llvm_value(g, instruction->op); 4820 LLVMValueRef params[] { 4821 operand, 4822 LLVMConstNull(LLVMInt1Type()), 4823 }; 4824 LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, params, 2, ""); 4825 return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int); 4826 } 4827 4828 static LLVMValueRef ir_render_shuffle_vector(CodeGen *g, IrExecutable *executable, IrInstructionShuffleVector *instruction) { 4829 uint64_t len_a = instruction->a->value->type->data.vector.len; 4830 uint64_t len_mask = instruction->mask->value->type->data.vector.len; 4831 4832 // LLVM uses integers larger than the length of the first array to 4833 // index into the second array. This was deemed unnecessarily fragile 4834 // when changing code, so Zig uses negative numbers to index the 4835 // second vector. These start at -1 and go down, and are easiest to use 4836 // with the ~ operator. Here we convert between the two formats. 4837 IrInstruction *mask = instruction->mask; 4838 LLVMValueRef *values = allocate<LLVMValueRef>(len_mask); 4839 for (uint64_t i = 0; i < len_mask; i++) { 4840 if (mask->value->data.x_array.data.s_none.elements[i].special == ConstValSpecialUndef) { 4841 values[i] = LLVMGetUndef(LLVMInt32Type()); 4842 } else { 4843 int32_t v = bigint_as_signed(&mask->value->data.x_array.data.s_none.elements[i].data.x_bigint); 4844 uint32_t index_val = (v >= 0) ? (uint32_t)v : (uint32_t)~v + (uint32_t)len_a; 4845 values[i] = LLVMConstInt(LLVMInt32Type(), index_val, false); 4846 } 4847 } 4848 4849 LLVMValueRef llvm_mask_value = LLVMConstVector(values, len_mask); 4850 free(values); 4851 4852 return LLVMBuildShuffleVector(g->builder, 4853 ir_llvm_value(g, instruction->a), 4854 ir_llvm_value(g, instruction->b), 4855 llvm_mask_value, ""); 4856 } 4857 4858 static LLVMValueRef ir_render_splat(CodeGen *g, IrExecutable *executable, IrInstructionSplatGen *instruction) { 4859 ZigType *result_type = instruction->base.value->type; 4860 ir_assert(result_type->id == ZigTypeIdVector, &instruction->base); 4861 uint32_t len = result_type->data.vector.len; 4862 LLVMTypeRef op_llvm_type = LLVMVectorType(get_llvm_type(g, instruction->scalar->value->type), 1); 4863 LLVMTypeRef mask_llvm_type = LLVMVectorType(LLVMInt32Type(), len); 4864 LLVMValueRef undef_vector = LLVMGetUndef(op_llvm_type); 4865 LLVMValueRef op_vector = LLVMBuildInsertElement(g->builder, undef_vector, 4866 ir_llvm_value(g, instruction->scalar), LLVMConstInt(LLVMInt32Type(), 0, false), ""); 4867 return LLVMBuildShuffleVector(g->builder, op_vector, undef_vector, LLVMConstNull(mask_llvm_type), ""); 4868 } 4869 4870 static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutable *executable, IrInstructionPopCount *instruction) { 4871 ZigType *int_type = instruction->op->value->type; 4872 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount); 4873 LLVMValueRef operand = ir_llvm_value(g, instruction->op); 4874 LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, &operand, 1, ""); 4875 return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int); 4876 } 4877 4878 static LLVMValueRef ir_render_switch_br(CodeGen *g, IrExecutable *executable, IrInstructionSwitchBr *instruction) { 4879 ZigType *target_type = instruction->target_value->value->type; 4880 LLVMBasicBlockRef else_block = instruction->else_block->llvm_block; 4881 4882 LLVMValueRef target_value = ir_llvm_value(g, instruction->target_value); 4883 if (target_type->id == ZigTypeIdPointer) { 4884 const ZigType *usize = g->builtin_types.entry_usize; 4885 target_value = LLVMBuildPtrToInt(g->builder, target_value, usize->llvm_type, ""); 4886 } 4887 4888 LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, target_value, else_block, 4889 (unsigned)instruction->case_count); 4890 4891 for (size_t i = 0; i < instruction->case_count; i += 1) { 4892 IrInstructionSwitchBrCase *this_case = &instruction->cases[i]; 4893 4894 LLVMValueRef case_value = ir_llvm_value(g, this_case->value); 4895 if (target_type->id == ZigTypeIdPointer) { 4896 const ZigType *usize = g->builtin_types.entry_usize; 4897 case_value = LLVMBuildPtrToInt(g->builder, case_value, usize->llvm_type, ""); 4898 } 4899 4900 LLVMAddCase(switch_instr, case_value, this_case->block->llvm_block); 4901 } 4902 4903 return nullptr; 4904 } 4905 4906 static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstructionPhi *instruction) { 4907 if (!type_has_bits(instruction->base.value->type)) 4908 return nullptr; 4909 4910 LLVMTypeRef phi_type; 4911 if (handle_is_ptr(instruction->base.value->type)) { 4912 phi_type = LLVMPointerType(get_llvm_type(g,instruction->base.value->type), 0); 4913 } else { 4914 phi_type = get_llvm_type(g, instruction->base.value->type); 4915 } 4916 4917 LLVMValueRef phi = LLVMBuildPhi(g->builder, phi_type, ""); 4918 LLVMValueRef *incoming_values = allocate<LLVMValueRef>(instruction->incoming_count); 4919 LLVMBasicBlockRef *incoming_blocks = allocate<LLVMBasicBlockRef>(instruction->incoming_count); 4920 for (size_t i = 0; i < instruction->incoming_count; i += 1) { 4921 incoming_values[i] = ir_llvm_value(g, instruction->incoming_values[i]); 4922 incoming_blocks[i] = instruction->incoming_blocks[i]->llvm_exit_block; 4923 } 4924 LLVMAddIncoming(phi, incoming_values, incoming_blocks, (unsigned)instruction->incoming_count); 4925 return phi; 4926 } 4927 4928 static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstructionRefGen *instruction) { 4929 if (!type_has_bits(instruction->base.value->type)) { 4930 return nullptr; 4931 } 4932 LLVMValueRef value = ir_llvm_value(g, instruction->operand); 4933 if (handle_is_ptr(instruction->operand->value->type)) { 4934 return value; 4935 } else { 4936 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); 4937 gen_store_untyped(g, value, result_loc, 0, false); 4938 return result_loc; 4939 } 4940 } 4941 4942 static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrInstructionErrName *instruction) { 4943 assert(g->generate_error_name_table); 4944 4945 if (g->errors_by_index.length == 1) { 4946 LLVMBuildUnreachable(g->builder); 4947 return nullptr; 4948 } 4949 4950 LLVMValueRef err_val = ir_llvm_value(g, instruction->value); 4951 if (ir_want_runtime_safety(g, &instruction->base)) { 4952 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(err_val)); 4953 LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(err_val), g->errors_by_index.length, false); 4954 add_bounds_check(g, err_val, LLVMIntNE, zero, LLVMIntULT, end_val); 4955 } 4956 4957 LLVMValueRef indices[] = { 4958 LLVMConstNull(g->builtin_types.entry_usize->llvm_type), 4959 err_val, 4960 }; 4961 return LLVMBuildInBoundsGEP(g->builder, g->err_name_table, indices, 2, ""); 4962 } 4963 4964 static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { 4965 assert(enum_type->id == ZigTypeIdEnum); 4966 if (enum_type->data.enumeration.name_function) 4967 return enum_type->data.enumeration.name_function; 4968 4969 ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, false, false, 4970 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false); 4971 ZigType *u8_slice_type = get_slice_type(g, u8_ptr_type); 4972 ZigType *tag_int_type = enum_type->data.enumeration.tag_int_type; 4973 4974 LLVMTypeRef tag_int_llvm_type = get_llvm_type(g, tag_int_type); 4975 LLVMTypeRef fn_type_ref = LLVMFunctionType(LLVMPointerType(get_llvm_type(g, u8_slice_type), 0), 4976 &tag_int_llvm_type, 1, false); 4977 4978 const char *fn_name = get_mangled_name(g, 4979 buf_ptr(buf_sprintf("__zig_tag_name_%s", buf_ptr(&enum_type->name))), false); 4980 LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); 4981 LLVMSetLinkage(fn_val, LLVMInternalLinkage); 4982 ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); 4983 addLLVMFnAttr(fn_val, "nounwind"); 4984 add_uwtable_attr(g, fn_val); 4985 if (codegen_have_frame_pointer(g)) { 4986 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); 4987 ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr); 4988 } 4989 4990 LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder); 4991 LLVMValueRef prev_debug_location = LLVMGetCurrentDebugLocation(g->builder); 4992 ZigFn *prev_cur_fn = g->cur_fn; 4993 LLVMValueRef prev_cur_fn_val = g->cur_fn_val; 4994 4995 LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry"); 4996 LLVMPositionBuilderAtEnd(g->builder, entry_block); 4997 ZigLLVMClearCurrentDebugLocation(g->builder); 4998 g->cur_fn = nullptr; 4999 g->cur_fn_val = fn_val; 5000 5001 size_t field_count = enum_type->data.enumeration.src_field_count; 5002 LLVMBasicBlockRef bad_value_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadValue"); 5003 LLVMValueRef tag_int_value = LLVMGetParam(fn_val, 0); 5004 LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, tag_int_value, bad_value_block, field_count); 5005 5006 5007 ZigType *usize = g->builtin_types.entry_usize; 5008 LLVMValueRef array_ptr_indices[] = { 5009 LLVMConstNull(usize->llvm_type), 5010 LLVMConstNull(usize->llvm_type), 5011 }; 5012 5013 for (size_t field_i = 0; field_i < field_count; field_i += 1) { 5014 Buf *name = enum_type->data.enumeration.fields[field_i].name; 5015 LLVMValueRef str_init = LLVMConstString(buf_ptr(name), (unsigned)buf_len(name), true); 5016 LLVMValueRef str_global = LLVMAddGlobal(g->module, LLVMTypeOf(str_init), ""); 5017 LLVMSetInitializer(str_global, str_init); 5018 LLVMSetLinkage(str_global, LLVMPrivateLinkage); 5019 LLVMSetGlobalConstant(str_global, true); 5020 LLVMSetUnnamedAddr(str_global, true); 5021 LLVMSetAlignment(str_global, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(str_init))); 5022 5023 LLVMValueRef fields[] = { 5024 LLVMConstGEP(str_global, array_ptr_indices, 2), 5025 LLVMConstInt(g->builtin_types.entry_usize->llvm_type, buf_len(name), false), 5026 }; 5027 LLVMValueRef slice_init_value = LLVMConstNamedStruct(get_llvm_type(g, u8_slice_type), fields, 2); 5028 5029 LLVMValueRef slice_global = LLVMAddGlobal(g->module, LLVMTypeOf(slice_init_value), ""); 5030 LLVMSetInitializer(slice_global, slice_init_value); 5031 LLVMSetLinkage(slice_global, LLVMPrivateLinkage); 5032 LLVMSetGlobalConstant(slice_global, true); 5033 LLVMSetUnnamedAddr(slice_global, true); 5034 LLVMSetAlignment(slice_global, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(slice_init_value))); 5035 5036 LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(g->cur_fn_val, "Name"); 5037 LLVMValueRef this_tag_int_value = bigint_to_llvm_const(get_llvm_type(g, tag_int_type), 5038 &enum_type->data.enumeration.fields[field_i].value); 5039 LLVMAddCase(switch_instr, this_tag_int_value, return_block); 5040 5041 LLVMPositionBuilderAtEnd(g->builder, return_block); 5042 LLVMBuildRet(g->builder, slice_global); 5043 } 5044 5045 LLVMPositionBuilderAtEnd(g->builder, bad_value_block); 5046 if (g->build_mode == BuildModeDebug || g->build_mode == BuildModeSafeRelease) { 5047 gen_safety_crash(g, PanicMsgIdBadEnumValue); 5048 } else { 5049 LLVMBuildUnreachable(g->builder); 5050 } 5051 5052 g->cur_fn = prev_cur_fn; 5053 g->cur_fn_val = prev_cur_fn_val; 5054 LLVMPositionBuilderAtEnd(g->builder, prev_block); 5055 if (!g->strip_debug_symbols) { 5056 LLVMSetCurrentDebugLocation(g->builder, prev_debug_location); 5057 } 5058 5059 enum_type->data.enumeration.name_function = fn_val; 5060 return fn_val; 5061 } 5062 5063 static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable, 5064 IrInstructionTagName *instruction) 5065 { 5066 ZigType *enum_type = instruction->target->value->type; 5067 assert(enum_type->id == ZigTypeIdEnum); 5068 if (enum_type->data.enumeration.non_exhaustive) { 5069 add_node_error(g, instruction->base.source_node, 5070 buf_sprintf("TODO @tagName on non-exhaustive enum https://github.com/ziglang/zig/issues/3991")); 5071 codegen_report_errors_and_exit(g); 5072 } 5073 5074 LLVMValueRef enum_name_function = get_enum_tag_name_function(g, enum_type); 5075 5076 LLVMValueRef enum_tag_value = ir_llvm_value(g, instruction->target); 5077 return ZigLLVMBuildCall(g->builder, enum_name_function, &enum_tag_value, 1, 5078 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, ""); 5079 } 5080 5081 static LLVMValueRef ir_render_field_parent_ptr(CodeGen *g, IrExecutable *executable, 5082 IrInstructionFieldParentPtr *instruction) 5083 { 5084 ZigType *container_ptr_type = instruction->base.value->type; 5085 assert(container_ptr_type->id == ZigTypeIdPointer); 5086 5087 ZigType *container_type = container_ptr_type->data.pointer.child_type; 5088 5089 size_t byte_offset = LLVMOffsetOfElement(g->target_data_ref, 5090 get_llvm_type(g, container_type), instruction->field->gen_index); 5091 5092 LLVMValueRef field_ptr_val = ir_llvm_value(g, instruction->field_ptr); 5093 5094 if (byte_offset == 0) { 5095 return LLVMBuildBitCast(g->builder, field_ptr_val, get_llvm_type(g, container_ptr_type), ""); 5096 } else { 5097 ZigType *usize = g->builtin_types.entry_usize; 5098 5099 LLVMValueRef field_ptr_int = LLVMBuildPtrToInt(g->builder, field_ptr_val, usize->llvm_type, ""); 5100 5101 LLVMValueRef base_ptr_int = LLVMBuildNUWSub(g->builder, field_ptr_int, 5102 LLVMConstInt(usize->llvm_type, byte_offset, false), ""); 5103 5104 return LLVMBuildIntToPtr(g->builder, base_ptr_int, get_llvm_type(g, container_ptr_type), ""); 5105 } 5106 } 5107 5108 static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, IrInstructionAlignCast *instruction) { 5109 LLVMValueRef target_val = ir_llvm_value(g, instruction->target); 5110 assert(target_val); 5111 5112 bool want_runtime_safety = ir_want_runtime_safety(g, &instruction->base); 5113 if (!want_runtime_safety) { 5114 return target_val; 5115 } 5116 5117 ZigType *target_type = instruction->base.value->type; 5118 uint32_t align_bytes; 5119 LLVMValueRef ptr_val; 5120 5121 if (target_type->id == ZigTypeIdPointer) { 5122 align_bytes = get_ptr_align(g, target_type); 5123 ptr_val = target_val; 5124 } else if (target_type->id == ZigTypeIdFn) { 5125 align_bytes = target_type->data.fn.fn_type_id.alignment; 5126 ptr_val = target_val; 5127 } else if (target_type->id == ZigTypeIdOptional && 5128 target_type->data.maybe.child_type->id == ZigTypeIdPointer) 5129 { 5130 align_bytes = get_ptr_align(g, target_type->data.maybe.child_type); 5131 ptr_val = target_val; 5132 } else if (target_type->id == ZigTypeIdOptional && 5133 target_type->data.maybe.child_type->id == ZigTypeIdFn) 5134 { 5135 align_bytes = target_type->data.maybe.child_type->data.fn.fn_type_id.alignment; 5136 ptr_val = target_val; 5137 } else if (target_type->id == ZigTypeIdStruct && 5138 target_type->data.structure.special == StructSpecialSlice) 5139 { 5140 ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index]->type_entry; 5141 align_bytes = get_ptr_align(g, slice_ptr_type); 5142 5143 size_t ptr_index = target_type->data.structure.fields[slice_ptr_index]->gen_index; 5144 LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP(g->builder, target_val, (unsigned)ptr_index, ""); 5145 ptr_val = gen_load_untyped(g, ptr_val_ptr, 0, false, ""); 5146 } else { 5147 zig_unreachable(); 5148 } 5149 5150 assert(align_bytes != 1); 5151 5152 ZigType *usize = g->builtin_types.entry_usize; 5153 LLVMValueRef ptr_as_int_val = LLVMBuildPtrToInt(g->builder, ptr_val, usize->llvm_type, ""); 5154 LLVMValueRef alignment_minus_1 = LLVMConstInt(usize->llvm_type, align_bytes - 1, false); 5155 LLVMValueRef anded_val = LLVMBuildAnd(g->builder, ptr_as_int_val, alignment_minus_1, ""); 5156 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, anded_val, LLVMConstNull(usize->llvm_type), ""); 5157 5158 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "AlignCastOk"); 5159 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "AlignCastFail"); 5160 5161 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block); 5162 5163 LLVMPositionBuilderAtEnd(g->builder, fail_block); 5164 gen_safety_crash(g, PanicMsgIdIncorrectAlignment); 5165 5166 LLVMPositionBuilderAtEnd(g->builder, ok_block); 5167 5168 return target_val; 5169 } 5170 5171 static LLVMValueRef ir_render_error_return_trace(CodeGen *g, IrExecutable *executable, 5172 IrInstructionErrorReturnTrace *instruction) 5173 { 5174 bool is_llvm_alloca; 5175 LLVMValueRef cur_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca); 5176 if (cur_err_ret_trace_val == nullptr) { 5177 return LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type(g))); 5178 } 5179 return cur_err_ret_trace_val; 5180 } 5181 5182 static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) { 5183 switch (atomic_order) { 5184 case AtomicOrderUnordered: return LLVMAtomicOrderingUnordered; 5185 case AtomicOrderMonotonic: return LLVMAtomicOrderingMonotonic; 5186 case AtomicOrderAcquire: return LLVMAtomicOrderingAcquire; 5187 case AtomicOrderRelease: return LLVMAtomicOrderingRelease; 5188 case AtomicOrderAcqRel: return LLVMAtomicOrderingAcquireRelease; 5189 case AtomicOrderSeqCst: return LLVMAtomicOrderingSequentiallyConsistent; 5190 } 5191 zig_unreachable(); 5192 } 5193 5194 static enum ZigLLVM_AtomicRMWBinOp to_ZigLLVMAtomicRMWBinOp(AtomicRmwOp op, bool is_signed, bool is_float) { 5195 switch (op) { 5196 case AtomicRmwOp_xchg: return ZigLLVMAtomicRMWBinOpXchg; 5197 case AtomicRmwOp_add: 5198 return is_float ? ZigLLVMAtomicRMWBinOpFAdd : ZigLLVMAtomicRMWBinOpAdd; 5199 case AtomicRmwOp_sub: 5200 return is_float ? ZigLLVMAtomicRMWBinOpFSub : ZigLLVMAtomicRMWBinOpSub; 5201 case AtomicRmwOp_and: return ZigLLVMAtomicRMWBinOpAnd; 5202 case AtomicRmwOp_nand: return ZigLLVMAtomicRMWBinOpNand; 5203 case AtomicRmwOp_or: return ZigLLVMAtomicRMWBinOpOr; 5204 case AtomicRmwOp_xor: return ZigLLVMAtomicRMWBinOpXor; 5205 case AtomicRmwOp_max: 5206 return is_signed ? ZigLLVMAtomicRMWBinOpMax : ZigLLVMAtomicRMWBinOpUMax; 5207 case AtomicRmwOp_min: 5208 return is_signed ? ZigLLVMAtomicRMWBinOpMin : ZigLLVMAtomicRMWBinOpUMin; 5209 } 5210 zig_unreachable(); 5211 } 5212 5213 static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutable *executable, IrInstructionCmpxchgGen *instruction) { 5214 LLVMValueRef ptr_val = ir_llvm_value(g, instruction->ptr); 5215 LLVMValueRef cmp_val = ir_llvm_value(g, instruction->cmp_value); 5216 LLVMValueRef new_val = ir_llvm_value(g, instruction->new_value); 5217 5218 LLVMAtomicOrdering success_order = to_LLVMAtomicOrdering(instruction->success_order); 5219 LLVMAtomicOrdering failure_order = to_LLVMAtomicOrdering(instruction->failure_order); 5220 5221 LLVMValueRef result_val = ZigLLVMBuildCmpXchg(g->builder, ptr_val, cmp_val, new_val, 5222 success_order, failure_order, instruction->is_weak); 5223 5224 ZigType *optional_type = instruction->base.value->type; 5225 assert(optional_type->id == ZigTypeIdOptional); 5226 ZigType *child_type = optional_type->data.maybe.child_type; 5227 5228 if (!handle_is_ptr(optional_type)) { 5229 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, ""); 5230 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, ""); 5231 return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, ""); 5232 } 5233 5234 // When the cmpxchg is discarded, the result location will have no bits. 5235 if (!type_has_bits(instruction->result_loc->value->type)) { 5236 return nullptr; 5237 } 5238 5239 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); 5240 ir_assert(result_loc != nullptr, &instruction->base); 5241 ir_assert(type_has_bits(child_type), &instruction->base); 5242 5243 LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, ""); 5244 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, ""); 5245 gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val); 5246 5247 LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, ""); 5248 LLVMValueRef nonnull_bit = LLVMBuildNot(g->builder, success_bit, ""); 5249 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_null_index, ""); 5250 gen_store_untyped(g, nonnull_bit, maybe_ptr, 0, false); 5251 return result_loc; 5252 } 5253 5254 static LLVMValueRef ir_render_fence(CodeGen *g, IrExecutable *executable, IrInstructionFence *instruction) { 5255 LLVMAtomicOrdering atomic_order = to_LLVMAtomicOrdering(instruction->order); 5256 LLVMBuildFence(g->builder, atomic_order, false, ""); 5257 return nullptr; 5258 } 5259 5260 static LLVMValueRef ir_render_truncate(CodeGen *g, IrExecutable *executable, IrInstructionTruncate *instruction) { 5261 LLVMValueRef target_val = ir_llvm_value(g, instruction->target); 5262 ZigType *dest_type = instruction->base.value->type; 5263 ZigType *src_type = instruction->target->value->type; 5264 if (dest_type == src_type) { 5265 // no-op 5266 return target_val; 5267 } if (src_type->data.integral.bit_count == dest_type->data.integral.bit_count) { 5268 return LLVMBuildBitCast(g->builder, target_val, get_llvm_type(g, dest_type), ""); 5269 } else { 5270 LLVMValueRef target_val = ir_llvm_value(g, instruction->target); 5271 return LLVMBuildTrunc(g->builder, target_val, get_llvm_type(g, dest_type), ""); 5272 } 5273 } 5274 5275 static LLVMValueRef ir_render_memset(CodeGen *g, IrExecutable *executable, IrInstructionMemset *instruction) { 5276 LLVMValueRef dest_ptr = ir_llvm_value(g, instruction->dest_ptr); 5277 LLVMValueRef len_val = ir_llvm_value(g, instruction->count); 5278 5279 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); 5280 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, ""); 5281 5282 ZigType *ptr_type = instruction->dest_ptr->value->type; 5283 assert(ptr_type->id == ZigTypeIdPointer); 5284 5285 bool val_is_undef = value_is_all_undef(g, instruction->byte->value); 5286 LLVMValueRef fill_char; 5287 if (val_is_undef && ir_want_runtime_safety_scope(g, instruction->base.scope)) { 5288 fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false); 5289 } else { 5290 fill_char = ir_llvm_value(g, instruction->byte); 5291 } 5292 ZigLLVMBuildMemSet(g->builder, dest_ptr_casted, fill_char, len_val, get_ptr_align(g, ptr_type), 5293 ptr_type->data.pointer.is_volatile); 5294 5295 if (val_is_undef && want_valgrind_support(g)) { 5296 gen_valgrind_undef(g, dest_ptr_casted, len_val); 5297 } 5298 return nullptr; 5299 } 5300 5301 static LLVMValueRef ir_render_memcpy(CodeGen *g, IrExecutable *executable, IrInstructionMemcpy *instruction) { 5302 LLVMValueRef dest_ptr = ir_llvm_value(g, instruction->dest_ptr); 5303 LLVMValueRef src_ptr = ir_llvm_value(g, instruction->src_ptr); 5304 LLVMValueRef len_val = ir_llvm_value(g, instruction->count); 5305 5306 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); 5307 5308 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, dest_ptr, ptr_u8, ""); 5309 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr, ptr_u8, ""); 5310 5311 ZigType *dest_ptr_type = instruction->dest_ptr->value->type; 5312 ZigType *src_ptr_type = instruction->src_ptr->value->type; 5313 5314 assert(dest_ptr_type->id == ZigTypeIdPointer); 5315 assert(src_ptr_type->id == ZigTypeIdPointer); 5316 5317 bool is_volatile = (dest_ptr_type->data.pointer.is_volatile || src_ptr_type->data.pointer.is_volatile); 5318 ZigLLVMBuildMemCpy(g->builder, dest_ptr_casted, get_ptr_align(g, dest_ptr_type), 5319 src_ptr_casted, get_ptr_align(g, src_ptr_type), len_val, is_volatile); 5320 return nullptr; 5321 } 5322 5323 static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInstructionSliceGen *instruction) { 5324 LLVMValueRef array_ptr_ptr = ir_llvm_value(g, instruction->ptr); 5325 ZigType *array_ptr_type = instruction->ptr->value->type; 5326 assert(array_ptr_type->id == ZigTypeIdPointer); 5327 ZigType *array_type = array_ptr_type->data.pointer.child_type; 5328 LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type); 5329 5330 LLVMValueRef tmp_struct_ptr = ir_llvm_value(g, instruction->result_loc); 5331 5332 bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base); 5333 5334 ZigType *res_slice_ptr_type = instruction->base.value->type->data.structure.fields[slice_ptr_index]->type_entry; 5335 ZigValue *sentinel = res_slice_ptr_type->data.pointer.sentinel; 5336 5337 if (array_type->id == ZigTypeIdArray || 5338 (array_type->id == ZigTypeIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle)) 5339 { 5340 if (array_type->id == ZigTypeIdPointer) { 5341 array_type = array_type->data.pointer.child_type; 5342 } 5343 LLVMValueRef start_val = ir_llvm_value(g, instruction->start); 5344 LLVMValueRef end_val; 5345 if (instruction->end) { 5346 end_val = ir_llvm_value(g, instruction->end); 5347 } else { 5348 end_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, array_type->data.array.len, false); 5349 } 5350 if (want_runtime_safety) { 5351 if (instruction->start->value->special == ConstValSpecialRuntime || instruction->end) { 5352 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val); 5353 } 5354 if (instruction->end) { 5355 LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 5356 array_type->data.array.len, false); 5357 add_bounds_check(g, end_val, LLVMIntEQ, nullptr, LLVMIntULE, array_end); 5358 5359 if (sentinel != nullptr) { 5360 LLVMValueRef indices[] = { 5361 LLVMConstNull(g->builtin_types.entry_usize->llvm_type), 5362 end_val, 5363 }; 5364 LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, ""); 5365 add_sentinel_check(g, sentinel_elem_ptr, sentinel); 5366 } 5367 } 5368 } 5369 if (!type_has_bits(array_type)) { 5370 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, ""); 5371 5372 // TODO if runtime safety is on, store 0xaaaaaaa in ptr field 5373 LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, ""); 5374 gen_store_untyped(g, len_value, len_field_ptr, 0, false); 5375 return tmp_struct_ptr; 5376 } 5377 5378 5379 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_ptr_index, ""); 5380 LLVMValueRef indices[] = { 5381 LLVMConstNull(g->builtin_types.entry_usize->llvm_type), 5382 start_val, 5383 }; 5384 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, ""); 5385 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false); 5386 5387 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, ""); 5388 LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, ""); 5389 gen_store_untyped(g, len_value, len_field_ptr, 0, false); 5390 5391 return tmp_struct_ptr; 5392 } else if (array_type->id == ZigTypeIdPointer) { 5393 assert(array_type->data.pointer.ptr_len != PtrLenSingle); 5394 LLVMValueRef start_val = ir_llvm_value(g, instruction->start); 5395 LLVMValueRef end_val = ir_llvm_value(g, instruction->end); 5396 5397 if (want_runtime_safety) { 5398 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val); 5399 if (sentinel != nullptr) { 5400 LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &end_val, 1, ""); 5401 add_sentinel_check(g, sentinel_elem_ptr, sentinel); 5402 } 5403 } 5404 5405 if (type_has_bits(array_type)) { 5406 size_t gen_ptr_index = instruction->base.value->type->data.structure.fields[slice_ptr_index]->gen_index; 5407 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_ptr_index, ""); 5408 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, ""); 5409 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false); 5410 } 5411 5412 size_t gen_len_index = instruction->base.value->type->data.structure.fields[slice_len_index]->gen_index; 5413 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_len_index, ""); 5414 LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, ""); 5415 gen_store_untyped(g, len_value, len_field_ptr, 0, false); 5416 5417 return tmp_struct_ptr; 5418 } else if (array_type->id == ZigTypeIdStruct) { 5419 assert(array_type->data.structure.special == StructSpecialSlice); 5420 assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind); 5421 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind); 5422 assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(tmp_struct_ptr))) == LLVMStructTypeKind); 5423 5424 size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index; 5425 assert(ptr_index != SIZE_MAX); 5426 size_t len_index = array_type->data.structure.fields[slice_len_index]->gen_index; 5427 assert(len_index != SIZE_MAX); 5428 5429 LLVMValueRef prev_end = nullptr; 5430 if (!instruction->end || want_runtime_safety) { 5431 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, ""); 5432 prev_end = gen_load_untyped(g, src_len_ptr, 0, false, ""); 5433 } 5434 5435 LLVMValueRef start_val = ir_llvm_value(g, instruction->start); 5436 LLVMValueRef end_val; 5437 if (instruction->end) { 5438 end_val = ir_llvm_value(g, instruction->end); 5439 } else { 5440 end_val = prev_end; 5441 } 5442 5443 LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)ptr_index, ""); 5444 LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, ""); 5445 5446 if (want_runtime_safety) { 5447 assert(prev_end); 5448 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val); 5449 if (instruction->end) { 5450 add_bounds_check(g, end_val, LLVMIntEQ, nullptr, LLVMIntULE, prev_end); 5451 5452 if (sentinel != nullptr) { 5453 LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr, &end_val, 1, ""); 5454 add_sentinel_check(g, sentinel_elem_ptr, sentinel); 5455 } 5456 } 5457 } 5458 5459 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, (unsigned)ptr_index, ""); 5460 LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr, &start_val, 1, ""); 5461 gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false); 5462 5463 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, (unsigned)len_index, ""); 5464 LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, ""); 5465 gen_store_untyped(g, len_value, len_field_ptr, 0, false); 5466 5467 return tmp_struct_ptr; 5468 } else { 5469 zig_unreachable(); 5470 } 5471 } 5472 5473 static LLVMValueRef get_trap_fn_val(CodeGen *g) { 5474 if (g->trap_fn_val) 5475 return g->trap_fn_val; 5476 5477 LLVMTypeRef fn_type = LLVMFunctionType(LLVMVoidType(), nullptr, 0, false); 5478 g->trap_fn_val = LLVMAddFunction(g->module, "llvm.debugtrap", fn_type); 5479 assert(LLVMGetIntrinsicID(g->trap_fn_val)); 5480 5481 return g->trap_fn_val; 5482 } 5483 5484 5485 static LLVMValueRef ir_render_breakpoint(CodeGen *g, IrExecutable *executable, IrInstructionBreakpoint *instruction) { 5486 LLVMBuildCall(g->builder, get_trap_fn_val(g), nullptr, 0, ""); 5487 return nullptr; 5488 } 5489 5490 static LLVMValueRef ir_render_return_address(CodeGen *g, IrExecutable *executable, 5491 IrInstructionReturnAddress *instruction) 5492 { 5493 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type); 5494 LLVMValueRef ptr_val = LLVMBuildCall(g->builder, get_return_address_fn_val(g), &zero, 1, ""); 5495 return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, ""); 5496 } 5497 5498 static LLVMValueRef get_frame_address_fn_val(CodeGen *g) { 5499 if (g->frame_address_fn_val) 5500 return g->frame_address_fn_val; 5501 5502 ZigType *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true); 5503 5504 LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, return_type), 5505 &g->builtin_types.entry_i32->llvm_type, 1, false); 5506 g->frame_address_fn_val = LLVMAddFunction(g->module, "llvm.frameaddress", fn_type); 5507 assert(LLVMGetIntrinsicID(g->frame_address_fn_val)); 5508 5509 return g->frame_address_fn_val; 5510 } 5511 5512 static LLVMValueRef ir_render_frame_address(CodeGen *g, IrExecutable *executable, 5513 IrInstructionFrameAddress *instruction) 5514 { 5515 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type); 5516 LLVMValueRef ptr_val = LLVMBuildCall(g->builder, get_frame_address_fn_val(g), &zero, 1, ""); 5517 return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, ""); 5518 } 5519 5520 static LLVMValueRef ir_render_handle(CodeGen *g, IrExecutable *executable, IrInstructionFrameHandle *instruction) { 5521 return g->cur_frame_ptr; 5522 } 5523 5524 static LLVMValueRef render_shl_with_overflow(CodeGen *g, IrInstructionOverflowOp *instruction) { 5525 ZigType *int_type = instruction->result_ptr_type; 5526 assert(int_type->id == ZigTypeIdInt); 5527 5528 LLVMValueRef op1 = ir_llvm_value(g, instruction->op1); 5529 LLVMValueRef op2 = ir_llvm_value(g, instruction->op2); 5530 LLVMValueRef ptr_result = ir_llvm_value(g, instruction->result_ptr); 5531 5532 LLVMValueRef op2_casted = gen_widen_or_shorten(g, false, instruction->op2->value->type, 5533 instruction->op1->value->type, op2); 5534 5535 LLVMValueRef result = LLVMBuildShl(g->builder, op1, op2_casted, ""); 5536 LLVMValueRef orig_val; 5537 if (int_type->data.integral.is_signed) { 5538 orig_val = LLVMBuildAShr(g->builder, result, op2_casted, ""); 5539 } else { 5540 orig_val = LLVMBuildLShr(g->builder, result, op2_casted, ""); 5541 } 5542 LLVMValueRef overflow_bit = LLVMBuildICmp(g->builder, LLVMIntNE, op1, orig_val, ""); 5543 5544 gen_store(g, result, ptr_result, instruction->result_ptr->value->type); 5545 5546 return overflow_bit; 5547 } 5548 5549 static LLVMValueRef ir_render_overflow_op(CodeGen *g, IrExecutable *executable, IrInstructionOverflowOp *instruction) { 5550 AddSubMul add_sub_mul; 5551 switch (instruction->op) { 5552 case IrOverflowOpAdd: 5553 add_sub_mul = AddSubMulAdd; 5554 break; 5555 case IrOverflowOpSub: 5556 add_sub_mul = AddSubMulSub; 5557 break; 5558 case IrOverflowOpMul: 5559 add_sub_mul = AddSubMulMul; 5560 break; 5561 case IrOverflowOpShl: 5562 return render_shl_with_overflow(g, instruction); 5563 } 5564 5565 ZigType *int_type = instruction->result_ptr_type; 5566 assert(int_type->id == ZigTypeIdInt); 5567 5568 LLVMValueRef fn_val = get_int_overflow_fn(g, int_type, add_sub_mul); 5569 5570 LLVMValueRef op1 = ir_llvm_value(g, instruction->op1); 5571 LLVMValueRef op2 = ir_llvm_value(g, instruction->op2); 5572 LLVMValueRef ptr_result = ir_llvm_value(g, instruction->result_ptr); 5573 5574 LLVMValueRef params[] = { 5575 op1, 5576 op2, 5577 }; 5578 5579 LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, ""); 5580 LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, ""); 5581 LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, ""); 5582 gen_store(g, result, ptr_result, instruction->result_ptr->value->type); 5583 5584 return overflow_bit; 5585 } 5586 5587 static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrInstructionTestErrGen *instruction) { 5588 ZigType *err_union_type = instruction->err_union->value->type; 5589 ZigType *payload_type = err_union_type->data.error_union.payload_type; 5590 LLVMValueRef err_union_handle = ir_llvm_value(g, instruction->err_union); 5591 5592 LLVMValueRef err_val; 5593 if (type_has_bits(payload_type)) { 5594 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); 5595 err_val = gen_load_untyped(g, err_val_ptr, 0, false, ""); 5596 } else { 5597 err_val = err_union_handle; 5598 } 5599 5600 LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, g->err_tag_type)); 5601 return LLVMBuildICmp(g->builder, LLVMIntNE, err_val, zero, ""); 5602 } 5603 5604 static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable, 5605 IrInstructionUnwrapErrCode *instruction) 5606 { 5607 if (instruction->base.value->special != ConstValSpecialRuntime) 5608 return nullptr; 5609 5610 ZigType *ptr_type = instruction->err_union_ptr->value->type; 5611 assert(ptr_type->id == ZigTypeIdPointer); 5612 ZigType *err_union_type = ptr_type->data.pointer.child_type; 5613 ZigType *payload_type = err_union_type->data.error_union.payload_type; 5614 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->err_union_ptr); 5615 if (!type_has_bits(payload_type)) { 5616 return err_union_ptr; 5617 } else { 5618 // TODO assign undef to the payload 5619 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type); 5620 return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); 5621 } 5622 } 5623 5624 static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable, 5625 IrInstructionUnwrapErrPayload *instruction) 5626 { 5627 Error err; 5628 5629 if (instruction->base.value->special != ConstValSpecialRuntime) 5630 return nullptr; 5631 5632 bool want_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base) && 5633 g->errors_by_index.length > 1; 5634 5635 bool value_has_bits; 5636 if ((err = type_has_bits2(g, instruction->base.value->type, &value_has_bits))) 5637 codegen_report_errors_and_exit(g); 5638 5639 if (!want_safety && !value_has_bits) 5640 return nullptr; 5641 5642 ZigType *ptr_type = instruction->value->value->type; 5643 assert(ptr_type->id == ZigTypeIdPointer); 5644 ZigType *err_union_type = ptr_type->data.pointer.child_type; 5645 ZigType *payload_type = err_union_type->data.error_union.payload_type; 5646 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value); 5647 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type); 5648 5649 if (!type_has_bits(err_union_type->data.error_union.err_set_type)) { 5650 return err_union_handle; 5651 } 5652 5653 if (want_safety) { 5654 LLVMValueRef err_val; 5655 if (type_has_bits(payload_type)) { 5656 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); 5657 err_val = gen_load_untyped(g, err_val_ptr, 0, false, ""); 5658 } else { 5659 err_val = err_union_handle; 5660 } 5661 LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, g->err_tag_type)); 5662 LLVMValueRef cond_val = LLVMBuildICmp(g->builder, LLVMIntEQ, err_val, zero, ""); 5663 LLVMBasicBlockRef err_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapErrError"); 5664 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapErrOk"); 5665 LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block); 5666 5667 LLVMPositionBuilderAtEnd(g->builder, err_block); 5668 gen_safety_crash_for_err(g, err_val, instruction->base.scope); 5669 5670 LLVMPositionBuilderAtEnd(g->builder, ok_block); 5671 } 5672 5673 if (type_has_bits(payload_type)) { 5674 if (instruction->initializing) { 5675 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); 5676 LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type)); 5677 gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false); 5678 } 5679 return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_payload_index, ""); 5680 } else { 5681 return nullptr; 5682 } 5683 } 5684 5685 static LLVMValueRef ir_render_optional_wrap(CodeGen *g, IrExecutable *executable, IrInstructionOptionalWrap *instruction) { 5686 ZigType *wanted_type = instruction->base.value->type; 5687 5688 assert(wanted_type->id == ZigTypeIdOptional); 5689 5690 ZigType *child_type = wanted_type->data.maybe.child_type; 5691 5692 if (!type_has_bits(child_type)) { 5693 LLVMValueRef result = LLVMConstAllOnes(LLVMInt1Type()); 5694 if (instruction->result_loc != nullptr) { 5695 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); 5696 gen_store_untyped(g, result, result_loc, 0, false); 5697 } 5698 return result; 5699 } 5700 5701 LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand); 5702 if (!handle_is_ptr(wanted_type)) { 5703 if (instruction->result_loc != nullptr) { 5704 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); 5705 gen_store_untyped(g, payload_val, result_loc, 0, false); 5706 } 5707 return payload_val; 5708 } 5709 5710 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); 5711 5712 LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, ""); 5713 // child_type and instruction->value->value->type may differ by constness 5714 gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val); 5715 LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_null_index, ""); 5716 gen_store_untyped(g, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr, 0, false); 5717 5718 return result_loc; 5719 } 5720 5721 static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapCode *instruction) { 5722 ZigType *wanted_type = instruction->base.value->type; 5723 5724 assert(wanted_type->id == ZigTypeIdErrorUnion); 5725 5726 LLVMValueRef err_val = ir_llvm_value(g, instruction->operand); 5727 5728 if (!handle_is_ptr(wanted_type)) 5729 return err_val; 5730 5731 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); 5732 5733 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, ""); 5734 gen_store_untyped(g, err_val, err_tag_ptr, 0, false); 5735 5736 // TODO store undef to the payload 5737 5738 return result_loc; 5739 } 5740 5741 static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, IrExecutable *executable, IrInstructionErrWrapPayload *instruction) { 5742 ZigType *wanted_type = instruction->base.value->type; 5743 5744 assert(wanted_type->id == ZigTypeIdErrorUnion); 5745 5746 ZigType *payload_type = wanted_type->data.error_union.payload_type; 5747 ZigType *err_set_type = wanted_type->data.error_union.err_set_type; 5748 5749 if (!type_has_bits(err_set_type)) { 5750 return ir_llvm_value(g, instruction->operand); 5751 } 5752 5753 LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type)); 5754 5755 if (!type_has_bits(payload_type)) 5756 return ok_err_val; 5757 5758 5759 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); 5760 5761 LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand); 5762 5763 LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, ""); 5764 gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false); 5765 5766 LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, ""); 5767 gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, payload_type, false), payload_val); 5768 5769 return result_loc; 5770 } 5771 5772 static LLVMValueRef ir_render_union_tag(CodeGen *g, IrExecutable *executable, IrInstructionUnionTag *instruction) { 5773 ZigType *union_type = instruction->value->value->type; 5774 5775 ZigType *tag_type = union_type->data.unionation.tag_type; 5776 if (!type_has_bits(tag_type)) 5777 return nullptr; 5778 5779 LLVMValueRef union_val = ir_llvm_value(g, instruction->value); 5780 if (union_type->data.unionation.gen_field_count == 0) 5781 return union_val; 5782 5783 assert(union_type->data.unionation.gen_tag_index != SIZE_MAX); 5784 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_val, 5785 union_type->data.unionation.gen_tag_index, ""); 5786 ZigType *ptr_type = get_pointer_to_type(g, tag_type, false); 5787 return get_handle_value(g, tag_field_ptr, tag_type, ptr_type); 5788 } 5789 5790 static LLVMValueRef ir_render_panic(CodeGen *g, IrExecutable *executable, IrInstructionPanic *instruction) { 5791 bool is_llvm_alloca; 5792 LLVMValueRef err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca); 5793 gen_panic(g, ir_llvm_value(g, instruction->msg), err_ret_trace_val, is_llvm_alloca); 5794 return nullptr; 5795 } 5796 5797 static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutable *executable, 5798 IrInstructionAtomicRmw *instruction) 5799 { 5800 bool is_signed; 5801 ZigType *operand_type = instruction->operand->value->type; 5802 bool is_float = operand_type->id == ZigTypeIdFloat; 5803 if (operand_type->id == ZigTypeIdInt) { 5804 is_signed = operand_type->data.integral.is_signed; 5805 } else { 5806 is_signed = false; 5807 } 5808 enum ZigLLVM_AtomicRMWBinOp op = to_ZigLLVMAtomicRMWBinOp(instruction->resolved_op, is_signed, is_float); 5809 LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering); 5810 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); 5811 LLVMValueRef operand = ir_llvm_value(g, instruction->operand); 5812 5813 if (get_codegen_ptr_type(operand_type) == nullptr) { 5814 return ZigLLVMBuildAtomicRMW(g->builder, op, ptr, operand, ordering, g->is_single_threaded); 5815 } 5816 5817 // it's a pointer but we need to treat it as an int 5818 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr, 5819 LLVMPointerType(g->builtin_types.entry_usize->llvm_type, 0), ""); 5820 LLVMValueRef casted_operand = LLVMBuildPtrToInt(g->builder, operand, g->builtin_types.entry_usize->llvm_type, ""); 5821 LLVMValueRef uncasted_result = ZigLLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering, 5822 g->is_single_threaded); 5823 return LLVMBuildIntToPtr(g->builder, uncasted_result, get_llvm_type(g, operand_type), ""); 5824 } 5825 5826 static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutable *executable, 5827 IrInstructionAtomicLoad *instruction) 5828 { 5829 LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering); 5830 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); 5831 LLVMValueRef load_inst = gen_load(g, ptr, instruction->ptr->value->type, ""); 5832 LLVMSetOrdering(load_inst, ordering); 5833 return load_inst; 5834 } 5835 5836 static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutable *executable, 5837 IrInstructionAtomicStore *instruction) 5838 { 5839 LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->resolved_ordering); 5840 LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr); 5841 LLVMValueRef value = ir_llvm_value(g, instruction->value); 5842 LLVMValueRef store_inst = gen_store(g, value, ptr, instruction->ptr->value->type); 5843 LLVMSetOrdering(store_inst, ordering); 5844 return nullptr; 5845 } 5846 5847 static LLVMValueRef ir_render_float_op(CodeGen *g, IrExecutable *executable, IrInstructionFloatOp *instruction) { 5848 LLVMValueRef operand = ir_llvm_value(g, instruction->operand); 5849 LLVMValueRef fn_val = get_float_fn(g, instruction->base.value->type, ZigLLVMFnIdFloatOp, instruction->fn_id); 5850 return LLVMBuildCall(g->builder, fn_val, &operand, 1, ""); 5851 } 5852 5853 static LLVMValueRef ir_render_mul_add(CodeGen *g, IrExecutable *executable, IrInstructionMulAdd *instruction) { 5854 LLVMValueRef op1 = ir_llvm_value(g, instruction->op1); 5855 LLVMValueRef op2 = ir_llvm_value(g, instruction->op2); 5856 LLVMValueRef op3 = ir_llvm_value(g, instruction->op3); 5857 assert(instruction->base.value->type->id == ZigTypeIdFloat || 5858 instruction->base.value->type->id == ZigTypeIdVector); 5859 LLVMValueRef fn_val = get_float_fn(g, instruction->base.value->type, ZigLLVMFnIdFMA, BuiltinFnIdMulAdd); 5860 LLVMValueRef args[3] = { 5861 op1, 5862 op2, 5863 op3, 5864 }; 5865 return LLVMBuildCall(g->builder, fn_val, args, 3, ""); 5866 } 5867 5868 static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutable *executable, IrInstructionBswap *instruction) { 5869 LLVMValueRef op = ir_llvm_value(g, instruction->op); 5870 ZigType *expr_type = instruction->base.value->type; 5871 bool is_vector = expr_type->id == ZigTypeIdVector; 5872 ZigType *int_type = is_vector ? expr_type->data.vector.elem_type : expr_type; 5873 assert(int_type->id == ZigTypeIdInt); 5874 if (int_type->data.integral.bit_count % 16 == 0) { 5875 LLVMValueRef fn_val = get_int_builtin_fn(g, expr_type, BuiltinFnIdBswap); 5876 return LLVMBuildCall(g->builder, fn_val, &op, 1, ""); 5877 } 5878 // Not an even number of bytes, so we zext 1 byte, then bswap, shift right 1 byte, truncate 5879 ZigType *extended_type = get_int_type(g, int_type->data.integral.is_signed, 5880 int_type->data.integral.bit_count + 8); 5881 LLVMValueRef shift_amt = LLVMConstInt(get_llvm_type(g, extended_type), 8, false); 5882 if (is_vector) { 5883 extended_type = get_vector_type(g, expr_type->data.vector.len, extended_type); 5884 LLVMValueRef *values = allocate_nonzero<LLVMValueRef>(expr_type->data.vector.len); 5885 for (uint32_t i = 0; i < expr_type->data.vector.len; i += 1) { 5886 values[i] = shift_amt; 5887 } 5888 shift_amt = LLVMConstVector(values, expr_type->data.vector.len); 5889 free(values); 5890 } 5891 // aabbcc 5892 LLVMValueRef extended = LLVMBuildZExt(g->builder, op, get_llvm_type(g, extended_type), ""); 5893 // 00aabbcc 5894 LLVMValueRef fn_val = get_int_builtin_fn(g, extended_type, BuiltinFnIdBswap); 5895 LLVMValueRef swapped = LLVMBuildCall(g->builder, fn_val, &extended, 1, ""); 5896 // ccbbaa00 5897 LLVMValueRef shifted = ZigLLVMBuildLShrExact(g->builder, swapped, shift_amt, ""); 5898 // 00ccbbaa 5899 return LLVMBuildTrunc(g->builder, shifted, get_llvm_type(g, expr_type), ""); 5900 } 5901 5902 static LLVMValueRef ir_render_bit_reverse(CodeGen *g, IrExecutable *executable, IrInstructionBitReverse *instruction) { 5903 LLVMValueRef op = ir_llvm_value(g, instruction->op); 5904 ZigType *int_type = instruction->base.value->type; 5905 assert(int_type->id == ZigTypeIdInt); 5906 LLVMValueRef fn_val = get_int_builtin_fn(g, instruction->base.value->type, BuiltinFnIdBitReverse); 5907 return LLVMBuildCall(g->builder, fn_val, &op, 1, ""); 5908 } 5909 5910 static LLVMValueRef ir_render_vector_to_array(CodeGen *g, IrExecutable *executable, 5911 IrInstructionVectorToArray *instruction) 5912 { 5913 ZigType *array_type = instruction->base.value->type; 5914 assert(array_type->id == ZigTypeIdArray); 5915 assert(handle_is_ptr(array_type)); 5916 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); 5917 LLVMValueRef vector = ir_llvm_value(g, instruction->vector); 5918 5919 ZigType *elem_type = array_type->data.array.child_type; 5920 bool bitcast_ok = elem_type->size_in_bits == elem_type->abi_size * 8; 5921 if (bitcast_ok) { 5922 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, result_loc, 5923 LLVMPointerType(get_llvm_type(g, instruction->vector->value->type), 0), ""); 5924 uint32_t alignment = get_ptr_align(g, instruction->result_loc->value->type); 5925 gen_store_untyped(g, vector, casted_ptr, alignment, false); 5926 } else { 5927 // If the ABI size of the element type is not evenly divisible by size_in_bits, a simple bitcast 5928 // will not work, and we fall back to extractelement. 5929 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 5930 LLVMTypeRef u32_type_ref = LLVMInt32Type(); 5931 LLVMValueRef zero = LLVMConstInt(usize_type_ref, 0, false); 5932 for (uintptr_t i = 0; i < instruction->vector->value->type->data.vector.len; i++) { 5933 LLVMValueRef index_usize = LLVMConstInt(usize_type_ref, i, false); 5934 LLVMValueRef index_u32 = LLVMConstInt(u32_type_ref, i, false); 5935 LLVMValueRef indexes[] = { zero, index_usize }; 5936 LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, result_loc, indexes, 2, ""); 5937 LLVMValueRef elem = LLVMBuildExtractElement(g->builder, vector, index_u32, ""); 5938 LLVMBuildStore(g->builder, elem, elem_ptr); 5939 } 5940 } 5941 return result_loc; 5942 } 5943 5944 static LLVMValueRef ir_render_array_to_vector(CodeGen *g, IrExecutable *executable, 5945 IrInstructionArrayToVector *instruction) 5946 { 5947 ZigType *vector_type = instruction->base.value->type; 5948 assert(vector_type->id == ZigTypeIdVector); 5949 assert(!handle_is_ptr(vector_type)); 5950 LLVMValueRef array_ptr = ir_llvm_value(g, instruction->array); 5951 LLVMTypeRef vector_type_ref = get_llvm_type(g, vector_type); 5952 5953 ZigType *elem_type = vector_type->data.vector.elem_type; 5954 bool bitcast_ok = elem_type->size_in_bits == elem_type->abi_size * 8; 5955 if (bitcast_ok) { 5956 LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, array_ptr, 5957 LLVMPointerType(vector_type_ref, 0), ""); 5958 ZigType *array_type = instruction->array->value->type; 5959 assert(array_type->id == ZigTypeIdArray); 5960 uint32_t alignment = get_abi_alignment(g, array_type->data.array.child_type); 5961 return gen_load_untyped(g, casted_ptr, alignment, false, ""); 5962 } else { 5963 // If the ABI size of the element type is not evenly divisible by size_in_bits, a simple bitcast 5964 // will not work, and we fall back to insertelement. 5965 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 5966 LLVMTypeRef u32_type_ref = LLVMInt32Type(); 5967 LLVMValueRef zero = LLVMConstInt(usize_type_ref, 0, false); 5968 LLVMValueRef vector = LLVMGetUndef(vector_type_ref); 5969 for (uintptr_t i = 0; i < instruction->base.value->type->data.vector.len; i++) { 5970 LLVMValueRef index_usize = LLVMConstInt(usize_type_ref, i, false); 5971 LLVMValueRef index_u32 = LLVMConstInt(u32_type_ref, i, false); 5972 LLVMValueRef indexes[] = { zero, index_usize }; 5973 LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indexes, 2, ""); 5974 LLVMValueRef elem = LLVMBuildLoad(g->builder, elem_ptr, ""); 5975 vector = LLVMBuildInsertElement(g->builder, vector, elem, index_u32, ""); 5976 } 5977 return vector; 5978 } 5979 } 5980 5981 static LLVMValueRef ir_render_assert_zero(CodeGen *g, IrExecutable *executable, 5982 IrInstructionAssertZero *instruction) 5983 { 5984 LLVMValueRef target = ir_llvm_value(g, instruction->target); 5985 ZigType *int_type = instruction->target->value->type; 5986 if (ir_want_runtime_safety(g, &instruction->base)) { 5987 return gen_assert_zero(g, target, int_type); 5988 } 5989 return nullptr; 5990 } 5991 5992 static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutable *executable, 5993 IrInstructionAssertNonNull *instruction) 5994 { 5995 LLVMValueRef target = ir_llvm_value(g, instruction->target); 5996 ZigType *target_type = instruction->target->value->type; 5997 5998 if (target_type->id == ZigTypeIdPointer) { 5999 assert(target_type->data.pointer.ptr_len == PtrLenC); 6000 LLVMValueRef non_null_bit = LLVMBuildICmp(g->builder, LLVMIntNE, target, 6001 LLVMConstNull(get_llvm_type(g, target_type)), ""); 6002 6003 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "AssertNonNullFail"); 6004 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "AssertNonNullOk"); 6005 LLVMBuildCondBr(g->builder, non_null_bit, ok_block, fail_block); 6006 6007 LLVMPositionBuilderAtEnd(g->builder, fail_block); 6008 gen_assertion(g, PanicMsgIdUnwrapOptionalFail, &instruction->base); 6009 6010 LLVMPositionBuilderAtEnd(g->builder, ok_block); 6011 } else { 6012 zig_unreachable(); 6013 } 6014 return nullptr; 6015 } 6016 6017 static LLVMValueRef ir_render_suspend_begin(CodeGen *g, IrExecutable *executable, 6018 IrInstructionSuspendBegin *instruction) 6019 { 6020 if (fn_is_async(g->cur_fn)) { 6021 instruction->resume_bb = gen_suspend_begin(g, "SuspendResume"); 6022 } 6023 return nullptr; 6024 } 6025 6026 static LLVMValueRef ir_render_suspend_finish(CodeGen *g, IrExecutable *executable, 6027 IrInstructionSuspendFinish *instruction) 6028 { 6029 LLVMBuildRetVoid(g->builder); 6030 6031 LLVMPositionBuilderAtEnd(g->builder, instruction->begin->resume_bb); 6032 if (ir_want_runtime_safety(g, &instruction->base)) { 6033 LLVMBuildStore(g->builder, g->cur_bad_not_suspended_index, g->cur_async_resume_index_ptr); 6034 } 6035 render_async_var_decls(g, instruction->base.scope); 6036 return nullptr; 6037 } 6038 6039 static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstruction *source_instr, 6040 LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type, 6041 LLVMValueRef result_loc, bool non_async) 6042 { 6043 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 6044 LLVMValueRef their_result_ptr = nullptr; 6045 if (type_has_bits(result_type) && (non_async || result_loc != nullptr)) { 6046 LLVMValueRef their_result_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start, ""); 6047 their_result_ptr = LLVMBuildLoad(g->builder, their_result_ptr_ptr, ""); 6048 if (result_loc != nullptr) { 6049 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); 6050 LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, result_loc, ptr_u8, ""); 6051 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, their_result_ptr, ptr_u8, ""); 6052 bool is_volatile = false; 6053 uint32_t abi_align = get_abi_alignment(g, result_type); 6054 LLVMValueRef byte_count_val = LLVMConstInt(usize_type_ref, type_size(g, result_type), false); 6055 ZigLLVMBuildMemCpy(g->builder, 6056 dest_ptr_casted, abi_align, 6057 src_ptr_casted, abi_align, byte_count_val, is_volatile); 6058 } 6059 } 6060 if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) { 6061 LLVMValueRef their_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, 6062 frame_index_trace_arg(g, result_type), ""); 6063 LLVMValueRef src_trace_ptr = LLVMBuildLoad(g->builder, their_trace_ptr_ptr, ""); 6064 bool is_llvm_alloca; 6065 LLVMValueRef dest_trace_ptr = get_cur_err_ret_trace_val(g, source_instr->scope, &is_llvm_alloca); 6066 LLVMValueRef args[] = { dest_trace_ptr, src_trace_ptr }; 6067 ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2, 6068 get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, ""); 6069 } 6070 if (non_async && type_has_bits(result_type)) { 6071 LLVMValueRef result_ptr = (result_loc == nullptr) ? their_result_ptr : result_loc; 6072 return get_handle_value(g, result_ptr, result_type, ptr_result_type); 6073 } else { 6074 return nullptr; 6075 } 6076 } 6077 6078 static LLVMValueRef ir_render_await(CodeGen *g, IrExecutable *executable, IrInstructionAwaitGen *instruction) { 6079 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 6080 LLVMValueRef zero = LLVMConstNull(usize_type_ref); 6081 LLVMValueRef target_frame_ptr = ir_llvm_value(g, instruction->frame); 6082 ZigType *result_type = instruction->base.value->type; 6083 ZigType *ptr_result_type = get_pointer_to_type(g, result_type, true); 6084 6085 LLVMValueRef result_loc = (instruction->result_loc == nullptr) ? 6086 nullptr : ir_llvm_value(g, instruction->result_loc); 6087 6088 if (instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn)) { 6089 return gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type, 6090 ptr_result_type, result_loc, true); 6091 } 6092 6093 // Prepare to be suspended 6094 LLVMBasicBlockRef resume_bb = gen_suspend_begin(g, "AwaitResume"); 6095 LLVMBasicBlockRef end_bb = LLVMAppendBasicBlock(g->cur_fn_val, "AwaitEnd"); 6096 6097 // At this point resuming the function will continue from resume_bb. 6098 // This code is as if it is running inside the suspend block. 6099 6100 // supply the awaiter return pointer 6101 if (type_has_bits(result_type)) { 6102 LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start + 1, ""); 6103 if (result_loc == nullptr) { 6104 // no copy needed 6105 LLVMBuildStore(g->builder, LLVMConstNull(LLVMGetElementType(LLVMTypeOf(awaiter_ret_ptr_ptr))), 6106 awaiter_ret_ptr_ptr); 6107 } else { 6108 LLVMBuildStore(g->builder, result_loc, awaiter_ret_ptr_ptr); 6109 } 6110 } 6111 6112 // supply the error return trace pointer 6113 if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) { 6114 bool is_llvm_alloca; 6115 LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca); 6116 assert(my_err_ret_trace_val != nullptr); 6117 LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, 6118 frame_index_trace_arg(g, result_type) + 1, ""); 6119 LLVMBuildStore(g->builder, my_err_ret_trace_val, err_ret_trace_ptr_ptr); 6120 } 6121 6122 // caller's own frame pointer 6123 LLVMValueRef awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, ""); 6124 LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_awaiter_index, ""); 6125 LLVMValueRef prev_val = gen_maybe_atomic_op(g, LLVMAtomicRMWBinOpXchg, awaiter_ptr, awaiter_init_val, 6126 LLVMAtomicOrderingRelease); 6127 6128 LLVMBasicBlockRef bad_await_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadAwait"); 6129 LLVMBasicBlockRef complete_suspend_block = LLVMAppendBasicBlock(g->cur_fn_val, "CompleteSuspend"); 6130 LLVMBasicBlockRef early_return_block = LLVMAppendBasicBlock(g->cur_fn_val, "EarlyReturn"); 6131 6132 LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref); 6133 LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, prev_val, bad_await_block, 2); 6134 6135 LLVMAddCase(switch_instr, zero, complete_suspend_block); 6136 LLVMAddCase(switch_instr, all_ones, early_return_block); 6137 6138 // We discovered that another awaiter was already here. 6139 LLVMPositionBuilderAtEnd(g->builder, bad_await_block); 6140 gen_assertion(g, PanicMsgIdBadAwait, &instruction->base); 6141 6142 // Rely on the target to resume us from suspension. 6143 LLVMPositionBuilderAtEnd(g->builder, complete_suspend_block); 6144 LLVMBuildRetVoid(g->builder); 6145 6146 // Early return: The async function has already completed. We must copy the result and 6147 // the error return trace if applicable. 6148 LLVMPositionBuilderAtEnd(g->builder, early_return_block); 6149 gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type, ptr_result_type, 6150 result_loc, false); 6151 LLVMBuildBr(g->builder, end_bb); 6152 6153 LLVMPositionBuilderAtEnd(g->builder, resume_bb); 6154 gen_assert_resume_id(g, &instruction->base, ResumeIdReturn, PanicMsgIdResumedAnAwaitingFn, nullptr); 6155 LLVMBuildBr(g->builder, end_bb); 6156 6157 LLVMPositionBuilderAtEnd(g->builder, end_bb); 6158 // Rely on the spill for the llvm_value to be populated. 6159 // See the implementation of ir_llvm_value. 6160 return nullptr; 6161 } 6162 6163 static LLVMValueRef ir_render_resume(CodeGen *g, IrExecutable *executable, IrInstructionResume *instruction) { 6164 LLVMValueRef frame = ir_llvm_value(g, instruction->frame); 6165 ZigType *frame_type = instruction->frame->value->type; 6166 assert(frame_type->id == ZigTypeIdAnyFrame); 6167 6168 gen_resume(g, nullptr, frame, ResumeIdManual); 6169 return nullptr; 6170 } 6171 6172 static LLVMValueRef ir_render_frame_size(CodeGen *g, IrExecutable *executable, 6173 IrInstructionFrameSizeGen *instruction) 6174 { 6175 LLVMValueRef fn_val = ir_llvm_value(g, instruction->fn); 6176 return gen_frame_size(g, fn_val); 6177 } 6178 6179 static LLVMValueRef ir_render_spill_begin(CodeGen *g, IrExecutable *executable, 6180 IrInstructionSpillBegin *instruction) 6181 { 6182 if (!fn_is_async(g->cur_fn)) 6183 return nullptr; 6184 6185 switch (instruction->spill_id) { 6186 case SpillIdInvalid: 6187 zig_unreachable(); 6188 case SpillIdRetErrCode: { 6189 LLVMValueRef operand = ir_llvm_value(g, instruction->operand); 6190 LLVMValueRef ptr = ir_llvm_value(g, g->cur_fn->err_code_spill); 6191 LLVMBuildStore(g->builder, operand, ptr); 6192 return nullptr; 6193 } 6194 6195 } 6196 zig_unreachable(); 6197 } 6198 6199 static LLVMValueRef ir_render_spill_end(CodeGen *g, IrExecutable *executable, IrInstructionSpillEnd *instruction) { 6200 if (!fn_is_async(g->cur_fn)) 6201 return ir_llvm_value(g, instruction->begin->operand); 6202 6203 switch (instruction->begin->spill_id) { 6204 case SpillIdInvalid: 6205 zig_unreachable(); 6206 case SpillIdRetErrCode: { 6207 LLVMValueRef ptr = ir_llvm_value(g, g->cur_fn->err_code_spill); 6208 return LLVMBuildLoad(g->builder, ptr, ""); 6209 } 6210 6211 } 6212 zig_unreachable(); 6213 } 6214 6215 static LLVMValueRef ir_render_vector_extract_elem(CodeGen *g, IrExecutable *executable, 6216 IrInstructionVectorExtractElem *instruction) 6217 { 6218 LLVMValueRef vector = ir_llvm_value(g, instruction->vector); 6219 LLVMValueRef index = ir_llvm_value(g, instruction->index); 6220 return LLVMBuildExtractElement(g->builder, vector, index, ""); 6221 } 6222 6223 static void set_debug_location(CodeGen *g, IrInstruction *instruction) { 6224 AstNode *source_node = instruction->source_node; 6225 Scope *scope = instruction->scope; 6226 6227 assert(source_node); 6228 assert(scope); 6229 6230 ZigLLVMSetCurrentDebugLocation(g->builder, (int)source_node->line + 1, 6231 (int)source_node->column + 1, get_di_scope(g, scope)); 6232 } 6233 6234 static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, IrInstruction *instruction) { 6235 switch (instruction->id) { 6236 case IrInstructionIdInvalid: 6237 case IrInstructionIdConst: 6238 case IrInstructionIdTypeOf: 6239 case IrInstructionIdFieldPtr: 6240 case IrInstructionIdSetCold: 6241 case IrInstructionIdSetRuntimeSafety: 6242 case IrInstructionIdSetFloatMode: 6243 case IrInstructionIdArrayType: 6244 case IrInstructionIdAnyFrameType: 6245 case IrInstructionIdSliceType: 6246 case IrInstructionIdSizeOf: 6247 case IrInstructionIdSwitchTarget: 6248 case IrInstructionIdContainerInitFields: 6249 case IrInstructionIdCompileErr: 6250 case IrInstructionIdCompileLog: 6251 case IrInstructionIdImport: 6252 case IrInstructionIdCImport: 6253 case IrInstructionIdCInclude: 6254 case IrInstructionIdCDefine: 6255 case IrInstructionIdCUndef: 6256 case IrInstructionIdEmbedFile: 6257 case IrInstructionIdIntType: 6258 case IrInstructionIdVectorType: 6259 case IrInstructionIdMemberCount: 6260 case IrInstructionIdMemberType: 6261 case IrInstructionIdMemberName: 6262 case IrInstructionIdAlignOf: 6263 case IrInstructionIdFnProto: 6264 case IrInstructionIdTestComptime: 6265 case IrInstructionIdCheckSwitchProngs: 6266 case IrInstructionIdCheckStatementIsVoid: 6267 case IrInstructionIdTypeName: 6268 case IrInstructionIdDeclRef: 6269 case IrInstructionIdSwitchVar: 6270 case IrInstructionIdSwitchElseVar: 6271 case IrInstructionIdByteOffsetOf: 6272 case IrInstructionIdBitOffsetOf: 6273 case IrInstructionIdTypeInfo: 6274 case IrInstructionIdType: 6275 case IrInstructionIdHasField: 6276 case IrInstructionIdTypeId: 6277 case IrInstructionIdSetEvalBranchQuota: 6278 case IrInstructionIdPtrType: 6279 case IrInstructionIdOpaqueType: 6280 case IrInstructionIdSetAlignStack: 6281 case IrInstructionIdArgType: 6282 case IrInstructionIdTagType: 6283 case IrInstructionIdExport: 6284 case IrInstructionIdErrorUnion: 6285 case IrInstructionIdAddImplicitReturnType: 6286 case IrInstructionIdIntCast: 6287 case IrInstructionIdFloatCast: 6288 case IrInstructionIdIntToFloat: 6289 case IrInstructionIdFloatToInt: 6290 case IrInstructionIdBoolToInt: 6291 case IrInstructionIdErrSetCast: 6292 case IrInstructionIdFromBytes: 6293 case IrInstructionIdToBytes: 6294 case IrInstructionIdEnumToInt: 6295 case IrInstructionIdCheckRuntimeScope: 6296 case IrInstructionIdDeclVarSrc: 6297 case IrInstructionIdPtrCastSrc: 6298 case IrInstructionIdCmpxchgSrc: 6299 case IrInstructionIdLoadPtr: 6300 case IrInstructionIdHasDecl: 6301 case IrInstructionIdUndeclaredIdent: 6302 case IrInstructionIdCallExtra: 6303 case IrInstructionIdCallSrc: 6304 case IrInstructionIdCallSrcArgs: 6305 case IrInstructionIdAllocaSrc: 6306 case IrInstructionIdEndExpr: 6307 case IrInstructionIdImplicitCast: 6308 case IrInstructionIdResolveResult: 6309 case IrInstructionIdResetResult: 6310 case IrInstructionIdContainerInitList: 6311 case IrInstructionIdSliceSrc: 6312 case IrInstructionIdRef: 6313 case IrInstructionIdBitCastSrc: 6314 case IrInstructionIdTestErrSrc: 6315 case IrInstructionIdUnionInitNamedField: 6316 case IrInstructionIdFrameType: 6317 case IrInstructionIdFrameSizeSrc: 6318 case IrInstructionIdAllocaGen: 6319 case IrInstructionIdAwaitSrc: 6320 case IrInstructionIdSplatSrc: 6321 case IrInstructionIdMergeErrSets: 6322 case IrInstructionIdAsmSrc: 6323 zig_unreachable(); 6324 6325 case IrInstructionIdDeclVarGen: 6326 return ir_render_decl_var(g, executable, (IrInstructionDeclVarGen *)instruction); 6327 case IrInstructionIdReturn: 6328 return ir_render_return(g, executable, (IrInstructionReturn *)instruction); 6329 case IrInstructionIdBinOp: 6330 return ir_render_bin_op(g, executable, (IrInstructionBinOp *)instruction); 6331 case IrInstructionIdCast: 6332 return ir_render_cast(g, executable, (IrInstructionCast *)instruction); 6333 case IrInstructionIdUnreachable: 6334 return ir_render_unreachable(g, executable, (IrInstructionUnreachable *)instruction); 6335 case IrInstructionIdCondBr: 6336 return ir_render_cond_br(g, executable, (IrInstructionCondBr *)instruction); 6337 case IrInstructionIdBr: 6338 return ir_render_br(g, executable, (IrInstructionBr *)instruction); 6339 case IrInstructionIdUnOp: 6340 return ir_render_un_op(g, executable, (IrInstructionUnOp *)instruction); 6341 case IrInstructionIdLoadPtrGen: 6342 return ir_render_load_ptr(g, executable, (IrInstructionLoadPtrGen *)instruction); 6343 case IrInstructionIdStorePtr: 6344 return ir_render_store_ptr(g, executable, (IrInstructionStorePtr *)instruction); 6345 case IrInstructionIdVectorStoreElem: 6346 return ir_render_vector_store_elem(g, executable, (IrInstructionVectorStoreElem *)instruction); 6347 case IrInstructionIdVarPtr: 6348 return ir_render_var_ptr(g, executable, (IrInstructionVarPtr *)instruction); 6349 case IrInstructionIdReturnPtr: 6350 return ir_render_return_ptr(g, executable, (IrInstructionReturnPtr *)instruction); 6351 case IrInstructionIdElemPtr: 6352 return ir_render_elem_ptr(g, executable, (IrInstructionElemPtr *)instruction); 6353 case IrInstructionIdCallGen: 6354 return ir_render_call(g, executable, (IrInstructionCallGen *)instruction); 6355 case IrInstructionIdStructFieldPtr: 6356 return ir_render_struct_field_ptr(g, executable, (IrInstructionStructFieldPtr *)instruction); 6357 case IrInstructionIdUnionFieldPtr: 6358 return ir_render_union_field_ptr(g, executable, (IrInstructionUnionFieldPtr *)instruction); 6359 case IrInstructionIdAsmGen: 6360 return ir_render_asm_gen(g, executable, (IrInstructionAsmGen *)instruction); 6361 case IrInstructionIdTestNonNull: 6362 return ir_render_test_non_null(g, executable, (IrInstructionTestNonNull *)instruction); 6363 case IrInstructionIdOptionalUnwrapPtr: 6364 return ir_render_optional_unwrap_ptr(g, executable, (IrInstructionOptionalUnwrapPtr *)instruction); 6365 case IrInstructionIdClz: 6366 return ir_render_clz(g, executable, (IrInstructionClz *)instruction); 6367 case IrInstructionIdCtz: 6368 return ir_render_ctz(g, executable, (IrInstructionCtz *)instruction); 6369 case IrInstructionIdPopCount: 6370 return ir_render_pop_count(g, executable, (IrInstructionPopCount *)instruction); 6371 case IrInstructionIdSwitchBr: 6372 return ir_render_switch_br(g, executable, (IrInstructionSwitchBr *)instruction); 6373 case IrInstructionIdBswap: 6374 return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction); 6375 case IrInstructionIdBitReverse: 6376 return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction); 6377 case IrInstructionIdPhi: 6378 return ir_render_phi(g, executable, (IrInstructionPhi *)instruction); 6379 case IrInstructionIdRefGen: 6380 return ir_render_ref(g, executable, (IrInstructionRefGen *)instruction); 6381 case IrInstructionIdErrName: 6382 return ir_render_err_name(g, executable, (IrInstructionErrName *)instruction); 6383 case IrInstructionIdCmpxchgGen: 6384 return ir_render_cmpxchg(g, executable, (IrInstructionCmpxchgGen *)instruction); 6385 case IrInstructionIdFence: 6386 return ir_render_fence(g, executable, (IrInstructionFence *)instruction); 6387 case IrInstructionIdTruncate: 6388 return ir_render_truncate(g, executable, (IrInstructionTruncate *)instruction); 6389 case IrInstructionIdBoolNot: 6390 return ir_render_bool_not(g, executable, (IrInstructionBoolNot *)instruction); 6391 case IrInstructionIdMemset: 6392 return ir_render_memset(g, executable, (IrInstructionMemset *)instruction); 6393 case IrInstructionIdMemcpy: 6394 return ir_render_memcpy(g, executable, (IrInstructionMemcpy *)instruction); 6395 case IrInstructionIdSliceGen: 6396 return ir_render_slice(g, executable, (IrInstructionSliceGen *)instruction); 6397 case IrInstructionIdBreakpoint: 6398 return ir_render_breakpoint(g, executable, (IrInstructionBreakpoint *)instruction); 6399 case IrInstructionIdReturnAddress: 6400 return ir_render_return_address(g, executable, (IrInstructionReturnAddress *)instruction); 6401 case IrInstructionIdFrameAddress: 6402 return ir_render_frame_address(g, executable, (IrInstructionFrameAddress *)instruction); 6403 case IrInstructionIdFrameHandle: 6404 return ir_render_handle(g, executable, (IrInstructionFrameHandle *)instruction); 6405 case IrInstructionIdOverflowOp: 6406 return ir_render_overflow_op(g, executable, (IrInstructionOverflowOp *)instruction); 6407 case IrInstructionIdTestErrGen: 6408 return ir_render_test_err(g, executable, (IrInstructionTestErrGen *)instruction); 6409 case IrInstructionIdUnwrapErrCode: 6410 return ir_render_unwrap_err_code(g, executable, (IrInstructionUnwrapErrCode *)instruction); 6411 case IrInstructionIdUnwrapErrPayload: 6412 return ir_render_unwrap_err_payload(g, executable, (IrInstructionUnwrapErrPayload *)instruction); 6413 case IrInstructionIdOptionalWrap: 6414 return ir_render_optional_wrap(g, executable, (IrInstructionOptionalWrap *)instruction); 6415 case IrInstructionIdErrWrapCode: 6416 return ir_render_err_wrap_code(g, executable, (IrInstructionErrWrapCode *)instruction); 6417 case IrInstructionIdErrWrapPayload: 6418 return ir_render_err_wrap_payload(g, executable, (IrInstructionErrWrapPayload *)instruction); 6419 case IrInstructionIdUnionTag: 6420 return ir_render_union_tag(g, executable, (IrInstructionUnionTag *)instruction); 6421 case IrInstructionIdPtrCastGen: 6422 return ir_render_ptr_cast(g, executable, (IrInstructionPtrCastGen *)instruction); 6423 case IrInstructionIdBitCastGen: 6424 return ir_render_bit_cast(g, executable, (IrInstructionBitCastGen *)instruction); 6425 case IrInstructionIdWidenOrShorten: 6426 return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction); 6427 case IrInstructionIdPtrToInt: 6428 return ir_render_ptr_to_int(g, executable, (IrInstructionPtrToInt *)instruction); 6429 case IrInstructionIdIntToPtr: 6430 return ir_render_int_to_ptr(g, executable, (IrInstructionIntToPtr *)instruction); 6431 case IrInstructionIdIntToEnum: 6432 return ir_render_int_to_enum(g, executable, (IrInstructionIntToEnum *)instruction); 6433 case IrInstructionIdIntToErr: 6434 return ir_render_int_to_err(g, executable, (IrInstructionIntToErr *)instruction); 6435 case IrInstructionIdErrToInt: 6436 return ir_render_err_to_int(g, executable, (IrInstructionErrToInt *)instruction); 6437 case IrInstructionIdPanic: 6438 return ir_render_panic(g, executable, (IrInstructionPanic *)instruction); 6439 case IrInstructionIdTagName: 6440 return ir_render_enum_tag_name(g, executable, (IrInstructionTagName *)instruction); 6441 case IrInstructionIdFieldParentPtr: 6442 return ir_render_field_parent_ptr(g, executable, (IrInstructionFieldParentPtr *)instruction); 6443 case IrInstructionIdAlignCast: 6444 return ir_render_align_cast(g, executable, (IrInstructionAlignCast *)instruction); 6445 case IrInstructionIdErrorReturnTrace: 6446 return ir_render_error_return_trace(g, executable, (IrInstructionErrorReturnTrace *)instruction); 6447 case IrInstructionIdAtomicRmw: 6448 return ir_render_atomic_rmw(g, executable, (IrInstructionAtomicRmw *)instruction); 6449 case IrInstructionIdAtomicLoad: 6450 return ir_render_atomic_load(g, executable, (IrInstructionAtomicLoad *)instruction); 6451 case IrInstructionIdAtomicStore: 6452 return ir_render_atomic_store(g, executable, (IrInstructionAtomicStore *)instruction); 6453 case IrInstructionIdSaveErrRetAddr: 6454 return ir_render_save_err_ret_addr(g, executable, (IrInstructionSaveErrRetAddr *)instruction); 6455 case IrInstructionIdFloatOp: 6456 return ir_render_float_op(g, executable, (IrInstructionFloatOp *)instruction); 6457 case IrInstructionIdMulAdd: 6458 return ir_render_mul_add(g, executable, (IrInstructionMulAdd *)instruction); 6459 case IrInstructionIdArrayToVector: 6460 return ir_render_array_to_vector(g, executable, (IrInstructionArrayToVector *)instruction); 6461 case IrInstructionIdVectorToArray: 6462 return ir_render_vector_to_array(g, executable, (IrInstructionVectorToArray *)instruction); 6463 case IrInstructionIdAssertZero: 6464 return ir_render_assert_zero(g, executable, (IrInstructionAssertZero *)instruction); 6465 case IrInstructionIdAssertNonNull: 6466 return ir_render_assert_non_null(g, executable, (IrInstructionAssertNonNull *)instruction); 6467 case IrInstructionIdResizeSlice: 6468 return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction); 6469 case IrInstructionIdPtrOfArrayToSlice: 6470 return ir_render_ptr_of_array_to_slice(g, executable, (IrInstructionPtrOfArrayToSlice *)instruction); 6471 case IrInstructionIdSuspendBegin: 6472 return ir_render_suspend_begin(g, executable, (IrInstructionSuspendBegin *)instruction); 6473 case IrInstructionIdSuspendFinish: 6474 return ir_render_suspend_finish(g, executable, (IrInstructionSuspendFinish *)instruction); 6475 case IrInstructionIdResume: 6476 return ir_render_resume(g, executable, (IrInstructionResume *)instruction); 6477 case IrInstructionIdFrameSizeGen: 6478 return ir_render_frame_size(g, executable, (IrInstructionFrameSizeGen *)instruction); 6479 case IrInstructionIdAwaitGen: 6480 return ir_render_await(g, executable, (IrInstructionAwaitGen *)instruction); 6481 case IrInstructionIdSpillBegin: 6482 return ir_render_spill_begin(g, executable, (IrInstructionSpillBegin *)instruction); 6483 case IrInstructionIdSpillEnd: 6484 return ir_render_spill_end(g, executable, (IrInstructionSpillEnd *)instruction); 6485 case IrInstructionIdShuffleVector: 6486 return ir_render_shuffle_vector(g, executable, (IrInstructionShuffleVector *) instruction); 6487 case IrInstructionIdSplatGen: 6488 return ir_render_splat(g, executable, (IrInstructionSplatGen *) instruction); 6489 case IrInstructionIdVectorExtractElem: 6490 return ir_render_vector_extract_elem(g, executable, (IrInstructionVectorExtractElem *) instruction); 6491 } 6492 zig_unreachable(); 6493 } 6494 6495 static void ir_render(CodeGen *g, ZigFn *fn_entry) { 6496 assert(fn_entry); 6497 6498 IrExecutable *executable = &fn_entry->analyzed_executable; 6499 assert(executable->basic_block_list.length > 0); 6500 6501 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) { 6502 IrBasicBlock *current_block = executable->basic_block_list.at(block_i); 6503 if (get_scope_typeof(current_block->scope) != nullptr) { 6504 LLVMBuildBr(g->builder, current_block->llvm_block); 6505 } 6506 assert(current_block->llvm_block); 6507 LLVMPositionBuilderAtEnd(g->builder, current_block->llvm_block); 6508 for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) { 6509 IrInstruction *instruction = current_block->instruction_list.at(instr_i); 6510 if (instruction->ref_count == 0 && !ir_has_side_effects(instruction)) 6511 continue; 6512 if (get_scope_typeof(instruction->scope) != nullptr) 6513 continue; 6514 6515 if (!g->strip_debug_symbols) { 6516 set_debug_location(g, instruction); 6517 } 6518 instruction->llvm_value = ir_render_instruction(g, executable, instruction); 6519 if (instruction->spill != nullptr) { 6520 LLVMValueRef spill_ptr = ir_llvm_value(g, instruction->spill); 6521 gen_assign_raw(g, spill_ptr, instruction->spill->value->type, instruction->llvm_value); 6522 instruction->llvm_value = nullptr; 6523 } 6524 } 6525 current_block->llvm_exit_block = LLVMGetInsertBlock(g->builder); 6526 } 6527 } 6528 6529 static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ZigValue *struct_const_val, size_t field_index); 6530 static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ZigValue *array_const_val, size_t index); 6531 static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ZigValue *union_const_val); 6532 static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ZigValue *err_union_const_val); 6533 static LLVMValueRef gen_const_ptr_err_union_payload_recursive(CodeGen *g, ZigValue *err_union_const_val); 6534 static LLVMValueRef gen_const_ptr_optional_payload_recursive(CodeGen *g, ZigValue *optional_const_val); 6535 6536 static LLVMValueRef gen_parent_ptr(CodeGen *g, ZigValue *val, ConstParent *parent) { 6537 switch (parent->id) { 6538 case ConstParentIdNone: 6539 render_const_val(g, val, ""); 6540 render_const_val_global(g, val, ""); 6541 return val->llvm_global; 6542 case ConstParentIdStruct: 6543 return gen_const_ptr_struct_recursive(g, parent->data.p_struct.struct_val, 6544 parent->data.p_struct.field_index); 6545 case ConstParentIdErrUnionCode: 6546 return gen_const_ptr_err_union_code_recursive(g, parent->data.p_err_union_code.err_union_val); 6547 case ConstParentIdErrUnionPayload: 6548 return gen_const_ptr_err_union_payload_recursive(g, parent->data.p_err_union_payload.err_union_val); 6549 case ConstParentIdOptionalPayload: 6550 return gen_const_ptr_optional_payload_recursive(g, parent->data.p_optional_payload.optional_val); 6551 case ConstParentIdArray: 6552 return gen_const_ptr_array_recursive(g, parent->data.p_array.array_val, 6553 parent->data.p_array.elem_index); 6554 case ConstParentIdUnion: 6555 return gen_const_ptr_union_recursive(g, parent->data.p_union.union_val); 6556 case ConstParentIdScalar: 6557 render_const_val(g, parent->data.p_scalar.scalar_val, ""); 6558 render_const_val_global(g, parent->data.p_scalar.scalar_val, ""); 6559 return parent->data.p_scalar.scalar_val->llvm_global; 6560 } 6561 zig_unreachable(); 6562 } 6563 6564 static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ZigValue *array_const_val, size_t index) { 6565 expand_undef_array(g, array_const_val); 6566 ConstParent *parent = &array_const_val->parent; 6567 LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent); 6568 6569 LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr))); 6570 if (el_type == LLVMArrayTypeKind) { 6571 ZigType *usize = g->builtin_types.entry_usize; 6572 LLVMValueRef indices[] = { 6573 LLVMConstNull(usize->llvm_type), 6574 LLVMConstInt(usize->llvm_type, index, false), 6575 }; 6576 return LLVMConstInBoundsGEP(base_ptr, indices, 2); 6577 } else if (el_type == LLVMStructTypeKind) { 6578 ZigType *u32 = g->builtin_types.entry_u32; 6579 LLVMValueRef indices[] = { 6580 LLVMConstNull(get_llvm_type(g, u32)), 6581 LLVMConstInt(get_llvm_type(g, u32), index, false), 6582 }; 6583 return LLVMConstInBoundsGEP(base_ptr, indices, 2); 6584 } else { 6585 assert(parent->id == ConstParentIdScalar); 6586 return base_ptr; 6587 } 6588 } 6589 6590 static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ZigValue *struct_const_val, size_t field_index) { 6591 ConstParent *parent = &struct_const_val->parent; 6592 LLVMValueRef base_ptr = gen_parent_ptr(g, struct_const_val, parent); 6593 6594 ZigType *u32 = g->builtin_types.entry_u32; 6595 LLVMValueRef indices[] = { 6596 LLVMConstNull(get_llvm_type(g, u32)), 6597 LLVMConstInt(get_llvm_type(g, u32), field_index, false), 6598 }; 6599 return LLVMConstInBoundsGEP(base_ptr, indices, 2); 6600 } 6601 6602 static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ZigValue *err_union_const_val) { 6603 ConstParent *parent = &err_union_const_val->parent; 6604 LLVMValueRef base_ptr = gen_parent_ptr(g, err_union_const_val, parent); 6605 6606 ZigType *u32 = g->builtin_types.entry_u32; 6607 LLVMValueRef indices[] = { 6608 LLVMConstNull(get_llvm_type(g, u32)), 6609 LLVMConstInt(get_llvm_type(g, u32), err_union_err_index, false), 6610 }; 6611 return LLVMConstInBoundsGEP(base_ptr, indices, 2); 6612 } 6613 6614 static LLVMValueRef gen_const_ptr_err_union_payload_recursive(CodeGen *g, ZigValue *err_union_const_val) { 6615 ConstParent *parent = &err_union_const_val->parent; 6616 LLVMValueRef base_ptr = gen_parent_ptr(g, err_union_const_val, parent); 6617 6618 ZigType *u32 = g->builtin_types.entry_u32; 6619 LLVMValueRef indices[] = { 6620 LLVMConstNull(get_llvm_type(g, u32)), 6621 LLVMConstInt(get_llvm_type(g, u32), err_union_payload_index, false), 6622 }; 6623 return LLVMConstInBoundsGEP(base_ptr, indices, 2); 6624 } 6625 6626 static LLVMValueRef gen_const_ptr_optional_payload_recursive(CodeGen *g, ZigValue *optional_const_val) { 6627 ConstParent *parent = &optional_const_val->parent; 6628 LLVMValueRef base_ptr = gen_parent_ptr(g, optional_const_val, parent); 6629 6630 ZigType *u32 = g->builtin_types.entry_u32; 6631 LLVMValueRef indices[] = { 6632 LLVMConstNull(get_llvm_type(g, u32)), 6633 LLVMConstInt(get_llvm_type(g, u32), maybe_child_index, false), 6634 }; 6635 return LLVMConstInBoundsGEP(base_ptr, indices, 2); 6636 } 6637 6638 static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ZigValue *union_const_val) { 6639 ConstParent *parent = &union_const_val->parent; 6640 LLVMValueRef base_ptr = gen_parent_ptr(g, union_const_val, parent); 6641 6642 // Slot in the structure where the payload is stored, if equal to SIZE_MAX 6643 // the union has no tag and a single field and is collapsed into the field 6644 // itself 6645 size_t union_payload_index = union_const_val->type->data.unionation.gen_union_index; 6646 6647 ZigType *u32 = g->builtin_types.entry_u32; 6648 LLVMValueRef indices[] = { 6649 LLVMConstNull(get_llvm_type(g, u32)), 6650 LLVMConstInt(get_llvm_type(g, u32), union_payload_index, false), 6651 }; 6652 return LLVMConstInBoundsGEP(base_ptr, indices, (union_payload_index != SIZE_MAX) ? 2 : 1); 6653 } 6654 6655 static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ZigValue *const_val) { 6656 switch (const_val->special) { 6657 case ConstValSpecialLazy: 6658 case ConstValSpecialRuntime: 6659 zig_unreachable(); 6660 case ConstValSpecialUndef: 6661 return LLVMConstInt(big_int_type_ref, 0, false); 6662 case ConstValSpecialStatic: 6663 break; 6664 } 6665 6666 ZigType *type_entry = const_val->type; 6667 assert(type_has_bits(type_entry)); 6668 switch (type_entry->id) { 6669 case ZigTypeIdInvalid: 6670 case ZigTypeIdMetaType: 6671 case ZigTypeIdUnreachable: 6672 case ZigTypeIdComptimeFloat: 6673 case ZigTypeIdComptimeInt: 6674 case ZigTypeIdEnumLiteral: 6675 case ZigTypeIdUndefined: 6676 case ZigTypeIdNull: 6677 case ZigTypeIdErrorUnion: 6678 case ZigTypeIdErrorSet: 6679 case ZigTypeIdBoundFn: 6680 case ZigTypeIdVoid: 6681 case ZigTypeIdOpaque: 6682 zig_unreachable(); 6683 case ZigTypeIdBool: 6684 return LLVMConstInt(big_int_type_ref, const_val->data.x_bool ? 1 : 0, false); 6685 case ZigTypeIdEnum: 6686 { 6687 assert(type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr); 6688 LLVMValueRef int_val = gen_const_val(g, const_val, ""); 6689 return LLVMConstZExt(int_val, big_int_type_ref); 6690 } 6691 case ZigTypeIdInt: 6692 { 6693 LLVMValueRef int_val = gen_const_val(g, const_val, ""); 6694 return LLVMConstZExt(int_val, big_int_type_ref); 6695 } 6696 case ZigTypeIdFloat: 6697 { 6698 LLVMValueRef float_val = gen_const_val(g, const_val, ""); 6699 LLVMValueRef int_val = LLVMConstFPToUI(float_val, 6700 LLVMIntType((unsigned)type_entry->data.floating.bit_count)); 6701 return LLVMConstZExt(int_val, big_int_type_ref); 6702 } 6703 case ZigTypeIdPointer: 6704 case ZigTypeIdFn: 6705 case ZigTypeIdOptional: 6706 { 6707 LLVMValueRef ptr_val = gen_const_val(g, const_val, ""); 6708 LLVMValueRef ptr_size_int_val = LLVMConstPtrToInt(ptr_val, g->builtin_types.entry_usize->llvm_type); 6709 return LLVMConstZExt(ptr_size_int_val, big_int_type_ref); 6710 } 6711 case ZigTypeIdArray: { 6712 LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false); 6713 if (const_val->data.x_array.special == ConstArraySpecialUndef) { 6714 return val; 6715 } 6716 expand_undef_array(g, const_val); 6717 bool is_big_endian = g->is_big_endian; // TODO get endianness from struct type 6718 uint32_t packed_bits_size = type_size_bits(g, type_entry->data.array.child_type); 6719 size_t used_bits = 0; 6720 for (size_t i = 0; i < type_entry->data.array.len; i += 1) { 6721 ZigValue *elem_val = &const_val->data.x_array.data.s_none.elements[i]; 6722 LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, elem_val); 6723 6724 if (is_big_endian) { 6725 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, packed_bits_size, false); 6726 val = LLVMConstShl(val, shift_amt); 6727 val = LLVMConstOr(val, child_val); 6728 } else { 6729 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, used_bits, false); 6730 LLVMValueRef child_val_shifted = LLVMConstShl(child_val, shift_amt); 6731 val = LLVMConstOr(val, child_val_shifted); 6732 used_bits += packed_bits_size; 6733 } 6734 } 6735 return val; 6736 } 6737 case ZigTypeIdVector: 6738 zig_panic("TODO bit pack a vector"); 6739 case ZigTypeIdUnion: 6740 zig_panic("TODO bit pack a union"); 6741 case ZigTypeIdStruct: 6742 { 6743 assert(type_entry->data.structure.layout == ContainerLayoutPacked); 6744 bool is_big_endian = g->is_big_endian; // TODO get endianness from struct type 6745 6746 LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false); 6747 size_t used_bits = 0; 6748 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { 6749 TypeStructField *field = type_entry->data.structure.fields[i]; 6750 if (field->gen_index == SIZE_MAX) { 6751 continue; 6752 } 6753 LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, const_val->data.x_struct.fields[i]); 6754 uint32_t packed_bits_size = type_size_bits(g, field->type_entry); 6755 if (is_big_endian) { 6756 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, packed_bits_size, false); 6757 val = LLVMConstShl(val, shift_amt); 6758 val = LLVMConstOr(val, child_val); 6759 } else { 6760 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, used_bits, false); 6761 LLVMValueRef child_val_shifted = LLVMConstShl(child_val, shift_amt); 6762 val = LLVMConstOr(val, child_val_shifted); 6763 used_bits += packed_bits_size; 6764 } 6765 } 6766 return val; 6767 } 6768 case ZigTypeIdFnFrame: 6769 zig_panic("TODO bit pack an async function frame"); 6770 case ZigTypeIdAnyFrame: 6771 zig_panic("TODO bit pack an anyframe"); 6772 } 6773 zig_unreachable(); 6774 } 6775 6776 // We have this because union constants can't be represented by the official union type, 6777 // and this property bubbles up in whatever aggregate type contains a union constant 6778 static bool is_llvm_value_unnamed_type(CodeGen *g, ZigType *type_entry, LLVMValueRef val) { 6779 return LLVMTypeOf(val) != get_llvm_type(g, type_entry); 6780 } 6781 6782 static LLVMValueRef gen_const_val_ptr(CodeGen *g, ZigValue *const_val, const char *name) { 6783 switch (const_val->data.x_ptr.special) { 6784 case ConstPtrSpecialInvalid: 6785 case ConstPtrSpecialDiscard: 6786 zig_unreachable(); 6787 case ConstPtrSpecialRef: 6788 { 6789 ZigValue *pointee = const_val->data.x_ptr.data.ref.pointee; 6790 render_const_val(g, pointee, ""); 6791 render_const_val_global(g, pointee, ""); 6792 const_val->llvm_value = LLVMConstBitCast(pointee->llvm_global, 6793 get_llvm_type(g, const_val->type)); 6794 return const_val->llvm_value; 6795 } 6796 case ConstPtrSpecialBaseArray: 6797 { 6798 ZigValue *array_const_val = const_val->data.x_ptr.data.base_array.array_val; 6799 assert(array_const_val->type->id == ZigTypeIdArray); 6800 if (!type_has_bits(array_const_val->type)) { 6801 if (array_const_val->type->data.array.sentinel != nullptr) { 6802 ZigValue *pointee = array_const_val->type->data.array.sentinel; 6803 render_const_val(g, pointee, ""); 6804 render_const_val_global(g, pointee, ""); 6805 const_val->llvm_value = LLVMConstBitCast(pointee->llvm_global, 6806 get_llvm_type(g, const_val->type)); 6807 return const_val->llvm_value; 6808 } else { 6809 // make this a null pointer 6810 ZigType *usize = g->builtin_types.entry_usize; 6811 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), 6812 get_llvm_type(g, const_val->type)); 6813 return const_val->llvm_value; 6814 } 6815 } 6816 size_t elem_index = const_val->data.x_ptr.data.base_array.elem_index; 6817 LLVMValueRef uncasted_ptr_val = gen_const_ptr_array_recursive(g, array_const_val, elem_index); 6818 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type)); 6819 const_val->llvm_value = ptr_val; 6820 return ptr_val; 6821 } 6822 case ConstPtrSpecialBaseStruct: 6823 { 6824 ZigValue *struct_const_val = const_val->data.x_ptr.data.base_struct.struct_val; 6825 assert(struct_const_val->type->id == ZigTypeIdStruct); 6826 if (!type_has_bits(struct_const_val->type)) { 6827 // make this a null pointer 6828 ZigType *usize = g->builtin_types.entry_usize; 6829 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), 6830 get_llvm_type(g, const_val->type)); 6831 return const_val->llvm_value; 6832 } 6833 size_t src_field_index = const_val->data.x_ptr.data.base_struct.field_index; 6834 size_t gen_field_index = struct_const_val->type->data.structure.fields[src_field_index]->gen_index; 6835 LLVMValueRef uncasted_ptr_val = gen_const_ptr_struct_recursive(g, struct_const_val, 6836 gen_field_index); 6837 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type)); 6838 const_val->llvm_value = ptr_val; 6839 return ptr_val; 6840 } 6841 case ConstPtrSpecialBaseErrorUnionCode: 6842 { 6843 ZigValue *err_union_const_val = const_val->data.x_ptr.data.base_err_union_code.err_union_val; 6844 assert(err_union_const_val->type->id == ZigTypeIdErrorUnion); 6845 if (!type_has_bits(err_union_const_val->type)) { 6846 // make this a null pointer 6847 ZigType *usize = g->builtin_types.entry_usize; 6848 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), 6849 get_llvm_type(g, const_val->type)); 6850 return const_val->llvm_value; 6851 } 6852 LLVMValueRef uncasted_ptr_val = gen_const_ptr_err_union_code_recursive(g, err_union_const_val); 6853 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type)); 6854 const_val->llvm_value = ptr_val; 6855 return ptr_val; 6856 } 6857 case ConstPtrSpecialBaseErrorUnionPayload: 6858 { 6859 ZigValue *err_union_const_val = const_val->data.x_ptr.data.base_err_union_payload.err_union_val; 6860 assert(err_union_const_val->type->id == ZigTypeIdErrorUnion); 6861 if (!type_has_bits(err_union_const_val->type)) { 6862 // make this a null pointer 6863 ZigType *usize = g->builtin_types.entry_usize; 6864 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), 6865 get_llvm_type(g, const_val->type)); 6866 return const_val->llvm_value; 6867 } 6868 LLVMValueRef uncasted_ptr_val = gen_const_ptr_err_union_payload_recursive(g, err_union_const_val); 6869 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type)); 6870 const_val->llvm_value = ptr_val; 6871 return ptr_val; 6872 } 6873 case ConstPtrSpecialBaseOptionalPayload: 6874 { 6875 ZigValue *optional_const_val = const_val->data.x_ptr.data.base_optional_payload.optional_val; 6876 assert(optional_const_val->type->id == ZigTypeIdOptional); 6877 if (!type_has_bits(optional_const_val->type)) { 6878 // make this a null pointer 6879 ZigType *usize = g->builtin_types.entry_usize; 6880 const_val->llvm_value = LLVMConstIntToPtr(LLVMConstNull(usize->llvm_type), 6881 get_llvm_type(g, const_val->type)); 6882 return const_val->llvm_value; 6883 } 6884 LLVMValueRef uncasted_ptr_val = gen_const_ptr_optional_payload_recursive(g, optional_const_val); 6885 LLVMValueRef ptr_val = LLVMConstBitCast(uncasted_ptr_val, get_llvm_type(g, const_val->type)); 6886 const_val->llvm_value = ptr_val; 6887 return ptr_val; 6888 } 6889 case ConstPtrSpecialHardCodedAddr: 6890 { 6891 uint64_t addr_value = const_val->data.x_ptr.data.hard_coded_addr.addr; 6892 ZigType *usize = g->builtin_types.entry_usize; 6893 const_val->llvm_value = LLVMConstIntToPtr( 6894 LLVMConstInt(usize->llvm_type, addr_value, false), get_llvm_type(g, const_val->type)); 6895 return const_val->llvm_value; 6896 } 6897 case ConstPtrSpecialFunction: 6898 return LLVMConstBitCast(fn_llvm_value(g, const_val->data.x_ptr.data.fn.fn_entry), 6899 get_llvm_type(g, const_val->type)); 6900 case ConstPtrSpecialNull: 6901 return LLVMConstNull(get_llvm_type(g, const_val->type)); 6902 } 6903 zig_unreachable(); 6904 } 6905 6906 static LLVMValueRef gen_const_val_err_set(CodeGen *g, ZigValue *const_val, const char *name) { 6907 uint64_t value = (const_val->data.x_err_set == nullptr) ? 0 : const_val->data.x_err_set->value; 6908 return LLVMConstInt(get_llvm_type(g, g->builtin_types.entry_global_error_set), value, false); 6909 } 6910 6911 static LLVMValueRef gen_const_val(CodeGen *g, ZigValue *const_val, const char *name) { 6912 Error err; 6913 6914 ZigType *type_entry = const_val->type; 6915 assert(type_has_bits(type_entry)); 6916 6917 check: switch (const_val->special) { 6918 case ConstValSpecialLazy: 6919 if ((err = ir_resolve_lazy(g, nullptr, const_val))) { 6920 codegen_report_errors_and_exit(g); 6921 } 6922 goto check; 6923 case ConstValSpecialRuntime: 6924 zig_unreachable(); 6925 case ConstValSpecialUndef: 6926 return LLVMGetUndef(get_llvm_type(g, type_entry)); 6927 case ConstValSpecialStatic: 6928 break; 6929 } 6930 6931 if ((err = type_resolve(g, type_entry, ResolveStatusLLVMFull))) 6932 zig_unreachable(); 6933 6934 switch (type_entry->id) { 6935 case ZigTypeIdInt: 6936 return bigint_to_llvm_const(get_llvm_type(g, type_entry), &const_val->data.x_bigint); 6937 case ZigTypeIdErrorSet: 6938 return gen_const_val_err_set(g, const_val, name); 6939 case ZigTypeIdFloat: 6940 switch (type_entry->data.floating.bit_count) { 6941 case 16: 6942 return LLVMConstReal(get_llvm_type(g, type_entry), zig_f16_to_double(const_val->data.x_f16)); 6943 case 32: 6944 return LLVMConstReal(get_llvm_type(g, type_entry), const_val->data.x_f32); 6945 case 64: 6946 return LLVMConstReal(get_llvm_type(g, type_entry), const_val->data.x_f64); 6947 case 128: 6948 { 6949 // TODO make sure this is correct on big endian targets too 6950 uint8_t buf[16]; 6951 memcpy(buf, &const_val->data.x_f128, 16); 6952 LLVMValueRef as_int = LLVMConstIntOfArbitraryPrecision(LLVMInt128Type(), 2, 6953 (uint64_t*)buf); 6954 return LLVMConstBitCast(as_int, get_llvm_type(g, type_entry)); 6955 } 6956 default: 6957 zig_unreachable(); 6958 } 6959 case ZigTypeIdBool: 6960 if (const_val->data.x_bool) { 6961 return LLVMConstAllOnes(LLVMInt1Type()); 6962 } else { 6963 return LLVMConstNull(LLVMInt1Type()); 6964 } 6965 case ZigTypeIdOptional: 6966 { 6967 ZigType *child_type = type_entry->data.maybe.child_type; 6968 if (!type_has_bits(child_type)) { 6969 return LLVMConstInt(LLVMInt1Type(), const_val->data.x_optional ? 1 : 0, false); 6970 } else if (get_codegen_ptr_type(type_entry) != nullptr) { 6971 return gen_const_val_ptr(g, const_val, name); 6972 } else if (child_type->id == ZigTypeIdErrorSet) { 6973 return gen_const_val_err_set(g, const_val, name); 6974 } else { 6975 LLVMValueRef child_val; 6976 LLVMValueRef maybe_val; 6977 bool make_unnamed_struct; 6978 if (const_val->data.x_optional) { 6979 child_val = gen_const_val(g, const_val->data.x_optional, ""); 6980 maybe_val = LLVMConstAllOnes(LLVMInt1Type()); 6981 6982 make_unnamed_struct = is_llvm_value_unnamed_type(g, const_val->type, child_val); 6983 } else { 6984 child_val = LLVMGetUndef(get_llvm_type(g, child_type)); 6985 maybe_val = LLVMConstNull(LLVMInt1Type()); 6986 6987 make_unnamed_struct = false; 6988 } 6989 LLVMValueRef fields[] = { 6990 child_val, 6991 maybe_val, 6992 }; 6993 if (make_unnamed_struct) { 6994 return LLVMConstStruct(fields, 2, false); 6995 } else { 6996 return LLVMConstNamedStruct(get_llvm_type(g, type_entry), fields, 2); 6997 } 6998 } 6999 } 7000 case ZigTypeIdStruct: 7001 { 7002 LLVMValueRef *fields = allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count); 7003 size_t src_field_count = type_entry->data.structure.src_field_count; 7004 bool make_unnamed_struct = false; 7005 assert(type_entry->data.structure.resolve_status == ResolveStatusLLVMFull); 7006 if (type_entry->data.structure.layout == ContainerLayoutPacked) { 7007 size_t src_field_index = 0; 7008 while (src_field_index < src_field_count) { 7009 TypeStructField *type_struct_field = type_entry->data.structure.fields[src_field_index]; 7010 if (type_struct_field->gen_index == SIZE_MAX) { 7011 src_field_index += 1; 7012 continue; 7013 } 7014 7015 size_t src_field_index_end = src_field_index + 1; 7016 for (; src_field_index_end < src_field_count; src_field_index_end += 1) { 7017 TypeStructField *it_field = type_entry->data.structure.fields[src_field_index_end]; 7018 if (it_field->gen_index != type_struct_field->gen_index) 7019 break; 7020 } 7021 7022 if (src_field_index + 1 == src_field_index_end) { 7023 ZigValue *field_val = const_val->data.x_struct.fields[src_field_index]; 7024 LLVMValueRef val = gen_const_val(g, field_val, ""); 7025 fields[type_struct_field->gen_index] = val; 7026 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val); 7027 } else { 7028 bool is_big_endian = g->is_big_endian; // TODO get endianness from struct type 7029 LLVMTypeRef field_ty = LLVMStructGetTypeAtIndex(get_llvm_type(g, type_entry), 7030 (unsigned)type_struct_field->gen_index); 7031 const size_t size_in_bytes = LLVMStoreSizeOfType(g->target_data_ref, field_ty); 7032 LLVMTypeRef big_int_type_ref = LLVMIntType(size_in_bytes * 8); 7033 LLVMValueRef val = LLVMConstInt(big_int_type_ref, 0, false); 7034 size_t used_bits = 0; 7035 for (size_t i = src_field_index; i < src_field_index_end; i += 1) { 7036 TypeStructField *it_field = type_entry->data.structure.fields[i]; 7037 if (it_field->gen_index == SIZE_MAX) { 7038 continue; 7039 } 7040 LLVMValueRef child_val = pack_const_int(g, big_int_type_ref, 7041 const_val->data.x_struct.fields[i]); 7042 uint32_t packed_bits_size = type_size_bits(g, it_field->type_entry); 7043 if (is_big_endian) { 7044 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, 7045 packed_bits_size, false); 7046 val = LLVMConstShl(val, shift_amt); 7047 val = LLVMConstOr(val, child_val); 7048 } else { 7049 LLVMValueRef shift_amt = LLVMConstInt(big_int_type_ref, used_bits, false); 7050 LLVMValueRef child_val_shifted = LLVMConstShl(child_val, shift_amt); 7051 val = LLVMConstOr(val, child_val_shifted); 7052 used_bits += packed_bits_size; 7053 } 7054 } 7055 if (LLVMGetTypeKind(field_ty) != LLVMArrayTypeKind) { 7056 assert(LLVMGetTypeKind(field_ty) == LLVMIntegerTypeKind); 7057 fields[type_struct_field->gen_index] = val; 7058 } else { 7059 const LLVMValueRef AMT = LLVMConstInt(LLVMTypeOf(val), 8, false); 7060 7061 LLVMValueRef *values = allocate<LLVMValueRef>(size_in_bytes); 7062 for (size_t i = 0; i < size_in_bytes; i++) { 7063 const size_t idx = is_big_endian ? size_in_bytes - 1 - i : i; 7064 values[idx] = LLVMConstTruncOrBitCast(val, LLVMInt8Type()); 7065 val = LLVMConstLShr(val, AMT); 7066 } 7067 7068 fields[type_struct_field->gen_index] = LLVMConstArray(LLVMInt8Type(), values, size_in_bytes); 7069 } 7070 } 7071 7072 src_field_index = src_field_index_end; 7073 } 7074 } else { 7075 for (uint32_t i = 0; i < src_field_count; i += 1) { 7076 TypeStructField *type_struct_field = type_entry->data.structure.fields[i]; 7077 if (type_struct_field->gen_index == SIZE_MAX) { 7078 continue; 7079 } 7080 ZigValue *field_val = const_val->data.x_struct.fields[i]; 7081 assert(field_val->type != nullptr); 7082 if ((err = ensure_const_val_repr(nullptr, g, nullptr, field_val, 7083 type_struct_field->type_entry))) 7084 { 7085 zig_unreachable(); 7086 } 7087 7088 LLVMValueRef val = gen_const_val(g, field_val, ""); 7089 fields[type_struct_field->gen_index] = val; 7090 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val); 7091 7092 size_t end_pad_gen_index = (i + 1 < src_field_count) ? 7093 type_entry->data.structure.fields[i + 1]->gen_index : 7094 type_entry->data.structure.gen_field_count; 7095 size_t next_offset = (i + 1 < src_field_count) ? 7096 type_entry->data.structure.fields[i + 1]->offset : type_entry->abi_size; 7097 if (end_pad_gen_index != SIZE_MAX) { 7098 for (size_t gen_i = type_struct_field->gen_index + 1; gen_i < end_pad_gen_index; 7099 gen_i += 1) 7100 { 7101 size_t pad_bytes = next_offset - 7102 (type_struct_field->offset + type_struct_field->type_entry->abi_size); 7103 LLVMTypeRef llvm_array_type = LLVMArrayType(LLVMInt8Type(), pad_bytes); 7104 fields[gen_i] = LLVMGetUndef(llvm_array_type); 7105 } 7106 } 7107 } 7108 } 7109 if (make_unnamed_struct) { 7110 return LLVMConstStruct(fields, type_entry->data.structure.gen_field_count, 7111 type_entry->data.structure.layout == ContainerLayoutPacked); 7112 } else { 7113 return LLVMConstNamedStruct(get_llvm_type(g, type_entry), fields, type_entry->data.structure.gen_field_count); 7114 } 7115 } 7116 case ZigTypeIdArray: 7117 { 7118 uint64_t len = type_entry->data.array.len; 7119 switch (const_val->data.x_array.special) { 7120 case ConstArraySpecialUndef: 7121 return LLVMGetUndef(get_llvm_type(g, type_entry)); 7122 case ConstArraySpecialNone: { 7123 uint64_t extra_len_from_sentinel = (type_entry->data.array.sentinel != nullptr) ? 1 : 0; 7124 uint64_t full_len = len + extra_len_from_sentinel; 7125 LLVMValueRef *values = allocate<LLVMValueRef>(full_len); 7126 LLVMTypeRef element_type_ref = get_llvm_type(g, type_entry->data.array.child_type); 7127 bool make_unnamed_struct = false; 7128 for (uint64_t i = 0; i < len; i += 1) { 7129 ZigValue *elem_value = &const_val->data.x_array.data.s_none.elements[i]; 7130 LLVMValueRef val = gen_const_val(g, elem_value, ""); 7131 values[i] = val; 7132 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, elem_value->type, val); 7133 } 7134 if (type_entry->data.array.sentinel != nullptr) { 7135 values[len] = gen_const_val(g, type_entry->data.array.sentinel, ""); 7136 } 7137 if (make_unnamed_struct) { 7138 return LLVMConstStruct(values, full_len, true); 7139 } else { 7140 return LLVMConstArray(element_type_ref, values, (unsigned)full_len); 7141 } 7142 } 7143 case ConstArraySpecialBuf: { 7144 Buf *buf = const_val->data.x_array.data.s_buf; 7145 return LLVMConstString(buf_ptr(buf), (unsigned)buf_len(buf), 7146 type_entry->data.array.sentinel == nullptr); 7147 } 7148 } 7149 zig_unreachable(); 7150 } 7151 case ZigTypeIdVector: { 7152 uint32_t len = type_entry->data.vector.len; 7153 switch (const_val->data.x_array.special) { 7154 case ConstArraySpecialUndef: 7155 return LLVMGetUndef(get_llvm_type(g, type_entry)); 7156 case ConstArraySpecialNone: { 7157 LLVMValueRef *values = allocate<LLVMValueRef>(len); 7158 for (uint64_t i = 0; i < len; i += 1) { 7159 ZigValue *elem_value = &const_val->data.x_array.data.s_none.elements[i]; 7160 values[i] = gen_const_val(g, elem_value, ""); 7161 } 7162 return LLVMConstVector(values, len); 7163 } 7164 case ConstArraySpecialBuf: { 7165 Buf *buf = const_val->data.x_array.data.s_buf; 7166 assert(buf_len(buf) == len); 7167 LLVMValueRef *values = allocate<LLVMValueRef>(len); 7168 for (uint64_t i = 0; i < len; i += 1) { 7169 values[i] = LLVMConstInt(g->builtin_types.entry_u8->llvm_type, buf_ptr(buf)[i], false); 7170 } 7171 return LLVMConstVector(values, len); 7172 } 7173 } 7174 zig_unreachable(); 7175 } 7176 case ZigTypeIdUnion: 7177 { 7178 // Force type_entry->data.unionation.union_llvm_type to get resolved 7179 (void)get_llvm_type(g, type_entry); 7180 7181 if (type_entry->data.unionation.gen_field_count == 0) { 7182 if (type_entry->data.unionation.tag_type == nullptr) { 7183 return nullptr; 7184 } else { 7185 return bigint_to_llvm_const(get_llvm_type(g, type_entry->data.unionation.tag_type), 7186 &const_val->data.x_union.tag); 7187 } 7188 } 7189 7190 LLVMTypeRef union_type_ref = type_entry->data.unionation.union_llvm_type; 7191 assert(union_type_ref != nullptr); 7192 7193 LLVMValueRef union_value_ref; 7194 bool make_unnamed_struct; 7195 ZigValue *payload_value = const_val->data.x_union.payload; 7196 if (payload_value == nullptr || !type_has_bits(payload_value->type)) { 7197 if (type_entry->data.unionation.gen_tag_index == SIZE_MAX) 7198 return LLVMGetUndef(get_llvm_type(g, type_entry)); 7199 7200 union_value_ref = LLVMGetUndef(union_type_ref); 7201 make_unnamed_struct = false; 7202 } else { 7203 uint64_t field_type_bytes = LLVMABISizeOfType(g->target_data_ref, 7204 get_llvm_type(g, payload_value->type)); 7205 uint64_t pad_bytes = type_entry->data.unionation.union_abi_size - field_type_bytes; 7206 LLVMValueRef correctly_typed_value = gen_const_val(g, payload_value, ""); 7207 make_unnamed_struct = is_llvm_value_unnamed_type(g, payload_value->type, correctly_typed_value) || 7208 payload_value->type != type_entry->data.unionation.most_aligned_union_member->type_entry; 7209 7210 { 7211 if (pad_bytes == 0) { 7212 union_value_ref = correctly_typed_value; 7213 } else { 7214 LLVMValueRef fields[2]; 7215 fields[0] = correctly_typed_value; 7216 fields[1] = LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), (unsigned)pad_bytes)); 7217 if (make_unnamed_struct || type_entry->data.unionation.gen_tag_index != SIZE_MAX) { 7218 union_value_ref = LLVMConstStruct(fields, 2, false); 7219 } else { 7220 union_value_ref = LLVMConstNamedStruct(union_type_ref, fields, 2); 7221 } 7222 } 7223 } 7224 7225 if (type_entry->data.unionation.gen_tag_index == SIZE_MAX) { 7226 return union_value_ref; 7227 } 7228 } 7229 7230 LLVMValueRef tag_value = bigint_to_llvm_const( 7231 get_llvm_type(g, type_entry->data.unionation.tag_type), 7232 &const_val->data.x_union.tag); 7233 7234 LLVMValueRef fields[3]; 7235 fields[type_entry->data.unionation.gen_union_index] = union_value_ref; 7236 fields[type_entry->data.unionation.gen_tag_index] = tag_value; 7237 7238 if (make_unnamed_struct) { 7239 LLVMValueRef result = LLVMConstStruct(fields, 2, false); 7240 uint64_t last_field_offset = LLVMOffsetOfElement(g->target_data_ref, LLVMTypeOf(result), 1); 7241 uint64_t end_offset = last_field_offset + 7242 LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(fields[1])); 7243 uint64_t expected_sz = LLVMABISizeOfType(g->target_data_ref, get_llvm_type(g, type_entry)); 7244 unsigned pad_sz = expected_sz - end_offset; 7245 if (pad_sz != 0) { 7246 fields[2] = LLVMGetUndef(LLVMArrayType(LLVMInt8Type(), pad_sz)); 7247 result = LLVMConstStruct(fields, 3, false); 7248 } 7249 uint64_t actual_sz = LLVMStoreSizeOfType(g->target_data_ref, LLVMTypeOf(result)); 7250 assert(actual_sz == expected_sz); 7251 return result; 7252 } else { 7253 return LLVMConstNamedStruct(get_llvm_type(g, type_entry), fields, 2); 7254 } 7255 7256 } 7257 7258 case ZigTypeIdEnum: 7259 return bigint_to_llvm_const(get_llvm_type(g, type_entry), &const_val->data.x_enum_tag); 7260 case ZigTypeIdFn: 7261 if (const_val->data.x_ptr.special == ConstPtrSpecialFunction && 7262 const_val->data.x_ptr.mut != ConstPtrMutComptimeConst) { 7263 zig_unreachable(); 7264 } 7265 // Treat it the same as we do for pointers 7266 return gen_const_val_ptr(g, const_val, name); 7267 case ZigTypeIdPointer: 7268 return gen_const_val_ptr(g, const_val, name); 7269 case ZigTypeIdErrorUnion: 7270 { 7271 ZigType *payload_type = type_entry->data.error_union.payload_type; 7272 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 7273 if (!type_has_bits(payload_type)) { 7274 assert(type_has_bits(err_set_type)); 7275 ErrorTableEntry *err_set = const_val->data.x_err_union.error_set->data.x_err_set; 7276 uint64_t value = (err_set == nullptr) ? 0 : err_set->value; 7277 return LLVMConstInt(get_llvm_type(g, g->err_tag_type), value, false); 7278 } else if (!type_has_bits(err_set_type)) { 7279 assert(type_has_bits(payload_type)); 7280 return gen_const_val(g, const_val->data.x_err_union.payload, ""); 7281 } else { 7282 LLVMValueRef err_tag_value; 7283 LLVMValueRef err_payload_value; 7284 bool make_unnamed_struct; 7285 ErrorTableEntry *err_set = const_val->data.x_err_union.error_set->data.x_err_set; 7286 if (err_set != nullptr) { 7287 err_tag_value = LLVMConstInt(get_llvm_type(g, g->err_tag_type), err_set->value, false); 7288 err_payload_value = LLVMConstNull(get_llvm_type(g, payload_type)); 7289 make_unnamed_struct = false; 7290 } else { 7291 err_tag_value = LLVMConstNull(get_llvm_type(g, g->err_tag_type)); 7292 ZigValue *payload_val = const_val->data.x_err_union.payload; 7293 err_payload_value = gen_const_val(g, payload_val, ""); 7294 make_unnamed_struct = is_llvm_value_unnamed_type(g, payload_val->type, err_payload_value); 7295 } 7296 LLVMValueRef fields[3]; 7297 fields[err_union_err_index] = err_tag_value; 7298 fields[err_union_payload_index] = err_payload_value; 7299 size_t field_count = 2; 7300 if (type_entry->data.error_union.pad_llvm_type != nullptr) { 7301 fields[2] = LLVMGetUndef(type_entry->data.error_union.pad_llvm_type); 7302 field_count = 3; 7303 } 7304 if (make_unnamed_struct) { 7305 return LLVMConstStruct(fields, field_count, false); 7306 } else { 7307 return LLVMConstNamedStruct(get_llvm_type(g, type_entry), fields, field_count); 7308 } 7309 } 7310 } 7311 case ZigTypeIdVoid: 7312 return nullptr; 7313 case ZigTypeIdInvalid: 7314 case ZigTypeIdMetaType: 7315 case ZigTypeIdUnreachable: 7316 case ZigTypeIdComptimeFloat: 7317 case ZigTypeIdComptimeInt: 7318 case ZigTypeIdEnumLiteral: 7319 case ZigTypeIdUndefined: 7320 case ZigTypeIdNull: 7321 case ZigTypeIdBoundFn: 7322 case ZigTypeIdOpaque: 7323 zig_unreachable(); 7324 case ZigTypeIdFnFrame: 7325 zig_panic("TODO"); 7326 case ZigTypeIdAnyFrame: 7327 zig_panic("TODO"); 7328 } 7329 zig_unreachable(); 7330 } 7331 7332 static void render_const_val(CodeGen *g, ZigValue *const_val, const char *name) { 7333 if (!const_val->llvm_value) 7334 const_val->llvm_value = gen_const_val(g, const_val, name); 7335 7336 if (const_val->llvm_global) 7337 LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value); 7338 } 7339 7340 static void render_const_val_global(CodeGen *g, ZigValue *const_val, const char *name) { 7341 if (!const_val->llvm_global) { 7342 LLVMTypeRef type_ref = const_val->llvm_value ? 7343 LLVMTypeOf(const_val->llvm_value) : get_llvm_type(g, const_val->type); 7344 LLVMValueRef global_value = LLVMAddGlobal(g->module, type_ref, name); 7345 LLVMSetLinkage(global_value, (name == nullptr) ? LLVMPrivateLinkage : LLVMInternalLinkage); 7346 LLVMSetGlobalConstant(global_value, true); 7347 LLVMSetUnnamedAddr(global_value, true); 7348 LLVMSetAlignment(global_value, (const_val->llvm_align == 0) ? 7349 get_abi_alignment(g, const_val->type) : const_val->llvm_align); 7350 7351 const_val->llvm_global = global_value; 7352 } 7353 7354 if (const_val->llvm_value) 7355 LLVMSetInitializer(const_val->llvm_global, const_val->llvm_value); 7356 } 7357 7358 static void generate_error_name_table(CodeGen *g) { 7359 if (g->err_name_table != nullptr || !g->generate_error_name_table || g->errors_by_index.length == 1) { 7360 return; 7361 } 7362 7363 assert(g->errors_by_index.length > 0); 7364 7365 ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, 7366 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false); 7367 ZigType *str_type = get_slice_type(g, u8_ptr_type); 7368 7369 LLVMValueRef *values = allocate<LLVMValueRef>(g->errors_by_index.length); 7370 values[0] = LLVMGetUndef(get_llvm_type(g, str_type)); 7371 for (size_t i = 1; i < g->errors_by_index.length; i += 1) { 7372 ErrorTableEntry *err_entry = g->errors_by_index.at(i); 7373 Buf *name = &err_entry->name; 7374 7375 g->largest_err_name_len = max(g->largest_err_name_len, buf_len(name)); 7376 7377 LLVMValueRef str_init = LLVMConstString(buf_ptr(name), (unsigned)buf_len(name), true); 7378 LLVMValueRef str_global = LLVMAddGlobal(g->module, LLVMTypeOf(str_init), ""); 7379 LLVMSetInitializer(str_global, str_init); 7380 LLVMSetLinkage(str_global, LLVMPrivateLinkage); 7381 LLVMSetGlobalConstant(str_global, true); 7382 LLVMSetUnnamedAddr(str_global, true); 7383 LLVMSetAlignment(str_global, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(str_init))); 7384 7385 LLVMValueRef fields[] = { 7386 LLVMConstBitCast(str_global, get_llvm_type(g, u8_ptr_type)), 7387 LLVMConstInt(g->builtin_types.entry_usize->llvm_type, buf_len(name), false), 7388 }; 7389 values[i] = LLVMConstNamedStruct(get_llvm_type(g, str_type), fields, 2); 7390 } 7391 7392 LLVMValueRef err_name_table_init = LLVMConstArray(get_llvm_type(g, str_type), values, (unsigned)g->errors_by_index.length); 7393 7394 g->err_name_table = LLVMAddGlobal(g->module, LLVMTypeOf(err_name_table_init), 7395 get_mangled_name(g, buf_ptr(buf_create_from_str("__zig_err_name_table")), false)); 7396 LLVMSetInitializer(g->err_name_table, err_name_table_init); 7397 LLVMSetLinkage(g->err_name_table, LLVMPrivateLinkage); 7398 LLVMSetGlobalConstant(g->err_name_table, true); 7399 LLVMSetUnnamedAddr(g->err_name_table, true); 7400 LLVMSetAlignment(g->err_name_table, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(err_name_table_init))); 7401 } 7402 7403 static void build_all_basic_blocks(CodeGen *g, ZigFn *fn) { 7404 IrExecutable *executable = &fn->analyzed_executable; 7405 assert(executable->basic_block_list.length > 0); 7406 LLVMValueRef fn_val = fn_llvm_value(g, fn); 7407 LLVMBasicBlockRef first_bb = nullptr; 7408 if (fn_is_async(fn)) { 7409 first_bb = LLVMAppendBasicBlock(fn_val, "AsyncSwitch"); 7410 g->cur_preamble_llvm_block = first_bb; 7411 } 7412 for (size_t block_i = 0; block_i < executable->basic_block_list.length; block_i += 1) { 7413 IrBasicBlock *bb = executable->basic_block_list.at(block_i); 7414 bb->llvm_block = LLVMAppendBasicBlock(fn_val, bb->name_hint); 7415 } 7416 if (first_bb == nullptr) { 7417 first_bb = executable->basic_block_list.at(0)->llvm_block; 7418 } 7419 LLVMPositionBuilderAtEnd(g->builder, first_bb); 7420 } 7421 7422 static void gen_global_var(CodeGen *g, ZigVar *var, LLVMValueRef init_val, 7423 ZigType *type_entry) 7424 { 7425 if (g->strip_debug_symbols) { 7426 return; 7427 } 7428 7429 assert(var->gen_is_const); 7430 assert(type_entry); 7431 7432 ZigType *import = get_scope_import(var->parent_scope); 7433 assert(import); 7434 7435 bool is_local_to_unit = true; 7436 ZigLLVMCreateGlobalVariable(g->dbuilder, get_di_scope(g, var->parent_scope), var->name, 7437 var->name, import->data.structure.root_struct->di_file, 7438 (unsigned)(var->decl_node->line + 1), 7439 get_llvm_di_type(g, type_entry), is_local_to_unit); 7440 7441 // TODO ^^ make an actual global variable 7442 } 7443 7444 static void validate_inline_fns(CodeGen *g) { 7445 for (size_t i = 0; i < g->inline_fns.length; i += 1) { 7446 ZigFn *fn_entry = g->inline_fns.at(i); 7447 LLVMValueRef fn_val = LLVMGetNamedFunction(g->module, fn_entry->llvm_name); 7448 if (fn_val != nullptr) { 7449 add_node_error(g, fn_entry->proto_node, buf_sprintf("unable to inline function")); 7450 } 7451 } 7452 report_errors_and_maybe_exit(g); 7453 } 7454 7455 static void set_global_tls(CodeGen *g, ZigVar *var, LLVMValueRef global_value) { 7456 bool is_extern = var->decl_node->data.variable_declaration.is_extern; 7457 bool is_export = var->decl_node->data.variable_declaration.is_export; 7458 bool is_internal_linkage = !is_extern && !is_export; 7459 if (var->is_thread_local && (!g->is_single_threaded || !is_internal_linkage)) { 7460 LLVMSetThreadLocalMode(global_value, LLVMGeneralDynamicTLSModel); 7461 } 7462 } 7463 7464 static void do_code_gen(CodeGen *g) { 7465 Error err; 7466 assert(!g->errors.length); 7467 7468 generate_error_name_table(g); 7469 7470 // Generate module level variables 7471 for (size_t i = 0; i < g->global_vars.length; i += 1) { 7472 TldVar *tld_var = g->global_vars.at(i); 7473 ZigVar *var = tld_var->var; 7474 7475 if (var->var_type->id == ZigTypeIdComptimeFloat) { 7476 // Generate debug info for it but that's it. 7477 ZigValue *const_val = var->const_value; 7478 assert(const_val->special != ConstValSpecialRuntime); 7479 if ((err = ir_resolve_lazy(g, var->decl_node, const_val))) 7480 zig_unreachable(); 7481 if (const_val->type != var->var_type) { 7482 zig_panic("TODO debug info for var with ptr casted value"); 7483 } 7484 ZigType *var_type = g->builtin_types.entry_f128; 7485 ZigValue coerced_value = {}; 7486 coerced_value.special = ConstValSpecialStatic; 7487 coerced_value.type = var_type; 7488 coerced_value.data.x_f128 = bigfloat_to_f128(&const_val->data.x_bigfloat); 7489 LLVMValueRef init_val = gen_const_val(g, &coerced_value, ""); 7490 gen_global_var(g, var, init_val, var_type); 7491 continue; 7492 } 7493 7494 if (var->var_type->id == ZigTypeIdComptimeInt) { 7495 // Generate debug info for it but that's it. 7496 ZigValue *const_val = var->const_value; 7497 assert(const_val->special != ConstValSpecialRuntime); 7498 if ((err = ir_resolve_lazy(g, var->decl_node, const_val))) 7499 zig_unreachable(); 7500 if (const_val->type != var->var_type) { 7501 zig_panic("TODO debug info for var with ptr casted value"); 7502 } 7503 size_t bits_needed = bigint_bits_needed(&const_val->data.x_bigint); 7504 if (bits_needed < 8) { 7505 bits_needed = 8; 7506 } 7507 ZigType *var_type = get_int_type(g, const_val->data.x_bigint.is_negative, bits_needed); 7508 LLVMValueRef init_val = bigint_to_llvm_const(get_llvm_type(g, var_type), &const_val->data.x_bigint); 7509 gen_global_var(g, var, init_val, var_type); 7510 continue; 7511 } 7512 7513 if (!type_has_bits(var->var_type)) 7514 continue; 7515 7516 assert(var->decl_node); 7517 7518 GlobalLinkageId linkage; 7519 const char *unmangled_name = var->name; 7520 const char *symbol_name; 7521 if (var->export_list.length == 0) { 7522 if (var->decl_node->data.variable_declaration.is_extern) { 7523 symbol_name = unmangled_name; 7524 linkage = GlobalLinkageIdStrong; 7525 } else { 7526 symbol_name = get_mangled_name(g, unmangled_name, false); 7527 linkage = GlobalLinkageIdInternal; 7528 } 7529 } else { 7530 GlobalExport *global_export = &var->export_list.items[0]; 7531 symbol_name = buf_ptr(&global_export->name); 7532 linkage = global_export->linkage; 7533 } 7534 7535 LLVMValueRef global_value; 7536 bool externally_initialized = var->decl_node->data.variable_declaration.expr == nullptr; 7537 if (externally_initialized) { 7538 LLVMValueRef existing_llvm_var = LLVMGetNamedGlobal(g->module, symbol_name); 7539 if (existing_llvm_var) { 7540 global_value = LLVMConstBitCast(existing_llvm_var, 7541 LLVMPointerType(get_llvm_type(g, var->var_type), 0)); 7542 } else { 7543 global_value = LLVMAddGlobal(g->module, get_llvm_type(g, var->var_type), symbol_name); 7544 // TODO debug info for the extern variable 7545 7546 LLVMSetLinkage(global_value, to_llvm_linkage(linkage)); 7547 maybe_import_dll(g, global_value, GlobalLinkageIdStrong); 7548 LLVMSetAlignment(global_value, var->align_bytes); 7549 LLVMSetGlobalConstant(global_value, var->gen_is_const); 7550 set_global_tls(g, var, global_value); 7551 } 7552 } else { 7553 bool exported = (linkage != GlobalLinkageIdInternal); 7554 render_const_val(g, var->const_value, symbol_name); 7555 render_const_val_global(g, var->const_value, symbol_name); 7556 global_value = var->const_value->llvm_global; 7557 7558 if (exported) { 7559 LLVMSetLinkage(global_value, to_llvm_linkage(linkage)); 7560 maybe_export_dll(g, global_value, GlobalLinkageIdStrong); 7561 } 7562 if (var->section_name) { 7563 LLVMSetSection(global_value, buf_ptr(var->section_name)); 7564 } 7565 LLVMSetAlignment(global_value, var->align_bytes); 7566 7567 // TODO debug info for function pointers 7568 // Here we use const_value->type because that's the type of the llvm global, 7569 // which we const ptr cast upon use to whatever it needs to be. 7570 if (var->gen_is_const && var->const_value->type->id != ZigTypeIdFn) { 7571 gen_global_var(g, var, var->const_value->llvm_value, var->const_value->type); 7572 } 7573 7574 LLVMSetGlobalConstant(global_value, var->gen_is_const); 7575 set_global_tls(g, var, global_value); 7576 } 7577 7578 var->value_ref = global_value; 7579 7580 for (size_t export_i = 1; export_i < var->export_list.length; export_i += 1) { 7581 GlobalExport *global_export = &var->export_list.items[export_i]; 7582 LLVMAddAlias(g->module, LLVMTypeOf(var->value_ref), var->value_ref, buf_ptr(&global_export->name)); 7583 } 7584 } 7585 7586 // Generate function definitions. 7587 stage2_progress_update_node(g->sub_progress_node, 0, g->fn_defs.length); 7588 for (size_t fn_i = 0; fn_i < g->fn_defs.length; fn_i += 1) { 7589 ZigFn *fn_table_entry = g->fn_defs.at(fn_i); 7590 Stage2ProgressNode *fn_prog_node = stage2_progress_start(g->sub_progress_node, 7591 buf_ptr(&fn_table_entry->symbol_name), buf_len(&fn_table_entry->symbol_name), 0); 7592 7593 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id; 7594 CallingConvention cc = fn_type_id->cc; 7595 bool is_c_abi = cc == CallingConventionC; 7596 bool want_sret = want_first_arg_sret(g, fn_type_id); 7597 7598 LLVMValueRef fn = fn_llvm_value(g, fn_table_entry); 7599 g->cur_fn = fn_table_entry; 7600 g->cur_fn_val = fn; 7601 7602 build_all_basic_blocks(g, fn_table_entry); 7603 clear_debug_source_node(g); 7604 7605 bool is_async = fn_is_async(fn_table_entry); 7606 7607 if (is_async) { 7608 g->cur_frame_ptr = LLVMGetParam(fn, 0); 7609 } else { 7610 if (want_sret) { 7611 g->cur_ret_ptr = LLVMGetParam(fn, 0); 7612 } else if (handle_is_ptr(fn_type_id->return_type)) { 7613 g->cur_ret_ptr = build_alloca(g, fn_type_id->return_type, "result", 0); 7614 // TODO add debug info variable for this 7615 } else { 7616 g->cur_ret_ptr = nullptr; 7617 } 7618 } 7619 7620 uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry); 7621 bool have_err_ret_trace_arg = err_ret_trace_arg_index != UINT32_MAX; 7622 if (have_err_ret_trace_arg) { 7623 g->cur_err_ret_trace_val_arg = LLVMGetParam(fn, err_ret_trace_arg_index); 7624 } else { 7625 g->cur_err_ret_trace_val_arg = nullptr; 7626 } 7627 7628 // error return tracing setup 7629 bool have_err_ret_trace_stack = g->have_err_ret_tracing && fn_table_entry->calls_or_awaits_errorable_fn && 7630 !is_async && !have_err_ret_trace_arg; 7631 LLVMValueRef err_ret_array_val = nullptr; 7632 if (have_err_ret_trace_stack) { 7633 ZigType *array_type = get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count, nullptr); 7634 err_ret_array_val = build_alloca(g, array_type, "error_return_trace_addresses", get_abi_alignment(g, array_type)); 7635 7636 (void)get_llvm_type(g, get_stack_trace_type(g)); 7637 g->cur_err_ret_trace_val_stack = build_alloca(g, get_stack_trace_type(g), "error_return_trace", 7638 get_abi_alignment(g, g->stack_trace_type)); 7639 } else { 7640 g->cur_err_ret_trace_val_stack = nullptr; 7641 } 7642 7643 if (!is_async) { 7644 // allocate async frames for noasync calls & awaits to async functions 7645 ZigType *largest_call_frame_type = nullptr; 7646 IrInstruction *all_calls_alloca = ir_create_alloca(g, &fn_table_entry->fndef_scope->base, 7647 fn_table_entry->body_node, fn_table_entry, g->builtin_types.entry_void, "@async_call_frame"); 7648 for (size_t i = 0; i < fn_table_entry->call_list.length; i += 1) { 7649 IrInstructionCallGen *call = fn_table_entry->call_list.at(i); 7650 if (call->fn_entry == nullptr) 7651 continue; 7652 if (!fn_is_async(call->fn_entry)) 7653 continue; 7654 if (call->modifier != CallModifierNoAsync) 7655 continue; 7656 if (call->frame_result_loc != nullptr) 7657 continue; 7658 ZigType *callee_frame_type = get_fn_frame_type(g, call->fn_entry); 7659 if (largest_call_frame_type == nullptr || 7660 callee_frame_type->abi_size > largest_call_frame_type->abi_size) 7661 { 7662 largest_call_frame_type = callee_frame_type; 7663 } 7664 call->frame_result_loc = all_calls_alloca; 7665 } 7666 if (largest_call_frame_type != nullptr) { 7667 all_calls_alloca->value->type = get_pointer_to_type(g, largest_call_frame_type, false); 7668 } 7669 // allocate temporary stack data 7670 for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_gen_list.length; alloca_i += 1) { 7671 IrInstructionAllocaGen *instruction = fn_table_entry->alloca_gen_list.at(alloca_i); 7672 ZigType *ptr_type = instruction->base.value->type; 7673 assert(ptr_type->id == ZigTypeIdPointer); 7674 ZigType *child_type = ptr_type->data.pointer.child_type; 7675 if (type_resolve(g, child_type, ResolveStatusSizeKnown)) 7676 zig_unreachable(); 7677 if (!type_has_bits(child_type)) 7678 continue; 7679 if (instruction->base.ref_count == 0) 7680 continue; 7681 if (instruction->base.value->special != ConstValSpecialRuntime) { 7682 if (const_ptr_pointee(nullptr, g, instruction->base.value, nullptr)->special != 7683 ConstValSpecialRuntime) 7684 { 7685 continue; 7686 } 7687 } 7688 if (type_resolve(g, child_type, ResolveStatusLLVMFull)) 7689 zig_unreachable(); 7690 instruction->base.llvm_value = build_alloca(g, child_type, instruction->name_hint, 7691 get_ptr_align(g, ptr_type)); 7692 } 7693 } 7694 7695 ZigType *import = get_scope_import(&fn_table_entry->fndef_scope->base); 7696 unsigned gen_i_init = want_sret ? 1 : 0; 7697 7698 // create debug variable declarations for variables and allocate all local variables 7699 FnWalk fn_walk_var = {}; 7700 fn_walk_var.id = FnWalkIdVars; 7701 fn_walk_var.data.vars.import = import; 7702 fn_walk_var.data.vars.fn = fn_table_entry; 7703 fn_walk_var.data.vars.llvm_fn = fn; 7704 fn_walk_var.data.vars.gen_i = gen_i_init; 7705 for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) { 7706 ZigVar *var = fn_table_entry->variable_list.at(var_i); 7707 7708 if (!type_has_bits(var->var_type)) { 7709 continue; 7710 } 7711 if (ir_get_var_is_comptime(var)) 7712 continue; 7713 switch (type_requires_comptime(g, var->var_type)) { 7714 case ReqCompTimeInvalid: 7715 zig_unreachable(); 7716 case ReqCompTimeYes: 7717 continue; 7718 case ReqCompTimeNo: 7719 break; 7720 } 7721 7722 if (var->src_arg_index == SIZE_MAX) { 7723 var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope), 7724 var->name, import->data.structure.root_struct->di_file, (unsigned)(var->decl_node->line + 1), 7725 get_llvm_di_type(g, var->var_type), !g->strip_debug_symbols, 0); 7726 7727 } else if (is_c_abi) { 7728 fn_walk_var.data.vars.var = var; 7729 iter_function_params_c_abi(g, fn_table_entry->type_entry, &fn_walk_var, var->src_arg_index); 7730 } else if (!is_async) { 7731 ZigType *gen_type; 7732 FnGenParamInfo *gen_info = &fn_table_entry->type_entry->data.fn.gen_param_info[var->src_arg_index]; 7733 assert(gen_info->gen_index != SIZE_MAX); 7734 7735 if (handle_is_ptr(var->var_type)) { 7736 if (gen_info->is_byval) { 7737 gen_type = var->var_type; 7738 } else { 7739 gen_type = gen_info->type; 7740 } 7741 var->value_ref = LLVMGetParam(fn, gen_info->gen_index); 7742 } else { 7743 gen_type = var->var_type; 7744 var->value_ref = build_alloca(g, var->var_type, var->name, var->align_bytes); 7745 } 7746 if (var->decl_node) { 7747 var->di_loc_var = ZigLLVMCreateParameterVariable(g->dbuilder, get_di_scope(g, var->parent_scope), 7748 var->name, import->data.structure.root_struct->di_file, 7749 (unsigned)(var->decl_node->line + 1), 7750 get_llvm_di_type(g, gen_type), !g->strip_debug_symbols, 0, (unsigned)(gen_info->gen_index+1)); 7751 } 7752 7753 } 7754 } 7755 7756 // finishing error return trace setup. we have to do this after all the allocas. 7757 if (have_err_ret_trace_stack) { 7758 ZigType *usize = g->builtin_types.entry_usize; 7759 size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index; 7760 LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, ""); 7761 gen_store_untyped(g, LLVMConstNull(usize->llvm_type), index_field_ptr, 0, false); 7762 7763 size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index; 7764 LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, ""); 7765 7766 ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry; 7767 size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index; 7768 LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, ""); 7769 LLVMValueRef zero = LLVMConstNull(usize->llvm_type); 7770 LLVMValueRef indices[] = {zero, zero}; 7771 LLVMValueRef err_ret_array_val_elem0_ptr = LLVMBuildInBoundsGEP(g->builder, err_ret_array_val, 7772 indices, 2, ""); 7773 ZigType *ptr_ptr_usize_type = get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false); 7774 gen_store(g, err_ret_array_val_elem0_ptr, ptr_field_ptr, ptr_ptr_usize_type); 7775 7776 size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index; 7777 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, ""); 7778 gen_store(g, LLVMConstInt(usize->llvm_type, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false)); 7779 } 7780 7781 if (is_async) { 7782 (void)get_llvm_type(g, fn_table_entry->frame_type); 7783 g->cur_resume_block_count = 0; 7784 7785 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; 7786 LLVMValueRef size_val = LLVMConstInt(usize_type_ref, fn_table_entry->frame_type->abi_size, false); 7787 if (g->need_frame_size_prefix_data) { 7788 ZigLLVMFunctionSetPrefixData(fn_table_entry->llvm_value, size_val); 7789 } 7790 7791 if (!g->strip_debug_symbols) { 7792 AstNode *source_node = fn_table_entry->proto_node; 7793 ZigLLVMSetCurrentDebugLocation(g->builder, (int)source_node->line + 1, 7794 (int)source_node->column + 1, get_di_scope(g, fn_table_entry->child_scope)); 7795 } 7796 IrExecutable *executable = &fn_table_entry->analyzed_executable; 7797 LLVMBasicBlockRef bad_resume_block = LLVMAppendBasicBlock(g->cur_fn_val, "BadResume"); 7798 LLVMPositionBuilderAtEnd(g->builder, bad_resume_block); 7799 gen_assertion_scope(g, PanicMsgIdBadResume, fn_table_entry->child_scope); 7800 7801 LLVMPositionBuilderAtEnd(g->builder, g->cur_preamble_llvm_block); 7802 render_async_spills(g); 7803 g->cur_async_awaiter_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_awaiter_index, ""); 7804 LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_resume_index, ""); 7805 g->cur_async_resume_index_ptr = resume_index_ptr; 7806 7807 if (type_has_bits(fn_type_id->return_type)) { 7808 LLVMValueRef cur_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_ret_start, ""); 7809 g->cur_ret_ptr = LLVMBuildLoad(g->builder, cur_ret_ptr_ptr, ""); 7810 } 7811 uint32_t trace_field_index_stack = UINT32_MAX; 7812 if (codegen_fn_has_err_ret_tracing_stack(g, fn_table_entry, true)) { 7813 trace_field_index_stack = frame_index_trace_stack(g, fn_type_id); 7814 g->cur_err_ret_trace_val_stack = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, 7815 trace_field_index_stack, ""); 7816 } 7817 7818 LLVMValueRef resume_index = LLVMBuildLoad(g->builder, resume_index_ptr, ""); 7819 LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, resume_index, bad_resume_block, 4); 7820 g->cur_async_switch_instr = switch_instr; 7821 7822 LLVMValueRef zero = LLVMConstNull(usize_type_ref); 7823 IrBasicBlock *entry_block = executable->basic_block_list.at(0); 7824 LLVMAddCase(switch_instr, zero, entry_block->llvm_block); 7825 g->cur_resume_block_count += 1; 7826 7827 { 7828 LLVMBasicBlockRef bad_not_suspended_bb = LLVMAppendBasicBlock(g->cur_fn_val, "NotSuspended"); 7829 size_t new_block_index = g->cur_resume_block_count; 7830 g->cur_resume_block_count += 1; 7831 g->cur_bad_not_suspended_index = LLVMConstInt(usize_type_ref, new_block_index, false); 7832 LLVMAddCase(g->cur_async_switch_instr, g->cur_bad_not_suspended_index, bad_not_suspended_bb); 7833 7834 LLVMPositionBuilderAtEnd(g->builder, bad_not_suspended_bb); 7835 gen_assertion_scope(g, PanicMsgIdResumeNotSuspendedFn, fn_table_entry->child_scope); 7836 } 7837 7838 LLVMPositionBuilderAtEnd(g->builder, entry_block->llvm_block); 7839 LLVMBuildStore(g->builder, g->cur_bad_not_suspended_index, g->cur_async_resume_index_ptr); 7840 if (trace_field_index_stack != UINT32_MAX) { 7841 if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) { 7842 LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, 7843 frame_index_trace_arg(g, fn_type_id->return_type), ""); 7844 LLVMValueRef zero_ptr = LLVMConstNull(LLVMGetElementType(LLVMTypeOf(trace_ptr_ptr))); 7845 LLVMBuildStore(g->builder, zero_ptr, trace_ptr_ptr); 7846 } 7847 7848 LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, 7849 trace_field_index_stack, ""); 7850 LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, 7851 trace_field_index_stack + 1, ""); 7852 7853 gen_init_stack_trace(g, trace_field_ptr, addrs_field_ptr); 7854 } 7855 render_async_var_decls(g, entry_block->instruction_list.at(0)->scope); 7856 } else { 7857 // create debug variable declarations for parameters 7858 // rely on the first variables in the variable_list being parameters. 7859 FnWalk fn_walk_init = {}; 7860 fn_walk_init.id = FnWalkIdInits; 7861 fn_walk_init.data.inits.fn = fn_table_entry; 7862 fn_walk_init.data.inits.llvm_fn = fn; 7863 fn_walk_init.data.inits.gen_i = gen_i_init; 7864 walk_function_params(g, fn_table_entry->type_entry, &fn_walk_init); 7865 } 7866 7867 ir_render(g, fn_table_entry); 7868 7869 stage2_progress_end(fn_prog_node); 7870 } 7871 7872 assert(!g->errors.length); 7873 7874 if (buf_len(&g->global_asm) != 0) { 7875 LLVMSetModuleInlineAsm(g->module, buf_ptr(&g->global_asm)); 7876 } 7877 7878 while (g->type_resolve_stack.length != 0) { 7879 ZigType *ty = g->type_resolve_stack.last(); 7880 if (type_resolve(g, ty, ResolveStatusLLVMFull)) 7881 zig_unreachable(); 7882 } 7883 7884 ZigLLVMDIBuilderFinalize(g->dbuilder); 7885 7886 if (g->verbose_llvm_ir) { 7887 fflush(stderr); 7888 LLVMDumpModule(g->module); 7889 } 7890 7891 char *error = nullptr; 7892 if (LLVMVerifyModule(g->module, LLVMReturnStatusAction, &error)) { 7893 zig_panic("broken LLVM module found: %s\nThis is a bug in the Zig compiler.", error); 7894 } 7895 } 7896 7897 static void zig_llvm_emit_output(CodeGen *g) { 7898 bool is_small = g->build_mode == BuildModeSmallRelease; 7899 7900 Buf *output_path = &g->o_file_output_path; 7901 char *err_msg = nullptr; 7902 switch (g->emit_file_type) { 7903 case EmitFileTypeBinary: 7904 if (g->disable_bin_generation) 7905 return; 7906 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), 7907 ZigLLVM_EmitBinary, &err_msg, g->build_mode == BuildModeDebug, is_small, 7908 g->enable_time_report)) 7909 { 7910 zig_panic("unable to write object file %s: %s", buf_ptr(output_path), err_msg); 7911 } 7912 validate_inline_fns(g); 7913 g->link_objects.append(output_path); 7914 if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || 7915 (g->out_type == OutTypeLib && !g->is_dynamic))) 7916 { 7917 zig_link_add_compiler_rt(g, g->sub_progress_node); 7918 } 7919 break; 7920 7921 case EmitFileTypeAssembly: 7922 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), 7923 ZigLLVM_EmitAssembly, &err_msg, g->build_mode == BuildModeDebug, is_small, 7924 g->enable_time_report)) 7925 { 7926 zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg); 7927 } 7928 validate_inline_fns(g); 7929 break; 7930 7931 case EmitFileTypeLLVMIr: 7932 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), 7933 ZigLLVM_EmitLLVMIr, &err_msg, g->build_mode == BuildModeDebug, is_small, 7934 g->enable_time_report)) 7935 { 7936 zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg); 7937 } 7938 validate_inline_fns(g); 7939 break; 7940 7941 default: 7942 zig_unreachable(); 7943 } 7944 } 7945 7946 struct CIntTypeInfo { 7947 CIntType id; 7948 const char *name; 7949 bool is_signed; 7950 }; 7951 7952 static const CIntTypeInfo c_int_type_infos[] = { 7953 {CIntTypeShort, "c_short", true}, 7954 {CIntTypeUShort, "c_ushort", false}, 7955 {CIntTypeInt, "c_int", true}, 7956 {CIntTypeUInt, "c_uint", false}, 7957 {CIntTypeLong, "c_long", true}, 7958 {CIntTypeULong, "c_ulong", false}, 7959 {CIntTypeLongLong, "c_longlong", true}, 7960 {CIntTypeULongLong, "c_ulonglong", false}, 7961 }; 7962 7963 static const bool is_signed_list[] = { false, true, }; 7964 7965 struct GlobalLinkageValue { 7966 GlobalLinkageId id; 7967 const char *name; 7968 }; 7969 7970 static void add_fp_entry(CodeGen *g, const char *name, uint32_t bit_count, LLVMTypeRef type_ref, 7971 ZigType **field) 7972 { 7973 ZigType *entry = new_type_table_entry(ZigTypeIdFloat); 7974 entry->llvm_type = type_ref; 7975 entry->size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->llvm_type); 7976 entry->abi_size = LLVMABISizeOfType(g->target_data_ref, entry->llvm_type); 7977 entry->abi_align = LLVMABIAlignmentOfType(g->target_data_ref, entry->llvm_type); 7978 buf_init_from_str(&entry->name, name); 7979 entry->data.floating.bit_count = bit_count; 7980 7981 entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), 7982 entry->size_in_bits, ZigLLVMEncoding_DW_ATE_float()); 7983 *field = entry; 7984 g->primitive_type_table.put(&entry->name, entry); 7985 } 7986 7987 static void define_builtin_types(CodeGen *g) { 7988 { 7989 // if this type is anywhere in the AST, we should never hit codegen. 7990 ZigType *entry = new_type_table_entry(ZigTypeIdInvalid); 7991 buf_init_from_str(&entry->name, "(invalid)"); 7992 g->builtin_types.entry_invalid = entry; 7993 } 7994 { 7995 ZigType *entry = new_type_table_entry(ZigTypeIdComptimeFloat); 7996 buf_init_from_str(&entry->name, "comptime_float"); 7997 g->builtin_types.entry_num_lit_float = entry; 7998 g->primitive_type_table.put(&entry->name, entry); 7999 } 8000 { 8001 ZigType *entry = new_type_table_entry(ZigTypeIdComptimeInt); 8002 buf_init_from_str(&entry->name, "comptime_int"); 8003 g->builtin_types.entry_num_lit_int = entry; 8004 g->primitive_type_table.put(&entry->name, entry); 8005 } 8006 { 8007 ZigType *entry = new_type_table_entry(ZigTypeIdEnumLiteral); 8008 buf_init_from_str(&entry->name, "(enum literal)"); 8009 g->builtin_types.entry_enum_literal = entry; 8010 } 8011 { 8012 ZigType *entry = new_type_table_entry(ZigTypeIdUndefined); 8013 buf_init_from_str(&entry->name, "(undefined)"); 8014 g->builtin_types.entry_undef = entry; 8015 } 8016 { 8017 ZigType *entry = new_type_table_entry(ZigTypeIdNull); 8018 buf_init_from_str(&entry->name, "(null)"); 8019 g->builtin_types.entry_null = entry; 8020 } 8021 { 8022 ZigType *entry = new_type_table_entry(ZigTypeIdOpaque); 8023 buf_init_from_str(&entry->name, "(var)"); 8024 g->builtin_types.entry_var = entry; 8025 } 8026 8027 for (size_t i = 0; i < array_length(c_int_type_infos); i += 1) { 8028 const CIntTypeInfo *info = &c_int_type_infos[i]; 8029 uint32_t size_in_bits = target_c_type_size_in_bits(g->zig_target, info->id); 8030 bool is_signed = info->is_signed; 8031 8032 ZigType *entry = new_type_table_entry(ZigTypeIdInt); 8033 entry->llvm_type = LLVMIntType(size_in_bits); 8034 entry->size_in_bits = size_in_bits; 8035 entry->abi_size = LLVMABISizeOfType(g->target_data_ref, entry->llvm_type); 8036 entry->abi_align = LLVMABIAlignmentOfType(g->target_data_ref, entry->llvm_type); 8037 8038 buf_init_from_str(&entry->name, info->name); 8039 8040 entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), 8041 8*LLVMStoreSizeOfType(g->target_data_ref, entry->llvm_type), 8042 is_signed ? ZigLLVMEncoding_DW_ATE_signed() : ZigLLVMEncoding_DW_ATE_unsigned()); 8043 entry->data.integral.is_signed = is_signed; 8044 entry->data.integral.bit_count = size_in_bits; 8045 g->primitive_type_table.put(&entry->name, entry); 8046 8047 get_c_int_type_ptr(g, info->id)[0] = entry; 8048 } 8049 8050 { 8051 ZigType *entry = new_type_table_entry(ZigTypeIdBool); 8052 entry->llvm_type = LLVMInt1Type(); 8053 entry->size_in_bits = 1; 8054 entry->abi_size = LLVMABISizeOfType(g->target_data_ref, entry->llvm_type); 8055 entry->abi_align = LLVMABIAlignmentOfType(g->target_data_ref, entry->llvm_type); 8056 buf_init_from_str(&entry->name, "bool"); 8057 entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), 8058 8*LLVMStoreSizeOfType(g->target_data_ref, entry->llvm_type), 8059 ZigLLVMEncoding_DW_ATE_boolean()); 8060 g->builtin_types.entry_bool = entry; 8061 g->primitive_type_table.put(&entry->name, entry); 8062 } 8063 8064 for (size_t sign_i = 0; sign_i < array_length(is_signed_list); sign_i += 1) { 8065 bool is_signed = is_signed_list[sign_i]; 8066 8067 ZigType *entry = new_type_table_entry(ZigTypeIdInt); 8068 entry->llvm_type = LLVMIntType(g->pointer_size_bytes * 8); 8069 entry->size_in_bits = g->pointer_size_bytes * 8; 8070 entry->abi_size = LLVMABISizeOfType(g->target_data_ref, entry->llvm_type); 8071 entry->abi_align = LLVMABIAlignmentOfType(g->target_data_ref, entry->llvm_type); 8072 8073 const char u_or_i = is_signed ? 'i' : 'u'; 8074 buf_resize(&entry->name, 0); 8075 buf_appendf(&entry->name, "%csize", u_or_i); 8076 8077 entry->data.integral.is_signed = is_signed; 8078 entry->data.integral.bit_count = g->pointer_size_bytes * 8; 8079 8080 entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), 8081 8*LLVMStoreSizeOfType(g->target_data_ref, entry->llvm_type), 8082 is_signed ? ZigLLVMEncoding_DW_ATE_signed() : ZigLLVMEncoding_DW_ATE_unsigned()); 8083 g->primitive_type_table.put(&entry->name, entry); 8084 8085 if (is_signed) { 8086 g->builtin_types.entry_isize = entry; 8087 } else { 8088 g->builtin_types.entry_usize = entry; 8089 } 8090 } 8091 8092 add_fp_entry(g, "f16", 16, LLVMHalfType(), &g->builtin_types.entry_f16); 8093 add_fp_entry(g, "f32", 32, LLVMFloatType(), &g->builtin_types.entry_f32); 8094 add_fp_entry(g, "f64", 64, LLVMDoubleType(), &g->builtin_types.entry_f64); 8095 add_fp_entry(g, "f128", 128, LLVMFP128Type(), &g->builtin_types.entry_f128); 8096 add_fp_entry(g, "c_longdouble", 80, LLVMX86FP80Type(), &g->builtin_types.entry_c_longdouble); 8097 8098 { 8099 ZigType *entry = new_type_table_entry(ZigTypeIdVoid); 8100 entry->llvm_type = LLVMVoidType(); 8101 buf_init_from_str(&entry->name, "void"); 8102 entry->llvm_di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), 8103 0, 8104 ZigLLVMEncoding_DW_ATE_signed()); 8105 g->builtin_types.entry_void = entry; 8106 g->primitive_type_table.put(&entry->name, entry); 8107 } 8108 { 8109 ZigType *entry = new_type_table_entry(ZigTypeIdUnreachable); 8110 entry->llvm_type = LLVMVoidType(); 8111 buf_init_from_str(&entry->name, "noreturn"); 8112 entry->llvm_di_type = g->builtin_types.entry_void->llvm_di_type; 8113 g->builtin_types.entry_unreachable = entry; 8114 g->primitive_type_table.put(&entry->name, entry); 8115 } 8116 { 8117 ZigType *entry = new_type_table_entry(ZigTypeIdMetaType); 8118 buf_init_from_str(&entry->name, "type"); 8119 g->builtin_types.entry_type = entry; 8120 g->primitive_type_table.put(&entry->name, entry); 8121 } 8122 8123 g->builtin_types.entry_u8 = get_int_type(g, false, 8); 8124 g->builtin_types.entry_u16 = get_int_type(g, false, 16); 8125 g->builtin_types.entry_u29 = get_int_type(g, false, 29); 8126 g->builtin_types.entry_u32 = get_int_type(g, false, 32); 8127 g->builtin_types.entry_u64 = get_int_type(g, false, 64); 8128 g->builtin_types.entry_i8 = get_int_type(g, true, 8); 8129 g->builtin_types.entry_i32 = get_int_type(g, true, 32); 8130 g->builtin_types.entry_i64 = get_int_type(g, true, 64); 8131 8132 { 8133 g->builtin_types.entry_c_void = get_opaque_type(g, nullptr, nullptr, "c_void", 8134 buf_create_from_str("c_void")); 8135 g->primitive_type_table.put(&g->builtin_types.entry_c_void->name, g->builtin_types.entry_c_void); 8136 } 8137 8138 { 8139 ZigType *entry = new_type_table_entry(ZigTypeIdErrorSet); 8140 buf_init_from_str(&entry->name, "anyerror"); 8141 entry->data.error_set.err_count = UINT32_MAX; 8142 8143 // TODO https://github.com/ziglang/zig/issues/786 8144 g->err_tag_type = g->builtin_types.entry_u16; 8145 8146 entry->size_in_bits = g->err_tag_type->size_in_bits; 8147 entry->abi_align = g->err_tag_type->abi_align; 8148 entry->abi_size = g->err_tag_type->abi_size; 8149 8150 g->builtin_types.entry_global_error_set = entry; 8151 8152 g->errors_by_index.append(nullptr); 8153 8154 g->primitive_type_table.put(&entry->name, entry); 8155 } 8156 } 8157 8158 static void define_intern_values(CodeGen *g) { 8159 { 8160 auto& value = g->intern.x_undefined; 8161 value.type = g->builtin_types.entry_undef; 8162 value.special = ConstValSpecialStatic; 8163 } 8164 { 8165 auto& value = g->intern.x_void; 8166 value.type = g->builtin_types.entry_void; 8167 value.special = ConstValSpecialStatic; 8168 } 8169 { 8170 auto& value = g->intern.x_null; 8171 value.type = g->builtin_types.entry_null; 8172 value.special = ConstValSpecialStatic; 8173 } 8174 { 8175 auto& value = g->intern.x_unreachable; 8176 value.type = g->builtin_types.entry_unreachable; 8177 value.special = ConstValSpecialStatic; 8178 } 8179 { 8180 auto& value = g->intern.zero_byte; 8181 value.type = g->builtin_types.entry_u8; 8182 value.special = ConstValSpecialStatic; 8183 bigint_init_unsigned(&value.data.x_bigint, 0); 8184 } 8185 } 8186 8187 static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char *name, size_t count) { 8188 BuiltinFnEntry *builtin_fn = allocate<BuiltinFnEntry>(1); 8189 buf_init_from_str(&builtin_fn->name, name); 8190 builtin_fn->id = id; 8191 builtin_fn->param_count = count; 8192 g->builtin_fn_table.put(&builtin_fn->name, builtin_fn); 8193 return builtin_fn; 8194 } 8195 8196 static void define_builtin_fns(CodeGen *g) { 8197 create_builtin_fn(g, BuiltinFnIdBreakpoint, "breakpoint", 0); 8198 create_builtin_fn(g, BuiltinFnIdReturnAddress, "returnAddress", 0); 8199 create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy", 3); 8200 create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3); 8201 create_builtin_fn(g, BuiltinFnIdSizeof, "sizeOf", 1); 8202 create_builtin_fn(g, BuiltinFnIdAlignOf, "alignOf", 1); 8203 create_builtin_fn(g, BuiltinFnIdMemberCount, "memberCount", 1); 8204 create_builtin_fn(g, BuiltinFnIdMemberType, "memberType", 2); 8205 create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2); 8206 create_builtin_fn(g, BuiltinFnIdField, "field", 2); 8207 create_builtin_fn(g, BuiltinFnIdTypeInfo, "typeInfo", 1); 8208 create_builtin_fn(g, BuiltinFnIdType, "Type", 1); 8209 create_builtin_fn(g, BuiltinFnIdHasField, "hasField", 2); 8210 create_builtin_fn(g, BuiltinFnIdTypeof, "TypeOf", 1); 8211 create_builtin_fn(g, BuiltinFnIdAddWithOverflow, "addWithOverflow", 4); 8212 create_builtin_fn(g, BuiltinFnIdSubWithOverflow, "subWithOverflow", 4); 8213 create_builtin_fn(g, BuiltinFnIdMulWithOverflow, "mulWithOverflow", 4); 8214 create_builtin_fn(g, BuiltinFnIdShlWithOverflow, "shlWithOverflow", 4); 8215 create_builtin_fn(g, BuiltinFnIdCInclude, "cInclude", 1); 8216 create_builtin_fn(g, BuiltinFnIdCDefine, "cDefine", 2); 8217 create_builtin_fn(g, BuiltinFnIdCUndef, "cUndef", 1); 8218 create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 2); 8219 create_builtin_fn(g, BuiltinFnIdClz, "clz", 2); 8220 create_builtin_fn(g, BuiltinFnIdPopCount, "popCount", 2); 8221 create_builtin_fn(g, BuiltinFnIdBswap, "byteSwap", 2); 8222 create_builtin_fn(g, BuiltinFnIdBitReverse, "bitReverse", 2); 8223 create_builtin_fn(g, BuiltinFnIdImport, "import", 1); 8224 create_builtin_fn(g, BuiltinFnIdCImport, "cImport", 1); 8225 create_builtin_fn(g, BuiltinFnIdErrName, "errorName", 1); 8226 create_builtin_fn(g, BuiltinFnIdTypeName, "typeName", 1); 8227 create_builtin_fn(g, BuiltinFnIdEmbedFile, "embedFile", 1); 8228 create_builtin_fn(g, BuiltinFnIdCmpxchgWeak, "cmpxchgWeak", 6); 8229 create_builtin_fn(g, BuiltinFnIdCmpxchgStrong, "cmpxchgStrong", 6); 8230 create_builtin_fn(g, BuiltinFnIdFence, "fence", 1); 8231 create_builtin_fn(g, BuiltinFnIdTruncate, "truncate", 2); 8232 create_builtin_fn(g, BuiltinFnIdIntCast, "intCast", 2); 8233 create_builtin_fn(g, BuiltinFnIdFloatCast, "floatCast", 2); 8234 create_builtin_fn(g, BuiltinFnIdIntToFloat, "intToFloat", 2); 8235 create_builtin_fn(g, BuiltinFnIdFloatToInt, "floatToInt", 2); 8236 create_builtin_fn(g, BuiltinFnIdBoolToInt, "boolToInt", 1); 8237 create_builtin_fn(g, BuiltinFnIdErrToInt, "errorToInt", 1); 8238 create_builtin_fn(g, BuiltinFnIdIntToErr, "intToError", 1); 8239 create_builtin_fn(g, BuiltinFnIdEnumToInt, "enumToInt", 1); 8240 create_builtin_fn(g, BuiltinFnIdIntToEnum, "intToEnum", 2); 8241 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1); 8242 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX); 8243 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int 8244 create_builtin_fn(g, BuiltinFnIdVectorType, "Vector", 2); 8245 create_builtin_fn(g, BuiltinFnIdShuffle, "shuffle", 4); 8246 create_builtin_fn(g, BuiltinFnIdSplat, "splat", 2); 8247 create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1); 8248 create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1); 8249 create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 1); 8250 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1); 8251 create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2); 8252 create_builtin_fn(g, BuiltinFnIdBitCast, "bitCast", 2); 8253 create_builtin_fn(g, BuiltinFnIdIntToPtr, "intToPtr", 2); 8254 create_builtin_fn(g, BuiltinFnIdPtrToInt, "ptrToInt", 1); 8255 create_builtin_fn(g, BuiltinFnIdTagName, "tagName", 1); 8256 create_builtin_fn(g, BuiltinFnIdTagType, "TagType", 1); 8257 create_builtin_fn(g, BuiltinFnIdFieldParentPtr, "fieldParentPtr", 3); 8258 create_builtin_fn(g, BuiltinFnIdByteOffsetOf, "byteOffsetOf", 2); 8259 create_builtin_fn(g, BuiltinFnIdBitOffsetOf, "bitOffsetOf", 2); 8260 create_builtin_fn(g, BuiltinFnIdDivExact, "divExact", 2); 8261 create_builtin_fn(g, BuiltinFnIdDivTrunc, "divTrunc", 2); 8262 create_builtin_fn(g, BuiltinFnIdDivFloor, "divFloor", 2); 8263 create_builtin_fn(g, BuiltinFnIdRem, "rem", 2); 8264 create_builtin_fn(g, BuiltinFnIdMod, "mod", 2); 8265 create_builtin_fn(g, BuiltinFnIdSqrt, "sqrt", 1); 8266 create_builtin_fn(g, BuiltinFnIdSin, "sin", 1); 8267 create_builtin_fn(g, BuiltinFnIdCos, "cos", 1); 8268 create_builtin_fn(g, BuiltinFnIdExp, "exp", 1); 8269 create_builtin_fn(g, BuiltinFnIdExp2, "exp2", 1); 8270 create_builtin_fn(g, BuiltinFnIdLog, "log", 1); 8271 create_builtin_fn(g, BuiltinFnIdLog2, "log2", 1); 8272 create_builtin_fn(g, BuiltinFnIdLog10, "log10", 1); 8273 create_builtin_fn(g, BuiltinFnIdFabs, "fabs", 1); 8274 create_builtin_fn(g, BuiltinFnIdFloor, "floor", 1); 8275 create_builtin_fn(g, BuiltinFnIdCeil, "ceil", 1); 8276 create_builtin_fn(g, BuiltinFnIdTrunc, "trunc", 1); 8277 create_builtin_fn(g, BuiltinFnIdNearbyInt, "nearbyInt", 1); 8278 create_builtin_fn(g, BuiltinFnIdRound, "round", 1); 8279 create_builtin_fn(g, BuiltinFnIdMulAdd, "mulAdd", 4); 8280 create_builtin_fn(g, BuiltinFnIdNewStackCall, "newStackCall", SIZE_MAX); 8281 create_builtin_fn(g, BuiltinFnIdAsyncCall, "asyncCall", SIZE_MAX); 8282 create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1); 8283 create_builtin_fn(g, BuiltinFnIdShlExact, "shlExact", 2); 8284 create_builtin_fn(g, BuiltinFnIdShrExact, "shrExact", 2); 8285 create_builtin_fn(g, BuiltinFnIdSetEvalBranchQuota, "setEvalBranchQuota", 1); 8286 create_builtin_fn(g, BuiltinFnIdAlignCast, "alignCast", 2); 8287 create_builtin_fn(g, BuiltinFnIdOpaqueType, "OpaqueType", 0); 8288 create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1); 8289 create_builtin_fn(g, BuiltinFnIdArgType, "ArgType", 2); 8290 create_builtin_fn(g, BuiltinFnIdExport, "export", 2); 8291 create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0); 8292 create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5); 8293 create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3); 8294 create_builtin_fn(g, BuiltinFnIdAtomicStore, "atomicStore", 4); 8295 create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2); 8296 create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1); 8297 create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2); 8298 create_builtin_fn(g, BuiltinFnIdThis, "This", 0); 8299 create_builtin_fn(g, BuiltinFnIdHasDecl, "hasDecl", 2); 8300 create_builtin_fn(g, BuiltinFnIdUnionInit, "unionInit", 3); 8301 create_builtin_fn(g, BuiltinFnIdFrameHandle, "frame", 0); 8302 create_builtin_fn(g, BuiltinFnIdFrameType, "Frame", 1); 8303 create_builtin_fn(g, BuiltinFnIdFrameAddress, "frameAddress", 0); 8304 create_builtin_fn(g, BuiltinFnIdFrameSize, "frameSize", 1); 8305 create_builtin_fn(g, BuiltinFnIdAs, "as", 2); 8306 create_builtin_fn(g, BuiltinFnIdCall, "call", 3); 8307 create_builtin_fn(g, BuiltinFnIdBitSizeof, "bitSizeOf", 1); 8308 } 8309 8310 static const char *bool_to_str(bool b) { 8311 return b ? "true" : "false"; 8312 } 8313 8314 static const char *build_mode_to_str(BuildMode build_mode) { 8315 switch (build_mode) { 8316 case BuildModeDebug: return "Mode.Debug"; 8317 case BuildModeSafeRelease: return "Mode.ReleaseSafe"; 8318 case BuildModeFastRelease: return "Mode.ReleaseFast"; 8319 case BuildModeSmallRelease: return "Mode.ReleaseSmall"; 8320 } 8321 zig_unreachable(); 8322 } 8323 8324 static const char *subsystem_to_str(TargetSubsystem subsystem) { 8325 switch (subsystem) { 8326 case TargetSubsystemConsole: return "Console"; 8327 case TargetSubsystemWindows: return "Windows"; 8328 case TargetSubsystemPosix: return "Posix"; 8329 case TargetSubsystemNative: return "Native"; 8330 case TargetSubsystemEfiApplication: return "EfiApplication"; 8331 case TargetSubsystemEfiBootServiceDriver: return "EfiBootServiceDriver"; 8332 case TargetSubsystemEfiRom: return "EfiRom"; 8333 case TargetSubsystemEfiRuntimeDriver: return "EfiRuntimeDriver"; 8334 case TargetSubsystemAuto: zig_unreachable(); 8335 } 8336 zig_unreachable(); 8337 } 8338 8339 static bool detect_dynamic_link(CodeGen *g) { 8340 if (g->is_dynamic) 8341 return true; 8342 if (g->zig_target->os == OsFreestanding) 8343 return false; 8344 if (target_requires_pic(g->zig_target, g->libc_link_lib != nullptr)) 8345 return true; 8346 // If there are no dynamic libraries then we can disable PIC 8347 for (size_t i = 0; i < g->link_libs_list.length; i += 1) { 8348 LinkLib *link_lib = g->link_libs_list.at(i); 8349 if (target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name))) 8350 continue; 8351 return true; 8352 } 8353 return false; 8354 } 8355 8356 static bool detect_pic(CodeGen *g) { 8357 if (target_requires_pic(g->zig_target, g->libc_link_lib != nullptr)) 8358 return true; 8359 switch (g->want_pic) { 8360 case WantPICDisabled: 8361 return false; 8362 case WantPICEnabled: 8363 return true; 8364 case WantPICAuto: 8365 return g->have_dynamic_link; 8366 } 8367 zig_unreachable(); 8368 } 8369 8370 static bool detect_stack_probing(CodeGen *g) { 8371 if (!target_supports_stack_probing(g->zig_target)) 8372 return false; 8373 switch (g->want_stack_check) { 8374 case WantStackCheckDisabled: 8375 return false; 8376 case WantStackCheckEnabled: 8377 return true; 8378 case WantStackCheckAuto: 8379 return g->build_mode == BuildModeSafeRelease || g->build_mode == BuildModeDebug; 8380 } 8381 zig_unreachable(); 8382 } 8383 8384 static bool detect_sanitize_c(CodeGen *g) { 8385 if (!target_supports_sanitize_c(g->zig_target)) 8386 return false; 8387 switch (g->want_sanitize_c) { 8388 case WantCSanitizeDisabled: 8389 return false; 8390 case WantCSanitizeEnabled: 8391 return true; 8392 case WantCSanitizeAuto: 8393 return g->build_mode == BuildModeSafeRelease || g->build_mode == BuildModeDebug; 8394 } 8395 zig_unreachable(); 8396 } 8397 8398 // Returns TargetSubsystemAuto to mean "no subsystem" 8399 TargetSubsystem detect_subsystem(CodeGen *g) { 8400 if (g->subsystem != TargetSubsystemAuto) 8401 return g->subsystem; 8402 if (g->zig_target->os == OsWindows) { 8403 if (g->have_dllmain_crt_startup || (g->out_type == OutTypeLib && g->is_dynamic)) 8404 return TargetSubsystemAuto; 8405 if (g->have_c_main || g->is_test_build || g->have_winmain_crt_startup) 8406 return TargetSubsystemConsole; 8407 if (g->have_winmain) 8408 return TargetSubsystemWindows; 8409 } else if (g->zig_target->os == OsUefi) { 8410 return TargetSubsystemEfiApplication; 8411 } 8412 return TargetSubsystemAuto; 8413 } 8414 8415 static bool detect_single_threaded(CodeGen *g) { 8416 if (g->want_single_threaded) 8417 return true; 8418 if (target_is_single_threaded(g->zig_target)) { 8419 return true; 8420 } 8421 return false; 8422 } 8423 8424 static bool detect_err_ret_tracing(CodeGen *g) { 8425 return !g->strip_debug_symbols && 8426 g->build_mode != BuildModeFastRelease && 8427 g->build_mode != BuildModeSmallRelease; 8428 } 8429 8430 Buf *codegen_generate_builtin_source(CodeGen *g) { 8431 g->have_dynamic_link = detect_dynamic_link(g); 8432 g->have_pic = detect_pic(g); 8433 g->have_stack_probing = detect_stack_probing(g); 8434 g->have_sanitize_c = detect_sanitize_c(g); 8435 g->is_single_threaded = detect_single_threaded(g); 8436 g->have_err_ret_tracing = detect_err_ret_tracing(g); 8437 8438 Buf *contents = buf_alloc(); 8439 buf_appendf(contents, "usingnamespace @import(\"std\").builtin;\n\n"); 8440 8441 const char *cur_os = nullptr; 8442 { 8443 uint32_t field_count = (uint32_t)target_os_count(); 8444 for (uint32_t i = 0; i < field_count; i += 1) { 8445 Os os_type = target_os_enum(i); 8446 const char *name = target_os_name(os_type); 8447 8448 if (os_type == g->zig_target->os) { 8449 g->target_os_index = i; 8450 cur_os = name; 8451 } 8452 } 8453 } 8454 assert(cur_os != nullptr); 8455 8456 const char *cur_arch = nullptr; 8457 { 8458 uint32_t field_count = (uint32_t)target_arch_count(); 8459 for (uint32_t arch_i = 0; arch_i < field_count; arch_i += 1) { 8460 ZigLLVM_ArchType arch = target_arch_enum(arch_i); 8461 const char *arch_name = target_arch_name(arch); 8462 SubArchList sub_arch_list = target_subarch_list(arch); 8463 if (sub_arch_list == SubArchListNone) { 8464 if (arch == g->zig_target->arch) { 8465 g->target_arch_index = arch_i; 8466 cur_arch = buf_ptr(buf_sprintf("Arch.%s", arch_name)); 8467 } 8468 } else { 8469 const char *sub_arch_list_name = target_subarch_list_name(sub_arch_list); 8470 if (arch == g->zig_target->arch) { 8471 size_t sub_count = target_subarch_count(sub_arch_list); 8472 for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) { 8473 ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i); 8474 if (sub == g->zig_target->sub_arch) { 8475 g->target_sub_arch_index = sub_i; 8476 cur_arch = buf_ptr(buf_sprintf("Arch{ .%s = Arch.%s.%s }", 8477 arch_name, sub_arch_list_name, target_subarch_name(sub))); 8478 } 8479 } 8480 } 8481 } 8482 } 8483 } 8484 assert(cur_arch != nullptr); 8485 8486 const char *cur_abi = nullptr; 8487 { 8488 uint32_t field_count = (uint32_t)target_abi_count(); 8489 for (uint32_t i = 0; i < field_count; i += 1) { 8490 ZigLLVM_EnvironmentType abi = target_abi_enum(i); 8491 const char *name = target_abi_name(abi); 8492 8493 if (abi == g->zig_target->abi) { 8494 g->target_abi_index = i; 8495 cur_abi = name; 8496 } 8497 } 8498 } 8499 assert(cur_abi != nullptr); 8500 8501 const char *cur_obj_fmt = nullptr; 8502 { 8503 uint32_t field_count = (uint32_t)target_oformat_count(); 8504 for (uint32_t i = 0; i < field_count; i += 1) { 8505 ZigLLVM_ObjectFormatType oformat = target_oformat_enum(i); 8506 const char *name = target_oformat_name(oformat); 8507 8508 ZigLLVM_ObjectFormatType target_oformat = target_object_format(g->zig_target); 8509 if (oformat == target_oformat) { 8510 g->target_oformat_index = i; 8511 cur_obj_fmt = name; 8512 } 8513 } 8514 8515 } 8516 assert(cur_obj_fmt != nullptr); 8517 8518 // If any of these asserts trip then you need to either fix the internal compiler enum 8519 // or the corresponding one in std.Target or std.builtin. 8520 static_assert(ContainerLayoutAuto == 0, ""); 8521 static_assert(ContainerLayoutExtern == 1, ""); 8522 static_assert(ContainerLayoutPacked == 2, ""); 8523 8524 static_assert(CallingConventionUnspecified == 0, ""); 8525 static_assert(CallingConventionC == 1, ""); 8526 static_assert(CallingConventionCold == 2, ""); 8527 static_assert(CallingConventionNaked == 3, ""); 8528 static_assert(CallingConventionAsync == 4, ""); 8529 static_assert(CallingConventionInterrupt == 5, ""); 8530 static_assert(CallingConventionSignal == 6, ""); 8531 static_assert(CallingConventionStdcall == 7, ""); 8532 static_assert(CallingConventionFastcall == 8, ""); 8533 static_assert(CallingConventionVectorcall == 9, ""); 8534 static_assert(CallingConventionThiscall == 10, ""); 8535 static_assert(CallingConventionAPCS == 11, ""); 8536 static_assert(CallingConventionAAPCS == 12, ""); 8537 static_assert(CallingConventionAAPCSVFP == 13, ""); 8538 8539 static_assert(FnInlineAuto == 0, ""); 8540 static_assert(FnInlineAlways == 1, ""); 8541 static_assert(FnInlineNever == 2, ""); 8542 8543 static_assert(BuiltinPtrSizeOne == 0, ""); 8544 static_assert(BuiltinPtrSizeMany == 1, ""); 8545 static_assert(BuiltinPtrSizeSlice == 2, ""); 8546 static_assert(BuiltinPtrSizeC == 3, ""); 8547 8548 static_assert(TargetSubsystemConsole == 0, ""); 8549 static_assert(TargetSubsystemWindows == 1, ""); 8550 static_assert(TargetSubsystemPosix == 2, ""); 8551 static_assert(TargetSubsystemNative == 3, ""); 8552 static_assert(TargetSubsystemEfiApplication == 4, ""); 8553 static_assert(TargetSubsystemEfiBootServiceDriver == 5, ""); 8554 static_assert(TargetSubsystemEfiRom == 6, ""); 8555 static_assert(TargetSubsystemEfiRuntimeDriver == 7, ""); 8556 { 8557 const char *endian_str = g->is_big_endian ? "Endian.Big" : "Endian.Little"; 8558 buf_appendf(contents, "pub const endian = %s;\n", endian_str); 8559 } 8560 const char *out_type = nullptr; 8561 switch (g->out_type) { 8562 case OutTypeExe: 8563 out_type = "Exe"; 8564 break; 8565 case OutTypeLib: 8566 out_type = "Lib"; 8567 break; 8568 case OutTypeObj: 8569 case OutTypeUnknown: // This happens when running the `zig builtin` command. 8570 out_type = "Obj"; 8571 break; 8572 } 8573 buf_appendf(contents, "pub const output_mode = OutputMode.%s;\n", out_type); 8574 const char *link_type = g->is_dynamic ? "Dynamic" : "Static"; 8575 buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", link_type); 8576 buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build)); 8577 buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded)); 8578 buf_appendf(contents, "pub const os = Os.%s;\n", cur_os); 8579 buf_appendf(contents, "pub const arch = %s;\n", cur_arch); 8580 buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi); 8581 if (g->libc_link_lib != nullptr && g->zig_target->glibc_version != nullptr) { 8582 buf_appendf(contents, 8583 "pub const glibc_version: ?Version = Version{.major = %d, .minor = %d, .patch = %d};\n", 8584 g->zig_target->glibc_version->major, 8585 g->zig_target->glibc_version->minor, 8586 g->zig_target->glibc_version->patch); 8587 } else { 8588 buf_appendf(contents, "pub const glibc_version: ?Version = null;\n"); 8589 } 8590 buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt); 8591 buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode)); 8592 buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->libc_link_lib != nullptr)); 8593 buf_appendf(contents, "pub const have_error_return_tracing = %s;\n", bool_to_str(g->have_err_ret_tracing)); 8594 buf_appendf(contents, "pub const valgrind_support = %s;\n", bool_to_str(want_valgrind_support(g))); 8595 buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic)); 8596 buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols)); 8597 8598 { 8599 TargetSubsystem detected_subsystem = detect_subsystem(g); 8600 if (detected_subsystem != TargetSubsystemAuto) { 8601 buf_appendf(contents, "pub const explicit_subsystem = SubSystem.%s;\n", subsystem_to_str(detected_subsystem)); 8602 } 8603 } 8604 8605 if (g->is_test_build) { 8606 buf_appendf(contents, 8607 "pub var test_functions: []TestFn = undefined; // overwritten later\n" 8608 ); 8609 } 8610 8611 return contents; 8612 } 8613 8614 static ZigPackage *create_test_runner_pkg(CodeGen *g) { 8615 return codegen_create_package(g, buf_ptr(g->zig_std_special_dir), "test_runner.zig", "std.special"); 8616 } 8617 8618 static Error define_builtin_compile_vars(CodeGen *g) { 8619 if (g->std_package == nullptr) 8620 return ErrorNone; 8621 8622 Error err; 8623 8624 Buf *manifest_dir = buf_alloc(); 8625 os_path_join(get_global_cache_dir(), buf_create_from_str("builtin"), manifest_dir); 8626 8627 CacheHash cache_hash; 8628 cache_init(&cache_hash, manifest_dir); 8629 8630 Buf *compiler_id; 8631 if ((err = get_compiler_id(&compiler_id))) 8632 return err; 8633 8634 // Only a few things affect builtin.zig 8635 cache_buf(&cache_hash, compiler_id); 8636 cache_int(&cache_hash, g->build_mode); 8637 cache_bool(&cache_hash, g->strip_debug_symbols); 8638 cache_int(&cache_hash, g->out_type); 8639 cache_bool(&cache_hash, g->is_dynamic); 8640 cache_bool(&cache_hash, g->is_test_build); 8641 cache_bool(&cache_hash, g->is_single_threaded); 8642 cache_int(&cache_hash, g->zig_target->is_native); 8643 cache_int(&cache_hash, g->zig_target->arch); 8644 cache_int(&cache_hash, g->zig_target->sub_arch); 8645 cache_int(&cache_hash, g->zig_target->vendor); 8646 cache_int(&cache_hash, g->zig_target->os); 8647 cache_int(&cache_hash, g->zig_target->abi); 8648 if (g->zig_target->glibc_version != nullptr) { 8649 cache_int(&cache_hash, g->zig_target->glibc_version->major); 8650 cache_int(&cache_hash, g->zig_target->glibc_version->minor); 8651 cache_int(&cache_hash, g->zig_target->glibc_version->patch); 8652 } 8653 cache_bool(&cache_hash, g->have_err_ret_tracing); 8654 cache_bool(&cache_hash, g->libc_link_lib != nullptr); 8655 cache_bool(&cache_hash, g->valgrind_support); 8656 cache_bool(&cache_hash, g->link_eh_frame_hdr); 8657 cache_int(&cache_hash, detect_subsystem(g)); 8658 if (g->llvm_cpu) cache_str(&cache_hash, g->llvm_cpu); 8659 if (g->llvm_features) cache_str(&cache_hash, g->llvm_features); 8660 8661 Buf digest = BUF_INIT; 8662 buf_resize(&digest, 0); 8663 if ((err = cache_hit(&cache_hash, &digest))) { 8664 // Treat an invalid format error as a cache miss. 8665 if (err != ErrorInvalidFormat) 8666 return err; 8667 } 8668 8669 // We should always get a cache hit because there are no 8670 // files in the input hash. 8671 assert(buf_len(&digest) != 0); 8672 8673 Buf *this_dir = buf_alloc(); 8674 os_path_join(manifest_dir, &digest, this_dir); 8675 8676 if ((err = os_make_path(this_dir))) 8677 return err; 8678 8679 const char *builtin_zig_basename = "builtin.zig"; 8680 Buf *builtin_zig_path = buf_alloc(); 8681 os_path_join(this_dir, buf_create_from_str(builtin_zig_basename), builtin_zig_path); 8682 8683 bool hit; 8684 if ((err = os_file_exists(builtin_zig_path, &hit))) 8685 return err; 8686 Buf *contents; 8687 if (hit) { 8688 contents = buf_alloc(); 8689 if ((err = os_fetch_file_path(builtin_zig_path, contents))) { 8690 fprintf(stderr, "Unable to open '%s': %s\n", buf_ptr(builtin_zig_path), err_str(err)); 8691 exit(1); 8692 } 8693 } else { 8694 contents = codegen_generate_builtin_source(g); 8695 if ((err = os_write_file(builtin_zig_path, contents))) { 8696 fprintf(stderr, "Unable to write file '%s': %s\n", buf_ptr(builtin_zig_path), err_str(err)); 8697 exit(1); 8698 } 8699 } 8700 8701 assert(g->main_pkg); 8702 assert(g->std_package); 8703 g->compile_var_package = new_package(buf_ptr(this_dir), builtin_zig_basename, "builtin"); 8704 if (g->is_test_build) { 8705 if (g->test_runner_package == nullptr) { 8706 g->test_runner_package = create_test_runner_pkg(g); 8707 } 8708 g->root_pkg = g->test_runner_package; 8709 } else { 8710 g->root_pkg = g->main_pkg; 8711 } 8712 g->compile_var_package->package_table.put(buf_create_from_str("std"), g->std_package); 8713 g->main_pkg->package_table.put(buf_create_from_str("builtin"), g->compile_var_package); 8714 g->main_pkg->package_table.put(buf_create_from_str("root"), g->root_pkg); 8715 g->std_package->package_table.put(buf_create_from_str("builtin"), g->compile_var_package); 8716 g->std_package->package_table.put(buf_create_from_str("std"), g->std_package); 8717 g->std_package->package_table.put(buf_create_from_str("root"), g->root_pkg); 8718 g->compile_var_import = add_source_file(g, g->compile_var_package, builtin_zig_path, contents, 8719 SourceKindPkgMain); 8720 8721 return ErrorNone; 8722 } 8723 8724 static void init(CodeGen *g) { 8725 if (g->module) 8726 return; 8727 8728 g->have_dynamic_link = detect_dynamic_link(g); 8729 g->have_pic = detect_pic(g); 8730 g->have_stack_probing = detect_stack_probing(g); 8731 g->have_sanitize_c = detect_sanitize_c(g); 8732 g->is_single_threaded = detect_single_threaded(g); 8733 g->have_err_ret_tracing = detect_err_ret_tracing(g); 8734 8735 if (target_is_single_threaded(g->zig_target)) { 8736 g->is_single_threaded = true; 8737 } 8738 8739 assert(g->root_out_name); 8740 g->module = LLVMModuleCreateWithName(buf_ptr(g->root_out_name)); 8741 8742 LLVMSetTarget(g->module, buf_ptr(&g->llvm_triple_str)); 8743 8744 if (target_object_format(g->zig_target) == ZigLLVM_COFF) { 8745 ZigLLVMAddModuleCodeViewFlag(g->module); 8746 } else { 8747 ZigLLVMAddModuleDebugInfoFlag(g->module); 8748 } 8749 8750 LLVMTargetRef target_ref; 8751 char *err_msg = nullptr; 8752 if (LLVMGetTargetFromTriple(buf_ptr(&g->llvm_triple_str), &target_ref, &err_msg)) { 8753 fprintf(stderr, 8754 "Zig is expecting LLVM to understand this target: '%s'\n" 8755 "However LLVM responded with: \"%s\"\n" 8756 "Zig is unable to continue. This is a bug in Zig:\n" 8757 "https://github.com/ziglang/zig/issues/438\n" 8758 , buf_ptr(&g->llvm_triple_str), err_msg); 8759 exit(1); 8760 } 8761 8762 bool is_optimized = g->build_mode != BuildModeDebug; 8763 LLVMCodeGenOptLevel opt_level = is_optimized ? LLVMCodeGenLevelAggressive : LLVMCodeGenLevelNone; 8764 8765 LLVMRelocMode reloc_mode; 8766 if (g->have_pic) { 8767 reloc_mode = LLVMRelocPIC; 8768 } else if (g->have_dynamic_link) { 8769 reloc_mode = LLVMRelocDynamicNoPic; 8770 } else { 8771 reloc_mode = LLVMRelocStatic; 8772 } 8773 8774 const char *target_specific_cpu_args; 8775 const char *target_specific_features; 8776 if (g->zig_target->is_native) { 8777 // LLVM creates invalid binaries on Windows sometimes. 8778 // See https://github.com/ziglang/zig/issues/508 8779 // As a workaround we do not use target native features on Windows. 8780 if (g->zig_target->os == OsWindows || g->zig_target->os == OsUefi) { 8781 target_specific_cpu_args = ""; 8782 target_specific_features = ""; 8783 } else { 8784 target_specific_cpu_args = ZigLLVMGetHostCPUName(); 8785 target_specific_features = ZigLLVMGetNativeFeatures(); 8786 } 8787 } else if (target_is_riscv(g->zig_target)) { 8788 // TODO https://github.com/ziglang/zig/issues/2883 8789 // Be aware of https://github.com/ziglang/zig/issues/3275 8790 target_specific_cpu_args = ""; 8791 target_specific_features = riscv_default_features; 8792 } else if (g->zig_target->arch == ZigLLVM_x86) { 8793 // This is because we're really targeting i686 rather than i386. 8794 // It's pretty much impossible to use many of the language features 8795 // such as fp16 if you stick use the x87 only. This is also what clang 8796 // uses as base cpu. 8797 // TODO https://github.com/ziglang/zig/issues/2883 8798 target_specific_cpu_args = "pentium4"; 8799 target_specific_features = (g->zig_target->os == OsFreestanding) ? "-sse": ""; 8800 } else { 8801 target_specific_cpu_args = ""; 8802 target_specific_features = ""; 8803 } 8804 8805 // Override CPU and features if non-null. 8806 if (g->llvm_cpu != nullptr) { 8807 target_specific_cpu_args = g->llvm_cpu; 8808 } 8809 8810 if (g->llvm_features != nullptr) { 8811 target_specific_features = g->llvm_features; 8812 } 8813 8814 g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str), 8815 target_specific_cpu_args, target_specific_features, opt_level, reloc_mode, 8816 LLVMCodeModelDefault, g->function_sections); 8817 8818 g->target_data_ref = LLVMCreateTargetDataLayout(g->target_machine); 8819 8820 char *layout_str = LLVMCopyStringRepOfTargetData(g->target_data_ref); 8821 LLVMSetDataLayout(g->module, layout_str); 8822 8823 8824 assert(g->pointer_size_bytes == LLVMPointerSize(g->target_data_ref)); 8825 g->is_big_endian = (LLVMByteOrder(g->target_data_ref) == LLVMBigEndian); 8826 8827 g->builder = LLVMCreateBuilder(); 8828 g->dbuilder = ZigLLVMCreateDIBuilder(g->module, true); 8829 8830 // Don't use ZIG_VERSION_STRING here, llvm misparses it when it includes 8831 // the git revision. 8832 Buf *producer = buf_sprintf("zig %d.%d.%d", ZIG_VERSION_MAJOR, ZIG_VERSION_MINOR, ZIG_VERSION_PATCH); 8833 const char *flags = ""; 8834 unsigned runtime_version = 0; 8835 8836 // For macOS stack traces, we want to avoid having to parse the compilation unit debug 8837 // info. As long as each debug info file has a path independent of the compilation unit 8838 // directory (DW_AT_comp_dir), then we never have to look at the compilation unit debug 8839 // info. If we provide an absolute path to LLVM here for the compilation unit debug info, 8840 // LLVM will emit DWARF info that depends on DW_AT_comp_dir. To avoid this, we pass "." 8841 // for the compilation unit directory. This forces each debug file to have a directory 8842 // rather than be relative to DW_AT_comp_dir. According to DWARF 5, debug files will 8843 // no longer reference DW_AT_comp_dir, for the purpose of being able to support the 8844 // common practice of stripping all but the line number sections from an executable. 8845 const char *compile_unit_dir = target_os_is_darwin(g->zig_target->os) ? "." : 8846 buf_ptr(&g->main_pkg->root_src_dir); 8847 8848 ZigLLVMDIFile *compile_unit_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(g->root_out_name), 8849 compile_unit_dir); 8850 g->compile_unit = ZigLLVMCreateCompileUnit(g->dbuilder, ZigLLVMLang_DW_LANG_C99(), 8851 compile_unit_file, buf_ptr(producer), is_optimized, flags, runtime_version, 8852 "", 0, !g->strip_debug_symbols); 8853 8854 // This is for debug stuff that doesn't have a real file. 8855 g->dummy_di_file = nullptr; 8856 8857 define_builtin_types(g); 8858 define_intern_values(g); 8859 8860 IrInstruction *sentinel_instructions = allocate<IrInstruction>(2); 8861 g->invalid_instruction = &sentinel_instructions[0]; 8862 g->invalid_instruction->value = allocate<ZigValue>(1, "ZigValue"); 8863 g->invalid_instruction->value->type = g->builtin_types.entry_invalid; 8864 8865 g->unreach_instruction = &sentinel_instructions[1]; 8866 g->unreach_instruction->value = allocate<ZigValue>(1, "ZigValue"); 8867 g->unreach_instruction->value->type = g->builtin_types.entry_unreachable; 8868 8869 define_builtin_fns(g); 8870 Error err; 8871 if ((err = define_builtin_compile_vars(g))) { 8872 fprintf(stderr, "Unable to create builtin.zig: %s\n", err_str(err)); 8873 exit(1); 8874 } 8875 } 8876 8877 static void detect_dynamic_linker(CodeGen *g) { 8878 if (g->dynamic_linker_path != nullptr) 8879 return; 8880 if (!g->have_dynamic_link) 8881 return; 8882 if (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic)) 8883 return; 8884 8885 const char *standard_ld_path = target_dynamic_linker(g->zig_target); 8886 if (standard_ld_path == nullptr) 8887 return; 8888 8889 if (g->zig_target->is_native) { 8890 // target_dynamic_linker is usually correct. However on some systems, such as NixOS 8891 // it will be incorrect. See if we can do better by looking at what zig's own 8892 // dynamic linker path is. 8893 g->dynamic_linker_path = get_self_dynamic_linker_path(); 8894 if (g->dynamic_linker_path != nullptr) 8895 return; 8896 8897 // If Zig is statically linked, such as via distributed binary static builds, the above 8898 // trick won't work. What are we left with? Try to run the system C compiler and get 8899 // it to tell us the dynamic linker path 8900 #if defined(ZIG_OS_LINUX) 8901 { 8902 Error err; 8903 Buf *result = buf_alloc(); 8904 for (size_t i = 0; possible_ld_names[i] != NULL; i += 1) { 8905 const char *lib_name = possible_ld_names[i]; 8906 if ((err = zig_libc_cc_print_file_name(lib_name, result, false, true))) { 8907 if (err != ErrorCCompilerCannotFindFile && err != ErrorNoCCompilerInstalled) { 8908 fprintf(stderr, "Unable to detect native dynamic linker: %s\n", err_str(err)); 8909 exit(1); 8910 } 8911 continue; 8912 } 8913 g->dynamic_linker_path = result; 8914 return; 8915 } 8916 } 8917 #endif 8918 } 8919 8920 g->dynamic_linker_path = buf_create_from_str(standard_ld_path); 8921 } 8922 8923 static void detect_libc(CodeGen *g) { 8924 Error err; 8925 8926 if (g->libc != nullptr || g->libc_link_lib == nullptr) 8927 return; 8928 8929 if (target_can_build_libc(g->zig_target)) { 8930 const char *generic_name = target_libc_generic_name(g->zig_target); 8931 const char *arch_name = target_arch_name(g->zig_target->arch); 8932 const char *abi_name = target_abi_name(g->zig_target->abi); 8933 if (target_is_musl(g->zig_target)) { 8934 // musl has some overrides. its headers are ABI-agnostic and so they all have the "musl" ABI name. 8935 abi_name = "musl"; 8936 // some architectures are handled by the same set of headers 8937 arch_name = target_arch_musl_name(g->zig_target->arch); 8938 } 8939 Buf *arch_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-%s-%s", 8940 buf_ptr(g->zig_lib_dir), arch_name, target_os_name(g->zig_target->os), abi_name); 8941 Buf *generic_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "generic-%s", 8942 buf_ptr(g->zig_lib_dir), generic_name); 8943 Buf *arch_os_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "%s-%s-any", 8944 buf_ptr(g->zig_lib_dir), target_arch_name(g->zig_target->arch), target_os_name(g->zig_target->os)); 8945 Buf *generic_os_include_dir = buf_sprintf("%s" OS_SEP "libc" OS_SEP "include" OS_SEP "any-%s-any", 8946 buf_ptr(g->zig_lib_dir), target_os_name(g->zig_target->os)); 8947 8948 g->libc_include_dir_len = 4; 8949 g->libc_include_dir_list = allocate<Buf*>(g->libc_include_dir_len); 8950 g->libc_include_dir_list[0] = arch_include_dir; 8951 g->libc_include_dir_list[1] = generic_include_dir; 8952 g->libc_include_dir_list[2] = arch_os_include_dir; 8953 g->libc_include_dir_list[3] = generic_os_include_dir; 8954 return; 8955 } 8956 8957 if (g->zig_target->is_native) { 8958 g->libc = allocate<ZigLibCInstallation>(1); 8959 8960 // search for native_libc.txt in following dirs: 8961 // - LOCAL_CACHE_DIR 8962 // - GLOBAL_CACHE_DIR 8963 // if not found create at: 8964 // - GLOBAL_CACHE_DIR 8965 // be mindful local/global caches may be the same dir 8966 8967 Buf basename = BUF_INIT; 8968 buf_init_from_str(&basename, "native_libc.txt"); 8969 8970 Buf local_libc_txt = BUF_INIT; 8971 os_path_join(g->cache_dir, &basename, &local_libc_txt); 8972 8973 Buf global_libc_txt = BUF_INIT; 8974 os_path_join(get_global_cache_dir(), &basename, &global_libc_txt); 8975 8976 Buf *pathnames[3] = { nullptr }; 8977 size_t pathnames_idx = 0; 8978 8979 pathnames[pathnames_idx] = &local_libc_txt; 8980 pathnames_idx += 1; 8981 8982 if (!buf_eql_buf(pathnames[0], &global_libc_txt)) { 8983 pathnames[pathnames_idx] = &global_libc_txt; 8984 pathnames_idx += 1; 8985 } 8986 8987 Buf* libc_txt = nullptr; 8988 for (auto name : pathnames) { 8989 if (name == nullptr) 8990 break; 8991 8992 bool result; 8993 if (os_file_exists(name, &result) != ErrorNone || !result) 8994 continue; 8995 8996 libc_txt = name; 8997 break; 8998 } 8999 9000 if (libc_txt == nullptr) 9001 libc_txt = &global_libc_txt; 9002 9003 if ((err = zig_libc_parse(g->libc, libc_txt, g->zig_target, false))) { 9004 if ((err = zig_libc_find_native(g->libc, true))) { 9005 fprintf(stderr, 9006 "Unable to link against libc: Unable to find libc installation: %s\n" 9007 "See `zig libc --help` for more details.\n", err_str(err)); 9008 exit(1); 9009 } 9010 if ((err = os_make_path(g->cache_dir))) { 9011 fprintf(stderr, "Unable to create %s directory: %s\n", 9012 buf_ptr(g->cache_dir), err_str(err)); 9013 exit(1); 9014 } 9015 Buf *native_libc_tmp = buf_sprintf("%s.tmp", buf_ptr(libc_txt)); 9016 FILE *file = fopen(buf_ptr(native_libc_tmp), "wb"); 9017 if (file == nullptr) { 9018 fprintf(stderr, "Unable to open %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno)); 9019 exit(1); 9020 } 9021 zig_libc_render(g->libc, file); 9022 if (fclose(file) != 0) { 9023 fprintf(stderr, "Unable to save %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno)); 9024 exit(1); 9025 } 9026 if ((err = os_rename(native_libc_tmp, libc_txt))) { 9027 fprintf(stderr, "Unable to create %s: %s\n", buf_ptr(libc_txt), err_str(err)); 9028 exit(1); 9029 } 9030 } 9031 bool want_sys_dir = !buf_eql_buf(&g->libc->include_dir, &g->libc->sys_include_dir); 9032 size_t want_um_and_shared_dirs = (g->zig_target->os == OsWindows) ? 2 : 0; 9033 size_t dir_count = 1 + want_sys_dir + want_um_and_shared_dirs; 9034 g->libc_include_dir_len = 0; 9035 g->libc_include_dir_list = allocate<Buf*>(dir_count); 9036 9037 g->libc_include_dir_list[g->libc_include_dir_len] = &g->libc->include_dir; 9038 g->libc_include_dir_len += 1; 9039 9040 if (want_sys_dir) { 9041 g->libc_include_dir_list[g->libc_include_dir_len] = &g->libc->sys_include_dir; 9042 g->libc_include_dir_len += 1; 9043 } 9044 9045 if (want_um_and_shared_dirs != 0) { 9046 g->libc_include_dir_list[g->libc_include_dir_len] = buf_sprintf("%s" OS_SEP ".." OS_SEP "um", 9047 buf_ptr(&g->libc->include_dir)); 9048 g->libc_include_dir_len += 1; 9049 9050 g->libc_include_dir_list[g->libc_include_dir_len] = buf_sprintf("%s" OS_SEP ".." OS_SEP "shared", 9051 buf_ptr(&g->libc->include_dir)); 9052 g->libc_include_dir_len += 1; 9053 } 9054 assert(g->libc_include_dir_len == dir_count); 9055 9056 buf_deinit(&global_libc_txt); 9057 buf_deinit(&local_libc_txt); 9058 buf_deinit(&basename); 9059 } else if ((g->out_type == OutTypeExe || (g->out_type == OutTypeLib && g->is_dynamic)) && 9060 !target_os_is_darwin(g->zig_target->os)) 9061 { 9062 Buf triple_buf = BUF_INIT; 9063 target_triple_zig(&triple_buf, g->zig_target); 9064 fprintf(stderr, 9065 "Zig is unable to provide a libc for the chosen target '%s'.\n" 9066 "The target is non-native, so Zig also cannot use the native libc installation.\n" 9067 "Choose a target which has a libc available (see `zig targets`), or\n" 9068 "provide a libc installation text file (see `zig libc --help`).\n", buf_ptr(&triple_buf)); 9069 exit(1); 9070 } 9071 } 9072 9073 // does not add the "cc" arg 9074 void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_path, bool translate_c) { 9075 if (translate_c) { 9076 args.append("-x"); 9077 args.append("c"); 9078 } 9079 9080 if (out_dep_path != nullptr) { 9081 args.append("-MD"); 9082 args.append("-MV"); 9083 args.append("-MF"); 9084 args.append(out_dep_path); 9085 } 9086 9087 args.append("-nostdinc"); 9088 args.append("-fno-spell-checking"); 9089 9090 if (g->function_sections) { 9091 args.append("-ffunction-sections"); 9092 } 9093 9094 if (translate_c) { 9095 // this gives us access to preprocessing entities, presumably at 9096 // the cost of performance 9097 args.append("-Xclang"); 9098 args.append("-detailed-preprocessing-record"); 9099 } else { 9100 switch (g->err_color) { 9101 case ErrColorAuto: 9102 break; 9103 case ErrColorOff: 9104 args.append("-fno-color-diagnostics"); 9105 args.append("-fno-caret-diagnostics"); 9106 break; 9107 case ErrColorOn: 9108 args.append("-fcolor-diagnostics"); 9109 args.append("-fcaret-diagnostics"); 9110 break; 9111 } 9112 } 9113 9114 for (size_t i = 0; i < g->framework_dirs.length; i += 1) { 9115 args.append("-iframework"); 9116 args.append(g->framework_dirs.at(i)); 9117 } 9118 9119 // According to Rich Felker libc headers are supposed to go before C language headers. 9120 // However as noted by @dimenus, appending libc headers before c_headers breaks intrinsics 9121 // and other compiler specific items. 9122 args.append("-isystem"); 9123 args.append(buf_ptr(g->zig_c_headers_dir)); 9124 9125 for (size_t i = 0; i < g->libc_include_dir_len; i += 1) { 9126 Buf *include_dir = g->libc_include_dir_list[i]; 9127 args.append("-isystem"); 9128 args.append(buf_ptr(include_dir)); 9129 } 9130 9131 if (g->zig_target->is_native) { 9132 if (target_supports_clang_march_native(g->zig_target)) { 9133 args.append("-march=native"); 9134 } 9135 } else { 9136 args.append("-target"); 9137 args.append(buf_ptr(&g->llvm_triple_str)); 9138 9139 if (target_is_musl(g->zig_target) && target_is_riscv(g->zig_target)) { 9140 // Musl depends on atomic instructions, which are disabled by default in Clang/LLVM's 9141 // cross compilation CPU info for RISCV. 9142 // TODO: https://github.com/ziglang/zig/issues/2883 9143 args.append("-Xclang"); 9144 args.append("-target-feature"); 9145 args.append("-Xclang"); 9146 args.append(riscv_default_features); 9147 } else if (g->zig_target->os == OsFreestanding && g->zig_target->arch == ZigLLVM_x86) { 9148 args.append("-Xclang"); 9149 args.append("-target-feature"); 9150 args.append("-Xclang"); 9151 args.append("-sse"); 9152 } 9153 } 9154 if (g->zig_target->os == OsFreestanding) { 9155 args.append("-ffreestanding"); 9156 } 9157 9158 // windows.h has files such as pshpack1.h which do #pragma packing, triggering a clang warning. 9159 // So for this target, we disable this warning. 9160 if (g->zig_target->os == OsWindows && target_abi_is_gnu(g->zig_target->abi)) { 9161 args.append("-Wno-pragma-pack"); 9162 } 9163 9164 if (!g->strip_debug_symbols) { 9165 args.append("-g"); 9166 } 9167 9168 if (codegen_have_frame_pointer(g)) { 9169 args.append("-fno-omit-frame-pointer"); 9170 } else { 9171 args.append("-fomit-frame-pointer"); 9172 } 9173 9174 if (g->have_sanitize_c) { 9175 args.append("-fsanitize=undefined"); 9176 args.append("-fsanitize-trap=undefined"); 9177 } 9178 9179 switch (g->build_mode) { 9180 case BuildModeDebug: 9181 // windows c runtime requires -D_DEBUG if using debug libraries 9182 args.append("-D_DEBUG"); 9183 9184 if (g->libc_link_lib != nullptr) { 9185 args.append("-fstack-protector-strong"); 9186 args.append("--param"); 9187 args.append("ssp-buffer-size=4"); 9188 } else { 9189 args.append("-fno-stack-protector"); 9190 } 9191 break; 9192 case BuildModeSafeRelease: 9193 // See the comment in the BuildModeFastRelease case for why we pass -O2 rather 9194 // than -O3 here. 9195 args.append("-O2"); 9196 if (g->libc_link_lib != nullptr) { 9197 args.append("-D_FORTIFY_SOURCE=2"); 9198 args.append("-fstack-protector-strong"); 9199 args.append("--param"); 9200 args.append("ssp-buffer-size=4"); 9201 } else { 9202 args.append("-fno-stack-protector"); 9203 } 9204 break; 9205 case BuildModeFastRelease: 9206 args.append("-DNDEBUG"); 9207 // Here we pass -O2 rather than -O3 because, although we do the equivalent of 9208 // -O3 in Zig code, the justification for the difference here is that Zig 9209 // has better detection and prevention of undefined behavior, so -O3 is safer for 9210 // Zig code than it is for C code. Also, C programmers are used to their code 9211 // running in -O2 and thus the -O3 path has been tested less. 9212 args.append("-O2"); 9213 args.append("-fno-stack-protector"); 9214 break; 9215 case BuildModeSmallRelease: 9216 args.append("-DNDEBUG"); 9217 args.append("-Os"); 9218 args.append("-fno-stack-protector"); 9219 break; 9220 } 9221 9222 if (target_supports_fpic(g->zig_target) && g->have_pic) { 9223 args.append("-fPIC"); 9224 } 9225 9226 for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) { 9227 args.append(g->clang_argv[arg_i]); 9228 } 9229 9230 } 9231 9232 void codegen_translate_c(CodeGen *g, Buf *full_path) { 9233 Error err; 9234 9235 Buf *src_basename = buf_alloc(); 9236 Buf *src_dirname = buf_alloc(); 9237 os_path_split(full_path, src_dirname, src_basename); 9238 9239 Buf noextname = BUF_INIT; 9240 os_path_extname(src_basename, &noextname, nullptr); 9241 9242 Buf *zig_basename = buf_sprintf("%s.zig", buf_ptr(&noextname)); 9243 9244 detect_libc(g); 9245 9246 Buf cache_digest = BUF_INIT; 9247 buf_resize(&cache_digest, 0); 9248 9249 CacheHash *cache_hash = nullptr; 9250 if (g->enable_cache) { 9251 if ((err = create_c_object_cache(g, &cache_hash, true))) { 9252 // Already printed error; verbose = true 9253 exit(1); 9254 } 9255 cache_file(cache_hash, full_path); 9256 // to distinguish from generating a C object 9257 cache_buf(cache_hash, buf_create_from_str("translate-c")); 9258 9259 if ((err = cache_hit(cache_hash, &cache_digest))) { 9260 if (err != ErrorInvalidFormat) { 9261 fprintf(stderr, "unable to check cache: %s\n", err_str(err)); 9262 exit(1); 9263 } 9264 } 9265 if (cache_hash->manifest_file_path != nullptr) { 9266 g->caches_to_release.append(cache_hash); 9267 } 9268 } 9269 9270 if (g->enable_cache && buf_len(&cache_digest) != 0) { 9271 // cache hit 9272 Buf *cached_path = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s" OS_SEP "%s", 9273 buf_ptr(g->cache_dir), buf_ptr(&cache_digest), buf_ptr(zig_basename)); 9274 fprintf(stdout, "%s\n", buf_ptr(cached_path)); 9275 return; 9276 } 9277 9278 // cache miss or cache disabled 9279 init(g); 9280 9281 Buf *out_dep_path = nullptr; 9282 const char *out_dep_path_cstr = nullptr; 9283 9284 if (g->enable_cache) { 9285 buf_alloc();// we can't know the digest until we do the C compiler invocation, so we 9286 // need a tmp filename. 9287 out_dep_path = buf_alloc(); 9288 if ((err = get_tmp_filename(g, out_dep_path, buf_sprintf("%s.d", buf_ptr(zig_basename))))) { 9289 fprintf(stderr, "unable to create tmp dir: %s\n", err_str(err)); 9290 exit(1); 9291 } 9292 out_dep_path_cstr = buf_ptr(out_dep_path); 9293 } 9294 9295 ZigList<const char *> clang_argv = {0}; 9296 add_cc_args(g, clang_argv, out_dep_path_cstr, true); 9297 9298 clang_argv.append(buf_ptr(full_path)); 9299 9300 if (g->verbose_cc) { 9301 fprintf(stderr, "clang"); 9302 for (size_t i = 0; i < clang_argv.length; i += 1) { 9303 fprintf(stderr, " %s", clang_argv.at(i)); 9304 } 9305 fprintf(stderr, "\n"); 9306 } 9307 9308 clang_argv.append(nullptr); // to make the [start...end] argument work 9309 9310 const char *resources_path = buf_ptr(g->zig_c_headers_dir); 9311 Stage2ErrorMsg *errors_ptr; 9312 size_t errors_len; 9313 Stage2Ast *ast; 9314 9315 err = stage2_translate_c(&ast, &errors_ptr, &errors_len, 9316 &clang_argv.at(0), &clang_argv.last(), resources_path); 9317 9318 if (err == ErrorCCompileErrors && errors_len > 0) { 9319 for (size_t i = 0; i < errors_len; i += 1) { 9320 Stage2ErrorMsg *clang_err = &errors_ptr[i]; 9321 9322 ErrorMsg *err_msg = err_msg_create_with_offset( 9323 clang_err->filename_ptr ? 9324 buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : nullptr, 9325 clang_err->line, clang_err->column, clang_err->offset, clang_err->source, 9326 buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len)); 9327 print_err_msg(err_msg, g->err_color); 9328 } 9329 exit(1); 9330 } 9331 9332 if (err) { 9333 fprintf(stderr, "unable to parse C file: %s\n", err_str(err)); 9334 exit(1); 9335 } 9336 9337 if (!g->enable_cache) { 9338 stage2_render_ast(ast, stdout); 9339 return; 9340 } 9341 9342 // add the files depended on to the cache system 9343 if ((err = cache_add_dep_file(cache_hash, out_dep_path, true))) { 9344 // Don't treat the absence of the .d file as a fatal error, the 9345 // compiler may not produce one eg. when compiling .s files 9346 if (err != ErrorFileNotFound) { 9347 fprintf(stderr, "Failed to add C source dependencies to cache: %s\n", err_str(err)); 9348 exit(1); 9349 } 9350 } 9351 if (err != ErrorFileNotFound) { 9352 os_delete_file(out_dep_path); 9353 } 9354 9355 if ((err = cache_final(cache_hash, &cache_digest))) { 9356 fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err)); 9357 exit(1); 9358 } 9359 9360 Buf *artifact_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s", 9361 buf_ptr(g->cache_dir), buf_ptr(&cache_digest)); 9362 9363 if ((err = os_make_path(artifact_dir))) { 9364 fprintf(stderr, "Unable to make dir: %s\n", err_str(err)); 9365 exit(1); 9366 } 9367 9368 Buf *cached_path = buf_sprintf("%s" OS_SEP "%s", buf_ptr(artifact_dir), buf_ptr(zig_basename)); 9369 9370 FILE *out_file = fopen(buf_ptr(cached_path), "wb"); 9371 if (out_file == nullptr) { 9372 fprintf(stderr, "Unable to open output file: %s\n", strerror(errno)); 9373 exit(1); 9374 } 9375 stage2_render_ast(ast, out_file); 9376 if (fclose(out_file) != 0) { 9377 fprintf(stderr, "Unable to write to output file: %s\n", strerror(errno)); 9378 exit(1); 9379 } 9380 fprintf(stdout, "%s\n", buf_ptr(cached_path)); 9381 } 9382 9383 static void update_test_functions_builtin_decl(CodeGen *g) { 9384 Error err; 9385 9386 assert(g->is_test_build); 9387 9388 if (g->test_fns.length == 0) { 9389 fprintf(stderr, "No tests to run.\n"); 9390 exit(0); 9391 } 9392 9393 ZigType *fn_type = get_test_fn_type(g); 9394 9395 ZigValue *test_fn_type_val = get_builtin_value(g, "TestFn"); 9396 assert(test_fn_type_val->type->id == ZigTypeIdMetaType); 9397 ZigType *struct_type = test_fn_type_val->data.x_type; 9398 if ((err = type_resolve(g, struct_type, ResolveStatusSizeKnown))) 9399 zig_unreachable(); 9400 9401 ZigValue *test_fn_array = create_const_vals(1); 9402 test_fn_array->type = get_array_type(g, struct_type, g->test_fns.length, nullptr); 9403 test_fn_array->special = ConstValSpecialStatic; 9404 test_fn_array->data.x_array.data.s_none.elements = create_const_vals(g->test_fns.length); 9405 9406 for (size_t i = 0; i < g->test_fns.length; i += 1) { 9407 ZigFn *test_fn_entry = g->test_fns.at(i); 9408 9409 if (fn_is_async(test_fn_entry)) { 9410 ErrorMsg *msg = add_node_error(g, test_fn_entry->proto_node, 9411 buf_create_from_str("test functions cannot be async")); 9412 add_error_note(g, msg, test_fn_entry->proto_node, 9413 buf_sprintf("this restriction may be lifted in the future. See https://github.com/ziglang/zig/issues/3117 for more details")); 9414 add_async_error_notes(g, msg, test_fn_entry); 9415 continue; 9416 } 9417 9418 ZigValue *this_val = &test_fn_array->data.x_array.data.s_none.elements[i]; 9419 this_val->special = ConstValSpecialStatic; 9420 this_val->type = struct_type; 9421 this_val->parent.id = ConstParentIdArray; 9422 this_val->parent.data.p_array.array_val = test_fn_array; 9423 this_val->parent.data.p_array.elem_index = i; 9424 this_val->data.x_struct.fields = alloc_const_vals_ptrs(2); 9425 9426 ZigValue *name_field = this_val->data.x_struct.fields[0]; 9427 ZigValue *name_array_val = create_const_str_lit(g, &test_fn_entry->symbol_name)->data.x_ptr.data.ref.pointee; 9428 init_const_slice(g, name_field, name_array_val, 0, buf_len(&test_fn_entry->symbol_name), true); 9429 9430 ZigValue *fn_field = this_val->data.x_struct.fields[1]; 9431 fn_field->type = fn_type; 9432 fn_field->special = ConstValSpecialStatic; 9433 fn_field->data.x_ptr.special = ConstPtrSpecialFunction; 9434 fn_field->data.x_ptr.mut = ConstPtrMutComptimeConst; 9435 fn_field->data.x_ptr.data.fn.fn_entry = test_fn_entry; 9436 } 9437 report_errors_and_maybe_exit(g); 9438 9439 ZigValue *test_fn_slice = create_const_slice(g, test_fn_array, 0, g->test_fns.length, true); 9440 9441 update_compile_var(g, buf_create_from_str("test_functions"), test_fn_slice); 9442 assert(g->test_runner_package != nullptr); 9443 } 9444 9445 static Buf *get_resolved_root_src_path(CodeGen *g) { 9446 // TODO memoize 9447 if (buf_len(&g->main_pkg->root_src_path) == 0) 9448 return nullptr; 9449 9450 Buf rel_full_path = BUF_INIT; 9451 os_path_join(&g->main_pkg->root_src_dir, &g->main_pkg->root_src_path, &rel_full_path); 9452 9453 Buf *resolved_path = buf_alloc(); 9454 Buf *resolve_paths[] = {&rel_full_path}; 9455 *resolved_path = os_path_resolve(resolve_paths, 1); 9456 9457 return resolved_path; 9458 } 9459 9460 static void gen_root_source(CodeGen *g) { 9461 Buf *resolved_path = get_resolved_root_src_path(g); 9462 if (resolved_path == nullptr) 9463 return; 9464 9465 Buf *source_code = buf_alloc(); 9466 Error err; 9467 // No need for using the caching system for this file fetch because it is handled 9468 // separately. 9469 if ((err = os_fetch_file_path(resolved_path, source_code))) { 9470 fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(resolved_path), err_str(err)); 9471 exit(1); 9472 } 9473 9474 ZigType *root_import_alias = add_source_file(g, g->main_pkg, resolved_path, source_code, SourceKindRoot); 9475 assert(root_import_alias == g->root_import); 9476 9477 assert(g->root_out_name); 9478 assert(g->out_type != OutTypeUnknown); 9479 9480 if (!g->is_dummy_so) { 9481 // Zig has lazy top level definitions. Here we semantically analyze the panic function. 9482 Buf *import_target_path; 9483 Buf full_path = BUF_INIT; 9484 ZigType *std_import; 9485 if ((err = analyze_import(g, g->root_import, buf_create_from_str("std"), &std_import, 9486 &import_target_path, &full_path))) 9487 { 9488 if (err == ErrorFileNotFound) { 9489 fprintf(stderr, "unable to find '%s'", buf_ptr(import_target_path)); 9490 } else { 9491 fprintf(stderr, "unable to open '%s': %s\n", buf_ptr(&full_path), err_str(err)); 9492 } 9493 exit(1); 9494 } 9495 9496 Tld *builtin_tld = find_decl(g, &get_container_scope(std_import)->base, 9497 buf_create_from_str("builtin")); 9498 assert(builtin_tld != nullptr); 9499 resolve_top_level_decl(g, builtin_tld, nullptr, false); 9500 report_errors_and_maybe_exit(g); 9501 assert(builtin_tld->id == TldIdVar); 9502 TldVar *builtin_tld_var = (TldVar*)builtin_tld; 9503 ZigValue *builtin_val = builtin_tld_var->var->const_value; 9504 assert(builtin_val->type->id == ZigTypeIdMetaType); 9505 ZigType *builtin_type = builtin_val->data.x_type; 9506 9507 Tld *panic_tld = find_decl(g, &get_container_scope(builtin_type)->base, 9508 buf_create_from_str("panic")); 9509 assert(panic_tld != nullptr); 9510 resolve_top_level_decl(g, panic_tld, nullptr, false); 9511 report_errors_and_maybe_exit(g); 9512 assert(panic_tld->id == TldIdVar); 9513 TldVar *panic_tld_var = (TldVar*)panic_tld; 9514 ZigValue *panic_fn_val = panic_tld_var->var->const_value; 9515 assert(panic_fn_val->type->id == ZigTypeIdFn); 9516 assert(panic_fn_val->data.x_ptr.special == ConstPtrSpecialFunction); 9517 g->panic_fn = panic_fn_val->data.x_ptr.data.fn.fn_entry; 9518 assert(g->panic_fn != nullptr); 9519 } 9520 9521 if (!g->error_during_imports) { 9522 semantic_analyze(g); 9523 } 9524 report_errors_and_maybe_exit(g); 9525 9526 if (g->is_test_build) { 9527 update_test_functions_builtin_decl(g); 9528 if (!g->error_during_imports) { 9529 semantic_analyze(g); 9530 } 9531 } 9532 9533 report_errors_and_maybe_exit(g); 9534 9535 } 9536 9537 static void print_zig_cc_cmd(ZigList<const char *> *args) { 9538 for (size_t arg_i = 0; arg_i < args->length; arg_i += 1) { 9539 const char *space_str = (arg_i == 0) ? "" : " "; 9540 fprintf(stderr, "%s%s", space_str, args->at(arg_i)); 9541 } 9542 fprintf(stderr, "\n"); 9543 } 9544 9545 // Caller should delete the file when done or rename it into a better location. 9546 static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix) { 9547 Error err; 9548 buf_resize(out, 0); 9549 os_path_join(g->cache_dir, buf_create_from_str("tmp" OS_SEP), out); 9550 if ((err = os_make_path(out))) { 9551 return err; 9552 } 9553 const char base64[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"; 9554 assert(array_length(base64) == 64 + 1); 9555 for (size_t i = 0; i < 12; i += 1) { 9556 buf_append_char(out, base64[rand() % 64]); 9557 } 9558 buf_append_char(out, '-'); 9559 buf_append_buf(out, suffix); 9560 return ErrorNone; 9561 } 9562 9563 Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose) { 9564 Error err; 9565 CacheHash *cache_hash = allocate<CacheHash>(1); 9566 Buf *manifest_dir = buf_sprintf("%s" OS_SEP CACHE_HASH_SUBDIR, buf_ptr(g->cache_dir)); 9567 cache_init(cache_hash, manifest_dir); 9568 9569 Buf *compiler_id; 9570 if ((err = get_compiler_id(&compiler_id))) { 9571 if (verbose) { 9572 fprintf(stderr, "unable to get compiler id: %s\n", err_str(err)); 9573 } 9574 return err; 9575 } 9576 cache_buf(cache_hash, compiler_id); 9577 cache_int(cache_hash, g->err_color); 9578 cache_buf(cache_hash, g->zig_c_headers_dir); 9579 cache_list_of_buf(cache_hash, g->libc_include_dir_list, g->libc_include_dir_len); 9580 cache_int(cache_hash, g->zig_target->is_native); 9581 cache_int(cache_hash, g->zig_target->arch); 9582 cache_int(cache_hash, g->zig_target->sub_arch); 9583 cache_int(cache_hash, g->zig_target->vendor); 9584 cache_int(cache_hash, g->zig_target->os); 9585 cache_int(cache_hash, g->zig_target->abi); 9586 cache_bool(cache_hash, g->strip_debug_symbols); 9587 cache_int(cache_hash, g->build_mode); 9588 cache_bool(cache_hash, g->have_pic); 9589 cache_bool(cache_hash, g->have_sanitize_c); 9590 cache_bool(cache_hash, want_valgrind_support(g)); 9591 cache_bool(cache_hash, g->function_sections); 9592 for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) { 9593 cache_str(cache_hash, g->clang_argv[arg_i]); 9594 } 9595 9596 *out_cache_hash = cache_hash; 9597 return ErrorNone; 9598 } 9599 9600 // returns true if it was a cache miss 9601 static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { 9602 Error err; 9603 9604 Buf *artifact_dir; 9605 Buf *o_final_path; 9606 9607 Buf *o_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR, buf_ptr(g->cache_dir)); 9608 9609 Buf *c_source_file = buf_create_from_str(c_file->source_path); 9610 Buf *c_source_basename = buf_alloc(); 9611 os_path_split(c_source_file, nullptr, c_source_basename); 9612 9613 Stage2ProgressNode *child_prog_node = stage2_progress_start(g->sub_progress_node, buf_ptr(c_source_basename), 9614 buf_len(c_source_basename), 0); 9615 9616 Buf *final_o_basename = buf_alloc(); 9617 os_path_extname(c_source_basename, final_o_basename, nullptr); 9618 buf_append_str(final_o_basename, target_o_file_ext(g->zig_target)); 9619 9620 CacheHash *cache_hash; 9621 if ((err = create_c_object_cache(g, &cache_hash, true))) { 9622 // Already printed error; verbose = true 9623 exit(1); 9624 } 9625 cache_file(cache_hash, c_source_file); 9626 9627 // Note: not directory args, just args that always have a file next 9628 static const char *file_args[] = { 9629 "-include", 9630 }; 9631 for (size_t arg_i = 0; arg_i < c_file->args.length; arg_i += 1) { 9632 const char *arg = c_file->args.at(arg_i); 9633 cache_str(cache_hash, arg); 9634 for (size_t file_arg_i = 0; file_arg_i < array_length(file_args); file_arg_i += 1) { 9635 if (strcmp(arg, file_args[file_arg_i]) == 0 && arg_i + 1 < c_file->args.length) { 9636 arg_i += 1; 9637 cache_file(cache_hash, buf_create_from_str(c_file->args.at(arg_i))); 9638 } 9639 } 9640 } 9641 9642 Buf digest = BUF_INIT; 9643 buf_resize(&digest, 0); 9644 if ((err = cache_hit(cache_hash, &digest))) { 9645 if (err != ErrorInvalidFormat) { 9646 if (err == ErrorCacheUnavailable) { 9647 // already printed error 9648 } else { 9649 fprintf(stderr, "unable to check cache when compiling C object: %s\n", err_str(err)); 9650 } 9651 exit(1); 9652 } 9653 } 9654 bool is_cache_miss = (buf_len(&digest) == 0); 9655 if (is_cache_miss) { 9656 // we can't know the digest until we do the C compiler invocation, so we 9657 // need a tmp filename. 9658 Buf *out_obj_path = buf_alloc(); 9659 if ((err = get_tmp_filename(g, out_obj_path, final_o_basename))) { 9660 fprintf(stderr, "unable to create tmp dir: %s\n", err_str(err)); 9661 exit(1); 9662 } 9663 9664 Termination term; 9665 ZigList<const char *> args = {}; 9666 args.append(buf_ptr(self_exe_path)); 9667 args.append("cc"); 9668 9669 Buf *out_dep_path = buf_sprintf("%s.d", buf_ptr(out_obj_path)); 9670 add_cc_args(g, args, buf_ptr(out_dep_path), false); 9671 9672 args.append("-o"); 9673 args.append(buf_ptr(out_obj_path)); 9674 9675 args.append("-c"); 9676 args.append(buf_ptr(c_source_file)); 9677 9678 for (size_t arg_i = 0; arg_i < c_file->args.length; arg_i += 1) { 9679 args.append(c_file->args.at(arg_i)); 9680 } 9681 9682 if (g->verbose_cc) { 9683 print_zig_cc_cmd(&args); 9684 } 9685 os_spawn_process(args, &term); 9686 if (term.how != TerminationIdClean || term.code != 0) { 9687 fprintf(stderr, "\nThe following command failed:\n"); 9688 print_zig_cc_cmd(&args); 9689 exit(1); 9690 } 9691 9692 // add the files depended on to the cache system 9693 if ((err = cache_add_dep_file(cache_hash, out_dep_path, true))) { 9694 // Don't treat the absence of the .d file as a fatal error, the 9695 // compiler may not produce one eg. when compiling .s files 9696 if (err != ErrorFileNotFound) { 9697 fprintf(stderr, "Failed to add C source dependencies to cache: %s\n", err_str(err)); 9698 exit(1); 9699 } 9700 } 9701 if (err != ErrorFileNotFound) { 9702 os_delete_file(out_dep_path); 9703 } 9704 9705 if ((err = cache_final(cache_hash, &digest))) { 9706 fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err)); 9707 exit(1); 9708 } 9709 artifact_dir = buf_alloc(); 9710 os_path_join(o_dir, &digest, artifact_dir); 9711 if ((err = os_make_path(artifact_dir))) { 9712 fprintf(stderr, "Unable to create output directory '%s': %s", 9713 buf_ptr(artifact_dir), err_str(err)); 9714 exit(1); 9715 } 9716 o_final_path = buf_alloc(); 9717 os_path_join(artifact_dir, final_o_basename, o_final_path); 9718 if ((err = os_rename(out_obj_path, o_final_path))) { 9719 fprintf(stderr, "Unable to rename object: %s\n", err_str(err)); 9720 exit(1); 9721 } 9722 } else { 9723 // cache hit 9724 artifact_dir = buf_alloc(); 9725 os_path_join(o_dir, &digest, artifact_dir); 9726 o_final_path = buf_alloc(); 9727 os_path_join(artifact_dir, final_o_basename, o_final_path); 9728 } 9729 9730 g->link_objects.append(o_final_path); 9731 g->caches_to_release.append(cache_hash); 9732 9733 stage2_progress_end(child_prog_node); 9734 } 9735 9736 // returns true if we had any cache misses 9737 static void gen_c_objects(CodeGen *g) { 9738 Error err; 9739 9740 if (g->c_source_files.length == 0) 9741 return; 9742 9743 Buf *self_exe_path = buf_alloc(); 9744 if ((err = os_self_exe_path(self_exe_path))) { 9745 fprintf(stderr, "Unable to get self exe path: %s\n", err_str(err)); 9746 exit(1); 9747 } 9748 9749 codegen_add_time_event(g, "Compile C Objects"); 9750 const char *c_prog_name = "Compile C Objects"; 9751 codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, c_prog_name, strlen(c_prog_name), 9752 g->c_source_files.length)); 9753 9754 for (size_t c_file_i = 0; c_file_i < g->c_source_files.length; c_file_i += 1) { 9755 CFile *c_file = g->c_source_files.at(c_file_i); 9756 gen_c_object(g, self_exe_path, c_file); 9757 } 9758 } 9759 9760 void codegen_add_object(CodeGen *g, Buf *object_path) { 9761 g->link_objects.append(object_path); 9762 } 9763 9764 // Must be coordinated with with CIntType enum 9765 static const char *c_int_type_names[] = { 9766 "short", 9767 "unsigned short", 9768 "int", 9769 "unsigned int", 9770 "long", 9771 "unsigned long", 9772 "long long", 9773 "unsigned long long", 9774 }; 9775 9776 struct GenH { 9777 ZigList<ZigType *> types_to_declare; 9778 }; 9779 9780 static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_entry) { 9781 if (type_entry->gen_h_loop_flag) 9782 return; 9783 type_entry->gen_h_loop_flag = true; 9784 9785 switch (type_entry->id) { 9786 case ZigTypeIdInvalid: 9787 case ZigTypeIdMetaType: 9788 case ZigTypeIdComptimeFloat: 9789 case ZigTypeIdComptimeInt: 9790 case ZigTypeIdEnumLiteral: 9791 case ZigTypeIdUndefined: 9792 case ZigTypeIdNull: 9793 case ZigTypeIdBoundFn: 9794 case ZigTypeIdErrorUnion: 9795 case ZigTypeIdErrorSet: 9796 case ZigTypeIdFnFrame: 9797 case ZigTypeIdAnyFrame: 9798 zig_unreachable(); 9799 case ZigTypeIdVoid: 9800 case ZigTypeIdUnreachable: 9801 case ZigTypeIdBool: 9802 g->c_want_stdbool = true; 9803 return; 9804 case ZigTypeIdInt: 9805 g->c_want_stdint = true; 9806 return; 9807 case ZigTypeIdFloat: 9808 return; 9809 case ZigTypeIdOpaque: 9810 gen_h->types_to_declare.append(type_entry); 9811 return; 9812 case ZigTypeIdStruct: 9813 for (uint32_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { 9814 TypeStructField *field = type_entry->data.structure.fields[i]; 9815 prepend_c_type_to_decl_list(g, gen_h, field->type_entry); 9816 } 9817 gen_h->types_to_declare.append(type_entry); 9818 return; 9819 case ZigTypeIdUnion: 9820 for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) { 9821 TypeUnionField *field = &type_entry->data.unionation.fields[i]; 9822 prepend_c_type_to_decl_list(g, gen_h, field->type_entry); 9823 } 9824 gen_h->types_to_declare.append(type_entry); 9825 return; 9826 case ZigTypeIdEnum: 9827 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.enumeration.tag_int_type); 9828 gen_h->types_to_declare.append(type_entry); 9829 return; 9830 case ZigTypeIdPointer: 9831 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.pointer.child_type); 9832 return; 9833 case ZigTypeIdArray: 9834 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.array.child_type); 9835 return; 9836 case ZigTypeIdVector: 9837 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.vector.elem_type); 9838 return; 9839 case ZigTypeIdOptional: 9840 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.maybe.child_type); 9841 return; 9842 case ZigTypeIdFn: 9843 for (size_t i = 0; i < type_entry->data.fn.fn_type_id.param_count; i += 1) { 9844 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.fn.fn_type_id.param_info[i].type); 9845 } 9846 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.fn.fn_type_id.return_type); 9847 return; 9848 } 9849 } 9850 9851 static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_buf) { 9852 assert(type_entry); 9853 9854 for (size_t i = 0; i < array_length(c_int_type_names); i += 1) { 9855 if (type_entry == g->builtin_types.entry_c_int[i]) { 9856 buf_init_from_str(out_buf, c_int_type_names[i]); 9857 return; 9858 } 9859 } 9860 if (type_entry == g->builtin_types.entry_c_longdouble) { 9861 buf_init_from_str(out_buf, "long double"); 9862 return; 9863 } 9864 if (type_entry == g->builtin_types.entry_c_void) { 9865 buf_init_from_str(out_buf, "void"); 9866 return; 9867 } 9868 if (type_entry == g->builtin_types.entry_isize) { 9869 g->c_want_stdint = true; 9870 buf_init_from_str(out_buf, "intptr_t"); 9871 return; 9872 } 9873 if (type_entry == g->builtin_types.entry_usize) { 9874 g->c_want_stdint = true; 9875 buf_init_from_str(out_buf, "uintptr_t"); 9876 return; 9877 } 9878 9879 prepend_c_type_to_decl_list(g, gen_h, type_entry); 9880 9881 switch (type_entry->id) { 9882 case ZigTypeIdVoid: 9883 buf_init_from_str(out_buf, "void"); 9884 break; 9885 case ZigTypeIdBool: 9886 buf_init_from_str(out_buf, "bool"); 9887 break; 9888 case ZigTypeIdUnreachable: 9889 buf_init_from_str(out_buf, "__attribute__((__noreturn__)) void"); 9890 break; 9891 case ZigTypeIdFloat: 9892 switch (type_entry->data.floating.bit_count) { 9893 case 32: 9894 buf_init_from_str(out_buf, "float"); 9895 break; 9896 case 64: 9897 buf_init_from_str(out_buf, "double"); 9898 break; 9899 case 80: 9900 buf_init_from_str(out_buf, "__float80"); 9901 break; 9902 case 128: 9903 buf_init_from_str(out_buf, "__float128"); 9904 break; 9905 default: 9906 zig_unreachable(); 9907 } 9908 break; 9909 case ZigTypeIdInt: 9910 buf_resize(out_buf, 0); 9911 buf_appendf(out_buf, "%sint%" PRIu32 "_t", 9912 type_entry->data.integral.is_signed ? "" : "u", 9913 type_entry->data.integral.bit_count); 9914 break; 9915 case ZigTypeIdPointer: 9916 { 9917 Buf child_buf = BUF_INIT; 9918 ZigType *child_type = type_entry->data.pointer.child_type; 9919 get_c_type(g, gen_h, child_type, &child_buf); 9920 9921 const char *const_str = type_entry->data.pointer.is_const ? "const " : ""; 9922 buf_resize(out_buf, 0); 9923 buf_appendf(out_buf, "%s%s *", const_str, buf_ptr(&child_buf)); 9924 break; 9925 } 9926 case ZigTypeIdOptional: 9927 { 9928 ZigType *child_type = type_entry->data.maybe.child_type; 9929 if (!type_has_bits(child_type)) { 9930 buf_init_from_str(out_buf, "bool"); 9931 return; 9932 } else if (type_is_nonnull_ptr(child_type)) { 9933 return get_c_type(g, gen_h, child_type, out_buf); 9934 } else { 9935 zig_unreachable(); 9936 } 9937 } 9938 case ZigTypeIdStruct: 9939 case ZigTypeIdOpaque: 9940 { 9941 buf_init_from_str(out_buf, "struct "); 9942 buf_append_buf(out_buf, type_h_name(type_entry)); 9943 return; 9944 } 9945 case ZigTypeIdUnion: 9946 { 9947 buf_init_from_str(out_buf, "union "); 9948 buf_append_buf(out_buf, type_h_name(type_entry)); 9949 return; 9950 } 9951 case ZigTypeIdEnum: 9952 { 9953 buf_init_from_str(out_buf, "enum "); 9954 buf_append_buf(out_buf, type_h_name(type_entry)); 9955 return; 9956 } 9957 case ZigTypeIdArray: 9958 { 9959 ZigTypeArray *array_data = &type_entry->data.array; 9960 9961 Buf *child_buf = buf_alloc(); 9962 get_c_type(g, gen_h, array_data->child_type, child_buf); 9963 9964 buf_resize(out_buf, 0); 9965 buf_appendf(out_buf, "%s", buf_ptr(child_buf)); 9966 return; 9967 } 9968 case ZigTypeIdVector: 9969 zig_panic("TODO implement get_c_type for vector types"); 9970 case ZigTypeIdErrorUnion: 9971 case ZigTypeIdErrorSet: 9972 case ZigTypeIdFn: 9973 zig_panic("TODO implement get_c_type for more types"); 9974 case ZigTypeIdInvalid: 9975 case ZigTypeIdMetaType: 9976 case ZigTypeIdBoundFn: 9977 case ZigTypeIdComptimeFloat: 9978 case ZigTypeIdComptimeInt: 9979 case ZigTypeIdEnumLiteral: 9980 case ZigTypeIdUndefined: 9981 case ZigTypeIdNull: 9982 case ZigTypeIdFnFrame: 9983 case ZigTypeIdAnyFrame: 9984 zig_unreachable(); 9985 } 9986 } 9987 9988 static const char *preprocessor_alphabet1 = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 9989 static const char *preprocessor_alphabet2 = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 9990 9991 static bool need_to_preprocessor_mangle(Buf *src) { 9992 for (size_t i = 0; i < buf_len(src); i += 1) { 9993 const char *alphabet = (i == 0) ? preprocessor_alphabet1 : preprocessor_alphabet2; 9994 uint8_t byte = buf_ptr(src)[i]; 9995 if (strchr(alphabet, byte) == nullptr) { 9996 return true; 9997 } 9998 } 9999 return false; 10000 } 10001 10002 static Buf *preprocessor_mangle(Buf *src) { 10003 if (!need_to_preprocessor_mangle(src)) { 10004 return buf_create_from_buf(src); 10005 } 10006 Buf *result = buf_alloc(); 10007 for (size_t i = 0; i < buf_len(src); i += 1) { 10008 const char *alphabet = (i == 0) ? preprocessor_alphabet1 : preprocessor_alphabet2; 10009 uint8_t byte = buf_ptr(src)[i]; 10010 if (strchr(alphabet, byte) == nullptr) { 10011 // perform escape 10012 buf_appendf(result, "_%02x_", byte); 10013 } else { 10014 buf_append_char(result, byte); 10015 } 10016 } 10017 return result; 10018 } 10019 10020 static void gen_h_file_types(CodeGen* g, GenH* gen_h, Buf* out_buf) { 10021 for (size_t type_i = 0; type_i < gen_h->types_to_declare.length; type_i += 1) { 10022 ZigType *type_entry = gen_h->types_to_declare.at(type_i); 10023 switch (type_entry->id) { 10024 case ZigTypeIdInvalid: 10025 case ZigTypeIdMetaType: 10026 case ZigTypeIdVoid: 10027 case ZigTypeIdBool: 10028 case ZigTypeIdUnreachable: 10029 case ZigTypeIdInt: 10030 case ZigTypeIdFloat: 10031 case ZigTypeIdPointer: 10032 case ZigTypeIdComptimeFloat: 10033 case ZigTypeIdComptimeInt: 10034 case ZigTypeIdEnumLiteral: 10035 case ZigTypeIdArray: 10036 case ZigTypeIdUndefined: 10037 case ZigTypeIdNull: 10038 case ZigTypeIdErrorUnion: 10039 case ZigTypeIdErrorSet: 10040 case ZigTypeIdBoundFn: 10041 case ZigTypeIdOptional: 10042 case ZigTypeIdFn: 10043 case ZigTypeIdVector: 10044 case ZigTypeIdFnFrame: 10045 case ZigTypeIdAnyFrame: 10046 zig_unreachable(); 10047 10048 case ZigTypeIdEnum: 10049 if (type_entry->data.enumeration.layout == ContainerLayoutExtern) { 10050 buf_appendf(out_buf, "enum %s {\n", buf_ptr(type_h_name(type_entry))); 10051 for (uint32_t field_i = 0; field_i < type_entry->data.enumeration.src_field_count; field_i += 1) { 10052 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[field_i]; 10053 Buf *value_buf = buf_alloc(); 10054 bigint_append_buf(value_buf, &enum_field->value, 10); 10055 buf_appendf(out_buf, " %s = %s", buf_ptr(enum_field->name), buf_ptr(value_buf)); 10056 if (field_i != type_entry->data.enumeration.src_field_count - 1) { 10057 buf_appendf(out_buf, ","); 10058 } 10059 buf_appendf(out_buf, "\n"); 10060 } 10061 buf_appendf(out_buf, "};\n\n"); 10062 } else { 10063 buf_appendf(out_buf, "enum %s;\n\n", buf_ptr(type_h_name(type_entry))); 10064 } 10065 break; 10066 case ZigTypeIdStruct: 10067 if (type_entry->data.structure.layout == ContainerLayoutExtern) { 10068 buf_appendf(out_buf, "struct %s {\n", buf_ptr(type_h_name(type_entry))); 10069 for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) { 10070 TypeStructField *struct_field = type_entry->data.structure.fields[field_i]; 10071 10072 Buf *type_name_buf = buf_alloc(); 10073 get_c_type(g, gen_h, struct_field->type_entry, type_name_buf); 10074 10075 if (struct_field->type_entry->id == ZigTypeIdArray) { 10076 buf_appendf(out_buf, " %s %s[%" ZIG_PRI_u64 "];\n", buf_ptr(type_name_buf), 10077 buf_ptr(struct_field->name), 10078 struct_field->type_entry->data.array.len); 10079 } else { 10080 buf_appendf(out_buf, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(struct_field->name)); 10081 } 10082 10083 } 10084 buf_appendf(out_buf, "};\n\n"); 10085 } else { 10086 buf_appendf(out_buf, "struct %s;\n\n", buf_ptr(type_h_name(type_entry))); 10087 } 10088 break; 10089 case ZigTypeIdUnion: 10090 if (type_entry->data.unionation.layout == ContainerLayoutExtern) { 10091 buf_appendf(out_buf, "union %s {\n", buf_ptr(type_h_name(type_entry))); 10092 for (uint32_t field_i = 0; field_i < type_entry->data.unionation.src_field_count; field_i += 1) { 10093 TypeUnionField *union_field = &type_entry->data.unionation.fields[field_i]; 10094 10095 Buf *type_name_buf = buf_alloc(); 10096 get_c_type(g, gen_h, union_field->type_entry, type_name_buf); 10097 buf_appendf(out_buf, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(union_field->name)); 10098 } 10099 buf_appendf(out_buf, "};\n\n"); 10100 } else { 10101 buf_appendf(out_buf, "union %s;\n\n", buf_ptr(type_h_name(type_entry))); 10102 } 10103 break; 10104 case ZigTypeIdOpaque: 10105 buf_appendf(out_buf, "struct %s;\n\n", buf_ptr(type_h_name(type_entry))); 10106 break; 10107 } 10108 } 10109 } 10110 10111 static void gen_h_file_functions(CodeGen* g, GenH* gen_h, Buf* out_buf, Buf* export_macro) { 10112 for (size_t fn_def_i = 0; fn_def_i < g->fn_defs.length; fn_def_i += 1) { 10113 ZigFn *fn_table_entry = g->fn_defs.at(fn_def_i); 10114 10115 if (fn_table_entry->export_list.length == 0) 10116 continue; 10117 10118 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id; 10119 10120 Buf return_type_c = BUF_INIT; 10121 get_c_type(g, gen_h, fn_type_id->return_type, &return_type_c); 10122 10123 Buf *symbol_name; 10124 if (fn_table_entry->export_list.length == 0) { 10125 symbol_name = &fn_table_entry->symbol_name; 10126 } else { 10127 GlobalExport *fn_export = &fn_table_entry->export_list.items[0]; 10128 symbol_name = &fn_export->name; 10129 } 10130 10131 if (export_macro != nullptr) { 10132 buf_appendf(out_buf, "%s %s %s(", 10133 buf_ptr(export_macro), 10134 buf_ptr(&return_type_c), 10135 buf_ptr(symbol_name)); 10136 } else { 10137 buf_appendf(out_buf, "%s %s(", 10138 buf_ptr(&return_type_c), 10139 buf_ptr(symbol_name)); 10140 } 10141 10142 Buf param_type_c = BUF_INIT; 10143 if (fn_type_id->param_count > 0) { 10144 for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) { 10145 FnTypeParamInfo *param_info = &fn_type_id->param_info[param_i]; 10146 AstNode *param_decl_node = get_param_decl_node(fn_table_entry, param_i); 10147 Buf *param_name = param_decl_node->data.param_decl.name; 10148 10149 const char *comma_str = (param_i == 0) ? "" : ", "; 10150 const char *restrict_str = param_info->is_noalias ? "restrict" : ""; 10151 get_c_type(g, gen_h, param_info->type, ¶m_type_c); 10152 10153 if (param_info->type->id == ZigTypeIdArray) { 10154 // Arrays decay to pointers 10155 buf_appendf(out_buf, "%s%s%s %s[]", comma_str, buf_ptr(¶m_type_c), 10156 restrict_str, buf_ptr(param_name)); 10157 } else { 10158 buf_appendf(out_buf, "%s%s%s %s", comma_str, buf_ptr(¶m_type_c), 10159 restrict_str, buf_ptr(param_name)); 10160 } 10161 } 10162 buf_appendf(out_buf, ")"); 10163 } else { 10164 buf_appendf(out_buf, "void)"); 10165 } 10166 10167 buf_appendf(out_buf, ";\n"); 10168 } 10169 } 10170 10171 static void gen_h_file_variables(CodeGen* g, GenH* gen_h, Buf* h_buf, Buf* export_macro) { 10172 for (size_t exp_var_i = 0; exp_var_i < g->global_vars.length; exp_var_i += 1) { 10173 ZigVar* var = g->global_vars.at(exp_var_i)->var; 10174 if (var->export_list.length == 0) 10175 continue; 10176 10177 Buf var_type_c = BUF_INIT; 10178 get_c_type(g, gen_h, var->var_type, &var_type_c); 10179 10180 if (export_macro != nullptr) { 10181 buf_appendf(h_buf, "extern %s %s %s;\n", 10182 buf_ptr(export_macro), 10183 buf_ptr(&var_type_c), 10184 var->name); 10185 } else { 10186 buf_appendf(h_buf, "extern %s %s;\n", 10187 buf_ptr(&var_type_c), 10188 var->name); 10189 } 10190 } 10191 } 10192 10193 static void gen_h_file(CodeGen *g) { 10194 GenH gen_h_data = {0}; 10195 GenH *gen_h = &gen_h_data; 10196 10197 assert(!g->is_test_build); 10198 assert(!g->disable_gen_h); 10199 10200 Buf *out_h_path = buf_sprintf("%s" OS_SEP "%s.h", buf_ptr(g->output_dir), buf_ptr(g->root_out_name)); 10201 10202 FILE *out_h = fopen(buf_ptr(out_h_path), "wb"); 10203 if (!out_h) 10204 zig_panic("unable to open %s: %s\n", buf_ptr(out_h_path), strerror(errno)); 10205 10206 Buf *export_macro = nullptr; 10207 if (g->is_dynamic) { 10208 export_macro = preprocessor_mangle(buf_sprintf("%s_EXPORT", buf_ptr(g->root_out_name))); 10209 buf_upcase(export_macro); 10210 } 10211 10212 Buf fns_buf = BUF_INIT; 10213 buf_resize(&fns_buf, 0); 10214 gen_h_file_functions(g, gen_h, &fns_buf, export_macro); 10215 10216 Buf vars_buf = BUF_INIT; 10217 buf_resize(&vars_buf, 0); 10218 gen_h_file_variables(g, gen_h, &vars_buf, export_macro); 10219 10220 // Types will be populated by exported functions and variables so it has to run last. 10221 Buf types_buf = BUF_INIT; 10222 buf_resize(&types_buf, 0); 10223 gen_h_file_types(g, gen_h, &types_buf); 10224 10225 Buf *ifdef_dance_name = preprocessor_mangle(buf_sprintf("%s_H", buf_ptr(g->root_out_name))); 10226 buf_upcase(ifdef_dance_name); 10227 10228 fprintf(out_h, "#ifndef %s\n", buf_ptr(ifdef_dance_name)); 10229 fprintf(out_h, "#define %s\n\n", buf_ptr(ifdef_dance_name)); 10230 10231 if (g->c_want_stdbool) 10232 fprintf(out_h, "#include <stdbool.h>\n"); 10233 if (g->c_want_stdint) 10234 fprintf(out_h, "#include <stdint.h>\n"); 10235 10236 fprintf(out_h, "\n"); 10237 10238 if (g->is_dynamic) { 10239 fprintf(out_h, "#if defined(_WIN32)\n"); 10240 fprintf(out_h, "#define %s __declspec(dllimport)\n", buf_ptr(export_macro)); 10241 fprintf(out_h, "#else\n"); 10242 fprintf(out_h, "#define %s __attribute__((visibility (\"default\")))\n", 10243 buf_ptr(export_macro)); 10244 fprintf(out_h, "#endif\n"); 10245 fprintf(out_h, "\n"); 10246 } 10247 10248 fprintf(out_h, "%s", buf_ptr(&types_buf)); 10249 10250 fprintf(out_h, "#ifdef __cplusplus\n"); 10251 fprintf(out_h, "extern \"C\" {\n"); 10252 fprintf(out_h, "#endif\n"); 10253 fprintf(out_h, "\n"); 10254 10255 fprintf(out_h, "%s\n", buf_ptr(&fns_buf)); 10256 10257 fprintf(out_h, "#ifdef __cplusplus\n"); 10258 fprintf(out_h, "} // extern \"C\"\n"); 10259 fprintf(out_h, "#endif\n\n"); 10260 10261 fprintf(out_h, "%s\n", buf_ptr(&vars_buf)); 10262 10263 fprintf(out_h, "#endif // %s\n", buf_ptr(ifdef_dance_name)); 10264 10265 if (fclose(out_h)) 10266 zig_panic("unable to close h file: %s", strerror(errno)); 10267 } 10268 10269 void codegen_print_timing_report(CodeGen *g, FILE *f) { 10270 double start_time = g->timing_events.at(0).time; 10271 double end_time = g->timing_events.last().time; 10272 double total = end_time - start_time; 10273 fprintf(f, "%20s%12s%12s%12s%12s\n", "Name", "Start", "End", "Duration", "Percent"); 10274 for (size_t i = 0; i < g->timing_events.length - 1; i += 1) { 10275 TimeEvent *te = &g->timing_events.at(i); 10276 TimeEvent *next_te = &g->timing_events.at(i + 1); 10277 fprintf(f, "%20s%12.4f%12.4f%12.4f%12.4f\n", te->name, 10278 te->time - start_time, 10279 next_te->time - start_time, 10280 next_te->time - te->time, 10281 (next_te->time - te->time) / total); 10282 } 10283 fprintf(f, "%20s%12.4f%12.4f%12.4f%12.4f\n", "Total", 0.0, total, total, 1.0); 10284 } 10285 10286 void codegen_add_time_event(CodeGen *g, const char *name) { 10287 OsTimeStamp timestamp = os_timestamp_monotonic(); 10288 double seconds = (double)timestamp.sec; 10289 seconds += ((double)timestamp.nsec) / 1000000000.0; 10290 g->timing_events.append({seconds, name}); 10291 } 10292 10293 static void add_cache_pkg(CodeGen *g, CacheHash *ch, ZigPackage *pkg) { 10294 if (buf_len(&pkg->root_src_path) == 0) 10295 return; 10296 pkg->added_to_cache = true; 10297 10298 Buf *rel_full_path = buf_alloc(); 10299 os_path_join(&pkg->root_src_dir, &pkg->root_src_path, rel_full_path); 10300 cache_file(ch, rel_full_path); 10301 10302 auto it = pkg->package_table.entry_iterator(); 10303 for (;;) { 10304 auto *entry = it.next(); 10305 if (!entry) 10306 break; 10307 10308 if (!pkg->added_to_cache) { 10309 cache_buf(ch, entry->key); 10310 add_cache_pkg(g, ch, entry->value); 10311 } 10312 } 10313 } 10314 10315 // Called before init() 10316 // is_cache_hit takes into account gen_c_objects 10317 static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { 10318 Error err; 10319 10320 Buf *compiler_id; 10321 if ((err = get_compiler_id(&compiler_id))) 10322 return err; 10323 10324 CacheHash *ch = &g->cache_hash; 10325 cache_init(ch, manifest_dir); 10326 10327 add_cache_pkg(g, ch, g->main_pkg); 10328 if (g->linker_script != nullptr) { 10329 cache_file(ch, buf_create_from_str(g->linker_script)); 10330 } 10331 cache_buf(ch, compiler_id); 10332 cache_buf(ch, g->root_out_name); 10333 cache_buf(ch, g->zig_lib_dir); 10334 cache_buf(ch, g->zig_std_dir); 10335 cache_list_of_link_lib(ch, g->link_libs_list.items, g->link_libs_list.length); 10336 cache_list_of_buf(ch, g->darwin_frameworks.items, g->darwin_frameworks.length); 10337 cache_list_of_buf(ch, g->rpath_list.items, g->rpath_list.length); 10338 cache_list_of_buf(ch, g->forbidden_libs.items, g->forbidden_libs.length); 10339 cache_int(ch, g->build_mode); 10340 cache_int(ch, g->out_type); 10341 cache_bool(ch, g->zig_target->is_native); 10342 cache_int(ch, g->zig_target->arch); 10343 cache_int(ch, g->zig_target->sub_arch); 10344 cache_int(ch, g->zig_target->vendor); 10345 cache_int(ch, g->zig_target->os); 10346 cache_int(ch, g->zig_target->abi); 10347 if (g->zig_target->glibc_version != nullptr) { 10348 cache_int(ch, g->zig_target->glibc_version->major); 10349 cache_int(ch, g->zig_target->glibc_version->minor); 10350 cache_int(ch, g->zig_target->glibc_version->patch); 10351 } 10352 cache_int(ch, detect_subsystem(g)); 10353 cache_bool(ch, g->strip_debug_symbols); 10354 cache_bool(ch, g->is_test_build); 10355 if (g->is_test_build) { 10356 cache_buf_opt(ch, g->test_filter); 10357 cache_buf_opt(ch, g->test_name_prefix); 10358 } 10359 cache_bool(ch, g->link_eh_frame_hdr); 10360 cache_bool(ch, g->is_single_threaded); 10361 cache_bool(ch, g->linker_rdynamic); 10362 cache_bool(ch, g->each_lib_rpath); 10363 cache_bool(ch, g->disable_gen_h); 10364 cache_bool(ch, g->bundle_compiler_rt); 10365 cache_bool(ch, want_valgrind_support(g)); 10366 cache_bool(ch, g->have_pic); 10367 cache_bool(ch, g->have_dynamic_link); 10368 cache_bool(ch, g->have_stack_probing); 10369 cache_bool(ch, g->have_sanitize_c); 10370 cache_bool(ch, g->is_dummy_so); 10371 cache_bool(ch, g->function_sections); 10372 cache_bool(ch, g->enable_dump_analysis); 10373 cache_bool(ch, g->enable_doc_generation); 10374 cache_bool(ch, g->disable_bin_generation); 10375 cache_buf_opt(ch, g->mmacosx_version_min); 10376 cache_buf_opt(ch, g->mios_version_min); 10377 cache_usize(ch, g->version_major); 10378 cache_usize(ch, g->version_minor); 10379 cache_usize(ch, g->version_patch); 10380 cache_list_of_str(ch, g->llvm_argv, g->llvm_argv_len); 10381 cache_list_of_str(ch, g->clang_argv, g->clang_argv_len); 10382 cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length); 10383 cache_list_of_str(ch, g->framework_dirs.items, g->framework_dirs.length); 10384 if (g->libc) { 10385 cache_buf(ch, &g->libc->include_dir); 10386 cache_buf(ch, &g->libc->sys_include_dir); 10387 cache_buf(ch, &g->libc->crt_dir); 10388 cache_buf(ch, &g->libc->msvc_lib_dir); 10389 cache_buf(ch, &g->libc->kernel32_lib_dir); 10390 } 10391 cache_buf_opt(ch, g->dynamic_linker_path); 10392 cache_buf_opt(ch, g->version_script_path); 10393 if (g->llvm_cpu) cache_str(ch, g->llvm_cpu); 10394 if (g->llvm_features) cache_str(ch, g->llvm_features); 10395 10396 // gen_c_objects appends objects to g->link_objects which we want to include in the hash 10397 gen_c_objects(g); 10398 cache_list_of_file(ch, g->link_objects.items, g->link_objects.length); 10399 10400 buf_resize(digest, 0); 10401 if ((err = cache_hit(ch, digest))) { 10402 if (err != ErrorInvalidFormat) 10403 return err; 10404 } 10405 10406 if (ch->manifest_file_path != nullptr) { 10407 g->caches_to_release.append(ch); 10408 } 10409 10410 return ErrorNone; 10411 } 10412 10413 static bool need_llvm_module(CodeGen *g) { 10414 return buf_len(&g->main_pkg->root_src_path) != 0; 10415 } 10416 10417 static void resolve_out_paths(CodeGen *g) { 10418 assert(g->output_dir != nullptr); 10419 assert(g->root_out_name != nullptr); 10420 10421 Buf *out_basename = buf_create_from_buf(g->root_out_name); 10422 Buf *o_basename = buf_create_from_buf(g->root_out_name); 10423 switch (g->emit_file_type) { 10424 case EmitFileTypeBinary: { 10425 switch (g->out_type) { 10426 case OutTypeUnknown: 10427 zig_unreachable(); 10428 case OutTypeObj: 10429 if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) { 10430 buf_init_from_buf(&g->output_file_path, g->link_objects.at(0)); 10431 return; 10432 } 10433 if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache && 10434 buf_eql_buf(o_basename, out_basename)) 10435 { 10436 // make it not collide with main output object 10437 buf_append_str(o_basename, ".root"); 10438 } 10439 buf_append_str(o_basename, target_o_file_ext(g->zig_target)); 10440 buf_append_str(out_basename, target_o_file_ext(g->zig_target)); 10441 break; 10442 case OutTypeExe: 10443 buf_append_str(o_basename, target_o_file_ext(g->zig_target)); 10444 buf_append_str(out_basename, target_exe_file_ext(g->zig_target)); 10445 break; 10446 case OutTypeLib: 10447 buf_append_str(o_basename, target_o_file_ext(g->zig_target)); 10448 buf_resize(out_basename, 0); 10449 buf_append_str(out_basename, target_lib_file_prefix(g->zig_target)); 10450 buf_append_buf(out_basename, g->root_out_name); 10451 buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic, 10452 g->version_major, g->version_minor, g->version_patch)); 10453 break; 10454 } 10455 break; 10456 } 10457 case EmitFileTypeAssembly: { 10458 const char *asm_ext = target_asm_file_ext(g->zig_target); 10459 buf_append_str(o_basename, asm_ext); 10460 buf_append_str(out_basename, asm_ext); 10461 break; 10462 } 10463 case EmitFileTypeLLVMIr: { 10464 const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target); 10465 buf_append_str(o_basename, llvm_ir_ext); 10466 buf_append_str(out_basename, llvm_ir_ext); 10467 break; 10468 } 10469 } 10470 10471 os_path_join(g->output_dir, o_basename, &g->o_file_output_path); 10472 os_path_join(g->output_dir, out_basename, &g->output_file_path); 10473 } 10474 10475 void codegen_build_and_link(CodeGen *g) { 10476 Error err; 10477 assert(g->out_type != OutTypeUnknown); 10478 10479 if (!g->enable_cache) { 10480 if (g->output_dir == nullptr) { 10481 g->output_dir = buf_create_from_str("."); 10482 } else if ((err = os_make_path(g->output_dir))) { 10483 fprintf(stderr, "Unable to create output directory: %s\n", err_str(err)); 10484 exit(1); 10485 } 10486 } 10487 10488 g->have_dynamic_link = detect_dynamic_link(g); 10489 g->have_pic = detect_pic(g); 10490 g->is_single_threaded = detect_single_threaded(g); 10491 g->have_err_ret_tracing = detect_err_ret_tracing(g); 10492 g->have_sanitize_c = detect_sanitize_c(g); 10493 detect_libc(g); 10494 detect_dynamic_linker(g); 10495 10496 Buf digest = BUF_INIT; 10497 if (g->enable_cache) { 10498 Buf *manifest_dir = buf_alloc(); 10499 os_path_join(g->cache_dir, buf_create_from_str(CACHE_HASH_SUBDIR), manifest_dir); 10500 10501 if ((err = check_cache(g, manifest_dir, &digest))) { 10502 if (err == ErrorCacheUnavailable) { 10503 // message already printed 10504 } else if (err == ErrorNotDir) { 10505 fprintf(stderr, "Unable to check cache: %s is not a directory\n", 10506 buf_ptr(manifest_dir)); 10507 } else { 10508 fprintf(stderr, "Unable to check cache: %s: %s\n", buf_ptr(manifest_dir), err_str(err)); 10509 } 10510 exit(1); 10511 } 10512 } else { 10513 // There is a call to this in check_cache 10514 gen_c_objects(g); 10515 } 10516 10517 if (g->enable_cache && buf_len(&digest) != 0) { 10518 g->output_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s", 10519 buf_ptr(g->cache_dir), buf_ptr(&digest)); 10520 resolve_out_paths(g); 10521 } else { 10522 if (need_llvm_module(g)) { 10523 init(g); 10524 10525 codegen_add_time_event(g, "Semantic Analysis"); 10526 const char *progress_name = "Semantic Analysis"; 10527 codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, 10528 progress_name, strlen(progress_name), 0)); 10529 10530 gen_root_source(g); 10531 10532 } 10533 if (g->enable_cache) { 10534 if (buf_len(&digest) == 0) { 10535 if ((err = cache_final(&g->cache_hash, &digest))) { 10536 fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err)); 10537 exit(1); 10538 } 10539 } 10540 g->output_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s", 10541 buf_ptr(g->cache_dir), buf_ptr(&digest)); 10542 10543 if ((err = os_make_path(g->output_dir))) { 10544 fprintf(stderr, "Unable to create output directory: %s\n", err_str(err)); 10545 exit(1); 10546 } 10547 } 10548 resolve_out_paths(g); 10549 10550 if (need_llvm_module(g)) { 10551 codegen_add_time_event(g, "Code Generation"); 10552 { 10553 const char *progress_name = "Code Generation"; 10554 codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, 10555 progress_name, strlen(progress_name), 0)); 10556 } 10557 10558 do_code_gen(g); 10559 codegen_add_time_event(g, "LLVM Emit Output"); 10560 { 10561 const char *progress_name = "LLVM Emit Output"; 10562 codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, 10563 progress_name, strlen(progress_name), 0)); 10564 } 10565 zig_llvm_emit_output(g); 10566 10567 if (!g->disable_gen_h && (g->out_type == OutTypeObj || g->out_type == OutTypeLib)) { 10568 codegen_add_time_event(g, "Generate .h"); 10569 { 10570 const char *progress_name = "Generate .h"; 10571 codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, 10572 progress_name, strlen(progress_name), 0)); 10573 } 10574 gen_h_file(g); 10575 } 10576 } 10577 if (g->enable_dump_analysis) { 10578 const char *analysis_json_filename = buf_ptr(buf_sprintf("%s" OS_SEP "%s-analysis.json", 10579 buf_ptr(g->output_dir), buf_ptr(g->root_out_name))); 10580 FILE *f = fopen(analysis_json_filename, "wb"); 10581 if (f == nullptr) { 10582 fprintf(stderr, "Unable to open '%s': %s\n", analysis_json_filename, strerror(errno)); 10583 exit(1); 10584 } 10585 zig_print_analysis_dump(g, f, " ", "\n"); 10586 if (fclose(f) != 0) { 10587 fprintf(stderr, "Unable to write '%s': %s\n", analysis_json_filename, strerror(errno)); 10588 exit(1); 10589 } 10590 } 10591 if (g->enable_doc_generation) { 10592 Buf *doc_dir_path = buf_sprintf("%s" OS_SEP "docs", buf_ptr(g->output_dir)); 10593 if ((err = os_make_path(doc_dir_path))) { 10594 fprintf(stderr, "Unable to create directory %s: %s\n", buf_ptr(doc_dir_path), err_str(err)); 10595 exit(1); 10596 } 10597 Buf *index_html_src_path = buf_sprintf("%s" OS_SEP "special" OS_SEP "docs" OS_SEP "index.html", 10598 buf_ptr(g->zig_std_dir)); 10599 Buf *index_html_dest_path = buf_sprintf("%s" OS_SEP "index.html", buf_ptr(doc_dir_path)); 10600 Buf *main_js_src_path = buf_sprintf("%s" OS_SEP "special" OS_SEP "docs" OS_SEP "main.js", 10601 buf_ptr(g->zig_std_dir)); 10602 Buf *main_js_dest_path = buf_sprintf("%s" OS_SEP "main.js", buf_ptr(doc_dir_path)); 10603 10604 if ((err = os_copy_file(index_html_src_path, index_html_dest_path))) { 10605 fprintf(stderr, "Unable to copy %s to %s: %s\n", buf_ptr(index_html_src_path), 10606 buf_ptr(index_html_dest_path), err_str(err)); 10607 exit(1); 10608 } 10609 if ((err = os_copy_file(main_js_src_path, main_js_dest_path))) { 10610 fprintf(stderr, "Unable to copy %s to %s: %s\n", buf_ptr(main_js_src_path), 10611 buf_ptr(main_js_dest_path), err_str(err)); 10612 exit(1); 10613 } 10614 const char *data_js_filename = buf_ptr(buf_sprintf("%s" OS_SEP "data.js", buf_ptr(doc_dir_path))); 10615 FILE *f = fopen(data_js_filename, "wb"); 10616 if (f == nullptr) { 10617 fprintf(stderr, "Unable to open '%s': %s\n", data_js_filename, strerror(errno)); 10618 exit(1); 10619 } 10620 fprintf(f, "zigAnalysis="); 10621 zig_print_analysis_dump(g, f, "", ""); 10622 fprintf(f, ";"); 10623 if (fclose(f) != 0) { 10624 fprintf(stderr, "Unable to write '%s': %s\n", data_js_filename, strerror(errno)); 10625 exit(1); 10626 } 10627 } 10628 10629 // If we're outputting assembly or llvm IR we skip linking. 10630 // If we're making a library or executable we must link. 10631 // If there is more than one object, we have to link them (with -r). 10632 // Finally, if we didn't make an object from zig source, and we don't have caching enabled, 10633 // then we have an object from C source that we must copy to the output dir which we do with a -r link. 10634 if (!g->disable_bin_generation && g->emit_file_type == EmitFileTypeBinary && 10635 (g->out_type != OutTypeObj || g->link_objects.length > 1 || 10636 (!need_llvm_module(g) && !g->enable_cache))) 10637 { 10638 codegen_link(g); 10639 } 10640 } 10641 10642 codegen_release_caches(g); 10643 codegen_add_time_event(g, "Done"); 10644 codegen_switch_sub_prog_node(g, nullptr); 10645 } 10646 10647 void codegen_release_caches(CodeGen *g) { 10648 while (g->caches_to_release.length != 0) { 10649 cache_release(g->caches_to_release.pop()); 10650 } 10651 } 10652 10653 ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const char *root_src_path, 10654 const char *pkg_path) 10655 { 10656 init(g); 10657 ZigPackage *pkg = new_package(root_src_dir, root_src_path, pkg_path); 10658 if (g->std_package != nullptr) { 10659 assert(g->compile_var_package != nullptr); 10660 pkg->package_table.put(buf_create_from_str("std"), g->std_package); 10661 10662 pkg->package_table.put(buf_create_from_str("root"), g->root_pkg); 10663 10664 pkg->package_table.put(buf_create_from_str("builtin"), g->compile_var_package); 10665 } 10666 return pkg; 10667 } 10668 10669 CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type, 10670 ZigLibCInstallation *libc, const char *name, Stage2ProgressNode *parent_progress_node) 10671 { 10672 Stage2ProgressNode *child_progress_node = stage2_progress_start( 10673 parent_progress_node ? parent_progress_node : parent_gen->sub_progress_node, 10674 name, strlen(name), 0); 10675 10676 CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type, 10677 parent_gen->build_mode, parent_gen->zig_lib_dir, libc, get_global_cache_dir(), false, child_progress_node); 10678 child_gen->root_out_name = buf_create_from_str(name); 10679 child_gen->disable_gen_h = true; 10680 child_gen->want_stack_check = WantStackCheckDisabled; 10681 child_gen->want_sanitize_c = WantCSanitizeDisabled; 10682 child_gen->verbose_tokenize = parent_gen->verbose_tokenize; 10683 child_gen->verbose_ast = parent_gen->verbose_ast; 10684 child_gen->verbose_link = parent_gen->verbose_link; 10685 child_gen->verbose_ir = parent_gen->verbose_ir; 10686 child_gen->verbose_llvm_ir = parent_gen->verbose_llvm_ir; 10687 child_gen->verbose_cimport = parent_gen->verbose_cimport; 10688 child_gen->verbose_cc = parent_gen->verbose_cc; 10689 child_gen->llvm_argv = parent_gen->llvm_argv; 10690 child_gen->dynamic_linker_path = parent_gen->dynamic_linker_path; 10691 10692 codegen_set_strip(child_gen, parent_gen->strip_debug_symbols); 10693 child_gen->want_pic = parent_gen->have_pic ? WantPICEnabled : WantPICDisabled; 10694 child_gen->valgrind_support = ValgrindSupportDisabled; 10695 10696 codegen_set_errmsg_color(child_gen, parent_gen->err_color); 10697 10698 codegen_set_mmacosx_version_min(child_gen, parent_gen->mmacosx_version_min); 10699 codegen_set_mios_version_min(child_gen, parent_gen->mios_version_min); 10700 10701 child_gen->enable_cache = true; 10702 10703 return child_gen; 10704 } 10705 10706 CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target, 10707 OutType out_type, BuildMode build_mode, Buf *override_lib_dir, 10708 ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node) 10709 { 10710 CodeGen *g = allocate<CodeGen>(1); 10711 g->main_progress_node = progress_node; 10712 10713 codegen_add_time_event(g, "Initialize"); 10714 { 10715 const char *progress_name = "Initialize"; 10716 codegen_switch_sub_prog_node(g, stage2_progress_start(g->main_progress_node, 10717 progress_name, strlen(progress_name), 0)); 10718 } 10719 10720 g->subsystem = TargetSubsystemAuto; 10721 g->libc = libc; 10722 g->zig_target = target; 10723 g->cache_dir = cache_dir; 10724 10725 if (override_lib_dir == nullptr) { 10726 g->zig_lib_dir = get_zig_lib_dir(); 10727 } else { 10728 g->zig_lib_dir = override_lib_dir; 10729 } 10730 10731 g->zig_std_dir = buf_alloc(); 10732 os_path_join(g->zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir); 10733 10734 g->zig_c_headers_dir = buf_alloc(); 10735 os_path_join(g->zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir); 10736 10737 g->build_mode = build_mode; 10738 g->out_type = out_type; 10739 g->import_table.init(32); 10740 g->builtin_fn_table.init(32); 10741 g->primitive_type_table.init(32); 10742 g->type_table.init(32); 10743 g->fn_type_table.init(32); 10744 g->error_table.init(16); 10745 g->generic_table.init(16); 10746 g->llvm_fn_table.init(16); 10747 g->memoized_fn_eval_table.init(16); 10748 g->exported_symbol_names.init(8); 10749 g->external_prototypes.init(8); 10750 g->string_literals_table.init(16); 10751 g->type_info_cache.init(32); 10752 g->one_possible_values.init(32); 10753 g->is_test_build = is_test_build; 10754 g->is_single_threaded = false; 10755 buf_resize(&g->global_asm, 0); 10756 10757 for (size_t i = 0; i < array_length(symbols_that_llvm_depends_on); i += 1) { 10758 g->external_prototypes.put(buf_create_from_str(symbols_that_llvm_depends_on[i]), nullptr); 10759 } 10760 10761 if (root_src_path) { 10762 Buf *root_pkg_path; 10763 Buf *rel_root_src_path; 10764 if (main_pkg_path == nullptr) { 10765 Buf *src_basename = buf_alloc(); 10766 Buf *src_dir = buf_alloc(); 10767 os_path_split(root_src_path, src_dir, src_basename); 10768 10769 if (buf_len(src_basename) == 0) { 10770 fprintf(stderr, "Invalid root source path: %s\n", buf_ptr(root_src_path)); 10771 exit(1); 10772 } 10773 root_pkg_path = src_dir; 10774 rel_root_src_path = src_basename; 10775 } else { 10776 Buf resolved_root_src_path = os_path_resolve(&root_src_path, 1); 10777 Buf resolved_main_pkg_path = os_path_resolve(&main_pkg_path, 1); 10778 10779 if (!buf_starts_with_buf(&resolved_root_src_path, &resolved_main_pkg_path)) { 10780 fprintf(stderr, "Root source path '%s' outside main package path '%s'", 10781 buf_ptr(root_src_path), buf_ptr(main_pkg_path)); 10782 exit(1); 10783 } 10784 root_pkg_path = main_pkg_path; 10785 rel_root_src_path = buf_create_from_mem( 10786 buf_ptr(&resolved_root_src_path) + buf_len(&resolved_main_pkg_path) + 1, 10787 buf_len(&resolved_root_src_path) - buf_len(&resolved_main_pkg_path) - 1); 10788 } 10789 10790 g->main_pkg = new_package(buf_ptr(root_pkg_path), buf_ptr(rel_root_src_path), ""); 10791 g->std_package = new_package(buf_ptr(g->zig_std_dir), "std.zig", "std"); 10792 g->main_pkg->package_table.put(buf_create_from_str("std"), g->std_package); 10793 } else { 10794 g->main_pkg = new_package(".", "", ""); 10795 } 10796 10797 g->zig_std_special_dir = buf_alloc(); 10798 os_path_join(g->zig_std_dir, buf_sprintf("special"), g->zig_std_special_dir); 10799 10800 assert(target != nullptr); 10801 if (!target->is_native) { 10802 g->each_lib_rpath = false; 10803 } else { 10804 g->each_lib_rpath = true; 10805 10806 if (target_os_is_darwin(g->zig_target->os)) { 10807 init_darwin_native(g); 10808 } 10809 10810 } 10811 10812 if (target_os_requires_libc(g->zig_target->os)) { 10813 g->libc_link_lib = create_link_lib(buf_create_from_str("c")); 10814 g->link_libs_list.append(g->libc_link_lib); 10815 } 10816 10817 target_triple_llvm(&g->llvm_triple_str, g->zig_target); 10818 g->pointer_size_bytes = target_arch_pointer_bit_width(g->zig_target->arch) / 8; 10819 10820 if (!target_has_debug_info(g->zig_target)) { 10821 g->strip_debug_symbols = true; 10822 } 10823 10824 return g; 10825 } 10826 10827 bool codegen_fn_has_err_ret_tracing_arg(CodeGen *g, ZigType *return_type) { 10828 return g->have_err_ret_tracing && 10829 (return_type->id == ZigTypeIdErrorUnion || 10830 return_type->id == ZigTypeIdErrorSet); 10831 } 10832 10833 bool codegen_fn_has_err_ret_tracing_stack(CodeGen *g, ZigFn *fn, bool is_async) { 10834 if (is_async) { 10835 return g->have_err_ret_tracing && (fn->calls_or_awaits_errorable_fn || 10836 codegen_fn_has_err_ret_tracing_arg(g, fn->type_entry->data.fn.fn_type_id.return_type)); 10837 } else { 10838 return g->have_err_ret_tracing && fn->calls_or_awaits_errorable_fn && 10839 !codegen_fn_has_err_ret_tracing_arg(g, fn->type_entry->data.fn.fn_type_id.return_type); 10840 } 10841 } 10842 10843 void codegen_switch_sub_prog_node(CodeGen *g, Stage2ProgressNode *node) { 10844 if (g->sub_progress_node != nullptr) { 10845 stage2_progress_end(g->sub_progress_node); 10846 } 10847 g->sub_progress_node = node; 10848 } 10849 10850 ZigValue *CodeGen::Intern::for_undefined() { 10851 #ifdef ZIG_ENABLE_MEM_PROFILE 10852 memprof_intern_count.x_undefined += 1; 10853 #endif 10854 return &this->x_undefined; 10855 } 10856 10857 ZigValue *CodeGen::Intern::for_void() { 10858 #ifdef ZIG_ENABLE_MEM_PROFILE 10859 memprof_intern_count.x_void += 1; 10860 #endif 10861 return &this->x_void; 10862 } 10863 10864 ZigValue *CodeGen::Intern::for_null() { 10865 #ifdef ZIG_ENABLE_MEM_PROFILE 10866 memprof_intern_count.x_null += 1; 10867 #endif 10868 return &this->x_null; 10869 } 10870 10871 ZigValue *CodeGen::Intern::for_unreachable() { 10872 #ifdef ZIG_ENABLE_MEM_PROFILE 10873 memprof_intern_count.x_unreachable += 1; 10874 #endif 10875 return &this->x_unreachable; 10876 } 10877 10878 ZigValue *CodeGen::Intern::for_zero_byte() { 10879 #ifdef ZIG_ENABLE_MEM_PROFILE 10880 memprof_intern_count.zero_byte += 1; 10881 #endif 10882 return &this->zero_byte; 10883 }