| ... | @@ -224,48 +224,26 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) { | ... | @@ -224,48 +224,26 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) { |
| 224 | return child_type->error_parent; | 224 | return child_type->error_parent; |
| 225 | } else { | 225 | } else { |
| 226 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdError); | 226 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdError); |
| 227 | zig_panic("TODO get_error_type"); | | |
| 228 | // create a struct with a boolean whether this is the null value | | |
| 229 | assert(child_type->type_ref); | 227 | assert(child_type->type_ref); |
| 230 | LLVMTypeRef elem_types[] = { | | |
| 231 | child_type->type_ref, | | |
| 232 | LLVMInt1Type(), | | |
| 233 | }; | | |
| 234 | entry->type_ref = LLVMStructType(elem_types, 2, false); | | |
| 235 | buf_resize(&entry->name, 0); | | |
| 236 | buf_appendf(&entry->name, "?%s", buf_ptr(&child_type->name)); | | |
| 237 | entry->size_in_bits = child_type->size_in_bits + 8; | | |
| 238 | entry->align_in_bits = child_type->align_in_bits; | | |
| 239 | assert(child_type->di_type); | 228 | assert(child_type->di_type); |
| 240 | | 229 | |
| | 230 | buf_resize(&entry->name, 0); |
| | 231 | buf_appendf(&entry->name, "%%%s", buf_ptr(&child_type->name)); |
| 241 | | 232 | |
| 242 | LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit); | 233 | entry->data.error.child_type = child_type; |
| 243 | LLVMZigDIFile *di_file = nullptr; | | |
| 244 | unsigned line = 0; | | |
| 245 | entry->di_type = LLVMZigCreateReplaceableCompositeType(g->dbuilder, | | |
| 246 | LLVMZigTag_DW_structure_type(), buf_ptr(&entry->name), | | |
| 247 | compile_unit_scope, di_file, line); | | |
| 248 | | | |
| 249 | LLVMZigDIType *di_element_types[] = { | | |
| 250 | LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type), | | |
| 251 | "val", di_file, line, child_type->size_in_bits, child_type->align_in_bits, 0, 0, | | |
| 252 | child_type->di_type), | | |
| 253 | LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type), | | |
| 254 | "maybe", di_file, line, 8, 8, 8, 0, | | |
| 255 | child_type->di_type), | | |
| 256 | }; | | |
| 257 | LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder, | | |
| 258 | compile_unit_scope, | | |
| 259 | buf_ptr(&entry->name), | | |
| 260 | di_file, line, entry->size_in_bits, entry->align_in_bits, 0, | | |
| 261 | nullptr, di_element_types, 2, 0, nullptr, ""); | | |
| 262 | | 234 | |
| 263 | LLVMZigReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type); | 235 | if (child_type->size_in_bits == 0) { |
| 264 | entry->di_type = replacement_di_type; | 236 | TypeTableEntry *tag_type = get_smallest_unsigned_int_type(g, g->next_error_index); |
| | 237 | entry->type_ref = tag_type->type_ref; |
| | 238 | entry->size_in_bits = tag_type->size_in_bits; |
| | 239 | entry->align_in_bits = tag_type->align_in_bits; |
| | 240 | entry->di_type = tag_type->di_type; |
| 265 | | 241 | |
| 266 | entry->data.maybe.child_type = child_type; | 242 | } else { |
| | 243 | zig_panic("TODO get_error_type non-void"); |
| | 244 | } |
| 267 | | 245 | |
| 268 | child_type->maybe_parent = entry; | 246 | child_type->error_parent = entry; |
| 269 | return entry; | 247 | return entry; |
| 270 | } | 248 | } |
| 271 | } | 249 | } |
| ... | @@ -938,6 +916,40 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import, | ... | @@ -938,6 +916,40 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import, |
| 938 | } | 916 | } |
| 939 | } | 917 | } |
| 940 | | 918 | |
| | 919 | static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| | 920 | assert(node->type == NodeTypeErrorValueDecl); |
| | 921 | |
| | 922 | ErrorTableEntry *err = allocate<ErrorTableEntry>(1); |
| | 923 | |
| | 924 | err->value = g->next_error_index; |
| | 925 | g->next_error_index += 1; |
| | 926 | |
| | 927 | err->decl_node = node; |
| | 928 | buf_init_from_buf(&err->name, &node->data.error_value_decl.name); |
| | 929 | |
| | 930 | auto existing_entry = import->block_context->error_table.maybe_get(&err->name); |
| | 931 | if (existing_entry) { |
| | 932 | add_node_error(g, node, buf_sprintf("redefinition of error '%s'", buf_ptr(&err->name))); |
| | 933 | } else { |
| | 934 | import->block_context->error_table.put(&err->name, err); |
| | 935 | } |
| | 936 | |
| | 937 | bool is_pub = (node->data.error_value_decl.visib_mod != VisibModPrivate); |
| | 938 | if (is_pub) { |
| | 939 | for (int i = 0; i < import->importers.length; i += 1) { |
| | 940 | ImporterInfo importer = import->importers.at(i); |
| | 941 | auto table_entry = importer.import->block_context->error_table.maybe_get(&err->name); |
| | 942 | if (table_entry) { |
| | 943 | add_node_error(g, importer.source_node, |
| | 944 | buf_sprintf("import of error '%s' overrides existing definition", |
| | 945 | buf_ptr(&err->name))); |
| | 946 | } else { |
| | 947 | importer.import->block_context->error_table.put(&err->name, err); |
| | 948 | } |
| | 949 | } |
| | 950 | } |
| | 951 | } |
| | 952 | |
| 941 | static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) { | 953 | static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) { |
| 942 | switch (node->type) { | 954 | switch (node->type) { |
| 943 | case NodeTypeExternBlock: | 955 | case NodeTypeExternBlock: |
| ... | @@ -984,10 +996,8 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -984,10 +996,8 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode |
| 984 | break; | 996 | break; |
| 985 | } | 997 | } |
| 986 | case NodeTypeErrorValueDecl: | 998 | case NodeTypeErrorValueDecl: |
| 987 | { | 999 | resolve_error_value_decl(g, import, node); |
| 988 | zig_panic("TODO resolve_top_level_decl NodeTypeErrorValueDecl"); | 1000 | break; |
| 989 | break; | | |
| 990 | } | | |
| 991 | case NodeTypeUse: | 1001 | case NodeTypeUse: |
| 992 | // nothing to do here | 1002 | // nothing to do here |
| 993 | break; | 1003 | break; |
| ... | @@ -1388,6 +1398,7 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) { | ... | @@ -1388,6 +1398,7 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) { |
| 1388 | context->parent = parent; | 1398 | context->parent = parent; |
| 1389 | context->variable_table.init(8); | 1399 | context->variable_table.init(8); |
| 1390 | context->type_table.init(8); | 1400 | context->type_table.init(8); |
| | 1401 | context->error_table.init(8); |
| 1391 | | 1402 | |
| 1392 | if (parent) { | 1403 | if (parent) { |
| 1393 | context->parent_loop_node = parent->parent_loop_node; | 1404 | context->parent_loop_node = parent->parent_loop_node; |
| ... | @@ -1799,6 +1810,13 @@ static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, F | ... | @@ -1799,6 +1810,13 @@ static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, F |
| 1799 | return fn->type_entry; | 1810 | return fn->type_entry; |
| 1800 | } | 1811 | } |
| 1801 | | 1812 | |
| | 1813 | static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node, ErrorTableEntry *err) { |
| | 1814 | Expr *expr = get_resolved_expr(node); |
| | 1815 | expr->const_val.ok = true; |
| | 1816 | expr->const_val.data.x_err = err; |
| | 1817 | return get_error_type(g, g->builtin_types.entry_void); |
| | 1818 | } |
| | 1819 | |
| 1802 | static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node, bool value) { | 1820 | static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node, bool value) { |
| 1803 | Expr *expr = get_resolved_expr(node); | 1821 | Expr *expr = get_resolved_expr(node); |
| 1804 | expr->const_val.ok = true; | 1822 | expr->const_val.ok = true; |
| ... | @@ -2333,7 +2351,13 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Block | ... | @@ -2333,7 +2351,13 @@ static VariableTableEntry *add_local_var(CodeGen *g, AstNode *source_node, Block |
| 2333 | | 2351 | |
| 2334 | if (name) { | 2352 | if (name) { |
| 2335 | buf_init_from_buf(&variable_entry->name, name); | 2353 | buf_init_from_buf(&variable_entry->name, name); |
| 2336 | VariableTableEntry *existing_var = find_local_variable(context, name); | 2354 | VariableTableEntry *existing_var; |
| | 2355 | |
| | 2356 | if (context->fn_entry) { |
| | 2357 | existing_var = find_local_variable(context, name); |
| | 2358 | } else { |
| | 2359 | existing_var = find_variable(context, name); |
| | 2360 | } |
| 2337 | | 2361 | |
| 2338 | if (existing_var) { | 2362 | if (existing_var) { |
| 2339 | add_node_error(g, source_node, buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); | 2363 | add_node_error(g, source_node, buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); |
| ... | @@ -2511,7 +2535,18 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry | ... | @@ -2511,7 +2535,18 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry |
| 2511 | static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import, | 2535 | static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import, |
| 2512 | BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node) | 2536 | BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node) |
| 2513 | { | 2537 | { |
| 2514 | zig_panic("TODO analyze_error_literal_expr"); | 2538 | Buf *err_name = &node->data.error_literal.symbol; |
| | 2539 | |
| | 2540 | auto err_table_entry = import->block_context->error_table.maybe_get(err_name); |
| | 2541 | |
| | 2542 | if (err_table_entry) { |
| | 2543 | return resolve_expr_const_val_as_err(g, node, err_table_entry->value); |
| | 2544 | } |
| | 2545 | |
| | 2546 | add_node_error(g, node, |
| | 2547 | buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name))); |
| | 2548 | |
| | 2549 | return get_error_type(g, g->builtin_types.entry_void); |
| 2515 | } | 2550 | } |
| 2516 | | 2551 | |
| 2517 | static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 2552 | static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, BlockContext *context, |