authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-04 00:58:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-04 00:58:45-07:00
log1f9734d1eefa98c4c51ee740717a6cc003a5a7ed
treee1f6a95b41a3300c2f9ec639017b6202e82850a3
parenta6d43352175ac49ee180592055d56101fe20b83a

allow defining errors with the same name

they get the same value, too.

5 files changed, 44 insertions(+), 26 deletions(-)

src/all_types.hpp+2-1
...@@ -271,6 +271,7 @@ struct AstNodeErrorValueDecl {...@@ -271,6 +271,7 @@ struct AstNodeErrorValueDecl {
271271
272 // populated by semantic analyzer272 // populated by semantic analyzer
273 TopLevelDecl top_level_decl;273 TopLevelDecl top_level_decl;
274 ErrorTableEntry *err;
274};275};
275276
276enum BinOpType {277enum BinOpType {
...@@ -1034,6 +1035,7 @@ struct CodeGen {...@@ -1034,6 +1035,7 @@ struct CodeGen {
1034 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> primitive_type_table;1035 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> primitive_type_table;
1035 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> unresolved_top_level_decls;1036 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> unresolved_top_level_decls;
1036 HashMap<FnTypeId, TypeTableEntry *, fn_type_id_hash, fn_type_id_eql> fn_type_table;1037 HashMap<FnTypeId, TypeTableEntry *, fn_type_id_hash, fn_type_id_eql> fn_type_table;
1038 HashMap<Buf *, ErrorTableEntry *, buf_hash, buf_eql_buf> error_table;
10371039
1038 uint32_t next_unresolved_index;1040 uint32_t next_unresolved_index;
10391041
...@@ -1111,7 +1113,6 @@ struct CodeGen {...@@ -1111,7 +1113,6 @@ struct CodeGen {
1111 LLVMValueRef trap_fn_val;1113 LLVMValueRef trap_fn_val;
1112 bool error_during_imports;1114 bool error_during_imports;
1113 uint32_t next_node_index;1115 uint32_t next_node_index;
1114 uint32_t next_error_index;
1115 uint32_t error_value_count;1116 uint32_t error_value_count;
1116 TypeTableEntry *err_tag_type;1117 TypeTableEntry *err_tag_type;
1117 LLVMValueRef int_overflow_fns[2][3][4]; // [0-signed,1-unsigned][0-add,1-sub,2-mul][0-8,1-16,2-32,3-64]1118 LLVMValueRef int_overflow_fns[2][3][4]; // [0-signed,1-unsigned][0-add,1-sub,2-mul][0-8,1-16,2-32,3-64]
src/analyze.cpp+30-19
...@@ -1290,36 +1290,39 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,...@@ -1290,36 +1290,39 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
1290 }1290 }
1291}1291}
12921292
1293static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {1293static void preview_error_value_decl(CodeGen *g, AstNode *node) {
1294 assert(node->type == NodeTypeErrorValueDecl);1294 assert(node->type == NodeTypeErrorValueDecl);
12951295
1296 ErrorTableEntry *err = allocate<ErrorTableEntry>(1);1296 ErrorTableEntry *err = allocate<ErrorTableEntry>(1);
12971297
1298 err->value = g->next_error_index;
1299 g->next_error_index += 1;
1300
1301 err->decl_node = node;1298 err->decl_node = node;
1302 buf_init_from_buf(&err->name, &node->data.error_value_decl.name);1299 buf_init_from_buf(&err->name, &node->data.error_value_decl.name);
13031300
1304 auto existing_entry = import->block_context->error_table.maybe_get(&err->name);1301 auto existing_entry = g->error_table.maybe_get(&err->name);
1305 if (existing_entry) {1302 if (existing_entry) {
1306 add_node_error(g, node, buf_sprintf("redefinition of error '%s'", buf_ptr(&err->name)));1303 // duplicate error definitions allowed and they get the same value
1304 err->value = existing_entry->value->value;
1307 } else {1305 } else {
1308 import->block_context->error_table.put(&err->name, err);1306 err->value = g->error_value_count;
1307 g->error_value_count += 1;
1308 g->error_table.put(&err->name, err);
1309 }1309 }
13101310
1311 node->data.error_value_decl.err = err;
1312}
1313
1314static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
1315 assert(node->type == NodeTypeErrorValueDecl);
1316
1317 ErrorTableEntry *err = node->data.error_value_decl.err;
1318
1319 import->block_context->error_table.put(&err->name, err);
1320
1311 bool is_pub = (node->data.error_value_decl.visib_mod != VisibModPrivate);1321 bool is_pub = (node->data.error_value_decl.visib_mod != VisibModPrivate);
1312 if (is_pub) {1322 if (is_pub) {
1313 for (int i = 0; i < import->importers.length; i += 1) {1323 for (int i = 0; i < import->importers.length; i += 1) {
1314 ImporterInfo importer = import->importers.at(i);1324 ImporterInfo importer = import->importers.at(i);
1315 auto table_entry = importer.import->block_context->error_table.maybe_get(&err->name);1325 importer.import->block_context->error_table.put(&err->name, err);
1316 if (table_entry) {
1317 add_node_error(g, importer.source_node,
1318 buf_sprintf("import of error '%s' overrides existing definition",
1319 buf_ptr(&err->name)));
1320 } else {
1321 importer.import->block_context->error_table.put(&err->name, err);
1322 }
1323 }1326 }
1324 }1327 }
1325}1328}
...@@ -2516,7 +2519,7 @@ static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *...@@ -2516,7 +2519,7 @@ static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *
2516 add_node_error(g, node,2519 add_node_error(g, node,
2517 buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name)));2520 buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name)));
25182521
2519 return get_error_type(g, g->builtin_types.entry_void);2522 return g->builtin_types.entry_invalid;
2520}2523}
25212524
25222525
...@@ -2759,6 +2762,16 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im...@@ -2759,6 +2762,16 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im
2759 are_equal = true;2762 are_equal = true;
2760 }2763 }
2761 }2764 }
2765 if (bin_op_type == BinOpTypeCmpEq) {
2766 answer = are_equal;
2767 } else if (bin_op_type == BinOpTypeCmpNotEq) {
2768 answer = !are_equal;
2769 } else {
2770 zig_unreachable();
2771 }
2772 } else if (resolved_type->id == TypeTableEntryIdPureError) {
2773 bool are_equal = op1_val->data.x_err.err == op2_val->data.x_err.err;
2774
2762 if (bin_op_type == BinOpTypeCmpEq) {2775 if (bin_op_type == BinOpTypeCmpEq) {
2763 answer = are_equal;2776 answer = are_equal;
2764 } else if (bin_op_type == BinOpTypeCmpNotEq) {2777 } else if (bin_op_type == BinOpTypeCmpNotEq) {
...@@ -5402,7 +5415,7 @@ void semantic_analyze(CodeGen *g) {...@@ -5402,7 +5415,7 @@ void semantic_analyze(CodeGen *g) {
54025415
5403 target_import->importers.append({import, child});5416 target_import->importers.append({import, child});
5404 } else if (child->type == NodeTypeErrorValueDecl) {5417 } else if (child->type == NodeTypeErrorValueDecl) {
5405 g->error_value_count += 1;5418 preview_error_value_decl(g, child);
5406 }5419 }
5407 }5420 }
5408 }5421 }
...@@ -5428,8 +5441,6 @@ void semantic_analyze(CodeGen *g) {...@@ -5428,8 +5441,6 @@ void semantic_analyze(CodeGen *g) {
5428 }5441 }
5429 }5442 }
54305443
5431 assert(g->error_value_count == g->next_error_index);
5432
5433 {5444 {
5434 auto it = g->import_table.entry_iterator();5445 auto it = g->import_table.entry_iterator();
5435 for (;;) {5446 for (;;) {
src/codegen.cpp+1-1
...@@ -28,10 +28,10 @@ CodeGen *codegen_create(Buf *root_source_dir) {...@@ -28,10 +28,10 @@ CodeGen *codegen_create(Buf *root_source_dir) {
28 g->primitive_type_table.init(32);28 g->primitive_type_table.init(32);
29 g->unresolved_top_level_decls.init(32);29 g->unresolved_top_level_decls.init(32);
30 g->fn_type_table.init(32);30 g->fn_type_table.init(32);
31 g->error_table.init(16);
31 g->is_release_build = false;32 g->is_release_build = false;
32 g->is_test_build = false;33 g->is_test_build = false;
33 g->root_source_dir = root_source_dir;34 g->root_source_dir = root_source_dir;
34 g->next_error_index = 1;
35 g->error_value_count = 1;35 g->error_value_count = 1;
3636
37 g->libc_lib_dir = buf_create_from_str(ZIG_LIBC_LIB_DIR);37 g->libc_lib_dir = buf_create_from_str(ZIG_LIBC_LIB_DIR);
test/run_tests.cpp-5
...@@ -1789,11 +1789,6 @@ enum A {}...@@ -1789,11 +1789,6 @@ enum A {}
1789enum A {}1789enum A {}
1790 )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'A'");1790 )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'A'");
17911791
1792 add_compile_fail_case("redefinition of error values", R"SOURCE(
1793error A;
1794error A;
1795 )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of error 'A'");
1796
1797 add_compile_fail_case("redefinition of global variables", R"SOURCE(1792 add_compile_fail_case("redefinition of global variables", R"SOURCE(
1798var a : i32 = 1;1793var a : i32 = 1;
1799var a : i32 = 2;1794var a : i32 = 2;
test/self_hosted.zig+11
...@@ -35,3 +35,14 @@ fn a_func() -> i32 { 13 }...@@ -35,3 +35,14 @@ fn a_func() -> i32 { 13 }
35fn call_struct_field(foo: Foo) -> i32 {35fn call_struct_field(foo: Foo) -> i32 {
36 return foo.ptr();36 return foo.ptr();
37}37}
38
39
40
41error AnError;
42error AnError;
43error SecondError;
44
45#attribute("test")
46fn redefinition_of_error_values_allowed() {
47 if (error.AnError == error.SecondError) unreachable{}
48}