Commit 2b65dc1032

Andrew Kelley <andrew@ziglang.org>
2020-03-22 03:30:46
zig cc: detect optimization and debug flags
1 parent 4b0ddb8
src/codegen.cpp
@@ -9269,6 +9269,7 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &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");
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");
src/stage2.h
@@ -334,6 +334,9 @@ enum Stage2ClangArg {
     Stage2ClangArgRDynamic,
     Stage2ClangArgWL,
     Stage2ClangArgPreprocess,
+    Stage2ClangArgOptimize,
+    Stage2ClangArgDebug,
+    Stage2ClangArgSanitize,
 };
 
 // ABI warning
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 {
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,
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");
             },
         }
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{};