diff --git a/src-self-hosted/clang_options.zig b/src-self-hosted/clang_options.zig index 538f281706..70525655de 100644 --- a/src-self-hosted/clang_options.zig +++ b/src-self-hosted/clang_options.zig @@ -46,23 +46,23 @@ pub const CliArg = struct { multi_arg: u8, }; - pub fn matchEql(self: CliArg, arg: []const u8) bool { + pub fn matchEql(self: CliArg, arg: []const u8) u2 { if (self.pd1 and arg.len >= self.name.len + 1 and mem.startsWith(u8, arg, "-") and mem.eql(u8, arg[1..], self.name)) { - return true; + return 1; } if (self.pd2 and arg.len >= self.name.len + 2 and mem.startsWith(u8, arg, "--") and mem.eql(u8, arg[2..], self.name)) { - return true; + return 2; } if (self.psl and arg.len >= self.name.len + 1 and mem.startsWith(u8, arg, "/") and mem.eql(u8, arg[1..], self.name)) { - return true; + return 1; } - return false; + return 0; } pub fn matchStartsWith(self: CliArg, arg: []const u8) usize { diff --git a/src-self-hosted/clang_options_data.zig b/src-self-hosted/clang_options_data.zig index b1796dce75..1e472f80a5 100644 --- a/src-self-hosted/clang_options_data.zig +++ b/src-self-hosted/clang_options_data.zig @@ -35,7 +35,14 @@ flagpd1("MV"), flagpd1("Mach"), flagpd1("O0"), flagpd1("O4"), -flagpd1("O"), +.{ + .name = "O", + .syntax = .flag, + .zig_equivalent = .optimize, + .pd1 = true, + .pd2 = false, + .psl = false, +}, flagpd1("ObjC"), flagpd1("ObjC++"), flagpd1("P"), @@ -1485,7 +1492,7 @@ flagpd1("###"), .{ .name = "debug", .syntax = .flag, - .zig_equivalent = .other, + .zig_equivalent = .debug, .pd1 = false, .pd2 = true, .psl = false, @@ -1701,7 +1708,7 @@ flagpd1("###"), .{ .name = "optimize", .syntax = .flag, - .zig_equivalent = .other, + .zig_equivalent = .optimize, .pd1 = false, .pd2 = true, .psl = false, @@ -2034,7 +2041,7 @@ flagpd1("fno-semantic-interposition"), .{ .name = "O1", .syntax = .flag, - .zig_equivalent = .other, + .zig_equivalent = .optimize, .pd1 = true, .pd2 = false, .psl = true, @@ -2042,7 +2049,7 @@ flagpd1("fno-semantic-interposition"), .{ .name = "O2", .syntax = .flag, - .zig_equivalent = .other, + .zig_equivalent = .optimize, .pd1 = true, .pd2 = false, .psl = true, @@ -2083,7 +2090,7 @@ flagpd1("fno-ident"), .{ .name = "Og", .syntax = .flag, - .zig_equivalent = .other, + .zig_equivalent = .optimize, .pd1 = true, .pd2 = false, .psl = true, @@ -3088,7 +3095,14 @@ flagpd1("g0"), flagpd1("g1"), flagpd1("g2"), flagpd1("g3"), -flagpd1("g"), +.{ + .name = "g", + .syntax = .flag, + .zig_equivalent = .debug, + .pd1 = true, + .pd2 = false, + .psl = false, +}, sepd1("gcc-toolchain"), flagpd1("gcodeview"), flagpd1("gcodeview-ghash"), @@ -4954,7 +4968,7 @@ joinpd1("flto-jobs="), .{ .name = "fsanitize=", .syntax = .comma_joined, - .zig_equivalent = .other, + .zig_equivalent = .sanitize, .pd1 = true, .pd2 = false, .psl = false, @@ -4997,7 +5011,7 @@ joinpd1("segs_read_"), .{ .name = "optimize=", .syntax = .joined, - .zig_equivalent = .other, + .zig_equivalent = .optimize, .pd1 = false, .pd2 = true, .psl = false, @@ -5187,7 +5201,7 @@ joinpd1("Rpass="), .{ .name = "debug=", .syntax = .joined, - .zig_equivalent = .other, + .zig_equivalent = .debug, .pd1 = false, .pd2 = true, .psl = false, @@ -5231,7 +5245,14 @@ joinpd1("mtune="), .psl = false, }, joinpd1("weak-l"), -joinpd1("Ofast"), +.{ + .name = "Ofast", + .syntax = .joined, + .zig_equivalent = .optimize, + .pd1 = true, + .pd2 = false, + .psl = false, +}, jspd1("Tdata"), jspd1("Ttext"), .{ @@ -5584,7 +5605,14 @@ jspd1("G"), jspd1("I"), jspd1("J"), jspd1("L"), -joinpd1("O"), +.{ + .name = "O", + .syntax = .joined, + .zig_equivalent = .optimize, + .pd1 = true, + .pd2 = false, + .psl = false, +}, joinpd1("R"), jspd1("T"), jspd1("U"), @@ -5619,7 +5647,7 @@ joinpd1("Z"), .{ .name = "O", .syntax = .joined, - .zig_equivalent = .other, + .zig_equivalent = .optimize, .pd1 = true, .pd2 = false, .psl = true, diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index 030e9694e8..f67200097c 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -1248,6 +1248,9 @@ pub const ClangArgIterator = extern struct { rdynamic, wl, preprocess, + optimize, + debug, + sanitize, }; fn init(argv: []const [*:0]const u8) ClangArgIterator { @@ -1284,11 +1287,14 @@ pub const ClangArgIterator = extern struct { } find_clang_arg: for (clang_args) |clang_arg| switch (clang_arg.syntax) { - .flag => if (clang_arg.matchEql(arg)) { - self.zig_equivalent = clang_arg.zig_equivalent; - self.only_arg = arg.ptr; + .flag => { + const prefix_len = clang_arg.matchEql(arg); + if (prefix_len > 0) { + self.zig_equivalent = clang_arg.zig_equivalent; + self.only_arg = arg.ptr + prefix_len; - break :find_clang_arg; + break :find_clang_arg; + } }, .joined, .comma_joined => { // joined example: --target=foo @@ -1338,7 +1344,7 @@ pub const ClangArgIterator = extern struct { break :find_clang_arg; } }, - .separate => if (clang_arg.matchEql(arg)) { + .separate => if (clang_arg.matchEql(arg) > 0) { if (self.next_index >= self.argv_len) { std.debug.warn("Expected parameter after '{}'\n", .{arg}); process.exit(1); @@ -1355,7 +1361,7 @@ pub const ClangArgIterator = extern struct { @panic("TODO"); } }, - .multi_arg => if (clang_arg.matchEql(arg)) { + .multi_arg => if (clang_arg.matchEql(arg) > 0) { @panic("TODO"); }, } diff --git a/src/codegen.cpp b/src/codegen.cpp index 7b481f7c21..a0fd984740 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -9269,6 +9269,7 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa case BuildModeDebug: // windows c runtime requires -D_DEBUG if using debug libraries args.append("-D_DEBUG"); + args.append("-Og"); if (g->libc_link_lib != nullptr) { args.append("-fstack-protector-strong"); diff --git a/src/main.cpp b/src/main.cpp index 071b365d2f..b47e532d9b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -580,6 +580,7 @@ static int main0(int argc, char **argv) { return stage2_fmt(argc, argv); } else if (argc >= 2 && strcmp(argv[1], "cc") == 0) { emit_h = false; + strip = true; bool c_arg = false; Stage2ClangArgIterator it; @@ -664,6 +665,42 @@ static int main0(int argc, char **argv) { case Stage2ClangArgPreprocess: only_preprocess = true; break; + case Stage2ClangArgOptimize: + // alright what release mode do they want? + if (strcmp(it.only_arg, "Os") == 0) { + build_mode = BuildModeSmallRelease; + } else if (strcmp(it.only_arg, "O2") == 0 || + strcmp(it.only_arg, "O3") == 0 || + strcmp(it.only_arg, "O4") == 0) + { + build_mode = BuildModeFastRelease; + } else if (strcmp(it.only_arg, "Og") == 0) { + build_mode = BuildModeDebug; + } else { + for (size_t i = 0; i < it.other_args_len; i += 1) { + clang_argv.append(it.other_args_ptr[i]); + } + } + break; + case Stage2ClangArgDebug: + strip = false; + if (strcmp(it.only_arg, "-g") == 0) { + // we handled with strip = false above + } else { + for (size_t i = 0; i < it.other_args_len; i += 1) { + clang_argv.append(it.other_args_ptr[i]); + } + } + break; + case Stage2ClangArgSanitize: + if (strcmp(it.only_arg, "undefined") == 0) { + want_sanitize_c = WantCSanitizeEnabled; + } else { + for (size_t i = 0; i < it.other_args_len; i += 1) { + clang_argv.append(it.other_args_ptr[i]); + } + } + break; } } // Parse linker args @@ -715,6 +752,10 @@ static int main0(int argc, char **argv) { } } + if (want_sanitize_c == WantCSanitizeEnabled && build_mode == BuildModeFastRelease) { + build_mode = BuildModeSafeRelease; + } + if (!nostdlib && !have_libc) { have_libc = true; link_libs.append("c"); diff --git a/src/stage2.h b/src/stage2.h index 15c4c604cd..a66163eceb 100644 --- a/src/stage2.h +++ b/src/stage2.h @@ -334,6 +334,9 @@ enum Stage2ClangArg { Stage2ClangArgRDynamic, Stage2ClangArgWL, Stage2ClangArgPreprocess, + Stage2ClangArgOptimize, + Stage2ClangArgDebug, + Stage2ClangArgSanitize, }; // ABI warning diff --git a/tools/update_clang_options.zig b/tools/update_clang_options.zig index ccd4443130..f65c89c258 100644 --- a/tools/update_clang_options.zig +++ b/tools/update_clang_options.zig @@ -90,6 +90,62 @@ const known_options = [_]KnownOpt{ .name = "assemble", .ident = "driver_punt", }, + .{ + .name = "O1", + .ident = "optimize", + }, + .{ + .name = "O2", + .ident = "optimize", + }, + .{ + .name = "Og", + .ident = "optimize", + }, + .{ + .name = "O", + .ident = "optimize", + }, + .{ + .name = "Ofast", + .ident = "optimize", + }, + .{ + .name = "optimize", + .ident = "optimize", + }, + .{ + .name = "g", + .ident = "debug", + }, + .{ + .name = "debug", + .ident = "debug", + }, + .{ + .name = "g-dwarf", + .ident = "debug", + }, + .{ + .name = "g-dwarf-2", + .ident = "debug", + }, + .{ + .name = "g-dwarf-3", + .ident = "debug", + }, + .{ + .name = "g-dwarf-4", + .ident = "debug", + }, + .{ + .name = "g-dwarf-5", + .ident = "debug", + }, + .{ + .name = "fsanitize", + .ident = "sanitize", + }, }; const blacklisted_options = [_][]const u8{};