diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-04-16 16:20:29 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-04-16 16:20:29 -0700 |
| commit | a271f12a149239ab6e6361423589687e32f64cda (patch) | |
| tree | ea35c9389e0b01a24bba957525cabda86e8847ff /src | |
| parent | edd75d03e312d6020623df4e06c9bb19c2f217c5 (diff) | |
| download | zig-a271f12a149239ab6e6361423589687e32f64cda.tar.gz zig-a271f12a149239ab6e6361423589687e32f64cda.zip | |
AstGen: store list of imports
Diffstat (limited to 'src')
| -rw-r--r-- | src/AstGen.zig | 30 | ||||
| -rw-r--r-- | src/Compilation.zig | 2 | ||||
| -rw-r--r-- | src/Zir.zig | 40 |
3 files changed, 56 insertions, 16 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig index 303da5c58c..a9422a0472 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -35,6 +35,8 @@ string_bytes: ArrayListUnmanaged(u8) = .{}, arena: *Allocator, string_table: std.StringHashMapUnmanaged(u32) = .{}, compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{}, +/// String table indexes, keeps track of all `@import` operands. +imports: std.AutoArrayHashMapUnmanaged(u32, void) = .{}, pub fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 { const fields = std.meta.fields(@TypeOf(extra)); @@ -76,8 +78,8 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir { }; defer astgen.deinit(gpa); - // Indexes 0,1 of extra are reserved and set at the end. - try astgen.extra.resize(gpa, 2); + // First few indexes of extra are reserved and set at the end. + try astgen.extra.resize(gpa, @typeInfo(Zir.ExtraIndex).Enum.fields.len); var gen_scope: Scope.GenZir = .{ .force_comptime = true, @@ -103,20 +105,21 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir { container_decl, .struct_decl, )) |struct_decl_ref| { - astgen.extra.items[0] = @enumToInt(struct_decl_ref); + astgen.extra.items[@enumToInt(Zir.ExtraIndex.main_struct)] = @enumToInt(struct_decl_ref); } else |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, error.AnalysisFail => {}, // Handled via compile_errors below. } + const err_index = @enumToInt(Zir.ExtraIndex.compile_errors); if (astgen.compile_errors.items.len == 0) { - astgen.extra.items[1] = 0; + astgen.extra.items[err_index] = 0; } else { try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len + 1 + astgen.compile_errors.items.len * @typeInfo(Zir.Inst.CompileErrors.Item).Struct.fields.len); - astgen.extra.items[1] = astgen.addExtraAssumeCapacity(Zir.Inst.CompileErrors{ + astgen.extra.items[err_index] = astgen.addExtraAssumeCapacity(Zir.Inst.CompileErrors{ .items_len = @intCast(u32, astgen.compile_errors.items.len), }); @@ -125,6 +128,21 @@ pub fn generate(gpa: *Allocator, file: *Scope.File) InnerError!Zir { } } + const imports_index = @enumToInt(Zir.ExtraIndex.imports); + if (astgen.imports.count() == 0) { + astgen.extra.items[imports_index] = 0; + } else { + try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len + + @typeInfo(Zir.Inst.Imports).Struct.fields.len + astgen.imports.count()); + + astgen.extra.items[imports_index] = astgen.addExtraAssumeCapacity(Zir.Inst.Imports{ + .imports_len = @intCast(u32, astgen.imports.count()), + }); + for (astgen.imports.items()) |entry| { + astgen.extra.appendAssumeCapacity(entry.key); + } + } + return Zir{ .instructions = astgen.instructions.toOwnedSlice(), .string_bytes = astgen.string_bytes.toOwnedSlice(gpa), @@ -138,6 +156,7 @@ pub fn deinit(astgen: *AstGen, gpa: *Allocator) void { astgen.string_table.deinit(gpa); astgen.string_bytes.deinit(gpa); astgen.compile_errors.deinit(gpa); + astgen.imports.deinit(gpa); } pub const ResultLoc = union(enum) { @@ -4684,6 +4703,7 @@ fn builtinCall( } const str_lit_token = main_tokens[operand_node]; const str = try gz.strLitAsString(str_lit_token); + try astgen.imports.put(astgen.gpa, str.index, {}); const result = try gz.addStrTok(.import, str.index, str_lit_token); return rvalue(gz, scope, rl, result, node); }, diff --git a/src/Compilation.zig b/src/Compilation.zig index b3fe13db1b..85a0820f05 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -432,7 +432,7 @@ pub const AllErrors = struct { assert(file.zir_loaded); assert(file.tree_loaded); const Zir = @import("Zir.zig"); - const payload_index = file.zir.extra[Zir.compile_error_extra_index]; + const payload_index = file.zir.extra[@enumToInt(Zir.ExtraIndex.compile_errors)]; assert(payload_index != 0); const header = file.zir.extraData(Zir.Inst.CompileErrors, payload_index); diff --git a/src/Zir.zig b/src/Zir.zig index ab883df68e..4a7322d4c6 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -34,16 +34,21 @@ instructions: std.MultiArrayList(Inst).Slice, /// `string_bytes` array is agnostic to either usage. string_bytes: []u8, /// The meaning of this data is determined by `Inst.Tag` value. -/// Indexes 0 and 1 are reserved for: -/// 0. struct_decl: Ref -/// - the main struct decl for this file -/// 1. errors_payload_index: u32 -/// - if this is 0, no compile errors. Otherwise there is a `CompileErrors` -/// payload at this index. +/// The first few indexes are reserved. See `ExtraIndex` for the values. extra: []u32, -pub const main_struct_extra_index = 0; -pub const compile_error_extra_index = 1; +pub const ExtraIndex = enum(u32) { + /// Ref. The main struct decl for this file. + main_struct, + /// If this is 0, no compile errors. Otherwise there is a `CompileErrors` + /// payload at this index. + compile_errors, + /// If this is 0, this file contains no imports. Otherwise there is a `Imports` + /// payload at this index. + imports, + + _, +}; /// Returns the requested data, as well as the new index which is at the start of the /// trailers for the object. @@ -80,7 +85,7 @@ pub fn refSlice(code: Zir, start: usize, len: usize) []Inst.Ref { } pub fn hasCompileErrors(code: Zir) bool { - return code.extra[compile_error_extra_index] != 0; + return code.extra[@enumToInt(ExtraIndex.compile_errors)] != 0; } pub fn deinit(code: *Zir, gpa: *Allocator) void { @@ -109,10 +114,20 @@ pub fn renderAsTextToFile( .param_count = 0, }; - const main_struct_inst = scope_file.zir.extra[0] - @intCast(u32, Inst.Ref.typed_value_map.len); + const main_struct_inst = scope_file.zir.extra[@enumToInt(ExtraIndex.main_struct)] - + @intCast(u32, Inst.Ref.typed_value_map.len); try fs_file.writer().print("%{d} ", .{main_struct_inst}); try writer.writeInstToStream(fs_file.writer(), main_struct_inst); try fs_file.writeAll("\n"); + const imports_index = scope_file.zir.extra[@enumToInt(ExtraIndex.imports)]; + if (imports_index != 0) { + try fs_file.writeAll("Imports:\n"); + const imports_len = scope_file.zir.extra[imports_index]; + for (scope_file.zir.extra[imports_index + 1 ..][0..imports_len]) |str_index| { + const import_path = scope_file.zir.nullTerminatedString(str_index); + try fs_file.writer().print(" {s}\n", .{import_path}); + } + } } /// These are untyped instructions generated from an Abstract Syntax Tree. @@ -1649,6 +1664,11 @@ pub const Inst = struct { notes: u32, }; }; + + /// Trailing: for each `imports_len` there is a string table index. + pub const Imports = struct { + imports_len: u32, + }; }; pub const SpecialProng = enum { none, @"else", under }; |
