blob 0aa5ea5d (255382B) - 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 "config.h" 11 #include "error.hpp" 12 #include "ir.hpp" 13 #include "ir_print.hpp" 14 #include "os.hpp" 15 #include "parser.hpp" 16 #include "softfloat.hpp" 17 #include "zig_llvm.h" 18 19 20 static const size_t default_backward_branch_quota = 1000; 21 22 static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type); 23 static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type); 24 25 static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type); 26 static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type); 27 static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type); 28 static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry); 29 30 ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) { 31 if (node->owner->c_import_node != nullptr) { 32 // if this happens, then translate_c generated code that 33 // failed semantic analysis, which isn't supposed to happen 34 ErrorMsg *err = add_node_error(g, node->owner->c_import_node, 35 buf_sprintf("compiler bug: @cImport generated invalid zig code")); 36 37 add_error_note(g, err, node, msg); 38 39 g->errors.append(err); 40 return err; 41 } 42 43 ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column, 44 node->owner->source_code, node->owner->line_offsets, msg); 45 46 g->errors.append(err); 47 return err; 48 } 49 50 ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg) { 51 if (node->owner->c_import_node != nullptr) { 52 // if this happens, then translate_c generated code that 53 // failed semantic analysis, which isn't supposed to happen 54 55 Buf *note_path = buf_create_from_str("?.c"); 56 Buf *note_source = buf_create_from_str("TODO: remember C source location to display here "); 57 ZigList<size_t> note_line_offsets = {0}; 58 note_line_offsets.append(0); 59 ErrorMsg *note = err_msg_create_with_line(note_path, 0, 0, 60 note_source, ¬e_line_offsets, msg); 61 62 err_msg_add_note(parent_msg, note); 63 return note; 64 } 65 66 ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column, 67 node->owner->source_code, node->owner->line_offsets, msg); 68 69 err_msg_add_note(parent_msg, err); 70 return err; 71 } 72 73 TypeTableEntry *new_type_table_entry(TypeTableEntryId id) { 74 TypeTableEntry *entry = allocate<TypeTableEntry>(1); 75 entry->id = id; 76 return entry; 77 } 78 79 static ScopeDecls **get_container_scope_ptr(TypeTableEntry *type_entry) { 80 if (type_entry->id == TypeTableEntryIdStruct) { 81 return &type_entry->data.structure.decls_scope; 82 } else if (type_entry->id == TypeTableEntryIdEnum) { 83 return &type_entry->data.enumeration.decls_scope; 84 } else if (type_entry->id == TypeTableEntryIdUnion) { 85 return &type_entry->data.unionation.decls_scope; 86 } 87 zig_unreachable(); 88 } 89 90 ScopeDecls *get_container_scope(TypeTableEntry *type_entry) { 91 return *get_container_scope_ptr(type_entry); 92 } 93 94 void init_scope(Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) { 95 dest->id = id; 96 dest->source_node = source_node; 97 dest->parent = parent; 98 } 99 100 ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, TypeTableEntry *container_type, ImportTableEntry *import) { 101 assert(node == nullptr || node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr); 102 ScopeDecls *scope = allocate<ScopeDecls>(1); 103 init_scope(&scope->base, ScopeIdDecls, node, parent); 104 scope->decl_table.init(4); 105 scope->container_type = container_type; 106 scope->import = import; 107 return scope; 108 } 109 110 ScopeBlock *create_block_scope(AstNode *node, Scope *parent) { 111 assert(node->type == NodeTypeBlock); 112 ScopeBlock *scope = allocate<ScopeBlock>(1); 113 init_scope(&scope->base, ScopeIdBlock, node, parent); 114 scope->name = node->data.block.name; 115 return scope; 116 } 117 118 ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) { 119 assert(node->type == NodeTypeDefer); 120 ScopeDefer *scope = allocate<ScopeDefer>(1); 121 init_scope(&scope->base, ScopeIdDefer, node, parent); 122 return scope; 123 } 124 125 ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent) { 126 assert(node->type == NodeTypeDefer); 127 ScopeDeferExpr *scope = allocate<ScopeDeferExpr>(1); 128 init_scope(&scope->base, ScopeIdDeferExpr, node, parent); 129 return scope; 130 } 131 132 Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var) { 133 ScopeVarDecl *scope = allocate<ScopeVarDecl>(1); 134 init_scope(&scope->base, ScopeIdVarDecl, node, parent); 135 scope->var = var; 136 return &scope->base; 137 } 138 139 ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent) { 140 assert(node->type == NodeTypeFnCallExpr); 141 ScopeCImport *scope = allocate<ScopeCImport>(1); 142 init_scope(&scope->base, ScopeIdCImport, node, parent); 143 buf_resize(&scope->buf, 0); 144 return scope; 145 } 146 147 ScopeLoop *create_loop_scope(AstNode *node, Scope *parent) { 148 ScopeLoop *scope = allocate<ScopeLoop>(1); 149 init_scope(&scope->base, ScopeIdLoop, node, parent); 150 if (node->type == NodeTypeWhileExpr) { 151 scope->name = node->data.while_expr.name; 152 } else if (node->type == NodeTypeForExpr) { 153 scope->name = node->data.for_expr.name; 154 } else { 155 zig_unreachable(); 156 } 157 return scope; 158 } 159 160 ScopeSuspend *create_suspend_scope(AstNode *node, Scope *parent) { 161 assert(node->type == NodeTypeSuspend); 162 ScopeSuspend *scope = allocate<ScopeSuspend>(1); 163 init_scope(&scope->base, ScopeIdSuspend, node, parent); 164 scope->name = node->data.suspend.name; 165 return scope; 166 } 167 168 ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_entry) { 169 ScopeFnDef *scope = allocate<ScopeFnDef>(1); 170 init_scope(&scope->base, ScopeIdFnDef, node, parent); 171 scope->fn_entry = fn_entry; 172 return scope; 173 } 174 175 Scope *create_comptime_scope(AstNode *node, Scope *parent) { 176 assert(node->type == NodeTypeCompTime || node->type == NodeTypeSwitchExpr); 177 ScopeCompTime *scope = allocate<ScopeCompTime>(1); 178 init_scope(&scope->base, ScopeIdCompTime, node, parent); 179 return &scope->base; 180 } 181 182 Scope *create_coro_prelude_scope(AstNode *node, Scope *parent) { 183 ScopeCoroPrelude *scope = allocate<ScopeCoroPrelude>(1); 184 init_scope(&scope->base, ScopeIdCoroPrelude, node, parent); 185 return &scope->base; 186 } 187 188 ImportTableEntry *get_scope_import(Scope *scope) { 189 while (scope) { 190 if (scope->id == ScopeIdDecls) { 191 ScopeDecls *decls_scope = (ScopeDecls *)scope; 192 assert(decls_scope->import); 193 return decls_scope->import; 194 } 195 scope = scope->parent; 196 } 197 zig_unreachable(); 198 } 199 200 static TypeTableEntry *new_container_type_entry(TypeTableEntryId id, AstNode *source_node, Scope *parent_scope) { 201 TypeTableEntry *entry = new_type_table_entry(id); 202 *get_container_scope_ptr(entry) = create_decls_scope(source_node, parent_scope, entry, get_scope_import(parent_scope)); 203 return entry; 204 } 205 206 static uint8_t bits_needed_for_unsigned(uint64_t x) { 207 if (x == 0) { 208 return 0; 209 } 210 uint8_t base = log2_u64(x); 211 uint64_t upper = (((uint64_t)1) << base) - 1; 212 return (upper >= x) ? base : (base + 1); 213 } 214 215 bool type_is_complete(TypeTableEntry *type_entry) { 216 switch (type_entry->id) { 217 case TypeTableEntryIdInvalid: 218 zig_unreachable(); 219 case TypeTableEntryIdStruct: 220 return type_entry->data.structure.complete; 221 case TypeTableEntryIdEnum: 222 return type_entry->data.enumeration.complete; 223 case TypeTableEntryIdUnion: 224 return type_entry->data.unionation.complete; 225 case TypeTableEntryIdOpaque: 226 return false; 227 case TypeTableEntryIdMetaType: 228 case TypeTableEntryIdVoid: 229 case TypeTableEntryIdBool: 230 case TypeTableEntryIdUnreachable: 231 case TypeTableEntryIdInt: 232 case TypeTableEntryIdFloat: 233 case TypeTableEntryIdPointer: 234 case TypeTableEntryIdArray: 235 case TypeTableEntryIdComptimeFloat: 236 case TypeTableEntryIdComptimeInt: 237 case TypeTableEntryIdUndefined: 238 case TypeTableEntryIdNull: 239 case TypeTableEntryIdOptional: 240 case TypeTableEntryIdErrorUnion: 241 case TypeTableEntryIdErrorSet: 242 case TypeTableEntryIdFn: 243 case TypeTableEntryIdNamespace: 244 case TypeTableEntryIdBlock: 245 case TypeTableEntryIdBoundFn: 246 case TypeTableEntryIdArgTuple: 247 case TypeTableEntryIdPromise: 248 return true; 249 } 250 zig_unreachable(); 251 } 252 253 bool type_has_zero_bits_known(TypeTableEntry *type_entry) { 254 switch (type_entry->id) { 255 case TypeTableEntryIdInvalid: 256 zig_unreachable(); 257 case TypeTableEntryIdStruct: 258 return type_entry->data.structure.zero_bits_known; 259 case TypeTableEntryIdEnum: 260 return type_entry->data.enumeration.zero_bits_known; 261 case TypeTableEntryIdUnion: 262 return type_entry->data.unionation.zero_bits_known; 263 case TypeTableEntryIdMetaType: 264 case TypeTableEntryIdVoid: 265 case TypeTableEntryIdBool: 266 case TypeTableEntryIdUnreachable: 267 case TypeTableEntryIdInt: 268 case TypeTableEntryIdFloat: 269 case TypeTableEntryIdPointer: 270 case TypeTableEntryIdArray: 271 case TypeTableEntryIdComptimeFloat: 272 case TypeTableEntryIdComptimeInt: 273 case TypeTableEntryIdUndefined: 274 case TypeTableEntryIdNull: 275 case TypeTableEntryIdOptional: 276 case TypeTableEntryIdErrorUnion: 277 case TypeTableEntryIdErrorSet: 278 case TypeTableEntryIdFn: 279 case TypeTableEntryIdNamespace: 280 case TypeTableEntryIdBlock: 281 case TypeTableEntryIdBoundFn: 282 case TypeTableEntryIdArgTuple: 283 case TypeTableEntryIdOpaque: 284 case TypeTableEntryIdPromise: 285 return true; 286 } 287 zig_unreachable(); 288 } 289 290 291 uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry) { 292 assert(type_is_complete(type_entry)); 293 294 if (!type_has_bits(type_entry)) 295 return 0; 296 297 if (type_entry->id == TypeTableEntryIdStruct && type_entry->data.structure.layout == ContainerLayoutPacked) { 298 uint64_t size_in_bits = type_size_bits(g, type_entry); 299 return (size_in_bits + 7) / 8; 300 } else if (type_entry->id == TypeTableEntryIdArray) { 301 TypeTableEntry *child_type = type_entry->data.array.child_type; 302 if (child_type->id == TypeTableEntryIdStruct && 303 child_type->data.structure.layout == ContainerLayoutPacked) 304 { 305 uint64_t size_in_bits = type_size_bits(g, type_entry); 306 return (size_in_bits + 7) / 8; 307 } 308 } 309 310 return LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref); 311 } 312 313 uint64_t type_size_bits(CodeGen *g, TypeTableEntry *type_entry) { 314 assert(type_is_complete(type_entry)); 315 316 if (!type_has_bits(type_entry)) 317 return 0; 318 319 if (type_entry->id == TypeTableEntryIdStruct && type_entry->data.structure.layout == ContainerLayoutPacked) { 320 uint64_t result = 0; 321 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { 322 result += type_size_bits(g, type_entry->data.structure.fields[i].type_entry); 323 } 324 return result; 325 } else if (type_entry->id == TypeTableEntryIdArray) { 326 TypeTableEntry *child_type = type_entry->data.array.child_type; 327 if (child_type->id == TypeTableEntryIdStruct && 328 child_type->data.structure.layout == ContainerLayoutPacked) 329 { 330 return type_entry->data.array.len * type_size_bits(g, child_type); 331 } 332 } 333 334 return LLVMSizeOfTypeInBits(g->target_data_ref, type_entry->type_ref); 335 } 336 337 bool type_is_copyable(CodeGen *g, TypeTableEntry *type_entry) { 338 type_ensure_zero_bits_known(g, type_entry); 339 if (!type_has_bits(type_entry)) 340 return true; 341 342 if (!handle_is_ptr(type_entry)) 343 return true; 344 345 ensure_complete_type(g, type_entry); 346 return type_entry->is_copyable; 347 } 348 349 static bool is_slice(TypeTableEntry *type) { 350 return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice; 351 } 352 353 TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) { 354 return get_int_type(g, false, bits_needed_for_unsigned(x)); 355 } 356 357 TypeTableEntry *get_promise_type(CodeGen *g, TypeTableEntry *result_type) { 358 if (result_type != nullptr && result_type->promise_parent != nullptr) { 359 return result_type->promise_parent; 360 } else if (result_type == nullptr && g->builtin_types.entry_promise != nullptr) { 361 return g->builtin_types.entry_promise; 362 } 363 364 TypeTableEntry *u8_ptr_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false); 365 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPromise); 366 entry->type_ref = u8_ptr_type->type_ref; 367 entry->zero_bits = false; 368 entry->data.promise.result_type = result_type; 369 buf_init_from_str(&entry->name, "promise"); 370 if (result_type != nullptr) { 371 buf_appendf(&entry->name, "->%s", buf_ptr(&result_type->name)); 372 } 373 entry->di_type = u8_ptr_type->di_type; 374 375 if (result_type != nullptr) { 376 result_type->promise_parent = entry; 377 } else if (result_type == nullptr) { 378 g->builtin_types.entry_promise = entry; 379 } 380 return entry; 381 } 382 383 TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type, bool is_const, 384 bool is_volatile, PtrLen ptr_len, uint32_t byte_alignment, uint32_t bit_offset, uint32_t unaligned_bit_count) 385 { 386 assert(!type_is_invalid(child_type)); 387 assert(ptr_len == PtrLenSingle || child_type->id != TypeTableEntryIdOpaque); 388 389 TypeId type_id = {}; 390 TypeTableEntry **parent_pointer = nullptr; 391 uint32_t abi_alignment = get_abi_alignment(g, child_type); 392 if (unaligned_bit_count != 0 || is_volatile || byte_alignment != abi_alignment || ptr_len != PtrLenSingle) { 393 type_id.id = TypeTableEntryIdPointer; 394 type_id.data.pointer.child_type = child_type; 395 type_id.data.pointer.is_const = is_const; 396 type_id.data.pointer.is_volatile = is_volatile; 397 type_id.data.pointer.alignment = byte_alignment; 398 type_id.data.pointer.bit_offset = bit_offset; 399 type_id.data.pointer.unaligned_bit_count = unaligned_bit_count; 400 type_id.data.pointer.ptr_len = ptr_len; 401 402 auto existing_entry = g->type_table.maybe_get(type_id); 403 if (existing_entry) 404 return existing_entry->value; 405 } else { 406 assert(bit_offset == 0); 407 parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)]; 408 if (*parent_pointer) { 409 assert((*parent_pointer)->data.pointer.alignment == byte_alignment); 410 return *parent_pointer; 411 } 412 } 413 414 type_ensure_zero_bits_known(g, child_type); 415 416 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer); 417 entry->is_copyable = true; 418 419 const char *star_str = ptr_len == PtrLenSingle ? "*" : "[*]"; 420 const char *const_str = is_const ? "const " : ""; 421 const char *volatile_str = is_volatile ? "volatile " : ""; 422 buf_resize(&entry->name, 0); 423 if (unaligned_bit_count == 0 && byte_alignment == abi_alignment) { 424 buf_appendf(&entry->name, "%s%s%s%s", star_str, const_str, volatile_str, buf_ptr(&child_type->name)); 425 } else if (unaligned_bit_count == 0) { 426 buf_appendf(&entry->name, "%salign(%" PRIu32 ") %s%s%s", star_str, byte_alignment, 427 const_str, volatile_str, buf_ptr(&child_type->name)); 428 } else { 429 buf_appendf(&entry->name, "%salign(%" PRIu32 ":%" PRIu32 ":%" PRIu32 ") %s%s%s", star_str, byte_alignment, 430 bit_offset, bit_offset + unaligned_bit_count, const_str, volatile_str, buf_ptr(&child_type->name)); 431 } 432 433 assert(child_type->id != TypeTableEntryIdInvalid); 434 435 entry->zero_bits = !type_has_bits(child_type); 436 437 if (!entry->zero_bits) { 438 assert(byte_alignment > 0); 439 if (is_const || is_volatile || unaligned_bit_count != 0 || byte_alignment != abi_alignment || 440 ptr_len != PtrLenSingle) 441 { 442 TypeTableEntry *peer_type = get_pointer_to_type(g, child_type, false); 443 entry->type_ref = peer_type->type_ref; 444 entry->di_type = peer_type->di_type; 445 } else { 446 entry->type_ref = LLVMPointerType(child_type->type_ref, 0); 447 448 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); 449 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref); 450 assert(child_type->di_type); 451 entry->di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, child_type->di_type, 452 debug_size_in_bits, debug_align_in_bits, buf_ptr(&entry->name)); 453 } 454 } else { 455 assert(byte_alignment == 0); 456 entry->di_type = g->builtin_types.entry_void->di_type; 457 } 458 459 entry->data.pointer.ptr_len = ptr_len; 460 entry->data.pointer.child_type = child_type; 461 entry->data.pointer.is_const = is_const; 462 entry->data.pointer.is_volatile = is_volatile; 463 entry->data.pointer.alignment = byte_alignment; 464 entry->data.pointer.bit_offset = bit_offset; 465 entry->data.pointer.unaligned_bit_count = unaligned_bit_count; 466 467 if (parent_pointer) { 468 *parent_pointer = entry; 469 } else { 470 g->type_table.put(type_id, entry); 471 } 472 return entry; 473 } 474 475 TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) { 476 return get_pointer_to_type_extra(g, child_type, is_const, false, PtrLenSingle, 477 get_abi_alignment(g, child_type), 0, 0); 478 } 479 480 TypeTableEntry *get_promise_frame_type(CodeGen *g, TypeTableEntry *return_type) { 481 if (return_type->promise_frame_parent != nullptr) { 482 return return_type->promise_frame_parent; 483 } 484 485 TypeTableEntry *awaiter_handle_type = get_maybe_type(g, g->builtin_types.entry_promise); 486 TypeTableEntry *result_ptr_type = get_pointer_to_type(g, return_type, false); 487 488 ZigList<const char *> field_names = {}; 489 field_names.append(AWAITER_HANDLE_FIELD_NAME); 490 field_names.append(RESULT_FIELD_NAME); 491 field_names.append(RESULT_PTR_FIELD_NAME); 492 if (g->have_err_ret_tracing) { 493 field_names.append(ERR_RET_TRACE_PTR_FIELD_NAME); 494 field_names.append(ERR_RET_TRACE_FIELD_NAME); 495 field_names.append(RETURN_ADDRESSES_FIELD_NAME); 496 } 497 498 ZigList<TypeTableEntry *> field_types = {}; 499 field_types.append(awaiter_handle_type); 500 field_types.append(return_type); 501 field_types.append(result_ptr_type); 502 if (g->have_err_ret_tracing) { 503 field_types.append(get_ptr_to_stack_trace_type(g)); 504 field_types.append(g->stack_trace_type); 505 field_types.append(get_array_type(g, g->builtin_types.entry_usize, stack_trace_ptr_count)); 506 } 507 508 assert(field_names.length == field_types.length); 509 Buf *name = buf_sprintf("AsyncFramePromise(%s)", buf_ptr(&return_type->name)); 510 TypeTableEntry *entry = get_struct_type(g, buf_ptr(name), field_names.items, field_types.items, field_names.length); 511 512 return_type->promise_frame_parent = entry; 513 return entry; 514 } 515 516 TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) { 517 if (child_type->maybe_parent) { 518 TypeTableEntry *entry = child_type->maybe_parent; 519 return entry; 520 } else { 521 ensure_complete_type(g, child_type); 522 523 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdOptional); 524 assert(child_type->type_ref || child_type->zero_bits); 525 assert(child_type->di_type); 526 entry->is_copyable = type_is_copyable(g, child_type); 527 528 buf_resize(&entry->name, 0); 529 buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name)); 530 531 if (child_type->zero_bits) { 532 entry->type_ref = LLVMInt1Type(); 533 entry->di_type = g->builtin_types.entry_bool->di_type; 534 } else if (type_is_codegen_pointer(child_type)) { 535 // this is an optimization but also is necessary for calling C 536 // functions where all pointers are maybe pointers 537 // function types are technically pointers 538 entry->type_ref = child_type->type_ref; 539 entry->di_type = child_type->di_type; 540 } else { 541 // create a struct with a boolean whether this is the null value 542 LLVMTypeRef elem_types[] = { 543 child_type->type_ref, 544 LLVMInt1Type(), 545 }; 546 entry->type_ref = LLVMStructType(elem_types, 2, false); 547 548 549 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit); 550 ZigLLVMDIFile *di_file = nullptr; 551 unsigned line = 0; 552 entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, 553 ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name), 554 compile_unit_scope, di_file, line); 555 556 uint64_t val_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, child_type->type_ref); 557 uint64_t val_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, child_type->type_ref); 558 uint64_t val_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 0); 559 560 TypeTableEntry *bool_type = g->builtin_types.entry_bool; 561 uint64_t maybe_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, bool_type->type_ref); 562 uint64_t maybe_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, bool_type->type_ref); 563 uint64_t maybe_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 1); 564 565 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); 566 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); 567 568 ZigLLVMDIType *di_element_types[] = { 569 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 570 "val", di_file, line, 571 val_debug_size_in_bits, 572 val_debug_align_in_bits, 573 val_offset_in_bits, 574 0, child_type->di_type), 575 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 576 "maybe", di_file, line, 577 maybe_debug_size_in_bits, 578 maybe_debug_align_in_bits, 579 maybe_offset_in_bits, 580 0, bool_type->di_type), 581 }; 582 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 583 compile_unit_scope, 584 buf_ptr(&entry->name), 585 di_file, line, debug_size_in_bits, debug_align_in_bits, 0, 586 nullptr, di_element_types, 2, 0, nullptr, ""); 587 588 ZigLLVMReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type); 589 entry->di_type = replacement_di_type; 590 } 591 592 entry->data.maybe.child_type = child_type; 593 594 child_type->maybe_parent = entry; 595 return entry; 596 } 597 } 598 599 TypeTableEntry *get_error_union_type(CodeGen *g, TypeTableEntry *err_set_type, TypeTableEntry *payload_type) { 600 assert(err_set_type->id == TypeTableEntryIdErrorSet); 601 assert(!type_is_invalid(payload_type)); 602 603 TypeId type_id = {}; 604 type_id.id = TypeTableEntryIdErrorUnion; 605 type_id.data.error_union.err_set_type = err_set_type; 606 type_id.data.error_union.payload_type = payload_type; 607 608 auto existing_entry = g->type_table.maybe_get(type_id); 609 if (existing_entry) { 610 return existing_entry->value; 611 } 612 613 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdErrorUnion); 614 entry->is_copyable = true; 615 assert(payload_type->di_type); 616 ensure_complete_type(g, payload_type); 617 618 buf_resize(&entry->name, 0); 619 buf_appendf(&entry->name, "%s!%s", buf_ptr(&err_set_type->name), buf_ptr(&payload_type->name)); 620 621 entry->data.error_union.err_set_type = err_set_type; 622 entry->data.error_union.payload_type = payload_type; 623 624 if (!type_has_bits(payload_type)) { 625 if (type_has_bits(err_set_type)) { 626 entry->type_ref = err_set_type->type_ref; 627 entry->di_type = err_set_type->di_type; 628 g->error_di_types.append(&entry->di_type); 629 } else { 630 entry->zero_bits = true; 631 entry->di_type = g->builtin_types.entry_void->di_type; 632 } 633 } else if (!type_has_bits(err_set_type)) { 634 entry->type_ref = payload_type->type_ref; 635 entry->di_type = payload_type->di_type; 636 } else { 637 LLVMTypeRef elem_types[] = { 638 err_set_type->type_ref, 639 payload_type->type_ref, 640 }; 641 entry->type_ref = LLVMStructType(elem_types, 2, false); 642 643 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit); 644 ZigLLVMDIFile *di_file = nullptr; 645 unsigned line = 0; 646 entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, 647 ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name), 648 compile_unit_scope, di_file, line); 649 650 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, err_set_type->type_ref); 651 uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, err_set_type->type_ref); 652 uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, err_union_err_index); 653 654 uint64_t value_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, payload_type->type_ref); 655 uint64_t value_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, payload_type->type_ref); 656 uint64_t value_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 657 err_union_payload_index); 658 659 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); 660 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); 661 662 ZigLLVMDIType *di_element_types[] = { 663 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 664 "tag", di_file, line, 665 tag_debug_size_in_bits, 666 tag_debug_align_in_bits, 667 tag_offset_in_bits, 668 0, err_set_type->di_type), 669 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 670 "value", di_file, line, 671 value_debug_size_in_bits, 672 value_debug_align_in_bits, 673 value_offset_in_bits, 674 0, payload_type->di_type), 675 }; 676 677 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 678 compile_unit_scope, 679 buf_ptr(&entry->name), 680 di_file, line, 681 debug_size_in_bits, 682 debug_align_in_bits, 683 0, 684 nullptr, di_element_types, 2, 0, nullptr, ""); 685 686 ZigLLVMReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type); 687 entry->di_type = replacement_di_type; 688 } 689 690 g->type_table.put(type_id, entry); 691 return entry; 692 } 693 694 TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size) { 695 TypeId type_id = {}; 696 type_id.id = TypeTableEntryIdArray; 697 type_id.data.array.child_type = child_type; 698 type_id.data.array.size = array_size; 699 auto existing_entry = g->type_table.maybe_get(type_id); 700 if (existing_entry) { 701 TypeTableEntry *entry = existing_entry->value; 702 return entry; 703 } 704 705 ensure_complete_type(g, child_type); 706 707 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray); 708 entry->zero_bits = (array_size == 0) || child_type->zero_bits; 709 entry->is_copyable = false; 710 711 buf_resize(&entry->name, 0); 712 buf_appendf(&entry->name, "[%" ZIG_PRI_u64 "]%s", array_size, buf_ptr(&child_type->name)); 713 714 if (entry->zero_bits) { 715 entry->di_type = ZigLLVMCreateDebugArrayType(g->dbuilder, 0, 716 0, child_type->di_type, 0); 717 } else { 718 entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref, 719 (unsigned int)array_size) : nullptr; 720 721 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); 722 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); 723 724 entry->di_type = ZigLLVMCreateDebugArrayType(g->dbuilder, debug_size_in_bits, 725 debug_align_in_bits, child_type->di_type, (int)array_size); 726 } 727 entry->data.array.child_type = child_type; 728 entry->data.array.len = array_size; 729 730 g->type_table.put(type_id, entry); 731 return entry; 732 } 733 734 static void slice_type_common_init(CodeGen *g, TypeTableEntry *pointer_type, TypeTableEntry *entry) { 735 unsigned element_count = 2; 736 Buf *ptr_field_name = buf_create_from_str("ptr"); 737 Buf *len_field_name = buf_create_from_str("len"); 738 739 entry->data.structure.layout = ContainerLayoutAuto; 740 entry->data.structure.is_slice = true; 741 entry->data.structure.src_field_count = element_count; 742 entry->data.structure.gen_field_count = element_count; 743 entry->data.structure.fields = allocate<TypeStructField>(element_count); 744 entry->data.structure.fields_by_name.init(element_count); 745 entry->data.structure.fields[slice_ptr_index].name = ptr_field_name; 746 entry->data.structure.fields[slice_ptr_index].type_entry = pointer_type; 747 entry->data.structure.fields[slice_ptr_index].src_index = slice_ptr_index; 748 entry->data.structure.fields[slice_ptr_index].gen_index = 0; 749 entry->data.structure.fields[slice_len_index].name = len_field_name; 750 entry->data.structure.fields[slice_len_index].type_entry = g->builtin_types.entry_usize; 751 entry->data.structure.fields[slice_len_index].src_index = slice_len_index; 752 entry->data.structure.fields[slice_len_index].gen_index = 1; 753 754 entry->data.structure.fields_by_name.put(ptr_field_name, &entry->data.structure.fields[slice_ptr_index]); 755 entry->data.structure.fields_by_name.put(len_field_name, &entry->data.structure.fields[slice_len_index]); 756 757 assert(type_has_zero_bits_known(pointer_type->data.pointer.child_type)); 758 if (pointer_type->data.pointer.child_type->zero_bits) { 759 entry->data.structure.gen_field_count = 1; 760 entry->data.structure.fields[slice_ptr_index].gen_index = SIZE_MAX; 761 entry->data.structure.fields[slice_len_index].gen_index = 0; 762 } 763 } 764 765 TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *ptr_type) { 766 assert(ptr_type->id == TypeTableEntryIdPointer); 767 assert(ptr_type->data.pointer.ptr_len == PtrLenUnknown); 768 769 TypeTableEntry **parent_pointer = &ptr_type->data.pointer.slice_parent; 770 if (*parent_pointer) { 771 return *parent_pointer; 772 } 773 774 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct); 775 entry->is_copyable = true; 776 777 // replace the & with [] to go from a ptr type name to a slice type name 778 buf_resize(&entry->name, 0); 779 size_t name_offset = (ptr_type->data.pointer.ptr_len == PtrLenSingle) ? 1 : 3; 780 buf_appendf(&entry->name, "[]%s", buf_ptr(&ptr_type->name) + name_offset); 781 782 TypeTableEntry *child_type = ptr_type->data.pointer.child_type; 783 uint32_t abi_alignment = get_abi_alignment(g, child_type); 784 if (ptr_type->data.pointer.is_const || ptr_type->data.pointer.is_volatile || 785 ptr_type->data.pointer.alignment != abi_alignment) 786 { 787 TypeTableEntry *peer_ptr_type = get_pointer_to_type_extra(g, child_type, false, false, 788 PtrLenUnknown, abi_alignment, 0, 0); 789 TypeTableEntry *peer_slice_type = get_slice_type(g, peer_ptr_type); 790 791 slice_type_common_init(g, ptr_type, entry); 792 793 entry->type_ref = peer_slice_type->type_ref; 794 entry->di_type = peer_slice_type->di_type; 795 entry->data.structure.complete = true; 796 entry->data.structure.zero_bits_known = true; 797 entry->data.structure.abi_alignment = peer_slice_type->data.structure.abi_alignment; 798 799 *parent_pointer = entry; 800 return entry; 801 } 802 803 // If the child type is []const T then we need to make sure the type ref 804 // and debug info is the same as if the child type were []T. 805 if (is_slice(child_type)) { 806 TypeTableEntry *child_ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry; 807 assert(child_ptr_type->id == TypeTableEntryIdPointer); 808 TypeTableEntry *grand_child_type = child_ptr_type->data.pointer.child_type; 809 if (child_ptr_type->data.pointer.is_const || child_ptr_type->data.pointer.is_volatile || 810 child_ptr_type->data.pointer.alignment != get_abi_alignment(g, grand_child_type)) 811 { 812 TypeTableEntry *bland_child_ptr_type = get_pointer_to_type_extra(g, grand_child_type, false, false, 813 PtrLenUnknown, get_abi_alignment(g, grand_child_type), 0, 0); 814 TypeTableEntry *bland_child_slice = get_slice_type(g, bland_child_ptr_type); 815 TypeTableEntry *peer_ptr_type = get_pointer_to_type_extra(g, bland_child_slice, false, false, 816 PtrLenUnknown, get_abi_alignment(g, bland_child_slice), 0, 0); 817 TypeTableEntry *peer_slice_type = get_slice_type(g, peer_ptr_type); 818 819 entry->type_ref = peer_slice_type->type_ref; 820 entry->di_type = peer_slice_type->di_type; 821 entry->data.structure.abi_alignment = peer_slice_type->data.structure.abi_alignment; 822 } 823 } 824 825 slice_type_common_init(g, ptr_type, entry); 826 827 if (!entry->type_ref) { 828 entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&entry->name)); 829 830 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit); 831 ZigLLVMDIFile *di_file = nullptr; 832 unsigned line = 0; 833 entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, 834 ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name), 835 compile_unit_scope, di_file, line); 836 837 if (child_type->zero_bits) { 838 LLVMTypeRef element_types[] = { 839 g->builtin_types.entry_usize->type_ref, 840 }; 841 LLVMStructSetBody(entry->type_ref, element_types, 1, false); 842 843 TypeTableEntry *usize_type = g->builtin_types.entry_usize; 844 uint64_t len_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, usize_type->type_ref); 845 uint64_t len_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, usize_type->type_ref); 846 uint64_t len_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 0); 847 848 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); 849 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref); 850 851 ZigLLVMDIType *di_element_types[] = { 852 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 853 "len", di_file, line, 854 len_debug_size_in_bits, 855 len_debug_align_in_bits, 856 len_offset_in_bits, 857 0, usize_type->di_type), 858 }; 859 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 860 compile_unit_scope, 861 buf_ptr(&entry->name), 862 di_file, line, debug_size_in_bits, debug_align_in_bits, 0, 863 nullptr, di_element_types, 1, 0, nullptr, ""); 864 865 ZigLLVMReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type); 866 entry->di_type = replacement_di_type; 867 868 entry->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref, usize_type->type_ref); 869 } else { 870 unsigned element_count = 2; 871 LLVMTypeRef element_types[] = { 872 ptr_type->type_ref, 873 g->builtin_types.entry_usize->type_ref, 874 }; 875 LLVMStructSetBody(entry->type_ref, element_types, element_count, false); 876 877 878 uint64_t ptr_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, ptr_type->type_ref); 879 uint64_t ptr_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, ptr_type->type_ref); 880 uint64_t ptr_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 0); 881 882 TypeTableEntry *usize_type = g->builtin_types.entry_usize; 883 uint64_t len_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, usize_type->type_ref); 884 uint64_t len_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, usize_type->type_ref); 885 uint64_t len_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 1); 886 887 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); 888 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref); 889 890 ZigLLVMDIType *di_element_types[] = { 891 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 892 "ptr", di_file, line, 893 ptr_debug_size_in_bits, 894 ptr_debug_align_in_bits, 895 ptr_offset_in_bits, 896 0, ptr_type->di_type), 897 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 898 "len", di_file, line, 899 len_debug_size_in_bits, 900 len_debug_align_in_bits, 901 len_offset_in_bits, 902 0, usize_type->di_type), 903 }; 904 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 905 compile_unit_scope, 906 buf_ptr(&entry->name), 907 di_file, line, debug_size_in_bits, debug_align_in_bits, 0, 908 nullptr, di_element_types, 2, 0, nullptr, ""); 909 910 ZigLLVMReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type); 911 entry->di_type = replacement_di_type; 912 913 entry->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref, entry->type_ref); 914 } 915 } 916 917 918 entry->data.structure.complete = true; 919 entry->data.structure.zero_bits_known = true; 920 921 *parent_pointer = entry; 922 return entry; 923 } 924 925 TypeTableEntry *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *name) { 926 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdOpaque); 927 928 buf_init_from_str(&entry->name, name); 929 930 ImportTableEntry *import = scope ? get_scope_import(scope) : nullptr; 931 unsigned line = source_node ? (unsigned)(source_node->line + 1) : 0; 932 933 entry->is_copyable = false; 934 entry->type_ref = LLVMInt8Type(); 935 entry->di_type = ZigLLVMCreateDebugForwardDeclType(g->dbuilder, 936 ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name), 937 import ? ZigLLVMFileToScope(import->di_file) : nullptr, 938 import ? import->di_file : nullptr, 939 line); 940 entry->zero_bits = false; 941 942 return entry; 943 } 944 945 TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry) { 946 TypeTableEntry *fn_type = fn_entry->type_entry; 947 assert(fn_type->id == TypeTableEntryIdFn); 948 if (fn_type->data.fn.bound_fn_parent) 949 return fn_type->data.fn.bound_fn_parent; 950 951 TypeTableEntry *bound_fn_type = new_type_table_entry(TypeTableEntryIdBoundFn); 952 bound_fn_type->is_copyable = false; 953 bound_fn_type->data.bound_fn.fn_type = fn_type; 954 bound_fn_type->zero_bits = true; 955 956 buf_resize(&bound_fn_type->name, 0); 957 buf_appendf(&bound_fn_type->name, "(bound %s)", buf_ptr(&fn_type->name)); 958 959 fn_type->data.fn.bound_fn_parent = bound_fn_type; 960 return bound_fn_type; 961 } 962 963 bool calling_convention_does_first_arg_return(CallingConvention cc) { 964 return cc == CallingConventionUnspecified; 965 } 966 967 static const char *calling_convention_name(CallingConvention cc) { 968 switch (cc) { 969 case CallingConventionUnspecified: return "undefined"; 970 case CallingConventionC: return "ccc"; 971 case CallingConventionCold: return "coldcc"; 972 case CallingConventionNaked: return "nakedcc"; 973 case CallingConventionStdcall: return "stdcallcc"; 974 case CallingConventionAsync: return "async"; 975 } 976 zig_unreachable(); 977 } 978 979 static const char *calling_convention_fn_type_str(CallingConvention cc) { 980 switch (cc) { 981 case CallingConventionUnspecified: return ""; 982 case CallingConventionC: return "extern "; 983 case CallingConventionCold: return "coldcc "; 984 case CallingConventionNaked: return "nakedcc "; 985 case CallingConventionStdcall: return "stdcallcc "; 986 case CallingConventionAsync: return "async "; 987 } 988 zig_unreachable(); 989 } 990 991 static bool calling_convention_allows_zig_types(CallingConvention cc) { 992 switch (cc) { 993 case CallingConventionUnspecified: 994 case CallingConventionAsync: 995 return true; 996 case CallingConventionC: 997 case CallingConventionCold: 998 case CallingConventionNaked: 999 case CallingConventionStdcall: 1000 return false; 1001 } 1002 zig_unreachable(); 1003 } 1004 1005 TypeTableEntry *get_ptr_to_stack_trace_type(CodeGen *g) { 1006 if (g->stack_trace_type == nullptr) { 1007 ConstExprValue *stack_trace_type_val = get_builtin_value(g, "StackTrace"); 1008 assert(stack_trace_type_val->type->id == TypeTableEntryIdMetaType); 1009 g->stack_trace_type = stack_trace_type_val->data.x_type; 1010 g->ptr_to_stack_trace_type = get_pointer_to_type(g, g->stack_trace_type, false); 1011 } 1012 return g->ptr_to_stack_trace_type; 1013 } 1014 1015 TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { 1016 auto table_entry = g->fn_type_table.maybe_get(fn_type_id); 1017 if (table_entry) { 1018 return table_entry->value; 1019 } 1020 if (fn_type_id->return_type != nullptr) { 1021 ensure_complete_type(g, fn_type_id->return_type); 1022 if (type_is_invalid(fn_type_id->return_type)) 1023 return g->builtin_types.entry_invalid; 1024 } else { 1025 zig_panic("TODO implement inferred return types https://github.com/ziglang/zig/issues/447"); 1026 } 1027 1028 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn); 1029 fn_type->is_copyable = true; 1030 fn_type->data.fn.fn_type_id = *fn_type_id; 1031 1032 bool skip_debug_info = false; 1033 1034 // populate the name of the type 1035 buf_resize(&fn_type->name, 0); 1036 if (fn_type->data.fn.fn_type_id.cc == CallingConventionAsync) { 1037 assert(fn_type_id->async_allocator_type != nullptr); 1038 buf_appendf(&fn_type->name, "async<%s> ", buf_ptr(&fn_type_id->async_allocator_type->name)); 1039 } else { 1040 const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc); 1041 buf_appendf(&fn_type->name, "%s", cc_str); 1042 } 1043 buf_appendf(&fn_type->name, "fn("); 1044 for (size_t i = 0; i < fn_type_id->param_count; i += 1) { 1045 FnTypeParamInfo *param_info = &fn_type_id->param_info[i]; 1046 1047 TypeTableEntry *param_type = param_info->type; 1048 const char *comma = (i == 0) ? "" : ", "; 1049 const char *noalias_str = param_info->is_noalias ? "noalias " : ""; 1050 buf_appendf(&fn_type->name, "%s%s%s", comma, noalias_str, buf_ptr(¶m_type->name)); 1051 1052 skip_debug_info = skip_debug_info || !param_type->di_type; 1053 } 1054 1055 if (fn_type_id->is_var_args) { 1056 const char *comma = (fn_type_id->param_count == 0) ? "" : ", "; 1057 buf_appendf(&fn_type->name, "%s...", comma); 1058 } 1059 buf_appendf(&fn_type->name, ")"); 1060 if (fn_type_id->alignment != 0) { 1061 buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment); 1062 } 1063 buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name)); 1064 skip_debug_info = skip_debug_info || !fn_type_id->return_type->di_type; 1065 1066 // next, loop over the parameters again and compute debug information 1067 // and codegen information 1068 if (!skip_debug_info) { 1069 bool first_arg_return = calling_convention_does_first_arg_return(fn_type_id->cc) && 1070 handle_is_ptr(fn_type_id->return_type); 1071 bool is_async = fn_type_id->cc == CallingConventionAsync; 1072 bool prefix_arg_error_return_trace = g->have_err_ret_tracing && fn_type_can_fail(fn_type_id); 1073 // +1 for maybe making the first argument the return value 1074 // +1 for maybe first argument the error return trace 1075 // +2 for maybe arguments async allocator and error code pointer 1076 LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(4 + fn_type_id->param_count); 1077 // +1 because 0 is the return type and 1078 // +1 for maybe making first arg ret val and 1079 // +1 for maybe first argument the error return trace 1080 // +2 for maybe arguments async allocator and error code pointer 1081 ZigLLVMDIType **param_di_types = allocate<ZigLLVMDIType*>(5 + fn_type_id->param_count); 1082 param_di_types[0] = fn_type_id->return_type->di_type; 1083 size_t gen_param_index = 0; 1084 TypeTableEntry *gen_return_type; 1085 if (is_async) { 1086 gen_return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, false); 1087 } else if (!type_has_bits(fn_type_id->return_type)) { 1088 gen_return_type = g->builtin_types.entry_void; 1089 } else if (first_arg_return) { 1090 TypeTableEntry *gen_type = get_pointer_to_type(g, fn_type_id->return_type, false); 1091 gen_param_types[gen_param_index] = gen_type->type_ref; 1092 gen_param_index += 1; 1093 // after the gen_param_index += 1 because 0 is the return type 1094 param_di_types[gen_param_index] = gen_type->di_type; 1095 gen_return_type = g->builtin_types.entry_void; 1096 } else { 1097 gen_return_type = fn_type_id->return_type; 1098 } 1099 fn_type->data.fn.gen_return_type = gen_return_type; 1100 1101 if (prefix_arg_error_return_trace) { 1102 TypeTableEntry *gen_type = get_ptr_to_stack_trace_type(g); 1103 gen_param_types[gen_param_index] = gen_type->type_ref; 1104 gen_param_index += 1; 1105 // after the gen_param_index += 1 because 0 is the return type 1106 param_di_types[gen_param_index] = gen_type->di_type; 1107 } 1108 if (is_async) { 1109 { 1110 // async allocator param 1111 TypeTableEntry *gen_type = fn_type_id->async_allocator_type; 1112 gen_param_types[gen_param_index] = gen_type->type_ref; 1113 gen_param_index += 1; 1114 // after the gen_param_index += 1 because 0 is the return type 1115 param_di_types[gen_param_index] = gen_type->di_type; 1116 } 1117 1118 { 1119 // error code pointer 1120 TypeTableEntry *gen_type = get_pointer_to_type(g, g->builtin_types.entry_global_error_set, false); 1121 gen_param_types[gen_param_index] = gen_type->type_ref; 1122 gen_param_index += 1; 1123 // after the gen_param_index += 1 because 0 is the return type 1124 param_di_types[gen_param_index] = gen_type->di_type; 1125 } 1126 } 1127 1128 fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count); 1129 for (size_t i = 0; i < fn_type_id->param_count; i += 1) { 1130 FnTypeParamInfo *src_param_info = &fn_type->data.fn.fn_type_id.param_info[i]; 1131 TypeTableEntry *type_entry = src_param_info->type; 1132 FnGenParamInfo *gen_param_info = &fn_type->data.fn.gen_param_info[i]; 1133 1134 gen_param_info->src_index = i; 1135 gen_param_info->gen_index = SIZE_MAX; 1136 1137 type_ensure_zero_bits_known(g, type_entry); 1138 if (type_has_bits(type_entry)) { 1139 TypeTableEntry *gen_type; 1140 if (handle_is_ptr(type_entry)) { 1141 gen_type = get_pointer_to_type(g, type_entry, true); 1142 gen_param_info->is_byval = true; 1143 } else { 1144 gen_type = type_entry; 1145 } 1146 gen_param_types[gen_param_index] = gen_type->type_ref; 1147 gen_param_info->gen_index = gen_param_index; 1148 gen_param_info->type = gen_type; 1149 1150 gen_param_index += 1; 1151 1152 // after the gen_param_index += 1 because 0 is the return type 1153 param_di_types[gen_param_index] = gen_type->di_type; 1154 } 1155 } 1156 1157 fn_type->data.fn.gen_param_count = gen_param_index; 1158 1159 fn_type->data.fn.raw_type_ref = LLVMFunctionType(gen_return_type->type_ref, 1160 gen_param_types, (unsigned int)gen_param_index, fn_type_id->is_var_args); 1161 fn_type->type_ref = LLVMPointerType(fn_type->data.fn.raw_type_ref, 0); 1162 fn_type->di_type = ZigLLVMCreateSubroutineType(g->dbuilder, param_di_types, (int)(gen_param_index + 1), 0); 1163 } 1164 1165 g->fn_type_table.put(&fn_type->data.fn.fn_type_id, fn_type); 1166 1167 return fn_type; 1168 } 1169 1170 static TypeTableEntryId container_to_type(ContainerKind kind) { 1171 switch (kind) { 1172 case ContainerKindStruct: 1173 return TypeTableEntryIdStruct; 1174 case ContainerKindEnum: 1175 return TypeTableEntryIdEnum; 1176 case ContainerKindUnion: 1177 return TypeTableEntryIdUnion; 1178 } 1179 zig_unreachable(); 1180 } 1181 1182 TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, 1183 AstNode *decl_node, const char *name, ContainerLayout layout) 1184 { 1185 TypeTableEntryId type_id = container_to_type(kind); 1186 TypeTableEntry *entry = new_container_type_entry(type_id, decl_node, scope); 1187 1188 switch (kind) { 1189 case ContainerKindStruct: 1190 entry->data.structure.decl_node = decl_node; 1191 entry->data.structure.layout = layout; 1192 break; 1193 case ContainerKindEnum: 1194 entry->data.enumeration.decl_node = decl_node; 1195 entry->data.enumeration.layout = layout; 1196 break; 1197 case ContainerKindUnion: 1198 entry->data.unionation.decl_node = decl_node; 1199 entry->data.unionation.layout = layout; 1200 break; 1201 } 1202 1203 size_t line = decl_node ? decl_node->line : 0; 1204 unsigned dwarf_kind = ZigLLVMTag_DW_structure_type(); 1205 1206 ImportTableEntry *import = get_scope_import(scope); 1207 entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), name); 1208 entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, 1209 dwarf_kind, name, 1210 ZigLLVMFileToScope(import->di_file), import->di_file, (unsigned)(line + 1)); 1211 1212 buf_init_from_str(&entry->name, name); 1213 1214 return entry; 1215 } 1216 1217 static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, TypeTableEntry *type_entry, Buf *type_name) { 1218 size_t backward_branch_count = 0; 1219 return ir_eval_const_value(g, scope, node, type_entry, 1220 &backward_branch_count, default_backward_branch_quota, 1221 nullptr, nullptr, node, type_name, nullptr); 1222 } 1223 1224 TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { 1225 IrInstruction *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type, nullptr); 1226 if (result->value.type->id == TypeTableEntryIdInvalid) 1227 return g->builtin_types.entry_invalid; 1228 1229 assert(result->value.special != ConstValSpecialRuntime); 1230 return result->value.data.x_type; 1231 } 1232 1233 TypeTableEntry *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) { 1234 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn); 1235 fn_type->is_copyable = false; 1236 buf_resize(&fn_type->name, 0); 1237 if (fn_type->data.fn.fn_type_id.cc == CallingConventionAsync) { 1238 const char *async_allocator_type_str = (fn_type->data.fn.fn_type_id.async_allocator_type == nullptr) ? 1239 "var" : buf_ptr(&fn_type_id->async_allocator_type->name); 1240 buf_appendf(&fn_type->name, "async(%s) ", async_allocator_type_str); 1241 } else { 1242 const char *cc_str = calling_convention_fn_type_str(fn_type->data.fn.fn_type_id.cc); 1243 buf_appendf(&fn_type->name, "%s", cc_str); 1244 } 1245 buf_appendf(&fn_type->name, "fn("); 1246 size_t i = 0; 1247 for (; i < fn_type_id->next_param_index; i += 1) { 1248 const char *comma_str = (i == 0) ? "" : ","; 1249 buf_appendf(&fn_type->name, "%s%s", comma_str, 1250 buf_ptr(&fn_type_id->param_info[i].type->name)); 1251 } 1252 for (; i < fn_type_id->param_count; i += 1) { 1253 const char *comma_str = (i == 0) ? "" : ","; 1254 buf_appendf(&fn_type->name, "%svar", comma_str); 1255 } 1256 buf_appendf(&fn_type->name, ")var"); 1257 1258 fn_type->data.fn.fn_type_id = *fn_type_id; 1259 fn_type->data.fn.is_generic = true; 1260 fn_type->zero_bits = true; 1261 return fn_type; 1262 } 1263 1264 void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc) { 1265 assert(proto_node->type == NodeTypeFnProto); 1266 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; 1267 1268 if (fn_proto->cc == CallingConventionUnspecified) { 1269 bool extern_abi = fn_proto->is_extern || fn_proto->is_export; 1270 fn_type_id->cc = extern_abi ? CallingConventionC : CallingConventionUnspecified; 1271 } else { 1272 fn_type_id->cc = fn_proto->cc; 1273 } 1274 1275 fn_type_id->param_count = fn_proto->params.length; 1276 fn_type_id->param_info = allocate<FnTypeParamInfo>(param_count_alloc); 1277 fn_type_id->next_param_index = 0; 1278 fn_type_id->is_var_args = fn_proto->is_var_args; 1279 } 1280 1281 static bool analyze_const_align(CodeGen *g, Scope *scope, AstNode *node, uint32_t *result) { 1282 IrInstruction *align_result = analyze_const_value(g, scope, node, get_align_amt_type(g), nullptr); 1283 if (type_is_invalid(align_result->value.type)) 1284 return false; 1285 1286 uint32_t align_bytes = bigint_as_unsigned(&align_result->value.data.x_bigint); 1287 if (align_bytes == 0) { 1288 add_node_error(g, node, buf_sprintf("alignment must be >= 1")); 1289 return false; 1290 } 1291 if (!is_power_of_2(align_bytes)) { 1292 add_node_error(g, node, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); 1293 return false; 1294 } 1295 1296 *result = align_bytes; 1297 return true; 1298 } 1299 1300 static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **out_buffer) { 1301 TypeTableEntry *ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, 1302 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0); 1303 TypeTableEntry *str_type = get_slice_type(g, ptr_type); 1304 IrInstruction *instr = analyze_const_value(g, scope, node, str_type, nullptr); 1305 if (type_is_invalid(instr->value.type)) 1306 return false; 1307 1308 ConstExprValue *ptr_field = &instr->value.data.x_struct.fields[slice_ptr_index]; 1309 ConstExprValue *len_field = &instr->value.data.x_struct.fields[slice_len_index]; 1310 1311 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); 1312 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; 1313 expand_undef_array(g, array_val); 1314 size_t len = bigint_as_unsigned(&len_field->data.x_bigint); 1315 Buf *result = buf_alloc(); 1316 buf_resize(result, len); 1317 for (size_t i = 0; i < len; i += 1) { 1318 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; 1319 ConstExprValue *char_val = &array_val->data.x_array.s_none.elements[new_index]; 1320 if (char_val->special == ConstValSpecialUndef) { 1321 add_node_error(g, node, buf_sprintf("use of undefined value")); 1322 return false; 1323 } 1324 uint64_t big_c = bigint_as_unsigned(&char_val->data.x_bigint); 1325 assert(big_c <= UINT8_MAX); 1326 uint8_t c = (uint8_t)big_c; 1327 buf_ptr(result)[i] = c; 1328 } 1329 *out_buffer = result; 1330 return true; 1331 } 1332 1333 static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) { 1334 switch (type_entry->id) { 1335 case TypeTableEntryIdInvalid: 1336 zig_unreachable(); 1337 case TypeTableEntryIdMetaType: 1338 case TypeTableEntryIdUnreachable: 1339 case TypeTableEntryIdComptimeFloat: 1340 case TypeTableEntryIdComptimeInt: 1341 case TypeTableEntryIdUndefined: 1342 case TypeTableEntryIdNull: 1343 case TypeTableEntryIdErrorUnion: 1344 case TypeTableEntryIdErrorSet: 1345 case TypeTableEntryIdNamespace: 1346 case TypeTableEntryIdBlock: 1347 case TypeTableEntryIdBoundFn: 1348 case TypeTableEntryIdArgTuple: 1349 case TypeTableEntryIdOpaque: 1350 case TypeTableEntryIdPromise: 1351 return false; 1352 case TypeTableEntryIdVoid: 1353 case TypeTableEntryIdBool: 1354 case TypeTableEntryIdInt: 1355 case TypeTableEntryIdFloat: 1356 case TypeTableEntryIdPointer: 1357 case TypeTableEntryIdArray: 1358 case TypeTableEntryIdFn: 1359 return true; 1360 case TypeTableEntryIdStruct: 1361 return type_entry->data.structure.layout == ContainerLayoutPacked; 1362 case TypeTableEntryIdUnion: 1363 return type_entry->data.unionation.layout == ContainerLayoutPacked; 1364 case TypeTableEntryIdOptional: 1365 { 1366 TypeTableEntry *child_type = type_entry->data.maybe.child_type; 1367 return type_is_codegen_pointer(child_type); 1368 } 1369 case TypeTableEntryIdEnum: 1370 return type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr; 1371 } 1372 zig_unreachable(); 1373 } 1374 1375 static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) { 1376 switch (type_entry->id) { 1377 case TypeTableEntryIdInvalid: 1378 zig_unreachable(); 1379 case TypeTableEntryIdMetaType: 1380 case TypeTableEntryIdComptimeFloat: 1381 case TypeTableEntryIdComptimeInt: 1382 case TypeTableEntryIdUndefined: 1383 case TypeTableEntryIdNull: 1384 case TypeTableEntryIdErrorUnion: 1385 case TypeTableEntryIdErrorSet: 1386 case TypeTableEntryIdNamespace: 1387 case TypeTableEntryIdBlock: 1388 case TypeTableEntryIdBoundFn: 1389 case TypeTableEntryIdArgTuple: 1390 case TypeTableEntryIdPromise: 1391 return false; 1392 case TypeTableEntryIdOpaque: 1393 case TypeTableEntryIdUnreachable: 1394 case TypeTableEntryIdVoid: 1395 case TypeTableEntryIdBool: 1396 return true; 1397 case TypeTableEntryIdInt: 1398 switch (type_entry->data.integral.bit_count) { 1399 case 8: 1400 case 16: 1401 case 32: 1402 case 64: 1403 case 128: 1404 return true; 1405 default: 1406 return false; 1407 } 1408 case TypeTableEntryIdFloat: 1409 return true; 1410 case TypeTableEntryIdArray: 1411 return type_allowed_in_extern(g, type_entry->data.array.child_type); 1412 case TypeTableEntryIdFn: 1413 return type_entry->data.fn.fn_type_id.cc == CallingConventionC; 1414 case TypeTableEntryIdPointer: 1415 return type_allowed_in_extern(g, type_entry->data.pointer.child_type); 1416 case TypeTableEntryIdStruct: 1417 return type_entry->data.structure.layout == ContainerLayoutExtern || type_entry->data.structure.layout == ContainerLayoutPacked; 1418 case TypeTableEntryIdOptional: 1419 { 1420 TypeTableEntry *child_type = type_entry->data.maybe.child_type; 1421 return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn; 1422 } 1423 case TypeTableEntryIdEnum: 1424 return type_entry->data.enumeration.layout == ContainerLayoutExtern || type_entry->data.enumeration.layout == ContainerLayoutPacked; 1425 case TypeTableEntryIdUnion: 1426 return type_entry->data.unionation.layout == ContainerLayoutExtern || type_entry->data.unionation.layout == ContainerLayoutPacked; 1427 } 1428 zig_unreachable(); 1429 } 1430 1431 TypeTableEntry *get_auto_err_set_type(CodeGen *g, FnTableEntry *fn_entry) { 1432 TypeTableEntry *err_set_type = new_type_table_entry(TypeTableEntryIdErrorSet); 1433 buf_resize(&err_set_type->name, 0); 1434 buf_appendf(&err_set_type->name, "@typeOf(%s).ReturnType.ErrorSet", buf_ptr(&fn_entry->symbol_name)); 1435 err_set_type->is_copyable = true; 1436 err_set_type->type_ref = g->builtin_types.entry_global_error_set->type_ref; 1437 err_set_type->di_type = g->builtin_types.entry_global_error_set->di_type; 1438 err_set_type->data.error_set.err_count = 0; 1439 err_set_type->data.error_set.errors = nullptr; 1440 err_set_type->data.error_set.infer_fn = fn_entry; 1441 1442 g->error_di_types.append(&err_set_type->di_type); 1443 1444 return err_set_type; 1445 } 1446 1447 static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope, FnTableEntry *fn_entry) { 1448 assert(proto_node->type == NodeTypeFnProto); 1449 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; 1450 1451 FnTypeId fn_type_id = {0}; 1452 init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); 1453 1454 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { 1455 AstNode *param_node = fn_proto->params.at(fn_type_id.next_param_index); 1456 assert(param_node->type == NodeTypeParamDecl); 1457 1458 bool param_is_comptime = param_node->data.param_decl.is_inline; 1459 bool param_is_var_args = param_node->data.param_decl.is_var_args; 1460 1461 if (param_is_comptime) { 1462 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 1463 add_node_error(g, param_node, 1464 buf_sprintf("comptime parameter not allowed in function with calling convention '%s'", 1465 calling_convention_name(fn_type_id.cc))); 1466 return g->builtin_types.entry_invalid; 1467 } 1468 return get_generic_fn_type(g, &fn_type_id); 1469 } else if (param_is_var_args) { 1470 if (fn_type_id.cc == CallingConventionC) { 1471 fn_type_id.param_count = fn_type_id.next_param_index; 1472 continue; 1473 } else if (calling_convention_allows_zig_types(fn_type_id.cc)) { 1474 return get_generic_fn_type(g, &fn_type_id); 1475 } else { 1476 add_node_error(g, param_node, 1477 buf_sprintf("var args not allowed in function with calling convention '%s'", 1478 calling_convention_name(fn_type_id.cc))); 1479 return g->builtin_types.entry_invalid; 1480 } 1481 } else if (param_node->data.param_decl.var_token != nullptr) { 1482 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 1483 add_node_error(g, param_node->data.param_decl.type, 1484 buf_sprintf("parameter of type 'var' not allowed in function with calling convention '%s'", 1485 calling_convention_name(fn_type_id.cc))); 1486 return g->builtin_types.entry_invalid; 1487 } 1488 return get_generic_fn_type(g, &fn_type_id); 1489 } 1490 1491 TypeTableEntry *type_entry = analyze_type_expr(g, child_scope, param_node->data.param_decl.type); 1492 if (type_is_invalid(type_entry)) { 1493 return g->builtin_types.entry_invalid; 1494 } 1495 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 1496 type_ensure_zero_bits_known(g, type_entry); 1497 if (!type_has_bits(type_entry)) { 1498 add_node_error(g, param_node->data.param_decl.type, 1499 buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", 1500 buf_ptr(&type_entry->name), calling_convention_name(fn_type_id.cc))); 1501 return g->builtin_types.entry_invalid; 1502 } 1503 } 1504 1505 if (!calling_convention_allows_zig_types(fn_type_id.cc) && !type_allowed_in_extern(g, type_entry)) { 1506 add_node_error(g, param_node->data.param_decl.type, 1507 buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", 1508 buf_ptr(&type_entry->name), 1509 calling_convention_name(fn_type_id.cc))); 1510 return g->builtin_types.entry_invalid; 1511 } 1512 1513 switch (type_entry->id) { 1514 case TypeTableEntryIdInvalid: 1515 return g->builtin_types.entry_invalid; 1516 case TypeTableEntryIdUnreachable: 1517 case TypeTableEntryIdUndefined: 1518 case TypeTableEntryIdNull: 1519 case TypeTableEntryIdArgTuple: 1520 case TypeTableEntryIdOpaque: 1521 add_node_error(g, param_node->data.param_decl.type, 1522 buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name))); 1523 return g->builtin_types.entry_invalid; 1524 case TypeTableEntryIdComptimeFloat: 1525 case TypeTableEntryIdComptimeInt: 1526 case TypeTableEntryIdNamespace: 1527 case TypeTableEntryIdBlock: 1528 case TypeTableEntryIdBoundFn: 1529 case TypeTableEntryIdMetaType: 1530 add_node_error(g, param_node->data.param_decl.type, 1531 buf_sprintf("parameter of type '%s' must be declared comptime", 1532 buf_ptr(&type_entry->name))); 1533 return g->builtin_types.entry_invalid; 1534 case TypeTableEntryIdVoid: 1535 case TypeTableEntryIdBool: 1536 case TypeTableEntryIdInt: 1537 case TypeTableEntryIdFloat: 1538 case TypeTableEntryIdPointer: 1539 case TypeTableEntryIdArray: 1540 case TypeTableEntryIdStruct: 1541 case TypeTableEntryIdOptional: 1542 case TypeTableEntryIdErrorUnion: 1543 case TypeTableEntryIdErrorSet: 1544 case TypeTableEntryIdEnum: 1545 case TypeTableEntryIdUnion: 1546 case TypeTableEntryIdFn: 1547 case TypeTableEntryIdPromise: 1548 ensure_complete_type(g, type_entry); 1549 if (calling_convention_allows_zig_types(fn_type_id.cc) && !type_is_copyable(g, type_entry)) { 1550 add_node_error(g, param_node->data.param_decl.type, 1551 buf_sprintf("type '%s' is not copyable; cannot pass by value", buf_ptr(&type_entry->name))); 1552 return g->builtin_types.entry_invalid; 1553 } 1554 break; 1555 } 1556 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; 1557 param_info->type = type_entry; 1558 param_info->is_noalias = param_node->data.param_decl.is_noalias; 1559 } 1560 1561 if (fn_proto->align_expr != nullptr) { 1562 if (!analyze_const_align(g, child_scope, fn_proto->align_expr, &fn_type_id.alignment)) { 1563 return g->builtin_types.entry_invalid; 1564 } 1565 } 1566 1567 if (fn_proto->return_var_token != nullptr) { 1568 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 1569 add_node_error(g, fn_proto->return_type, 1570 buf_sprintf("return type 'var' not allowed in function with calling convention '%s'", 1571 calling_convention_name(fn_type_id.cc))); 1572 return g->builtin_types.entry_invalid; 1573 } 1574 add_node_error(g, proto_node, 1575 buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447")); 1576 return g->builtin_types.entry_invalid; 1577 //return get_generic_fn_type(g, &fn_type_id); 1578 } 1579 1580 TypeTableEntry *specified_return_type = analyze_type_expr(g, child_scope, fn_proto->return_type); 1581 if (type_is_invalid(specified_return_type)) { 1582 fn_type_id.return_type = g->builtin_types.entry_invalid; 1583 return g->builtin_types.entry_invalid; 1584 } 1585 1586 if (fn_proto->auto_err_set) { 1587 TypeTableEntry *inferred_err_set_type = get_auto_err_set_type(g, fn_entry); 1588 fn_type_id.return_type = get_error_union_type(g, inferred_err_set_type, specified_return_type); 1589 } else { 1590 fn_type_id.return_type = specified_return_type; 1591 } 1592 1593 if (!calling_convention_allows_zig_types(fn_type_id.cc) && !type_allowed_in_extern(g, fn_type_id.return_type)) { 1594 add_node_error(g, fn_proto->return_type, 1595 buf_sprintf("return type '%s' not allowed in function with calling convention '%s'", 1596 buf_ptr(&fn_type_id.return_type->name), 1597 calling_convention_name(fn_type_id.cc))); 1598 return g->builtin_types.entry_invalid; 1599 } 1600 1601 switch (fn_type_id.return_type->id) { 1602 case TypeTableEntryIdInvalid: 1603 zig_unreachable(); 1604 1605 case TypeTableEntryIdUndefined: 1606 case TypeTableEntryIdNull: 1607 case TypeTableEntryIdArgTuple: 1608 case TypeTableEntryIdOpaque: 1609 add_node_error(g, fn_proto->return_type, 1610 buf_sprintf("return type '%s' not allowed", buf_ptr(&fn_type_id.return_type->name))); 1611 return g->builtin_types.entry_invalid; 1612 1613 case TypeTableEntryIdComptimeFloat: 1614 case TypeTableEntryIdComptimeInt: 1615 case TypeTableEntryIdNamespace: 1616 case TypeTableEntryIdBlock: 1617 case TypeTableEntryIdBoundFn: 1618 case TypeTableEntryIdMetaType: 1619 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 1620 add_node_error(g, fn_proto->return_type, 1621 buf_sprintf("return type '%s' not allowed in function with calling convention '%s'", 1622 buf_ptr(&fn_type_id.return_type->name), 1623 calling_convention_name(fn_type_id.cc))); 1624 return g->builtin_types.entry_invalid; 1625 } 1626 return get_generic_fn_type(g, &fn_type_id); 1627 case TypeTableEntryIdUnreachable: 1628 case TypeTableEntryIdVoid: 1629 case TypeTableEntryIdBool: 1630 case TypeTableEntryIdInt: 1631 case TypeTableEntryIdFloat: 1632 case TypeTableEntryIdPointer: 1633 case TypeTableEntryIdArray: 1634 case TypeTableEntryIdStruct: 1635 case TypeTableEntryIdOptional: 1636 case TypeTableEntryIdErrorUnion: 1637 case TypeTableEntryIdErrorSet: 1638 case TypeTableEntryIdEnum: 1639 case TypeTableEntryIdUnion: 1640 case TypeTableEntryIdFn: 1641 case TypeTableEntryIdPromise: 1642 break; 1643 } 1644 1645 if (fn_type_id.cc == CallingConventionAsync) { 1646 if (fn_proto->async_allocator_type == nullptr) { 1647 return get_generic_fn_type(g, &fn_type_id); 1648 } 1649 fn_type_id.async_allocator_type = analyze_type_expr(g, child_scope, fn_proto->async_allocator_type); 1650 if (type_is_invalid(fn_type_id.async_allocator_type)) { 1651 return g->builtin_types.entry_invalid; 1652 } 1653 } 1654 1655 return get_fn_type(g, &fn_type_id); 1656 } 1657 1658 bool type_is_invalid(TypeTableEntry *type_entry) { 1659 switch (type_entry->id) { 1660 case TypeTableEntryIdInvalid: 1661 return true; 1662 case TypeTableEntryIdStruct: 1663 return type_entry->data.structure.is_invalid; 1664 case TypeTableEntryIdEnum: 1665 return type_entry->data.enumeration.is_invalid; 1666 case TypeTableEntryIdUnion: 1667 return type_entry->data.unionation.is_invalid; 1668 default: 1669 return false; 1670 } 1671 zig_unreachable(); 1672 } 1673 1674 1675 static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { 1676 assert(enum_type->id == TypeTableEntryIdEnum); 1677 1678 if (enum_type->data.enumeration.complete) 1679 return; 1680 1681 resolve_enum_zero_bits(g, enum_type); 1682 if (type_is_invalid(enum_type)) 1683 return; 1684 1685 AstNode *decl_node = enum_type->data.enumeration.decl_node; 1686 1687 if (enum_type->data.enumeration.embedded_in_current) { 1688 if (!enum_type->data.enumeration.reported_infinite_err) { 1689 enum_type->data.enumeration.reported_infinite_err = true; 1690 add_node_error(g, decl_node, buf_sprintf("enum '%s' contains itself", buf_ptr(&enum_type->name))); 1691 } 1692 return; 1693 } 1694 1695 assert(!enum_type->data.enumeration.zero_bits_loop_flag); 1696 assert(decl_node->type == NodeTypeContainerDecl); 1697 assert(enum_type->di_type); 1698 1699 uint32_t field_count = enum_type->data.enumeration.src_field_count; 1700 1701 assert(enum_type->data.enumeration.fields); 1702 ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count); 1703 1704 Scope *scope = &enum_type->data.enumeration.decls_scope->base; 1705 ImportTableEntry *import = get_scope_import(scope); 1706 1707 // set temporary flag 1708 enum_type->data.enumeration.embedded_in_current = true; 1709 1710 for (uint32_t i = 0; i < field_count; i += 1) { 1711 TypeEnumField *enum_field = &enum_type->data.enumeration.fields[i]; 1712 1713 // TODO send patch to LLVM to support APInt in createEnumerator instead of int64_t 1714 // http://lists.llvm.org/pipermail/llvm-dev/2017-December/119456.html 1715 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(enum_field->name), 1716 bigint_as_signed(&enum_field->value)); 1717 } 1718 1719 // unset temporary flag 1720 enum_type->data.enumeration.embedded_in_current = false; 1721 enum_type->data.enumeration.complete = true; 1722 1723 if (enum_type->data.enumeration.is_invalid) 1724 return; 1725 1726 if (enum_type->zero_bits) { 1727 enum_type->type_ref = LLVMVoidType(); 1728 1729 uint64_t debug_size_in_bits = 0; 1730 uint64_t debug_align_in_bits = 0; 1731 ZigLLVMDIType **di_root_members = nullptr; 1732 size_t debug_member_count = 0; 1733 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 1734 ZigLLVMFileToScope(import->di_file), 1735 buf_ptr(&enum_type->name), 1736 import->di_file, (unsigned)(decl_node->line + 1), 1737 debug_size_in_bits, 1738 debug_align_in_bits, 1739 0, nullptr, di_root_members, (int)debug_member_count, 0, nullptr, ""); 1740 1741 ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, replacement_di_type); 1742 enum_type->di_type = replacement_di_type; 1743 return; 1744 } 1745 1746 TypeTableEntry *tag_int_type = enum_type->data.enumeration.tag_int_type; 1747 1748 // create debug type for tag 1749 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_int_type->type_ref); 1750 uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref); 1751 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, 1752 ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name), 1753 import->di_file, (unsigned)(decl_node->line + 1), 1754 tag_debug_size_in_bits, 1755 tag_debug_align_in_bits, 1756 di_enumerators, field_count, 1757 tag_int_type->di_type, ""); 1758 1759 ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type); 1760 enum_type->di_type = tag_di_type; 1761 } 1762 1763 1764 TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[], 1765 TypeTableEntry *field_types[], size_t field_count) 1766 { 1767 TypeTableEntry *struct_type = new_type_table_entry(TypeTableEntryIdStruct); 1768 1769 buf_init_from_str(&struct_type->name, type_name); 1770 1771 struct_type->data.structure.src_field_count = field_count; 1772 struct_type->data.structure.gen_field_count = 0; 1773 struct_type->data.structure.zero_bits_known = true; 1774 struct_type->data.structure.complete = true; 1775 struct_type->data.structure.fields = allocate<TypeStructField>(field_count); 1776 struct_type->data.structure.fields_by_name.init(field_count); 1777 1778 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count); 1779 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count); 1780 for (size_t i = 0; i < field_count; i += 1) { 1781 element_types[struct_type->data.structure.gen_field_count] = field_types[i]->type_ref; 1782 1783 TypeStructField *field = &struct_type->data.structure.fields[i]; 1784 field->name = buf_create_from_str(field_names[i]); 1785 field->type_entry = field_types[i]; 1786 field->src_index = i; 1787 1788 if (type_has_bits(field->type_entry)) { 1789 field->gen_index = struct_type->data.structure.gen_field_count; 1790 struct_type->data.structure.gen_field_count += 1; 1791 } else { 1792 field->gen_index = SIZE_MAX; 1793 } 1794 1795 auto prev_entry = struct_type->data.structure.fields_by_name.put_unique(field->name, field); 1796 assert(prev_entry == nullptr); 1797 } 1798 1799 struct_type->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), type_name); 1800 LLVMStructSetBody(struct_type->type_ref, element_types, struct_type->data.structure.gen_field_count, false); 1801 1802 struct_type->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, 1803 ZigLLVMTag_DW_structure_type(), type_name, 1804 ZigLLVMCompileUnitToScope(g->compile_unit), nullptr, 0); 1805 1806 for (size_t i = 0; i < field_count; i += 1) { 1807 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; 1808 if (type_struct_field->gen_index == SIZE_MAX) { 1809 continue; 1810 } 1811 TypeTableEntry *field_type = type_struct_field->type_entry; 1812 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref); 1813 uint64_t debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref); 1814 uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, type_struct_field->gen_index); 1815 di_element_types[type_struct_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder, 1816 ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name), 1817 nullptr, 0, 1818 debug_size_in_bits, 1819 debug_align_in_bits, 1820 debug_offset_in_bits, 1821 0, field_type->di_type); 1822 1823 assert(di_element_types[type_struct_field->gen_index]); 1824 } 1825 1826 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref); 1827 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, struct_type->type_ref); 1828 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 1829 ZigLLVMCompileUnitToScope(g->compile_unit), 1830 type_name, nullptr, 0, 1831 debug_size_in_bits, 1832 debug_align_in_bits, 1833 0, 1834 nullptr, di_element_types, struct_type->data.structure.gen_field_count, 0, nullptr, ""); 1835 1836 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type); 1837 struct_type->di_type = replacement_di_type; 1838 struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref, struct_type->type_ref); 1839 1840 return struct_type; 1841 } 1842 1843 static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { 1844 assert(struct_type->id == TypeTableEntryIdStruct); 1845 1846 if (struct_type->data.structure.complete) 1847 return; 1848 1849 resolve_struct_zero_bits(g, struct_type); 1850 if (struct_type->data.structure.is_invalid) 1851 return; 1852 1853 AstNode *decl_node = struct_type->data.structure.decl_node; 1854 1855 if (struct_type->data.structure.embedded_in_current) { 1856 struct_type->data.structure.is_invalid = true; 1857 if (!struct_type->data.structure.reported_infinite_err) { 1858 struct_type->data.structure.reported_infinite_err = true; 1859 add_node_error(g, decl_node, 1860 buf_sprintf("struct '%s' contains itself", buf_ptr(&struct_type->name))); 1861 } 1862 return; 1863 } 1864 1865 assert(!struct_type->data.structure.zero_bits_loop_flag); 1866 assert(struct_type->data.structure.fields || struct_type->data.structure.src_field_count == 0); 1867 assert(decl_node->type == NodeTypeContainerDecl); 1868 1869 size_t field_count = struct_type->data.structure.src_field_count; 1870 1871 size_t gen_field_count = struct_type->data.structure.gen_field_count; 1872 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(gen_field_count); 1873 1874 // this field should be set to true only during the recursive calls to resolve_struct_type 1875 struct_type->data.structure.embedded_in_current = true; 1876 1877 Scope *scope = &struct_type->data.structure.decls_scope->base; 1878 1879 size_t gen_field_index = 0; 1880 bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked); 1881 size_t packed_bits_offset = 0; 1882 size_t first_packed_bits_offset_misalign = SIZE_MAX; 1883 size_t debug_field_count = 0; 1884 1885 for (size_t i = 0; i < field_count; i += 1) { 1886 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; 1887 TypeTableEntry *field_type = type_struct_field->type_entry; 1888 1889 ensure_complete_type(g, field_type); 1890 if (type_is_invalid(field_type)) { 1891 struct_type->data.structure.is_invalid = true; 1892 break; 1893 } 1894 1895 if (!type_has_bits(field_type)) 1896 continue; 1897 1898 type_struct_field->gen_index = gen_field_index; 1899 1900 if (packed) { 1901 if (!type_allowed_in_packed_struct(field_type)) { 1902 AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); 1903 add_node_error(g, field_source_node, 1904 buf_sprintf("packed structs cannot contain fields of type '%s'", 1905 buf_ptr(&field_type->name))); 1906 struct_type->data.structure.is_invalid = true; 1907 break; 1908 } 1909 1910 size_t field_size_in_bits = type_size_bits(g, field_type); 1911 size_t next_packed_bits_offset = packed_bits_offset + field_size_in_bits; 1912 1913 type_struct_field->packed_bits_size = field_size_in_bits; 1914 1915 if (first_packed_bits_offset_misalign != SIZE_MAX) { 1916 // this field is not byte-aligned; it is part of the previous field with a bit offset 1917 type_struct_field->packed_bits_offset = packed_bits_offset - first_packed_bits_offset_misalign; 1918 type_struct_field->unaligned_bit_count = field_size_in_bits; 1919 1920 size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign; 1921 LLVMTypeRef int_type_ref = LLVMIntType((unsigned)(full_bit_count)); 1922 if (8 * LLVMStoreSizeOfType(g->target_data_ref, int_type_ref) == full_bit_count) { 1923 // next field recovers store alignment 1924 element_types[gen_field_index] = int_type_ref; 1925 gen_field_index += 1; 1926 1927 first_packed_bits_offset_misalign = SIZE_MAX; 1928 } 1929 } else if (8 * LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref) != field_size_in_bits) { 1930 first_packed_bits_offset_misalign = packed_bits_offset; 1931 type_struct_field->packed_bits_offset = 0; 1932 type_struct_field->unaligned_bit_count = field_size_in_bits; 1933 } else { 1934 // This is a byte-aligned field (both start and end) in a packed struct. 1935 element_types[gen_field_index] = field_type->type_ref; 1936 type_struct_field->packed_bits_offset = 0; 1937 type_struct_field->unaligned_bit_count = 0; 1938 gen_field_index += 1; 1939 } 1940 packed_bits_offset = next_packed_bits_offset; 1941 } else { 1942 element_types[gen_field_index] = field_type->type_ref; 1943 assert(element_types[gen_field_index]); 1944 1945 gen_field_index += 1; 1946 } 1947 debug_field_count += 1; 1948 } 1949 if (first_packed_bits_offset_misalign != SIZE_MAX) { 1950 size_t full_bit_count = packed_bits_offset - first_packed_bits_offset_misalign; 1951 LLVMTypeRef int_type_ref = LLVMIntType((unsigned)full_bit_count); 1952 size_t store_bit_count = 8 * LLVMStoreSizeOfType(g->target_data_ref, int_type_ref); 1953 element_types[gen_field_index] = LLVMIntType((unsigned)store_bit_count); 1954 gen_field_index += 1; 1955 } 1956 1957 struct_type->data.structure.embedded_in_current = false; 1958 struct_type->data.structure.complete = true; 1959 1960 if (struct_type->data.structure.is_invalid) 1961 return; 1962 1963 if (struct_type->zero_bits) { 1964 struct_type->type_ref = LLVMVoidType(); 1965 1966 ImportTableEntry *import = get_scope_import(scope); 1967 uint64_t debug_size_in_bits = 0; 1968 uint64_t debug_align_in_bits = 0; 1969 ZigLLVMDIType **di_element_types = nullptr; 1970 size_t debug_field_count = 0; 1971 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 1972 ZigLLVMFileToScope(import->di_file), 1973 buf_ptr(&struct_type->name), 1974 import->di_file, (unsigned)(decl_node->line + 1), 1975 debug_size_in_bits, 1976 debug_align_in_bits, 1977 0, nullptr, di_element_types, (int)debug_field_count, 0, nullptr, ""); 1978 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type); 1979 struct_type->di_type = replacement_di_type; 1980 return; 1981 } 1982 assert(struct_type->di_type); 1983 1984 1985 // the count may have been adjusting from packing bit fields 1986 gen_field_count = gen_field_index; 1987 struct_type->data.structure.gen_field_count = (uint32_t)gen_field_count; 1988 1989 LLVMStructSetBody(struct_type->type_ref, element_types, (unsigned)gen_field_count, packed); 1990 1991 // if you hit this assert then probably this type or a related type didn't 1992 // get ensure_complete_type called on it before using it with something that 1993 // requires a complete type 1994 assert(LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref) > 0); 1995 1996 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(debug_field_count); 1997 1998 ImportTableEntry *import = get_scope_import(scope); 1999 size_t debug_field_index = 0; 2000 for (size_t i = 0; i < field_count; i += 1) { 2001 AstNode *field_node = decl_node->data.container_decl.fields.at(i); 2002 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; 2003 size_t gen_field_index = type_struct_field->gen_index; 2004 if (gen_field_index == SIZE_MAX) { 2005 continue; 2006 } 2007 2008 TypeTableEntry *field_type = type_struct_field->type_entry; 2009 2010 // if the field is a function, actually the debug info should be a pointer. 2011 ZigLLVMDIType *field_di_type; 2012 if (field_type->id == TypeTableEntryIdFn) { 2013 TypeTableEntry *field_ptr_type = get_pointer_to_type(g, field_type, true); 2014 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_ptr_type->type_ref); 2015 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_ptr_type->type_ref); 2016 field_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, field_type->di_type, 2017 debug_size_in_bits, debug_align_in_bits, buf_ptr(&field_ptr_type->name)); 2018 } else { 2019 field_di_type = field_type->di_type; 2020 } 2021 2022 assert(field_type->type_ref); 2023 assert(struct_type->type_ref); 2024 assert(struct_type->data.structure.complete); 2025 uint64_t debug_size_in_bits; 2026 uint64_t debug_align_in_bits; 2027 uint64_t debug_offset_in_bits; 2028 if (packed) { 2029 debug_size_in_bits = type_struct_field->packed_bits_size; 2030 debug_align_in_bits = 1; 2031 debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, 2032 (unsigned)gen_field_index) + type_struct_field->packed_bits_offset; 2033 } else { 2034 debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref); 2035 debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref); 2036 debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, 2037 (unsigned)gen_field_index); 2038 } 2039 di_element_types[debug_field_index] = ZigLLVMCreateDebugMemberType(g->dbuilder, 2040 ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name), 2041 import->di_file, (unsigned)(field_node->line + 1), 2042 debug_size_in_bits, 2043 debug_align_in_bits, 2044 debug_offset_in_bits, 2045 0, field_di_type); 2046 assert(di_element_types[debug_field_index]); 2047 debug_field_index += 1; 2048 } 2049 2050 2051 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref); 2052 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, struct_type->type_ref); 2053 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 2054 ZigLLVMFileToScope(import->di_file), 2055 buf_ptr(&struct_type->name), 2056 import->di_file, (unsigned)(decl_node->line + 1), 2057 debug_size_in_bits, 2058 debug_align_in_bits, 2059 0, nullptr, di_element_types, (int)debug_field_count, 0, nullptr, ""); 2060 2061 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type); 2062 struct_type->di_type = replacement_di_type; 2063 } 2064 2065 static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) { 2066 assert(union_type->id == TypeTableEntryIdUnion); 2067 2068 if (union_type->data.unionation.complete) 2069 return; 2070 2071 resolve_union_zero_bits(g, union_type); 2072 if (type_is_invalid(union_type)) 2073 return; 2074 2075 AstNode *decl_node = union_type->data.unionation.decl_node; 2076 2077 if (union_type->data.unionation.embedded_in_current) { 2078 if (!union_type->data.unionation.reported_infinite_err) { 2079 union_type->data.unionation.reported_infinite_err = true; 2080 union_type->data.unionation.is_invalid = true; 2081 add_node_error(g, decl_node, buf_sprintf("union '%s' contains itself", buf_ptr(&union_type->name))); 2082 } 2083 return; 2084 } 2085 2086 assert(!union_type->data.unionation.zero_bits_loop_flag); 2087 assert(decl_node->type == NodeTypeContainerDecl); 2088 assert(union_type->di_type); 2089 2090 uint32_t field_count = union_type->data.unionation.src_field_count; 2091 2092 assert(union_type->data.unionation.fields); 2093 2094 uint32_t gen_field_count = union_type->data.unionation.gen_field_count; 2095 ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count); 2096 2097 TypeTableEntry *most_aligned_union_member = nullptr; 2098 uint64_t size_of_most_aligned_member_in_bits = 0; 2099 uint64_t biggest_align_in_bits = 0; 2100 uint64_t biggest_size_in_bits = 0; 2101 2102 Scope *scope = &union_type->data.unionation.decls_scope->base; 2103 ImportTableEntry *import = get_scope_import(scope); 2104 2105 // set temporary flag 2106 union_type->data.unionation.embedded_in_current = true; 2107 2108 2109 for (uint32_t i = 0; i < field_count; i += 1) { 2110 AstNode *field_node = decl_node->data.container_decl.fields.at(i); 2111 TypeUnionField *union_field = &union_type->data.unionation.fields[i]; 2112 TypeTableEntry *field_type = union_field->type_entry; 2113 2114 ensure_complete_type(g, field_type); 2115 if (type_is_invalid(field_type)) { 2116 union_type->data.unionation.is_invalid = true; 2117 continue; 2118 } 2119 2120 if (!type_has_bits(field_type)) 2121 continue; 2122 2123 uint64_t store_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref); 2124 uint64_t abi_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, field_type->type_ref); 2125 2126 assert(store_size_in_bits > 0); 2127 assert(abi_align_in_bits > 0); 2128 2129 union_inner_di_types[union_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder, 2130 ZigLLVMTypeToScope(union_type->di_type), buf_ptr(union_field->enum_field->name), 2131 import->di_file, (unsigned)(field_node->line + 1), 2132 store_size_in_bits, 2133 abi_align_in_bits, 2134 0, 2135 0, field_type->di_type); 2136 2137 biggest_size_in_bits = max(biggest_size_in_bits, store_size_in_bits); 2138 2139 if (!most_aligned_union_member || abi_align_in_bits > biggest_align_in_bits) { 2140 most_aligned_union_member = field_type; 2141 biggest_align_in_bits = abi_align_in_bits; 2142 size_of_most_aligned_member_in_bits = store_size_in_bits; 2143 } 2144 } 2145 2146 2147 // unset temporary flag 2148 union_type->data.unionation.embedded_in_current = false; 2149 union_type->data.unionation.complete = true; 2150 union_type->data.unionation.union_size_bytes = biggest_size_in_bits / 8; 2151 union_type->data.unionation.most_aligned_union_member = most_aligned_union_member; 2152 2153 if (union_type->data.unionation.is_invalid) 2154 return; 2155 2156 if (union_type->zero_bits) { 2157 union_type->type_ref = LLVMVoidType(); 2158 2159 uint64_t debug_size_in_bits = 0; 2160 uint64_t debug_align_in_bits = 0; 2161 ZigLLVMDIType **di_root_members = nullptr; 2162 size_t debug_member_count = 0; 2163 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, 2164 ZigLLVMFileToScope(import->di_file), 2165 buf_ptr(&union_type->name), 2166 import->di_file, (unsigned)(decl_node->line + 1), 2167 debug_size_in_bits, 2168 debug_align_in_bits, 2169 0, di_root_members, (int)debug_member_count, 0, ""); 2170 2171 ZigLLVMReplaceTemporary(g->dbuilder, union_type->di_type, replacement_di_type); 2172 union_type->di_type = replacement_di_type; 2173 return; 2174 } 2175 2176 uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits; 2177 2178 TypeTableEntry *tag_type = union_type->data.unionation.tag_type; 2179 if (tag_type == nullptr || tag_type->zero_bits) { 2180 assert(most_aligned_union_member != nullptr); 2181 2182 if (padding_in_bits > 0) { 2183 TypeTableEntry *u8_type = get_int_type(g, false, 8); 2184 TypeTableEntry *padding_array = get_array_type(g, u8_type, padding_in_bits / 8); 2185 LLVMTypeRef union_element_types[] = { 2186 most_aligned_union_member->type_ref, 2187 padding_array->type_ref, 2188 }; 2189 LLVMStructSetBody(union_type->type_ref, union_element_types, 2, false); 2190 } else { 2191 LLVMStructSetBody(union_type->type_ref, &most_aligned_union_member->type_ref, 1, false); 2192 } 2193 union_type->data.unionation.union_type_ref = union_type->type_ref; 2194 union_type->data.unionation.gen_tag_index = SIZE_MAX; 2195 union_type->data.unionation.gen_union_index = SIZE_MAX; 2196 2197 assert(8*LLVMABIAlignmentOfType(g->target_data_ref, union_type->type_ref) >= biggest_align_in_bits); 2198 assert(8*LLVMStoreSizeOfType(g->target_data_ref, union_type->type_ref) >= biggest_size_in_bits); 2199 2200 // create debug type for union 2201 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, 2202 ZigLLVMFileToScope(import->di_file), buf_ptr(&union_type->name), 2203 import->di_file, (unsigned)(decl_node->line + 1), 2204 biggest_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types, 2205 gen_field_count, 0, ""); 2206 2207 ZigLLVMReplaceTemporary(g->dbuilder, union_type->di_type, replacement_di_type); 2208 union_type->di_type = replacement_di_type; 2209 return; 2210 } 2211 2212 LLVMTypeRef union_type_ref; 2213 if (padding_in_bits > 0) { 2214 TypeTableEntry *u8_type = get_int_type(g, false, 8); 2215 TypeTableEntry *padding_array = get_array_type(g, u8_type, padding_in_bits / 8); 2216 LLVMTypeRef union_element_types[] = { 2217 most_aligned_union_member->type_ref, 2218 padding_array->type_ref, 2219 }; 2220 union_type_ref = LLVMStructType(union_element_types, 2, false); 2221 } else if (most_aligned_union_member == nullptr) { 2222 union_type->data.unionation.gen_tag_index = SIZE_MAX; 2223 union_type->data.unionation.gen_union_index = SIZE_MAX; 2224 union_type->type_ref = tag_type->type_ref; 2225 2226 ZigLLVMReplaceTemporary(g->dbuilder, union_type->di_type, tag_type->di_type); 2227 union_type->di_type = tag_type->di_type; 2228 return; 2229 } else { 2230 union_type_ref = most_aligned_union_member->type_ref; 2231 } 2232 union_type->data.unionation.union_type_ref = union_type_ref; 2233 2234 assert(8*LLVMABIAlignmentOfType(g->target_data_ref, union_type_ref) >= biggest_align_in_bits); 2235 assert(8*LLVMStoreSizeOfType(g->target_data_ref, union_type_ref) >= biggest_size_in_bits); 2236 2237 // create llvm type for root struct 2238 TypeTableEntry *tag_int_type = tag_type->data.enumeration.tag_int_type; 2239 uint64_t align_of_tag_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_int_type->type_ref); 2240 2241 if (align_of_tag_in_bits >= biggest_align_in_bits) { 2242 union_type->data.unionation.gen_tag_index = 0; 2243 union_type->data.unionation.gen_union_index = 1; 2244 } else { 2245 union_type->data.unionation.gen_union_index = 0; 2246 union_type->data.unionation.gen_tag_index = 1; 2247 } 2248 2249 LLVMTypeRef root_struct_element_types[2]; 2250 root_struct_element_types[union_type->data.unionation.gen_tag_index] = tag_type->type_ref; 2251 root_struct_element_types[union_type->data.unionation.gen_union_index] = union_type_ref; 2252 LLVMStructSetBody(union_type->type_ref, root_struct_element_types, 2, false); 2253 2254 2255 // create debug type for union 2256 ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, 2257 ZigLLVMTypeToScope(union_type->di_type), "AnonUnion", 2258 import->di_file, (unsigned)(decl_node->line + 1), 2259 biggest_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types, 2260 gen_field_count, 0, ""); 2261 2262 uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->type_ref, 2263 union_type->data.unionation.gen_union_index); 2264 uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, union_type->type_ref, 2265 union_type->data.unionation.gen_tag_index); 2266 2267 ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, 2268 ZigLLVMTypeToScope(union_type->di_type), "payload", 2269 import->di_file, (unsigned)(decl_node->line + 1), 2270 biggest_size_in_bits, 2271 biggest_align_in_bits, 2272 union_offset_in_bits, 2273 0, union_di_type); 2274 2275 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref); 2276 uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref); 2277 2278 ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, 2279 ZigLLVMTypeToScope(union_type->di_type), "tag", 2280 import->di_file, (unsigned)(decl_node->line + 1), 2281 tag_debug_size_in_bits, 2282 tag_debug_align_in_bits, 2283 tag_offset_in_bits, 2284 0, tag_type->di_type); 2285 2286 ZigLLVMDIType *di_root_members[2]; 2287 di_root_members[union_type->data.unionation.gen_tag_index] = tag_member_di_type; 2288 di_root_members[union_type->data.unionation.gen_union_index] = union_member_di_type; 2289 2290 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, union_type->type_ref); 2291 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, union_type->type_ref); 2292 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 2293 ZigLLVMFileToScope(import->di_file), 2294 buf_ptr(&union_type->name), 2295 import->di_file, (unsigned)(decl_node->line + 1), 2296 debug_size_in_bits, 2297 debug_align_in_bits, 2298 0, nullptr, di_root_members, 2, 0, nullptr, ""); 2299 2300 ZigLLVMReplaceTemporary(g->dbuilder, union_type->di_type, replacement_di_type); 2301 union_type->di_type = replacement_di_type; 2302 } 2303 2304 static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type) { 2305 assert(enum_type->id == TypeTableEntryIdEnum); 2306 2307 if (enum_type->data.enumeration.zero_bits_known) 2308 return; 2309 2310 if (enum_type->data.enumeration.zero_bits_loop_flag) { 2311 enum_type->data.enumeration.zero_bits_known = true; 2312 enum_type->data.enumeration.zero_bits_loop_flag = false; 2313 return; 2314 } 2315 2316 enum_type->data.enumeration.zero_bits_loop_flag = true; 2317 2318 AstNode *decl_node = enum_type->data.enumeration.decl_node; 2319 assert(decl_node->type == NodeTypeContainerDecl); 2320 assert(enum_type->di_type); 2321 2322 assert(!enum_type->data.enumeration.fields); 2323 uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length; 2324 if (field_count == 0) { 2325 add_node_error(g, decl_node, buf_sprintf("enums must have 1 or more fields")); 2326 2327 enum_type->data.enumeration.src_field_count = field_count; 2328 enum_type->data.enumeration.fields = nullptr; 2329 enum_type->data.enumeration.is_invalid = true; 2330 enum_type->data.enumeration.zero_bits_loop_flag = false; 2331 enum_type->data.enumeration.zero_bits_known = true; 2332 return; 2333 } 2334 2335 enum_type->data.enumeration.src_field_count = field_count; 2336 enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); 2337 enum_type->data.enumeration.fields_by_name.init(field_count); 2338 2339 Scope *scope = &enum_type->data.enumeration.decls_scope->base; 2340 2341 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {}; 2342 occupied_tag_values.init(field_count); 2343 2344 TypeTableEntry *tag_int_type; 2345 if (enum_type->data.enumeration.layout == ContainerLayoutExtern) { 2346 tag_int_type = get_c_int_type(g, CIntTypeInt); 2347 } else { 2348 tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1); 2349 } 2350 2351 // TODO: Are extern enums allowed to have an init_arg_expr? 2352 if (decl_node->data.container_decl.init_arg_expr != nullptr) { 2353 TypeTableEntry *wanted_tag_int_type = analyze_type_expr(g, scope, decl_node->data.container_decl.init_arg_expr); 2354 if (type_is_invalid(wanted_tag_int_type)) { 2355 enum_type->data.enumeration.is_invalid = true; 2356 } else if (wanted_tag_int_type->id != TypeTableEntryIdInt) { 2357 enum_type->data.enumeration.is_invalid = true; 2358 add_node_error(g, decl_node->data.container_decl.init_arg_expr, 2359 buf_sprintf("expected integer, found '%s'", buf_ptr(&wanted_tag_int_type->name))); 2360 } else if (wanted_tag_int_type->data.integral.is_signed) { 2361 enum_type->data.enumeration.is_invalid = true; 2362 add_node_error(g, decl_node->data.container_decl.init_arg_expr, 2363 buf_sprintf("expected unsigned integer, found '%s'", buf_ptr(&wanted_tag_int_type->name))); 2364 } else if (wanted_tag_int_type->data.integral.bit_count < tag_int_type->data.integral.bit_count) { 2365 enum_type->data.enumeration.is_invalid = true; 2366 add_node_error(g, decl_node->data.container_decl.init_arg_expr, 2367 buf_sprintf("'%s' too small to hold all bits; must be at least '%s'", 2368 buf_ptr(&wanted_tag_int_type->name), buf_ptr(&tag_int_type->name))); 2369 } else { 2370 tag_int_type = wanted_tag_int_type; 2371 } 2372 } 2373 enum_type->data.enumeration.tag_int_type = tag_int_type; 2374 enum_type->type_ref = tag_int_type->type_ref; 2375 2376 for (uint32_t field_i = 0; field_i < field_count; field_i += 1) { 2377 AstNode *field_node = decl_node->data.container_decl.fields.at(field_i); 2378 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i]; 2379 type_enum_field->name = field_node->data.struct_field.name; 2380 type_enum_field->decl_index = field_i; 2381 type_enum_field->decl_node = field_node; 2382 2383 if (field_node->data.struct_field.type != nullptr) { 2384 ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.type, 2385 buf_sprintf("structs and unions, not enums, support field types")); 2386 add_error_note(g, msg, decl_node, 2387 buf_sprintf("consider 'union(enum)' here")); 2388 } 2389 2390 auto field_entry = enum_type->data.enumeration.fields_by_name.put_unique(type_enum_field->name, type_enum_field); 2391 if (field_entry != nullptr) { 2392 ErrorMsg *msg = add_node_error(g, field_node, 2393 buf_sprintf("duplicate enum field: '%s'", buf_ptr(type_enum_field->name))); 2394 add_error_note(g, msg, field_entry->value->decl_node, buf_sprintf("other field here")); 2395 enum_type->data.enumeration.is_invalid = true; 2396 continue; 2397 } 2398 2399 AstNode *tag_value = field_node->data.struct_field.value; 2400 2401 // In this first pass we resolve explicit tag values. 2402 // In a second pass we will fill in the unspecified ones. 2403 if (tag_value != nullptr) { 2404 IrInstruction *result_inst = analyze_const_value(g, scope, tag_value, tag_int_type, nullptr); 2405 if (result_inst->value.type->id == TypeTableEntryIdInvalid) { 2406 enum_type->data.enumeration.is_invalid = true; 2407 continue; 2408 } 2409 assert(result_inst->value.special != ConstValSpecialRuntime); 2410 assert(result_inst->value.type->id == TypeTableEntryIdInt); 2411 auto entry = occupied_tag_values.put_unique(result_inst->value.data.x_bigint, tag_value); 2412 if (entry == nullptr) { 2413 bigint_init_bigint(&type_enum_field->value, &result_inst->value.data.x_bigint); 2414 } else { 2415 Buf *val_buf = buf_alloc(); 2416 bigint_append_buf(val_buf, &result_inst->value.data.x_bigint, 10); 2417 2418 ErrorMsg *msg = add_node_error(g, tag_value, 2419 buf_sprintf("enum tag value %s already taken", buf_ptr(val_buf))); 2420 add_error_note(g, msg, entry->value, 2421 buf_sprintf("other occurrence here")); 2422 enum_type->data.enumeration.is_invalid = true; 2423 continue; 2424 } 2425 } 2426 } 2427 2428 // Now iterate again and populate the unspecified tag values 2429 uint32_t next_maybe_unoccupied_index = 0; 2430 2431 for (uint32_t field_i = 0; field_i < field_count; field_i += 1) { 2432 AstNode *field_node = decl_node->data.container_decl.fields.at(field_i); 2433 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[field_i]; 2434 AstNode *tag_value = field_node->data.struct_field.value; 2435 2436 if (tag_value == nullptr) { 2437 if (occupied_tag_values.size() == 0) { 2438 bigint_init_unsigned(&type_enum_field->value, next_maybe_unoccupied_index); 2439 next_maybe_unoccupied_index += 1; 2440 } else { 2441 BigInt proposed_value; 2442 for (;;) { 2443 bigint_init_unsigned(&proposed_value, next_maybe_unoccupied_index); 2444 next_maybe_unoccupied_index += 1; 2445 auto entry = occupied_tag_values.put_unique(proposed_value, field_node); 2446 if (entry != nullptr) { 2447 continue; 2448 } 2449 break; 2450 } 2451 bigint_init_bigint(&type_enum_field->value, &proposed_value); 2452 } 2453 } 2454 } 2455 2456 enum_type->data.enumeration.zero_bits_loop_flag = false; 2457 enum_type->zero_bits = !type_has_bits(tag_int_type); 2458 enum_type->data.enumeration.zero_bits_known = true; 2459 } 2460 2461 static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) { 2462 assert(struct_type->id == TypeTableEntryIdStruct); 2463 2464 if (struct_type->data.structure.zero_bits_known) 2465 return; 2466 2467 if (struct_type->data.structure.zero_bits_loop_flag) { 2468 // If we get here it's due to recursion. This is a design flaw in the compiler, 2469 // we should be able to still figure out alignment, but here we give up and say that 2470 // the alignment is pointer width, then assert that the first field is within that 2471 // alignment 2472 struct_type->data.structure.zero_bits_known = true; 2473 struct_type->data.structure.zero_bits_loop_flag = false; 2474 if (struct_type->data.structure.abi_alignment == 0) { 2475 if (struct_type->data.structure.layout == ContainerLayoutPacked) { 2476 struct_type->data.structure.abi_alignment = 1; 2477 } else { 2478 struct_type->data.structure.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref, LLVMPointerType(LLVMInt8Type(), 0)); 2479 } 2480 } 2481 return; 2482 } 2483 2484 struct_type->data.structure.zero_bits_loop_flag = true; 2485 2486 AstNode *decl_node = struct_type->data.structure.decl_node; 2487 assert(decl_node->type == NodeTypeContainerDecl); 2488 assert(struct_type->di_type); 2489 2490 assert(!struct_type->data.structure.fields); 2491 size_t field_count = decl_node->data.container_decl.fields.length; 2492 struct_type->data.structure.src_field_count = (uint32_t)field_count; 2493 struct_type->data.structure.fields = allocate<TypeStructField>(field_count); 2494 struct_type->data.structure.fields_by_name.init(field_count); 2495 2496 Scope *scope = &struct_type->data.structure.decls_scope->base; 2497 2498 size_t gen_field_index = 0; 2499 for (size_t i = 0; i < field_count; i += 1) { 2500 AstNode *field_node = decl_node->data.container_decl.fields.at(i); 2501 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; 2502 type_struct_field->name = field_node->data.struct_field.name; 2503 type_struct_field->decl_node = field_node; 2504 2505 if (field_node->data.struct_field.type == nullptr) { 2506 add_node_error(g, field_node, buf_sprintf("struct field missing type")); 2507 struct_type->data.structure.is_invalid = true; 2508 continue; 2509 } 2510 2511 auto field_entry = struct_type->data.structure.fields_by_name.put_unique(type_struct_field->name, type_struct_field); 2512 if (field_entry != nullptr) { 2513 ErrorMsg *msg = add_node_error(g, field_node, 2514 buf_sprintf("duplicate struct field: '%s'", buf_ptr(type_struct_field->name))); 2515 add_error_note(g, msg, field_entry->value->decl_node, buf_sprintf("other field here")); 2516 struct_type->data.structure.is_invalid = true; 2517 continue; 2518 } 2519 2520 TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); 2521 type_struct_field->type_entry = field_type; 2522 type_struct_field->src_index = i; 2523 type_struct_field->gen_index = SIZE_MAX; 2524 2525 if (field_node->data.struct_field.value != nullptr) { 2526 add_node_error(g, field_node->data.struct_field.value, 2527 buf_sprintf("enums, not structs, support field assignment")); 2528 } 2529 2530 type_ensure_zero_bits_known(g, field_type); 2531 if (type_is_invalid(field_type)) { 2532 struct_type->data.structure.is_invalid = true; 2533 continue; 2534 } 2535 2536 if (type_requires_comptime(field_type)) { 2537 struct_type->data.structure.requires_comptime = true; 2538 } 2539 2540 if (!type_has_bits(field_type)) 2541 continue; 2542 2543 if (gen_field_index == 0) { 2544 if (struct_type->data.structure.layout == ContainerLayoutPacked) { 2545 struct_type->data.structure.abi_alignment = 1; 2546 } else if (struct_type->data.structure.abi_alignment == 0) { 2547 // Alignment of structs is the alignment of the first field, for now. 2548 // TODO change this when we re-order struct fields (issue #168) 2549 struct_type->data.structure.abi_alignment = get_abi_alignment(g, field_type); 2550 assert(struct_type->data.structure.abi_alignment != 0); 2551 } else { 2552 // due to a design flaw in the compiler we assumed that alignment was 2553 // pointer width, so we assert that this wasn't violated. 2554 if (get_abi_alignment(g, field_type) > struct_type->data.structure.abi_alignment) { 2555 zig_panic("compiler design flaw: incorrect alignment assumption"); 2556 } 2557 } 2558 } 2559 2560 type_struct_field->gen_index = gen_field_index; 2561 gen_field_index += 1; 2562 } 2563 2564 struct_type->data.structure.zero_bits_loop_flag = false; 2565 struct_type->data.structure.gen_field_count = (uint32_t)gen_field_index; 2566 struct_type->zero_bits = (gen_field_index == 0); 2567 struct_type->data.structure.zero_bits_known = true; 2568 } 2569 2570 static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) { 2571 assert(union_type->id == TypeTableEntryIdUnion); 2572 2573 if (union_type->data.unionation.zero_bits_known) 2574 return; 2575 2576 if (type_is_invalid(union_type)) 2577 return; 2578 2579 if (union_type->data.unionation.zero_bits_loop_flag) { 2580 // If we get here it's due to recursion. From this we conclude that the struct is 2581 // not zero bits, and if abi_alignment == 0 we further conclude that the first field 2582 // is a pointer to this very struct, or a function pointer with parameters that 2583 // reference such a type. 2584 union_type->data.unionation.zero_bits_known = true; 2585 union_type->data.unionation.zero_bits_loop_flag = false; 2586 if (union_type->data.unionation.abi_alignment == 0) { 2587 if (union_type->data.unionation.layout == ContainerLayoutPacked) { 2588 union_type->data.unionation.abi_alignment = 1; 2589 } else { 2590 union_type->data.unionation.abi_alignment = LLVMABIAlignmentOfType(g->target_data_ref, 2591 LLVMPointerType(LLVMInt8Type(), 0)); 2592 } 2593 } 2594 return; 2595 } 2596 2597 union_type->data.unionation.zero_bits_loop_flag = true; 2598 2599 AstNode *decl_node = union_type->data.unionation.decl_node; 2600 assert(decl_node->type == NodeTypeContainerDecl); 2601 assert(union_type->di_type); 2602 2603 assert(!union_type->data.unionation.fields); 2604 uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length; 2605 if (field_count == 0) { 2606 add_node_error(g, decl_node, buf_sprintf("unions must have 1 or more fields")); 2607 2608 union_type->data.unionation.src_field_count = field_count; 2609 union_type->data.unionation.fields = nullptr; 2610 union_type->data.unionation.is_invalid = true; 2611 union_type->data.unionation.zero_bits_loop_flag = false; 2612 union_type->data.unionation.zero_bits_known = true; 2613 return; 2614 } 2615 union_type->data.unionation.src_field_count = field_count; 2616 union_type->data.unionation.fields = allocate<TypeUnionField>(field_count); 2617 union_type->data.unionation.fields_by_name.init(field_count); 2618 2619 uint32_t biggest_align_bytes = 0; 2620 2621 Scope *scope = &union_type->data.unionation.decls_scope->base; 2622 2623 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> occupied_tag_values = {}; 2624 2625 AstNode *enum_type_node = decl_node->data.container_decl.init_arg_expr; 2626 union_type->data.unionation.have_explicit_tag_type = decl_node->data.container_decl.auto_enum || 2627 enum_type_node != nullptr; 2628 bool auto_layout = (union_type->data.unionation.layout == ContainerLayoutAuto); 2629 bool want_safety = (field_count >= 2) && (auto_layout || enum_type_node != nullptr); 2630 TypeTableEntry *tag_type; 2631 bool create_enum_type = decl_node->data.container_decl.auto_enum || (enum_type_node == nullptr && want_safety); 2632 bool *covered_enum_fields; 2633 ZigLLVMDIEnumerator **di_enumerators; 2634 uint32_t abi_alignment_so_far; 2635 if (create_enum_type) { 2636 occupied_tag_values.init(field_count); 2637 2638 di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count); 2639 2640 TypeTableEntry *tag_int_type; 2641 if (enum_type_node != nullptr) { 2642 tag_int_type = analyze_type_expr(g, scope, enum_type_node); 2643 if (type_is_invalid(tag_int_type)) { 2644 union_type->data.unionation.is_invalid = true; 2645 return; 2646 } 2647 if (tag_int_type->id != TypeTableEntryIdInt) { 2648 add_node_error(g, enum_type_node, 2649 buf_sprintf("expected integer tag type, found '%s'", buf_ptr(&tag_int_type->name))); 2650 union_type->data.unionation.is_invalid = true; 2651 return; 2652 } 2653 } else { 2654 tag_int_type = get_smallest_unsigned_int_type(g, field_count - 1); 2655 } 2656 abi_alignment_so_far = get_abi_alignment(g, tag_int_type); 2657 2658 tag_type = new_type_table_entry(TypeTableEntryIdEnum); 2659 buf_resize(&tag_type->name, 0); 2660 buf_appendf(&tag_type->name, "@TagType(%s)", buf_ptr(&union_type->name)); 2661 tag_type->is_copyable = true; 2662 tag_type->type_ref = tag_int_type->type_ref; 2663 tag_type->zero_bits = tag_int_type->zero_bits; 2664 2665 tag_type->data.enumeration.tag_int_type = tag_int_type; 2666 tag_type->data.enumeration.zero_bits_known = true; 2667 tag_type->data.enumeration.decl_node = decl_node; 2668 tag_type->data.enumeration.layout = ContainerLayoutAuto; 2669 tag_type->data.enumeration.src_field_count = field_count; 2670 tag_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); 2671 tag_type->data.enumeration.fields_by_name.init(field_count); 2672 tag_type->data.enumeration.decls_scope = union_type->data.unionation.decls_scope; 2673 tag_type->data.enumeration.complete = true; 2674 } else if (enum_type_node != nullptr) { 2675 TypeTableEntry *enum_type = analyze_type_expr(g, scope, enum_type_node); 2676 if (type_is_invalid(enum_type)) { 2677 union_type->data.unionation.is_invalid = true; 2678 return; 2679 } 2680 if (enum_type->id != TypeTableEntryIdEnum) { 2681 union_type->data.unionation.is_invalid = true; 2682 add_node_error(g, enum_type_node, 2683 buf_sprintf("expected enum tag type, found '%s'", buf_ptr(&enum_type->name))); 2684 return; 2685 } 2686 tag_type = enum_type; 2687 abi_alignment_so_far = get_abi_alignment(g, enum_type); // this populates src_field_count 2688 covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count); 2689 } else { 2690 tag_type = nullptr; 2691 abi_alignment_so_far = 0; 2692 } 2693 union_type->data.unionation.tag_type = tag_type; 2694 2695 uint32_t gen_field_index = 0; 2696 for (uint32_t i = 0; i < field_count; i += 1) { 2697 AstNode *field_node = decl_node->data.container_decl.fields.at(i); 2698 Buf *field_name = field_node->data.struct_field.name; 2699 TypeUnionField *union_field = &union_type->data.unionation.fields[i]; 2700 union_field->name = field_node->data.struct_field.name; 2701 union_field->decl_node = field_node; 2702 2703 auto field_entry = union_type->data.unionation.fields_by_name.put_unique(union_field->name, union_field); 2704 if (field_entry != nullptr) { 2705 ErrorMsg *msg = add_node_error(g, field_node, 2706 buf_sprintf("duplicate union field: '%s'", buf_ptr(union_field->name))); 2707 add_error_note(g, msg, field_entry->value->decl_node, buf_sprintf("other field here")); 2708 union_type->data.unionation.is_invalid = true; 2709 continue; 2710 } 2711 2712 TypeTableEntry *field_type; 2713 if (field_node->data.struct_field.type == nullptr) { 2714 if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) { 2715 field_type = g->builtin_types.entry_void; 2716 } else { 2717 add_node_error(g, field_node, buf_sprintf("union field missing type")); 2718 union_type->data.unionation.is_invalid = true; 2719 continue; 2720 } 2721 } else { 2722 field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); 2723 type_ensure_zero_bits_known(g, field_type); 2724 if (type_is_invalid(field_type)) { 2725 union_type->data.unionation.is_invalid = true; 2726 continue; 2727 } 2728 } 2729 union_field->type_entry = field_type; 2730 2731 if (type_requires_comptime(field_type)) { 2732 union_type->data.unionation.requires_comptime = true; 2733 } 2734 2735 2736 if (field_node->data.struct_field.value != nullptr && !decl_node->data.container_decl.auto_enum) { 2737 ErrorMsg *msg = add_node_error(g, field_node->data.struct_field.value, 2738 buf_sprintf("non-enum union field assignment")); 2739 add_error_note(g, msg, decl_node, 2740 buf_sprintf("consider 'union(enum)' here")); 2741 } 2742 2743 if (create_enum_type) { 2744 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(field_name), i); 2745 union_field->enum_field = &tag_type->data.enumeration.fields[i]; 2746 union_field->enum_field->name = field_name; 2747 union_field->enum_field->decl_index = i; 2748 union_field->enum_field->decl_node = field_node; 2749 2750 auto prev_entry = tag_type->data.enumeration.fields_by_name.put_unique(union_field->enum_field->name, union_field->enum_field); 2751 assert(prev_entry == nullptr); // caught by union de-duplicator above 2752 2753 AstNode *tag_value = field_node->data.struct_field.value; 2754 // In this first pass we resolve explicit tag values. 2755 // In a second pass we will fill in the unspecified ones. 2756 if (tag_value != nullptr) { 2757 TypeTableEntry *tag_int_type = tag_type->data.enumeration.tag_int_type; 2758 IrInstruction *result_inst = analyze_const_value(g, scope, tag_value, tag_int_type, nullptr); 2759 if (result_inst->value.type->id == TypeTableEntryIdInvalid) { 2760 union_type->data.unionation.is_invalid = true; 2761 continue; 2762 } 2763 assert(result_inst->value.special != ConstValSpecialRuntime); 2764 assert(result_inst->value.type->id == TypeTableEntryIdInt); 2765 auto entry = occupied_tag_values.put_unique(result_inst->value.data.x_bigint, tag_value); 2766 if (entry == nullptr) { 2767 bigint_init_bigint(&union_field->enum_field->value, &result_inst->value.data.x_bigint); 2768 } else { 2769 Buf *val_buf = buf_alloc(); 2770 bigint_append_buf(val_buf, &result_inst->value.data.x_bigint, 10); 2771 2772 ErrorMsg *msg = add_node_error(g, tag_value, 2773 buf_sprintf("enum tag value %s already taken", buf_ptr(val_buf))); 2774 add_error_note(g, msg, entry->value, 2775 buf_sprintf("other occurrence here")); 2776 union_type->data.unionation.is_invalid = true; 2777 continue; 2778 } 2779 } 2780 } else if (enum_type_node != nullptr) { 2781 union_field->enum_field = find_enum_type_field(tag_type, field_name); 2782 if (union_field->enum_field == nullptr) { 2783 ErrorMsg *msg = add_node_error(g, field_node, 2784 buf_sprintf("enum field not found: '%s'", buf_ptr(field_name))); 2785 add_error_note(g, msg, tag_type->data.enumeration.decl_node, 2786 buf_sprintf("enum declared here")); 2787 union_type->data.unionation.is_invalid = true; 2788 continue; 2789 } 2790 covered_enum_fields[union_field->enum_field->decl_index] = true; 2791 } else { 2792 union_field->enum_field = allocate<TypeEnumField>(1); 2793 union_field->enum_field->name = field_name; 2794 union_field->enum_field->decl_index = i; 2795 bigint_init_unsigned(&union_field->enum_field->value, i); 2796 } 2797 assert(union_field->enum_field != nullptr); 2798 2799 if (!type_has_bits(field_type)) 2800 continue; 2801 2802 union_field->gen_index = gen_field_index; 2803 gen_field_index += 1; 2804 2805 uint32_t field_align_bytes = get_abi_alignment(g, field_type); 2806 if (field_align_bytes > biggest_align_bytes) { 2807 biggest_align_bytes = field_align_bytes; 2808 if (biggest_align_bytes > abi_alignment_so_far) { 2809 abi_alignment_so_far = biggest_align_bytes; 2810 } 2811 } 2812 } 2813 2814 union_type->data.unionation.abi_alignment = abi_alignment_so_far; 2815 2816 if (union_type->data.unionation.is_invalid) 2817 return; 2818 2819 bool src_have_tag = decl_node->data.container_decl.auto_enum || 2820 decl_node->data.container_decl.init_arg_expr != nullptr; 2821 2822 if (src_have_tag && union_type->data.unionation.layout != ContainerLayoutAuto) { 2823 const char *qual_str; 2824 switch (union_type->data.unionation.layout) { 2825 case ContainerLayoutAuto: 2826 zig_unreachable(); 2827 case ContainerLayoutPacked: 2828 qual_str = "packed"; 2829 break; 2830 case ContainerLayoutExtern: 2831 qual_str = "extern"; 2832 break; 2833 } 2834 AstNode *source_node = (decl_node->data.container_decl.init_arg_expr != nullptr) ? 2835 decl_node->data.container_decl.init_arg_expr : decl_node; 2836 add_node_error(g, source_node, 2837 buf_sprintf("%s union does not support enum tag type", qual_str)); 2838 union_type->data.unionation.is_invalid = true; 2839 return; 2840 } 2841 2842 if (create_enum_type) { 2843 // Now iterate again and populate the unspecified tag values 2844 uint32_t next_maybe_unoccupied_index = 0; 2845 2846 for (uint32_t field_i = 0; field_i < field_count; field_i += 1) { 2847 AstNode *field_node = decl_node->data.container_decl.fields.at(field_i); 2848 TypeUnionField *union_field = &union_type->data.unionation.fields[field_i]; 2849 AstNode *tag_value = field_node->data.struct_field.value; 2850 2851 if (tag_value == nullptr) { 2852 if (occupied_tag_values.size() == 0) { 2853 bigint_init_unsigned(&union_field->enum_field->value, next_maybe_unoccupied_index); 2854 next_maybe_unoccupied_index += 1; 2855 } else { 2856 BigInt proposed_value; 2857 for (;;) { 2858 bigint_init_unsigned(&proposed_value, next_maybe_unoccupied_index); 2859 next_maybe_unoccupied_index += 1; 2860 auto entry = occupied_tag_values.put_unique(proposed_value, field_node); 2861 if (entry != nullptr) { 2862 continue; 2863 } 2864 break; 2865 } 2866 bigint_init_bigint(&union_field->enum_field->value, &proposed_value); 2867 } 2868 } 2869 } 2870 } else if (enum_type_node != nullptr) { 2871 for (uint32_t i = 0; i < tag_type->data.enumeration.src_field_count; i += 1) { 2872 TypeEnumField *enum_field = &tag_type->data.enumeration.fields[i]; 2873 if (!covered_enum_fields[i]) { 2874 AstNode *enum_decl_node = tag_type->data.enumeration.decl_node; 2875 AstNode *field_node = enum_decl_node->data.container_decl.fields.at(i); 2876 ErrorMsg *msg = add_node_error(g, decl_node, 2877 buf_sprintf("enum field missing: '%s'", buf_ptr(enum_field->name))); 2878 add_error_note(g, msg, field_node, 2879 buf_sprintf("declared here")); 2880 union_type->data.unionation.is_invalid = true; 2881 } 2882 } 2883 } 2884 2885 if (create_enum_type) { 2886 ImportTableEntry *import = get_scope_import(scope); 2887 uint64_t tag_debug_size_in_bits = tag_type->zero_bits ? 0 : 2888 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref); 2889 uint64_t tag_debug_align_in_bits = tag_type->zero_bits ? 0 : 2890 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref); 2891 // TODO get a more accurate debug scope 2892 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, 2893 ZigLLVMFileToScope(import->di_file), buf_ptr(&tag_type->name), 2894 import->di_file, (unsigned)(decl_node->line + 1), 2895 tag_debug_size_in_bits, tag_debug_align_in_bits, di_enumerators, field_count, 2896 tag_type->di_type, ""); 2897 tag_type->di_type = tag_di_type; 2898 } 2899 2900 union_type->data.unionation.zero_bits_loop_flag = false; 2901 union_type->data.unionation.gen_field_count = gen_field_index; 2902 union_type->zero_bits = (gen_field_index == 0 && (field_count < 2 || !src_have_tag)); 2903 union_type->data.unionation.zero_bits_known = true; 2904 } 2905 2906 static void get_fully_qualified_decl_name_internal(Buf *buf, Scope *scope, uint8_t sep) { 2907 if (!scope) 2908 return; 2909 2910 if (scope->id == ScopeIdDecls) { 2911 get_fully_qualified_decl_name_internal(buf, scope->parent, sep); 2912 2913 ScopeDecls *scope_decls = (ScopeDecls *)scope; 2914 if (scope_decls->container_type) { 2915 buf_append_buf(buf, &scope_decls->container_type->name); 2916 buf_append_char(buf, sep); 2917 } 2918 return; 2919 } 2920 2921 get_fully_qualified_decl_name_internal(buf, scope->parent, sep); 2922 } 2923 2924 static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) { 2925 buf_resize(buf, 0); 2926 get_fully_qualified_decl_name_internal(buf, tld->parent_scope, sep); 2927 buf_append_buf(buf, tld->name); 2928 } 2929 2930 FnTableEntry *create_fn_raw(FnInline inline_value) { 2931 FnTableEntry *fn_entry = allocate<FnTableEntry>(1); 2932 2933 fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc; 2934 fn_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota; 2935 fn_entry->analyzed_executable.fn_entry = fn_entry; 2936 fn_entry->ir_executable.fn_entry = fn_entry; 2937 fn_entry->fn_inline = inline_value; 2938 2939 return fn_entry; 2940 } 2941 2942 FnTableEntry *create_fn(AstNode *proto_node) { 2943 assert(proto_node->type == NodeTypeFnProto); 2944 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; 2945 2946 FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto; 2947 FnTableEntry *fn_entry = create_fn_raw(inline_value); 2948 2949 fn_entry->proto_node = proto_node; 2950 fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr : 2951 proto_node->data.fn_proto.fn_def_node->data.fn_def.body; 2952 2953 return fn_entry; 2954 } 2955 2956 static bool scope_is_root_decls(Scope *scope) { 2957 while (scope) { 2958 if (scope->id == ScopeIdDecls) { 2959 ScopeDecls *scope_decls = (ScopeDecls *)scope; 2960 return (scope_decls->container_type == nullptr); 2961 } 2962 scope = scope->parent; 2963 } 2964 zig_unreachable(); 2965 } 2966 2967 static void wrong_panic_prototype(CodeGen *g, AstNode *proto_node, TypeTableEntry *fn_type) { 2968 add_node_error(g, proto_node, 2969 buf_sprintf("expected 'fn([]const u8, ?&builtin.StackTrace) unreachable', found '%s'", 2970 buf_ptr(&fn_type->name))); 2971 } 2972 2973 static void typecheck_panic_fn(CodeGen *g, FnTableEntry *panic_fn) { 2974 AstNode *proto_node = panic_fn->proto_node; 2975 assert(proto_node->type == NodeTypeFnProto); 2976 TypeTableEntry *fn_type = panic_fn->type_entry; 2977 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 2978 if (fn_type_id->param_count != 2) { 2979 return wrong_panic_prototype(g, proto_node, fn_type); 2980 } 2981 TypeTableEntry *const_u8_ptr = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, 2982 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0); 2983 TypeTableEntry *const_u8_slice = get_slice_type(g, const_u8_ptr); 2984 if (fn_type_id->param_info[0].type != const_u8_slice) { 2985 return wrong_panic_prototype(g, proto_node, fn_type); 2986 } 2987 2988 TypeTableEntry *optional_ptr_to_stack_trace_type = get_maybe_type(g, get_ptr_to_stack_trace_type(g)); 2989 if (fn_type_id->param_info[1].type != optional_ptr_to_stack_trace_type) { 2990 return wrong_panic_prototype(g, proto_node, fn_type); 2991 } 2992 2993 TypeTableEntry *actual_return_type = fn_type_id->return_type; 2994 if (actual_return_type != g->builtin_types.entry_unreachable) { 2995 return wrong_panic_prototype(g, proto_node, fn_type); 2996 } 2997 } 2998 2999 TypeTableEntry *get_test_fn_type(CodeGen *g) { 3000 if (g->test_fn_type) 3001 return g->test_fn_type; 3002 3003 FnTypeId fn_type_id = {0}; 3004 fn_type_id.return_type = get_error_union_type(g, g->builtin_types.entry_global_error_set, 3005 g->builtin_types.entry_void); 3006 g->test_fn_type = get_fn_type(g, &fn_type_id); 3007 return g->test_fn_type; 3008 } 3009 3010 void add_fn_export(CodeGen *g, FnTableEntry *fn_table_entry, Buf *symbol_name, GlobalLinkageId linkage, bool ccc) { 3011 if (ccc) { 3012 if (buf_eql_str(symbol_name, "main") && g->libc_link_lib != nullptr) { 3013 g->have_c_main = true; 3014 g->windows_subsystem_windows = false; 3015 g->windows_subsystem_console = true; 3016 } else if (buf_eql_str(symbol_name, "WinMain") && 3017 g->zig_target.os == OsWindows) 3018 { 3019 g->have_winmain = true; 3020 g->windows_subsystem_windows = true; 3021 g->windows_subsystem_console = false; 3022 } else if (buf_eql_str(symbol_name, "WinMainCRTStartup") && 3023 g->zig_target.os == OsWindows) 3024 { 3025 g->have_winmain_crt_startup = true; 3026 } else if (buf_eql_str(symbol_name, "DllMainCRTStartup") && 3027 g->zig_target.os == OsWindows) 3028 { 3029 g->have_dllmain_crt_startup = true; 3030 } 3031 } 3032 FnExport *fn_export = fn_table_entry->export_list.add_one(); 3033 memset(fn_export, 0, sizeof(FnExport)); 3034 buf_init_from_buf(&fn_export->name, symbol_name); 3035 fn_export->linkage = linkage; 3036 } 3037 3038 static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { 3039 ImportTableEntry *import = tld_fn->base.import; 3040 AstNode *source_node = tld_fn->base.source_node; 3041 if (source_node->type == NodeTypeFnProto) { 3042 AstNodeFnProto *fn_proto = &source_node->data.fn_proto; 3043 3044 AstNode *fn_def_node = fn_proto->fn_def_node; 3045 3046 FnTableEntry *fn_table_entry = create_fn(source_node); 3047 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); 3048 3049 if (fn_proto->is_export) { 3050 bool ccc = (fn_proto->cc == CallingConventionUnspecified || fn_proto->cc == CallingConventionC); 3051 add_fn_export(g, fn_table_entry, &fn_table_entry->symbol_name, GlobalLinkageIdStrong, ccc); 3052 } 3053 3054 tld_fn->fn_entry = fn_table_entry; 3055 3056 if (fn_table_entry->body_node) { 3057 fn_table_entry->fndef_scope = create_fndef_scope( 3058 fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry); 3059 3060 for (size_t i = 0; i < fn_proto->params.length; i += 1) { 3061 AstNode *param_node = fn_proto->params.at(i); 3062 assert(param_node->type == NodeTypeParamDecl); 3063 if (param_node->data.param_decl.name == nullptr) { 3064 add_node_error(g, param_node, buf_sprintf("missing parameter name")); 3065 } 3066 } 3067 } else { 3068 g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base); 3069 } 3070 3071 Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope; 3072 3073 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry); 3074 3075 if (fn_proto->section_expr != nullptr) { 3076 if (fn_table_entry->body_node == nullptr) { 3077 add_node_error(g, fn_proto->section_expr, 3078 buf_sprintf("cannot set section of external function '%s'", buf_ptr(&fn_table_entry->symbol_name))); 3079 } else { 3080 analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name); 3081 } 3082 } 3083 3084 if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) { 3085 tld_fn->base.resolution = TldResolutionInvalid; 3086 return; 3087 } 3088 3089 if (!fn_table_entry->type_entry->data.fn.is_generic) { 3090 if (fn_def_node) 3091 g->fn_defs.append(fn_table_entry); 3092 3093 if (scope_is_root_decls(tld_fn->base.parent_scope) && 3094 (import == g->root_import || import->package == g->panic_package)) 3095 { 3096 if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) { 3097 g->main_fn = fn_table_entry; 3098 } else if ((import->package == g->panic_package || g->have_pub_panic) && 3099 buf_eql_str(&fn_table_entry->symbol_name, "panic")) 3100 { 3101 g->panic_fn = fn_table_entry; 3102 typecheck_panic_fn(g, fn_table_entry); 3103 } 3104 } 3105 } 3106 } else if (source_node->type == NodeTypeTestDecl) { 3107 FnTableEntry *fn_table_entry = create_fn_raw(FnInlineAuto); 3108 3109 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); 3110 3111 tld_fn->fn_entry = fn_table_entry; 3112 3113 fn_table_entry->proto_node = source_node; 3114 fn_table_entry->fndef_scope = create_fndef_scope(source_node, tld_fn->base.parent_scope, fn_table_entry); 3115 fn_table_entry->type_entry = get_test_fn_type(g); 3116 fn_table_entry->body_node = source_node->data.test_decl.body; 3117 fn_table_entry->is_test = true; 3118 3119 g->fn_defs.append(fn_table_entry); 3120 g->test_fns.append(fn_table_entry); 3121 3122 } else { 3123 zig_unreachable(); 3124 } 3125 } 3126 3127 static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) { 3128 assert(tld_comptime->base.source_node->type == NodeTypeCompTime); 3129 AstNode *expr_node = tld_comptime->base.source_node->data.comptime_expr.expr; 3130 analyze_const_value(g, tld_comptime->base.parent_scope, expr_node, g->builtin_types.entry_void, nullptr); 3131 } 3132 3133 static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { 3134 bool is_export = false; 3135 if (tld->id == TldIdVar) { 3136 assert(tld->source_node->type == NodeTypeVariableDeclaration); 3137 is_export = tld->source_node->data.variable_declaration.is_export; 3138 } else if (tld->id == TldIdFn) { 3139 assert(tld->source_node->type == NodeTypeFnProto); 3140 is_export = tld->source_node->data.fn_proto.is_export; 3141 } 3142 if (is_export) { 3143 g->resolve_queue.append(tld); 3144 3145 auto entry = g->exported_symbol_names.put_unique(tld->name, tld->source_node); 3146 if (entry) { 3147 AstNode *other_source_node = entry->value; 3148 ErrorMsg *msg = add_node_error(g, tld->source_node, 3149 buf_sprintf("exported symbol collision: '%s'", buf_ptr(tld->name))); 3150 add_error_note(g, msg, other_source_node, buf_sprintf("other symbol here")); 3151 } 3152 } 3153 3154 { 3155 auto entry = decls_scope->decl_table.put_unique(tld->name, tld); 3156 if (entry) { 3157 Tld *other_tld = entry->value; 3158 ErrorMsg *msg = add_node_error(g, tld->source_node, buf_sprintf("redefinition of '%s'", buf_ptr(tld->name))); 3159 add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition is here")); 3160 return; 3161 } 3162 } 3163 3164 { 3165 auto entry = g->primitive_type_table.maybe_get(tld->name); 3166 if (entry) { 3167 TypeTableEntry *type = entry->value; 3168 add_node_error(g, tld->source_node, 3169 buf_sprintf("declaration shadows type '%s'", buf_ptr(&type->name))); 3170 } 3171 } 3172 } 3173 3174 static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) { 3175 assert(node->type == NodeTypeTestDecl); 3176 3177 if (!g->is_test_build) 3178 return; 3179 3180 ImportTableEntry *import = get_scope_import(&decls_scope->base); 3181 if (import->package != g->root_package) 3182 return; 3183 3184 Buf *decl_name_buf = node->data.test_decl.name; 3185 3186 Buf *test_name = g->test_name_prefix ? 3187 buf_sprintf("%s%s", buf_ptr(g->test_name_prefix), buf_ptr(decl_name_buf)) : decl_name_buf; 3188 3189 if (g->test_filter != nullptr && strstr(buf_ptr(test_name), buf_ptr(g->test_filter)) == nullptr) { 3190 return; 3191 } 3192 3193 TldFn *tld_fn = allocate<TldFn>(1); 3194 init_tld(&tld_fn->base, TldIdFn, test_name, VisibModPrivate, node, &decls_scope->base); 3195 g->resolve_queue.append(&tld_fn->base); 3196 } 3197 3198 static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) { 3199 assert(node->type == NodeTypeCompTime); 3200 3201 TldCompTime *tld_comptime = allocate<TldCompTime>(1); 3202 init_tld(&tld_comptime->base, TldIdCompTime, nullptr, VisibModPrivate, node, &decls_scope->base); 3203 g->resolve_queue.append(&tld_comptime->base); 3204 } 3205 3206 void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node, 3207 Scope *parent_scope) 3208 { 3209 tld->id = id; 3210 tld->name = name; 3211 tld->visib_mod = visib_mod; 3212 tld->source_node = source_node; 3213 tld->import = source_node ? source_node->owner : nullptr; 3214 tld->parent_scope = parent_scope; 3215 } 3216 3217 void update_compile_var(CodeGen *g, Buf *name, ConstExprValue *value) { 3218 Tld *tld = g->compile_var_import->decls_scope->decl_table.get(name); 3219 resolve_top_level_decl(g, tld, false, tld->source_node); 3220 assert(tld->id == TldIdVar); 3221 TldVar *tld_var = (TldVar *)tld; 3222 tld_var->var->value = value; 3223 tld_var->var->align_bytes = get_abi_alignment(g, value->type); 3224 } 3225 3226 void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { 3227 switch (node->type) { 3228 case NodeTypeRoot: 3229 for (size_t i = 0; i < node->data.root.top_level_decls.length; i += 1) { 3230 AstNode *child = node->data.root.top_level_decls.at(i); 3231 scan_decls(g, decls_scope, child); 3232 } 3233 break; 3234 case NodeTypeFnDef: 3235 scan_decls(g, decls_scope, node->data.fn_def.fn_proto); 3236 break; 3237 case NodeTypeVariableDeclaration: 3238 { 3239 Buf *name = node->data.variable_declaration.symbol; 3240 VisibMod visib_mod = node->data.variable_declaration.visib_mod; 3241 TldVar *tld_var = allocate<TldVar>(1); 3242 init_tld(&tld_var->base, TldIdVar, name, visib_mod, node, &decls_scope->base); 3243 tld_var->extern_lib_name = node->data.variable_declaration.lib_name; 3244 add_top_level_decl(g, decls_scope, &tld_var->base); 3245 break; 3246 } 3247 case NodeTypeFnProto: 3248 { 3249 // if the name is missing, we immediately announce an error 3250 Buf *fn_name = node->data.fn_proto.name; 3251 if (fn_name == nullptr) { 3252 add_node_error(g, node, buf_sprintf("missing function name")); 3253 break; 3254 } 3255 3256 VisibMod visib_mod = node->data.fn_proto.visib_mod; 3257 TldFn *tld_fn = allocate<TldFn>(1); 3258 init_tld(&tld_fn->base, TldIdFn, fn_name, visib_mod, node, &decls_scope->base); 3259 tld_fn->extern_lib_name = node->data.fn_proto.lib_name; 3260 add_top_level_decl(g, decls_scope, &tld_fn->base); 3261 3262 break; 3263 } 3264 case NodeTypeUse: 3265 { 3266 g->use_queue.append(node); 3267 ImportTableEntry *import = get_scope_import(&decls_scope->base); 3268 import->use_decls.append(node); 3269 break; 3270 } 3271 case NodeTypeTestDecl: 3272 preview_test_decl(g, node, decls_scope); 3273 break; 3274 case NodeTypeCompTime: 3275 preview_comptime_decl(g, node, decls_scope); 3276 break; 3277 case NodeTypeContainerDecl: 3278 case NodeTypeParamDecl: 3279 case NodeTypeReturnExpr: 3280 case NodeTypeDefer: 3281 case NodeTypeBlock: 3282 case NodeTypeGroupedExpr: 3283 case NodeTypeBinOpExpr: 3284 case NodeTypeUnwrapErrorExpr: 3285 case NodeTypeFnCallExpr: 3286 case NodeTypeArrayAccessExpr: 3287 case NodeTypeSliceExpr: 3288 case NodeTypeFloatLiteral: 3289 case NodeTypeIntLiteral: 3290 case NodeTypeStringLiteral: 3291 case NodeTypeCharLiteral: 3292 case NodeTypeBoolLiteral: 3293 case NodeTypeNullLiteral: 3294 case NodeTypeUndefinedLiteral: 3295 case NodeTypeThisLiteral: 3296 case NodeTypeSymbol: 3297 case NodeTypePrefixOpExpr: 3298 case NodeTypePointerType: 3299 case NodeTypeIfBoolExpr: 3300 case NodeTypeWhileExpr: 3301 case NodeTypeForExpr: 3302 case NodeTypeSwitchExpr: 3303 case NodeTypeSwitchProng: 3304 case NodeTypeSwitchRange: 3305 case NodeTypeBreak: 3306 case NodeTypeContinue: 3307 case NodeTypeUnreachable: 3308 case NodeTypeAsmExpr: 3309 case NodeTypeFieldAccessExpr: 3310 case NodeTypePtrDeref: 3311 case NodeTypeUnwrapOptional: 3312 case NodeTypeStructField: 3313 case NodeTypeContainerInitExpr: 3314 case NodeTypeStructValueField: 3315 case NodeTypeArrayType: 3316 case NodeTypeErrorType: 3317 case NodeTypeIfErrorExpr: 3318 case NodeTypeTestExpr: 3319 case NodeTypeErrorSetDecl: 3320 case NodeTypeCancel: 3321 case NodeTypeResume: 3322 case NodeTypeAwaitExpr: 3323 case NodeTypeSuspend: 3324 case NodeTypePromiseType: 3325 zig_unreachable(); 3326 } 3327 } 3328 3329 static void resolve_decl_container(CodeGen *g, TldContainer *tld_container) { 3330 TypeTableEntry *type_entry = tld_container->type_entry; 3331 assert(type_entry); 3332 3333 switch (type_entry->id) { 3334 case TypeTableEntryIdStruct: 3335 resolve_struct_type(g, tld_container->type_entry); 3336 return; 3337 case TypeTableEntryIdEnum: 3338 resolve_enum_type(g, tld_container->type_entry); 3339 return; 3340 case TypeTableEntryIdUnion: 3341 resolve_union_type(g, tld_container->type_entry); 3342 return; 3343 default: 3344 zig_unreachable(); 3345 } 3346 } 3347 3348 TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry) { 3349 switch (type_entry->id) { 3350 case TypeTableEntryIdInvalid: 3351 return g->builtin_types.entry_invalid; 3352 case TypeTableEntryIdUnreachable: 3353 case TypeTableEntryIdUndefined: 3354 case TypeTableEntryIdNull: 3355 case TypeTableEntryIdBlock: 3356 case TypeTableEntryIdArgTuple: 3357 case TypeTableEntryIdOpaque: 3358 add_node_error(g, source_node, buf_sprintf("variable of type '%s' not allowed", 3359 buf_ptr(&type_entry->name))); 3360 return g->builtin_types.entry_invalid; 3361 case TypeTableEntryIdComptimeFloat: 3362 case TypeTableEntryIdComptimeInt: 3363 case TypeTableEntryIdNamespace: 3364 case TypeTableEntryIdMetaType: 3365 case TypeTableEntryIdVoid: 3366 case TypeTableEntryIdBool: 3367 case TypeTableEntryIdInt: 3368 case TypeTableEntryIdFloat: 3369 case TypeTableEntryIdPointer: 3370 case TypeTableEntryIdArray: 3371 case TypeTableEntryIdStruct: 3372 case TypeTableEntryIdOptional: 3373 case TypeTableEntryIdErrorUnion: 3374 case TypeTableEntryIdErrorSet: 3375 case TypeTableEntryIdEnum: 3376 case TypeTableEntryIdUnion: 3377 case TypeTableEntryIdFn: 3378 case TypeTableEntryIdBoundFn: 3379 case TypeTableEntryIdPromise: 3380 return type_entry; 3381 } 3382 zig_unreachable(); 3383 } 3384 3385 // Set name to nullptr to make the variable anonymous (not visible to programmer). 3386 // TODO merge with definition of add_local_var in ir.cpp 3387 VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name, 3388 bool is_const, ConstExprValue *value, Tld *src_tld) 3389 { 3390 assert(value); 3391 3392 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); 3393 variable_entry->value = value; 3394 variable_entry->parent_scope = parent_scope; 3395 variable_entry->shadowable = false; 3396 variable_entry->mem_slot_index = SIZE_MAX; 3397 variable_entry->src_arg_index = SIZE_MAX; 3398 variable_entry->align_bytes = get_abi_alignment(g, value->type); 3399 3400 assert(name); 3401 3402 buf_init_from_buf(&variable_entry->name, name); 3403 3404 if (value->type->id != TypeTableEntryIdInvalid) { 3405 VariableTableEntry *existing_var = find_variable(g, parent_scope, name); 3406 if (existing_var && !existing_var->shadowable) { 3407 ErrorMsg *msg = add_node_error(g, source_node, 3408 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); 3409 add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); 3410 variable_entry->value->type = g->builtin_types.entry_invalid; 3411 } else { 3412 auto primitive_table_entry = g->primitive_type_table.maybe_get(name); 3413 if (primitive_table_entry) { 3414 TypeTableEntry *type = primitive_table_entry->value; 3415 add_node_error(g, source_node, 3416 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); 3417 variable_entry->value->type = g->builtin_types.entry_invalid; 3418 } else { 3419 Scope *search_scope = nullptr; 3420 if (src_tld == nullptr) { 3421 search_scope = parent_scope; 3422 } else if (src_tld->parent_scope != nullptr && src_tld->parent_scope->parent != nullptr) { 3423 search_scope = src_tld->parent_scope->parent; 3424 } 3425 if (search_scope != nullptr) { 3426 Tld *tld = find_decl(g, search_scope, name); 3427 if (tld != nullptr) { 3428 ErrorMsg *msg = add_node_error(g, source_node, 3429 buf_sprintf("redefinition of '%s'", buf_ptr(name))); 3430 add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here")); 3431 variable_entry->value->type = g->builtin_types.entry_invalid; 3432 } 3433 } 3434 } 3435 } 3436 } 3437 3438 Scope *child_scope; 3439 if (source_node && source_node->type == NodeTypeParamDecl) { 3440 child_scope = create_var_scope(source_node, parent_scope, variable_entry); 3441 } else { 3442 // it's already in the decls table 3443 child_scope = parent_scope; 3444 } 3445 3446 3447 variable_entry->src_is_const = is_const; 3448 variable_entry->gen_is_const = is_const; 3449 variable_entry->decl_node = source_node; 3450 variable_entry->child_scope = child_scope; 3451 3452 3453 return variable_entry; 3454 } 3455 3456 static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { 3457 AstNode *source_node = tld_var->base.source_node; 3458 AstNodeVariableDeclaration *var_decl = &source_node->data.variable_declaration; 3459 3460 bool is_const = var_decl->is_const; 3461 bool is_extern = var_decl->is_extern; 3462 bool is_export = var_decl->is_export; 3463 3464 TypeTableEntry *explicit_type = nullptr; 3465 if (var_decl->type) { 3466 TypeTableEntry *proposed_type = analyze_type_expr(g, tld_var->base.parent_scope, var_decl->type); 3467 explicit_type = validate_var_type(g, var_decl->type, proposed_type); 3468 } 3469 3470 assert(!is_export || !is_extern); 3471 3472 VarLinkage linkage; 3473 if (is_export) { 3474 linkage = VarLinkageExport; 3475 } else if (is_extern) { 3476 linkage = VarLinkageExternal; 3477 } else { 3478 linkage = VarLinkageInternal; 3479 } 3480 3481 IrInstruction *init_value = nullptr; 3482 3483 // TODO more validation for types that can't be used for export/extern variables 3484 TypeTableEntry *implicit_type = nullptr; 3485 if (explicit_type && explicit_type->id == TypeTableEntryIdInvalid) { 3486 implicit_type = explicit_type; 3487 } else if (var_decl->expr) { 3488 init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type, var_decl->symbol); 3489 assert(init_value); 3490 implicit_type = init_value->value.type; 3491 3492 if (implicit_type->id == TypeTableEntryIdUnreachable) { 3493 add_node_error(g, source_node, buf_sprintf("variable initialization is unreachable")); 3494 implicit_type = g->builtin_types.entry_invalid; 3495 } else if ((!is_const || linkage == VarLinkageExternal) && 3496 (implicit_type->id == TypeTableEntryIdComptimeFloat || 3497 implicit_type->id == TypeTableEntryIdComptimeInt)) 3498 { 3499 add_node_error(g, source_node, buf_sprintf("unable to infer variable type")); 3500 implicit_type = g->builtin_types.entry_invalid; 3501 } else if (implicit_type->id == TypeTableEntryIdNull) { 3502 add_node_error(g, source_node, buf_sprintf("unable to infer variable type")); 3503 implicit_type = g->builtin_types.entry_invalid; 3504 } else if (implicit_type->id == TypeTableEntryIdMetaType && !is_const) { 3505 add_node_error(g, source_node, buf_sprintf("variable of type 'type' must be constant")); 3506 implicit_type = g->builtin_types.entry_invalid; 3507 } 3508 assert(implicit_type->id == TypeTableEntryIdInvalid || init_value->value.special != ConstValSpecialRuntime); 3509 } else if (linkage != VarLinkageExternal) { 3510 add_node_error(g, source_node, buf_sprintf("variables must be initialized")); 3511 implicit_type = g->builtin_types.entry_invalid; 3512 } 3513 3514 TypeTableEntry *type = explicit_type ? explicit_type : implicit_type; 3515 assert(type != nullptr); // should have been caught by the parser 3516 3517 ConstExprValue *init_val = init_value ? &init_value->value : create_const_runtime(type); 3518 3519 tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, var_decl->symbol, 3520 is_const, init_val, &tld_var->base); 3521 tld_var->var->linkage = linkage; 3522 3523 if (implicit_type != nullptr && type_is_invalid(implicit_type)) { 3524 tld_var->var->value->type = g->builtin_types.entry_invalid; 3525 } 3526 3527 if (var_decl->align_expr != nullptr) { 3528 if (!analyze_const_align(g, tld_var->base.parent_scope, var_decl->align_expr, &tld_var->var->align_bytes)) { 3529 tld_var->var->value->type = g->builtin_types.entry_invalid; 3530 } 3531 } 3532 3533 if (var_decl->section_expr != nullptr) { 3534 if (var_decl->is_extern) { 3535 add_node_error(g, var_decl->section_expr, 3536 buf_sprintf("cannot set section of external variable '%s'", buf_ptr(var_decl->symbol))); 3537 } else if (!analyze_const_string(g, tld_var->base.parent_scope, var_decl->section_expr, &tld_var->section_name)) { 3538 tld_var->section_name = nullptr; 3539 } 3540 } 3541 3542 g->global_vars.append(tld_var); 3543 } 3544 3545 void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *source_node) { 3546 if (tld->resolution != TldResolutionUnresolved) 3547 return; 3548 3549 if (tld->dep_loop_flag) { 3550 add_node_error(g, tld->source_node, buf_sprintf("'%s' depends on itself", buf_ptr(tld->name))); 3551 tld->resolution = TldResolutionInvalid; 3552 return; 3553 } 3554 3555 tld->dep_loop_flag = true; 3556 g->tld_ref_source_node_stack.append(source_node); 3557 3558 switch (tld->id) { 3559 case TldIdVar: 3560 { 3561 TldVar *tld_var = (TldVar *)tld; 3562 resolve_decl_var(g, tld_var); 3563 break; 3564 } 3565 case TldIdFn: 3566 { 3567 TldFn *tld_fn = (TldFn *)tld; 3568 resolve_decl_fn(g, tld_fn); 3569 break; 3570 } 3571 case TldIdContainer: 3572 { 3573 TldContainer *tld_container = (TldContainer *)tld; 3574 resolve_decl_container(g, tld_container); 3575 break; 3576 } 3577 case TldIdCompTime: 3578 { 3579 TldCompTime *tld_comptime = (TldCompTime *)tld; 3580 resolve_decl_comptime(g, tld_comptime); 3581 break; 3582 } 3583 } 3584 3585 tld->resolution = TldResolutionOk; 3586 tld->dep_loop_flag = false; 3587 g->tld_ref_source_node_stack.pop(); 3588 } 3589 3590 Tld *find_decl(CodeGen *g, Scope *scope, Buf *name) { 3591 // we must resolve all the use decls 3592 ImportTableEntry *import = get_scope_import(scope); 3593 for (size_t i = 0; i < import->use_decls.length; i += 1) { 3594 AstNode *use_decl_node = import->use_decls.at(i); 3595 if (use_decl_node->data.use.resolution == TldResolutionUnresolved) { 3596 preview_use_decl(g, use_decl_node); 3597 resolve_use_decl(g, use_decl_node); 3598 } 3599 } 3600 3601 while (scope) { 3602 if (scope->id == ScopeIdDecls) { 3603 ScopeDecls *decls_scope = (ScopeDecls *)scope; 3604 auto entry = decls_scope->decl_table.maybe_get(name); 3605 if (entry) 3606 return entry->value; 3607 } 3608 scope = scope->parent; 3609 } 3610 return nullptr; 3611 } 3612 3613 VariableTableEntry *find_variable(CodeGen *g, Scope *scope, Buf *name) { 3614 while (scope) { 3615 if (scope->id == ScopeIdVarDecl) { 3616 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope; 3617 if (buf_eql_buf(name, &var_scope->var->name)) 3618 return var_scope->var; 3619 } else if (scope->id == ScopeIdDecls) { 3620 ScopeDecls *decls_scope = (ScopeDecls *)scope; 3621 auto entry = decls_scope->decl_table.maybe_get(name); 3622 if (entry) { 3623 Tld *tld = entry->value; 3624 if (tld->id == TldIdVar) { 3625 TldVar *tld_var = (TldVar *)tld; 3626 if (tld_var->var) 3627 return tld_var->var; 3628 } 3629 } 3630 } 3631 scope = scope->parent; 3632 } 3633 3634 return nullptr; 3635 } 3636 3637 FnTableEntry *scope_fn_entry(Scope *scope) { 3638 while (scope) { 3639 if (scope->id == ScopeIdFnDef) { 3640 ScopeFnDef *fn_scope = (ScopeFnDef *)scope; 3641 return fn_scope->fn_entry; 3642 } 3643 scope = scope->parent; 3644 } 3645 return nullptr; 3646 } 3647 3648 FnTableEntry *scope_get_fn_if_root(Scope *scope) { 3649 assert(scope); 3650 scope = scope->parent; 3651 while (scope) { 3652 switch (scope->id) { 3653 case ScopeIdBlock: 3654 return nullptr; 3655 case ScopeIdDecls: 3656 case ScopeIdDefer: 3657 case ScopeIdDeferExpr: 3658 case ScopeIdVarDecl: 3659 case ScopeIdCImport: 3660 case ScopeIdLoop: 3661 case ScopeIdSuspend: 3662 case ScopeIdCompTime: 3663 case ScopeIdCoroPrelude: 3664 scope = scope->parent; 3665 continue; 3666 case ScopeIdFnDef: 3667 ScopeFnDef *fn_scope = (ScopeFnDef *)scope; 3668 return fn_scope->fn_entry; 3669 } 3670 zig_unreachable(); 3671 } 3672 return nullptr; 3673 } 3674 3675 TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name) { 3676 assert(enum_type->id == TypeTableEntryIdEnum); 3677 if (enum_type->data.enumeration.src_field_count == 0) 3678 return nullptr; 3679 auto entry = enum_type->data.enumeration.fields_by_name.maybe_get(name); 3680 if (entry == nullptr) 3681 return nullptr; 3682 return entry->value; 3683 } 3684 3685 TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name) { 3686 assert(type_entry->id == TypeTableEntryIdStruct); 3687 assert(type_entry->data.structure.complete); 3688 if (type_entry->data.structure.src_field_count == 0) 3689 return nullptr; 3690 auto entry = type_entry->data.structure.fields_by_name.maybe_get(name); 3691 if (entry == nullptr) 3692 return nullptr; 3693 return entry->value; 3694 } 3695 3696 TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name) { 3697 assert(type_entry->id == TypeTableEntryIdUnion); 3698 assert(type_entry->data.unionation.zero_bits_known); 3699 if (type_entry->data.unionation.src_field_count == 0) 3700 return nullptr; 3701 auto entry = type_entry->data.unionation.fields_by_name.maybe_get(name); 3702 if (entry == nullptr) 3703 return nullptr; 3704 return entry->value; 3705 } 3706 3707 TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag) { 3708 assert(type_entry->id == TypeTableEntryIdUnion); 3709 assert(type_entry->data.unionation.zero_bits_known); 3710 for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) { 3711 TypeUnionField *field = &type_entry->data.unionation.fields[i]; 3712 if (bigint_cmp(&field->enum_field->value, tag) == CmpEQ) { 3713 return field; 3714 } 3715 } 3716 return nullptr; 3717 } 3718 3719 TypeEnumField *find_enum_field_by_tag(TypeTableEntry *enum_type, const BigInt *tag) { 3720 for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) { 3721 TypeEnumField *field = &enum_type->data.enumeration.fields[i]; 3722 if (bigint_cmp(&field->value, tag) == CmpEQ) { 3723 return field; 3724 } 3725 } 3726 return nullptr; 3727 } 3728 3729 3730 static bool is_container(TypeTableEntry *type_entry) { 3731 switch (type_entry->id) { 3732 case TypeTableEntryIdInvalid: 3733 zig_unreachable(); 3734 case TypeTableEntryIdStruct: 3735 case TypeTableEntryIdEnum: 3736 case TypeTableEntryIdUnion: 3737 return true; 3738 case TypeTableEntryIdPointer: 3739 case TypeTableEntryIdMetaType: 3740 case TypeTableEntryIdVoid: 3741 case TypeTableEntryIdBool: 3742 case TypeTableEntryIdUnreachable: 3743 case TypeTableEntryIdInt: 3744 case TypeTableEntryIdFloat: 3745 case TypeTableEntryIdArray: 3746 case TypeTableEntryIdComptimeFloat: 3747 case TypeTableEntryIdComptimeInt: 3748 case TypeTableEntryIdUndefined: 3749 case TypeTableEntryIdNull: 3750 case TypeTableEntryIdOptional: 3751 case TypeTableEntryIdErrorUnion: 3752 case TypeTableEntryIdErrorSet: 3753 case TypeTableEntryIdFn: 3754 case TypeTableEntryIdNamespace: 3755 case TypeTableEntryIdBlock: 3756 case TypeTableEntryIdBoundFn: 3757 case TypeTableEntryIdArgTuple: 3758 case TypeTableEntryIdOpaque: 3759 case TypeTableEntryIdPromise: 3760 return false; 3761 } 3762 zig_unreachable(); 3763 } 3764 3765 bool is_ref(TypeTableEntry *type_entry) { 3766 return type_entry->id == TypeTableEntryIdPointer && type_entry->data.pointer.ptr_len == PtrLenSingle; 3767 } 3768 3769 bool is_array_ref(TypeTableEntry *type_entry) { 3770 TypeTableEntry *array = is_ref(type_entry) ? 3771 type_entry->data.pointer.child_type : type_entry; 3772 return array->id == TypeTableEntryIdArray; 3773 } 3774 3775 bool is_container_ref(TypeTableEntry *type_entry) { 3776 return is_ref(type_entry) ? 3777 is_container(type_entry->data.pointer.child_type) : is_container(type_entry); 3778 } 3779 3780 TypeTableEntry *container_ref_type(TypeTableEntry *type_entry) { 3781 assert(is_container_ref(type_entry)); 3782 return is_ref(type_entry) ? 3783 type_entry->data.pointer.child_type : type_entry; 3784 } 3785 3786 void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) { 3787 switch (type_entry->id) { 3788 case TypeTableEntryIdStruct: 3789 resolve_struct_type(g, type_entry); 3790 break; 3791 case TypeTableEntryIdEnum: 3792 resolve_enum_type(g, type_entry); 3793 break; 3794 case TypeTableEntryIdUnion: 3795 resolve_union_type(g, type_entry); 3796 break; 3797 case TypeTableEntryIdPointer: 3798 case TypeTableEntryIdMetaType: 3799 case TypeTableEntryIdVoid: 3800 case TypeTableEntryIdBool: 3801 case TypeTableEntryIdUnreachable: 3802 case TypeTableEntryIdInt: 3803 case TypeTableEntryIdFloat: 3804 case TypeTableEntryIdArray: 3805 case TypeTableEntryIdComptimeFloat: 3806 case TypeTableEntryIdComptimeInt: 3807 case TypeTableEntryIdUndefined: 3808 case TypeTableEntryIdNull: 3809 case TypeTableEntryIdOptional: 3810 case TypeTableEntryIdErrorUnion: 3811 case TypeTableEntryIdErrorSet: 3812 case TypeTableEntryIdFn: 3813 case TypeTableEntryIdNamespace: 3814 case TypeTableEntryIdBlock: 3815 case TypeTableEntryIdBoundFn: 3816 case TypeTableEntryIdInvalid: 3817 case TypeTableEntryIdArgTuple: 3818 case TypeTableEntryIdOpaque: 3819 case TypeTableEntryIdPromise: 3820 zig_unreachable(); 3821 } 3822 } 3823 3824 TypeTableEntry *get_codegen_ptr_type(TypeTableEntry *type) { 3825 if (type->id == TypeTableEntryIdPointer) return type; 3826 if (type->id == TypeTableEntryIdFn) return type; 3827 if (type->id == TypeTableEntryIdPromise) return type; 3828 if (type->id == TypeTableEntryIdOptional) { 3829 if (type->data.maybe.child_type->id == TypeTableEntryIdPointer) return type->data.maybe.child_type; 3830 if (type->data.maybe.child_type->id == TypeTableEntryIdFn) return type->data.maybe.child_type; 3831 if (type->data.maybe.child_type->id == TypeTableEntryIdPromise) return type->data.maybe.child_type; 3832 } 3833 return nullptr; 3834 } 3835 3836 bool type_is_codegen_pointer(TypeTableEntry *type) { 3837 return get_codegen_ptr_type(type) == type; 3838 } 3839 3840 uint32_t get_ptr_align(TypeTableEntry *type) { 3841 TypeTableEntry *ptr_type = get_codegen_ptr_type(type); 3842 if (ptr_type->id == TypeTableEntryIdPointer) { 3843 return ptr_type->data.pointer.alignment; 3844 } else if (ptr_type->id == TypeTableEntryIdFn) { 3845 return (ptr_type->data.fn.fn_type_id.alignment == 0) ? 1 : ptr_type->data.fn.fn_type_id.alignment; 3846 } else if (ptr_type->id == TypeTableEntryIdPromise) { 3847 return 1; 3848 } else { 3849 zig_unreachable(); 3850 } 3851 } 3852 3853 bool get_ptr_const(TypeTableEntry *type) { 3854 TypeTableEntry *ptr_type = get_codegen_ptr_type(type); 3855 if (ptr_type->id == TypeTableEntryIdPointer) { 3856 return ptr_type->data.pointer.is_const; 3857 } else if (ptr_type->id == TypeTableEntryIdFn) { 3858 return true; 3859 } else if (ptr_type->id == TypeTableEntryIdPromise) { 3860 return true; 3861 } else { 3862 zig_unreachable(); 3863 } 3864 } 3865 3866 AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index) { 3867 if (fn_entry->param_source_nodes) 3868 return fn_entry->param_source_nodes[index]; 3869 else if (fn_entry->proto_node) 3870 return fn_entry->proto_node->data.fn_proto.params.at(index); 3871 else 3872 return nullptr; 3873 } 3874 3875 static void define_local_param_variables(CodeGen *g, FnTableEntry *fn_table_entry, VariableTableEntry **arg_vars) { 3876 TypeTableEntry *fn_type = fn_table_entry->type_entry; 3877 assert(!fn_type->data.fn.is_generic); 3878 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 3879 for (size_t i = 0; i < fn_type_id->param_count; i += 1) { 3880 FnTypeParamInfo *param_info = &fn_type_id->param_info[i]; 3881 AstNode *param_decl_node = get_param_decl_node(fn_table_entry, i); 3882 Buf *param_name; 3883 bool is_var_args = param_decl_node && param_decl_node->data.param_decl.is_var_args; 3884 if (param_decl_node && !is_var_args) { 3885 param_name = param_decl_node->data.param_decl.name; 3886 } else { 3887 param_name = buf_sprintf("arg%" ZIG_PRI_usize "", i); 3888 } 3889 if (param_name == nullptr) { 3890 continue; 3891 } 3892 3893 TypeTableEntry *param_type = param_info->type; 3894 bool is_noalias = param_info->is_noalias; 3895 3896 if (is_noalias && get_codegen_ptr_type(param_type) == nullptr) { 3897 add_node_error(g, param_decl_node, buf_sprintf("noalias on non-pointer parameter")); 3898 } 3899 3900 VariableTableEntry *var = add_variable(g, param_decl_node, fn_table_entry->child_scope, 3901 param_name, true, create_const_runtime(param_type), nullptr); 3902 var->src_arg_index = i; 3903 fn_table_entry->child_scope = var->child_scope; 3904 var->shadowable = var->shadowable || is_var_args; 3905 3906 if (type_has_bits(param_type)) { 3907 fn_table_entry->variable_list.append(var); 3908 } 3909 3910 if (fn_type->data.fn.gen_param_info) { 3911 var->gen_arg_index = fn_type->data.fn.gen_param_info[i].gen_index; 3912 } 3913 3914 if (arg_vars) { 3915 arg_vars[i] = var; 3916 } 3917 } 3918 } 3919 3920 bool resolve_inferred_error_set(CodeGen *g, TypeTableEntry *err_set_type, AstNode *source_node) { 3921 FnTableEntry *infer_fn = err_set_type->data.error_set.infer_fn; 3922 if (infer_fn != nullptr) { 3923 if (infer_fn->anal_state == FnAnalStateInvalid) { 3924 return false; 3925 } else if (infer_fn->anal_state == FnAnalStateReady) { 3926 analyze_fn_body(g, infer_fn); 3927 if (err_set_type->data.error_set.infer_fn != nullptr) { 3928 assert(g->errors.length != 0); 3929 return false; 3930 } 3931 } else { 3932 add_node_error(g, source_node, 3933 buf_sprintf("cannot resolve inferred error set '%s': function '%s' not fully analyzed yet", 3934 buf_ptr(&err_set_type->name), buf_ptr(&err_set_type->data.error_set.infer_fn->symbol_name))); 3935 return false; 3936 } 3937 } 3938 return true; 3939 } 3940 3941 void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_type_node) { 3942 TypeTableEntry *fn_type = fn_table_entry->type_entry; 3943 assert(!fn_type->data.fn.is_generic); 3944 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 3945 3946 TypeTableEntry *block_return_type = ir_analyze(g, &fn_table_entry->ir_executable, 3947 &fn_table_entry->analyzed_executable, fn_type_id->return_type, return_type_node); 3948 fn_table_entry->src_implicit_return_type = block_return_type; 3949 3950 if (type_is_invalid(block_return_type) || fn_table_entry->analyzed_executable.invalid) { 3951 assert(g->errors.length > 0); 3952 fn_table_entry->anal_state = FnAnalStateInvalid; 3953 return; 3954 } 3955 3956 if (fn_type_id->return_type->id == TypeTableEntryIdErrorUnion) { 3957 TypeTableEntry *return_err_set_type = fn_type_id->return_type->data.error_union.err_set_type; 3958 if (return_err_set_type->data.error_set.infer_fn != nullptr) { 3959 TypeTableEntry *inferred_err_set_type; 3960 if (fn_table_entry->src_implicit_return_type->id == TypeTableEntryIdErrorSet) { 3961 inferred_err_set_type = fn_table_entry->src_implicit_return_type; 3962 } else if (fn_table_entry->src_implicit_return_type->id == TypeTableEntryIdErrorUnion) { 3963 inferred_err_set_type = fn_table_entry->src_implicit_return_type->data.error_union.err_set_type; 3964 } else { 3965 add_node_error(g, return_type_node, 3966 buf_sprintf("function with inferred error set must return at least one possible error")); 3967 fn_table_entry->anal_state = FnAnalStateInvalid; 3968 return; 3969 } 3970 3971 if (inferred_err_set_type->data.error_set.infer_fn != nullptr) { 3972 if (!resolve_inferred_error_set(g, inferred_err_set_type, return_type_node)) { 3973 fn_table_entry->anal_state = FnAnalStateInvalid; 3974 return; 3975 } 3976 } 3977 3978 return_err_set_type->data.error_set.infer_fn = nullptr; 3979 if (type_is_global_error_set(inferred_err_set_type)) { 3980 return_err_set_type->data.error_set.err_count = UINT32_MAX; 3981 } else { 3982 return_err_set_type->data.error_set.err_count = inferred_err_set_type->data.error_set.err_count; 3983 if (inferred_err_set_type->data.error_set.err_count > 0) { 3984 return_err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(inferred_err_set_type->data.error_set.err_count); 3985 for (uint32_t i = 0; i < inferred_err_set_type->data.error_set.err_count; i += 1) { 3986 return_err_set_type->data.error_set.errors[i] = inferred_err_set_type->data.error_set.errors[i]; 3987 } 3988 } 3989 } 3990 } 3991 } 3992 3993 if (g->verbose_ir) { 3994 fprintf(stderr, "{ // (analyzed)\n"); 3995 ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4); 3996 fprintf(stderr, "}\n"); 3997 } 3998 3999 fn_table_entry->anal_state = FnAnalStateComplete; 4000 } 4001 4002 static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) { 4003 assert(fn_table_entry->anal_state != FnAnalStateProbing); 4004 if (fn_table_entry->anal_state != FnAnalStateReady) 4005 return; 4006 4007 fn_table_entry->anal_state = FnAnalStateProbing; 4008 4009 AstNode *return_type_node = (fn_table_entry->proto_node != nullptr) ? 4010 fn_table_entry->proto_node->data.fn_proto.return_type : fn_table_entry->fndef_scope->base.source_node; 4011 4012 assert(fn_table_entry->fndef_scope); 4013 if (!fn_table_entry->child_scope) 4014 fn_table_entry->child_scope = &fn_table_entry->fndef_scope->base; 4015 4016 define_local_param_variables(g, fn_table_entry, nullptr); 4017 4018 TypeTableEntry *fn_type = fn_table_entry->type_entry; 4019 assert(!fn_type->data.fn.is_generic); 4020 4021 ir_gen_fn(g, fn_table_entry); 4022 if (fn_table_entry->ir_executable.invalid) { 4023 fn_table_entry->anal_state = FnAnalStateInvalid; 4024 return; 4025 } 4026 if (g->verbose_ir) { 4027 fprintf(stderr, "\n"); 4028 ast_render(g, stderr, fn_table_entry->body_node, 4); 4029 fprintf(stderr, "\n{ // (IR)\n"); 4030 ir_print(g, stderr, &fn_table_entry->ir_executable, 4); 4031 fprintf(stderr, "}\n"); 4032 } 4033 4034 analyze_fn_ir(g, fn_table_entry, return_type_node); 4035 } 4036 4037 static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node) { 4038 if (src_use_node->data.use.resolution == TldResolutionUnresolved) { 4039 preview_use_decl(g, src_use_node); 4040 } 4041 4042 IrInstruction *use_target_value = src_use_node->data.use.value; 4043 if (use_target_value->value.type->id == TypeTableEntryIdInvalid) { 4044 dst_use_node->owner->any_imports_failed = true; 4045 return; 4046 } 4047 4048 dst_use_node->data.use.resolution = TldResolutionOk; 4049 4050 ConstExprValue *const_val = &use_target_value->value; 4051 assert(const_val->special != ConstValSpecialRuntime); 4052 4053 ImportTableEntry *target_import = const_val->data.x_import; 4054 assert(target_import); 4055 4056 if (target_import->any_imports_failed) { 4057 dst_use_node->owner->any_imports_failed = true; 4058 } 4059 4060 auto it = target_import->decls_scope->decl_table.entry_iterator(); 4061 for (;;) { 4062 auto *entry = it.next(); 4063 if (!entry) 4064 break; 4065 4066 Tld *target_tld = entry->value; 4067 if (target_tld->import != target_import || 4068 target_tld->visib_mod == VisibModPrivate) 4069 { 4070 continue; 4071 } 4072 4073 Buf *target_tld_name = entry->key; 4074 4075 auto existing_entry = dst_use_node->owner->decls_scope->decl_table.put_unique(target_tld_name, target_tld); 4076 if (existing_entry) { 4077 Tld *existing_decl = existing_entry->value; 4078 if (existing_decl != target_tld) { 4079 ErrorMsg *msg = add_node_error(g, dst_use_node, 4080 buf_sprintf("import of '%s' overrides existing definition", 4081 buf_ptr(target_tld_name))); 4082 add_error_note(g, msg, existing_decl->source_node, buf_sprintf("previous definition here")); 4083 add_error_note(g, msg, target_tld->source_node, buf_sprintf("imported definition here")); 4084 } 4085 } 4086 } 4087 4088 for (size_t i = 0; i < target_import->use_decls.length; i += 1) { 4089 AstNode *use_decl_node = target_import->use_decls.at(i); 4090 if (use_decl_node->data.use.visib_mod != VisibModPrivate) 4091 add_symbols_from_import(g, use_decl_node, dst_use_node); 4092 } 4093 } 4094 4095 void resolve_use_decl(CodeGen *g, AstNode *node) { 4096 assert(node->type == NodeTypeUse); 4097 4098 if (node->data.use.resolution == TldResolutionOk || 4099 node->data.use.resolution == TldResolutionInvalid) 4100 { 4101 return; 4102 } 4103 add_symbols_from_import(g, node, node); 4104 } 4105 4106 void preview_use_decl(CodeGen *g, AstNode *node) { 4107 assert(node->type == NodeTypeUse); 4108 4109 if (node->data.use.resolution == TldResolutionOk || 4110 node->data.use.resolution == TldResolutionInvalid) 4111 { 4112 return; 4113 } 4114 4115 node->data.use.resolution = TldResolutionResolving; 4116 IrInstruction *result = analyze_const_value(g, &node->owner->decls_scope->base, 4117 node->data.use.expr, g->builtin_types.entry_namespace, nullptr); 4118 4119 if (result->value.type->id == TypeTableEntryIdInvalid) 4120 node->owner->any_imports_failed = true; 4121 4122 node->data.use.value = result; 4123 } 4124 4125 ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code) { 4126 if (g->verbose_tokenize) { 4127 fprintf(stderr, "\nOriginal Source (%s):\n", buf_ptr(abs_full_path)); 4128 fprintf(stderr, "----------------\n"); 4129 fprintf(stderr, "%s\n", buf_ptr(source_code)); 4130 4131 fprintf(stderr, "\nTokens:\n"); 4132 fprintf(stderr, "---------\n"); 4133 } 4134 4135 Tokenization tokenization = {0}; 4136 tokenize(source_code, &tokenization); 4137 4138 if (tokenization.err) { 4139 ErrorMsg *err = err_msg_create_with_line(abs_full_path, tokenization.err_line, tokenization.err_column, 4140 source_code, tokenization.line_offsets, tokenization.err); 4141 4142 print_err_msg(err, g->err_color); 4143 exit(1); 4144 } 4145 4146 if (g->verbose_tokenize) { 4147 print_tokens(source_code, tokenization.tokens); 4148 4149 fprintf(stderr, "\nAST:\n"); 4150 fprintf(stderr, "------\n"); 4151 } 4152 4153 ImportTableEntry *import_entry = allocate<ImportTableEntry>(1); 4154 import_entry->package = package; 4155 import_entry->source_code = source_code; 4156 import_entry->line_offsets = tokenization.line_offsets; 4157 import_entry->path = abs_full_path; 4158 4159 import_entry->root = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color); 4160 assert(import_entry->root); 4161 if (g->verbose_ast) { 4162 ast_print(stderr, import_entry->root, 0); 4163 } 4164 4165 Buf *src_dirname = buf_alloc(); 4166 Buf *src_basename = buf_alloc(); 4167 os_path_split(abs_full_path, src_dirname, src_basename); 4168 4169 import_entry->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname)); 4170 g->import_table.put(abs_full_path, import_entry); 4171 g->import_queue.append(import_entry); 4172 4173 import_entry->decls_scope = create_decls_scope(import_entry->root, nullptr, nullptr, import_entry); 4174 4175 4176 assert(import_entry->root->type == NodeTypeRoot); 4177 for (size_t decl_i = 0; decl_i < import_entry->root->data.root.top_level_decls.length; decl_i += 1) { 4178 AstNode *top_level_decl = import_entry->root->data.root.top_level_decls.at(decl_i); 4179 4180 if (top_level_decl->type == NodeTypeFnDef) { 4181 AstNode *proto_node = top_level_decl->data.fn_def.fn_proto; 4182 assert(proto_node->type == NodeTypeFnProto); 4183 Buf *proto_name = proto_node->data.fn_proto.name; 4184 4185 bool is_pub = (proto_node->data.fn_proto.visib_mod == VisibModPub); 4186 bool ok_cc = (proto_node->data.fn_proto.cc == CallingConventionUnspecified || 4187 proto_node->data.fn_proto.cc == CallingConventionCold); 4188 4189 if (is_pub && ok_cc) { 4190 if (buf_eql_str(proto_name, "main")) { 4191 g->have_pub_main = true; 4192 g->windows_subsystem_windows = false; 4193 g->windows_subsystem_console = true; 4194 } else if (buf_eql_str(proto_name, "panic")) { 4195 g->have_pub_panic = true; 4196 } 4197 } 4198 } 4199 } 4200 4201 return import_entry; 4202 } 4203 4204 void scan_import(CodeGen *g, ImportTableEntry *import) { 4205 if (!import->scanned) { 4206 import->scanned = true; 4207 scan_decls(g, import->decls_scope, import->root); 4208 } 4209 } 4210 4211 void semantic_analyze(CodeGen *g) { 4212 for (; g->import_queue_index < g->import_queue.length; g->import_queue_index += 1) { 4213 ImportTableEntry *import = g->import_queue.at(g->import_queue_index); 4214 scan_import(g, import); 4215 } 4216 4217 for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) { 4218 AstNode *use_decl_node = g->use_queue.at(g->use_queue_index); 4219 preview_use_decl(g, use_decl_node); 4220 } 4221 4222 for (size_t i = 0; i < g->use_queue.length; i += 1) { 4223 AstNode *use_decl_node = g->use_queue.at(i); 4224 resolve_use_decl(g, use_decl_node); 4225 } 4226 4227 while (g->resolve_queue_index < g->resolve_queue.length || 4228 g->fn_defs_index < g->fn_defs.length) 4229 { 4230 for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) { 4231 Tld *tld = g->resolve_queue.at(g->resolve_queue_index); 4232 bool pointer_only = false; 4233 AstNode *source_node = nullptr; 4234 resolve_top_level_decl(g, tld, pointer_only, source_node); 4235 } 4236 4237 for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) { 4238 FnTableEntry *fn_entry = g->fn_defs.at(g->fn_defs_index); 4239 analyze_fn_body(g, fn_entry); 4240 } 4241 } 4242 } 4243 4244 TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint32_t size_in_bits) { 4245 size_t index; 4246 if (size_in_bits == 2) { 4247 index = 0; 4248 } else if (size_in_bits == 3) { 4249 index = 1; 4250 } else if (size_in_bits == 4) { 4251 index = 2; 4252 } else if (size_in_bits == 5) { 4253 index = 3; 4254 } else if (size_in_bits == 6) { 4255 index = 4; 4256 } else if (size_in_bits == 7) { 4257 index = 5; 4258 } else if (size_in_bits == 8) { 4259 index = 6; 4260 } else if (size_in_bits == 16) { 4261 index = 7; 4262 } else if (size_in_bits == 29) { 4263 index = 8; 4264 } else if (size_in_bits == 32) { 4265 index = 9; 4266 } else if (size_in_bits == 64) { 4267 index = 10; 4268 } else if (size_in_bits == 128) { 4269 index = 11; 4270 } else { 4271 return nullptr; 4272 } 4273 return &g->builtin_types.entry_int[is_signed ? 0 : 1][index]; 4274 } 4275 4276 TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) { 4277 TypeTableEntry **common_entry = get_int_type_ptr(g, is_signed, size_in_bits); 4278 if (common_entry) 4279 return *common_entry; 4280 4281 TypeId type_id = {}; 4282 type_id.id = TypeTableEntryIdInt; 4283 type_id.data.integer.is_signed = is_signed; 4284 type_id.data.integer.bit_count = size_in_bits; 4285 4286 { 4287 auto entry = g->type_table.maybe_get(type_id); 4288 if (entry) 4289 return entry->value; 4290 } 4291 4292 TypeTableEntry *new_entry = make_int_type(g, is_signed, size_in_bits); 4293 g->type_table.put(type_id, new_entry); 4294 return new_entry; 4295 } 4296 4297 TypeTableEntry **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type) { 4298 return &g->builtin_types.entry_c_int[c_int_type]; 4299 } 4300 4301 TypeTableEntry *get_c_int_type(CodeGen *g, CIntType c_int_type) { 4302 return *get_c_int_type_ptr(g, c_int_type); 4303 } 4304 4305 bool handle_is_ptr(TypeTableEntry *type_entry) { 4306 switch (type_entry->id) { 4307 case TypeTableEntryIdInvalid: 4308 case TypeTableEntryIdMetaType: 4309 case TypeTableEntryIdComptimeFloat: 4310 case TypeTableEntryIdComptimeInt: 4311 case TypeTableEntryIdUndefined: 4312 case TypeTableEntryIdNull: 4313 case TypeTableEntryIdNamespace: 4314 case TypeTableEntryIdBlock: 4315 case TypeTableEntryIdBoundFn: 4316 case TypeTableEntryIdArgTuple: 4317 case TypeTableEntryIdOpaque: 4318 zig_unreachable(); 4319 case TypeTableEntryIdUnreachable: 4320 case TypeTableEntryIdVoid: 4321 case TypeTableEntryIdBool: 4322 case TypeTableEntryIdInt: 4323 case TypeTableEntryIdFloat: 4324 case TypeTableEntryIdPointer: 4325 case TypeTableEntryIdErrorSet: 4326 case TypeTableEntryIdFn: 4327 case TypeTableEntryIdEnum: 4328 case TypeTableEntryIdPromise: 4329 return false; 4330 case TypeTableEntryIdArray: 4331 case TypeTableEntryIdStruct: 4332 return type_has_bits(type_entry); 4333 case TypeTableEntryIdErrorUnion: 4334 return type_has_bits(type_entry->data.error_union.payload_type); 4335 case TypeTableEntryIdOptional: 4336 return type_has_bits(type_entry->data.maybe.child_type) && 4337 !type_is_codegen_pointer(type_entry->data.maybe.child_type); 4338 case TypeTableEntryIdUnion: 4339 assert(type_entry->data.unionation.complete); 4340 if (type_entry->data.unionation.gen_field_count == 0) 4341 return false; 4342 if (!type_has_bits(type_entry)) 4343 return false; 4344 return true; 4345 4346 } 4347 zig_unreachable(); 4348 } 4349 4350 static ZigWindowsSDK *get_windows_sdk(CodeGen *g) { 4351 if (g->win_sdk == nullptr) { 4352 if (os_find_windows_sdk(&g->win_sdk)) { 4353 fprintf(stderr, "unable to determine windows sdk path\n"); 4354 exit(1); 4355 } 4356 } 4357 assert(g->win_sdk != nullptr); 4358 return g->win_sdk; 4359 } 4360 4361 4362 Buf *get_linux_libc_lib_path(const char *o_file) { 4363 const char *cc_exe = getenv("CC"); 4364 cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe; 4365 ZigList<const char *> args = {}; 4366 args.append(buf_ptr(buf_sprintf("-print-file-name=%s", o_file))); 4367 Termination term; 4368 Buf *out_stderr = buf_alloc(); 4369 Buf *out_stdout = buf_alloc(); 4370 int err; 4371 if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) { 4372 zig_panic("unable to determine libc lib path: executing C compiler: %s", err_str(err)); 4373 } 4374 if (term.how != TerminationIdClean || term.code != 0) { 4375 zig_panic("unable to determine libc lib path: executing C compiler command failed"); 4376 } 4377 if (buf_ends_with_str(out_stdout, "\n")) { 4378 buf_resize(out_stdout, buf_len(out_stdout) - 1); 4379 } 4380 if (buf_len(out_stdout) == 0 || buf_eql_str(out_stdout, o_file)) { 4381 zig_panic("unable to determine libc lib path: C compiler could not find %s", o_file); 4382 } 4383 Buf *result = buf_alloc(); 4384 os_path_dirname(out_stdout, result); 4385 return result; 4386 } 4387 4388 Buf *get_linux_libc_include_path(void) { 4389 const char *cc_exe = getenv("CC"); 4390 cc_exe = (cc_exe == nullptr) ? "cc" : cc_exe; 4391 ZigList<const char *> args = {}; 4392 args.append("-E"); 4393 args.append("-Wp,-v"); 4394 args.append("-xc"); 4395 args.append("/dev/null"); 4396 Termination term; 4397 Buf *out_stderr = buf_alloc(); 4398 Buf *out_stdout = buf_alloc(); 4399 int err; 4400 if ((err = os_exec_process(cc_exe, args, &term, out_stderr, out_stdout))) { 4401 zig_panic("unable to determine libc include path: executing C compiler: %s", err_str(err)); 4402 } 4403 if (term.how != TerminationIdClean || term.code != 0) { 4404 zig_panic("unable to determine libc include path: executing C compiler command failed"); 4405 } 4406 char *prev_newline = buf_ptr(out_stderr); 4407 ZigList<const char *> search_paths = {}; 4408 bool found_search_paths = false; 4409 for (;;) { 4410 char *newline = strchr(prev_newline, '\n'); 4411 if (newline == nullptr) { 4412 zig_panic("unable to determine libc include path: bad output from C compiler command"); 4413 } 4414 *newline = 0; 4415 if (found_search_paths) { 4416 if (strcmp(prev_newline, "End of search list.") == 0) { 4417 break; 4418 } 4419 search_paths.append(prev_newline); 4420 } else { 4421 if (strcmp(prev_newline, "#include <...> search starts here:") == 0) { 4422 found_search_paths = true; 4423 } 4424 } 4425 prev_newline = newline + 1; 4426 } 4427 if (search_paths.length == 0) { 4428 zig_panic("unable to determine libc include path: even C compiler does not know where libc headers are"); 4429 } 4430 for (size_t i = 0; i < search_paths.length; i += 1) { 4431 // search in reverse order 4432 const char *search_path = search_paths.items[search_paths.length - i - 1]; 4433 // cut off spaces 4434 while (*search_path == ' ') { 4435 search_path += 1; 4436 } 4437 Buf *stdlib_path = buf_sprintf("%s/stdlib.h", search_path); 4438 bool exists; 4439 if ((err = os_file_exists(stdlib_path, &exists))) { 4440 exists = false; 4441 } 4442 if (exists) { 4443 return buf_create_from_str(search_path); 4444 } 4445 } 4446 zig_panic("unable to determine libc include path: stdlib.h not found in C compiler search paths"); 4447 } 4448 4449 void find_libc_include_path(CodeGen *g) { 4450 if (g->libc_include_dir == nullptr) { 4451 4452 if (g->zig_target.os == OsWindows) { 4453 ZigWindowsSDK *sdk = get_windows_sdk(g); 4454 g->libc_include_dir = buf_alloc(); 4455 if (os_get_win32_ucrt_include_path(sdk, g->libc_include_dir)) { 4456 fprintf(stderr, "Unable to determine libc include path. --libc-include-dir"); 4457 exit(1); 4458 } 4459 } else if (g->zig_target.os == OsLinux) { 4460 g->libc_include_dir = get_linux_libc_include_path(); 4461 } else if (g->zig_target.os == OsMacOSX) { 4462 g->libc_include_dir = buf_create_from_str("/usr/include"); 4463 } else { 4464 // TODO find libc at runtime for other operating systems 4465 zig_panic("Unable to determine libc include path."); 4466 } 4467 } 4468 assert(buf_len(g->libc_include_dir) != 0); 4469 } 4470 4471 void find_libc_lib_path(CodeGen *g) { 4472 // later we can handle this better by reporting an error via the normal mechanism 4473 if (g->libc_lib_dir == nullptr || 4474 (g->zig_target.os == OsWindows && (g->msvc_lib_dir == nullptr || g->kernel32_lib_dir == nullptr))) 4475 { 4476 if (g->zig_target.os == OsWindows) { 4477 ZigWindowsSDK *sdk = get_windows_sdk(g); 4478 4479 if (g->msvc_lib_dir == nullptr) { 4480 Buf* vc_lib_dir = buf_alloc(); 4481 if (os_get_win32_vcruntime_path(vc_lib_dir, g->zig_target.arch.arch)) { 4482 fprintf(stderr, "Unable to determine vcruntime path. --msvc-lib-dir"); 4483 exit(1); 4484 } 4485 g->msvc_lib_dir = vc_lib_dir; 4486 } 4487 4488 if (g->libc_lib_dir == nullptr) { 4489 Buf* ucrt_lib_path = buf_alloc(); 4490 if (os_get_win32_ucrt_lib_path(sdk, ucrt_lib_path, g->zig_target.arch.arch)) { 4491 fprintf(stderr, "Unable to determine ucrt path. --libc-lib-dir"); 4492 exit(1); 4493 } 4494 g->libc_lib_dir = ucrt_lib_path; 4495 } 4496 4497 if (g->kernel32_lib_dir == nullptr) { 4498 Buf* kern_lib_path = buf_alloc(); 4499 if (os_get_win32_kern32_path(sdk, kern_lib_path, g->zig_target.arch.arch)) { 4500 fprintf(stderr, "Unable to determine kernel32 path. --kernel32-lib-dir"); 4501 exit(1); 4502 } 4503 g->kernel32_lib_dir = kern_lib_path; 4504 } 4505 4506 } else if (g->zig_target.os == OsLinux) { 4507 g->libc_lib_dir = get_linux_libc_lib_path("crt1.o"); 4508 } else { 4509 zig_panic("Unable to determine libc lib path."); 4510 } 4511 } else { 4512 assert(buf_len(g->libc_lib_dir) != 0); 4513 } 4514 4515 if (g->libc_static_lib_dir == nullptr) { 4516 if ((g->zig_target.os == OsWindows) && (g->msvc_lib_dir != NULL)) { 4517 return; 4518 } else if (g->zig_target.os == OsLinux) { 4519 g->libc_static_lib_dir = get_linux_libc_lib_path("crtbegin.o"); 4520 } else { 4521 zig_panic("Unable to determine libc static lib path."); 4522 } 4523 } else { 4524 assert(buf_len(g->libc_static_lib_dir) != 0); 4525 } 4526 } 4527 4528 static uint32_t hash_ptr(void *ptr) { 4529 return (uint32_t)(((uintptr_t)ptr) % UINT32_MAX); 4530 } 4531 4532 static uint32_t hash_size(size_t x) { 4533 return (uint32_t)(x % UINT32_MAX); 4534 } 4535 4536 uint32_t fn_table_entry_hash(FnTableEntry* value) { 4537 return ptr_hash(value); 4538 } 4539 4540 bool fn_table_entry_eql(FnTableEntry *a, FnTableEntry *b) { 4541 return ptr_eq(a, b); 4542 } 4543 4544 uint32_t fn_type_id_hash(FnTypeId *id) { 4545 uint32_t result = 0; 4546 result += ((uint32_t)(id->cc)) * (uint32_t)3349388391; 4547 result += id->is_var_args ? (uint32_t)1931444534 : 0; 4548 result += hash_ptr(id->return_type); 4549 result += hash_ptr(id->async_allocator_type); 4550 result += id->alignment * 0xd3b3f3e2; 4551 for (size_t i = 0; i < id->param_count; i += 1) { 4552 FnTypeParamInfo *info = &id->param_info[i]; 4553 result += info->is_noalias ? (uint32_t)892356923 : 0; 4554 result += hash_ptr(info->type); 4555 } 4556 return result; 4557 } 4558 4559 bool fn_type_id_eql(FnTypeId *a, FnTypeId *b) { 4560 if (a->cc != b->cc || 4561 a->return_type != b->return_type || 4562 a->is_var_args != b->is_var_args || 4563 a->param_count != b->param_count || 4564 a->alignment != b->alignment || 4565 a->async_allocator_type != b->async_allocator_type) 4566 { 4567 return false; 4568 } 4569 for (size_t i = 0; i < a->param_count; i += 1) { 4570 FnTypeParamInfo *a_param_info = &a->param_info[i]; 4571 FnTypeParamInfo *b_param_info = &b->param_info[i]; 4572 4573 if (a_param_info->type != b_param_info->type || 4574 a_param_info->is_noalias != b_param_info->is_noalias) 4575 { 4576 return false; 4577 } 4578 } 4579 return true; 4580 } 4581 4582 static uint32_t hash_const_val_ptr(ConstExprValue *const_val) { 4583 uint32_t hash_val = 0; 4584 switch (const_val->data.x_ptr.mut) { 4585 case ConstPtrMutRuntimeVar: 4586 hash_val += (uint32_t)3500721036; 4587 break; 4588 case ConstPtrMutComptimeConst: 4589 hash_val += (uint32_t)4214318515; 4590 break; 4591 case ConstPtrMutComptimeVar: 4592 hash_val += (uint32_t)1103195694; 4593 break; 4594 } 4595 switch (const_val->data.x_ptr.special) { 4596 case ConstPtrSpecialInvalid: 4597 zig_unreachable(); 4598 case ConstPtrSpecialRef: 4599 hash_val += (uint32_t)2478261866; 4600 hash_val += hash_ptr(const_val->data.x_ptr.data.ref.pointee); 4601 return hash_val; 4602 case ConstPtrSpecialBaseArray: 4603 hash_val += (uint32_t)1764906839; 4604 hash_val += hash_ptr(const_val->data.x_ptr.data.base_array.array_val); 4605 hash_val += hash_size(const_val->data.x_ptr.data.base_array.elem_index); 4606 hash_val += const_val->data.x_ptr.data.base_array.is_cstr ? 1297263887 : 200363492; 4607 return hash_val; 4608 case ConstPtrSpecialBaseStruct: 4609 hash_val += (uint32_t)3518317043; 4610 hash_val += hash_ptr(const_val->data.x_ptr.data.base_struct.struct_val); 4611 hash_val += hash_size(const_val->data.x_ptr.data.base_struct.field_index); 4612 return hash_val; 4613 case ConstPtrSpecialHardCodedAddr: 4614 hash_val += (uint32_t)4048518294; 4615 hash_val += hash_size(const_val->data.x_ptr.data.hard_coded_addr.addr); 4616 return hash_val; 4617 case ConstPtrSpecialDiscard: 4618 hash_val += 2010123162; 4619 return hash_val; 4620 case ConstPtrSpecialFunction: 4621 hash_val += (uint32_t)2590901619; 4622 hash_val += hash_ptr(const_val->data.x_ptr.data.fn.fn_entry); 4623 return hash_val; 4624 } 4625 zig_unreachable(); 4626 } 4627 4628 static uint32_t hash_const_val(ConstExprValue *const_val) { 4629 assert(const_val->special == ConstValSpecialStatic); 4630 switch (const_val->type->id) { 4631 case TypeTableEntryIdOpaque: 4632 zig_unreachable(); 4633 case TypeTableEntryIdBool: 4634 return const_val->data.x_bool ? (uint32_t)127863866 : (uint32_t)215080464; 4635 case TypeTableEntryIdMetaType: 4636 return hash_ptr(const_val->data.x_type); 4637 case TypeTableEntryIdVoid: 4638 return (uint32_t)4149439618; 4639 case TypeTableEntryIdInt: 4640 case TypeTableEntryIdComptimeInt: 4641 { 4642 uint32_t result = 1331471175; 4643 for (size_t i = 0; i < const_val->data.x_bigint.digit_count; i += 1) { 4644 uint64_t digit = bigint_ptr(&const_val->data.x_bigint)[i]; 4645 result ^= ((uint32_t)(digit >> 32)) ^ (uint32_t)(result); 4646 } 4647 return result; 4648 } 4649 case TypeTableEntryIdEnum: 4650 { 4651 uint32_t result = 31643936; 4652 for (size_t i = 0; i < const_val->data.x_enum_tag.digit_count; i += 1) { 4653 uint64_t digit = bigint_ptr(&const_val->data.x_enum_tag)[i]; 4654 result ^= ((uint32_t)(digit >> 32)) ^ (uint32_t)(result); 4655 } 4656 return result; 4657 } 4658 case TypeTableEntryIdFloat: 4659 switch (const_val->type->data.floating.bit_count) { 4660 case 32: 4661 { 4662 uint32_t result; 4663 memcpy(&result, &const_val->data.x_f32, 4); 4664 return result ^ 4084870010; 4665 } 4666 case 64: 4667 { 4668 uint32_t ints[2]; 4669 memcpy(&ints[0], &const_val->data.x_f64, 8); 4670 return ints[0] ^ ints[1] ^ 0x22ed43c6; 4671 } 4672 case 128: 4673 { 4674 uint32_t ints[4]; 4675 memcpy(&ints[0], &const_val->data.x_f128, 16); 4676 return ints[0] ^ ints[1] ^ ints[2] ^ ints[3] ^ 0xb5ffef27; 4677 } 4678 default: 4679 zig_unreachable(); 4680 } 4681 case TypeTableEntryIdComptimeFloat: 4682 { 4683 float128_t f128 = bigfloat_to_f128(&const_val->data.x_bigfloat); 4684 uint32_t ints[4]; 4685 memcpy(&ints[0], &f128, 16); 4686 return ints[0] ^ ints[1] ^ ints[2] ^ ints[3] ^ 0xed8b3dfb; 4687 } 4688 case TypeTableEntryIdArgTuple: 4689 return (uint32_t)const_val->data.x_arg_tuple.start_index * (uint32_t)281907309 + 4690 (uint32_t)const_val->data.x_arg_tuple.end_index * (uint32_t)2290442768; 4691 case TypeTableEntryIdFn: 4692 assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst); 4693 assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction); 4694 return 3677364617 ^ hash_ptr(const_val->data.x_ptr.data.fn.fn_entry); 4695 case TypeTableEntryIdPointer: 4696 return hash_const_val_ptr(const_val); 4697 case TypeTableEntryIdPromise: 4698 // TODO better hashing algorithm 4699 return 223048345; 4700 case TypeTableEntryIdUndefined: 4701 return 162837799; 4702 case TypeTableEntryIdNull: 4703 return 844854567; 4704 case TypeTableEntryIdArray: 4705 // TODO better hashing algorithm 4706 return 1166190605; 4707 case TypeTableEntryIdStruct: 4708 // TODO better hashing algorithm 4709 return 1532530855; 4710 case TypeTableEntryIdUnion: 4711 // TODO better hashing algorithm 4712 return 2709806591; 4713 case TypeTableEntryIdOptional: 4714 if (get_codegen_ptr_type(const_val->type) != nullptr) { 4715 return hash_const_val(const_val) * 1992916303; 4716 } else { 4717 if (const_val->data.x_optional) { 4718 return hash_const_val(const_val->data.x_optional) * 1992916303; 4719 } else { 4720 return 4016830364; 4721 } 4722 } 4723 case TypeTableEntryIdErrorUnion: 4724 // TODO better hashing algorithm 4725 return 3415065496; 4726 case TypeTableEntryIdErrorSet: 4727 assert(const_val->data.x_err_set != nullptr); 4728 return const_val->data.x_err_set->value ^ 2630160122; 4729 case TypeTableEntryIdNamespace: 4730 return hash_ptr(const_val->data.x_import); 4731 case TypeTableEntryIdBlock: 4732 return hash_ptr(const_val->data.x_block); 4733 case TypeTableEntryIdBoundFn: 4734 case TypeTableEntryIdInvalid: 4735 case TypeTableEntryIdUnreachable: 4736 zig_unreachable(); 4737 } 4738 zig_unreachable(); 4739 } 4740 4741 uint32_t generic_fn_type_id_hash(GenericFnTypeId *id) { 4742 uint32_t result = 0; 4743 result += hash_ptr(id->fn_entry); 4744 for (size_t i = 0; i < id->param_count; i += 1) { 4745 ConstExprValue *generic_param = &id->params[i]; 4746 if (generic_param->special != ConstValSpecialRuntime) { 4747 result += hash_const_val(generic_param); 4748 result += hash_ptr(generic_param->type); 4749 } 4750 } 4751 return result; 4752 } 4753 4754 bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) { 4755 assert(a->fn_entry); 4756 if (a->fn_entry != b->fn_entry) return false; 4757 if (a->param_count != b->param_count) return false; 4758 for (size_t i = 0; i < a->param_count; i += 1) { 4759 ConstExprValue *a_val = &a->params[i]; 4760 ConstExprValue *b_val = &b->params[i]; 4761 if (a_val->type != b_val->type) return false; 4762 if (a_val->special != ConstValSpecialRuntime && b_val->special != ConstValSpecialRuntime) { 4763 assert(a_val->special == ConstValSpecialStatic); 4764 assert(b_val->special == ConstValSpecialStatic); 4765 if (!const_values_equal(a_val, b_val)) { 4766 return false; 4767 } 4768 } else { 4769 assert(a_val->special == ConstValSpecialRuntime && b_val->special == ConstValSpecialRuntime); 4770 } 4771 } 4772 return true; 4773 } 4774 4775 static bool can_mutate_comptime_var_state(ConstExprValue *value) { 4776 assert(value != nullptr); 4777 switch (value->type->id) { 4778 case TypeTableEntryIdInvalid: 4779 zig_unreachable(); 4780 case TypeTableEntryIdMetaType: 4781 case TypeTableEntryIdVoid: 4782 case TypeTableEntryIdBool: 4783 case TypeTableEntryIdUnreachable: 4784 case TypeTableEntryIdInt: 4785 case TypeTableEntryIdFloat: 4786 case TypeTableEntryIdComptimeFloat: 4787 case TypeTableEntryIdComptimeInt: 4788 case TypeTableEntryIdUndefined: 4789 case TypeTableEntryIdNull: 4790 case TypeTableEntryIdNamespace: 4791 case TypeTableEntryIdBoundFn: 4792 case TypeTableEntryIdFn: 4793 case TypeTableEntryIdBlock: 4794 case TypeTableEntryIdOpaque: 4795 case TypeTableEntryIdPromise: 4796 case TypeTableEntryIdErrorSet: 4797 case TypeTableEntryIdEnum: 4798 return false; 4799 4800 case TypeTableEntryIdPointer: 4801 return value->data.x_ptr.mut == ConstPtrMutComptimeVar; 4802 4803 case TypeTableEntryIdArray: 4804 if (value->type->data.array.len == 0) 4805 return false; 4806 if (value->data.x_array.special == ConstArraySpecialUndef) 4807 return false; 4808 for (uint32_t i = 0; i < value->type->data.array.len; i += 1) { 4809 if (can_mutate_comptime_var_state(&value->data.x_array.s_none.elements[i])) 4810 return true; 4811 } 4812 return false; 4813 4814 case TypeTableEntryIdStruct: 4815 for (uint32_t i = 0; i < value->type->data.structure.src_field_count; i += 1) { 4816 if (can_mutate_comptime_var_state(&value->data.x_struct.fields[i])) 4817 return true; 4818 } 4819 return false; 4820 4821 case TypeTableEntryIdOptional: 4822 if (get_codegen_ptr_type(value->type) != nullptr) 4823 return value->data.x_ptr.mut == ConstPtrMutComptimeVar; 4824 if (value->data.x_optional == nullptr) 4825 return false; 4826 return can_mutate_comptime_var_state(value->data.x_optional); 4827 4828 case TypeTableEntryIdErrorUnion: 4829 if (value->data.x_err_union.err != nullptr) 4830 return false; 4831 assert(value->data.x_err_union.payload != nullptr); 4832 return can_mutate_comptime_var_state(value->data.x_err_union.payload); 4833 4834 case TypeTableEntryIdUnion: 4835 return can_mutate_comptime_var_state(value->data.x_union.payload); 4836 4837 case TypeTableEntryIdArgTuple: 4838 zig_panic("TODO var args at comptime is currently not supported"); 4839 } 4840 zig_unreachable(); 4841 } 4842 4843 static bool return_type_is_cacheable(TypeTableEntry *return_type) { 4844 switch (return_type->id) { 4845 case TypeTableEntryIdInvalid: 4846 zig_unreachable(); 4847 case TypeTableEntryIdMetaType: 4848 case TypeTableEntryIdVoid: 4849 case TypeTableEntryIdBool: 4850 case TypeTableEntryIdUnreachable: 4851 case TypeTableEntryIdInt: 4852 case TypeTableEntryIdFloat: 4853 case TypeTableEntryIdComptimeFloat: 4854 case TypeTableEntryIdComptimeInt: 4855 case TypeTableEntryIdUndefined: 4856 case TypeTableEntryIdNull: 4857 case TypeTableEntryIdNamespace: 4858 case TypeTableEntryIdBoundFn: 4859 case TypeTableEntryIdFn: 4860 case TypeTableEntryIdBlock: 4861 case TypeTableEntryIdOpaque: 4862 case TypeTableEntryIdPromise: 4863 case TypeTableEntryIdErrorSet: 4864 case TypeTableEntryIdEnum: 4865 case TypeTableEntryIdPointer: 4866 return true; 4867 4868 case TypeTableEntryIdArray: 4869 case TypeTableEntryIdStruct: 4870 case TypeTableEntryIdUnion: 4871 return false; 4872 4873 case TypeTableEntryIdOptional: 4874 return return_type_is_cacheable(return_type->data.maybe.child_type); 4875 4876 case TypeTableEntryIdErrorUnion: 4877 return return_type_is_cacheable(return_type->data.error_union.payload_type); 4878 4879 case TypeTableEntryIdArgTuple: 4880 zig_panic("TODO var args at comptime is currently not supported"); 4881 } 4882 zig_unreachable(); 4883 } 4884 4885 bool fn_eval_cacheable(Scope *scope, TypeTableEntry *return_type) { 4886 if (!return_type_is_cacheable(return_type)) 4887 return false; 4888 while (scope) { 4889 if (scope->id == ScopeIdVarDecl) { 4890 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope; 4891 if (can_mutate_comptime_var_state(var_scope->var->value)) 4892 return false; 4893 } else if (scope->id == ScopeIdFnDef) { 4894 return true; 4895 } else { 4896 zig_unreachable(); 4897 } 4898 4899 scope = scope->parent; 4900 } 4901 zig_unreachable(); 4902 } 4903 4904 uint32_t fn_eval_hash(Scope* scope) { 4905 uint32_t result = 0; 4906 while (scope) { 4907 if (scope->id == ScopeIdVarDecl) { 4908 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope; 4909 result += hash_const_val(var_scope->var->value); 4910 } else if (scope->id == ScopeIdFnDef) { 4911 ScopeFnDef *fn_scope = (ScopeFnDef *)scope; 4912 result += hash_ptr(fn_scope->fn_entry); 4913 return result; 4914 } else { 4915 zig_unreachable(); 4916 } 4917 4918 scope = scope->parent; 4919 } 4920 zig_unreachable(); 4921 } 4922 4923 bool fn_eval_eql(Scope *a, Scope *b) { 4924 while (a && b) { 4925 if (a->id != b->id) 4926 return false; 4927 4928 if (a->id == ScopeIdVarDecl) { 4929 ScopeVarDecl *a_var_scope = (ScopeVarDecl *)a; 4930 ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b; 4931 if (a_var_scope->var->value->type != b_var_scope->var->value->type) 4932 return false; 4933 if (!const_values_equal(a_var_scope->var->value, b_var_scope->var->value)) 4934 return false; 4935 } else if (a->id == ScopeIdFnDef) { 4936 ScopeFnDef *a_fn_scope = (ScopeFnDef *)a; 4937 ScopeFnDef *b_fn_scope = (ScopeFnDef *)b; 4938 if (a_fn_scope->fn_entry != b_fn_scope->fn_entry) 4939 return false; 4940 4941 return true; 4942 } else { 4943 zig_unreachable(); 4944 } 4945 4946 a = a->parent; 4947 b = b->parent; 4948 } 4949 return false; 4950 } 4951 4952 bool type_has_bits(TypeTableEntry *type_entry) { 4953 assert(type_entry); 4954 assert(type_entry->id != TypeTableEntryIdInvalid); 4955 assert(type_has_zero_bits_known(type_entry)); 4956 return !type_entry->zero_bits; 4957 } 4958 4959 bool type_requires_comptime(TypeTableEntry *type_entry) { 4960 switch (type_entry->id) { 4961 case TypeTableEntryIdInvalid: 4962 case TypeTableEntryIdOpaque: 4963 zig_unreachable(); 4964 case TypeTableEntryIdComptimeFloat: 4965 case TypeTableEntryIdComptimeInt: 4966 case TypeTableEntryIdUndefined: 4967 case TypeTableEntryIdNull: 4968 case TypeTableEntryIdMetaType: 4969 case TypeTableEntryIdNamespace: 4970 case TypeTableEntryIdBlock: 4971 case TypeTableEntryIdBoundFn: 4972 case TypeTableEntryIdArgTuple: 4973 return true; 4974 case TypeTableEntryIdArray: 4975 return type_requires_comptime(type_entry->data.array.child_type); 4976 case TypeTableEntryIdStruct: 4977 assert(type_has_zero_bits_known(type_entry)); 4978 return type_entry->data.structure.requires_comptime; 4979 case TypeTableEntryIdUnion: 4980 assert(type_has_zero_bits_known(type_entry)); 4981 return type_entry->data.unionation.requires_comptime; 4982 case TypeTableEntryIdOptional: 4983 return type_requires_comptime(type_entry->data.maybe.child_type); 4984 case TypeTableEntryIdErrorUnion: 4985 return type_requires_comptime(type_entry->data.error_union.payload_type); 4986 case TypeTableEntryIdPointer: 4987 if (type_entry->data.pointer.child_type->id == TypeTableEntryIdOpaque) { 4988 return false; 4989 } else { 4990 return type_requires_comptime(type_entry->data.pointer.child_type); 4991 } 4992 case TypeTableEntryIdEnum: 4993 case TypeTableEntryIdErrorSet: 4994 case TypeTableEntryIdFn: 4995 case TypeTableEntryIdBool: 4996 case TypeTableEntryIdInt: 4997 case TypeTableEntryIdFloat: 4998 case TypeTableEntryIdVoid: 4999 case TypeTableEntryIdUnreachable: 5000 case TypeTableEntryIdPromise: 5001 return false; 5002 } 5003 zig_unreachable(); 5004 } 5005 5006 void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { 5007 auto entry = g->string_literals_table.maybe_get(str); 5008 if (entry != nullptr) { 5009 *const_val = *entry->value; 5010 return; 5011 } 5012 5013 const_val->special = ConstValSpecialStatic; 5014 const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str)); 5015 const_val->data.x_array.s_none.elements = create_const_vals(buf_len(str)); 5016 5017 for (size_t i = 0; i < buf_len(str); i += 1) { 5018 ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i]; 5019 this_char->special = ConstValSpecialStatic; 5020 this_char->type = g->builtin_types.entry_u8; 5021 bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]); 5022 } 5023 5024 g->string_literals_table.put(str, const_val); 5025 } 5026 5027 ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) { 5028 ConstExprValue *const_val = create_const_vals(1); 5029 init_const_str_lit(g, const_val, str); 5030 return const_val; 5031 } 5032 5033 void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { 5034 // first we build the underlying array 5035 size_t len_with_null = buf_len(str) + 1; 5036 ConstExprValue *array_val = create_const_vals(1); 5037 array_val->special = ConstValSpecialStatic; 5038 array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null); 5039 array_val->data.x_array.s_none.elements = create_const_vals(len_with_null); 5040 for (size_t i = 0; i < buf_len(str); i += 1) { 5041 ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i]; 5042 this_char->special = ConstValSpecialStatic; 5043 this_char->type = g->builtin_types.entry_u8; 5044 bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]); 5045 } 5046 ConstExprValue *null_char = &array_val->data.x_array.s_none.elements[len_with_null - 1]; 5047 null_char->special = ConstValSpecialStatic; 5048 null_char->type = g->builtin_types.entry_u8; 5049 bigint_init_unsigned(&null_char->data.x_bigint, 0); 5050 5051 // then make the pointer point to it 5052 const_val->special = ConstValSpecialStatic; 5053 // TODO make this `[*]null u8` instead of `[*]u8` 5054 const_val->type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, 5055 PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0); 5056 const_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 5057 const_val->data.x_ptr.data.base_array.array_val = array_val; 5058 const_val->data.x_ptr.data.base_array.elem_index = 0; 5059 const_val->data.x_ptr.data.base_array.is_cstr = true; 5060 } 5061 ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *str) { 5062 ConstExprValue *const_val = create_const_vals(1); 5063 init_const_c_str_lit(g, const_val, str); 5064 return const_val; 5065 } 5066 5067 void init_const_bigint(ConstExprValue *const_val, TypeTableEntry *type, const BigInt *bigint) { 5068 const_val->special = ConstValSpecialStatic; 5069 const_val->type = type; 5070 bigint_init_bigint(&const_val->data.x_bigint, bigint); 5071 } 5072 5073 ConstExprValue *create_const_bigint(TypeTableEntry *type, const BigInt *bigint) { 5074 ConstExprValue *const_val = create_const_vals(1); 5075 init_const_bigint(const_val, type, bigint); 5076 return const_val; 5077 } 5078 5079 5080 void init_const_unsigned_negative(ConstExprValue *const_val, TypeTableEntry *type, uint64_t x, bool negative) { 5081 const_val->special = ConstValSpecialStatic; 5082 const_val->type = type; 5083 bigint_init_unsigned(&const_val->data.x_bigint, x); 5084 const_val->data.x_bigint.is_negative = negative; 5085 } 5086 5087 ConstExprValue *create_const_unsigned_negative(TypeTableEntry *type, uint64_t x, bool negative) { 5088 ConstExprValue *const_val = create_const_vals(1); 5089 init_const_unsigned_negative(const_val, type, x, negative); 5090 return const_val; 5091 } 5092 5093 void init_const_usize(CodeGen *g, ConstExprValue *const_val, uint64_t x) { 5094 return init_const_unsigned_negative(const_val, g->builtin_types.entry_usize, x, false); 5095 } 5096 5097 ConstExprValue *create_const_usize(CodeGen *g, uint64_t x) { 5098 return create_const_unsigned_negative(g->builtin_types.entry_usize, x, false); 5099 } 5100 5101 void init_const_signed(ConstExprValue *const_val, TypeTableEntry *type, int64_t x) { 5102 const_val->special = ConstValSpecialStatic; 5103 const_val->type = type; 5104 bigint_init_signed(&const_val->data.x_bigint, x); 5105 } 5106 5107 ConstExprValue *create_const_signed(TypeTableEntry *type, int64_t x) { 5108 ConstExprValue *const_val = create_const_vals(1); 5109 init_const_signed(const_val, type, x); 5110 return const_val; 5111 } 5112 5113 void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double value) { 5114 const_val->special = ConstValSpecialStatic; 5115 const_val->type = type; 5116 if (type->id == TypeTableEntryIdComptimeFloat) { 5117 bigfloat_init_64(&const_val->data.x_bigfloat, value); 5118 } else if (type->id == TypeTableEntryIdFloat) { 5119 switch (type->data.floating.bit_count) { 5120 case 32: 5121 const_val->data.x_f32 = value; 5122 break; 5123 case 64: 5124 const_val->data.x_f64 = value; 5125 break; 5126 case 128: 5127 // if we need this, we should add a function that accepts a float128_t param 5128 zig_unreachable(); 5129 default: 5130 zig_unreachable(); 5131 } 5132 } else { 5133 zig_unreachable(); 5134 } 5135 } 5136 5137 ConstExprValue *create_const_float(TypeTableEntry *type, double value) { 5138 ConstExprValue *const_val = create_const_vals(1); 5139 init_const_float(const_val, type, value); 5140 return const_val; 5141 } 5142 5143 void init_const_enum(ConstExprValue *const_val, TypeTableEntry *type, const BigInt *tag) { 5144 const_val->special = ConstValSpecialStatic; 5145 const_val->type = type; 5146 bigint_init_bigint(&const_val->data.x_enum_tag, tag); 5147 } 5148 5149 ConstExprValue *create_const_enum(TypeTableEntry *type, const BigInt *tag) { 5150 ConstExprValue *const_val = create_const_vals(1); 5151 init_const_enum(const_val, type, tag); 5152 return const_val; 5153 } 5154 5155 5156 void init_const_bool(CodeGen *g, ConstExprValue *const_val, bool value) { 5157 const_val->special = ConstValSpecialStatic; 5158 const_val->type = g->builtin_types.entry_bool; 5159 const_val->data.x_bool = value; 5160 } 5161 5162 ConstExprValue *create_const_bool(CodeGen *g, bool value) { 5163 ConstExprValue *const_val = create_const_vals(1); 5164 init_const_bool(g, const_val, value); 5165 return const_val; 5166 } 5167 5168 void init_const_runtime(ConstExprValue *const_val, TypeTableEntry *type) { 5169 const_val->special = ConstValSpecialRuntime; 5170 const_val->type = type; 5171 } 5172 5173 ConstExprValue *create_const_runtime(TypeTableEntry *type) { 5174 ConstExprValue *const_val = create_const_vals(1); 5175 init_const_runtime(const_val, type); 5176 return const_val; 5177 } 5178 5179 void init_const_type(CodeGen *g, ConstExprValue *const_val, TypeTableEntry *type_value) { 5180 const_val->special = ConstValSpecialStatic; 5181 const_val->type = g->builtin_types.entry_type; 5182 const_val->data.x_type = type_value; 5183 } 5184 5185 ConstExprValue *create_const_type(CodeGen *g, TypeTableEntry *type_value) { 5186 ConstExprValue *const_val = create_const_vals(1); 5187 init_const_type(g, const_val, type_value); 5188 return const_val; 5189 } 5190 5191 void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val, 5192 size_t start, size_t len, bool is_const) 5193 { 5194 assert(array_val->type->id == TypeTableEntryIdArray); 5195 5196 TypeTableEntry *ptr_type = get_pointer_to_type_extra(g, array_val->type->data.array.child_type, 5197 is_const, false, PtrLenUnknown, get_abi_alignment(g, array_val->type->data.array.child_type), 5198 0, 0); 5199 5200 const_val->special = ConstValSpecialStatic; 5201 const_val->type = get_slice_type(g, ptr_type); 5202 const_val->data.x_struct.fields = create_const_vals(2); 5203 5204 init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const, 5205 PtrLenUnknown); 5206 init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len); 5207 } 5208 5209 ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t start, size_t len, bool is_const) { 5210 ConstExprValue *const_val = create_const_vals(1); 5211 init_const_slice(g, const_val, array_val, start, len, is_const); 5212 return const_val; 5213 } 5214 5215 void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val, 5216 size_t elem_index, bool is_const, PtrLen ptr_len) 5217 { 5218 assert(array_val->type->id == TypeTableEntryIdArray); 5219 TypeTableEntry *child_type = array_val->type->data.array.child_type; 5220 5221 const_val->special = ConstValSpecialStatic; 5222 const_val->type = get_pointer_to_type_extra(g, child_type, is_const, false, 5223 ptr_len, get_abi_alignment(g, child_type), 0, 0); 5224 const_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 5225 const_val->data.x_ptr.data.base_array.array_val = array_val; 5226 const_val->data.x_ptr.data.base_array.elem_index = elem_index; 5227 } 5228 5229 ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const, 5230 PtrLen ptr_len) 5231 { 5232 ConstExprValue *const_val = create_const_vals(1); 5233 init_const_ptr_array(g, const_val, array_val, elem_index, is_const, ptr_len); 5234 return const_val; 5235 } 5236 5237 void init_const_ptr_ref(CodeGen *g, ConstExprValue *const_val, ConstExprValue *pointee_val, bool is_const) { 5238 const_val->special = ConstValSpecialStatic; 5239 const_val->type = get_pointer_to_type(g, pointee_val->type, is_const); 5240 const_val->data.x_ptr.special = ConstPtrSpecialRef; 5241 const_val->data.x_ptr.data.ref.pointee = pointee_val; 5242 } 5243 5244 ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bool is_const) { 5245 ConstExprValue *const_val = create_const_vals(1); 5246 init_const_ptr_ref(g, const_val, pointee_val, is_const); 5247 return const_val; 5248 } 5249 5250 void init_const_ptr_hard_coded_addr(CodeGen *g, ConstExprValue *const_val, TypeTableEntry *pointee_type, 5251 size_t addr, bool is_const) 5252 { 5253 const_val->special = ConstValSpecialStatic; 5254 const_val->type = get_pointer_to_type(g, pointee_type, is_const); 5255 const_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 5256 const_val->data.x_ptr.data.hard_coded_addr.addr = addr; 5257 } 5258 5259 ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, TypeTableEntry *pointee_type, 5260 size_t addr, bool is_const) 5261 { 5262 ConstExprValue *const_val = create_const_vals(1); 5263 init_const_ptr_hard_coded_addr(g, const_val, pointee_type, addr, is_const); 5264 return const_val; 5265 } 5266 5267 void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end) { 5268 const_val->special = ConstValSpecialStatic; 5269 const_val->type = g->builtin_types.entry_arg_tuple; 5270 const_val->data.x_arg_tuple.start_index = arg_index_start; 5271 const_val->data.x_arg_tuple.end_index = arg_index_end; 5272 } 5273 5274 ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end) { 5275 ConstExprValue *const_val = create_const_vals(1); 5276 init_const_arg_tuple(g, const_val, arg_index_start, arg_index_end); 5277 return const_val; 5278 } 5279 5280 5281 void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { 5282 TypeTableEntry *wanted_type = const_val->type; 5283 if (wanted_type->id == TypeTableEntryIdArray) { 5284 const_val->special = ConstValSpecialStatic; 5285 const_val->data.x_array.special = ConstArraySpecialUndef; 5286 } else if (wanted_type->id == TypeTableEntryIdStruct) { 5287 ensure_complete_type(g, wanted_type); 5288 if (type_is_invalid(wanted_type)) { 5289 return; 5290 } 5291 5292 const_val->special = ConstValSpecialStatic; 5293 size_t field_count = wanted_type->data.structure.src_field_count; 5294 const_val->data.x_struct.fields = create_const_vals(field_count); 5295 for (size_t i = 0; i < field_count; i += 1) { 5296 ConstExprValue *field_val = &const_val->data.x_struct.fields[i]; 5297 field_val->type = wanted_type->data.structure.fields[i].type_entry; 5298 assert(field_val->type); 5299 init_const_undefined(g, field_val); 5300 ConstParent *parent = get_const_val_parent(g, field_val); 5301 if (parent != nullptr) { 5302 parent->id = ConstParentIdStruct; 5303 parent->data.p_struct.struct_val = const_val; 5304 parent->data.p_struct.field_index = i; 5305 } 5306 } 5307 } else { 5308 const_val->special = ConstValSpecialUndef; 5309 } 5310 } 5311 5312 ConstExprValue *create_const_vals(size_t count) { 5313 ConstGlobalRefs *global_refs = allocate<ConstGlobalRefs>(count); 5314 ConstExprValue *vals = allocate<ConstExprValue>(count); 5315 for (size_t i = 0; i < count; i += 1) { 5316 vals[i].global_refs = &global_refs[i]; 5317 } 5318 return vals; 5319 } 5320 5321 void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) { 5322 if (type_entry->id == TypeTableEntryIdStruct) { 5323 if (!type_entry->data.structure.complete) 5324 resolve_struct_type(g, type_entry); 5325 } else if (type_entry->id == TypeTableEntryIdEnum) { 5326 if (!type_entry->data.enumeration.complete) 5327 resolve_enum_type(g, type_entry); 5328 } else if (type_entry->id == TypeTableEntryIdUnion) { 5329 if (!type_entry->data.unionation.complete) 5330 resolve_union_type(g, type_entry); 5331 } 5332 } 5333 5334 void type_ensure_zero_bits_known(CodeGen *g, TypeTableEntry *type_entry) { 5335 if (type_entry->id == TypeTableEntryIdStruct) { 5336 resolve_struct_zero_bits(g, type_entry); 5337 } else if (type_entry->id == TypeTableEntryIdEnum) { 5338 resolve_enum_zero_bits(g, type_entry); 5339 } else if (type_entry->id == TypeTableEntryIdUnion) { 5340 resolve_union_zero_bits(g, type_entry); 5341 } 5342 } 5343 5344 bool ir_get_var_is_comptime(VariableTableEntry *var) { 5345 if (!var->is_comptime) 5346 return false; 5347 if (var->is_comptime->other) 5348 return var->is_comptime->other->value.data.x_bool; 5349 return var->is_comptime->value.data.x_bool; 5350 } 5351 5352 bool const_values_equal_ptr(ConstExprValue *a, ConstExprValue *b) { 5353 if (a->data.x_ptr.special != b->data.x_ptr.special) 5354 return false; 5355 if (a->data.x_ptr.mut != b->data.x_ptr.mut) 5356 return false; 5357 switch (a->data.x_ptr.special) { 5358 case ConstPtrSpecialInvalid: 5359 zig_unreachable(); 5360 case ConstPtrSpecialRef: 5361 if (a->data.x_ptr.data.ref.pointee != b->data.x_ptr.data.ref.pointee) 5362 return false; 5363 return true; 5364 case ConstPtrSpecialBaseArray: 5365 if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val && 5366 a->data.x_ptr.data.base_array.array_val->global_refs != 5367 b->data.x_ptr.data.base_array.array_val->global_refs) 5368 { 5369 return false; 5370 } 5371 if (a->data.x_ptr.data.base_array.elem_index != b->data.x_ptr.data.base_array.elem_index) 5372 return false; 5373 if (a->data.x_ptr.data.base_array.is_cstr != b->data.x_ptr.data.base_array.is_cstr) 5374 return false; 5375 return true; 5376 case ConstPtrSpecialBaseStruct: 5377 if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val && 5378 a->data.x_ptr.data.base_struct.struct_val->global_refs != 5379 b->data.x_ptr.data.base_struct.struct_val->global_refs) 5380 { 5381 return false; 5382 } 5383 if (a->data.x_ptr.data.base_struct.field_index != b->data.x_ptr.data.base_struct.field_index) 5384 return false; 5385 return true; 5386 case ConstPtrSpecialHardCodedAddr: 5387 if (a->data.x_ptr.data.hard_coded_addr.addr != b->data.x_ptr.data.hard_coded_addr.addr) 5388 return false; 5389 return true; 5390 case ConstPtrSpecialDiscard: 5391 return true; 5392 case ConstPtrSpecialFunction: 5393 return a->data.x_ptr.data.fn.fn_entry == b->data.x_ptr.data.fn.fn_entry; 5394 } 5395 zig_unreachable(); 5396 } 5397 5398 bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { 5399 assert(a->type->id == b->type->id); 5400 assert(a->special == ConstValSpecialStatic); 5401 assert(b->special == ConstValSpecialStatic); 5402 switch (a->type->id) { 5403 case TypeTableEntryIdOpaque: 5404 zig_unreachable(); 5405 case TypeTableEntryIdEnum: 5406 return bigint_cmp(&a->data.x_enum_tag, &b->data.x_enum_tag) == CmpEQ; 5407 case TypeTableEntryIdUnion: { 5408 ConstUnionValue *union1 = &a->data.x_union; 5409 ConstUnionValue *union2 = &b->data.x_union; 5410 5411 if (bigint_cmp(&union1->tag, &union2->tag) == CmpEQ) { 5412 TypeUnionField *field = find_union_field_by_tag(a->type, &union1->tag); 5413 assert(field != nullptr); 5414 if (type_has_bits(field->type_entry)) { 5415 zig_panic("TODO const expr analyze union field value for equality"); 5416 } else { 5417 return true; 5418 } 5419 } 5420 return false; 5421 } 5422 case TypeTableEntryIdMetaType: 5423 return a->data.x_type == b->data.x_type; 5424 case TypeTableEntryIdVoid: 5425 return true; 5426 case TypeTableEntryIdErrorSet: 5427 return a->data.x_err_set->value == b->data.x_err_set->value; 5428 case TypeTableEntryIdBool: 5429 return a->data.x_bool == b->data.x_bool; 5430 case TypeTableEntryIdFloat: 5431 assert(a->type->data.floating.bit_count == b->type->data.floating.bit_count); 5432 switch (a->type->data.floating.bit_count) { 5433 case 32: 5434 return a->data.x_f32 == b->data.x_f32; 5435 case 64: 5436 return a->data.x_f64 == b->data.x_f64; 5437 case 128: 5438 return f128M_eq(&a->data.x_f128, &b->data.x_f128); 5439 default: 5440 zig_unreachable(); 5441 } 5442 case TypeTableEntryIdComptimeFloat: 5443 return bigfloat_cmp(&a->data.x_bigfloat, &b->data.x_bigfloat) == CmpEQ; 5444 case TypeTableEntryIdInt: 5445 case TypeTableEntryIdComptimeInt: 5446 return bigint_cmp(&a->data.x_bigint, &b->data.x_bigint) == CmpEQ; 5447 case TypeTableEntryIdPointer: 5448 case TypeTableEntryIdFn: 5449 return const_values_equal_ptr(a, b); 5450 case TypeTableEntryIdArray: 5451 zig_panic("TODO"); 5452 case TypeTableEntryIdStruct: 5453 for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) { 5454 ConstExprValue *field_a = &a->data.x_struct.fields[i]; 5455 ConstExprValue *field_b = &b->data.x_struct.fields[i]; 5456 if (!const_values_equal(field_a, field_b)) 5457 return false; 5458 } 5459 return true; 5460 case TypeTableEntryIdUndefined: 5461 zig_panic("TODO"); 5462 case TypeTableEntryIdNull: 5463 zig_panic("TODO"); 5464 case TypeTableEntryIdOptional: 5465 if (get_codegen_ptr_type(a->type) != nullptr) 5466 return const_values_equal_ptr(a, b); 5467 if (a->data.x_optional == nullptr || b->data.x_optional == nullptr) { 5468 return (a->data.x_optional == nullptr && b->data.x_optional == nullptr); 5469 } else { 5470 return const_values_equal(a->data.x_optional, b->data.x_optional); 5471 } 5472 case TypeTableEntryIdErrorUnion: 5473 zig_panic("TODO"); 5474 case TypeTableEntryIdNamespace: 5475 return a->data.x_import == b->data.x_import; 5476 case TypeTableEntryIdBlock: 5477 return a->data.x_block == b->data.x_block; 5478 case TypeTableEntryIdArgTuple: 5479 return a->data.x_arg_tuple.start_index == b->data.x_arg_tuple.start_index && 5480 a->data.x_arg_tuple.end_index == b->data.x_arg_tuple.end_index; 5481 case TypeTableEntryIdBoundFn: 5482 case TypeTableEntryIdInvalid: 5483 case TypeTableEntryIdUnreachable: 5484 case TypeTableEntryIdPromise: 5485 zig_unreachable(); 5486 } 5487 zig_unreachable(); 5488 } 5489 5490 void eval_min_max_value_int(CodeGen *g, TypeTableEntry *int_type, BigInt *bigint, bool is_max) { 5491 assert(int_type->id == TypeTableEntryIdInt); 5492 if (int_type->data.integral.bit_count == 0) { 5493 bigint_init_unsigned(bigint, 0); 5494 return; 5495 } 5496 if (is_max) { 5497 // is_signed=true (1 << (bit_count - 1)) - 1 5498 // is_signed=false (1 << (bit_count - 0)) - 1 5499 BigInt one = {0}; 5500 bigint_init_unsigned(&one, 1); 5501 5502 size_t shift_amt = int_type->data.integral.bit_count - (int_type->data.integral.is_signed ? 1 : 0); 5503 BigInt bit_count_bi = {0}; 5504 bigint_init_unsigned(&bit_count_bi, shift_amt); 5505 5506 BigInt shifted_bi = {0}; 5507 bigint_shl(&shifted_bi, &one, &bit_count_bi); 5508 5509 bigint_sub(bigint, &shifted_bi, &one); 5510 } else if (int_type->data.integral.is_signed) { 5511 // - (1 << (bit_count - 1)) 5512 BigInt one = {0}; 5513 bigint_init_unsigned(&one, 1); 5514 5515 BigInt bit_count_bi = {0}; 5516 bigint_init_unsigned(&bit_count_bi, int_type->data.integral.bit_count - 1); 5517 5518 BigInt shifted_bi = {0}; 5519 bigint_shl(&shifted_bi, &one, &bit_count_bi); 5520 5521 bigint_negate(bigint, &shifted_bi); 5522 } else { 5523 bigint_init_unsigned(bigint, 0); 5524 } 5525 } 5526 5527 void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val, bool is_max) { 5528 if (type_entry->id == TypeTableEntryIdInt) { 5529 const_val->special = ConstValSpecialStatic; 5530 eval_min_max_value_int(g, type_entry, &const_val->data.x_bigint, is_max); 5531 } else if (type_entry->id == TypeTableEntryIdFloat) { 5532 zig_panic("TODO analyze_min_max_value float"); 5533 } else if (type_entry->id == TypeTableEntryIdBool) { 5534 const_val->special = ConstValSpecialStatic; 5535 const_val->data.x_bool = is_max; 5536 } else if (type_entry->id == TypeTableEntryIdVoid) { 5537 // nothing to do 5538 } else { 5539 zig_unreachable(); 5540 } 5541 } 5542 5543 void render_const_val_ptr(CodeGen *g, Buf *buf, ConstExprValue *const_val, TypeTableEntry *type_entry) { 5544 switch (const_val->data.x_ptr.special) { 5545 case ConstPtrSpecialInvalid: 5546 zig_unreachable(); 5547 case ConstPtrSpecialRef: 5548 case ConstPtrSpecialBaseStruct: 5549 buf_appendf(buf, "*"); 5550 render_const_value(g, buf, const_ptr_pointee(g, const_val)); 5551 return; 5552 case ConstPtrSpecialBaseArray: 5553 if (const_val->data.x_ptr.data.base_array.is_cstr) { 5554 buf_appendf(buf, "*(c str lit)"); 5555 return; 5556 } else { 5557 buf_appendf(buf, "*"); 5558 render_const_value(g, buf, const_ptr_pointee(g, const_val)); 5559 return; 5560 } 5561 case ConstPtrSpecialHardCodedAddr: 5562 buf_appendf(buf, "(*%s)(%" ZIG_PRI_x64 ")", buf_ptr(&type_entry->data.pointer.child_type->name), 5563 const_val->data.x_ptr.data.hard_coded_addr.addr); 5564 return; 5565 case ConstPtrSpecialDiscard: 5566 buf_append_str(buf, "*_"); 5567 return; 5568 case ConstPtrSpecialFunction: 5569 { 5570 FnTableEntry *fn_entry = const_val->data.x_ptr.data.fn.fn_entry; 5571 buf_appendf(buf, "@ptrCast(%s, %s)", buf_ptr(&const_val->type->name), buf_ptr(&fn_entry->symbol_name)); 5572 return; 5573 } 5574 } 5575 zig_unreachable(); 5576 } 5577 5578 void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { 5579 switch (const_val->special) { 5580 case ConstValSpecialRuntime: 5581 buf_appendf(buf, "(runtime value)"); 5582 return; 5583 case ConstValSpecialUndef: 5584 buf_appendf(buf, "undefined"); 5585 return; 5586 case ConstValSpecialStatic: 5587 break; 5588 } 5589 assert(const_val->type); 5590 5591 TypeTableEntry *type_entry = const_val->type; 5592 switch (type_entry->id) { 5593 case TypeTableEntryIdOpaque: 5594 zig_unreachable(); 5595 case TypeTableEntryIdInvalid: 5596 buf_appendf(buf, "(invalid)"); 5597 return; 5598 case TypeTableEntryIdVoid: 5599 buf_appendf(buf, "{}"); 5600 return; 5601 case TypeTableEntryIdComptimeFloat: 5602 bigfloat_append_buf(buf, &const_val->data.x_bigfloat); 5603 return; 5604 case TypeTableEntryIdFloat: 5605 switch (type_entry->data.floating.bit_count) { 5606 case 32: 5607 buf_appendf(buf, "%f", const_val->data.x_f32); 5608 return; 5609 case 64: 5610 buf_appendf(buf, "%f", const_val->data.x_f64); 5611 return; 5612 case 128: 5613 { 5614 const size_t extra_len = 100; 5615 size_t old_len = buf_len(buf); 5616 buf_resize(buf, old_len + extra_len); 5617 float64_t f64_value = f128M_to_f64(&const_val->data.x_f128); 5618 double double_value; 5619 memcpy(&double_value, &f64_value, sizeof(double)); 5620 // TODO actual f128 printing to decimal 5621 int len = snprintf(buf_ptr(buf) + old_len, extra_len, "%f", double_value); 5622 assert(len > 0); 5623 buf_resize(buf, old_len + len); 5624 return; 5625 } 5626 default: 5627 zig_unreachable(); 5628 } 5629 case TypeTableEntryIdComptimeInt: 5630 case TypeTableEntryIdInt: 5631 bigint_append_buf(buf, &const_val->data.x_bigint, 10); 5632 return; 5633 case TypeTableEntryIdMetaType: 5634 buf_appendf(buf, "%s", buf_ptr(&const_val->data.x_type->name)); 5635 return; 5636 case TypeTableEntryIdUnreachable: 5637 buf_appendf(buf, "unreachable"); 5638 return; 5639 case TypeTableEntryIdBool: 5640 { 5641 const char *value = const_val->data.x_bool ? "true" : "false"; 5642 buf_appendf(buf, "%s", value); 5643 return; 5644 } 5645 case TypeTableEntryIdFn: 5646 { 5647 assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst); 5648 assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction); 5649 FnTableEntry *fn_entry = const_val->data.x_ptr.data.fn.fn_entry; 5650 buf_appendf(buf, "%s", buf_ptr(&fn_entry->symbol_name)); 5651 return; 5652 } 5653 case TypeTableEntryIdPointer: 5654 return render_const_val_ptr(g, buf, const_val, type_entry); 5655 case TypeTableEntryIdBlock: 5656 { 5657 AstNode *node = const_val->data.x_block->source_node; 5658 buf_appendf(buf, "(scope:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ")", node->line + 1, node->column + 1); 5659 return; 5660 } 5661 case TypeTableEntryIdArray: 5662 { 5663 TypeTableEntry *child_type = type_entry->data.array.child_type; 5664 uint64_t len = type_entry->data.array.len; 5665 5666 if (const_val->data.x_array.special == ConstArraySpecialUndef) { 5667 buf_append_str(buf, "undefined"); 5668 return; 5669 } 5670 5671 // if it's []u8, assume UTF-8 and output a string 5672 if (child_type->id == TypeTableEntryIdInt && 5673 child_type->data.integral.bit_count == 8 && 5674 !child_type->data.integral.is_signed) 5675 { 5676 buf_append_char(buf, '"'); 5677 for (uint64_t i = 0; i < len; i += 1) { 5678 ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i]; 5679 uint64_t big_c = bigint_as_unsigned(&child_value->data.x_bigint); 5680 assert(big_c <= UINT8_MAX); 5681 uint8_t c = (uint8_t)big_c; 5682 if (c == '"') { 5683 buf_append_str(buf, "\\\""); 5684 } else { 5685 buf_append_char(buf, c); 5686 } 5687 } 5688 buf_append_char(buf, '"'); 5689 return; 5690 } 5691 5692 buf_appendf(buf, "%s{", buf_ptr(&type_entry->name)); 5693 for (uint64_t i = 0; i < len; i += 1) { 5694 if (i != 0) 5695 buf_appendf(buf, ","); 5696 ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i]; 5697 render_const_value(g, buf, child_value); 5698 } 5699 buf_appendf(buf, "}"); 5700 return; 5701 } 5702 case TypeTableEntryIdNull: 5703 { 5704 buf_appendf(buf, "null"); 5705 return; 5706 } 5707 case TypeTableEntryIdUndefined: 5708 { 5709 buf_appendf(buf, "undefined"); 5710 return; 5711 } 5712 case TypeTableEntryIdOptional: 5713 { 5714 if (get_codegen_ptr_type(const_val->type) != nullptr) 5715 return render_const_val_ptr(g, buf, const_val, type_entry->data.maybe.child_type); 5716 if (const_val->data.x_optional) { 5717 render_const_value(g, buf, const_val->data.x_optional); 5718 } else { 5719 buf_appendf(buf, "null"); 5720 } 5721 return; 5722 } 5723 case TypeTableEntryIdNamespace: 5724 { 5725 ImportTableEntry *import = const_val->data.x_import; 5726 if (import->c_import_node) { 5727 buf_appendf(buf, "(namespace from C import)"); 5728 } else { 5729 buf_appendf(buf, "(namespace: %s)", buf_ptr(import->path)); 5730 } 5731 return; 5732 } 5733 case TypeTableEntryIdBoundFn: 5734 { 5735 FnTableEntry *fn_entry = const_val->data.x_bound_fn.fn; 5736 buf_appendf(buf, "(bound fn %s)", buf_ptr(&fn_entry->symbol_name)); 5737 return; 5738 } 5739 case TypeTableEntryIdStruct: 5740 { 5741 buf_appendf(buf, "(struct %s constant)", buf_ptr(&type_entry->name)); 5742 return; 5743 } 5744 case TypeTableEntryIdEnum: 5745 { 5746 TypeEnumField *field = find_enum_field_by_tag(type_entry, &const_val->data.x_enum_tag); 5747 buf_appendf(buf, "%s.%s", buf_ptr(&type_entry->name), buf_ptr(field->name)); 5748 return; 5749 } 5750 case TypeTableEntryIdErrorUnion: 5751 { 5752 buf_appendf(buf, "(error union %s constant)", buf_ptr(&type_entry->name)); 5753 return; 5754 } 5755 case TypeTableEntryIdUnion: 5756 { 5757 buf_appendf(buf, "(union %s constant)", buf_ptr(&type_entry->name)); 5758 return; 5759 } 5760 case TypeTableEntryIdErrorSet: 5761 { 5762 buf_appendf(buf, "%s.%s", buf_ptr(&type_entry->name), buf_ptr(&const_val->data.x_err_set->name)); 5763 return; 5764 } 5765 case TypeTableEntryIdArgTuple: 5766 { 5767 buf_appendf(buf, "(args value)"); 5768 return; 5769 } 5770 case TypeTableEntryIdPromise: 5771 zig_unreachable(); 5772 } 5773 zig_unreachable(); 5774 } 5775 5776 TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) { 5777 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); 5778 entry->is_copyable = true; 5779 entry->type_ref = (size_in_bits == 0) ? LLVMVoidType() : LLVMIntType(size_in_bits); 5780 entry->zero_bits = (size_in_bits == 0); 5781 5782 const char u_or_i = is_signed ? 'i' : 'u'; 5783 buf_resize(&entry->name, 0); 5784 buf_appendf(&entry->name, "%c%" PRIu32, u_or_i, size_in_bits); 5785 5786 unsigned dwarf_tag; 5787 if (is_signed) { 5788 if (size_in_bits == 8) { 5789 dwarf_tag = ZigLLVMEncoding_DW_ATE_signed_char(); 5790 } else { 5791 dwarf_tag = ZigLLVMEncoding_DW_ATE_signed(); 5792 } 5793 } else { 5794 if (size_in_bits == 8) { 5795 dwarf_tag = ZigLLVMEncoding_DW_ATE_unsigned_char(); 5796 } else { 5797 dwarf_tag = ZigLLVMEncoding_DW_ATE_unsigned(); 5798 } 5799 } 5800 5801 uint64_t debug_size_in_bits = (size_in_bits == 0) ? 5802 0 : (8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref)); 5803 entry->di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), debug_size_in_bits, dwarf_tag); 5804 entry->data.integral.is_signed = is_signed; 5805 entry->data.integral.bit_count = size_in_bits; 5806 return entry; 5807 } 5808 5809 uint32_t type_id_hash(TypeId x) { 5810 switch (x.id) { 5811 case TypeTableEntryIdInvalid: 5812 case TypeTableEntryIdOpaque: 5813 case TypeTableEntryIdMetaType: 5814 case TypeTableEntryIdVoid: 5815 case TypeTableEntryIdBool: 5816 case TypeTableEntryIdUnreachable: 5817 case TypeTableEntryIdFloat: 5818 case TypeTableEntryIdStruct: 5819 case TypeTableEntryIdComptimeFloat: 5820 case TypeTableEntryIdComptimeInt: 5821 case TypeTableEntryIdUndefined: 5822 case TypeTableEntryIdNull: 5823 case TypeTableEntryIdOptional: 5824 case TypeTableEntryIdErrorSet: 5825 case TypeTableEntryIdEnum: 5826 case TypeTableEntryIdUnion: 5827 case TypeTableEntryIdFn: 5828 case TypeTableEntryIdNamespace: 5829 case TypeTableEntryIdBlock: 5830 case TypeTableEntryIdBoundFn: 5831 case TypeTableEntryIdArgTuple: 5832 case TypeTableEntryIdPromise: 5833 zig_unreachable(); 5834 case TypeTableEntryIdErrorUnion: 5835 return hash_ptr(x.data.error_union.err_set_type) ^ hash_ptr(x.data.error_union.payload_type); 5836 case TypeTableEntryIdPointer: 5837 return hash_ptr(x.data.pointer.child_type) + 5838 ((x.data.pointer.ptr_len == PtrLenSingle) ? (uint32_t)1120226602 : (uint32_t)3200913342) + 5839 (x.data.pointer.is_const ? (uint32_t)2749109194 : (uint32_t)4047371087) + 5840 (x.data.pointer.is_volatile ? (uint32_t)536730450 : (uint32_t)1685612214) + 5841 (((uint32_t)x.data.pointer.alignment) ^ (uint32_t)0x777fbe0e) + 5842 (((uint32_t)x.data.pointer.bit_offset) ^ (uint32_t)2639019452) + 5843 (((uint32_t)x.data.pointer.unaligned_bit_count) ^ (uint32_t)529908881); 5844 case TypeTableEntryIdArray: 5845 return hash_ptr(x.data.array.child_type) + 5846 ((uint32_t)x.data.array.size ^ (uint32_t)2122979968); 5847 case TypeTableEntryIdInt: 5848 return (x.data.integer.is_signed ? (uint32_t)2652528194 : (uint32_t)163929201) + 5849 (((uint32_t)x.data.integer.bit_count) ^ (uint32_t)2998081557); 5850 } 5851 zig_unreachable(); 5852 } 5853 5854 bool type_id_eql(TypeId a, TypeId b) { 5855 if (a.id != b.id) 5856 return false; 5857 switch (a.id) { 5858 case TypeTableEntryIdInvalid: 5859 case TypeTableEntryIdMetaType: 5860 case TypeTableEntryIdVoid: 5861 case TypeTableEntryIdBool: 5862 case TypeTableEntryIdUnreachable: 5863 case TypeTableEntryIdFloat: 5864 case TypeTableEntryIdStruct: 5865 case TypeTableEntryIdComptimeFloat: 5866 case TypeTableEntryIdComptimeInt: 5867 case TypeTableEntryIdUndefined: 5868 case TypeTableEntryIdNull: 5869 case TypeTableEntryIdOptional: 5870 case TypeTableEntryIdPromise: 5871 case TypeTableEntryIdErrorSet: 5872 case TypeTableEntryIdEnum: 5873 case TypeTableEntryIdUnion: 5874 case TypeTableEntryIdFn: 5875 case TypeTableEntryIdNamespace: 5876 case TypeTableEntryIdBlock: 5877 case TypeTableEntryIdBoundFn: 5878 case TypeTableEntryIdArgTuple: 5879 case TypeTableEntryIdOpaque: 5880 zig_unreachable(); 5881 case TypeTableEntryIdErrorUnion: 5882 return a.data.error_union.err_set_type == b.data.error_union.err_set_type && 5883 a.data.error_union.payload_type == b.data.error_union.payload_type; 5884 5885 case TypeTableEntryIdPointer: 5886 return a.data.pointer.child_type == b.data.pointer.child_type && 5887 a.data.pointer.ptr_len == b.data.pointer.ptr_len && 5888 a.data.pointer.is_const == b.data.pointer.is_const && 5889 a.data.pointer.is_volatile == b.data.pointer.is_volatile && 5890 a.data.pointer.alignment == b.data.pointer.alignment && 5891 a.data.pointer.bit_offset == b.data.pointer.bit_offset && 5892 a.data.pointer.unaligned_bit_count == b.data.pointer.unaligned_bit_count; 5893 case TypeTableEntryIdArray: 5894 return a.data.array.child_type == b.data.array.child_type && 5895 a.data.array.size == b.data.array.size; 5896 case TypeTableEntryIdInt: 5897 return a.data.integer.is_signed == b.data.integer.is_signed && 5898 a.data.integer.bit_count == b.data.integer.bit_count; 5899 } 5900 zig_unreachable(); 5901 } 5902 5903 uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) { 5904 switch (x.id) { 5905 case ZigLLVMFnIdCtz: 5906 return (uint32_t)(x.data.ctz.bit_count) * (uint32_t)810453934; 5907 case ZigLLVMFnIdClz: 5908 return (uint32_t)(x.data.clz.bit_count) * (uint32_t)2428952817; 5909 case ZigLLVMFnIdFloor: 5910 return (uint32_t)(x.data.floating.bit_count) * (uint32_t)1899859168; 5911 case ZigLLVMFnIdCeil: 5912 return (uint32_t)(x.data.floating.bit_count) * (uint32_t)1953839089; 5913 case ZigLLVMFnIdSqrt: 5914 return (uint32_t)(x.data.floating.bit_count) * (uint32_t)2225366385; 5915 case ZigLLVMFnIdOverflowArithmetic: 5916 return ((uint32_t)(x.data.overflow_arithmetic.bit_count) * 87135777) + 5917 ((uint32_t)(x.data.overflow_arithmetic.add_sub_mul) * 31640542) + 5918 ((uint32_t)(x.data.overflow_arithmetic.is_signed) ? 1062315172 : 314955820); 5919 } 5920 zig_unreachable(); 5921 } 5922 5923 bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) { 5924 if (a.id != b.id) 5925 return false; 5926 switch (a.id) { 5927 case ZigLLVMFnIdCtz: 5928 return a.data.ctz.bit_count == b.data.ctz.bit_count; 5929 case ZigLLVMFnIdClz: 5930 return a.data.clz.bit_count == b.data.clz.bit_count; 5931 case ZigLLVMFnIdFloor: 5932 case ZigLLVMFnIdCeil: 5933 case ZigLLVMFnIdSqrt: 5934 return a.data.floating.bit_count == b.data.floating.bit_count; 5935 case ZigLLVMFnIdOverflowArithmetic: 5936 return (a.data.overflow_arithmetic.bit_count == b.data.overflow_arithmetic.bit_count) && 5937 (a.data.overflow_arithmetic.add_sub_mul == b.data.overflow_arithmetic.add_sub_mul) && 5938 (a.data.overflow_arithmetic.is_signed == b.data.overflow_arithmetic.is_signed); 5939 } 5940 zig_unreachable(); 5941 } 5942 5943 void expand_undef_array(CodeGen *g, ConstExprValue *const_val) { 5944 assert(const_val->type->id == TypeTableEntryIdArray); 5945 if (const_val->data.x_array.special == ConstArraySpecialUndef) { 5946 const_val->data.x_array.special = ConstArraySpecialNone; 5947 size_t elem_count = const_val->type->data.array.len; 5948 const_val->data.x_array.s_none.elements = create_const_vals(elem_count); 5949 for (size_t i = 0; i < elem_count; i += 1) { 5950 ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i]; 5951 element_val->type = const_val->type->data.array.child_type; 5952 init_const_undefined(g, element_val); 5953 ConstParent *parent = get_const_val_parent(g, element_val); 5954 if (parent != nullptr) { 5955 parent->id = ConstParentIdArray; 5956 parent->data.p_array.array_val = const_val; 5957 parent->data.p_array.elem_index = i; 5958 } 5959 } 5960 } 5961 } 5962 5963 ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) { 5964 assert(value->type); 5965 TypeTableEntry *type_entry = value->type; 5966 if (type_entry->id == TypeTableEntryIdArray) { 5967 expand_undef_array(g, value); 5968 return &value->data.x_array.s_none.parent; 5969 } else if (type_entry->id == TypeTableEntryIdStruct) { 5970 return &value->data.x_struct.parent; 5971 } else if (type_entry->id == TypeTableEntryIdUnion) { 5972 return &value->data.x_union.parent; 5973 } 5974 return nullptr; 5975 } 5976 5977 static const TypeTableEntryId all_type_ids[] = { 5978 TypeTableEntryIdMetaType, 5979 TypeTableEntryIdVoid, 5980 TypeTableEntryIdBool, 5981 TypeTableEntryIdUnreachable, 5982 TypeTableEntryIdInt, 5983 TypeTableEntryIdFloat, 5984 TypeTableEntryIdPointer, 5985 TypeTableEntryIdArray, 5986 TypeTableEntryIdStruct, 5987 TypeTableEntryIdComptimeFloat, 5988 TypeTableEntryIdComptimeInt, 5989 TypeTableEntryIdUndefined, 5990 TypeTableEntryIdNull, 5991 TypeTableEntryIdOptional, 5992 TypeTableEntryIdErrorUnion, 5993 TypeTableEntryIdErrorSet, 5994 TypeTableEntryIdEnum, 5995 TypeTableEntryIdUnion, 5996 TypeTableEntryIdFn, 5997 TypeTableEntryIdNamespace, 5998 TypeTableEntryIdBlock, 5999 TypeTableEntryIdBoundFn, 6000 TypeTableEntryIdArgTuple, 6001 TypeTableEntryIdOpaque, 6002 TypeTableEntryIdPromise, 6003 }; 6004 6005 TypeTableEntryId type_id_at_index(size_t index) { 6006 assert(index < array_length(all_type_ids)); 6007 return all_type_ids[index]; 6008 } 6009 6010 size_t type_id_len() { 6011 return array_length(all_type_ids); 6012 } 6013 6014 size_t type_id_index(TypeTableEntry *entry) { 6015 switch (entry->id) { 6016 case TypeTableEntryIdInvalid: 6017 zig_unreachable(); 6018 case TypeTableEntryIdMetaType: 6019 return 0; 6020 case TypeTableEntryIdVoid: 6021 return 1; 6022 case TypeTableEntryIdBool: 6023 return 2; 6024 case TypeTableEntryIdUnreachable: 6025 return 3; 6026 case TypeTableEntryIdInt: 6027 return 4; 6028 case TypeTableEntryIdFloat: 6029 return 5; 6030 case TypeTableEntryIdPointer: 6031 return 6; 6032 case TypeTableEntryIdArray: 6033 return 7; 6034 case TypeTableEntryIdStruct: 6035 if (entry->data.structure.is_slice) 6036 return 6; 6037 return 8; 6038 case TypeTableEntryIdComptimeFloat: 6039 return 9; 6040 case TypeTableEntryIdComptimeInt: 6041 return 10; 6042 case TypeTableEntryIdUndefined: 6043 return 11; 6044 case TypeTableEntryIdNull: 6045 return 12; 6046 case TypeTableEntryIdOptional: 6047 return 13; 6048 case TypeTableEntryIdErrorUnion: 6049 return 14; 6050 case TypeTableEntryIdErrorSet: 6051 return 15; 6052 case TypeTableEntryIdEnum: 6053 return 16; 6054 case TypeTableEntryIdUnion: 6055 return 17; 6056 case TypeTableEntryIdFn: 6057 return 18; 6058 case TypeTableEntryIdNamespace: 6059 return 19; 6060 case TypeTableEntryIdBlock: 6061 return 20; 6062 case TypeTableEntryIdBoundFn: 6063 return 21; 6064 case TypeTableEntryIdArgTuple: 6065 return 22; 6066 case TypeTableEntryIdOpaque: 6067 return 23; 6068 case TypeTableEntryIdPromise: 6069 return 24; 6070 } 6071 zig_unreachable(); 6072 } 6073 6074 const char *type_id_name(TypeTableEntryId id) { 6075 switch (id) { 6076 case TypeTableEntryIdInvalid: 6077 zig_unreachable(); 6078 case TypeTableEntryIdMetaType: 6079 return "Type"; 6080 case TypeTableEntryIdVoid: 6081 return "Void"; 6082 case TypeTableEntryIdBool: 6083 return "Bool"; 6084 case TypeTableEntryIdUnreachable: 6085 return "NoReturn"; 6086 case TypeTableEntryIdInt: 6087 return "Int"; 6088 case TypeTableEntryIdFloat: 6089 return "Float"; 6090 case TypeTableEntryIdPointer: 6091 return "Pointer"; 6092 case TypeTableEntryIdArray: 6093 return "Array"; 6094 case TypeTableEntryIdStruct: 6095 return "Struct"; 6096 case TypeTableEntryIdComptimeFloat: 6097 return "ComptimeFloat"; 6098 case TypeTableEntryIdComptimeInt: 6099 return "ComptimeInt"; 6100 case TypeTableEntryIdUndefined: 6101 return "Undefined"; 6102 case TypeTableEntryIdNull: 6103 return "Null"; 6104 case TypeTableEntryIdOptional: 6105 return "Optional"; 6106 case TypeTableEntryIdErrorUnion: 6107 return "ErrorUnion"; 6108 case TypeTableEntryIdErrorSet: 6109 return "ErrorSet"; 6110 case TypeTableEntryIdEnum: 6111 return "Enum"; 6112 case TypeTableEntryIdUnion: 6113 return "Union"; 6114 case TypeTableEntryIdFn: 6115 return "Fn"; 6116 case TypeTableEntryIdNamespace: 6117 return "Namespace"; 6118 case TypeTableEntryIdBlock: 6119 return "Block"; 6120 case TypeTableEntryIdBoundFn: 6121 return "BoundFn"; 6122 case TypeTableEntryIdArgTuple: 6123 return "ArgTuple"; 6124 case TypeTableEntryIdOpaque: 6125 return "Opaque"; 6126 case TypeTableEntryIdPromise: 6127 return "Promise"; 6128 } 6129 zig_unreachable(); 6130 } 6131 6132 LinkLib *create_link_lib(Buf *name) { 6133 LinkLib *link_lib = allocate<LinkLib>(1); 6134 link_lib->name = name; 6135 return link_lib; 6136 } 6137 6138 LinkLib *add_link_lib(CodeGen *g, Buf *name) { 6139 bool is_libc = buf_eql_str(name, "c"); 6140 6141 if (is_libc && g->libc_link_lib != nullptr) 6142 return g->libc_link_lib; 6143 6144 for (size_t i = 0; i < g->link_libs_list.length; i += 1) { 6145 LinkLib *existing_lib = g->link_libs_list.at(i); 6146 if (buf_eql_buf(existing_lib->name, name)) { 6147 return existing_lib; 6148 } 6149 } 6150 6151 LinkLib *link_lib = create_link_lib(name); 6152 g->link_libs_list.append(link_lib); 6153 6154 if (is_libc) 6155 g->libc_link_lib = link_lib; 6156 6157 return link_lib; 6158 } 6159 6160 uint32_t get_abi_alignment(CodeGen *g, TypeTableEntry *type_entry) { 6161 type_ensure_zero_bits_known(g, type_entry); 6162 if (type_entry->zero_bits) return 0; 6163 6164 // We need to make this function work without requiring ensure_complete_type 6165 // so that we can have structs with fields that are pointers to their own type. 6166 if (type_entry->id == TypeTableEntryIdStruct) { 6167 assert(type_entry->data.structure.abi_alignment != 0); 6168 return type_entry->data.structure.abi_alignment; 6169 } else if (type_entry->id == TypeTableEntryIdUnion) { 6170 assert(type_entry->data.unionation.abi_alignment != 0); 6171 return type_entry->data.unionation.abi_alignment; 6172 } else if (type_entry->id == TypeTableEntryIdOpaque) { 6173 return 1; 6174 } else { 6175 return LLVMABIAlignmentOfType(g->target_data_ref, type_entry->type_ref); 6176 } 6177 } 6178 6179 TypeTableEntry *get_align_amt_type(CodeGen *g) { 6180 if (g->align_amt_type == nullptr) { 6181 // according to LLVM the maximum alignment is 1 << 29. 6182 g->align_amt_type = get_int_type(g, false, 29); 6183 } 6184 return g->align_amt_type; 6185 } 6186 6187 uint32_t type_ptr_hash(const TypeTableEntry *ptr) { 6188 return hash_ptr((void*)ptr); 6189 } 6190 6191 bool type_ptr_eql(const TypeTableEntry *a, const TypeTableEntry *b) { 6192 return a == b; 6193 } 6194 6195 ConstExprValue *get_builtin_value(CodeGen *codegen, const char *name) { 6196 Tld *tld = codegen->compile_var_import->decls_scope->decl_table.get(buf_create_from_str(name)); 6197 resolve_top_level_decl(codegen, tld, false, nullptr); 6198 assert(tld->id == TldIdVar); 6199 TldVar *tld_var = (TldVar *)tld; 6200 ConstExprValue *var_value = tld_var->var->value; 6201 assert(var_value != nullptr); 6202 return var_value; 6203 } 6204 6205 bool type_is_global_error_set(TypeTableEntry *err_set_type) { 6206 assert(err_set_type->id == TypeTableEntryIdErrorSet); 6207 assert(err_set_type->data.error_set.infer_fn == nullptr); 6208 return err_set_type->data.error_set.err_count == UINT32_MAX; 6209 } 6210 6211 uint32_t get_coro_frame_align_bytes(CodeGen *g) { 6212 return g->pointer_size_bytes * 2; 6213 } 6214 6215 bool type_can_fail(TypeTableEntry *type_entry) { 6216 return type_entry->id == TypeTableEntryIdErrorUnion || type_entry->id == TypeTableEntryIdErrorSet; 6217 } 6218 6219 bool fn_type_can_fail(FnTypeId *fn_type_id) { 6220 return type_can_fail(fn_type_id->return_type) || fn_type_id->cc == CallingConventionAsync; 6221 }