diff options
Diffstat (limited to 'src/Compilation.zig')
| -rw-r--r-- | src/Compilation.zig | 616 |
1 files changed, 337 insertions, 279 deletions
diff --git a/src/Compilation.zig b/src/Compilation.zig index 947012e716..1c4c97e06f 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -4687,19 +4687,19 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: std.Pr try argv.appendSlice(&[_][]const u8{ self_exe_path, "clang" }); // if "ext" is explicit, add "-x <lang>". Otherwise let clang do its thing. - if (c_object.src.ext != null) { + if (c_object.src.ext != null or ext.clangNeedsLanguageOverride()) { try argv.appendSlice(&[_][]const u8{ "-x", switch (ext) { .assembly => "assembler", .assembly_with_cpp => "assembler-with-cpp", .c => "c", - .cpp => "c++", .h => "c-header", + .cpp => "c++", .hpp => "c++-header", + .m => "objective-c", .hm => "objective-c-header", + .mm => "objective-c++", .hmm => "objective-c++-header", .cu => "cuda", - .m => "objective-c", - .mm => "objective-c++", else => fatal("language '{s}' is unsupported in this context", .{@tagName(ext)}), } }); } @@ -5273,10 +5273,6 @@ pub fn addCCArgs( // can be disabled. try argv.append("--no-default-config"); - if (ext == .cpp) { - try argv.append("-nostdinc++"); - } - // We don't ever put `-fcolor-diagnostics` or `-fno-color-diagnostics` because in passthrough mode // we want Clang to infer it, and in normal mode we always want it off, which will be true since // clang will detect stderr as a pipe rather than a terminal. @@ -5285,117 +5281,312 @@ pub fn addCCArgs( try argv.append("-fno-caret-diagnostics"); } - try argv.append(if (comp.function_sections) "-ffunction-sections" else "-fno-function-sections"); - try argv.append(if (comp.data_sections) "-fdata-sections" else "-fno-data-sections"); + // We never want clang to invoke the system assembler for anything. So we would want + // this option always enabled. However, it only matters for some targets. To avoid + // "unused parameter" warnings, and to keep CLI spam to a minimum, we only put this + // flag on the command line if it is necessary. + if (target_util.clangMightShellOutForAssembly(target)) { + try argv.append("-integrated-as"); + } - try argv.append(if (mod.no_builtin) "-fno-builtin" else "-fbuiltin"); + const llvm_triple = try @import("codegen/llvm.zig").targetTriple(arena, target); + try argv.appendSlice(&[_][]const u8{ "-target", llvm_triple }); - if (comp.config.link_libcpp) { - const libcxx_include_path = try std.fs.path.join(arena, &[_][]const u8{ - comp.zig_lib_directory.path.?, "libcxx", "include", - }); - const libcxxabi_include_path = try std.fs.path.join(arena, &[_][]const u8{ - comp.zig_lib_directory.path.?, "libcxxabi", "include", - }); + if (target.cpu.arch.isArm()) { + try argv.append(if (target.cpu.arch.isThumb()) "-mthumb" else "-mno-thumb"); + } - try argv.append("-isystem"); - try argv.append(libcxx_include_path); + if (target_util.llvmMachineAbi(target)) |mabi| { + try argv.append(try std.fmt.allocPrint(arena, "-mabi={s}", .{mabi})); + } - try argv.append("-isystem"); - try argv.append(libcxxabi_include_path); + // We might want to support -mfloat-abi=softfp for Arm and CSKY here in the future. + if (target_util.clangSupportsFloatAbiArg(target)) { + const fabi = @tagName(target.floatAbi()); - if (target.abi.isMusl()) { - try argv.append("-D_LIBCPP_HAS_MUSL_LIBC"); - } - try argv.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS"); - try argv.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS"); - try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS"); + try argv.append(switch (target.cpu.arch) { + // For whatever reason, Clang doesn't support `-mfloat-abi` for s390x. + .s390x => try std.fmt.allocPrint(arena, "-m{s}-float", .{fabi}), + else => try std.fmt.allocPrint(arena, "-mfloat-abi={s}", .{fabi}), + }); + } - if (!comp.config.any_non_single_threaded) { - try argv.append("-D_LIBCPP_HAS_NO_THREADS"); - } + if (target_util.supports_fpic(target)) { + try argv.append(if (mod.pic) "-fPIC" else "-fno-PIC"); + } - // See the comment in libcxx.zig for more details about this. - try argv.append("-D_LIBCPP_PSTL_BACKEND_SERIAL"); + if (comp.mingw_unicode_entry_point) { + try argv.append("-municode"); + } - try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_VERSION={d}", .{ - @intFromEnum(comp.libcxx_abi_version), - })); - try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{ - @intFromEnum(comp.libcxx_abi_version), - })); + if (mod.code_model != .default) { + try argv.append(try std.fmt.allocPrint(arena, "-mcmodel={s}", .{@tagName(mod.code_model)})); + } - try argv.append(libcxx.hardeningModeFlag(mod.optimize_mode)); + try argv.ensureUnusedCapacity(2); + switch (comp.config.debug_format) { + .strip => {}, + .code_view => { + // -g is required here because -gcodeview doesn't trigger debug info + // generation, it only changes the type of information generated. + argv.appendSliceAssumeCapacity(&.{ "-g", "-gcodeview" }); + }, + .dwarf => |f| { + argv.appendAssumeCapacity("-gdwarf-4"); + switch (f) { + .@"32" => argv.appendAssumeCapacity("-gdwarf32"), + .@"64" => argv.appendAssumeCapacity("-gdwarf64"), + } + }, } - if (comp.config.link_libunwind) { - const libunwind_include_path = try std.fs.path.join(arena, &[_][]const u8{ - comp.zig_lib_directory.path.?, "libunwind", "include", - }); + if (comp.config.lto) { + try argv.append("-flto"); + } - try argv.append("-isystem"); - try argv.append(libunwind_include_path); + // This only works for preprocessed files. Guarded by `FileExt.clangSupportsDepFile`. + if (out_dep_path) |p| { + try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p }); } - if (comp.config.link_libc) { - if (target.isGnuLibC()) { - const target_version = target.os.versionRange().gnuLibCVersion().?; - const glibc_minor_define = try std.fmt.allocPrint(arena, "-D__GLIBC_MINOR__={d}", .{ - target_version.minor, + // Non-preprocessed assembly files don't support these flags. + if (ext != .assembly) { + try argv.append(if (target.os.tag == .freestanding) "-ffreestanding" else "-fhosted"); + + if (target_util.clangSupportsNoImplicitFloatArg(target) and target.floatAbi() == .soft) { + try argv.append("-mno-implicit-float"); + } + + if (target_util.hasRedZone(target)) { + try argv.append(if (mod.red_zone) "-mred-zone" else "-mno-red-zone"); + } + + try argv.append(if (mod.omit_frame_pointer) "-fomit-frame-pointer" else "-fno-omit-frame-pointer"); + + const ssp_buf_size = mod.stack_protector; + if (ssp_buf_size != 0) { + try argv.appendSlice(&[_][]const u8{ + "-fstack-protector-strong", + "--param", + try std.fmt.allocPrint(arena, "ssp-buffer-size={d}", .{ssp_buf_size}), }); - try argv.append(glibc_minor_define); - } else if (target.isMinGW()) { - try argv.append("-D__MSVCRT_VERSION__=0xE00"); // use ucrt + } else { + try argv.append("-fno-stack-protector"); + } + + try argv.append(if (mod.no_builtin) "-fno-builtin" else "-fbuiltin"); + + try argv.append(if (comp.function_sections) "-ffunction-sections" else "-fno-function-sections"); + try argv.append(if (comp.data_sections) "-fdata-sections" else "-fno-data-sections"); + + switch (mod.unwind_tables) { + .none => { + try argv.append("-fno-unwind-tables"); + try argv.append("-fno-asynchronous-unwind-tables"); + }, + .sync => { + // Need to override Clang's convoluted default logic. + try argv.append("-fno-asynchronous-unwind-tables"); + try argv.append("-funwind-tables"); + }, + .@"async" => try argv.append("-fasynchronous-unwind-tables"), + } + + try argv.append("-nostdinc"); + + if (ext == .cpp or ext == .hpp) { + try argv.append("-nostdinc++"); + } + + // LLVM IR files don't support these flags. + if (ext != .ll and ext != .bc) { + // https://github.com/llvm/llvm-project/issues/105972 + if (target.cpu.arch.isPowerPC() and target.floatAbi() == .soft) { + try argv.append("-D__NO_FPRS__"); + try argv.append("-D_SOFT_FLOAT"); + try argv.append("-D_SOFT_DOUBLE"); + } + + if (comp.config.link_libc) { + if (target.isGnuLibC()) { + const target_version = target.os.versionRange().gnuLibCVersion().?; + const glibc_minor_define = try std.fmt.allocPrint(arena, "-D__GLIBC_MINOR__={d}", .{ + target_version.minor, + }); + try argv.append(glibc_minor_define); + } else if (target.isMinGW()) { + try argv.append("-D__MSVCRT_VERSION__=0xE00"); // use ucrt - switch (ext) { - .c, .cpp, .m, .mm, .h, .hpp, .hm, .hmm, .cu, .rc, .assembly, .assembly_with_cpp => { const minver: u16 = @truncate(@intFromEnum(target.os.versionRange().windows.min) >> 16); try argv.append( try std.fmt.allocPrint(arena, "-D_WIN32_WINNT=0x{x:0>4}", .{minver}), ); - }, - else => {}, + } } - } - } - const llvm_triple = try @import("codegen/llvm.zig").targetTriple(arena, target); - try argv.appendSlice(&[_][]const u8{ "-target", llvm_triple }); + if (comp.config.link_libcpp) { + try argv.append("-isystem"); + try argv.append(try std.fs.path.join(arena, &[_][]const u8{ + comp.zig_lib_directory.path.?, "libcxx", "include", + })); - switch (ext) { - .c, .cpp, .m, .mm, .h, .hpp, .hm, .hmm, .cu, .rc => { - try argv.appendSlice(&[_][]const u8{ - "-nostdinc", - "-fno-spell-checking", - }); - if (comp.config.lto) { - try argv.append("-flto"); + try argv.append("-isystem"); + try argv.append(try std.fs.path.join(arena, &[_][]const u8{ + comp.zig_lib_directory.path.?, "libcxxabi", "include", + })); + + if (target.abi.isMusl()) { + try argv.append("-D_LIBCPP_HAS_MUSL_LIBC"); + } + + try argv.append("-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS"); + try argv.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS"); + try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS"); + + if (!comp.config.any_non_single_threaded) { + try argv.append("-D_LIBCPP_HAS_NO_THREADS"); + } + + // See the comment in libcxx.zig for more details about this. + try argv.append("-D_LIBCPP_PSTL_BACKEND_SERIAL"); + + try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_VERSION={d}", .{ + @intFromEnum(comp.libcxx_abi_version), + })); + try argv.append(try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{ + @intFromEnum(comp.libcxx_abi_version), + })); + + try argv.append(libcxx.hardeningModeFlag(mod.optimize_mode)); + } + + // According to Rich Felker libc headers are supposed to go before C language headers. + // However as noted by @dimenus, appending libc headers before compiler headers breaks + // intrinsics and other compiler specific items. + try argv.append("-isystem"); + try argv.append(try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "include" })); + + try argv.ensureUnusedCapacity(comp.libc_include_dir_list.len * 2); + for (comp.libc_include_dir_list) |include_dir| { + try argv.append("-isystem"); + try argv.append(include_dir); } - if (ext == .mm) { - try argv.append("-ObjC++"); + if (mod.resolved_target.is_native_os and mod.resolved_target.is_native_abi) { + try argv.ensureUnusedCapacity(comp.native_system_include_paths.len * 2); + for (comp.native_system_include_paths) |include_path| { + argv.appendAssumeCapacity("-isystem"); + argv.appendAssumeCapacity(include_path); + } } + if (comp.config.link_libunwind) { + try argv.append("-isystem"); + try argv.append(try std.fs.path.join(arena, &[_][]const u8{ + comp.zig_lib_directory.path.?, "libunwind", "include", + })); + } + + try argv.ensureUnusedCapacity(comp.libc_framework_dir_list.len * 2); for (comp.libc_framework_dir_list) |framework_dir| { try argv.appendSlice(&.{ "-iframework", framework_dir }); } + try argv.ensureUnusedCapacity(comp.framework_dirs.len * 2); for (comp.framework_dirs) |framework_dir| { try argv.appendSlice(&.{ "-F", framework_dir }); } + } + } - // According to Rich Felker libc headers are supposed to go before C language headers. - // However as noted by @dimenus, appending libc headers before c_headers breaks intrinsics - // and other compiler specific items. - const c_headers_dir = try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "include" }); - try argv.append("-isystem"); - try argv.append(c_headers_dir); + // Only assembly files support these flags. + switch (ext) { + .assembly, + .assembly_with_cpp, + => { + // The Clang assembler does not accept the list of CPU features like the + // compiler frontend does. Therefore we must hard-code the -m flags for + // all CPU features here. + switch (target.cpu.arch) { + .riscv32, .riscv64 => { + const RvArchFeat = struct { char: u8, feat: std.Target.riscv.Feature }; + const letters = [_]RvArchFeat{ + .{ .char = 'm', .feat = .m }, + .{ .char = 'a', .feat = .a }, + .{ .char = 'f', .feat = .f }, + .{ .char = 'd', .feat = .d }, + .{ .char = 'c', .feat = .c }, + }; + const prefix: []const u8 = if (target.cpu.arch == .riscv64) "rv64" else "rv32"; + const prefix_len = 4; + assert(prefix.len == prefix_len); + var march_buf: [prefix_len + letters.len + 1]u8 = undefined; + var march_index: usize = prefix_len; + @memcpy(march_buf[0..prefix.len], prefix); - for (comp.libc_include_dir_list) |include_dir| { - try argv.append("-isystem"); - try argv.append(include_dir); + if (std.Target.riscv.featureSetHas(target.cpu.features, .e)) { + march_buf[march_index] = 'e'; + } else { + march_buf[march_index] = 'i'; + } + march_index += 1; + + for (letters) |letter| { + if (std.Target.riscv.featureSetHas(target.cpu.features, letter.feat)) { + march_buf[march_index] = letter.char; + march_index += 1; + } + } + + const march_arg = try std.fmt.allocPrint(arena, "-march={s}", .{ + march_buf[0..march_index], + }); + try argv.append(march_arg); + + if (std.Target.riscv.featureSetHas(target.cpu.features, .relax)) { + try argv.append("-mrelax"); + } else { + try argv.append("-mno-relax"); + } + if (std.Target.riscv.featureSetHas(target.cpu.features, .save_restore)) { + try argv.append("-msave-restore"); + } else { + try argv.append("-mno-save-restore"); + } + }, + .mips, .mipsel, .mips64, .mips64el => { + if (target.cpu.model.llvm_name) |llvm_name| { + try argv.append(try std.fmt.allocPrint(arena, "-march={s}", .{llvm_name})); + } + }, + else => { + // TODO + }, } + if (target_util.clangAssemblerSupportsMcpuArg(target)) { + if (target.cpu.model.llvm_name) |llvm_name| { + try argv.append(try std.fmt.allocPrint(arena, "-mcpu={s}", .{llvm_name})); + } + } + }, + else => {}, + } + + // Only C-family files support these flags. + switch (ext) { + .c, + .h, + .cpp, + .hpp, + .m, + .hm, + .mm, + .hmm, + .cu, + => { + try argv.append("-fno-spell-checking"); + if (target_util.clangSupportsTargetCpuArg(target)) { if (target.cpu.model.llvm_name) |llvm_name| { try argv.appendSlice(&[_][]const u8{ @@ -5421,9 +5612,6 @@ pub fn addCCArgs( argv.appendAssumeCapacity(arg); } } - if (mod.code_model != .default) { - try argv.append(try std.fmt.allocPrint(arena, "-mcmodel={s}", .{@tagName(mod.code_model)})); - } switch (target.os.tag) { .windows => { @@ -5506,23 +5694,6 @@ pub fn addCCArgs( } } - if (target_util.hasRedZone(target)) { - try argv.append(if (mod.red_zone) "-mred-zone" else "-mno-red-zone"); - } - - try argv.append(if (mod.omit_frame_pointer) "-fomit-frame-pointer" else "-fno-omit-frame-pointer"); - - const ssp_buf_size = mod.stack_protector; - if (ssp_buf_size != 0) { - try argv.appendSlice(&[_][]const u8{ - "-fstack-protector-strong", - "--param", - try std.fmt.allocPrint(arena, "ssp-buffer-size={d}", .{ssp_buf_size}), - }); - } else { - try argv.append("-fno-stack-protector"); - } - switch (mod.optimize_mode) { .Debug => { // windows c runtime requires -D_DEBUG if using debug libraries @@ -5556,177 +5727,8 @@ pub fn addCCArgs( if (mod.optimize_mode != .Debug) { try argv.append("-Werror=date-time"); } - - switch (mod.unwind_tables) { - .none => { - try argv.append("-fno-unwind-tables"); - try argv.append("-fno-asynchronous-unwind-tables"); - }, - .sync => { - // Need to override Clang's convoluted default logic. - try argv.append("-fno-asynchronous-unwind-tables"); - try argv.append("-funwind-tables"); - }, - .@"async" => try argv.append("-fasynchronous-unwind-tables"), - } - }, - .shared_library, .ll, .bc, .unknown, .static_library, .object, .def, .zig, .res, .manifest => {}, - .assembly, .assembly_with_cpp => { - if (ext == .assembly_with_cpp) { - const c_headers_dir = try std.fs.path.join(arena, &[_][]const u8{ comp.zig_lib_directory.path.?, "include" }); - try argv.append("-isystem"); - try argv.append(c_headers_dir); - - for (comp.libc_include_dir_list) |include_dir| { - try argv.append("-isystem"); - try argv.append(include_dir); - } - } - - // The Clang assembler does not accept the list of CPU features like the - // compiler frontend does. Therefore we must hard-code the -m flags for - // all CPU features here. - switch (target.cpu.arch) { - .riscv32, .riscv64 => { - const RvArchFeat = struct { char: u8, feat: std.Target.riscv.Feature }; - const letters = [_]RvArchFeat{ - .{ .char = 'm', .feat = .m }, - .{ .char = 'a', .feat = .a }, - .{ .char = 'f', .feat = .f }, - .{ .char = 'd', .feat = .d }, - .{ .char = 'c', .feat = .c }, - }; - const prefix: []const u8 = if (target.cpu.arch == .riscv64) "rv64" else "rv32"; - const prefix_len = 4; - assert(prefix.len == prefix_len); - var march_buf: [prefix_len + letters.len + 1]u8 = undefined; - var march_index: usize = prefix_len; - @memcpy(march_buf[0..prefix.len], prefix); - - if (std.Target.riscv.featureSetHas(target.cpu.features, .e)) { - march_buf[march_index] = 'e'; - } else { - march_buf[march_index] = 'i'; - } - march_index += 1; - - for (letters) |letter| { - if (std.Target.riscv.featureSetHas(target.cpu.features, letter.feat)) { - march_buf[march_index] = letter.char; - march_index += 1; - } - } - - const march_arg = try std.fmt.allocPrint(arena, "-march={s}", .{ - march_buf[0..march_index], - }); - try argv.append(march_arg); - - if (std.Target.riscv.featureSetHas(target.cpu.features, .relax)) { - try argv.append("-mrelax"); - } else { - try argv.append("-mno-relax"); - } - if (std.Target.riscv.featureSetHas(target.cpu.features, .save_restore)) { - try argv.append("-msave-restore"); - } else { - try argv.append("-mno-save-restore"); - } - }, - .mips, .mipsel, .mips64, .mips64el => { - if (target.cpu.model.llvm_name) |llvm_name| { - try argv.append(try std.fmt.allocPrint(arena, "-march={s}", .{llvm_name})); - } - }, - else => { - // TODO - }, - } - if (target_util.clangAssemblerSupportsMcpuArg(target)) { - if (target.cpu.model.llvm_name) |llvm_name| { - try argv.append(try std.fmt.allocPrint(arena, "-mcpu={s}", .{llvm_name})); - } - } - }, - } - - if (comp.mingw_unicode_entry_point) { - try argv.append("-municode"); - } - - if (target.cpu.arch.isArm()) { - try argv.append(if (target.cpu.arch.isThumb()) "-mthumb" else "-mno-thumb"); - } - - if (target_util.supports_fpic(target)) { - try argv.append(if (mod.pic) "-fPIC" else "-fno-PIC"); - } - - try argv.ensureUnusedCapacity(2); - switch (comp.config.debug_format) { - .strip => {}, - .code_view => { - // -g is required here because -gcodeview doesn't trigger debug info - // generation, it only changes the type of information generated. - argv.appendSliceAssumeCapacity(&.{ "-g", "-gcodeview" }); - }, - .dwarf => |f| { - argv.appendAssumeCapacity("-gdwarf-4"); - switch (f) { - .@"32" => argv.appendAssumeCapacity("-gdwarf32"), - .@"64" => argv.appendAssumeCapacity("-gdwarf64"), - } }, - } - - if (target_util.llvmMachineAbi(target)) |mabi| { - try argv.append(try std.fmt.allocPrint(arena, "-mabi={s}", .{mabi})); - } - - // We might want to support -mfloat-abi=softfp for Arm and CSKY here in the future. - if (target_util.clangSupportsFloatAbiArg(target)) { - const fabi = @tagName(target.floatAbi()); - - try argv.append(switch (target.cpu.arch) { - // For whatever reason, Clang doesn't support `-mfloat-abi` for s390x. - .s390x => try std.fmt.allocPrint(arena, "-m{s}-float", .{fabi}), - else => try std.fmt.allocPrint(arena, "-mfloat-abi={s}", .{fabi}), - }); - } - - if (target_util.clangSupportsNoImplicitFloatArg(target) and target.floatAbi() == .soft) { - try argv.append("-mno-implicit-float"); - } - - // https://github.com/llvm/llvm-project/issues/105972 - if (target.cpu.arch.isPowerPC() and target.floatAbi() == .soft) { - try argv.append("-D__NO_FPRS__"); - try argv.append("-D_SOFT_FLOAT"); - try argv.append("-D_SOFT_DOUBLE"); - } - - if (out_dep_path) |p| { - try argv.appendSlice(&[_][]const u8{ "-MD", "-MV", "-MF", p }); - } - - // We never want clang to invoke the system assembler for anything. So we would want - // this option always enabled. However, it only matters for some targets. To avoid - // "unused parameter" warnings, and to keep CLI spam to a minimum, we only put this - // flag on the command line if it is necessary. - if (target_util.clangMightShellOutForAssembly(target)) { - try argv.append("-integrated-as"); - } - - if (target.os.tag == .freestanding) { - try argv.append("-ffreestanding"); - } - - if (mod.resolved_target.is_native_os and mod.resolved_target.is_native_abi) { - try argv.ensureUnusedCapacity(comp.native_system_include_paths.len * 2); - for (comp.native_system_include_paths) |include_path| { - argv.appendAssumeCapacity("-isystem"); - argv.appendAssumeCapacity(include_path); - } + else => {}, } try argv.appendSlice(comp.global_cc_argv); @@ -5840,6 +5842,36 @@ pub const FileExt = enum { manifest, unknown, + pub fn clangNeedsLanguageOverride(ext: FileExt) bool { + return switch (ext) { + .h, + .hpp, + .hm, + .hmm, + => true, + + .c, + .cpp, + .cu, + .m, + .mm, + .ll, + .bc, + .assembly, + .assembly_with_cpp, + .shared_library, + .object, + .static_library, + .zig, + .def, + .rc, + .res, + .manifest, + .unknown, + => false, + }; + } + pub fn clangSupportsDiagnostics(ext: FileExt) bool { return switch (ext) { .c, .cpp, .h, .hpp, .hm, .hmm, .m, .mm, .cu, .ll, .bc => true, @@ -5861,12 +5893,11 @@ pub const FileExt = enum { pub fn clangSupportsDepFile(ext: FileExt) bool { return switch (ext) { - .c, .cpp, .h, .hpp, .hm, .hmm, .m, .mm, .cu => true, + .assembly_with_cpp, .c, .cpp, .h, .hpp, .hm, .hmm, .m, .mm, .cu => true, .ll, .bc, .assembly, - .assembly_with_cpp, .shared_library, .object, .static_library, @@ -5886,9 +5917,9 @@ pub const FileExt = enum { .cpp => ".cpp", .cu => ".cu", .h => ".h", - .hpp => ".h", - .hm => ".h", - .hmm => ".h", + .hpp => ".hpp", + .hm => ".hm", + .hmm => ".hmm", .m => ".m", .mm => ".mm", .ll => ".ll", @@ -5925,21 +5956,42 @@ pub fn hasCExt(filename: []const u8) bool { return mem.endsWith(u8, filename, ".c"); } +pub fn hasCHExt(filename: []const u8) bool { + return mem.endsWith(u8, filename, ".h"); +} + pub fn hasCppExt(filename: []const u8) bool { return mem.endsWith(u8, filename, ".C") or mem.endsWith(u8, filename, ".cc") or + mem.endsWith(u8, filename, ".cp") or + mem.endsWith(u8, filename, ".CPP") or mem.endsWith(u8, filename, ".cpp") or mem.endsWith(u8, filename, ".cxx") or mem.endsWith(u8, filename, ".c++") or mem.endsWith(u8, filename, ".stub"); } +pub fn hasCppHExt(filename: []const u8) bool { + return mem.endsWith(u8, filename, ".hh") or + mem.endsWith(u8, filename, ".hpp") or + mem.endsWith(u8, filename, ".hxx"); +} + pub fn hasObjCExt(filename: []const u8) bool { return mem.endsWith(u8, filename, ".m"); } +pub fn hasObjCHExt(filename: []const u8) bool { + return mem.endsWith(u8, filename, ".hm"); +} + pub fn hasObjCppExt(filename: []const u8) bool { - return mem.endsWith(u8, filename, ".mm"); + return mem.endsWith(u8, filename, ".M") or + mem.endsWith(u8, filename, ".mm"); +} + +pub fn hasObjCppHExt(filename: []const u8) bool { + return mem.endsWith(u8, filename, ".hmm"); } pub fn hasSharedLibraryExt(filename: []const u8) bool { @@ -5972,12 +6024,20 @@ pub fn hasSharedLibraryExt(filename: []const u8) bool { pub fn classifyFileExt(filename: []const u8) FileExt { if (hasCExt(filename)) { return .c; + } else if (hasCHExt(filename)) { + return .h; } else if (hasCppExt(filename)) { return .cpp; + } else if (hasCppHExt(filename)) { + return .hpp; } else if (hasObjCExt(filename)) { return .m; + } else if (hasObjCHExt(filename)) { + return .hm; } else if (hasObjCppExt(filename)) { return .mm; + } else if (hasObjCppHExt(filename)) { + return .hmm; } else if (mem.endsWith(u8, filename, ".ll")) { return .ll; } else if (mem.endsWith(u8, filename, ".bc")) { @@ -5986,8 +6046,6 @@ pub fn classifyFileExt(filename: []const u8) FileExt { return .assembly; } else if (mem.endsWith(u8, filename, ".S")) { return .assembly_with_cpp; - } else if (mem.endsWith(u8, filename, ".h")) { - return .h; } else if (mem.endsWith(u8, filename, ".zig")) { return .zig; } else if (hasSharedLibraryExt(filename)) { |
