diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-04-16 14:44:02 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-04-16 14:48:10 -0700 |
| commit | 01b4bf34ea4f37d8b778bb2413ac1fc445f8bead (patch) | |
| tree | 6075a5f6e35448ab1899b34a559d5c1ce9e27bd2 /src/main.zig | |
| parent | cf57e8223f06f6b305e7274445cf935b1ed312d2 (diff) | |
| download | zig-01b4bf34ea4f37d8b778bb2413ac1fc445f8bead.tar.gz zig-01b4bf34ea4f37d8b778bb2413ac1fc445f8bead.zip | |
stage2: AstGen improvements
* AstGen: represent compile errors in ZIR rather than returning
`error.AnalysisFail`.
* ZIR: remove decl_ref and decl_val instructions. These are replaced by
`decl_ref_named` and `decl_val_named`, respectively, which will
probably get renamed in the future to the instructions that were just
deleted.
* AstGen: implement `@This()`, `@fence()`, `@returnAddress()`, and
`@src()`.
* AstGen: struct_decl improved to support fields_len=0 but have decls.
* AstGen: fix missing null bytes after compile error messages.
* SrcLoc: no longer depend on `Decl`. Instead have an explicit field
`parent_decl_node` which is an absolute AST Node index.
* Module: `failed_files` table can have null value, in which case the
key, which is a `*Scope.File`, will have ZIR errors in it.
* ZIR: implement text rendering of struct decls.
* CLI: introduce debug_usage and `zig astgen` command which is enabled
when the compiler is built in debug mode.
Diffstat (limited to 'src/main.zig')
| -rw-r--r-- | src/main.zig | 99 |
1 files changed, 93 insertions, 6 deletions
diff --git a/src/main.zig b/src/main.zig index 044c6f0fec..40dd9f89af 100644 --- a/src/main.zig +++ b/src/main.zig @@ -25,7 +25,11 @@ pub fn fatal(comptime format: []const u8, args: anytype) noreturn { process.exit(1); } -pub const max_src_size = 2 * 1024 * 1024 * 1024; // 2 GiB +/// There are many assumptions in the entire codebase that Zig source files can +/// be byte-indexed with a u32 integer. +pub const max_src_size = std.math.maxInt(u32); + +pub const debug_extensions_enabled = std.builtin.mode == .Debug; pub const Color = enum { auto, @@ -33,7 +37,7 @@ pub const Color = enum { on, }; -const usage = +const normal_usage = \\Usage: zig [command] [options] \\ \\Commands: @@ -63,6 +67,16 @@ const usage = \\ ; +const debug_usage = normal_usage ++ + \\ + \\Debug Commands: + \\ + \\ astgen Print ZIR code for a .zig source file + \\ +; + +const usage = if (debug_extensions_enabled) debug_usage else normal_usage; + pub const log_level: std.log.Level = switch (std.builtin.mode) { .Debug => .debug, .ReleaseSafe, .ReleaseFast => .info, @@ -206,13 +220,15 @@ pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v const stdout = io.getStdOut().writer(); return @import("print_targets.zig").cmdTargets(arena, cmd_args, stdout, info.target); } else if (mem.eql(u8, cmd, "version")) { - try std.io.getStdOut().writeAll(build_options.version ++ "\n"); + return std.io.getStdOut().writeAll(build_options.version ++ "\n"); } else if (mem.eql(u8, cmd, "env")) { - try @import("print_env.zig").cmdEnv(arena, cmd_args, io.getStdOut().writer()); + return @import("print_env.zig").cmdEnv(arena, cmd_args, io.getStdOut().writer()); } else if (mem.eql(u8, cmd, "zen")) { - try io.getStdOut().writeAll(info_zen); + return io.getStdOut().writeAll(info_zen); } else if (mem.eql(u8, cmd, "help") or mem.eql(u8, cmd, "-h") or mem.eql(u8, cmd, "--help")) { - try io.getStdOut().writeAll(usage); + return io.getStdOut().writeAll(usage); + } else if (debug_extensions_enabled and mem.eql(u8, cmd, "astgen")) { + return cmdAstgen(gpa, arena, cmd_args); } else { std.log.info("{s}", .{usage}); fatal("unknown command: {s}", .{args[1]}); @@ -3485,3 +3501,74 @@ pub fn cleanExit() void { process.exit(0); } } + +/// This is only enabled for debug builds. +pub fn cmdAstgen( + gpa: *Allocator, + arena: *Allocator, + args: []const []const u8, +) !void { + const Module = @import("Module.zig"); + const AstGen = @import("AstGen.zig"); + const Zir = @import("Zir.zig"); + + const zig_source_file = args[0]; + + var f = try fs.cwd().openFile(zig_source_file, .{}); + defer f.close(); + + const stat = try f.stat(); + + if (stat.size > max_src_size) + return error.FileTooBig; + + var file: Module.Scope.File = .{ + .status = .never_loaded, + .source_loaded = false, + .tree_loaded = false, + .zir_loaded = false, + .sub_file_path = zig_source_file, + .source = undefined, + .stat_size = stat.size, + .stat_inode = stat.inode, + .stat_mtime = stat.mtime, + .tree = undefined, + .zir = undefined, + .pkg = undefined, + .namespace = undefined, + }; + + const source = try arena.allocSentinel(u8, stat.size, 0); + const amt = try f.readAll(source); + if (amt != stat.size) + return error.UnexpectedEndOfFile; + file.source = source; + file.source_loaded = true; + + file.tree = try std.zig.parse(gpa, file.source); + file.tree_loaded = true; + defer file.tree.deinit(gpa); + + for (file.tree.errors) |parse_error| { + try printErrMsgToFile(gpa, parse_error, file.tree, zig_source_file, io.getStdErr(), .auto); + } + if (file.tree.errors.len != 0) { + process.exit(1); + } + + file.zir = try AstGen.generate(gpa, &file); + file.zir_loaded = true; + defer file.zir.deinit(gpa); + + if (file.zir.hasCompileErrors()) { + var errors = std.ArrayList(Compilation.AllErrors.Message).init(arena); + try Compilation.AllErrors.addZir(arena, &errors, &file, source); + const ttyconf = std.debug.detectTTYConfig(); + for (errors.items) |full_err_msg| { + full_err_msg.renderToStdErr(ttyconf); + } + process.exit(1); + } + + return Zir.renderAsTextToFile(gpa, &file, io.getStdOut()); +} |
