Commit 2596f5d925

Andrew Kelley <andrew@ziglang.org>
2023-12-15 03:49:53
update bin_file.options references in Sema
mainly pertaining to error return tracing
1 parent 7e7d5dc
Changed files (5)
src
src/codegen/llvm.zig
@@ -1398,7 +1398,7 @@ pub const Object = struct {
         };
 
         const err_return_tracing = Type.fromInterned(fn_info.return_type).isError(mod) and
-            mod.comp.bin_file.options.error_return_tracing;
+            mod.comp.config.any_error_tracing;
 
         const err_ret_trace: Builder.Value = if (err_return_tracing) param: {
             const param = wip.arg(llvm_arg_i);
@@ -2820,7 +2820,7 @@ pub const Object = struct {
                 }
 
                 if (Type.fromInterned(fn_info.return_type).isError(mod) and
-                    o.module.comp.bin_file.options.error_return_tracing)
+                    o.module.comp.config.any_error_tracing)
                 {
                     const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType());
                     try param_di_types.append(try o.lowerDebugType(ptr_ty, .full));
@@ -2988,7 +2988,7 @@ pub const Object = struct {
         }
 
         const err_return_tracing = Type.fromInterned(fn_info.return_type).isError(mod) and
-            mod.comp.bin_file.options.error_return_tracing;
+            mod.comp.config.any_error_tracing;
 
         if (err_return_tracing) {
             try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
@@ -3677,7 +3677,7 @@ pub const Object = struct {
         }
 
         if (Type.fromInterned(fn_info.return_type).isError(mod) and
-            mod.comp.bin_file.options.error_return_tracing)
+            mod.comp.config.any_error_tracing)
         {
             const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType());
             try llvm_params.append(o.gpa, try o.lowerType(ptr_ty));
@@ -5142,7 +5142,7 @@ pub const FuncGen = struct {
         };
 
         const err_return_tracing = return_type.isError(mod) and
