diff --git a/src/Builtins.zig b/src/Builtins.zig index fe676e93..22a0a582 100644 --- a/src/Builtins.zig +++ b/src/Builtins.zig @@ -355,7 +355,7 @@ test Iterator { test "All builtins" { var comp = Compilation.init(std.testing.allocator); defer comp.deinit(); - _ = try comp.generateBuiltinMacros(); + _ = try comp.generateBuiltinMacros(.include_system_defines); var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); @@ -378,7 +378,7 @@ test "Allocation failures" { fn testOne(allocator: std.mem.Allocator) !void { var comp = Compilation.init(allocator); defer comp.deinit(); - _ = try comp.generateBuiltinMacros(); + _ = try comp.generateBuiltinMacros(.include_system_defines); var arena = std.heap.ArenaAllocator.init(comp.gpa); defer arena.deinit(); diff --git a/src/Compilation.zig b/src/Compilation.zig index 8c2f16ef..078df18c 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -219,32 +219,15 @@ fn generateDateAndTime(w: anytype, timestamp: u47) !void { }); } -/// Generate builtin macros that will be available to each source file. -pub fn generateBuiltinMacros(comp: *Compilation) !Source { - try comp.generateBuiltinTypes(); - - var buf = std.ArrayList(u8).init(comp.gpa); - defer buf.deinit(); - const w = buf.writer(); +/// Which set of system defines to generate via generateBuiltinMacros +pub const SystemDefinesMode = enum { + /// Only define macros required by the C standard (date/time macros and those beginning with `__STDC`) + no_system_defines, + /// Define the standard set of system macros + include_system_defines, +}; - // standard macros - try w.writeAll( - \\#define __VERSION__ "Aro - ++ @import("lib.zig").version_str ++ "\"\n" ++ - \\#define __Aro__ - \\#define __STDC__ 1 - \\#define __STDC_HOSTED__ 1 - \\#define __STDC_NO_ATOMICS__ 1 - \\#define __STDC_NO_COMPLEX__ 1 - \\#define __STDC_NO_THREADS__ 1 - \\#define __STDC_NO_VLA__ 1 - \\#define __STDC_UTF_16__ 1 - \\#define __STDC_UTF_32__ 1 - \\ - ); - if (comp.langopts.standard.StdCVersionMacro()) |stdc_version| { - try w.print("#define __STDC_VERSION__ {s}\n", .{stdc_version}); - } +fn generateSystemDefines(comp: *Compilation, w: anytype) !void { const ptr_width = comp.target.ptrBitWidth(); // os macros @@ -414,10 +397,6 @@ pub fn generateBuiltinMacros(comp: *Compilation) !Source { \\ ); - // timestamps - const timestamp = try comp.getTimestamp(); - try generateDateAndTime(w, timestamp); - // types if (comp.getCharSignedness() == .unsigned) try w.writeAll("#define __CHAR_UNSIGNED__ 1\n"); try w.writeAll("#define __CHAR_BIT__ 8\n"); @@ -489,6 +468,49 @@ pub fn generateBuiltinMacros(comp: *Compilation) !Source { \\#define __DECIMAL_DIG__ __LDBL_DECIMAL_DIG__ \\ ); +} + +/// Generate builtin macros that will be available to each source file. +pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefinesMode) !Source { + try comp.generateBuiltinTypes(); + + var buf = std.ArrayList(u8).init(comp.gpa); + defer buf.deinit(); + + if (system_defines_mode == .include_system_defines) { + try buf.appendSlice( + \\#define __VERSION__ "Aro + ++ @import("lib.zig").version_str ++ "\"\n" ++ + \\#define __Aro__ + \\ + ); + } + + // standard macros + try buf.appendSlice( + \\#define __STDC__ 1 + \\#define __STDC_HOSTED__ 1 + \\#define __STDC_NO_ATOMICS__ 1 + \\#define __STDC_NO_COMPLEX__ 1 + \\#define __STDC_NO_THREADS__ 1 + \\#define __STDC_NO_VLA__ 1 + \\#define __STDC_UTF_16__ 1 + \\#define __STDC_UTF_32__ 1 + \\ + ); + if (comp.langopts.standard.StdCVersionMacro()) |stdc_version| { + try buf.appendSlice("#define __STDC_VERSION__ "); + try buf.appendSlice(stdc_version); + try buf.append('\n'); + } + + // timestamps + const timestamp = try comp.getTimestamp(); + try generateDateAndTime(buf.writer(), timestamp); + + if (system_defines_mode == .include_system_defines) { + try comp.generateSystemDefines(buf.writer()); + } return comp.addSourceFromBuffer("", buf.items); } diff --git a/src/Driver.zig b/src/Driver.zig index cf6ff2bb..9266a850 100644 --- a/src/Driver.zig +++ b/src/Driver.zig @@ -27,6 +27,7 @@ inputs: std.ArrayListUnmanaged(Source) = .{}, link_objects: std.ArrayListUnmanaged([]const u8) = .{}, output_name: ?[]const u8 = null, sysroot: ?[]const u8 = null, +system_defines: Compilation.SystemDefinesMode = .include_system_defines, temp_file_count: u32 = 0, /// If false, do not emit line directives in -E mode line_commands: bool = true, @@ -131,6 +132,7 @@ pub const usage = \\ --sysroot= Use dir as the logical root directory for headers and libraries (not fully implemented) \\ --target= Generate code for the given target \\ -U Undefine + \\ -undef Do not predefine any system-specific macros. Standard predefined macros remain defined. \\ -Werror Treat all warnings as errors \\ -Werror= Treat warning as error \\ -W Enable the specified warning @@ -218,6 +220,8 @@ pub fn parseArgs( macro = args[i]; } try macro_buf.print("#undef {s}\n", .{macro}); + } else if (mem.eql(u8, arg, "-undef")) { + d.system_defines = .no_system_defines; } else if (mem.eql(u8, arg, "-c") or mem.eql(u8, arg, "--compile")) { d.only_compile = true; } else if (mem.eql(u8, arg, "-E")) { @@ -497,7 +501,7 @@ pub fn main(d: *Driver, tc: *Toolchain, args: []const []const u8) !void { error.AroIncludeNotFound => return d.fatal("unable to find Aro builtin headers", .{}), }; - const builtin = try d.comp.generateBuiltinMacros(); + const builtin = try d.comp.generateBuiltinMacros(d.system_defines); const user_macros = try d.comp.addSourceFromBuffer("", macro_buf.items); const fast_exit = @import("builtin").mode != .Debug; diff --git a/test/cases/undef.c b/test/cases/undef.c new file mode 100644 index 00000000..d45a5d03 --- /dev/null +++ b/test/cases/undef.c @@ -0,0 +1,5 @@ +//aro-args -undef --target=x86_64-linux-gnu + +#if defined(linux) || defined(__linux) || defined(__linux__) +#error Should not be defined +#endif diff --git a/test/record_runner.zig b/test/record_runner.zig index 633babbe..b9684ee5 100644 --- a/test/record_runner.zig +++ b/test/record_runner.zig @@ -268,7 +268,7 @@ fn singleRun(alloc: std.mem.Allocator, test_dir: []const u8, test_case: TestCase } const user_macros = try comp.addSourceFromBuffer("", macro_buf.items); - const builtin_macros = try comp.generateBuiltinMacros(); + const builtin_macros = try comp.generateBuiltinMacros(.include_system_defines); var pp = aro.Preprocessor.init(&comp); defer pp.deinit(); diff --git a/test/runner.zig b/test/runner.zig index e50f3390..e3e1a9ef 100644 --- a/test/runner.zig +++ b/test/runner.zig @@ -11,9 +11,10 @@ const AllocatorError = std.mem.Allocator.Error; var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){}; /// Returns only_preprocess and line_markers settings if saw -E -fn addCommandLineArgs(comp: *aro.Compilation, file: aro.Source, macro_buf: anytype) !struct { bool, aro.Preprocessor.Linemarkers } { +fn addCommandLineArgs(comp: *aro.Compilation, file: aro.Source, macro_buf: anytype) !struct { bool, aro.Preprocessor.Linemarkers, aro.Compilation.SystemDefinesMode } { var only_preprocess = false; var line_markers: aro.Preprocessor.Linemarkers = .none; + var system_defines: aro.Compilation.SystemDefinesMode = .include_system_defines; if (std.mem.startsWith(u8, file.buf, "//aro-args")) { var test_args = std.ArrayList([]const u8).init(comp.gpa); defer test_args.deinit(); @@ -25,6 +26,7 @@ fn addCommandLineArgs(comp: *aro.Compilation, file: aro.Source, macro_buf: anyty defer driver.deinit(); _ = try driver.parseArgs(std.io.null_writer, macro_buf, test_args.items); only_preprocess = driver.only_preprocess; + system_defines = driver.system_defines; if (only_preprocess) { if (driver.line_commands) { line_markers = if (driver.use_line_directives) .line_directives else .numeric_directives; @@ -47,7 +49,7 @@ fn addCommandLineArgs(comp: *aro.Compilation, file: aro.Source, macro_buf: anyty } } - return .{ only_preprocess, line_markers }; + return .{ only_preprocess, line_markers, system_defines }; } fn testOne(allocator: std.mem.Allocator, path: []const u8, test_dir: []const u8) !void { @@ -61,10 +63,10 @@ fn testOne(allocator: std.mem.Allocator, path: []const u8, test_dir: []const u8) var macro_buf = std.ArrayList(u8).init(comp.gpa); defer macro_buf.deinit(); - _ = try addCommandLineArgs(&comp, file, macro_buf.writer()); + _, _, const system_defines = try addCommandLineArgs(&comp, file, macro_buf.writer()); const user_macros = try comp.addSourceFromBuffer("", macro_buf.items); - const builtin_macros = try comp.generateBuiltinMacros(); + const builtin_macros = try comp.generateBuiltinMacros(system_defines); var pp = aro.Preprocessor.init(&comp); defer pp.deinit(); @@ -209,10 +211,10 @@ pub fn main() !void { var macro_buf = std.ArrayList(u8).init(comp.gpa); defer macro_buf.deinit(); - const only_preprocess, const linemarkers = try addCommandLineArgs(&comp, file, macro_buf.writer()); + const only_preprocess, const linemarkers, const system_defines = try addCommandLineArgs(&comp, file, macro_buf.writer()); const user_macros = try comp.addSourceFromBuffer("", macro_buf.items); - const builtin_macros = try comp.generateBuiltinMacros(); + const builtin_macros = try comp.generateBuiltinMacros(system_defines); comp.diag.errors = 0; var pp = aro.Preprocessor.init(&comp);