aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2016-02-04 00:58:45 -0700
committerAndrew Kelley <superjoe30@gmail.com>2016-02-04 00:58:45 -0700
commit1f9734d1eefa98c4c51ee740717a6cc003a5a7ed (patch)
treee1f6a95b41a3300c2f9ec639017b6202e82850a3 /src
parenta6d43352175ac49ee180592055d56101fe20b83a (diff)
downloadzig-1f9734d1eefa98c4c51ee740717a6cc003a5a7ed.tar.gz
zig-1f9734d1eefa98c4c51ee740717a6cc003a5a7ed.zip
allow defining errors with the same name
they get the same value, too.
Diffstat (limited to 'src')
-rw-r--r--src/all_types.hpp3
-rw-r--r--src/analyze.cpp49
-rw-r--r--src/codegen.cpp2
3 files changed, 33 insertions, 21 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 89c277914e..6613b6e685 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -271,6 +271,7 @@ struct AstNodeErrorValueDecl {
// populated by semantic analyzer
TopLevelDecl top_level_decl;
+ ErrorTableEntry *err;
};
enum BinOpType {
@@ -1034,6 +1035,7 @@ struct CodeGen {
HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> primitive_type_table;
HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> unresolved_top_level_decls;
HashMap<FnTypeId, TypeTableEntry *, fn_type_id_hash, fn_type_id_eql> fn_type_table;
+ HashMap<Buf *, ErrorTableEntry *, buf_hash, buf_eql_buf> error_table;
uint32_t next_unresolved_index;
@@ -1111,7 +1113,6 @@ struct CodeGen {
LLVMValueRef trap_fn_val;
bool error_during_imports;
uint32_t next_node_index;
- uint32_t next_error_index;
uint32_t error_value_count;
TypeTableEntry *err_tag_type;
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]
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 50fdafff71..e2b76a4a8c 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -1290,36 +1290,39 @@ static void preview_fn_proto(CodeGen *g, ImportTableEntry *import,
}
}
-static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
+static void preview_error_value_decl(CodeGen *g, AstNode *node) {
assert(node->type == NodeTypeErrorValueDecl);
ErrorTableEntry *err = allocate<ErrorTableEntry>(1);
- err->value = g->next_error_index;
- g->next_error_index += 1;
-
err->decl_node = node;
buf_init_from_buf(&err->name, &node->data.error_value_decl.name);
- auto existing_entry = import->block_context->error_table.maybe_get(&err->name);
+ auto existing_entry = g->error_table.maybe_get(&err->name);
if (existing_entry) {
- add_node_error(g, node, buf_sprintf("redefinition of error '%s'", buf_ptr(&err->name)));
+ // duplicate error definitions allowed and they get the same value
+ err->value = existing_entry->value->value;
} else {
- import->block_context->error_table.put(&err->name, err);
+ err->value = g->error_value_count;
+ g->error_value_count += 1;
+ g->error_table.put(&err->name, err);
}
+ node->data.error_value_decl.err = err;
+}
+
+static void resolve_error_value_decl(CodeGen *g, ImportTableEntry *import, AstNode *node) {
+ assert(node->type == NodeTypeErrorValueDecl);
+
+ ErrorTableEntry *err = node->data.error_value_decl.err;
+
+ import->block_context->error_table.put(&err->name, err);
+
bool is_pub = (node->data.error_value_decl.visib_mod != VisibModPrivate);
if (is_pub) {
for (int i = 0; i < import->importers.length; i += 1) {
ImporterInfo importer = import->importers.at(i);
- auto table_entry = importer.import->block_context->error_table.maybe_get(&err->name);
- if (table_entry) {
- add_node_error(g, importer.source_node,
- buf_sprintf("import of error '%s' overrides existing definition",
- buf_ptr(&err->name)));
- } else {
- importer.import->block_context->error_table.put(&err->name, err);
- }
+ importer.import->block_context->error_table.put(&err->name, err);
}
}
}
@@ -2516,7 +2519,7 @@ static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *
add_node_error(g, node,
buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name)));
- return get_error_type(g, g->builtin_types.entry_void);
+ return g->builtin_types.entry_invalid;
}
@@ -2766,6 +2769,16 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im
} else {
zig_unreachable();
}
+ } else if (resolved_type->id == TypeTableEntryIdPureError) {
+ bool are_equal = op1_val->data.x_err.err == op2_val->data.x_err.err;
+
+ if (bin_op_type == BinOpTypeCmpEq) {
+ answer = are_equal;
+ } else if (bin_op_type == BinOpTypeCmpNotEq) {
+ answer = !are_equal;
+ } else {
+ zig_unreachable();
+ }
} else {
zig_unreachable();
}
@@ -5402,7 +5415,7 @@ void semantic_analyze(CodeGen *g) {
target_import->importers.append({import, child});
} else if (child->type == NodeTypeErrorValueDecl) {
- g->error_value_count += 1;
+ preview_error_value_decl(g, child);
}
}
}
@@ -5428,8 +5441,6 @@ void semantic_analyze(CodeGen *g) {
}
}
- assert(g->error_value_count == g->next_error_index);
-
{
auto it = g->import_table.entry_iterator();
for (;;) {
diff --git a/src/codegen.cpp b/src/codegen.cpp
index ba72aa69d8..a96fe9ba0f 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -28,10 +28,10 @@ CodeGen *codegen_create(Buf *root_source_dir) {
g->primitive_type_table.init(32);
g->unresolved_top_level_decls.init(32);
g->fn_type_table.init(32);
+ g->error_table.init(16);
g->is_release_build = false;
g->is_test_build = false;
g->root_source_dir = root_source_dir;
- g->next_error_index = 1;
g->error_value_count = 1;
g->libc_lib_dir = buf_create_from_str(ZIG_LIBC_LIB_DIR);