-            o.module.comp.bin_file.options.error_return_tracing;
+            o.module.comp.config.any_error_tracing;
         if (err_return_tracing) {
             assert(self.err_ret_trace != .none);
             try llvm_args.append(self.err_ret_trace);
src/Compilation/Config.zig
@@ -9,6 +9,10 @@ link_libunwind: bool,
 any_unwind_tables: bool,
 any_c_source_files: bool,
 any_non_single_threaded: bool,
+/// This is true if any Module has error_tracing set to true. Function types
+/// and function calling convention depend on this global value, however, other
+/// kinds of error tracing are omitted depending on the per-Module setting.
+any_error_tracing: bool,
 pie: bool,
 /// If this is true then linker code is responsible for making an LLVM IR
 /// Module, outputting it to an object file, and then linking that together
@@ -34,6 +38,8 @@ is_test: bool,
 test_evented_io: bool,
 entry: ?[]const u8,
 debug_format: DebugFormat,
+root_strip: bool,
+root_error_tracing: bool,
 
 pub const CFrontend = enum { clang, aro };
 
@@ -51,6 +57,7 @@ pub const Options = struct {
     emit_bin: bool,
     root_optimize_mode: ?std.builtin.OptimizeMode = null,
     root_strip: ?bool = null,
+    root_error_tracing: ?bool = null,
     link_mode: ?std.builtin.LinkMode = null,
     ensure_libc_on_non_freestanding: bool = false,
     ensure_libcpp_on_non_freestanding: bool = false,
@@ -60,6 +67,7 @@ pub const Options = struct {
     any_dyn_libs: bool = false,
     any_c_source_files: bool = false,
     any_non_stripped: bool = false,
+    any_error_tracing: bool = false,
     emit_llvm_ir: bool = false,
     emit_llvm_bc: bool = false,
     link_libc: ?bool = null,
@@ -395,6 +403,17 @@ pub fn resolve(options: Options) !Config {
         };
     };
 
+    const root_error_tracing = b: {
+        if (options.root_error_tracing) |x| break :b x;
+        if (root_strip) break :b false;
+        break :b switch (root_optimize_mode) {
+            .Debug => true,
+            .ReleaseSafe, .ReleaseFast, .ReleaseSmall => false,
+        };
+    };
+
+    const any_error_tracing = root_error_tracing or options.any_error_tracing;
+
     return .{
         .output_mode = options.output_mode,
         .have_zcu = options.have_zcu,
@@ -407,6 +426,8 @@ pub fn resolve(options: Options) !Config {
         .any_unwind_tables = any_unwind_tables,
         .any_c_source_files = options.any_c_source_files,
         .any_non_single_threaded = options.any_non_single_threaded,
+        .any_error_tracing = any_error_tracing,
+        .root_error_tracing = root_error_tracing,
         .pie = pie,
         .lto = lto,
         .import_memory = import_memory,
@@ -419,6 +440,7 @@ pub fn resolve(options: Options) !Config {
         .entry = entry,
         .wasi_exec_model = wasi_exec_model,
         .debug_format = debug_format,
+        .root_strip = root_strip,
     };
 }
 
src/Package/Module.zig
@@ -114,9 +114,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
     const strip = b: {
         if (options.inherited.strip) |x| break :b x;
         if (options.parent) |p| break :b p.strip;
-        if (optimize_mode == .ReleaseSmall) break :b true;
-        if (!target_util.hasDebugInfo(target)) break :b true;
-        break :b false;
+        break :b options.global.root_strip;
     };
 
     const valgrind = b: {
@@ -156,11 +154,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
     const error_tracing = b: {
         if (options.inherited.error_tracing) |x| break :b x;
         if (options.parent) |p| break :b p.error_tracing;
-        if (strip) break :b false;
-        break :b switch (optimize_mode) {
-            .Debug => true,
-            .ReleaseSafe, .ReleaseFast, .ReleaseSmall => false,
-        };
+        break :b options.global.root_error_tracing;
     };
 
     const pic = b: {
src/main.zig
@@ -1055,6 +1055,8 @@ fn buildOutputType(
                             create_module.opts.any_unwind_tables = true;
                         if (mod_opts.strip == false)
                             create_module.opts.any_non_stripped = true;
+                        if (mod_opts.error_tracing == true)
+                            create_module.opts.any_error_tracing = true;
 
                         const root_src = try introspect.resolvePath(arena, root_src_orig);
                         try create_module.modules.put(arena, mod_name, .{
@@ -2535,6 +2537,8 @@ fn buildOutputType(
             create_module.opts.any_unwind_tables = true;
         if (mod_opts.strip == false)
             create_module.opts.any_non_stripped = true;
+        if (mod_opts.error_tracing == true)
+            create_module.opts.any_error_tracing = true;
 
         const src_path = try introspect.resolvePath(arena, unresolved_src_path);
         try create_module.modules.put(arena, "main", .{
@@ -3741,6 +3745,7 @@ fn createModule(
         create_module.opts.resolved_target = resolved_target;
         create_module.opts.root_optimize_mode = cli_mod.inherited.optimize_mode;
         create_module.opts.root_strip = cli_mod.inherited.strip;
+        create_module.opts.root_error_tracing = cli_mod.inherited.error_tracing;
         const target = resolved_target.result;
 
         // First, remove libc, libc++, and compiler_rt libraries from the system libraries list.
src/Sema.zig
@@ -1329,13 +1329,13 @@ fn analyzeBodyInner(
             },
             .dbg_block_begin => {
                 dbg_block_begins += 1;
-                try sema.zirDbgBlockBegin(block);
+                try zirDbgBlockBegin(block);
                 i += 1;
                 continue;
             },
             .dbg_block_end => {
                 dbg_block_begins -= 1;
-                try sema.zirDbgBlockEnd(block);
+                try zirDbgBlockEnd(block);
                 i += 1;
                 continue;
             },
@@ -1830,17 +1830,17 @@ fn analyzeBodyInner(
     };
 
     // balance out dbg_block_begins in case of early noreturn
-    const noreturn_inst = block.instructions.popOrNull();
-    while (dbg_block_begins > 0) {
-        dbg_block_begins -= 1;
-        if (block.is_comptime or mod.comp.bin_file.options.strip) continue;
-
-        _ = try block.addInst(.{
-            .tag = .dbg_block_end,
-            .data = undefined,
-        });
+    if (!block.is_comptime and !block.ownerModule().strip) {
+        const noreturn_inst = block.instructions.popOrNull();
+        while (dbg_block_begins > 0) {
+            dbg_block_begins -= 1;
+            _ = try block.addInst(.{
+                .tag = .dbg_block_end,
+                .data = undefined,
+            });
+        }
+        if (noreturn_inst) |some| try block.instructions.append(sema.gpa, some);
     }
-    if (noreturn_inst) |some| try block.instructions.append(sema.gpa, some);
 
     // We may have overwritten the capture scope due to a `repeat` instruction where
     // the body had a capture; restore it now.
@@ -6272,7 +6272,7 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
     // ZIR code that possibly will need to generate runtime code. So error messages
     // and other source locations must not rely on sema.src being set from dbg_stmt
     // instructions.
-    if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return;
+    if (block.is_comptime or block.ownerModule().strip) return;
 
     const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
 
@@ -6297,8 +6297,8 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
     });
 }
 
-fn zirDbgBlockBegin(sema: *Sema, block: *Block) CompileError!void {
-    if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return;
+fn zirDbgBlockBegin(block: *Block) CompileError!void {
+    if (block.is_comptime or block.ownerModule().strip) return;
 
     _ = try block.addInst(.{
         .tag = .dbg_block_begin,
@@ -6306,8 +6306,8 @@ fn zirDbgBlockBegin(sema: *Sema, block: *Block) CompileError!void {
     });
 }
 
-fn zirDbgBlockEnd(sema: *Sema, block: *Block) CompileError!void {
-    if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return;
+fn zirDbgBlockEnd(block: *Block) CompileError!void {
+    if (block.is_comptime or block.ownerModule().strip) return;
 
     _ = try block.addInst(.{
         .tag = .dbg_block_end,
@@ -6321,7 +6321,7 @@ fn zirDbgVar(
     inst: Zir.Inst.Index,
     air_tag: Air.Inst.Tag,
 ) CompileError!void {
-    if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return;
+    if (block.is_comptime or block.ownerModule().strip) return;
 
     const str_op = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_op;
     const operand = try sema.resolveInst(str_op.operand);
@@ -6519,7 +6519,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
     const src = sema.src;
 
     if (!mod.backendSupportsFeature(.error_return_trace)) return .none;
-    if (!mod.comp.bin_file.options.error_return_tracing) return .none;
+    if (!block.ownerModule().error_tracing) return .none;
 
     if (block.is_comptime)
         return .none;
@@ -6703,7 +6703,7 @@ fn zirCall(
         input_is_error = false;
     }
 
-    if (mod.backendSupportsFeature(.error_return_trace) and mod.comp.bin_file.options.error_return_tracing and
+    if (mod.backendSupportsFeature(.error_return_trace) and block.ownerModule().error_tracing and
         !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace))
     {
         const return_ty = sema.typeOf(call_inst);
@@ -7456,7 +7456,7 @@ fn analyzeCall(
             new_fn_info.return_type = sema.fn_ret_ty.toIntern();
             const new_func_resolved_ty = try mod.funcType(new_fn_info);
             if (!is_comptime_call and !block.is_typeof) {
-                try sema.emitDbgInline(block, prev_fn_index, module_fn_index, new_func_resolved_ty, .dbg_inline_begin);
+                try emitDbgInline(block, prev_fn_index, module_fn_index, new_func_resolved_ty, .dbg_inline_begin);
 
                 const zir_tags = sema.code.instructions.items(.tag);
                 for (fn_info.param_body) |param| switch (zir_tags[@intFromEnum(param)]) {
@@ -7494,7 +7494,7 @@ fn analyzeCall(
             if (!is_comptime_call and !block.is_typeof and
                 sema.typeOf(result).zigTypeTag(mod) != .NoReturn)
             {
-                try sema.emitDbgInline(
+                try emitDbgInline(
                     block,
                     module_fn_index,
                     prev_fn_index,
@@ -8067,15 +8067,13 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type)
 }
 
 fn emitDbgInline(
-    sema: *Sema,
     block: *Block,
     old_func: InternPool.Index,
     new_func: InternPool.Index,
     new_func_ty: Type,
     tag: Air.Inst.Tag,
 ) CompileError!void {
-    const mod = sema.mod;
-    if (mod.comp.bin_file.options.strip) return;
+    if (block.ownerModule().strip) return;
 
     // Recursive inline call; no dbg_inline needed.
     if (old_func == new_func) return;
@@ -9109,7 +9107,7 @@ fn handleExternLibName(
             );
             break :blk;
         }
-        if (!target.isWasm() and !comp.bin_file.options.pic) {
+        if (!target.isWasm() and !block.ownerModule().pic) {
             return sema.fail(
                 block,
                 src_loc,
@@ -18738,16 +18736,16 @@ fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {
     const mod = sema.mod;
     if (!mod.backendSupportsFeature(.error_return_trace)) return false;
 
-    return fn_ret_ty.isError(mod) and
-        mod.comp.bin_file.options.error_return_tracing;
+    return fn_ret_ty.isError(mod) and mod.comp.config.any_error_tracing;
 }
 
 fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
     const mod = sema.mod;
     const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index;
 
+    // TODO: replace all of these checks with logic in module creation
     if (!mod.backendSupportsFeature(.error_return_trace)) return;
-    if (!mod.comp.bin_file.options.error_return_tracing) return;
+    if (!block.ownerModule().error_tracing) return;
 
     // This is only relevant at runtime.
     if (block.is_comptime or block.is_typeof) return;
@@ -18774,7 +18772,7 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index)
 
     if (!mod.backendSupportsFeature(.error_return_trace)) return;
     if (!ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn) return;
-    if (!mod.comp.bin_file.options.error_return_tracing) return;
+    if (!start_block.ownerModule().error_tracing) return;
 
     const tracy = trace(@src());
     defer tracy.end();
@@ -20045,7 +20043,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
 
     if (sema.owner_func_index != .none and
         ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn and
-        mod.comp.bin_file.options.error_return_tracing and
+        mod.ownerModule().error_tracing and
         mod.backendSupportsFeature(.error_return_trace))
     {
         return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
@@ -34504,7 +34502,9 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
 
     try sema.resolveTypeFully(Type.fromInterned(fn_ty_info.return_type));
 
-    if (mod.comp.bin_file.options.error_return_tracing and Type.fromInterned(fn_ty_info.return_type).isError(mod)) {
+    if (mod.comp.config.any_error_tracing and
+        Type.fromInterned(fn_ty_info.return_type).isError(mod))
+    {
         // Ensure the type exists so that backends can assume that.
         _ = try sema.getBuiltinType("StackTrace");
     }