blob d7545351 (170016B) - 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 "zig_llvm.hpp" 17 18 static const size_t default_backward_branch_quota = 1000; 19 20 static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type); 21 static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type); 22 23 static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type); 24 static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type); 25 static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type); 26 27 ErrorMsg *add_node_error(CodeGen *g, AstNode *node, Buf *msg) { 28 // if this assert fails, then parseh generated code that 29 // failed semantic analysis, which isn't supposed to happen 30 assert(!node->owner->c_import_node); 31 32 ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column, 33 node->owner->source_code, node->owner->line_offsets, msg); 34 35 g->errors.append(err); 36 return err; 37 } 38 39 ErrorMsg *add_error_note(CodeGen *g, ErrorMsg *parent_msg, AstNode *node, Buf *msg) { 40 // if this assert fails, then parseh generated code that 41 // failed semantic analysis, which isn't supposed to happen 42 assert(!node->owner->c_import_node); 43 44 ErrorMsg *err = err_msg_create_with_line(node->owner->path, node->line, node->column, 45 node->owner->source_code, node->owner->line_offsets, msg); 46 47 err_msg_add_note(parent_msg, err); 48 return err; 49 } 50 51 TypeTableEntry *new_type_table_entry(TypeTableEntryId id) { 52 TypeTableEntry *entry = allocate<TypeTableEntry>(1); 53 entry->id = id; 54 return entry; 55 } 56 57 static ScopeDecls **get_container_scope_ptr(TypeTableEntry *type_entry) { 58 if (type_entry->id == TypeTableEntryIdStruct) { 59 return &type_entry->data.structure.decls_scope; 60 } else if (type_entry->id == TypeTableEntryIdEnum) { 61 return &type_entry->data.enumeration.decls_scope; 62 } else if (type_entry->id == TypeTableEntryIdUnion) { 63 return &type_entry->data.unionation.decls_scope; 64 } 65 zig_unreachable(); 66 } 67 68 ScopeDecls *get_container_scope(TypeTableEntry *type_entry) { 69 return *get_container_scope_ptr(type_entry); 70 } 71 72 void init_scope(Scope *dest, ScopeId id, AstNode *source_node, Scope *parent) { 73 dest->id = id; 74 dest->source_node = source_node; 75 dest->parent = parent; 76 } 77 78 ScopeDecls *create_decls_scope(AstNode *node, Scope *parent, TypeTableEntry *container_type, ImportTableEntry *import) { 79 assert(node == nullptr || node->type == NodeTypeRoot || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr); 80 ScopeDecls *scope = allocate<ScopeDecls>(1); 81 init_scope(&scope->base, ScopeIdDecls, node, parent); 82 scope->decl_table.init(4); 83 scope->container_type = container_type; 84 scope->import = import; 85 return scope; 86 } 87 88 ScopeBlock *create_block_scope(AstNode *node, Scope *parent) { 89 assert(node->type == NodeTypeBlock); 90 ScopeBlock *scope = allocate<ScopeBlock>(1); 91 init_scope(&scope->base, ScopeIdBlock, node, parent); 92 scope->label_table.init(1); 93 return scope; 94 } 95 96 ScopeDefer *create_defer_scope(AstNode *node, Scope *parent) { 97 assert(node->type == NodeTypeDefer); 98 ScopeDefer *scope = allocate<ScopeDefer>(1); 99 init_scope(&scope->base, ScopeIdDefer, node, parent); 100 return scope; 101 } 102 103 ScopeDeferExpr *create_defer_expr_scope(AstNode *node, Scope *parent) { 104 assert(node->type == NodeTypeDefer); 105 ScopeDeferExpr *scope = allocate<ScopeDeferExpr>(1); 106 init_scope(&scope->base, ScopeIdDeferExpr, node, parent); 107 return scope; 108 } 109 110 Scope *create_var_scope(AstNode *node, Scope *parent, VariableTableEntry *var) { 111 ScopeVarDecl *scope = allocate<ScopeVarDecl>(1); 112 init_scope(&scope->base, ScopeIdVarDecl, node, parent); 113 scope->var = var; 114 return &scope->base; 115 } 116 117 ScopeCImport *create_cimport_scope(AstNode *node, Scope *parent) { 118 assert(node->type == NodeTypeFnCallExpr); 119 ScopeCImport *scope = allocate<ScopeCImport>(1); 120 init_scope(&scope->base, ScopeIdCImport, node, parent); 121 buf_resize(&scope->buf, 0); 122 return scope; 123 } 124 125 Scope *create_loop_scope(AstNode *node, Scope *parent) { 126 assert(node->type == NodeTypeWhileExpr || node->type == NodeTypeForExpr); 127 ScopeLoop *scope = allocate<ScopeLoop>(1); 128 init_scope(&scope->base, ScopeIdLoop, node, parent); 129 return &scope->base; 130 } 131 132 ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_entry) { 133 ScopeFnDef *scope = allocate<ScopeFnDef>(1); 134 init_scope(&scope->base, ScopeIdFnDef, node, parent); 135 scope->fn_entry = fn_entry; 136 return scope; 137 } 138 139 Scope *create_comptime_scope(AstNode *node, Scope *parent) { 140 assert(node->type == NodeTypeCompTime || node->type == NodeTypeSwitchExpr); 141 ScopeCompTime *scope = allocate<ScopeCompTime>(1); 142 init_scope(&scope->base, ScopeIdCompTime, node, parent); 143 return &scope->base; 144 } 145 146 ImportTableEntry *get_scope_import(Scope *scope) { 147 while (scope) { 148 if (scope->id == ScopeIdDecls) { 149 ScopeDecls *decls_scope = (ScopeDecls *)scope; 150 assert(decls_scope->import); 151 return decls_scope->import; 152 } 153 scope = scope->parent; 154 } 155 zig_unreachable(); 156 } 157 158 static TypeTableEntry *new_container_type_entry(TypeTableEntryId id, AstNode *source_node, Scope *parent_scope) { 159 TypeTableEntry *entry = new_type_table_entry(id); 160 *get_container_scope_ptr(entry) = create_decls_scope(source_node, parent_scope, entry, get_scope_import(parent_scope)); 161 return entry; 162 } 163 164 165 // TODO no reason to limit to 8/16/32/64 166 static uint8_t bits_needed_for_unsigned(uint64_t x) { 167 if (x <= UINT8_MAX) { 168 return 8; 169 } else if (x <= UINT16_MAX) { 170 return 16; 171 } else if (x <= UINT32_MAX) { 172 return 32; 173 } else { 174 return 64; 175 } 176 } 177 178 bool type_is_complete(TypeTableEntry *type_entry) { 179 switch (type_entry->id) { 180 case TypeTableEntryIdInvalid: 181 case TypeTableEntryIdVar: 182 zig_unreachable(); 183 case TypeTableEntryIdStruct: 184 return type_entry->data.structure.complete; 185 case TypeTableEntryIdEnum: 186 return type_entry->data.enumeration.complete; 187 case TypeTableEntryIdUnion: 188 return type_entry->data.unionation.complete; 189 case TypeTableEntryIdOpaque: 190 return false; 191 case TypeTableEntryIdMetaType: 192 case TypeTableEntryIdVoid: 193 case TypeTableEntryIdBool: 194 case TypeTableEntryIdUnreachable: 195 case TypeTableEntryIdInt: 196 case TypeTableEntryIdFloat: 197 case TypeTableEntryIdPointer: 198 case TypeTableEntryIdArray: 199 case TypeTableEntryIdNumLitFloat: 200 case TypeTableEntryIdNumLitInt: 201 case TypeTableEntryIdUndefLit: 202 case TypeTableEntryIdNullLit: 203 case TypeTableEntryIdMaybe: 204 case TypeTableEntryIdErrorUnion: 205 case TypeTableEntryIdPureError: 206 case TypeTableEntryIdFn: 207 case TypeTableEntryIdNamespace: 208 case TypeTableEntryIdBlock: 209 case TypeTableEntryIdBoundFn: 210 case TypeTableEntryIdEnumTag: 211 case TypeTableEntryIdArgTuple: 212 return true; 213 } 214 zig_unreachable(); 215 } 216 217 bool type_has_zero_bits_known(TypeTableEntry *type_entry) { 218 switch (type_entry->id) { 219 case TypeTableEntryIdInvalid: 220 case TypeTableEntryIdVar: 221 zig_unreachable(); 222 case TypeTableEntryIdStruct: 223 return type_entry->data.structure.zero_bits_known; 224 case TypeTableEntryIdEnum: 225 return type_entry->data.enumeration.zero_bits_known; 226 case TypeTableEntryIdUnion: 227 return type_entry->data.unionation.zero_bits_known; 228 case TypeTableEntryIdMetaType: 229 case TypeTableEntryIdVoid: 230 case TypeTableEntryIdBool: 231 case TypeTableEntryIdUnreachable: 232 case TypeTableEntryIdInt: 233 case TypeTableEntryIdFloat: 234 case TypeTableEntryIdPointer: 235 case TypeTableEntryIdArray: 236 case TypeTableEntryIdNumLitFloat: 237 case TypeTableEntryIdNumLitInt: 238 case TypeTableEntryIdUndefLit: 239 case TypeTableEntryIdNullLit: 240 case TypeTableEntryIdMaybe: 241 case TypeTableEntryIdErrorUnion: 242 case TypeTableEntryIdPureError: 243 case TypeTableEntryIdFn: 244 case TypeTableEntryIdNamespace: 245 case TypeTableEntryIdBlock: 246 case TypeTableEntryIdBoundFn: 247 case TypeTableEntryIdEnumTag: 248 case TypeTableEntryIdArgTuple: 249 case TypeTableEntryIdOpaque: 250 return true; 251 } 252 zig_unreachable(); 253 } 254 255 256 uint64_t type_size(CodeGen *g, TypeTableEntry *type_entry) { 257 assert(type_is_complete(type_entry)); 258 259 if (!type_has_bits(type_entry)) 260 return 0; 261 262 if (type_entry->id == TypeTableEntryIdStruct && type_entry->data.structure.layout == ContainerLayoutPacked) { 263 uint64_t size_in_bits = type_size_bits(g, type_entry); 264 return (size_in_bits + 7) / 8; 265 } else if (type_entry->id == TypeTableEntryIdArray) { 266 TypeTableEntry *child_type = type_entry->data.array.child_type; 267 if (child_type->id == TypeTableEntryIdStruct && 268 child_type->data.structure.layout == ContainerLayoutPacked) 269 { 270 uint64_t size_in_bits = type_size_bits(g, type_entry); 271 return (size_in_bits + 7) / 8; 272 } 273 } 274 275 return LLVMStoreSizeOfType(g->target_data_ref, type_entry->type_ref); 276 } 277 278 uint64_t type_size_bits(CodeGen *g, TypeTableEntry *type_entry) { 279 assert(type_is_complete(type_entry)); 280 281 if (!type_has_bits(type_entry)) 282 return 0; 283 284 if (type_entry->id == TypeTableEntryIdStruct && type_entry->data.structure.layout == ContainerLayoutPacked) { 285 uint64_t result = 0; 286 for (size_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { 287 result += type_size_bits(g, type_entry->data.structure.fields[i].type_entry); 288 } 289 return result; 290 } else if (type_entry->id == TypeTableEntryIdArray) { 291 TypeTableEntry *child_type = type_entry->data.array.child_type; 292 if (child_type->id == TypeTableEntryIdStruct && 293 child_type->data.structure.layout == ContainerLayoutPacked) 294 { 295 return type_entry->data.array.len * type_size_bits(g, child_type); 296 } 297 } 298 299 return LLVMSizeOfTypeInBits(g->target_data_ref, type_entry->type_ref); 300 } 301 302 static bool type_is_copyable(CodeGen *g, TypeTableEntry *type_entry) { 303 type_ensure_zero_bits_known(g, type_entry); 304 if (!type_has_bits(type_entry)) 305 return true; 306 307 if (!handle_is_ptr(type_entry)) 308 return true; 309 310 ensure_complete_type(g, type_entry); 311 return type_entry->is_copyable; 312 } 313 314 static bool is_slice(TypeTableEntry *type) { 315 return type->id == TypeTableEntryIdStruct && type->data.structure.is_slice; 316 } 317 318 TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) { 319 return get_int_type(g, false, bits_needed_for_unsigned(x)); 320 } 321 322 TypeTableEntry *get_pointer_to_type_extra(CodeGen *g, TypeTableEntry *child_type, bool is_const, 323 bool is_volatile, uint32_t bit_offset, uint32_t unaligned_bit_count) 324 { 325 assert(child_type->id != TypeTableEntryIdInvalid); 326 327 TypeId type_id = {}; 328 TypeTableEntry **parent_pointer = nullptr; 329 if (unaligned_bit_count != 0 || is_volatile) { 330 type_id.id = TypeTableEntryIdPointer; 331 type_id.data.pointer.child_type = child_type; 332 type_id.data.pointer.is_const = is_const; 333 type_id.data.pointer.is_volatile = is_volatile; 334 type_id.data.pointer.bit_offset = bit_offset; 335 type_id.data.pointer.unaligned_bit_count = unaligned_bit_count; 336 337 auto existing_entry = g->type_table.maybe_get(type_id); 338 if (existing_entry) 339 return existing_entry->value; 340 } else { 341 assert(bit_offset == 0); 342 parent_pointer = &child_type->pointer_parent[(is_const ? 1 : 0)]; 343 if (*parent_pointer) 344 return *parent_pointer; 345 } 346 347 type_ensure_zero_bits_known(g, child_type); 348 349 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPointer); 350 entry->is_copyable = true; 351 352 const char *const_str = is_const ? "const " : ""; 353 const char *volatile_str = is_volatile ? "volatile " : ""; 354 buf_resize(&entry->name, 0); 355 if (unaligned_bit_count == 0) { 356 buf_appendf(&entry->name, "&%s%s%s", const_str, volatile_str, buf_ptr(&child_type->name)); 357 } else { 358 buf_appendf(&entry->name, "&:%" PRIu32 ":%" PRIu32 " %s%s%s", bit_offset, 359 bit_offset + unaligned_bit_count, const_str, volatile_str, buf_ptr(&child_type->name)); 360 } 361 362 assert(child_type->id != TypeTableEntryIdInvalid); 363 364 entry->zero_bits = !type_has_bits(child_type); 365 366 if (!entry->zero_bits) { 367 entry->type_ref = LLVMPointerType(child_type->type_ref, 0); 368 369 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); 370 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); 371 assert(child_type->di_type); 372 entry->di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, child_type->di_type, 373 debug_size_in_bits, debug_align_in_bits, buf_ptr(&entry->name)); 374 } else { 375 entry->di_type = g->builtin_types.entry_void->di_type; 376 } 377 378 entry->data.pointer.child_type = child_type; 379 entry->data.pointer.is_const = is_const; 380 entry->data.pointer.is_volatile = is_volatile; 381 entry->data.pointer.bit_offset = bit_offset; 382 entry->data.pointer.unaligned_bit_count = unaligned_bit_count; 383 384 if (parent_pointer) { 385 *parent_pointer = entry; 386 } else { 387 g->type_table.put(type_id, entry); 388 } 389 return entry; 390 } 391 392 TypeTableEntry *get_pointer_to_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) { 393 return get_pointer_to_type_extra(g, child_type, is_const, false, 0, 0); 394 } 395 396 TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) { 397 if (child_type->maybe_parent) { 398 TypeTableEntry *entry = child_type->maybe_parent; 399 return entry; 400 } else { 401 ensure_complete_type(g, child_type); 402 403 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdMaybe); 404 assert(child_type->type_ref); 405 assert(child_type->di_type); 406 entry->is_copyable = type_is_copyable(g, child_type); 407 408 buf_resize(&entry->name, 0); 409 buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name)); 410 411 if (child_type->zero_bits) { 412 entry->type_ref = LLVMInt1Type(); 413 entry->di_type = g->builtin_types.entry_bool->di_type; 414 } else if (child_type->id == TypeTableEntryIdPointer || 415 child_type->id == TypeTableEntryIdFn) 416 { 417 // this is an optimization but also is necessary for calling C 418 // functions where all pointers are maybe pointers 419 // function types are technically pointers 420 entry->type_ref = child_type->type_ref; 421 entry->di_type = child_type->di_type; 422 } else { 423 // create a struct with a boolean whether this is the null value 424 LLVMTypeRef elem_types[] = { 425 child_type->type_ref, 426 LLVMInt1Type(), 427 }; 428 entry->type_ref = LLVMStructType(elem_types, 2, false); 429 430 431 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit); 432 ZigLLVMDIFile *di_file = nullptr; 433 unsigned line = 0; 434 entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, 435 ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name), 436 compile_unit_scope, di_file, line); 437 438 uint64_t val_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, child_type->type_ref); 439 uint64_t val_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, child_type->type_ref); 440 uint64_t val_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 0); 441 442 TypeTableEntry *bool_type = g->builtin_types.entry_bool; 443 uint64_t maybe_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, bool_type->type_ref); 444 uint64_t maybe_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, bool_type->type_ref); 445 uint64_t maybe_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 1); 446 447 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); 448 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); 449 450 ZigLLVMDIType *di_element_types[] = { 451 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 452 "val", di_file, line, 453 val_debug_size_in_bits, 454 val_debug_align_in_bits, 455 val_offset_in_bits, 456 0, child_type->di_type), 457 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 458 "maybe", di_file, line, 459 maybe_debug_size_in_bits, 460 maybe_debug_align_in_bits, 461 maybe_offset_in_bits, 462 0, child_type->di_type), 463 }; 464 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 465 compile_unit_scope, 466 buf_ptr(&entry->name), 467 di_file, line, debug_size_in_bits, debug_align_in_bits, 0, 468 nullptr, di_element_types, 2, 0, nullptr, ""); 469 470 ZigLLVMReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type); 471 entry->di_type = replacement_di_type; 472 } 473 474 entry->data.maybe.child_type = child_type; 475 476 child_type->maybe_parent = entry; 477 return entry; 478 } 479 } 480 481 TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) { 482 if (child_type->error_parent) 483 return child_type->error_parent; 484 485 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdErrorUnion); 486 entry->is_copyable = true; 487 assert(child_type->type_ref); 488 assert(child_type->di_type); 489 ensure_complete_type(g, child_type); 490 491 buf_resize(&entry->name, 0); 492 buf_appendf(&entry->name, "%%%s", buf_ptr(&child_type->name)); 493 494 entry->data.error.child_type = child_type; 495 496 if (!type_has_bits(child_type)) { 497 entry->type_ref = g->err_tag_type->type_ref; 498 entry->di_type = g->err_tag_type->di_type; 499 500 } else { 501 LLVMTypeRef elem_types[] = { 502 g->err_tag_type->type_ref, 503 child_type->type_ref, 504 }; 505 entry->type_ref = LLVMStructType(elem_types, 2, false); 506 507 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit); 508 ZigLLVMDIFile *di_file = nullptr; 509 unsigned line = 0; 510 entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, 511 ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name), 512 compile_unit_scope, di_file, line); 513 514 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, g->err_tag_type->type_ref); 515 uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, g->err_tag_type->type_ref); 516 uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, err_union_err_index); 517 518 uint64_t value_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, child_type->type_ref); 519 uint64_t value_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, child_type->type_ref); 520 uint64_t value_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 521 err_union_payload_index); 522 523 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); 524 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); 525 526 ZigLLVMDIType *di_element_types[] = { 527 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 528 "tag", di_file, line, 529 tag_debug_size_in_bits, 530 tag_debug_align_in_bits, 531 tag_offset_in_bits, 532 0, child_type->di_type), 533 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 534 "value", di_file, line, 535 value_debug_size_in_bits, 536 value_debug_align_in_bits, 537 value_offset_in_bits, 538 0, child_type->di_type), 539 }; 540 541 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 542 compile_unit_scope, 543 buf_ptr(&entry->name), 544 di_file, line, 545 debug_size_in_bits, 546 debug_align_in_bits, 547 0, 548 nullptr, di_element_types, 2, 0, nullptr, ""); 549 550 ZigLLVMReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type); 551 entry->di_type = replacement_di_type; 552 } 553 554 child_type->error_parent = entry; 555 return entry; 556 } 557 558 TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t array_size) { 559 TypeId type_id = {}; 560 type_id.id = TypeTableEntryIdArray; 561 type_id.data.array.child_type = child_type; 562 type_id.data.array.size = array_size; 563 auto existing_entry = g->type_table.maybe_get(type_id); 564 if (existing_entry) { 565 TypeTableEntry *entry = existing_entry->value; 566 return entry; 567 } 568 569 ensure_complete_type(g, child_type); 570 571 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdArray); 572 entry->zero_bits = (array_size == 0) || child_type->zero_bits; 573 entry->is_copyable = false; 574 575 buf_resize(&entry->name, 0); 576 buf_appendf(&entry->name, "[%" PRIu64 "]%s", array_size, buf_ptr(&child_type->name)); 577 578 if (!entry->zero_bits) { 579 entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref, 580 (unsigned int)array_size) : nullptr; 581 582 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); 583 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); 584 585 entry->di_type = ZigLLVMCreateDebugArrayType(g->dbuilder, debug_size_in_bits, 586 debug_align_in_bits, child_type->di_type, (int)array_size); 587 } 588 entry->data.array.child_type = child_type; 589 entry->data.array.len = array_size; 590 591 g->type_table.put(type_id, entry); 592 return entry; 593 } 594 595 static void slice_type_common_init(CodeGen *g, TypeTableEntry *child_type, 596 bool is_const, TypeTableEntry *entry) 597 { 598 TypeTableEntry *pointer_type = get_pointer_to_type(g, child_type, is_const); 599 600 unsigned element_count = 2; 601 entry->data.structure.layout = ContainerLayoutAuto; 602 entry->data.structure.is_slice = true; 603 entry->data.structure.src_field_count = element_count; 604 entry->data.structure.gen_field_count = element_count; 605 entry->data.structure.fields = allocate<TypeStructField>(element_count); 606 entry->data.structure.fields[slice_ptr_index].name = buf_create_from_str("ptr"); 607 entry->data.structure.fields[slice_ptr_index].type_entry = pointer_type; 608 entry->data.structure.fields[slice_ptr_index].src_index = slice_ptr_index; 609 entry->data.structure.fields[slice_ptr_index].gen_index = 0; 610 entry->data.structure.fields[slice_len_index].name = buf_create_from_str("len"); 611 entry->data.structure.fields[slice_len_index].type_entry = g->builtin_types.entry_usize; 612 entry->data.structure.fields[slice_len_index].src_index = slice_len_index; 613 entry->data.structure.fields[slice_len_index].gen_index = 1; 614 615 assert(type_has_zero_bits_known(child_type)); 616 if (child_type->zero_bits) { 617 entry->data.structure.gen_field_count = 1; 618 entry->data.structure.fields[slice_ptr_index].gen_index = SIZE_MAX; 619 entry->data.structure.fields[slice_len_index].gen_index = 0; 620 } 621 } 622 623 TypeTableEntry *get_slice_type(CodeGen *g, TypeTableEntry *child_type, bool is_const) { 624 assert(child_type->id != TypeTableEntryIdInvalid); 625 TypeTableEntry **parent_pointer = &child_type->slice_parent[(is_const ? 1 : 0)]; 626 627 if (*parent_pointer) { 628 return *parent_pointer; 629 } else if (is_const) { 630 TypeTableEntry *var_peer = get_slice_type(g, child_type, false); 631 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct); 632 entry->is_copyable = true; 633 634 buf_resize(&entry->name, 0); 635 buf_appendf(&entry->name, "[]const %s", buf_ptr(&child_type->name)); 636 637 slice_type_common_init(g, child_type, is_const, entry); 638 639 entry->type_ref = var_peer->type_ref; 640 entry->di_type = var_peer->di_type; 641 entry->data.structure.complete = true; 642 entry->data.structure.zero_bits_known = true; 643 644 *parent_pointer = entry; 645 return entry; 646 } else { 647 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdStruct); 648 entry->is_copyable = true; 649 650 // If the child type is []const T then we need to make sure the type ref 651 // and debug info is the same as if the child type were []T. 652 if (is_slice(child_type)) { 653 TypeTableEntry *ptr_type = child_type->data.structure.fields[slice_ptr_index].type_entry; 654 assert(ptr_type->id == TypeTableEntryIdPointer); 655 if (ptr_type->data.pointer.is_const) { 656 TypeTableEntry *non_const_child_type = get_slice_type(g, 657 ptr_type->data.pointer.child_type, false); 658 TypeTableEntry *var_peer = get_slice_type(g, non_const_child_type, false); 659 660 entry->type_ref = var_peer->type_ref; 661 entry->di_type = var_peer->di_type; 662 } 663 } 664 665 buf_resize(&entry->name, 0); 666 buf_appendf(&entry->name, "[]%s", buf_ptr(&child_type->name)); 667 668 slice_type_common_init(g, child_type, is_const, entry); 669 670 if (!entry->type_ref) { 671 entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), buf_ptr(&entry->name)); 672 673 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit); 674 ZigLLVMDIFile *di_file = nullptr; 675 unsigned line = 0; 676 entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, 677 ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name), 678 compile_unit_scope, di_file, line); 679 680 if (child_type->zero_bits) { 681 LLVMTypeRef element_types[] = { 682 g->builtin_types.entry_usize->type_ref, 683 }; 684 LLVMStructSetBody(entry->type_ref, element_types, 1, false); 685 686 TypeTableEntry *usize_type = g->builtin_types.entry_usize; 687 uint64_t len_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, usize_type->type_ref); 688 uint64_t len_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, usize_type->type_ref); 689 uint64_t len_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 0); 690 691 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); 692 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); 693 694 ZigLLVMDIType *di_element_types[] = { 695 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 696 "len", di_file, line, 697 len_debug_size_in_bits, 698 len_debug_align_in_bits, 699 len_offset_in_bits, 700 0, usize_type->di_type), 701 }; 702 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 703 compile_unit_scope, 704 buf_ptr(&entry->name), 705 di_file, line, debug_size_in_bits, debug_align_in_bits, 0, 706 nullptr, di_element_types, 1, 0, nullptr, ""); 707 708 ZigLLVMReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type); 709 entry->di_type = replacement_di_type; 710 } else { 711 TypeTableEntry *pointer_type = get_pointer_to_type(g, child_type, is_const); 712 713 unsigned element_count = 2; 714 LLVMTypeRef element_types[] = { 715 pointer_type->type_ref, 716 g->builtin_types.entry_usize->type_ref, 717 }; 718 LLVMStructSetBody(entry->type_ref, element_types, element_count, false); 719 720 721 uint64_t ptr_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, pointer_type->type_ref); 722 uint64_t ptr_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, pointer_type->type_ref); 723 uint64_t ptr_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 0); 724 725 TypeTableEntry *usize_type = g->builtin_types.entry_usize; 726 uint64_t len_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, usize_type->type_ref); 727 uint64_t len_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, usize_type->type_ref); 728 uint64_t len_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, entry->type_ref, 1); 729 730 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); 731 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, entry->type_ref); 732 733 ZigLLVMDIType *di_element_types[] = { 734 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 735 "ptr", di_file, line, 736 ptr_debug_size_in_bits, 737 ptr_debug_align_in_bits, 738 ptr_offset_in_bits, 739 0, pointer_type->di_type), 740 ZigLLVMCreateDebugMemberType(g->dbuilder, ZigLLVMTypeToScope(entry->di_type), 741 "len", di_file, line, 742 len_debug_size_in_bits, 743 len_debug_align_in_bits, 744 len_offset_in_bits, 745 0, usize_type->di_type), 746 }; 747 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 748 compile_unit_scope, 749 buf_ptr(&entry->name), 750 di_file, line, debug_size_in_bits, debug_align_in_bits, 0, 751 nullptr, di_element_types, 2, 0, nullptr, ""); 752 753 ZigLLVMReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type); 754 entry->di_type = replacement_di_type; 755 } 756 } 757 758 759 entry->data.structure.complete = true; 760 entry->data.structure.zero_bits_known = true; 761 762 *parent_pointer = entry; 763 return entry; 764 } 765 } 766 767 TypeTableEntry *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *name) { 768 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdOpaque); 769 770 buf_init_from_str(&entry->name, name); 771 772 ImportTableEntry *import = scope ? get_scope_import(scope) : nullptr; 773 unsigned line = source_node ? (unsigned)(source_node->line + 1) : 0; 774 775 entry->is_copyable = false; 776 entry->type_ref = LLVMInt8Type(); 777 entry->di_type = ZigLLVMCreateDebugForwardDeclType(g->dbuilder, 778 ZigLLVMTag_DW_structure_type(), buf_ptr(&entry->name), 779 import ? ZigLLVMFileToScope(import->di_file) : nullptr, 780 import ? import->di_file : nullptr, 781 line); 782 entry->zero_bits = false; 783 784 return entry; 785 } 786 787 TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry) { 788 TypeTableEntry *fn_type = fn_entry->type_entry; 789 assert(fn_type->id == TypeTableEntryIdFn); 790 if (fn_type->data.fn.bound_fn_parent) 791 return fn_type->data.fn.bound_fn_parent; 792 793 TypeTableEntry *bound_fn_type = new_type_table_entry(TypeTableEntryIdBoundFn); 794 bound_fn_type->is_copyable = false; 795 bound_fn_type->data.bound_fn.fn_type = fn_type; 796 bound_fn_type->zero_bits = true; 797 798 buf_resize(&bound_fn_type->name, 0); 799 buf_appendf(&bound_fn_type->name, "(bound %s)", buf_ptr(&fn_type->name)); 800 801 fn_type->data.fn.bound_fn_parent = bound_fn_type; 802 return bound_fn_type; 803 } 804 805 TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { 806 auto table_entry = g->fn_type_table.maybe_get(fn_type_id); 807 if (table_entry) { 808 return table_entry->value; 809 } 810 ensure_complete_type(g, fn_type_id->return_type); 811 812 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn); 813 fn_type->is_copyable = true; 814 fn_type->data.fn.fn_type_id = *fn_type_id; 815 816 if (fn_type_id->is_cold) { 817 // cold calling convention only works on x86. 818 // but we can add the cold attribute later. 819 if (g->zig_target.arch.arch == ZigLLVM_x86 || 820 g->zig_target.arch.arch == ZigLLVM_x86_64) 821 { 822 fn_type->data.fn.calling_convention = LLVMColdCallConv; 823 } else { 824 fn_type->data.fn.calling_convention = LLVMFastCallConv; 825 } 826 } else if (fn_type_id->is_extern) { 827 fn_type->data.fn.calling_convention = LLVMCCallConv; 828 } else { 829 fn_type->data.fn.calling_convention = LLVMFastCallConv; 830 } 831 832 bool skip_debug_info = false; 833 834 // populate the name of the type 835 buf_resize(&fn_type->name, 0); 836 const char *extern_str = fn_type_id->is_extern ? "extern " : ""; 837 const char *naked_str = fn_type_id->is_naked ? "nakedcc " : ""; 838 const char *cold_str = fn_type_id->is_cold ? "coldcc " : ""; 839 buf_appendf(&fn_type->name, "%s%s%sfn(", extern_str, naked_str, cold_str); 840 for (size_t i = 0; i < fn_type_id->param_count; i += 1) { 841 FnTypeParamInfo *param_info = &fn_type_id->param_info[i]; 842 843 TypeTableEntry *param_type = param_info->type; 844 const char *comma = (i == 0) ? "" : ", "; 845 const char *noalias_str = param_info->is_noalias ? "noalias " : ""; 846 buf_appendf(&fn_type->name, "%s%s%s", comma, noalias_str, buf_ptr(¶m_type->name)); 847 848 skip_debug_info = skip_debug_info || !param_type->di_type; 849 } 850 851 if (fn_type_id->is_var_args) { 852 const char *comma = (fn_type_id->param_count == 0) ? "" : ", "; 853 buf_appendf(&fn_type->name, "%s...", comma); 854 } 855 buf_appendf(&fn_type->name, ")"); 856 if (fn_type_id->return_type->id != TypeTableEntryIdVoid) { 857 buf_appendf(&fn_type->name, " -> %s", buf_ptr(&fn_type_id->return_type->name)); 858 } 859 skip_debug_info = skip_debug_info || !fn_type_id->return_type->di_type; 860 861 // next, loop over the parameters again and compute debug information 862 // and codegen information 863 if (!skip_debug_info) { 864 bool first_arg_return = !fn_type_id->is_extern && handle_is_ptr(fn_type_id->return_type); 865 // +1 for maybe making the first argument the return value 866 LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(1 + fn_type_id->param_count); 867 // +1 because 0 is the return type and +1 for maybe making first arg ret val 868 ZigLLVMDIType **param_di_types = allocate<ZigLLVMDIType*>(2 + fn_type_id->param_count); 869 param_di_types[0] = fn_type_id->return_type->di_type; 870 size_t gen_param_index = 0; 871 TypeTableEntry *gen_return_type; 872 if (!type_has_bits(fn_type_id->return_type)) { 873 gen_return_type = g->builtin_types.entry_void; 874 } else if (first_arg_return) { 875 TypeTableEntry *gen_type = get_pointer_to_type(g, fn_type_id->return_type, false); 876 gen_param_types[gen_param_index] = gen_type->type_ref; 877 gen_param_index += 1; 878 // after the gen_param_index += 1 because 0 is the return type 879 param_di_types[gen_param_index] = gen_type->di_type; 880 gen_return_type = g->builtin_types.entry_void; 881 } else { 882 gen_return_type = fn_type_id->return_type; 883 } 884 fn_type->data.fn.gen_return_type = gen_return_type; 885 886 fn_type->data.fn.gen_param_info = allocate<FnGenParamInfo>(fn_type_id->param_count); 887 for (size_t i = 0; i < fn_type_id->param_count; i += 1) { 888 FnTypeParamInfo *src_param_info = &fn_type->data.fn.fn_type_id.param_info[i]; 889 TypeTableEntry *type_entry = src_param_info->type; 890 FnGenParamInfo *gen_param_info = &fn_type->data.fn.gen_param_info[i]; 891 892 gen_param_info->src_index = i; 893 gen_param_info->gen_index = SIZE_MAX; 894 895 ensure_complete_type(g, type_entry); 896 if (type_has_bits(type_entry)) { 897 TypeTableEntry *gen_type; 898 if (handle_is_ptr(type_entry)) { 899 gen_type = get_pointer_to_type(g, type_entry, true); 900 gen_param_info->is_byval = true; 901 } else { 902 gen_type = type_entry; 903 } 904 gen_param_types[gen_param_index] = gen_type->type_ref; 905 gen_param_info->gen_index = gen_param_index; 906 gen_param_info->type = gen_type; 907 908 gen_param_index += 1; 909 910 // after the gen_param_index += 1 because 0 is the return type 911 param_di_types[gen_param_index] = gen_type->di_type; 912 } 913 } 914 915 fn_type->data.fn.gen_param_count = gen_param_index; 916 917 fn_type->data.fn.raw_type_ref = LLVMFunctionType(gen_return_type->type_ref, 918 gen_param_types, (unsigned int)gen_param_index, fn_type_id->is_var_args); 919 fn_type->type_ref = LLVMPointerType(fn_type->data.fn.raw_type_ref, 0); 920 fn_type->di_type = ZigLLVMCreateSubroutineType(g->dbuilder, param_di_types, (int)(gen_param_index + 1), 0); 921 } 922 923 g->fn_type_table.put(&fn_type->data.fn.fn_type_id, fn_type); 924 925 return fn_type; 926 } 927 928 static TypeTableEntryId container_to_type(ContainerKind kind) { 929 switch (kind) { 930 case ContainerKindStruct: 931 return TypeTableEntryIdStruct; 932 case ContainerKindEnum: 933 return TypeTableEntryIdEnum; 934 case ContainerKindUnion: 935 return TypeTableEntryIdUnion; 936 } 937 zig_unreachable(); 938 } 939 940 TypeTableEntry *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, 941 AstNode *decl_node, const char *name, ContainerLayout layout) 942 { 943 TypeTableEntryId type_id = container_to_type(kind); 944 TypeTableEntry *entry = new_container_type_entry(type_id, decl_node, scope); 945 946 switch (kind) { 947 case ContainerKindStruct: 948 entry->data.structure.decl_node = decl_node; 949 entry->data.structure.layout = layout; 950 break; 951 case ContainerKindEnum: 952 entry->data.enumeration.decl_node = decl_node; 953 entry->data.enumeration.layout = layout; 954 break; 955 case ContainerKindUnion: 956 entry->data.unionation.decl_node = decl_node; 957 entry->data.unionation.layout = layout; 958 break; 959 } 960 961 size_t line = decl_node ? decl_node->line : 0; 962 963 ImportTableEntry *import = get_scope_import(scope); 964 entry->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), name); 965 entry->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder, 966 ZigLLVMTag_DW_structure_type(), name, 967 ZigLLVMFileToScope(import->di_file), import->di_file, (unsigned)(line + 1)); 968 969 buf_init_from_str(&entry->name, name); 970 971 return entry; 972 } 973 974 static IrInstruction *analyze_const_value(CodeGen *g, Scope *scope, AstNode *node, TypeTableEntry *type_entry, Buf *type_name) { 975 size_t backward_branch_count = 0; 976 return ir_eval_const_value(g, scope, node, type_entry, 977 &backward_branch_count, default_backward_branch_quota, 978 nullptr, nullptr, node, type_name, nullptr); 979 } 980 981 TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { 982 IrInstruction *result = analyze_const_value(g, scope, node, g->builtin_types.entry_type, nullptr); 983 if (result->value.type->id == TypeTableEntryIdInvalid) 984 return g->builtin_types.entry_invalid; 985 986 assert(result->value.special != ConstValSpecialRuntime); 987 return result->value.data.x_type; 988 } 989 990 static TypeTableEntry *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) { 991 TypeTableEntry *fn_type = new_type_table_entry(TypeTableEntryIdFn); 992 fn_type->is_copyable = false; 993 buf_init_from_str(&fn_type->name, "fn("); 994 size_t i = 0; 995 for (; i < fn_type_id->next_param_index; i += 1) { 996 const char *comma_str = (i == 0) ? "" : ","; 997 buf_appendf(&fn_type->name, "%s%s", comma_str, 998 buf_ptr(&fn_type_id->param_info[i].type->name)); 999 } 1000 for (; i < fn_type_id->param_count; i += 1) { 1001 const char *comma_str = (i == 0) ? "" : ","; 1002 buf_appendf(&fn_type->name, "%svar", comma_str); 1003 } 1004 buf_appendf(&fn_type->name, ")->var"); 1005 1006 fn_type->data.fn.fn_type_id = *fn_type_id; 1007 fn_type->data.fn.is_generic = true; 1008 fn_type->zero_bits = true; 1009 return fn_type; 1010 } 1011 1012 void init_fn_type_id(FnTypeId *fn_type_id, AstNode *proto_node, size_t param_count_alloc) { 1013 assert(proto_node->type == NodeTypeFnProto); 1014 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; 1015 1016 fn_type_id->is_extern = fn_proto->is_extern || (fn_proto->visib_mod == VisibModExport); 1017 fn_type_id->is_naked = fn_proto->is_nakedcc; 1018 fn_type_id->is_cold = fn_proto->is_coldcc; 1019 fn_type_id->param_count = fn_proto->params.length; 1020 fn_type_id->param_info = allocate_nonzero<FnTypeParamInfo>(param_count_alloc); 1021 fn_type_id->next_param_index = 0; 1022 fn_type_id->is_var_args = fn_proto->is_var_args; 1023 } 1024 1025 static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) { 1026 assert(proto_node->type == NodeTypeFnProto); 1027 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; 1028 1029 FnTypeId fn_type_id = {0}; 1030 init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); 1031 1032 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { 1033 AstNode *param_node = fn_proto->params.at(fn_type_id.next_param_index); 1034 assert(param_node->type == NodeTypeParamDecl); 1035 1036 bool param_is_inline = param_node->data.param_decl.is_inline; 1037 bool param_is_var_args = param_node->data.param_decl.is_var_args; 1038 1039 if (param_is_inline) { 1040 if (fn_type_id.is_extern) { 1041 add_node_error(g, param_node, 1042 buf_sprintf("comptime parameter not allowed in extern function")); 1043 return g->builtin_types.entry_invalid; 1044 } 1045 return get_generic_fn_type(g, &fn_type_id); 1046 } else if (param_is_var_args) { 1047 if (fn_type_id.is_extern) { 1048 fn_type_id.param_count = fn_type_id.next_param_index; 1049 continue; 1050 } else { 1051 return get_generic_fn_type(g, &fn_type_id); 1052 } 1053 } 1054 1055 TypeTableEntry *type_entry = analyze_type_expr(g, child_scope, param_node->data.param_decl.type); 1056 1057 switch (type_entry->id) { 1058 case TypeTableEntryIdInvalid: 1059 return g->builtin_types.entry_invalid; 1060 case TypeTableEntryIdUnreachable: 1061 case TypeTableEntryIdUndefLit: 1062 case TypeTableEntryIdNullLit: 1063 case TypeTableEntryIdArgTuple: 1064 case TypeTableEntryIdOpaque: 1065 add_node_error(g, param_node->data.param_decl.type, 1066 buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name))); 1067 return g->builtin_types.entry_invalid; 1068 case TypeTableEntryIdVar: 1069 if (fn_type_id.is_extern) { 1070 add_node_error(g, param_node->data.param_decl.type, 1071 buf_sprintf("parameter of type 'var' not allowed in extern function")); 1072 return g->builtin_types.entry_invalid; 1073 } 1074 return get_generic_fn_type(g, &fn_type_id); 1075 case TypeTableEntryIdNumLitFloat: 1076 case TypeTableEntryIdNumLitInt: 1077 case TypeTableEntryIdNamespace: 1078 case TypeTableEntryIdBlock: 1079 case TypeTableEntryIdBoundFn: 1080 case TypeTableEntryIdMetaType: 1081 add_node_error(g, param_node->data.param_decl.type, 1082 buf_sprintf("parameter of type '%s' must be declared inline", 1083 buf_ptr(&type_entry->name))); 1084 return g->builtin_types.entry_invalid; 1085 case TypeTableEntryIdVoid: 1086 case TypeTableEntryIdBool: 1087 case TypeTableEntryIdInt: 1088 case TypeTableEntryIdFloat: 1089 case TypeTableEntryIdPointer: 1090 case TypeTableEntryIdArray: 1091 case TypeTableEntryIdStruct: 1092 case TypeTableEntryIdMaybe: 1093 case TypeTableEntryIdErrorUnion: 1094 case TypeTableEntryIdPureError: 1095 case TypeTableEntryIdEnum: 1096 case TypeTableEntryIdUnion: 1097 case TypeTableEntryIdFn: 1098 case TypeTableEntryIdEnumTag: 1099 ensure_complete_type(g, type_entry); 1100 if (!fn_type_id.is_extern && !type_is_copyable(g, type_entry)) { 1101 add_node_error(g, param_node->data.param_decl.type, 1102 buf_sprintf("type '%s' is not copyable; cannot pass by value", buf_ptr(&type_entry->name))); 1103 return g->builtin_types.entry_invalid; 1104 } 1105 break; 1106 } 1107 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; 1108 param_info->type = type_entry; 1109 param_info->is_noalias = param_node->data.param_decl.is_noalias; 1110 } 1111 1112 fn_type_id.return_type = analyze_type_expr(g, child_scope, fn_proto->return_type); 1113 1114 switch (fn_type_id.return_type->id) { 1115 case TypeTableEntryIdInvalid: 1116 return g->builtin_types.entry_invalid; 1117 1118 case TypeTableEntryIdUndefLit: 1119 case TypeTableEntryIdNullLit: 1120 case TypeTableEntryIdArgTuple: 1121 case TypeTableEntryIdOpaque: 1122 add_node_error(g, fn_proto->return_type, 1123 buf_sprintf("return type '%s' not allowed", buf_ptr(&fn_type_id.return_type->name))); 1124 return g->builtin_types.entry_invalid; 1125 1126 case TypeTableEntryIdNumLitFloat: 1127 case TypeTableEntryIdNumLitInt: 1128 case TypeTableEntryIdNamespace: 1129 case TypeTableEntryIdBlock: 1130 case TypeTableEntryIdBoundFn: 1131 case TypeTableEntryIdVar: 1132 case TypeTableEntryIdMetaType: 1133 if (fn_type_id.is_extern) { 1134 add_node_error(g, fn_proto->return_type, 1135 buf_sprintf("return type '%s' not allowed in extern function", 1136 buf_ptr(&fn_type_id.return_type->name))); 1137 return g->builtin_types.entry_invalid; 1138 } 1139 return get_generic_fn_type(g, &fn_type_id); 1140 case TypeTableEntryIdUnreachable: 1141 case TypeTableEntryIdVoid: 1142 case TypeTableEntryIdBool: 1143 case TypeTableEntryIdInt: 1144 case TypeTableEntryIdFloat: 1145 case TypeTableEntryIdPointer: 1146 case TypeTableEntryIdArray: 1147 case TypeTableEntryIdStruct: 1148 case TypeTableEntryIdMaybe: 1149 case TypeTableEntryIdErrorUnion: 1150 case TypeTableEntryIdPureError: 1151 case TypeTableEntryIdEnum: 1152 case TypeTableEntryIdUnion: 1153 case TypeTableEntryIdFn: 1154 case TypeTableEntryIdEnumTag: 1155 break; 1156 } 1157 1158 return get_fn_type(g, &fn_type_id); 1159 } 1160 1161 bool type_is_invalid(TypeTableEntry *type_entry) { 1162 switch (type_entry->id) { 1163 case TypeTableEntryIdInvalid: 1164 return true; 1165 case TypeTableEntryIdStruct: 1166 return type_entry->data.structure.is_invalid; 1167 case TypeTableEntryIdEnum: 1168 return type_entry->data.enumeration.is_invalid; 1169 case TypeTableEntryIdUnion: 1170 return type_entry->data.unionation.is_invalid; 1171 default: 1172 return false; 1173 } 1174 zig_unreachable(); 1175 } 1176 1177 1178 TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type) { 1179 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdEnumTag); 1180 1181 buf_resize(&entry->name, 0); 1182 buf_appendf(&entry->name, "@enumTagType(%s)", buf_ptr(&enum_type->name)); 1183 1184 entry->is_copyable = true; 1185 entry->data.enum_tag.enum_type = enum_type; 1186 entry->data.enum_tag.int_type = int_type; 1187 entry->type_ref = int_type->type_ref; 1188 entry->di_type = int_type->di_type; 1189 entry->zero_bits = int_type->zero_bits; 1190 1191 return entry; 1192 } 1193 1194 static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) { 1195 // if you change this logic you likely must also change similar logic in parseh.cpp 1196 assert(enum_type->id == TypeTableEntryIdEnum); 1197 1198 if (enum_type->data.enumeration.complete) 1199 return; 1200 1201 resolve_enum_zero_bits(g, enum_type); 1202 if (enum_type->data.enumeration.is_invalid) 1203 return; 1204 1205 AstNode *decl_node = enum_type->data.enumeration.decl_node; 1206 1207 if (enum_type->data.enumeration.embedded_in_current) { 1208 if (!enum_type->data.enumeration.reported_infinite_err) { 1209 enum_type->data.enumeration.reported_infinite_err = true; 1210 add_node_error(g, decl_node, buf_sprintf("enum '%s' contains itself", buf_ptr(&enum_type->name))); 1211 } 1212 return; 1213 } 1214 1215 assert(!enum_type->data.enumeration.zero_bits_loop_flag); 1216 assert(decl_node->type == NodeTypeContainerDecl); 1217 assert(enum_type->di_type); 1218 1219 uint32_t field_count = enum_type->data.enumeration.src_field_count; 1220 1221 assert(enum_type->data.enumeration.fields); 1222 ZigLLVMDIEnumerator **di_enumerators = allocate<ZigLLVMDIEnumerator*>(field_count); 1223 1224 uint32_t gen_field_count = enum_type->data.enumeration.gen_field_count; 1225 ZigLLVMDIType **union_inner_di_types = allocate<ZigLLVMDIType*>(gen_field_count); 1226 1227 TypeTableEntry *biggest_union_member = nullptr; 1228 uint64_t biggest_align_in_bits = 0; 1229 uint64_t biggest_union_member_size_in_bits = 0; 1230 1231 Scope *scope = &enum_type->data.enumeration.decls_scope->base; 1232 ImportTableEntry *import = get_scope_import(scope); 1233 1234 // set temporary flag 1235 enum_type->data.enumeration.embedded_in_current = true; 1236 1237 for (uint32_t i = 0; i < field_count; i += 1) { 1238 AstNode *field_node = decl_node->data.container_decl.fields.at(i); 1239 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; 1240 TypeTableEntry *field_type = type_enum_field->type_entry; 1241 1242 di_enumerators[i] = ZigLLVMCreateDebugEnumerator(g->dbuilder, buf_ptr(type_enum_field->name), i); 1243 1244 ensure_complete_type(g, field_type); 1245 if (field_type->id == TypeTableEntryIdInvalid) { 1246 enum_type->data.enumeration.is_invalid = true; 1247 continue; 1248 } 1249 1250 if (!type_has_bits(field_type)) 1251 continue; 1252 1253 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref); 1254 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref); 1255 1256 assert(debug_size_in_bits > 0); 1257 assert(debug_align_in_bits > 0); 1258 1259 union_inner_di_types[type_enum_field->gen_index] = ZigLLVMCreateDebugMemberType(g->dbuilder, 1260 ZigLLVMTypeToScope(enum_type->di_type), buf_ptr(type_enum_field->name), 1261 import->di_file, (unsigned)(field_node->line + 1), 1262 debug_size_in_bits, 1263 debug_align_in_bits, 1264 0, 1265 0, field_type->di_type); 1266 1267 biggest_align_in_bits = max(biggest_align_in_bits, debug_align_in_bits); 1268 1269 if (!biggest_union_member || 1270 debug_size_in_bits > biggest_union_member_size_in_bits) 1271 { 1272 biggest_union_member = field_type; 1273 biggest_union_member_size_in_bits = debug_size_in_bits; 1274 } 1275 } 1276 1277 // unset temporary flag 1278 enum_type->data.enumeration.embedded_in_current = false; 1279 enum_type->data.enumeration.complete = true; 1280 1281 if (!enum_type->data.enumeration.is_invalid) { 1282 enum_type->data.enumeration.union_type = biggest_union_member; 1283 1284 TypeTableEntry *tag_int_type = get_smallest_unsigned_int_type(g, field_count); 1285 TypeTableEntry *tag_type_entry = create_enum_tag_type(g, enum_type, tag_int_type); 1286 enum_type->data.enumeration.tag_type = tag_type_entry; 1287 1288 if (biggest_union_member) { 1289 // create llvm type for union 1290 LLVMTypeRef union_element_type = biggest_union_member->type_ref; 1291 LLVMTypeRef union_type_ref = LLVMStructType(&union_element_type, 1, false); 1292 1293 // create llvm type for root struct 1294 LLVMTypeRef root_struct_element_types[] = { 1295 tag_type_entry->type_ref, 1296 union_type_ref, 1297 }; 1298 LLVMStructSetBody(enum_type->type_ref, root_struct_element_types, 2, false); 1299 1300 // create debug type for tag 1301 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref); 1302 uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, tag_type_entry->type_ref); 1303 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, 1304 ZigLLVMTypeToScope(enum_type->di_type), "AnonEnum", 1305 import->di_file, (unsigned)(decl_node->line + 1), 1306 tag_debug_size_in_bits, tag_debug_align_in_bits, di_enumerators, field_count, 1307 tag_type_entry->di_type, ""); 1308 1309 // create debug type for union 1310 ZigLLVMDIType *union_di_type = ZigLLVMCreateDebugUnionType(g->dbuilder, 1311 ZigLLVMTypeToScope(enum_type->di_type), "AnonUnion", 1312 import->di_file, (unsigned)(decl_node->line + 1), 1313 biggest_union_member_size_in_bits, biggest_align_in_bits, 0, union_inner_di_types, 1314 gen_field_count, 0, ""); 1315 1316 // create debug types for members of root struct 1317 uint64_t tag_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref, 0); 1318 ZigLLVMDIType *tag_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, 1319 ZigLLVMTypeToScope(enum_type->di_type), "tag_field", 1320 import->di_file, (unsigned)(decl_node->line + 1), 1321 tag_debug_size_in_bits, 1322 tag_debug_align_in_bits, 1323 tag_offset_in_bits, 1324 0, tag_di_type); 1325 1326 uint64_t union_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, enum_type->type_ref, 1); 1327 ZigLLVMDIType *union_member_di_type = ZigLLVMCreateDebugMemberType(g->dbuilder, 1328 ZigLLVMTypeToScope(enum_type->di_type), "union_field", 1329 import->di_file, (unsigned)(decl_node->line + 1), 1330 biggest_union_member_size_in_bits, 1331 biggest_align_in_bits, 1332 union_offset_in_bits, 1333 0, union_di_type); 1334 1335 // create debug type for root struct 1336 ZigLLVMDIType *di_root_members[] = { 1337 tag_member_di_type, 1338 union_member_di_type, 1339 }; 1340 1341 1342 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, enum_type->type_ref); 1343 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, enum_type->type_ref); 1344 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 1345 ZigLLVMFileToScope(import->di_file), 1346 buf_ptr(&enum_type->name), 1347 import->di_file, (unsigned)(decl_node->line + 1), 1348 debug_size_in_bits, 1349 debug_align_in_bits, 1350 0, nullptr, di_root_members, 2, 0, nullptr, ""); 1351 1352 ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, replacement_di_type); 1353 enum_type->di_type = replacement_di_type; 1354 } else { 1355 // create llvm type for root struct 1356 enum_type->type_ref = tag_type_entry->type_ref; 1357 1358 // create debug type for tag 1359 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type_entry->type_ref); 1360 uint64_t tag_debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, tag_type_entry->type_ref); 1361 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder, 1362 ZigLLVMFileToScope(import->di_file), buf_ptr(&enum_type->name), 1363 import->di_file, (unsigned)(decl_node->line + 1), 1364 tag_debug_size_in_bits, 1365 tag_debug_align_in_bits, 1366 di_enumerators, field_count, 1367 tag_type_entry->di_type, ""); 1368 1369 ZigLLVMReplaceTemporary(g->dbuilder, enum_type->di_type, tag_di_type); 1370 enum_type->di_type = tag_di_type; 1371 } 1372 } 1373 } 1374 1375 static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) { 1376 switch (type_entry->id) { 1377 case TypeTableEntryIdInvalid: 1378 case TypeTableEntryIdVar: 1379 zig_unreachable(); 1380 case TypeTableEntryIdMetaType: 1381 case TypeTableEntryIdUnreachable: 1382 case TypeTableEntryIdNumLitFloat: 1383 case TypeTableEntryIdNumLitInt: 1384 case TypeTableEntryIdUndefLit: 1385 case TypeTableEntryIdNullLit: 1386 case TypeTableEntryIdErrorUnion: 1387 case TypeTableEntryIdPureError: 1388 case TypeTableEntryIdEnum: 1389 case TypeTableEntryIdEnumTag: 1390 case TypeTableEntryIdNamespace: 1391 case TypeTableEntryIdBlock: 1392 case TypeTableEntryIdBoundFn: 1393 case TypeTableEntryIdArgTuple: 1394 case TypeTableEntryIdOpaque: 1395 return false; 1396 case TypeTableEntryIdVoid: 1397 case TypeTableEntryIdBool: 1398 case TypeTableEntryIdInt: 1399 case TypeTableEntryIdFloat: 1400 case TypeTableEntryIdPointer: 1401 case TypeTableEntryIdArray: 1402 case TypeTableEntryIdUnion: 1403 case TypeTableEntryIdFn: 1404 return true; 1405 case TypeTableEntryIdStruct: 1406 return type_entry->data.structure.layout == ContainerLayoutPacked; 1407 case TypeTableEntryIdMaybe: 1408 { 1409 TypeTableEntry *child_type = type_entry->data.maybe.child_type; 1410 return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn; 1411 } 1412 } 1413 zig_unreachable(); 1414 } 1415 1416 static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) { 1417 // if you change the logic of this function likely you must make a similar change in 1418 // parseh.cpp 1419 assert(struct_type->id == TypeTableEntryIdStruct); 1420 1421 if (struct_type->data.structure.complete) 1422 return; 1423 1424 resolve_struct_zero_bits(g, struct_type); 1425 if (struct_type->data.structure.is_invalid) 1426 return; 1427 1428 AstNode *decl_node = struct_type->data.structure.decl_node; 1429 1430 if (struct_type->data.structure.embedded_in_current) { 1431 struct_type->data.structure.is_invalid = true; 1432 if (!struct_type->data.structure.reported_infinite_err) { 1433 struct_type->data.structure.reported_infinite_err = true; 1434 add_node_error(g, decl_node, 1435 buf_sprintf("struct '%s' contains itself", buf_ptr(&struct_type->name))); 1436 } 1437 return; 1438 } 1439 1440 assert(!struct_type->data.structure.zero_bits_loop_flag); 1441 assert(struct_type->data.structure.fields); 1442 assert(decl_node->type == NodeTypeContainerDecl); 1443 1444 size_t field_count = struct_type->data.structure.src_field_count; 1445 1446 size_t gen_field_count = struct_type->data.structure.gen_field_count; 1447 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(gen_field_count); 1448 1449 // this field should be set to true only during the recursive calls to resolve_struct_type 1450 struct_type->data.structure.embedded_in_current = true; 1451 1452 Scope *scope = &struct_type->data.structure.decls_scope->base; 1453 1454 size_t gen_field_index = 0; 1455 bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked); 1456 size_t packed_bits_offset = 0; 1457 size_t first_packed_bits_offset_misalign = SIZE_MAX; 1458 size_t debug_field_count = 0; 1459 1460 for (size_t i = 0; i < field_count; i += 1) { 1461 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; 1462 TypeTableEntry *field_type = type_struct_field->type_entry; 1463 1464 ensure_complete_type(g, field_type); 1465 1466 if (type_is_invalid(field_type)) { 1467 struct_type->data.structure.is_invalid = true; 1468 break; 1469 } 1470 1471 if (!type_has_bits(field_type)) 1472 continue; 1473 1474 type_struct_field->gen_index = gen_field_index; 1475 1476 if (packed) { 1477 if (!type_allowed_in_packed_struct(field_type)) { 1478 AstNode *field_source_node = decl_node->data.container_decl.fields.at(i); 1479 add_node_error(g, field_source_node, 1480 buf_sprintf("packed structs cannot contain fields of type '%s'", 1481 buf_ptr(&field_type->name))); 1482 struct_type->data.structure.is_invalid = true; 1483 break; 1484 } 1485 1486 size_t field_size_in_bits = type_size_bits(g, field_type); 1487 size_t next_packed_bits_offset = packed_bits_offset + field_size_in_bits; 1488 1489 type_struct_field->packed_bits_size = field_size_in_bits; 1490 1491 if (first_packed_bits_offset_misalign != SIZE_MAX) { 1492 // this field is not byte-aligned; it is part of the previous field with a bit offset 1493 type_struct_field->packed_bits_offset = packed_bits_offset - first_packed_bits_offset_misalign; 1494 type_struct_field->unaligned_bit_count = field_size_in_bits; 1495 1496 size_t full_bit_count = next_packed_bits_offset - first_packed_bits_offset_misalign; 1497 LLVMTypeRef int_type_ref = LLVMIntType((unsigned)(full_bit_count)); 1498 if (8 * LLVMStoreSizeOfType(g->target_data_ref, int_type_ref) == full_bit_count) { 1499 // next field recovers store alignment 1500 element_types[gen_field_index] = int_type_ref; 1501 gen_field_index += 1; 1502 1503 first_packed_bits_offset_misalign = SIZE_MAX; 1504 } 1505 } else if (8 * LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref) != field_size_in_bits) { 1506 first_packed_bits_offset_misalign = packed_bits_offset; 1507 type_struct_field->packed_bits_offset = 0; 1508 type_struct_field->unaligned_bit_count = field_size_in_bits; 1509 } else { 1510 // This is a byte-aligned field (both start and end) in a packed struct. 1511 element_types[gen_field_index] = field_type->type_ref; 1512 type_struct_field->packed_bits_offset = 0; 1513 type_struct_field->unaligned_bit_count = 0; 1514 gen_field_index += 1; 1515 } 1516 packed_bits_offset = next_packed_bits_offset; 1517 } else { 1518 element_types[gen_field_index] = field_type->type_ref; 1519 assert(element_types[gen_field_index]); 1520 1521 gen_field_index += 1; 1522 } 1523 debug_field_count += 1; 1524 } 1525 if (first_packed_bits_offset_misalign != SIZE_MAX) { 1526 size_t full_bit_count = packed_bits_offset - first_packed_bits_offset_misalign; 1527 LLVMTypeRef int_type_ref = LLVMIntType((unsigned)full_bit_count); 1528 size_t store_bit_count = 8 * LLVMStoreSizeOfType(g->target_data_ref, int_type_ref); 1529 element_types[gen_field_index] = LLVMIntType((unsigned)store_bit_count); 1530 gen_field_index += 1; 1531 } 1532 1533 struct_type->data.structure.embedded_in_current = false; 1534 struct_type->data.structure.complete = true; 1535 1536 if (struct_type->data.structure.is_invalid) 1537 return; 1538 1539 if (struct_type->zero_bits) { 1540 struct_type->type_ref = LLVMVoidType(); 1541 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, g->builtin_types.entry_void->di_type); 1542 struct_type->di_type = g->builtin_types.entry_void->di_type; 1543 return; 1544 } 1545 assert(struct_type->di_type); 1546 1547 1548 // the count may have been adjusting from packing bit fields 1549 gen_field_count = gen_field_index; 1550 struct_type->data.structure.gen_field_count = (uint32_t)gen_field_count; 1551 1552 LLVMStructSetBody(struct_type->type_ref, element_types, (unsigned)gen_field_count, packed); 1553 assert(LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref) > 0); 1554 1555 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(debug_field_count); 1556 1557 ImportTableEntry *import = get_scope_import(scope); 1558 size_t debug_field_index = 0; 1559 for (size_t i = 0; i < field_count; i += 1) { 1560 AstNode *field_node = decl_node->data.container_decl.fields.at(i); 1561 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; 1562 size_t gen_field_index = type_struct_field->gen_index; 1563 if (gen_field_index == SIZE_MAX) { 1564 continue; 1565 } 1566 1567 TypeTableEntry *field_type = type_struct_field->type_entry; 1568 1569 // if the field is a function, actually the debug info should be a pointer. 1570 ZigLLVMDIType *field_di_type; 1571 if (field_type->id == TypeTableEntryIdFn) { 1572 TypeTableEntry *field_ptr_type = get_pointer_to_type(g, field_type, true); 1573 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_ptr_type->type_ref); 1574 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_ptr_type->type_ref); 1575 field_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, field_type->di_type, 1576 debug_size_in_bits, debug_align_in_bits, buf_ptr(&field_ptr_type->name)); 1577 } else { 1578 field_di_type = field_type->di_type; 1579 } 1580 1581 assert(field_type->type_ref); 1582 assert(struct_type->type_ref); 1583 assert(struct_type->data.structure.complete); 1584 uint64_t debug_size_in_bits; 1585 uint64_t debug_align_in_bits; 1586 uint64_t debug_offset_in_bits; 1587 if (packed) { 1588 debug_size_in_bits = type_struct_field->packed_bits_size; 1589 debug_align_in_bits = 1; 1590 debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, 1591 (unsigned)gen_field_index) + type_struct_field->packed_bits_offset; 1592 } else { 1593 debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref); 1594 debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref); 1595 debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, 1596 (unsigned)gen_field_index); 1597 } 1598 di_element_types[debug_field_index] = ZigLLVMCreateDebugMemberType(g->dbuilder, 1599 ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name), 1600 import->di_file, (unsigned)(field_node->line + 1), 1601 debug_size_in_bits, 1602 debug_align_in_bits, 1603 debug_offset_in_bits, 1604 0, field_di_type); 1605 assert(di_element_types[debug_field_index]); 1606 debug_field_index += 1; 1607 } 1608 1609 1610 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref); 1611 uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, struct_type->type_ref); 1612 ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder, 1613 ZigLLVMFileToScope(import->di_file), 1614 buf_ptr(&struct_type->name), 1615 import->di_file, (unsigned)(decl_node->line + 1), 1616 debug_size_in_bits, 1617 debug_align_in_bits, 1618 0, nullptr, di_element_types, (int)debug_field_count, 0, nullptr, ""); 1619 1620 ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type); 1621 struct_type->di_type = replacement_di_type; 1622 } 1623 1624 static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) { 1625 zig_panic("TODO"); 1626 } 1627 1628 static void resolve_enum_zero_bits(CodeGen *g, TypeTableEntry *enum_type) { 1629 assert(enum_type->id == TypeTableEntryIdEnum); 1630 1631 if (enum_type->data.enumeration.zero_bits_known) 1632 return; 1633 1634 if (enum_type->data.enumeration.zero_bits_loop_flag) { 1635 enum_type->data.enumeration.zero_bits_known = true; 1636 return; 1637 } 1638 1639 enum_type->data.enumeration.zero_bits_loop_flag = true; 1640 1641 AstNode *decl_node = enum_type->data.enumeration.decl_node; 1642 assert(decl_node->type == NodeTypeContainerDecl); 1643 assert(enum_type->di_type); 1644 1645 assert(!enum_type->data.enumeration.fields); 1646 uint32_t field_count = (uint32_t)decl_node->data.container_decl.fields.length; 1647 enum_type->data.enumeration.src_field_count = field_count; 1648 enum_type->data.enumeration.fields = allocate<TypeEnumField>(field_count); 1649 1650 Scope *scope = &enum_type->data.enumeration.decls_scope->base; 1651 1652 uint32_t gen_field_index = 0; 1653 for (uint32_t i = 0; i < field_count; i += 1) { 1654 AstNode *field_node = decl_node->data.container_decl.fields.at(i); 1655 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; 1656 type_enum_field->name = field_node->data.struct_field.name; 1657 TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); 1658 type_enum_field->type_entry = field_type; 1659 type_enum_field->value = i; 1660 1661 type_ensure_zero_bits_known(g, field_type); 1662 if (field_type->id == TypeTableEntryIdInvalid) { 1663 enum_type->data.enumeration.is_invalid = true; 1664 continue; 1665 } 1666 1667 if (!type_has_bits(field_type)) 1668 continue; 1669 1670 type_enum_field->gen_index = gen_field_index; 1671 gen_field_index += 1; 1672 } 1673 1674 enum_type->data.enumeration.zero_bits_loop_flag = false; 1675 enum_type->data.enumeration.gen_field_count = gen_field_index; 1676 enum_type->zero_bits = (gen_field_index == 0 && field_count < 2); 1677 enum_type->data.enumeration.zero_bits_known = true; 1678 } 1679 1680 static void resolve_struct_zero_bits(CodeGen *g, TypeTableEntry *struct_type) { 1681 assert(struct_type->id == TypeTableEntryIdStruct); 1682 1683 if (struct_type->data.structure.zero_bits_known) 1684 return; 1685 1686 if (struct_type->data.structure.zero_bits_loop_flag) { 1687 struct_type->data.structure.zero_bits_known = true; 1688 return; 1689 } 1690 1691 struct_type->data.structure.zero_bits_loop_flag = true; 1692 1693 AstNode *decl_node = struct_type->data.structure.decl_node; 1694 assert(decl_node->type == NodeTypeContainerDecl); 1695 assert(struct_type->di_type); 1696 1697 assert(!struct_type->data.structure.fields); 1698 size_t field_count = decl_node->data.container_decl.fields.length; 1699 struct_type->data.structure.src_field_count = (uint32_t)field_count; 1700 struct_type->data.structure.fields = allocate<TypeStructField>(field_count); 1701 1702 Scope *scope = &struct_type->data.structure.decls_scope->base; 1703 1704 size_t gen_field_index = 0; 1705 for (size_t i = 0; i < field_count; i += 1) { 1706 AstNode *field_node = decl_node->data.container_decl.fields.at(i); 1707 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i]; 1708 type_struct_field->name = field_node->data.struct_field.name; 1709 TypeTableEntry *field_type = analyze_type_expr(g, scope, field_node->data.struct_field.type); 1710 type_struct_field->type_entry = field_type; 1711 type_struct_field->src_index = i; 1712 type_struct_field->gen_index = SIZE_MAX; 1713 1714 type_ensure_zero_bits_known(g, field_type); 1715 if (type_is_invalid(field_type)) { 1716 struct_type->data.structure.is_invalid = true; 1717 continue; 1718 } 1719 1720 if (!type_has_bits(field_type)) 1721 continue; 1722 1723 type_struct_field->gen_index = gen_field_index; 1724 gen_field_index += 1; 1725 } 1726 1727 struct_type->data.structure.zero_bits_loop_flag = false; 1728 struct_type->data.structure.gen_field_count = (uint32_t)gen_field_index; 1729 struct_type->zero_bits = (gen_field_index == 0); 1730 struct_type->data.structure.zero_bits_known = true; 1731 } 1732 1733 static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) { 1734 zig_panic("TODO resolve_union_zero_bits"); 1735 } 1736 1737 static void get_fully_qualified_decl_name_internal(Buf *buf, Scope *scope, uint8_t sep) { 1738 if (!scope) 1739 return; 1740 1741 if (scope->id == ScopeIdDecls) { 1742 get_fully_qualified_decl_name_internal(buf, scope->parent, sep); 1743 1744 ScopeDecls *scope_decls = (ScopeDecls *)scope; 1745 if (scope_decls->container_type) { 1746 buf_append_buf(buf, &scope_decls->container_type->name); 1747 buf_append_char(buf, sep); 1748 } 1749 return; 1750 } 1751 1752 get_fully_qualified_decl_name_internal(buf, scope->parent, sep); 1753 } 1754 1755 static void get_fully_qualified_decl_name(Buf *buf, Tld *tld, uint8_t sep) { 1756 buf_resize(buf, 0); 1757 get_fully_qualified_decl_name_internal(buf, tld->parent_scope, sep); 1758 buf_append_buf(buf, tld->name); 1759 } 1760 1761 FnTableEntry *create_fn_raw(FnInline inline_value, GlobalLinkageId linkage) { 1762 FnTableEntry *fn_entry = allocate<FnTableEntry>(1); 1763 1764 fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc; 1765 fn_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota; 1766 fn_entry->analyzed_executable.fn_entry = fn_entry; 1767 fn_entry->ir_executable.fn_entry = fn_entry; 1768 fn_entry->fn_inline = inline_value; 1769 fn_entry->linkage = linkage; 1770 1771 return fn_entry; 1772 } 1773 1774 FnTableEntry *create_fn(AstNode *proto_node) { 1775 assert(proto_node->type == NodeTypeFnProto); 1776 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; 1777 1778 FnInline inline_value = fn_proto->is_inline ? FnInlineAlways : FnInlineAuto; 1779 GlobalLinkageId linkage = (fn_proto->visib_mod == VisibModExport || proto_node->data.fn_proto.is_extern) ? 1780 GlobalLinkageIdStrong : GlobalLinkageIdInternal; 1781 FnTableEntry *fn_entry = create_fn_raw(inline_value, linkage); 1782 1783 fn_entry->proto_node = proto_node; 1784 fn_entry->body_node = (proto_node->data.fn_proto.fn_def_node == nullptr) ? nullptr : 1785 proto_node->data.fn_proto.fn_def_node->data.fn_def.body; 1786 1787 return fn_entry; 1788 } 1789 1790 static bool scope_is_root_decls(Scope *scope) { 1791 while (scope) { 1792 if (scope->id == ScopeIdDecls) { 1793 ScopeDecls *scope_decls = (ScopeDecls *)scope; 1794 return (scope_decls->container_type == nullptr); 1795 } 1796 scope = scope->parent; 1797 } 1798 zig_unreachable(); 1799 } 1800 1801 static void wrong_panic_prototype(CodeGen *g, AstNode *proto_node, TypeTableEntry *fn_type) { 1802 add_node_error(g, proto_node, 1803 buf_sprintf("expected 'fn([]const u8) -> unreachable', found '%s'", 1804 buf_ptr(&fn_type->name))); 1805 } 1806 1807 static void typecheck_panic_fn(CodeGen *g, FnTableEntry *panic_fn) { 1808 AstNode *proto_node = panic_fn->proto_node; 1809 assert(proto_node->type == NodeTypeFnProto); 1810 TypeTableEntry *fn_type = panic_fn->type_entry; 1811 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 1812 if (fn_type_id->param_count != 1) { 1813 return wrong_panic_prototype(g, proto_node, fn_type); 1814 } 1815 TypeTableEntry *const_u8_slice = get_slice_type(g, g->builtin_types.entry_u8, true); 1816 if (fn_type_id->param_info[0].type != const_u8_slice) { 1817 return wrong_panic_prototype(g, proto_node, fn_type); 1818 } 1819 1820 TypeTableEntry *actual_return_type = fn_type_id->return_type; 1821 if (actual_return_type != g->builtin_types.entry_unreachable) { 1822 return wrong_panic_prototype(g, proto_node, fn_type); 1823 } 1824 } 1825 1826 static TypeTableEntry *get_test_fn_type(CodeGen *g) { 1827 if (g->test_fn_type) 1828 return g->test_fn_type; 1829 1830 FnTypeId fn_type_id = {0}; 1831 fn_type_id.return_type = g->builtin_types.entry_void; 1832 g->test_fn_type = get_fn_type(g, &fn_type_id); 1833 return g->test_fn_type; 1834 } 1835 1836 static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { 1837 ImportTableEntry *import = tld_fn->base.import; 1838 AstNode *source_node = tld_fn->base.source_node; 1839 if (source_node->type == NodeTypeFnProto) { 1840 AstNodeFnProto *fn_proto = &source_node->data.fn_proto; 1841 1842 AstNode *fn_def_node = fn_proto->fn_def_node; 1843 1844 FnTableEntry *fn_table_entry = create_fn(source_node); 1845 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); 1846 1847 tld_fn->fn_entry = fn_table_entry; 1848 1849 if (fn_table_entry->body_node) { 1850 fn_table_entry->fndef_scope = create_fndef_scope( 1851 fn_table_entry->body_node, tld_fn->base.parent_scope, fn_table_entry); 1852 1853 for (size_t i = 0; i < fn_proto->params.length; i += 1) { 1854 AstNode *param_node = fn_proto->params.at(i); 1855 assert(param_node->type == NodeTypeParamDecl); 1856 if (buf_len(param_node->data.param_decl.name) == 0) { 1857 add_node_error(g, param_node, buf_sprintf("missing parameter name")); 1858 } 1859 } 1860 } else if (fn_table_entry->linkage != GlobalLinkageIdInternal) { 1861 g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base); 1862 } 1863 1864 Scope *child_scope = fn_table_entry->fndef_scope ? &fn_table_entry->fndef_scope->base : tld_fn->base.parent_scope; 1865 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope); 1866 1867 if (fn_table_entry->type_entry->id == TypeTableEntryIdInvalid) { 1868 tld_fn->base.resolution = TldResolutionInvalid; 1869 return; 1870 } 1871 1872 if (!fn_table_entry->type_entry->data.fn.is_generic) { 1873 g->fn_protos.append(fn_table_entry); 1874 1875 if (fn_def_node) 1876 g->fn_defs.append(fn_table_entry); 1877 1878 if (g->have_pub_main && import == g->root_import && scope_is_root_decls(tld_fn->base.parent_scope)) { 1879 if (buf_eql_str(&fn_table_entry->symbol_name, "main")) { 1880 g->main_fn = fn_table_entry; 1881 1882 if (!g->link_libc && tld_fn->base.visib_mod != VisibModExport) { 1883 TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void); 1884 TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type; 1885 if (actual_return_type != err_void) { 1886 add_node_error(g, fn_proto->return_type, 1887 buf_sprintf("expected return type of main to be '%%void', instead is '%s'", 1888 buf_ptr(&actual_return_type->name))); 1889 } 1890 } 1891 } else if (buf_eql_str(&fn_table_entry->symbol_name, "panic")) { 1892 typecheck_panic_fn(g, fn_table_entry); 1893 } 1894 } else if (import->package == g->zigrt_package && scope_is_root_decls(tld_fn->base.parent_scope)) { 1895 if (buf_eql_str(&fn_table_entry->symbol_name, "__zig_panic")) { 1896 g->extern_panic_fn = fn_table_entry; 1897 } 1898 } 1899 } 1900 } else if (source_node->type == NodeTypeTestDecl) { 1901 FnTableEntry *fn_table_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong); 1902 1903 get_fully_qualified_decl_name(&fn_table_entry->symbol_name, &tld_fn->base, '_'); 1904 1905 tld_fn->fn_entry = fn_table_entry; 1906 1907 fn_table_entry->proto_node = source_node; 1908 fn_table_entry->fndef_scope = create_fndef_scope(source_node, tld_fn->base.parent_scope, fn_table_entry); 1909 fn_table_entry->type_entry = get_test_fn_type(g); 1910 fn_table_entry->body_node = source_node->data.test_decl.body; 1911 fn_table_entry->is_test = true; 1912 g->test_fn_count += 1; 1913 1914 g->fn_protos.append(fn_table_entry); 1915 g->fn_defs.append(fn_table_entry); 1916 1917 } else { 1918 zig_unreachable(); 1919 } 1920 } 1921 1922 static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) { 1923 assert(tld_comptime->base.source_node->type == NodeTypeCompTime); 1924 AstNode *expr_node = tld_comptime->base.source_node->data.comptime_expr.expr; 1925 analyze_const_value(g, tld_comptime->base.parent_scope, expr_node, g->builtin_types.entry_void, nullptr); 1926 } 1927 1928 static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) { 1929 if (tld->visib_mod == VisibModExport || (tld->id == TldIdVar && g->is_test_build)) { 1930 g->resolve_queue.append(tld); 1931 } 1932 1933 if (tld->visib_mod == VisibModExport) { 1934 auto entry = g->exported_symbol_names.put_unique(tld->name, tld); 1935 if (entry) { 1936 Tld *other_tld = entry->value; 1937 ErrorMsg *msg = add_node_error(g, tld->source_node, 1938 buf_sprintf("exported symbol collision: '%s'", buf_ptr(tld->name))); 1939 add_error_note(g, msg, other_tld->source_node, buf_sprintf("other symbol is here")); 1940 } 1941 } 1942 1943 auto entry = decls_scope->decl_table.put_unique(tld->name, tld); 1944 if (entry) { 1945 Tld *other_tld = entry->value; 1946 ErrorMsg *msg = add_node_error(g, tld->source_node, buf_sprintf("redefinition of '%s'", buf_ptr(tld->name))); 1947 add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition is here")); 1948 return; 1949 } 1950 } 1951 1952 static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) { 1953 assert(node->type == NodeTypeTestDecl); 1954 1955 if (!g->is_test_build) 1956 return; 1957 1958 ImportTableEntry *import = get_scope_import(&decls_scope->base); 1959 if (import->package != g->root_package) 1960 return; 1961 1962 Buf *decl_name_buf = node->data.test_decl.name; 1963 1964 Buf *test_name = g->test_name_prefix ? 1965 buf_sprintf("%s%s", buf_ptr(g->test_name_prefix), buf_ptr(decl_name_buf)) : decl_name_buf; 1966 1967 if (g->test_filter != nullptr && strstr(buf_ptr(test_name), buf_ptr(g->test_filter)) == nullptr) { 1968 return; 1969 } 1970 1971 TldFn *tld_fn = allocate<TldFn>(1); 1972 init_tld(&tld_fn->base, TldIdFn, test_name, VisibModPrivate, node, &decls_scope->base); 1973 g->resolve_queue.append(&tld_fn->base); 1974 } 1975 1976 static void preview_error_value_decl(CodeGen *g, AstNode *node) { 1977 assert(node->type == NodeTypeErrorValueDecl); 1978 1979 ErrorTableEntry *err = allocate<ErrorTableEntry>(1); 1980 1981 err->decl_node = node; 1982 buf_init_from_buf(&err->name, node->data.error_value_decl.name); 1983 1984 auto existing_entry = g->error_table.maybe_get(&err->name); 1985 if (existing_entry) { 1986 // duplicate error definitions allowed and they get the same value 1987 err->value = existing_entry->value->value; 1988 } else { 1989 size_t error_value_count = g->error_decls.length; 1990 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)g->err_tag_type->data.integral.bit_count)); 1991 err->value = (uint32_t)error_value_count; 1992 g->error_decls.append(node); 1993 g->error_table.put(&err->name, err); 1994 } 1995 1996 node->data.error_value_decl.err = err; 1997 } 1998 1999 static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) { 2000 assert(node->type == NodeTypeCompTime); 2001 2002 TldCompTime *tld_comptime = allocate<TldCompTime>(1); 2003 init_tld(&tld_comptime->base, TldIdCompTime, nullptr, VisibModPrivate, node, &decls_scope->base); 2004 g->resolve_queue.append(&tld_comptime->base); 2005 } 2006 2007 2008 void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node, 2009 Scope *parent_scope) 2010 { 2011 tld->id = id; 2012 tld->name = name; 2013 tld->visib_mod = visib_mod; 2014 tld->source_node = source_node; 2015 tld->import = source_node ? source_node->owner : nullptr; 2016 tld->parent_scope = parent_scope; 2017 } 2018 2019 void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { 2020 switch (node->type) { 2021 case NodeTypeRoot: 2022 for (size_t i = 0; i < node->data.root.top_level_decls.length; i += 1) { 2023 AstNode *child = node->data.root.top_level_decls.at(i); 2024 scan_decls(g, decls_scope, child); 2025 } 2026 break; 2027 case NodeTypeFnDef: 2028 scan_decls(g, decls_scope, node->data.fn_def.fn_proto); 2029 break; 2030 case NodeTypeVariableDeclaration: 2031 { 2032 Buf *name = node->data.variable_declaration.symbol; 2033 VisibMod visib_mod = node->data.variable_declaration.visib_mod; 2034 TldVar *tld_var = allocate<TldVar>(1); 2035 init_tld(&tld_var->base, TldIdVar, name, visib_mod, node, &decls_scope->base); 2036 add_top_level_decl(g, decls_scope, &tld_var->base); 2037 break; 2038 } 2039 case NodeTypeFnProto: 2040 { 2041 // if the name is missing, we immediately announce an error 2042 Buf *fn_name = node->data.fn_proto.name; 2043 if (buf_len(fn_name) == 0) { 2044 add_node_error(g, node, buf_sprintf("missing function name")); 2045 break; 2046 } 2047 2048 VisibMod visib_mod = node->data.fn_proto.visib_mod; 2049 TldFn *tld_fn = allocate<TldFn>(1); 2050 init_tld(&tld_fn->base, TldIdFn, fn_name, visib_mod, node, &decls_scope->base); 2051 add_top_level_decl(g, decls_scope, &tld_fn->base); 2052 2053 ImportTableEntry *import = get_scope_import(&decls_scope->base); 2054 if (import == g->root_import && scope_is_root_decls(&decls_scope->base) && 2055 buf_eql_str(fn_name, "panic")) 2056 { 2057 g->compile_vars.put(buf_create_from_str("panic_implementation_provided"), 2058 create_const_bool(g, true)); 2059 } 2060 2061 break; 2062 } 2063 case NodeTypeUse: 2064 { 2065 g->use_queue.append(node); 2066 ImportTableEntry *import = get_scope_import(&decls_scope->base); 2067 import->use_decls.append(node); 2068 break; 2069 } 2070 case NodeTypeErrorValueDecl: 2071 // error value declarations do not depend on other top level decls 2072 preview_error_value_decl(g, node); 2073 break; 2074 case NodeTypeTestDecl: 2075 preview_test_decl(g, node, decls_scope); 2076 break; 2077 case NodeTypeCompTime: 2078 preview_comptime_decl(g, node, decls_scope); 2079 break; 2080 case NodeTypeContainerDecl: 2081 case NodeTypeParamDecl: 2082 case NodeTypeFnDecl: 2083 case NodeTypeReturnExpr: 2084 case NodeTypeDefer: 2085 case NodeTypeBlock: 2086 case NodeTypeGroupedExpr: 2087 case NodeTypeBinOpExpr: 2088 case NodeTypeUnwrapErrorExpr: 2089 case NodeTypeFnCallExpr: 2090 case NodeTypeArrayAccessExpr: 2091 case NodeTypeSliceExpr: 2092 case NodeTypeNumberLiteral: 2093 case NodeTypeStringLiteral: 2094 case NodeTypeCharLiteral: 2095 case NodeTypeBoolLiteral: 2096 case NodeTypeNullLiteral: 2097 case NodeTypeUndefinedLiteral: 2098 case NodeTypeThisLiteral: 2099 case NodeTypeSymbol: 2100 case NodeTypePrefixOpExpr: 2101 case NodeTypeIfBoolExpr: 2102 case NodeTypeWhileExpr: 2103 case NodeTypeForExpr: 2104 case NodeTypeSwitchExpr: 2105 case NodeTypeSwitchProng: 2106 case NodeTypeSwitchRange: 2107 case NodeTypeLabel: 2108 case NodeTypeGoto: 2109 case NodeTypeBreak: 2110 case NodeTypeContinue: 2111 case NodeTypeUnreachable: 2112 case NodeTypeAsmExpr: 2113 case NodeTypeFieldAccessExpr: 2114 case NodeTypeStructField: 2115 case NodeTypeContainerInitExpr: 2116 case NodeTypeStructValueField: 2117 case NodeTypeArrayType: 2118 case NodeTypeErrorType: 2119 case NodeTypeVarLiteral: 2120 case NodeTypeTryExpr: 2121 case NodeTypeTestExpr: 2122 case NodeTypeInlineExpr: 2123 zig_unreachable(); 2124 } 2125 } 2126 2127 static void resolve_decl_container(CodeGen *g, TldContainer *tld_container) { 2128 TypeTableEntry *type_entry = tld_container->type_entry; 2129 assert(type_entry); 2130 2131 switch (type_entry->id) { 2132 case TypeTableEntryIdStruct: 2133 resolve_struct_type(g, tld_container->type_entry); 2134 return; 2135 case TypeTableEntryIdEnum: 2136 resolve_enum_type(g, tld_container->type_entry); 2137 return; 2138 case TypeTableEntryIdUnion: 2139 resolve_union_type(g, tld_container->type_entry); 2140 return; 2141 default: 2142 zig_unreachable(); 2143 } 2144 } 2145 2146 TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEntry *type_entry) { 2147 switch (type_entry->id) { 2148 case TypeTableEntryIdInvalid: 2149 return g->builtin_types.entry_invalid; 2150 case TypeTableEntryIdUnreachable: 2151 case TypeTableEntryIdVar: 2152 case TypeTableEntryIdNumLitFloat: 2153 case TypeTableEntryIdNumLitInt: 2154 case TypeTableEntryIdUndefLit: 2155 case TypeTableEntryIdNullLit: 2156 case TypeTableEntryIdBlock: 2157 case TypeTableEntryIdArgTuple: 2158 case TypeTableEntryIdOpaque: 2159 add_node_error(g, source_node, buf_sprintf("variable of type '%s' not allowed", 2160 buf_ptr(&type_entry->name))); 2161 return g->builtin_types.entry_invalid; 2162 case TypeTableEntryIdNamespace: 2163 case TypeTableEntryIdMetaType: 2164 case TypeTableEntryIdVoid: 2165 case TypeTableEntryIdBool: 2166 case TypeTableEntryIdInt: 2167 case TypeTableEntryIdFloat: 2168 case TypeTableEntryIdPointer: 2169 case TypeTableEntryIdArray: 2170 case TypeTableEntryIdStruct: 2171 case TypeTableEntryIdMaybe: 2172 case TypeTableEntryIdErrorUnion: 2173 case TypeTableEntryIdPureError: 2174 case TypeTableEntryIdEnum: 2175 case TypeTableEntryIdUnion: 2176 case TypeTableEntryIdFn: 2177 case TypeTableEntryIdBoundFn: 2178 case TypeTableEntryIdEnumTag: 2179 return type_entry; 2180 } 2181 zig_unreachable(); 2182 } 2183 2184 // Set name to nullptr to make the variable anonymous (not visible to programmer). 2185 // TODO merge with definition of add_local_var in ir.cpp 2186 VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name, 2187 bool is_const, ConstExprValue *value, Tld *src_tld) 2188 { 2189 assert(value); 2190 2191 VariableTableEntry *variable_entry = allocate<VariableTableEntry>(1); 2192 variable_entry->value = value; 2193 variable_entry->parent_scope = parent_scope; 2194 variable_entry->shadowable = false; 2195 variable_entry->mem_slot_index = SIZE_MAX; 2196 variable_entry->src_arg_index = SIZE_MAX; 2197 2198 assert(name); 2199 2200 buf_init_from_buf(&variable_entry->name, name); 2201 2202 if (value->type->id != TypeTableEntryIdInvalid) { 2203 VariableTableEntry *existing_var = find_variable(g, parent_scope, name); 2204 if (existing_var && !existing_var->shadowable) { 2205 ErrorMsg *msg = add_node_error(g, source_node, 2206 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); 2207 add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); 2208 variable_entry->value->type = g->builtin_types.entry_invalid; 2209 } else { 2210 auto primitive_table_entry = g->primitive_type_table.maybe_get(name); 2211 if (primitive_table_entry) { 2212 TypeTableEntry *type = primitive_table_entry->value; 2213 add_node_error(g, source_node, 2214 buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); 2215 variable_entry->value->type = g->builtin_types.entry_invalid; 2216 } else if (src_tld == nullptr) { 2217 Tld *tld = find_decl(g, parent_scope, name); 2218 if (tld) { 2219 ErrorMsg *msg = add_node_error(g, source_node, 2220 buf_sprintf("redefinition of '%s'", buf_ptr(name))); 2221 add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here")); 2222 variable_entry->value->type = g->builtin_types.entry_invalid; 2223 } 2224 } 2225 } 2226 } 2227 2228 Scope *child_scope; 2229 if (source_node && source_node->type == NodeTypeParamDecl) { 2230 child_scope = create_var_scope(source_node, parent_scope, variable_entry); 2231 } else { 2232 // it's already in the decls table 2233 child_scope = parent_scope; 2234 } 2235 2236 2237 variable_entry->src_is_const = is_const; 2238 variable_entry->gen_is_const = is_const; 2239 variable_entry->decl_node = source_node; 2240 variable_entry->child_scope = child_scope; 2241 2242 2243 return variable_entry; 2244 } 2245 2246 static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { 2247 AstNodeVariableDeclaration *var_decl = &tld_var->base.source_node->data.variable_declaration; 2248 2249 bool is_const = var_decl->is_const; 2250 bool is_export = (tld_var->base.visib_mod == VisibModExport); 2251 bool is_extern = var_decl->is_extern; 2252 2253 TypeTableEntry *explicit_type = nullptr; 2254 if (var_decl->type) { 2255 TypeTableEntry *proposed_type = analyze_type_expr(g, tld_var->base.parent_scope, var_decl->type); 2256 explicit_type = validate_var_type(g, var_decl->type, proposed_type); 2257 } 2258 2259 AstNode *source_node = tld_var->base.source_node; 2260 2261 if (is_export && is_extern) { 2262 add_node_error(g, source_node, buf_sprintf("variable is both export and extern")); 2263 } 2264 2265 VarLinkage linkage; 2266 if (is_export) { 2267 linkage = VarLinkageExport; 2268 } else if (is_extern) { 2269 linkage = VarLinkageExternal; 2270 } else { 2271 linkage = VarLinkageInternal; 2272 } 2273 2274 2275 IrInstruction *init_value = nullptr; 2276 2277 TypeTableEntry *implicit_type = nullptr; 2278 if (explicit_type && explicit_type->id == TypeTableEntryIdInvalid) { 2279 implicit_type = explicit_type; 2280 } else if (var_decl->expr) { 2281 init_value = analyze_const_value(g, tld_var->base.parent_scope, var_decl->expr, explicit_type, var_decl->symbol); 2282 assert(init_value); 2283 implicit_type = init_value->value.type; 2284 2285 if (implicit_type->id == TypeTableEntryIdUnreachable) { 2286 add_node_error(g, source_node, buf_sprintf("variable initialization is unreachable")); 2287 implicit_type = g->builtin_types.entry_invalid; 2288 } else if ((!is_const || linkage == VarLinkageExternal) && 2289 (implicit_type->id == TypeTableEntryIdNumLitFloat || 2290 implicit_type->id == TypeTableEntryIdNumLitInt)) 2291 { 2292 add_node_error(g, source_node, buf_sprintf("unable to infer variable type")); 2293 implicit_type = g->builtin_types.entry_invalid; 2294 } else if (implicit_type->id == TypeTableEntryIdNullLit) { 2295 add_node_error(g, source_node, buf_sprintf("unable to infer variable type")); 2296 implicit_type = g->builtin_types.entry_invalid; 2297 } else if (implicit_type->id == TypeTableEntryIdMetaType && !is_const) { 2298 add_node_error(g, source_node, buf_sprintf("variable of type 'type' must be constant")); 2299 implicit_type = g->builtin_types.entry_invalid; 2300 } 2301 assert(implicit_type->id == TypeTableEntryIdInvalid || init_value->value.special != ConstValSpecialRuntime); 2302 } else if (linkage != VarLinkageExternal) { 2303 add_node_error(g, source_node, buf_sprintf("variables must be initialized")); 2304 implicit_type = g->builtin_types.entry_invalid; 2305 } 2306 2307 TypeTableEntry *type = explicit_type ? explicit_type : implicit_type; 2308 assert(type != nullptr); // should have been caught by the parser 2309 2310 ConstExprValue *init_val = init_value ? &init_value->value : create_const_runtime(type); 2311 2312 tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, var_decl->symbol, 2313 is_const, init_val, &tld_var->base); 2314 tld_var->var->linkage = linkage; 2315 2316 g->global_vars.append(tld_var); 2317 } 2318 2319 void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only) { 2320 if (tld->resolution != TldResolutionUnresolved) 2321 return; 2322 2323 if (tld->dep_loop_flag) { 2324 add_node_error(g, tld->source_node, buf_sprintf("'%s' depends on itself", buf_ptr(tld->name))); 2325 tld->resolution = TldResolutionInvalid; 2326 return; 2327 } else { 2328 tld->dep_loop_flag = true; 2329 } 2330 2331 switch (tld->id) { 2332 case TldIdVar: 2333 { 2334 TldVar *tld_var = (TldVar *)tld; 2335 resolve_decl_var(g, tld_var); 2336 break; 2337 } 2338 case TldIdFn: 2339 { 2340 TldFn *tld_fn = (TldFn *)tld; 2341 resolve_decl_fn(g, tld_fn); 2342 break; 2343 } 2344 case TldIdContainer: 2345 { 2346 TldContainer *tld_container = (TldContainer *)tld; 2347 resolve_decl_container(g, tld_container); 2348 break; 2349 } 2350 case TldIdCompTime: 2351 { 2352 TldCompTime *tld_comptime = (TldCompTime *)tld; 2353 resolve_decl_comptime(g, tld_comptime); 2354 break; 2355 } 2356 } 2357 2358 tld->resolution = TldResolutionOk; 2359 tld->dep_loop_flag = false; 2360 } 2361 2362 bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTableEntry *actual_type) { 2363 if (expected_type == actual_type) 2364 return true; 2365 2366 // pointer const 2367 if (expected_type->id == TypeTableEntryIdPointer && 2368 actual_type->id == TypeTableEntryIdPointer && 2369 (!actual_type->data.pointer.is_const || expected_type->data.pointer.is_const) && 2370 (!actual_type->data.pointer.is_volatile || expected_type->data.pointer.is_volatile) && 2371 actual_type->data.pointer.bit_offset == expected_type->data.pointer.bit_offset && 2372 actual_type->data.pointer.unaligned_bit_count == expected_type->data.pointer.unaligned_bit_count) 2373 { 2374 return types_match_const_cast_only(expected_type->data.pointer.child_type, 2375 actual_type->data.pointer.child_type); 2376 } 2377 2378 // unknown size array const 2379 if (expected_type->id == TypeTableEntryIdStruct && 2380 actual_type->id == TypeTableEntryIdStruct && 2381 expected_type->data.structure.is_slice && 2382 actual_type->data.structure.is_slice && 2383 (!actual_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || 2384 expected_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const) && 2385 (!actual_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_volatile || 2386 expected_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_volatile)) 2387 { 2388 return types_match_const_cast_only( 2389 expected_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, 2390 actual_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type); 2391 } 2392 2393 // maybe 2394 if (expected_type->id == TypeTableEntryIdMaybe && 2395 actual_type->id == TypeTableEntryIdMaybe) 2396 { 2397 return types_match_const_cast_only( 2398 expected_type->data.maybe.child_type, 2399 actual_type->data.maybe.child_type); 2400 } 2401 2402 // error 2403 if (expected_type->id == TypeTableEntryIdErrorUnion && 2404 actual_type->id == TypeTableEntryIdErrorUnion) 2405 { 2406 return types_match_const_cast_only( 2407 expected_type->data.error.child_type, 2408 actual_type->data.error.child_type); 2409 } 2410 2411 // fn 2412 if (expected_type->id == TypeTableEntryIdFn && 2413 actual_type->id == TypeTableEntryIdFn) 2414 { 2415 if (expected_type->data.fn.fn_type_id.is_extern != actual_type->data.fn.fn_type_id.is_extern) { 2416 return false; 2417 } 2418 if (expected_type->data.fn.fn_type_id.is_naked != actual_type->data.fn.fn_type_id.is_naked) { 2419 return false; 2420 } 2421 if (expected_type->data.fn.fn_type_id.is_cold != actual_type->data.fn.fn_type_id.is_cold) { 2422 return false; 2423 } 2424 if (actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable && 2425 !types_match_const_cast_only( 2426 expected_type->data.fn.fn_type_id.return_type, 2427 actual_type->data.fn.fn_type_id.return_type)) 2428 { 2429 return false; 2430 } 2431 if (expected_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { 2432 return false; 2433 } 2434 for (size_t i = 0; i < expected_type->data.fn.fn_type_id.param_count; i += 1) { 2435 // note it's reversed for parameters 2436 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i]; 2437 FnTypeParamInfo *expected_param_info = &expected_type->data.fn.fn_type_id.param_info[i]; 2438 2439 if (!types_match_const_cast_only(actual_param_info->type, expected_param_info->type)) { 2440 return false; 2441 } 2442 2443 if (expected_param_info->is_noalias != actual_param_info->is_noalias) { 2444 return false; 2445 } 2446 } 2447 return true; 2448 } 2449 2450 2451 return false; 2452 } 2453 2454 Tld *find_decl(CodeGen *g, Scope *scope, Buf *name) { 2455 // we must resolve all the use decls 2456 ImportTableEntry *import = get_scope_import(scope); 2457 for (size_t i = 0; i < import->use_decls.length; i += 1) { 2458 AstNode *use_decl_node = import->use_decls.at(i); 2459 if (use_decl_node->data.use.resolution == TldResolutionUnresolved) { 2460 preview_use_decl(g, use_decl_node); 2461 resolve_use_decl(g, use_decl_node); 2462 } 2463 } 2464 2465 while (scope) { 2466 if (scope->id == ScopeIdDecls) { 2467 ScopeDecls *decls_scope = (ScopeDecls *)scope; 2468 auto entry = decls_scope->decl_table.maybe_get(name); 2469 if (entry) 2470 return entry->value; 2471 } 2472 scope = scope->parent; 2473 } 2474 return nullptr; 2475 } 2476 2477 VariableTableEntry *find_variable(CodeGen *g, Scope *scope, Buf *name) { 2478 while (scope) { 2479 if (scope->id == ScopeIdVarDecl) { 2480 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope; 2481 if (buf_eql_buf(name, &var_scope->var->name)) 2482 return var_scope->var; 2483 } else if (scope->id == ScopeIdDecls) { 2484 ScopeDecls *decls_scope = (ScopeDecls *)scope; 2485 auto entry = decls_scope->decl_table.maybe_get(name); 2486 if (entry) { 2487 Tld *tld = entry->value; 2488 if (tld->id == TldIdVar) { 2489 TldVar *tld_var = (TldVar *)tld; 2490 if (tld_var->var) 2491 return tld_var->var; 2492 } 2493 } 2494 } 2495 scope = scope->parent; 2496 } 2497 2498 return nullptr; 2499 } 2500 2501 FnTableEntry *scope_fn_entry(Scope *scope) { 2502 while (scope) { 2503 if (scope->id == ScopeIdFnDef) { 2504 ScopeFnDef *fn_scope = (ScopeFnDef *)scope; 2505 return fn_scope->fn_entry; 2506 } 2507 scope = scope->parent; 2508 } 2509 return nullptr; 2510 } 2511 2512 FnTableEntry *scope_get_fn_if_root(Scope *scope) { 2513 assert(scope); 2514 scope = scope->parent; 2515 while (scope) { 2516 switch (scope->id) { 2517 case ScopeIdBlock: 2518 return nullptr; 2519 case ScopeIdDecls: 2520 case ScopeIdDefer: 2521 case ScopeIdDeferExpr: 2522 case ScopeIdVarDecl: 2523 case ScopeIdCImport: 2524 case ScopeIdLoop: 2525 case ScopeIdCompTime: 2526 scope = scope->parent; 2527 continue; 2528 case ScopeIdFnDef: 2529 ScopeFnDef *fn_scope = (ScopeFnDef *)scope; 2530 return fn_scope->fn_entry; 2531 } 2532 zig_unreachable(); 2533 } 2534 return nullptr; 2535 } 2536 2537 TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name) { 2538 for (uint32_t i = 0; i < enum_type->data.enumeration.src_field_count; i += 1) { 2539 TypeEnumField *type_enum_field = &enum_type->data.enumeration.fields[i]; 2540 if (buf_eql_buf(type_enum_field->name, name)) { 2541 return type_enum_field; 2542 } 2543 } 2544 return nullptr; 2545 } 2546 2547 TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *name) { 2548 assert(type_entry->id == TypeTableEntryIdStruct); 2549 assert(type_entry->data.structure.complete); 2550 for (uint32_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) { 2551 TypeStructField *field = &type_entry->data.structure.fields[i]; 2552 if (buf_eql_buf(field->name, name)) { 2553 return field; 2554 } 2555 } 2556 return nullptr; 2557 } 2558 2559 static bool is_container(TypeTableEntry *type_entry) { 2560 switch (type_entry->id) { 2561 case TypeTableEntryIdInvalid: 2562 case TypeTableEntryIdVar: 2563 case TypeTableEntryIdOpaque: 2564 zig_unreachable(); 2565 case TypeTableEntryIdStruct: 2566 case TypeTableEntryIdEnum: 2567 case TypeTableEntryIdUnion: 2568 return true; 2569 case TypeTableEntryIdPointer: 2570 case TypeTableEntryIdMetaType: 2571 case TypeTableEntryIdVoid: 2572 case TypeTableEntryIdBool: 2573 case TypeTableEntryIdUnreachable: 2574 case TypeTableEntryIdInt: 2575 case TypeTableEntryIdFloat: 2576 case TypeTableEntryIdArray: 2577 case TypeTableEntryIdNumLitFloat: 2578 case TypeTableEntryIdNumLitInt: 2579 case TypeTableEntryIdUndefLit: 2580 case TypeTableEntryIdNullLit: 2581 case TypeTableEntryIdMaybe: 2582 case TypeTableEntryIdErrorUnion: 2583 case TypeTableEntryIdPureError: 2584 case TypeTableEntryIdFn: 2585 case TypeTableEntryIdNamespace: 2586 case TypeTableEntryIdBlock: 2587 case TypeTableEntryIdBoundFn: 2588 case TypeTableEntryIdEnumTag: 2589 case TypeTableEntryIdArgTuple: 2590 return false; 2591 } 2592 zig_unreachable(); 2593 } 2594 2595 bool is_container_ref(TypeTableEntry *type_entry) { 2596 return (type_entry->id == TypeTableEntryIdPointer) ? 2597 is_container(type_entry->data.pointer.child_type) : is_container(type_entry); 2598 } 2599 2600 TypeTableEntry *container_ref_type(TypeTableEntry *type_entry) { 2601 assert(is_container_ref(type_entry)); 2602 return (type_entry->id == TypeTableEntryIdPointer) ? 2603 type_entry->data.pointer.child_type : type_entry; 2604 } 2605 2606 void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) { 2607 switch (type_entry->id) { 2608 case TypeTableEntryIdStruct: 2609 resolve_struct_type(g, type_entry); 2610 break; 2611 case TypeTableEntryIdEnum: 2612 resolve_enum_type(g, type_entry); 2613 break; 2614 case TypeTableEntryIdUnion: 2615 resolve_union_type(g, type_entry); 2616 break; 2617 case TypeTableEntryIdPointer: 2618 case TypeTableEntryIdMetaType: 2619 case TypeTableEntryIdVoid: 2620 case TypeTableEntryIdBool: 2621 case TypeTableEntryIdUnreachable: 2622 case TypeTableEntryIdInt: 2623 case TypeTableEntryIdFloat: 2624 case TypeTableEntryIdArray: 2625 case TypeTableEntryIdNumLitFloat: 2626 case TypeTableEntryIdNumLitInt: 2627 case TypeTableEntryIdUndefLit: 2628 case TypeTableEntryIdNullLit: 2629 case TypeTableEntryIdMaybe: 2630 case TypeTableEntryIdErrorUnion: 2631 case TypeTableEntryIdPureError: 2632 case TypeTableEntryIdFn: 2633 case TypeTableEntryIdNamespace: 2634 case TypeTableEntryIdBlock: 2635 case TypeTableEntryIdBoundFn: 2636 case TypeTableEntryIdInvalid: 2637 case TypeTableEntryIdVar: 2638 case TypeTableEntryIdEnumTag: 2639 case TypeTableEntryIdArgTuple: 2640 case TypeTableEntryIdOpaque: 2641 zig_unreachable(); 2642 } 2643 } 2644 2645 bool type_is_codegen_pointer(TypeTableEntry *type) { 2646 if (type->id == TypeTableEntryIdPointer) return true; 2647 if (type->id == TypeTableEntryIdFn) return true; 2648 if (type->id == TypeTableEntryIdMaybe) { 2649 if (type->data.maybe.child_type->id == TypeTableEntryIdPointer) return true; 2650 if (type->data.maybe.child_type->id == TypeTableEntryIdFn) return true; 2651 } 2652 return false; 2653 } 2654 2655 AstNode *get_param_decl_node(FnTableEntry *fn_entry, size_t index) { 2656 if (fn_entry->param_source_nodes) 2657 return fn_entry->param_source_nodes[index]; 2658 else if (fn_entry->proto_node) 2659 return fn_entry->proto_node->data.fn_proto.params.at(index); 2660 else 2661 return nullptr; 2662 } 2663 2664 void define_local_param_variables(CodeGen *g, FnTableEntry *fn_table_entry, VariableTableEntry **arg_vars) { 2665 TypeTableEntry *fn_type = fn_table_entry->type_entry; 2666 assert(!fn_type->data.fn.is_generic); 2667 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 2668 for (size_t i = 0; i < fn_type_id->param_count; i += 1) { 2669 FnTypeParamInfo *param_info = &fn_type_id->param_info[i]; 2670 AstNode *param_decl_node = get_param_decl_node(fn_table_entry, i); 2671 Buf *param_name; 2672 bool is_var_args = param_decl_node && param_decl_node->data.param_decl.is_var_args; 2673 if (param_decl_node && !is_var_args) { 2674 param_name = param_decl_node->data.param_decl.name; 2675 } else { 2676 param_name = buf_sprintf("arg%zu", i); 2677 } 2678 2679 TypeTableEntry *param_type = param_info->type; 2680 bool is_noalias = param_info->is_noalias; 2681 2682 if (is_noalias && !type_is_codegen_pointer(param_type)) { 2683 add_node_error(g, param_decl_node, buf_sprintf("noalias on non-pointer parameter")); 2684 } 2685 2686 if (fn_type_id->is_extern && handle_is_ptr(param_type)) { 2687 add_node_error(g, param_decl_node, 2688 buf_sprintf("byvalue types not yet supported on extern function parameters")); 2689 } 2690 2691 VariableTableEntry *var = add_variable(g, param_decl_node, fn_table_entry->child_scope, 2692 param_name, true, create_const_runtime(param_type), nullptr); 2693 var->src_arg_index = i; 2694 fn_table_entry->child_scope = var->child_scope; 2695 var->shadowable = var->shadowable || is_var_args; 2696 2697 if (type_has_bits(param_type)) { 2698 fn_table_entry->variable_list.append(var); 2699 } 2700 2701 if (fn_type->data.fn.gen_param_info) { 2702 var->gen_arg_index = fn_type->data.fn.gen_param_info[i].gen_index; 2703 } 2704 2705 if (arg_vars) { 2706 arg_vars[i] = var; 2707 } 2708 } 2709 } 2710 2711 void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_type_node) { 2712 TypeTableEntry *fn_type = fn_table_entry->type_entry; 2713 assert(!fn_type->data.fn.is_generic); 2714 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 2715 2716 TypeTableEntry *block_return_type = ir_analyze(g, &fn_table_entry->ir_executable, 2717 &fn_table_entry->analyzed_executable, fn_type_id->return_type, return_type_node); 2718 fn_table_entry->implicit_return_type = block_return_type; 2719 2720 if (block_return_type->id == TypeTableEntryIdInvalid || 2721 fn_table_entry->analyzed_executable.invalid) 2722 { 2723 assert(g->errors.length > 0); 2724 fn_table_entry->anal_state = FnAnalStateInvalid; 2725 return; 2726 } 2727 2728 if (g->verbose) { 2729 fprintf(stderr, "{ // (analyzed)\n"); 2730 ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4); 2731 fprintf(stderr, "}\n"); 2732 } 2733 2734 fn_table_entry->anal_state = FnAnalStateComplete; 2735 } 2736 2737 static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) { 2738 assert(fn_table_entry->anal_state != FnAnalStateProbing); 2739 if (fn_table_entry->anal_state != FnAnalStateReady) 2740 return; 2741 2742 fn_table_entry->anal_state = FnAnalStateProbing; 2743 2744 AstNode *return_type_node = (fn_table_entry->proto_node != nullptr) ? 2745 fn_table_entry->proto_node->data.fn_proto.return_type : fn_table_entry->fndef_scope->base.source_node; 2746 2747 assert(fn_table_entry->fndef_scope); 2748 if (!fn_table_entry->child_scope) 2749 fn_table_entry->child_scope = &fn_table_entry->fndef_scope->base; 2750 2751 define_local_param_variables(g, fn_table_entry, nullptr); 2752 2753 TypeTableEntry *fn_type = fn_table_entry->type_entry; 2754 assert(!fn_type->data.fn.is_generic); 2755 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 2756 2757 if (fn_type_id->is_extern && handle_is_ptr(fn_type_id->return_type)) { 2758 add_node_error(g, return_type_node, 2759 buf_sprintf("byvalue types not yet supported on extern function return values")); 2760 } 2761 2762 ir_gen_fn(g, fn_table_entry); 2763 if (fn_table_entry->ir_executable.invalid) { 2764 fn_table_entry->anal_state = FnAnalStateInvalid; 2765 return; 2766 } 2767 if (g->verbose) { 2768 fprintf(stderr, "\n"); 2769 ast_render(g, stderr, fn_table_entry->body_node, 4); 2770 fprintf(stderr, "\n{ // (IR)\n"); 2771 ir_print(g, stderr, &fn_table_entry->ir_executable, 4); 2772 fprintf(stderr, "}\n"); 2773 } 2774 2775 analyze_fn_ir(g, fn_table_entry, return_type_node); 2776 } 2777 2778 static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node) { 2779 IrInstruction *use_target_value = src_use_node->data.use.value; 2780 if (use_target_value->value.type->id == TypeTableEntryIdInvalid) { 2781 dst_use_node->owner->any_imports_failed = true; 2782 return; 2783 } 2784 2785 dst_use_node->data.use.resolution = TldResolutionOk; 2786 2787 ConstExprValue *const_val = &use_target_value->value; 2788 assert(const_val->special != ConstValSpecialRuntime); 2789 2790 ImportTableEntry *target_import = const_val->data.x_import; 2791 assert(target_import); 2792 2793 if (target_import->any_imports_failed) { 2794 dst_use_node->owner->any_imports_failed = true; 2795 } 2796 2797 auto it = target_import->decls_scope->decl_table.entry_iterator(); 2798 for (;;) { 2799 auto *entry = it.next(); 2800 if (!entry) 2801 break; 2802 2803 Tld *target_tld = entry->value; 2804 if (target_tld->import != target_import || 2805 target_tld->visib_mod == VisibModPrivate) 2806 { 2807 continue; 2808 } 2809 2810 auto existing_entry = dst_use_node->owner->decls_scope->decl_table.put_unique(target_tld->name, target_tld); 2811 if (existing_entry) { 2812 Tld *existing_decl = existing_entry->value; 2813 if (existing_decl != target_tld) { 2814 ErrorMsg *msg = add_node_error(g, dst_use_node, 2815 buf_sprintf("import of '%s' overrides existing definition", 2816 buf_ptr(target_tld->name))); 2817 add_error_note(g, msg, existing_decl->source_node, buf_sprintf("previous definition here")); 2818 add_error_note(g, msg, target_tld->source_node, buf_sprintf("imported definition here")); 2819 } 2820 } 2821 } 2822 2823 for (size_t i = 0; i < target_import->use_decls.length; i += 1) { 2824 AstNode *use_decl_node = target_import->use_decls.at(i); 2825 if (use_decl_node->data.use.visib_mod != VisibModPrivate) 2826 add_symbols_from_import(g, use_decl_node, dst_use_node); 2827 } 2828 } 2829 2830 void resolve_use_decl(CodeGen *g, AstNode *node) { 2831 assert(node->type == NodeTypeUse); 2832 2833 if (node->data.use.resolution == TldResolutionOk || 2834 node->data.use.resolution == TldResolutionInvalid) 2835 { 2836 return; 2837 } 2838 add_symbols_from_import(g, node, node); 2839 } 2840 2841 void preview_use_decl(CodeGen *g, AstNode *node) { 2842 assert(node->type == NodeTypeUse); 2843 2844 node->data.use.resolution = TldResolutionResolving; 2845 IrInstruction *result = analyze_const_value(g, &node->owner->decls_scope->base, 2846 node->data.use.expr, g->builtin_types.entry_namespace, nullptr); 2847 2848 if (result->value.type->id == TypeTableEntryIdInvalid) 2849 node->owner->any_imports_failed = true; 2850 2851 node->data.use.value = result; 2852 } 2853 2854 ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, 2855 Buf *abs_full_path, Buf *src_dirname, Buf *src_basename, Buf *source_code) 2856 { 2857 if (g->verbose) { 2858 fprintf(stderr, "\nOriginal Source (%s):\n", buf_ptr(abs_full_path)); 2859 fprintf(stderr, "----------------\n"); 2860 fprintf(stderr, "%s\n", buf_ptr(source_code)); 2861 2862 fprintf(stderr, "\nTokens:\n"); 2863 fprintf(stderr, "---------\n"); 2864 } 2865 2866 Tokenization tokenization = {0}; 2867 tokenize(source_code, &tokenization); 2868 2869 if (tokenization.err) { 2870 ErrorMsg *err = err_msg_create_with_line(abs_full_path, tokenization.err_line, tokenization.err_column, 2871 source_code, tokenization.line_offsets, tokenization.err); 2872 2873 print_err_msg(err, g->err_color); 2874 exit(1); 2875 } 2876 2877 if (g->verbose) { 2878 print_tokens(source_code, tokenization.tokens); 2879 2880 fprintf(stderr, "\nAST:\n"); 2881 fprintf(stderr, "------\n"); 2882 } 2883 2884 ImportTableEntry *import_entry = allocate<ImportTableEntry>(1); 2885 import_entry->package = package; 2886 import_entry->source_code = source_code; 2887 import_entry->line_offsets = tokenization.line_offsets; 2888 import_entry->path = abs_full_path; 2889 2890 import_entry->root = ast_parse(source_code, tokenization.tokens, import_entry, g->err_color, 2891 &g->next_node_index); 2892 assert(import_entry->root); 2893 if (g->verbose) { 2894 ast_print(stderr, import_entry->root, 0); 2895 } 2896 2897 import_entry->di_file = ZigLLVMCreateFile(g->dbuilder, buf_ptr(src_basename), buf_ptr(src_dirname)); 2898 g->import_table.put(abs_full_path, import_entry); 2899 g->import_queue.append(import_entry); 2900 2901 import_entry->decls_scope = create_decls_scope(import_entry->root, nullptr, nullptr, import_entry); 2902 2903 2904 assert(import_entry->root->type == NodeTypeRoot); 2905 for (size_t decl_i = 0; decl_i < import_entry->root->data.root.top_level_decls.length; decl_i += 1) { 2906 AstNode *top_level_decl = import_entry->root->data.root.top_level_decls.at(decl_i); 2907 2908 if (top_level_decl->type == NodeTypeFnDef) { 2909 AstNode *proto_node = top_level_decl->data.fn_def.fn_proto; 2910 assert(proto_node->type == NodeTypeFnProto); 2911 Buf *proto_name = proto_node->data.fn_proto.name; 2912 2913 bool is_pub = (proto_node->data.fn_proto.visib_mod == VisibModPub); 2914 2915 if (is_pub) { 2916 if (buf_eql_str(proto_name, "main")) { 2917 g->have_pub_main = true; 2918 } else if (buf_eql_str(proto_name, "panic")) { 2919 g->have_pub_panic = true; 2920 } 2921 } else if (proto_node->data.fn_proto.visib_mod == VisibModExport && buf_eql_str(proto_name, "main") && 2922 g->link_libc) 2923 { 2924 g->have_c_main = true; 2925 } 2926 2927 } 2928 } 2929 2930 return import_entry; 2931 } 2932 2933 2934 void semantic_analyze(CodeGen *g) { 2935 for (; g->import_queue_index < g->import_queue.length; g->import_queue_index += 1) { 2936 ImportTableEntry *import = g->import_queue.at(g->import_queue_index); 2937 scan_decls(g, import->decls_scope, import->root); 2938 } 2939 2940 for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) { 2941 AstNode *use_decl_node = g->use_queue.at(g->use_queue_index); 2942 preview_use_decl(g, use_decl_node); 2943 } 2944 2945 for (size_t i = 0; i < g->use_queue.length; i += 1) { 2946 AstNode *use_decl_node = g->use_queue.at(i); 2947 resolve_use_decl(g, use_decl_node); 2948 } 2949 2950 while (g->resolve_queue_index < g->resolve_queue.length || 2951 g->fn_defs_index < g->fn_defs.length) 2952 { 2953 for (; g->resolve_queue_index < g->resolve_queue.length; g->resolve_queue_index += 1) { 2954 Tld *tld = g->resolve_queue.at(g->resolve_queue_index); 2955 bool pointer_only = false; 2956 resolve_top_level_decl(g, tld, pointer_only); 2957 } 2958 2959 for (; g->fn_defs_index < g->fn_defs.length; g->fn_defs_index += 1) { 2960 FnTableEntry *fn_entry = g->fn_defs.at(g->fn_defs_index); 2961 analyze_fn_body(g, fn_entry); 2962 } 2963 } 2964 } 2965 2966 TypeTableEntry **get_int_type_ptr(CodeGen *g, bool is_signed, uint32_t size_in_bits) { 2967 size_t index; 2968 if (size_in_bits == 8) { 2969 index = 0; 2970 } else if (size_in_bits == 16) { 2971 index = 1; 2972 } else if (size_in_bits == 32) { 2973 index = 2; 2974 } else if (size_in_bits == 64) { 2975 index = 3; 2976 } else { 2977 return nullptr; 2978 } 2979 return &g->builtin_types.entry_int[is_signed ? 0 : 1][index]; 2980 } 2981 2982 TypeTableEntry *get_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) { 2983 TypeTableEntry **common_entry = get_int_type_ptr(g, is_signed, size_in_bits); 2984 if (common_entry) 2985 return *common_entry; 2986 2987 TypeId type_id = {}; 2988 type_id.id = TypeTableEntryIdInt; 2989 type_id.data.integer.is_signed = is_signed; 2990 type_id.data.integer.bit_count = size_in_bits; 2991 2992 { 2993 auto entry = g->type_table.maybe_get(type_id); 2994 if (entry) 2995 return entry->value; 2996 } 2997 2998 TypeTableEntry *new_entry = make_int_type(g, is_signed, size_in_bits); 2999 g->type_table.put(type_id, new_entry); 3000 return new_entry; 3001 } 3002 3003 TypeTableEntry **get_c_int_type_ptr(CodeGen *g, CIntType c_int_type) { 3004 return &g->builtin_types.entry_c_int[c_int_type]; 3005 } 3006 3007 TypeTableEntry *get_c_int_type(CodeGen *g, CIntType c_int_type) { 3008 return *get_c_int_type_ptr(g, c_int_type); 3009 } 3010 3011 bool handle_is_ptr(TypeTableEntry *type_entry) { 3012 switch (type_entry->id) { 3013 case TypeTableEntryIdInvalid: 3014 case TypeTableEntryIdMetaType: 3015 case TypeTableEntryIdNumLitFloat: 3016 case TypeTableEntryIdNumLitInt: 3017 case TypeTableEntryIdUndefLit: 3018 case TypeTableEntryIdNullLit: 3019 case TypeTableEntryIdNamespace: 3020 case TypeTableEntryIdBlock: 3021 case TypeTableEntryIdBoundFn: 3022 case TypeTableEntryIdVar: 3023 case TypeTableEntryIdArgTuple: 3024 case TypeTableEntryIdOpaque: 3025 zig_unreachable(); 3026 case TypeTableEntryIdUnreachable: 3027 case TypeTableEntryIdVoid: 3028 case TypeTableEntryIdBool: 3029 case TypeTableEntryIdInt: 3030 case TypeTableEntryIdFloat: 3031 case TypeTableEntryIdPointer: 3032 case TypeTableEntryIdPureError: 3033 case TypeTableEntryIdFn: 3034 case TypeTableEntryIdEnumTag: 3035 return false; 3036 case TypeTableEntryIdArray: 3037 case TypeTableEntryIdStruct: 3038 case TypeTableEntryIdUnion: 3039 return type_has_bits(type_entry); 3040 case TypeTableEntryIdErrorUnion: 3041 return type_has_bits(type_entry->data.error.child_type); 3042 case TypeTableEntryIdEnum: 3043 assert(type_entry->data.enumeration.complete); 3044 return type_entry->data.enumeration.gen_field_count != 0; 3045 case TypeTableEntryIdMaybe: 3046 return type_has_bits(type_entry->data.maybe.child_type) && 3047 type_entry->data.maybe.child_type->id != TypeTableEntryIdPointer && 3048 type_entry->data.maybe.child_type->id != TypeTableEntryIdFn; 3049 } 3050 zig_unreachable(); 3051 } 3052 3053 void find_libc_include_path(CodeGen *g) { 3054 if (!g->libc_include_dir || buf_len(g->libc_include_dir) == 0) { 3055 zig_panic("Unable to determine libc include path."); 3056 } 3057 } 3058 3059 void find_libc_lib_path(CodeGen *g) { 3060 // later we can handle this better by reporting an error via the normal mechanism 3061 if (!g->libc_lib_dir || buf_len(g->libc_lib_dir) == 0) { 3062 zig_panic("Unable to determine libc lib path."); 3063 } 3064 if (!g->libc_static_lib_dir || buf_len(g->libc_static_lib_dir) == 0) { 3065 zig_panic("Unable to determine libc static lib path."); 3066 } 3067 } 3068 3069 static uint32_t hash_ptr(void *ptr) { 3070 return (uint32_t)(((uintptr_t)ptr) % UINT32_MAX); 3071 } 3072 3073 static uint32_t hash_size(size_t x) { 3074 return (uint32_t)(x % UINT32_MAX); 3075 } 3076 3077 uint32_t fn_table_entry_hash(FnTableEntry* value) { 3078 return ptr_hash(value); 3079 } 3080 3081 bool fn_table_entry_eql(FnTableEntry *a, FnTableEntry *b) { 3082 return ptr_eq(a, b); 3083 } 3084 3085 uint32_t fn_type_id_hash(FnTypeId *id) { 3086 uint32_t result = 0; 3087 result += id->is_extern ? (uint32_t)3349388391 : 0; 3088 result += id->is_naked ? (uint32_t)608688877 : 0; 3089 result += id->is_cold ? (uint32_t)3605523458 : 0; 3090 result += id->is_var_args ? (uint32_t)1931444534 : 0; 3091 result += hash_ptr(id->return_type); 3092 for (size_t i = 0; i < id->param_count; i += 1) { 3093 FnTypeParamInfo *info = &id->param_info[i]; 3094 result += info->is_noalias ? (uint32_t)892356923 : 0; 3095 result += hash_ptr(info->type); 3096 } 3097 return result; 3098 } 3099 3100 bool fn_type_id_eql(FnTypeId *a, FnTypeId *b) { 3101 if (a->is_extern != b->is_extern || 3102 a->is_naked != b->is_naked || 3103 a->is_cold != b->is_cold || 3104 a->return_type != b->return_type || 3105 a->is_var_args != b->is_var_args || 3106 a->param_count != b->param_count) 3107 { 3108 return false; 3109 } 3110 for (size_t i = 0; i < a->param_count; i += 1) { 3111 FnTypeParamInfo *a_param_info = &a->param_info[i]; 3112 FnTypeParamInfo *b_param_info = &b->param_info[i]; 3113 3114 if (a_param_info->type != b_param_info->type || 3115 a_param_info->is_noalias != b_param_info->is_noalias) 3116 { 3117 return false; 3118 } 3119 } 3120 return true; 3121 } 3122 3123 static uint32_t hash_const_val(ConstExprValue *const_val) { 3124 assert(const_val->special == ConstValSpecialStatic); 3125 switch (const_val->type->id) { 3126 case TypeTableEntryIdOpaque: 3127 zig_unreachable(); 3128 case TypeTableEntryIdBool: 3129 return const_val->data.x_bool ? (uint32_t)127863866 : (uint32_t)215080464; 3130 case TypeTableEntryIdMetaType: 3131 return hash_ptr(const_val->data.x_type); 3132 case TypeTableEntryIdVoid: 3133 return (uint32_t)4149439618; 3134 case TypeTableEntryIdInt: 3135 case TypeTableEntryIdNumLitInt: 3136 case TypeTableEntryIdEnumTag: 3137 return ((uint32_t)(bignum_to_twos_complement(&const_val->data.x_bignum) % UINT32_MAX)) * (uint32_t)1331471175; 3138 case TypeTableEntryIdFloat: 3139 case TypeTableEntryIdNumLitFloat: 3140 return (uint32_t)(const_val->data.x_bignum.data.x_float * (uint32_t)UINT32_MAX); 3141 case TypeTableEntryIdArgTuple: 3142 return (uint32_t)const_val->data.x_arg_tuple.start_index * (uint32_t)281907309 + 3143 (uint32_t)const_val->data.x_arg_tuple.end_index * (uint32_t)2290442768; 3144 case TypeTableEntryIdPointer: 3145 { 3146 uint32_t hash_val = 0; 3147 switch (const_val->data.x_ptr.mut) { 3148 case ConstPtrMutRuntimeVar: 3149 hash_val += (uint32_t)3500721036; 3150 break; 3151 case ConstPtrMutComptimeConst: 3152 hash_val += (uint32_t)4214318515; 3153 break; 3154 case ConstPtrMutComptimeVar: 3155 hash_val += (uint32_t)1103195694; 3156 break; 3157 } 3158 switch (const_val->data.x_ptr.special) { 3159 case ConstPtrSpecialInvalid: 3160 zig_unreachable(); 3161 case ConstPtrSpecialRef: 3162 hash_val += (uint32_t)2478261866; 3163 hash_val += hash_ptr(const_val->data.x_ptr.data.ref.pointee); 3164 return hash_val; 3165 case ConstPtrSpecialBaseArray: 3166 hash_val += (uint32_t)1764906839; 3167 hash_val += hash_ptr(const_val->data.x_ptr.data.base_array.array_val); 3168 hash_val += hash_size(const_val->data.x_ptr.data.base_array.elem_index); 3169 hash_val += const_val->data.x_ptr.data.base_array.is_cstr ? 1297263887 : 200363492; 3170 return hash_val; 3171 case ConstPtrSpecialBaseStruct: 3172 hash_val += (uint32_t)3518317043; 3173 hash_val += hash_ptr(const_val->data.x_ptr.data.base_struct.struct_val); 3174 hash_val += hash_size(const_val->data.x_ptr.data.base_struct.field_index); 3175 return hash_val; 3176 case ConstPtrSpecialHardCodedAddr: 3177 hash_val += (uint32_t)4048518294; 3178 hash_val += hash_size(const_val->data.x_ptr.data.hard_coded_addr.addr); 3179 return hash_val; 3180 case ConstPtrSpecialDiscard: 3181 hash_val += 2010123162; 3182 return hash_val; 3183 } 3184 zig_unreachable(); 3185 } 3186 case TypeTableEntryIdUndefLit: 3187 return 162837799; 3188 case TypeTableEntryIdNullLit: 3189 return 844854567; 3190 case TypeTableEntryIdArray: 3191 // TODO better hashing algorithm 3192 return 1166190605; 3193 case TypeTableEntryIdStruct: 3194 // TODO better hashing algorithm 3195 return 1532530855; 3196 case TypeTableEntryIdUnion: 3197 // TODO better hashing algorithm 3198 return 2709806591; 3199 case TypeTableEntryIdMaybe: 3200 if (const_val->data.x_maybe) { 3201 return hash_const_val(const_val->data.x_maybe) * 1992916303; 3202 } else { 3203 return 4016830364; 3204 } 3205 case TypeTableEntryIdErrorUnion: 3206 // TODO better hashing algorithm 3207 return 3415065496; 3208 case TypeTableEntryIdPureError: 3209 // TODO better hashing algorithm 3210 return 2630160122; 3211 case TypeTableEntryIdEnum: 3212 // TODO better hashing algorithm 3213 return 31643936; 3214 case TypeTableEntryIdFn: 3215 return hash_ptr(const_val->data.x_fn.fn_entry) + 3216 (const_val->data.x_fn.is_inline ? 4133894920 : 3983484790); 3217 case TypeTableEntryIdNamespace: 3218 return hash_ptr(const_val->data.x_import); 3219 case TypeTableEntryIdBlock: 3220 return hash_ptr(const_val->data.x_block); 3221 case TypeTableEntryIdBoundFn: 3222 case TypeTableEntryIdInvalid: 3223 case TypeTableEntryIdUnreachable: 3224 case TypeTableEntryIdVar: 3225 zig_unreachable(); 3226 } 3227 zig_unreachable(); 3228 } 3229 3230 uint32_t generic_fn_type_id_hash(GenericFnTypeId *id) { 3231 uint32_t result = 0; 3232 result += hash_ptr(id->fn_entry); 3233 for (size_t i = 0; i < id->param_count; i += 1) { 3234 ConstExprValue *generic_param = &id->params[i]; 3235 if (generic_param->special != ConstValSpecialRuntime) { 3236 result += hash_const_val(generic_param); 3237 result += hash_ptr(generic_param->type); 3238 } 3239 } 3240 return result; 3241 } 3242 3243 bool generic_fn_type_id_eql(GenericFnTypeId *a, GenericFnTypeId *b) { 3244 assert(a->fn_entry); 3245 if (a->fn_entry != b->fn_entry) return false; 3246 if (a->param_count != b->param_count) return false; 3247 for (size_t i = 0; i < a->param_count; i += 1) { 3248 ConstExprValue *a_val = &a->params[i]; 3249 ConstExprValue *b_val = &b->params[i]; 3250 if (a_val->type != b_val->type) return false; 3251 if (a_val->special != ConstValSpecialRuntime && b_val->special != ConstValSpecialRuntime) { 3252 assert(a_val->special == ConstValSpecialStatic); 3253 assert(b_val->special == ConstValSpecialStatic); 3254 if (!const_values_equal(a_val, b_val)) { 3255 return false; 3256 } 3257 } else { 3258 assert(a_val->special == ConstValSpecialRuntime && b_val->special == ConstValSpecialRuntime); 3259 } 3260 } 3261 return true; 3262 } 3263 3264 uint32_t fn_eval_hash(Scope* scope) { 3265 uint32_t result = 0; 3266 while (scope) { 3267 if (scope->id == ScopeIdVarDecl) { 3268 ScopeVarDecl *var_scope = (ScopeVarDecl *)scope; 3269 result += hash_const_val(var_scope->var->value); 3270 } else if (scope->id == ScopeIdFnDef) { 3271 ScopeFnDef *fn_scope = (ScopeFnDef *)scope; 3272 result += hash_ptr(fn_scope->fn_entry); 3273 return result; 3274 } else { 3275 zig_unreachable(); 3276 } 3277 3278 scope = scope->parent; 3279 } 3280 zig_unreachable(); 3281 } 3282 3283 bool fn_eval_eql(Scope *a, Scope *b) { 3284 while (a && b) { 3285 if (a->id != b->id) 3286 return false; 3287 3288 if (a->id == ScopeIdVarDecl) { 3289 ScopeVarDecl *a_var_scope = (ScopeVarDecl *)a; 3290 ScopeVarDecl *b_var_scope = (ScopeVarDecl *)b; 3291 if (a_var_scope->var->value->type != b_var_scope->var->value->type) 3292 return false; 3293 if (!const_values_equal(a_var_scope->var->value, b_var_scope->var->value)) 3294 return false; 3295 } else if (a->id == ScopeIdFnDef) { 3296 ScopeFnDef *a_fn_scope = (ScopeFnDef *)a; 3297 ScopeFnDef *b_fn_scope = (ScopeFnDef *)b; 3298 if (a_fn_scope->fn_entry != b_fn_scope->fn_entry) 3299 return false; 3300 3301 return true; 3302 } else { 3303 zig_unreachable(); 3304 } 3305 3306 a = a->parent; 3307 b = b->parent; 3308 } 3309 return false; 3310 } 3311 3312 bool type_has_bits(TypeTableEntry *type_entry) { 3313 assert(type_entry); 3314 assert(type_entry->id != TypeTableEntryIdInvalid); 3315 assert(type_has_zero_bits_known(type_entry)); 3316 return !type_entry->zero_bits; 3317 } 3318 3319 bool type_requires_comptime(TypeTableEntry *type_entry) { 3320 switch (type_entry->id) { 3321 case TypeTableEntryIdInvalid: 3322 case TypeTableEntryIdVar: 3323 case TypeTableEntryIdOpaque: 3324 zig_unreachable(); 3325 case TypeTableEntryIdNumLitFloat: 3326 case TypeTableEntryIdNumLitInt: 3327 case TypeTableEntryIdUndefLit: 3328 case TypeTableEntryIdNullLit: 3329 case TypeTableEntryIdMetaType: 3330 case TypeTableEntryIdNamespace: 3331 case TypeTableEntryIdBlock: 3332 case TypeTableEntryIdBoundFn: 3333 case TypeTableEntryIdArgTuple: 3334 return true; 3335 case TypeTableEntryIdArray: 3336 case TypeTableEntryIdStruct: 3337 case TypeTableEntryIdUnion: 3338 case TypeTableEntryIdMaybe: 3339 case TypeTableEntryIdErrorUnion: 3340 case TypeTableEntryIdEnum: 3341 case TypeTableEntryIdPureError: 3342 case TypeTableEntryIdFn: 3343 case TypeTableEntryIdBool: 3344 case TypeTableEntryIdInt: 3345 case TypeTableEntryIdFloat: 3346 case TypeTableEntryIdPointer: 3347 case TypeTableEntryIdEnumTag: 3348 case TypeTableEntryIdVoid: 3349 case TypeTableEntryIdUnreachable: 3350 return false; 3351 } 3352 zig_unreachable(); 3353 } 3354 3355 void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { 3356 const_val->special = ConstValSpecialStatic; 3357 const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str)); 3358 const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(buf_len(str)); 3359 3360 for (size_t i = 0; i < buf_len(str); i += 1) { 3361 ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i]; 3362 this_char->special = ConstValSpecialStatic; 3363 this_char->type = g->builtin_types.entry_u8; 3364 bignum_init_unsigned(&this_char->data.x_bignum, (uint8_t)buf_ptr(str)[i]); 3365 } 3366 } 3367 3368 ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) { 3369 ConstExprValue *const_val = allocate<ConstExprValue>(1); 3370 init_const_str_lit(g, const_val, str); 3371 return const_val; 3372 } 3373 3374 void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) { 3375 // first we build the underlying array 3376 size_t len_with_null = buf_len(str) + 1; 3377 ConstExprValue *array_val = allocate<ConstExprValue>(1); 3378 array_val->special = ConstValSpecialStatic; 3379 array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null); 3380 array_val->data.x_array.s_none.elements = allocate<ConstExprValue>(len_with_null); 3381 for (size_t i = 0; i < buf_len(str); i += 1) { 3382 ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i]; 3383 this_char->special = ConstValSpecialStatic; 3384 this_char->type = g->builtin_types.entry_u8; 3385 bignum_init_unsigned(&this_char->data.x_bignum, (uint8_t)buf_ptr(str)[i]); 3386 } 3387 ConstExprValue *null_char = &array_val->data.x_array.s_none.elements[len_with_null - 1]; 3388 null_char->special = ConstValSpecialStatic; 3389 null_char->type = g->builtin_types.entry_u8; 3390 bignum_init_unsigned(&null_char->data.x_bignum, 0); 3391 3392 // then make the pointer point to it 3393 const_val->special = ConstValSpecialStatic; 3394 const_val->type = get_pointer_to_type(g, g->builtin_types.entry_u8, true); 3395 const_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 3396 const_val->data.x_ptr.data.base_array.array_val = array_val; 3397 const_val->data.x_ptr.data.base_array.elem_index = 0; 3398 const_val->data.x_ptr.data.base_array.is_cstr = true; 3399 } 3400 ConstExprValue *create_const_c_str_lit(CodeGen *g, Buf *str) { 3401 ConstExprValue *const_val = allocate<ConstExprValue>(1); 3402 init_const_c_str_lit(g, const_val, str); 3403 return const_val; 3404 } 3405 3406 void init_const_unsigned_negative(ConstExprValue *const_val, TypeTableEntry *type, uint64_t x, bool negative) { 3407 const_val->special = ConstValSpecialStatic; 3408 const_val->type = type; 3409 bignum_init_unsigned(&const_val->data.x_bignum, x); 3410 const_val->data.x_bignum.is_negative = negative; 3411 } 3412 3413 ConstExprValue *create_const_unsigned_negative(TypeTableEntry *type, uint64_t x, bool negative) { 3414 ConstExprValue *const_val = allocate<ConstExprValue>(1); 3415 init_const_unsigned_negative(const_val, type, x, negative); 3416 return const_val; 3417 } 3418 3419 void init_const_usize(CodeGen *g, ConstExprValue *const_val, uint64_t x) { 3420 return init_const_unsigned_negative(const_val, g->builtin_types.entry_usize, x, false); 3421 } 3422 3423 ConstExprValue *create_const_usize(CodeGen *g, uint64_t x) { 3424 return create_const_unsigned_negative(g->builtin_types.entry_usize, x, false); 3425 } 3426 3427 void init_const_signed(ConstExprValue *const_val, TypeTableEntry *type, int64_t x) { 3428 const_val->special = ConstValSpecialStatic; 3429 const_val->type = type; 3430 bignum_init_signed(&const_val->data.x_bignum, x); 3431 } 3432 3433 ConstExprValue *create_const_signed(TypeTableEntry *type, int64_t x) { 3434 ConstExprValue *const_val = allocate<ConstExprValue>(1); 3435 init_const_signed(const_val, type, x); 3436 return const_val; 3437 } 3438 3439 void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double value) { 3440 const_val->special = ConstValSpecialStatic; 3441 const_val->type = type; 3442 bignum_init_float(&const_val->data.x_bignum, value); 3443 } 3444 3445 ConstExprValue *create_const_float(TypeTableEntry *type, double value) { 3446 ConstExprValue *const_val = allocate<ConstExprValue>(1); 3447 init_const_float(const_val, type, value); 3448 return const_val; 3449 } 3450 3451 void init_const_enum_tag(ConstExprValue *const_val, TypeTableEntry *type, uint64_t tag) { 3452 const_val->special = ConstValSpecialStatic; 3453 const_val->type = type; 3454 const_val->data.x_enum.tag = tag; 3455 } 3456 3457 ConstExprValue *create_const_enum_tag(TypeTableEntry *type, uint64_t tag) { 3458 ConstExprValue *const_val = allocate<ConstExprValue>(1); 3459 init_const_enum_tag(const_val, type, tag); 3460 return const_val; 3461 } 3462 3463 void init_const_bool(CodeGen *g, ConstExprValue *const_val, bool value) { 3464 const_val->special = ConstValSpecialStatic; 3465 const_val->type = g->builtin_types.entry_bool; 3466 const_val->data.x_bool = value; 3467 } 3468 3469 ConstExprValue *create_const_bool(CodeGen *g, bool value) { 3470 ConstExprValue *const_val = allocate<ConstExprValue>(1); 3471 init_const_bool(g, const_val, value); 3472 return const_val; 3473 } 3474 3475 void init_const_runtime(ConstExprValue *const_val, TypeTableEntry *type) { 3476 const_val->special = ConstValSpecialRuntime; 3477 const_val->type = type; 3478 } 3479 3480 ConstExprValue *create_const_runtime(TypeTableEntry *type) { 3481 ConstExprValue *const_val = allocate<ConstExprValue>(1); 3482 init_const_runtime(const_val, type); 3483 return const_val; 3484 } 3485 3486 void init_const_type(CodeGen *g, ConstExprValue *const_val, TypeTableEntry *type_value) { 3487 const_val->special = ConstValSpecialStatic; 3488 const_val->type = g->builtin_types.entry_type; 3489 const_val->data.x_type = type_value; 3490 } 3491 3492 ConstExprValue *create_const_type(CodeGen *g, TypeTableEntry *type_value) { 3493 ConstExprValue *const_val = allocate<ConstExprValue>(1); 3494 init_const_type(g, const_val, type_value); 3495 return const_val; 3496 } 3497 3498 void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val, 3499 size_t start, size_t len, bool is_const) 3500 { 3501 assert(array_val->type->id == TypeTableEntryIdArray); 3502 3503 const_val->special = ConstValSpecialStatic; 3504 const_val->type = get_slice_type(g, array_val->type->data.array.child_type, is_const); 3505 const_val->data.x_struct.fields = allocate<ConstExprValue>(2); 3506 3507 init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const); 3508 init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len); 3509 } 3510 3511 ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t start, size_t len, bool is_const) { 3512 ConstExprValue *const_val = allocate<ConstExprValue>(1); 3513 init_const_slice(g, const_val, array_val, start, len, is_const); 3514 return const_val; 3515 } 3516 3517 void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val, 3518 size_t elem_index, bool is_const) 3519 { 3520 assert(array_val->type->id == TypeTableEntryIdArray); 3521 TypeTableEntry *child_type = array_val->type->data.array.child_type; 3522 3523 const_val->special = ConstValSpecialStatic; 3524 const_val->type = get_pointer_to_type(g, child_type, is_const); 3525 const_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 3526 const_val->data.x_ptr.data.base_array.array_val = array_val; 3527 const_val->data.x_ptr.data.base_array.elem_index = elem_index; 3528 } 3529 3530 ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const) { 3531 ConstExprValue *const_val = allocate<ConstExprValue>(1); 3532 init_const_ptr_array(g, const_val, array_val, elem_index, is_const); 3533 return const_val; 3534 } 3535 3536 void init_const_ptr_ref(CodeGen *g, ConstExprValue *const_val, ConstExprValue *pointee_val, bool is_const) { 3537 const_val->special = ConstValSpecialStatic; 3538 const_val->type = get_pointer_to_type(g, pointee_val->type, is_const); 3539 const_val->data.x_ptr.special = ConstPtrSpecialRef; 3540 const_val->data.x_ptr.data.ref.pointee = pointee_val; 3541 } 3542 3543 ConstExprValue *create_const_ptr_ref(CodeGen *g, ConstExprValue *pointee_val, bool is_const) { 3544 ConstExprValue *const_val = allocate<ConstExprValue>(1); 3545 init_const_ptr_ref(g, const_val, pointee_val, is_const); 3546 return const_val; 3547 } 3548 3549 void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end) { 3550 const_val->special = ConstValSpecialStatic; 3551 const_val->type = g->builtin_types.entry_arg_tuple; 3552 const_val->data.x_arg_tuple.start_index = arg_index_start; 3553 const_val->data.x_arg_tuple.end_index = arg_index_end; 3554 } 3555 3556 ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end) { 3557 ConstExprValue *const_val = allocate<ConstExprValue>(1); 3558 init_const_arg_tuple(g, const_val, arg_index_start, arg_index_end); 3559 return const_val; 3560 } 3561 3562 3563 void init_const_undefined(CodeGen *g, ConstExprValue *const_val) { 3564 TypeTableEntry *wanted_type = const_val->type; 3565 if (wanted_type->id == TypeTableEntryIdArray) { 3566 const_val->special = ConstValSpecialStatic; 3567 const_val->data.x_array.special = ConstArraySpecialUndef; 3568 } else if (wanted_type->id == TypeTableEntryIdStruct) { 3569 ensure_complete_type(g, wanted_type); 3570 3571 const_val->special = ConstValSpecialStatic; 3572 size_t field_count = wanted_type->data.structure.src_field_count; 3573 const_val->data.x_struct.fields = allocate<ConstExprValue>(field_count); 3574 for (size_t i = 0; i < field_count; i += 1) { 3575 ConstExprValue *field_val = &const_val->data.x_struct.fields[i]; 3576 field_val->type = wanted_type->data.structure.fields[i].type_entry; 3577 assert(field_val->type); 3578 init_const_undefined(g, field_val); 3579 ConstParent *parent = get_const_val_parent(g, field_val); 3580 if (parent != nullptr) { 3581 parent->id = ConstParentIdStruct; 3582 parent->data.p_struct.struct_val = const_val; 3583 parent->data.p_struct.field_index = i; 3584 } 3585 } 3586 } else { 3587 const_val->special = ConstValSpecialUndef; 3588 } 3589 } 3590 3591 void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) { 3592 if (type_entry->id == TypeTableEntryIdStruct) { 3593 if (!type_entry->data.structure.complete) 3594 resolve_struct_type(g, type_entry); 3595 } else if (type_entry->id == TypeTableEntryIdEnum) { 3596 if (!type_entry->data.enumeration.complete) 3597 resolve_enum_type(g, type_entry); 3598 } else if (type_entry->id == TypeTableEntryIdUnion) { 3599 if (!type_entry->data.unionation.complete) 3600 resolve_union_type(g, type_entry); 3601 } 3602 } 3603 3604 void type_ensure_zero_bits_known(CodeGen *g, TypeTableEntry *type_entry) { 3605 if (type_entry->id == TypeTableEntryIdStruct) { 3606 resolve_struct_zero_bits(g, type_entry); 3607 } else if (type_entry->id == TypeTableEntryIdEnum) { 3608 resolve_enum_zero_bits(g, type_entry); 3609 } else if (type_entry->id == TypeTableEntryIdUnion) { 3610 resolve_union_zero_bits(g, type_entry); 3611 } 3612 } 3613 3614 bool ir_get_var_is_comptime(VariableTableEntry *var) { 3615 if (!var->is_comptime) 3616 return false; 3617 if (var->is_comptime->other) 3618 return var->is_comptime->other->value.data.x_bool; 3619 return var->is_comptime->value.data.x_bool; 3620 } 3621 3622 bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { 3623 assert(a->type->id == b->type->id); 3624 assert(a->special == ConstValSpecialStatic); 3625 assert(b->special == ConstValSpecialStatic); 3626 switch (a->type->id) { 3627 case TypeTableEntryIdOpaque: 3628 zig_unreachable(); 3629 case TypeTableEntryIdEnum: 3630 { 3631 ConstEnumValue *enum1 = &a->data.x_enum; 3632 ConstEnumValue *enum2 = &b->data.x_enum; 3633 if (enum1->tag == enum2->tag) { 3634 TypeEnumField *enum_field = &a->type->data.enumeration.fields[enum1->tag]; 3635 if (type_has_bits(enum_field->type_entry)) { 3636 zig_panic("TODO const expr analyze enum special value for equality"); 3637 } else { 3638 return true; 3639 } 3640 } 3641 return false; 3642 } 3643 case TypeTableEntryIdMetaType: 3644 return a->data.x_type == b->data.x_type; 3645 case TypeTableEntryIdVoid: 3646 return true; 3647 case TypeTableEntryIdPureError: 3648 return a->data.x_pure_err == b->data.x_pure_err; 3649 case TypeTableEntryIdFn: 3650 return a->data.x_fn.fn_entry == b->data.x_fn.fn_entry && 3651 a->data.x_fn.is_inline == b->data.x_fn.is_inline; 3652 case TypeTableEntryIdBool: 3653 return a->data.x_bool == b->data.x_bool; 3654 case TypeTableEntryIdInt: 3655 case TypeTableEntryIdFloat: 3656 case TypeTableEntryIdNumLitFloat: 3657 case TypeTableEntryIdNumLitInt: 3658 case TypeTableEntryIdEnumTag: 3659 return bignum_cmp_eq(&a->data.x_bignum, &b->data.x_bignum); 3660 case TypeTableEntryIdPointer: 3661 if (a->data.x_ptr.special != b->data.x_ptr.special) 3662 return false; 3663 if (a->data.x_ptr.mut != b->data.x_ptr.mut) 3664 return false; 3665 switch (a->data.x_ptr.special) { 3666 case ConstPtrSpecialInvalid: 3667 zig_unreachable(); 3668 case ConstPtrSpecialRef: 3669 if (a->data.x_ptr.data.ref.pointee != b->data.x_ptr.data.ref.pointee) 3670 return false; 3671 return true; 3672 case ConstPtrSpecialBaseArray: 3673 if (a->data.x_ptr.data.base_array.array_val != b->data.x_ptr.data.base_array.array_val) 3674 return false; 3675 if (a->data.x_ptr.data.base_array.elem_index != b->data.x_ptr.data.base_array.elem_index) 3676 return false; 3677 if (a->data.x_ptr.data.base_array.is_cstr != b->data.x_ptr.data.base_array.is_cstr) 3678 return false; 3679 return true; 3680 case ConstPtrSpecialBaseStruct: 3681 if (a->data.x_ptr.data.base_struct.struct_val != b->data.x_ptr.data.base_struct.struct_val) 3682 return false; 3683 if (a->data.x_ptr.data.base_struct.field_index != b->data.x_ptr.data.base_struct.field_index) 3684 return false; 3685 return true; 3686 case ConstPtrSpecialHardCodedAddr: 3687 if (a->data.x_ptr.data.hard_coded_addr.addr != b->data.x_ptr.data.hard_coded_addr.addr) 3688 return false; 3689 return true; 3690 case ConstPtrSpecialDiscard: 3691 return true; 3692 } 3693 zig_unreachable(); 3694 case TypeTableEntryIdArray: 3695 zig_panic("TODO"); 3696 case TypeTableEntryIdStruct: 3697 for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) { 3698 ConstExprValue *field_a = &a->data.x_struct.fields[i]; 3699 ConstExprValue *field_b = &b->data.x_struct.fields[i]; 3700 if (!const_values_equal(field_a, field_b)) 3701 return false; 3702 } 3703 return true; 3704 case TypeTableEntryIdUnion: 3705 zig_panic("TODO"); 3706 case TypeTableEntryIdUndefLit: 3707 zig_panic("TODO"); 3708 case TypeTableEntryIdNullLit: 3709 zig_panic("TODO"); 3710 case TypeTableEntryIdMaybe: 3711 if (a->data.x_maybe == nullptr || b->data.x_maybe == nullptr) { 3712 return (a->data.x_maybe == nullptr && b->data.x_maybe == nullptr); 3713 } else { 3714 return const_values_equal(a->data.x_maybe, b->data.x_maybe); 3715 } 3716 case TypeTableEntryIdErrorUnion: 3717 zig_panic("TODO"); 3718 case TypeTableEntryIdNamespace: 3719 return a->data.x_import == b->data.x_import; 3720 case TypeTableEntryIdBlock: 3721 return a->data.x_block == b->data.x_block; 3722 case TypeTableEntryIdArgTuple: 3723 return a->data.x_arg_tuple.start_index == b->data.x_arg_tuple.start_index && 3724 a->data.x_arg_tuple.end_index == b->data.x_arg_tuple.end_index; 3725 case TypeTableEntryIdBoundFn: 3726 case TypeTableEntryIdInvalid: 3727 case TypeTableEntryIdUnreachable: 3728 case TypeTableEntryIdVar: 3729 zig_unreachable(); 3730 } 3731 zig_unreachable(); 3732 } 3733 3734 uint64_t max_unsigned_val(TypeTableEntry *type_entry) { 3735 assert(type_entry->id == TypeTableEntryIdInt); 3736 if (type_entry->data.integral.bit_count == 64) { 3737 return UINT64_MAX; 3738 } else { 3739 return (((uint64_t)1) << type_entry->data.integral.bit_count) - 1; 3740 } 3741 } 3742 3743 static int64_t max_signed_val(TypeTableEntry *type_entry) { 3744 assert(type_entry->id == TypeTableEntryIdInt); 3745 3746 if (type_entry->data.integral.bit_count == 64) { 3747 return INT64_MAX; 3748 } else { 3749 return (((uint64_t)1) << (type_entry->data.integral.bit_count - 1)) - 1; 3750 } 3751 } 3752 3753 int64_t min_signed_val(TypeTableEntry *type_entry) { 3754 assert(type_entry->id == TypeTableEntryIdInt); 3755 if (type_entry->data.integral.bit_count == 64) { 3756 return INT64_MIN; 3757 } else { 3758 return -((int64_t)(((uint64_t)1) << (type_entry->data.integral.bit_count - 1))); 3759 } 3760 } 3761 3762 void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val, bool is_max) { 3763 if (type_entry->id == TypeTableEntryIdInt) { 3764 const_val->special = ConstValSpecialStatic; 3765 if (is_max) { 3766 if (type_entry->data.integral.is_signed) { 3767 int64_t val = max_signed_val(type_entry); 3768 bignum_init_signed(&const_val->data.x_bignum, val); 3769 } else { 3770 uint64_t val = max_unsigned_val(type_entry); 3771 bignum_init_unsigned(&const_val->data.x_bignum, val); 3772 } 3773 } else { 3774 if (type_entry->data.integral.is_signed) { 3775 int64_t val = min_signed_val(type_entry); 3776 bignum_init_signed(&const_val->data.x_bignum, val); 3777 } else { 3778 bignum_init_unsigned(&const_val->data.x_bignum, 0); 3779 } 3780 } 3781 } else if (type_entry->id == TypeTableEntryIdFloat) { 3782 zig_panic("TODO analyze_min_max_value float"); 3783 } else if (type_entry->id == TypeTableEntryIdBool) { 3784 const_val->special = ConstValSpecialStatic; 3785 const_val->data.x_bool = is_max; 3786 } else if (type_entry->id == TypeTableEntryIdVoid) { 3787 // nothing to do 3788 } else { 3789 zig_unreachable(); 3790 } 3791 } 3792 3793 void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { 3794 switch (const_val->special) { 3795 case ConstValSpecialRuntime: 3796 buf_appendf(buf, "(runtime value)"); 3797 return; 3798 case ConstValSpecialUndef: 3799 buf_appendf(buf, "undefined"); 3800 return; 3801 case ConstValSpecialStatic: 3802 break; 3803 } 3804 assert(const_val->type); 3805 3806 TypeTableEntry *type_entry = const_val->type; 3807 switch (type_entry->id) { 3808 case TypeTableEntryIdOpaque: 3809 zig_unreachable(); 3810 case TypeTableEntryIdInvalid: 3811 buf_appendf(buf, "(invalid)"); 3812 return; 3813 case TypeTableEntryIdVar: 3814 buf_appendf(buf, "(var)"); 3815 return; 3816 case TypeTableEntryIdVoid: 3817 buf_appendf(buf, "{}"); 3818 return; 3819 case TypeTableEntryIdNumLitFloat: 3820 buf_appendf(buf, "%f", const_val->data.x_bignum.data.x_float); 3821 return; 3822 case TypeTableEntryIdNumLitInt: 3823 { 3824 BigNum *bignum = &const_val->data.x_bignum; 3825 const char *negative_str = bignum->is_negative ? "-" : ""; 3826 buf_appendf(buf, "%s%llu", negative_str, bignum->data.x_uint); 3827 return; 3828 } 3829 case TypeTableEntryIdMetaType: 3830 buf_appendf(buf, "%s", buf_ptr(&const_val->data.x_type->name)); 3831 return; 3832 case TypeTableEntryIdInt: 3833 { 3834 BigNum *bignum = &const_val->data.x_bignum; 3835 assert(bignum->kind == BigNumKindInt); 3836 const char *negative_str = bignum->is_negative ? "-" : ""; 3837 buf_appendf(buf, "%s%llu", negative_str, bignum->data.x_uint); 3838 } 3839 return; 3840 case TypeTableEntryIdFloat: 3841 { 3842 BigNum *bignum = &const_val->data.x_bignum; 3843 assert(bignum->kind == BigNumKindFloat); 3844 buf_appendf(buf, "%f", bignum->data.x_float); 3845 } 3846 return; 3847 case TypeTableEntryIdUnreachable: 3848 buf_appendf(buf, "@unreachable()"); 3849 return; 3850 case TypeTableEntryIdBool: 3851 { 3852 const char *value = const_val->data.x_bool ? "true" : "false"; 3853 buf_appendf(buf, "%s", value); 3854 return; 3855 } 3856 case TypeTableEntryIdPointer: 3857 switch (const_val->data.x_ptr.special) { 3858 case ConstPtrSpecialInvalid: 3859 zig_unreachable(); 3860 case ConstPtrSpecialRef: 3861 case ConstPtrSpecialBaseStruct: 3862 buf_appendf(buf, "&"); 3863 render_const_value(g, buf, const_ptr_pointee(g, const_val)); 3864 return; 3865 case ConstPtrSpecialBaseArray: 3866 if (const_val->data.x_ptr.data.base_array.is_cstr) { 3867 buf_appendf(buf, "&(c str lit)"); 3868 return; 3869 } else { 3870 buf_appendf(buf, "&"); 3871 render_const_value(g, buf, const_ptr_pointee(g, const_val)); 3872 return; 3873 } 3874 case ConstPtrSpecialHardCodedAddr: 3875 buf_appendf(buf, "(&%s)(%" PRIx64 ")", buf_ptr(&type_entry->data.pointer.child_type->name), 3876 const_val->data.x_ptr.data.hard_coded_addr.addr); 3877 return; 3878 case ConstPtrSpecialDiscard: 3879 buf_append_str(buf, "&_"); 3880 return; 3881 } 3882 zig_unreachable(); 3883 case TypeTableEntryIdFn: 3884 { 3885 FnTableEntry *fn_entry = const_val->data.x_fn.fn_entry; 3886 const char *inline_str = const_val->data.x_fn.is_inline ? "inline " : ""; 3887 buf_appendf(buf, "%s%s", inline_str, buf_ptr(&fn_entry->symbol_name)); 3888 return; 3889 } 3890 case TypeTableEntryIdBlock: 3891 { 3892 AstNode *node = const_val->data.x_block->source_node; 3893 buf_appendf(buf, "(scope:%zu:%zu)", node->line + 1, node->column + 1); 3894 return; 3895 } 3896 case TypeTableEntryIdArray: 3897 { 3898 TypeTableEntry *child_type = type_entry->data.array.child_type; 3899 uint64_t len = type_entry->data.array.len; 3900 3901 if (const_val->data.x_array.special == ConstArraySpecialUndef) { 3902 buf_append_str(buf, "undefined"); 3903 return; 3904 } 3905 3906 // if it's []u8, assume UTF-8 and output a string 3907 if (child_type->id == TypeTableEntryIdInt && 3908 child_type->data.integral.bit_count == 8 && 3909 !child_type->data.integral.is_signed) 3910 { 3911 buf_append_char(buf, '"'); 3912 for (uint64_t i = 0; i < len; i += 1) { 3913 ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i]; 3914 uint64_t big_c = child_value->data.x_bignum.data.x_uint; 3915 assert(big_c <= UINT8_MAX); 3916 uint8_t c = (uint8_t)big_c; 3917 if (c == '"') { 3918 buf_append_str(buf, "\\\""); 3919 } else { 3920 buf_append_char(buf, c); 3921 } 3922 } 3923 buf_append_char(buf, '"'); 3924 return; 3925 } 3926 3927 buf_appendf(buf, "%s{", buf_ptr(&type_entry->name)); 3928 for (uint64_t i = 0; i < len; i += 1) { 3929 if (i != 0) 3930 buf_appendf(buf, ","); 3931 ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i]; 3932 render_const_value(g, buf, child_value); 3933 } 3934 buf_appendf(buf, "}"); 3935 return; 3936 } 3937 case TypeTableEntryIdNullLit: 3938 { 3939 buf_appendf(buf, "null"); 3940 return; 3941 } 3942 case TypeTableEntryIdUndefLit: 3943 { 3944 buf_appendf(buf, "undefined"); 3945 return; 3946 } 3947 case TypeTableEntryIdMaybe: 3948 { 3949 if (const_val->data.x_maybe) { 3950 render_const_value(g, buf, const_val->data.x_maybe); 3951 } else { 3952 buf_appendf(buf, "null"); 3953 } 3954 return; 3955 } 3956 case TypeTableEntryIdNamespace: 3957 { 3958 ImportTableEntry *import = const_val->data.x_import; 3959 if (import->c_import_node) { 3960 buf_appendf(buf, "(namespace from C import)"); 3961 } else { 3962 buf_appendf(buf, "(namespace: %s)", buf_ptr(import->path)); 3963 } 3964 return; 3965 } 3966 case TypeTableEntryIdBoundFn: 3967 { 3968 FnTableEntry *fn_entry = const_val->data.x_bound_fn.fn; 3969 const char *inline_str = const_val->data.x_bound_fn.is_inline ? "inline " : ""; 3970 buf_appendf(buf, "(%sbound fn %s)", inline_str, buf_ptr(&fn_entry->symbol_name)); 3971 return; 3972 } 3973 case TypeTableEntryIdStruct: 3974 { 3975 buf_appendf(buf, "(struct %s constant)", buf_ptr(&type_entry->name)); 3976 return; 3977 } 3978 case TypeTableEntryIdEnum: 3979 { 3980 buf_appendf(buf, "(enum %s constant)", buf_ptr(&type_entry->name)); 3981 return; 3982 } 3983 case TypeTableEntryIdErrorUnion: 3984 { 3985 buf_appendf(buf, "(error union %s constant)", buf_ptr(&type_entry->name)); 3986 return; 3987 } 3988 case TypeTableEntryIdUnion: 3989 { 3990 buf_appendf(buf, "(union %s constant)", buf_ptr(&type_entry->name)); 3991 return; 3992 } 3993 case TypeTableEntryIdPureError: 3994 { 3995 buf_appendf(buf, "(pure error constant)"); 3996 return; 3997 } 3998 case TypeTableEntryIdEnumTag: 3999 { 4000 TypeTableEntry *enum_type = type_entry->data.enum_tag.enum_type; 4001 TypeEnumField *field = &enum_type->data.enumeration.fields[const_val->data.x_bignum.data.x_uint]; 4002 buf_appendf(buf, "%s.%s", buf_ptr(&enum_type->name), buf_ptr(field->name)); 4003 return; 4004 } 4005 case TypeTableEntryIdArgTuple: 4006 { 4007 buf_appendf(buf, "(args value)"); 4008 return; 4009 } 4010 } 4011 zig_unreachable(); 4012 } 4013 4014 TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) { 4015 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdInt); 4016 entry->is_copyable = true; 4017 entry->type_ref = LLVMIntType(size_in_bits); 4018 4019 const char u_or_i = is_signed ? 'i' : 'u'; 4020 buf_resize(&entry->name, 0); 4021 buf_appendf(&entry->name, "%c%" PRIu8, u_or_i, size_in_bits); 4022 4023 unsigned dwarf_tag; 4024 if (is_signed) { 4025 if (size_in_bits == 8) { 4026 dwarf_tag = ZigLLVMEncoding_DW_ATE_signed_char(); 4027 } else { 4028 dwarf_tag = ZigLLVMEncoding_DW_ATE_signed(); 4029 } 4030 } else { 4031 if (size_in_bits == 8) { 4032 dwarf_tag = ZigLLVMEncoding_DW_ATE_unsigned_char(); 4033 } else { 4034 dwarf_tag = ZigLLVMEncoding_DW_ATE_unsigned(); 4035 } 4036 } 4037 4038 uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, entry->type_ref); 4039 entry->di_type = ZigLLVMCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), debug_size_in_bits, dwarf_tag); 4040 entry->data.integral.is_signed = is_signed; 4041 entry->data.integral.bit_count = size_in_bits; 4042 return entry; 4043 } 4044 4045 uint32_t type_id_hash(TypeId x) { 4046 switch (x.id) { 4047 case TypeTableEntryIdInvalid: 4048 case TypeTableEntryIdVar: 4049 case TypeTableEntryIdOpaque: 4050 case TypeTableEntryIdMetaType: 4051 case TypeTableEntryIdVoid: 4052 case TypeTableEntryIdBool: 4053 case TypeTableEntryIdUnreachable: 4054 case TypeTableEntryIdFloat: 4055 case TypeTableEntryIdStruct: 4056 case TypeTableEntryIdNumLitFloat: 4057 case TypeTableEntryIdNumLitInt: 4058 case TypeTableEntryIdUndefLit: 4059 case TypeTableEntryIdNullLit: 4060 case TypeTableEntryIdMaybe: 4061 case TypeTableEntryIdErrorUnion: 4062 case TypeTableEntryIdPureError: 4063 case TypeTableEntryIdEnum: 4064 case TypeTableEntryIdEnumTag: 4065 case TypeTableEntryIdUnion: 4066 case TypeTableEntryIdFn: 4067 case TypeTableEntryIdNamespace: 4068 case TypeTableEntryIdBlock: 4069 case TypeTableEntryIdBoundFn: 4070 case TypeTableEntryIdArgTuple: 4071 zig_unreachable(); 4072 case TypeTableEntryIdPointer: 4073 return hash_ptr(x.data.pointer.child_type) + 4074 (x.data.pointer.is_const ? (uint32_t)2749109194 : (uint32_t)4047371087) + 4075 (x.data.pointer.is_volatile ? (uint32_t)536730450 : (uint32_t)1685612214) + 4076 (((uint32_t)x.data.pointer.bit_offset) * (uint32_t)2639019452) + 4077 (((uint32_t)x.data.pointer.unaligned_bit_count) * (uint32_t)529908881); 4078 case TypeTableEntryIdArray: 4079 return hash_ptr(x.data.array.child_type) + 4080 ((uint32_t)x.data.array.size * (uint32_t)2122979968); 4081 case TypeTableEntryIdInt: 4082 return (x.data.integer.is_signed ? (uint32_t)2652528194 : (uint32_t)163929201) + 4083 (((uint32_t)x.data.integer.bit_count) * (uint32_t)2998081557); 4084 } 4085 zig_unreachable(); 4086 } 4087 4088 bool type_id_eql(TypeId a, TypeId b) { 4089 if (a.id != b.id) 4090 return false; 4091 switch (a.id) { 4092 case TypeTableEntryIdInvalid: 4093 case TypeTableEntryIdVar: 4094 case TypeTableEntryIdMetaType: 4095 case TypeTableEntryIdVoid: 4096 case TypeTableEntryIdBool: 4097 case TypeTableEntryIdUnreachable: 4098 case TypeTableEntryIdFloat: 4099 case TypeTableEntryIdStruct: 4100 case TypeTableEntryIdNumLitFloat: 4101 case TypeTableEntryIdNumLitInt: 4102 case TypeTableEntryIdUndefLit: 4103 case TypeTableEntryIdNullLit: 4104 case TypeTableEntryIdMaybe: 4105 case TypeTableEntryIdErrorUnion: 4106 case TypeTableEntryIdPureError: 4107 case TypeTableEntryIdEnum: 4108 case TypeTableEntryIdEnumTag: 4109 case TypeTableEntryIdUnion: 4110 case TypeTableEntryIdFn: 4111 case TypeTableEntryIdNamespace: 4112 case TypeTableEntryIdBlock: 4113 case TypeTableEntryIdBoundFn: 4114 case TypeTableEntryIdArgTuple: 4115 case TypeTableEntryIdOpaque: 4116 zig_unreachable(); 4117 case TypeTableEntryIdPointer: 4118 return a.data.pointer.child_type == b.data.pointer.child_type && 4119 a.data.pointer.is_const == b.data.pointer.is_const && 4120 a.data.pointer.is_volatile == b.data.pointer.is_volatile && 4121 a.data.pointer.bit_offset == b.data.pointer.bit_offset && 4122 a.data.pointer.unaligned_bit_count == b.data.pointer.unaligned_bit_count; 4123 case TypeTableEntryIdArray: 4124 return a.data.array.child_type == b.data.array.child_type && 4125 a.data.array.size == b.data.array.size; 4126 case TypeTableEntryIdInt: 4127 return a.data.integer.is_signed == b.data.integer.is_signed && 4128 a.data.integer.bit_count == b.data.integer.bit_count; 4129 } 4130 zig_unreachable(); 4131 } 4132 4133 uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) { 4134 switch (x.id) { 4135 case ZigLLVMFnIdCtz: 4136 return (uint32_t)(x.data.ctz.bit_count) * (uint32_t)810453934; 4137 case ZigLLVMFnIdClz: 4138 return (uint32_t)(x.data.clz.bit_count) * (uint32_t)2428952817; 4139 case ZigLLVMFnIdOverflowArithmetic: 4140 return ((uint32_t)(x.data.overflow_arithmetic.bit_count) * 87135777) + 4141 ((uint32_t)(x.data.overflow_arithmetic.add_sub_mul) * 31640542) + 4142 ((uint32_t)(x.data.overflow_arithmetic.is_signed) ? 1062315172 : 314955820); 4143 } 4144 zig_unreachable(); 4145 } 4146 4147 bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) { 4148 if (a.id != b.id) 4149 return false; 4150 switch (a.id) { 4151 case ZigLLVMFnIdCtz: 4152 return a.data.ctz.bit_count == b.data.ctz.bit_count; 4153 case ZigLLVMFnIdClz: 4154 return a.data.clz.bit_count == b.data.clz.bit_count; 4155 case ZigLLVMFnIdOverflowArithmetic: 4156 return (a.data.overflow_arithmetic.bit_count == b.data.overflow_arithmetic.bit_count) && 4157 (a.data.overflow_arithmetic.add_sub_mul == b.data.overflow_arithmetic.add_sub_mul) && 4158 (a.data.overflow_arithmetic.is_signed == b.data.overflow_arithmetic.is_signed); 4159 } 4160 zig_unreachable(); 4161 } 4162 4163 void expand_undef_array(CodeGen *g, ConstExprValue *const_val) { 4164 assert(const_val->type->id == TypeTableEntryIdArray); 4165 if (const_val->data.x_array.special == ConstArraySpecialUndef) { 4166 const_val->data.x_array.special = ConstArraySpecialNone; 4167 size_t elem_count = const_val->type->data.array.len; 4168 const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(elem_count); 4169 for (size_t i = 0; i < elem_count; i += 1) { 4170 ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i]; 4171 element_val->type = const_val->type->data.array.child_type; 4172 init_const_undefined(g, element_val); 4173 ConstParent *parent = get_const_val_parent(g, element_val); 4174 if (parent != nullptr) { 4175 parent->id = ConstParentIdArray; 4176 parent->data.p_array.array_val = const_val; 4177 parent->data.p_array.elem_index = i; 4178 } 4179 } 4180 } 4181 } 4182 4183 ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) { 4184 assert(value->type); 4185 TypeTableEntry *type_entry = value->type; 4186 if (type_entry->id == TypeTableEntryIdArray) { 4187 expand_undef_array(g, value); 4188 return &value->data.x_array.s_none.parent; 4189 } else if (type_entry->id == TypeTableEntryIdStruct) { 4190 return &value->data.x_struct.parent; 4191 } 4192 return nullptr; 4193 } 4194 4195 FnTableEntry *get_extern_panic_fn(CodeGen *g) { 4196 if (g->extern_panic_fn) 4197 return g->extern_panic_fn; 4198 4199 FnTypeId fn_type_id = {0}; 4200 fn_type_id.is_extern = true; 4201 fn_type_id.is_cold = true; 4202 fn_type_id.param_count = 2; 4203 fn_type_id.param_info = allocate<FnTypeParamInfo>(2); 4204 fn_type_id.next_param_index = 0; 4205 fn_type_id.param_info[0].type = get_pointer_to_type(g, g->builtin_types.entry_u8, true); 4206 fn_type_id.param_info[1].type = g->builtin_types.entry_usize; 4207 fn_type_id.return_type = g->builtin_types.entry_unreachable; 4208 4209 TypeTableEntry *fn_type = get_fn_type(g, &fn_type_id); 4210 assert(!type_is_invalid(fn_type)); 4211 4212 FnTableEntry *fn_entry = create_fn_raw(FnInlineAuto, GlobalLinkageIdStrong); 4213 buf_init_from_str(&fn_entry->symbol_name, "__zig_panic"); 4214 4215 TldFn *tld_fn = allocate<TldFn>(1); 4216 init_tld(&tld_fn->base, TldIdFn, &fn_entry->symbol_name, VisibModPrivate, nullptr, nullptr); 4217 tld_fn->fn_entry = fn_entry; 4218 4219 g->external_prototypes.put_unique(tld_fn->base.name, &tld_fn->base); 4220 4221 fn_entry->type_entry = fn_type; 4222 4223 g->extern_panic_fn = fn_entry; 4224 return g->extern_panic_fn; 4225 } 4226