aboutsummaryrefslogtreecommitdiff
path: root/src-self-hosted/Module.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-08-25 14:12:48 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-08-25 14:12:48 -0700
commita8f0f37adb3bae8ad3d1f344fdaf1f1051551d21 (patch)
treec433b384cc2dd72495c71d7820a69cc2ddd649d7 /src-self-hosted/Module.zig
parentf9bd049c89e4d2b4d3f51a937ec2114c3cac9176 (diff)
parent6fb105fdd7798dc988de09a7b6709c5168355dfa (diff)
downloadzig-a8f0f37adb3bae8ad3d1f344fdaf1f1051551d21.tar.gz
zig-a8f0f37adb3bae8ad3d1f344fdaf1f1051551d21.zip
Merge remote-tracking branch 'origin/master' into llvm11
Diffstat (limited to 'src-self-hosted/Module.zig')
-rw-r--r--src-self-hosted/Module.zig42
1 files changed, 42 insertions, 0 deletions
diff --git a/src-self-hosted/Module.zig b/src-self-hosted/Module.zig
index c0d1d0d654..82029c1e9f 100644
--- a/src-self-hosted/Module.zig
+++ b/src-self-hosted/Module.zig
@@ -80,6 +80,9 @@ deletion_set: std.ArrayListUnmanaged(*Decl) = .{},
root_name: []u8,
keep_source_files_loaded: bool,
+/// Error tags and their values, tag names are duped with mod.gpa.
+global_error_set: std.StringHashMapUnmanaged(u16) = .{},
+
pub const InnerError = error{ OutOfMemory, AnalysisFail };
const WorkItem = union(enum) {
@@ -928,6 +931,11 @@ pub fn deinit(self: *Module) void {
self.symbol_exports.deinit(gpa);
self.root_scope.destroy(gpa);
+
+ for (self.global_error_set.items()) |entry| {
+ gpa.free(entry.key);
+ }
+ self.global_error_set.deinit(gpa);
self.* = undefined;
}
@@ -2072,6 +2080,18 @@ fn createNewDecl(
return new_decl;
}
+/// Get error value for error tag `name`.
+pub fn getErrorValue(self: *Module, name: []const u8) !std.StringHashMapUnmanaged(u16).Entry {
+ const gop = try self.global_error_set.getOrPut(self.gpa, name);
+ if (gop.found_existing)
+ return gop.entry.*;
+ errdefer self.global_error_set.removeAssertDiscard(name);
+
+ gop.entry.key = try self.gpa.dupe(u8, name);
+ gop.entry.value = @intCast(u16, self.global_error_set.items().len - 1);
+ return gop.entry.*;
+}
+
/// TODO split this into `requireRuntimeBlock` and `requireFunctionBlock` and audit callsites.
pub fn requireRuntimeBlock(self: *Module, scope: *Scope, src: usize) !*Scope.Block {
return scope.cast(Scope.Block) orelse
@@ -3309,6 +3329,28 @@ pub fn arrayType(self: *Module, scope: *Scope, len: u64, sentinel: ?Value, elem_
return Type.initPayload(&payload.base);
}
+pub fn errorUnionType(self: *Module, scope: *Scope, error_set: Type, payload: Type) Allocator.Error!Type {
+ assert(error_set.zigTypeTag() == .ErrorSet);
+ if (error_set.eql(Type.initTag(.anyerror)) and payload.eql(Type.initTag(.void))) {
+ return Type.initTag(.anyerror_void_error_union);
+ }
+
+ const result = try scope.arena().create(Type.Payload.ErrorUnion);
+ result.* = .{
+ .error_set = error_set,
+ .payload = payload,
+ };
+ return Type.initPayload(&result.base);
+}
+
+pub fn anyframeType(self: *Module, scope: *Scope, return_type: Type) Allocator.Error!Type {
+ const result = try scope.arena().create(Type.Payload.AnyFrame);
+ result.* = .{
+ .return_type = return_type,
+ };
+ return Type.initPayload(&result.base);
+}
+
pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {
const zir_module = scope.namespace();
const source = zir_module.getSource(self) catch @panic("dumpInst failed to get source");