authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-21 13:34:55-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-21 13:34:55-05:00
log71573584cdfb1ddb176681fcb7d1544cac7a72ca
treea705cb0f0e25fceb5263e10fc027011e0ee26f76
parent7da7fbb9122e6e2a5f936ce9c1eaf8b5776fa8ac
signaturelock-open Commit is signed but in an unrecognized format.

std.Target.parse gives parsing diagnostics


2 files changed, 68 insertions(+), 7 deletions(-)

lib/std/target.zig+36-4
...@@ -727,18 +727,47 @@ pub const Target = union(enum) {...@@ -727,18 +727,47 @@ pub const Target = union(enum) {
727 /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features727 /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features
728 /// to remove from the set.728 /// to remove from the set.
729 cpu_features: []const u8 = "baseline",729 cpu_features: []const u8 = "baseline",
730
731 /// If this is provided, the function will populate some information about parsing failures,
732 /// so that user-friendly error messages can be delivered.
733 diagnostics: ?*Diagnostics = null,
734
735 pub const Diagnostics = struct {
736 /// If the architecture was determined, this will be populated.
737 arch: ?Cpu.Arch = null,
738
739 /// If the OS was determined, this will be populated.
740 os: ?Os = null,
741
742 /// If the ABI was determined, this will be populated.
743 abi: ?Abi = null,
744
745 /// If the CPU name was determined, this will be populated.
746 cpu_name: ?[]const u8 = null,
747
748 /// If error.UnknownCpuFeature is returned, this will be populated.
749 unknown_feature_name: ?[]const u8 = null,
750 };
730 };751 };
731752
732 pub fn parse(args: ParseOptions) !Target {753 pub fn parse(args: ParseOptions) !Target {
754 var dummy_diags: ParseOptions.Diagnostics = undefined;
755 var diags = args.diagnostics orelse &dummy_diags;
756
733 var it = mem.separate(args.arch_os_abi, "-");757 var it = mem.separate(args.arch_os_abi, "-");
734 const arch_name = it.next() orelse return error.MissingArchitecture;758 const arch_name = it.next() orelse return error.MissingArchitecture;
735 const os_name = it.next() orelse return error.MissingOperatingSystem;
736 const abi_name = it.next();
737 if (it.next() != null) return error.UnexpectedExtraField;
738
739 const arch = try Cpu.Arch.parse(arch_name);759 const arch = try Cpu.Arch.parse(arch_name);
760 diags.arch = arch;
761
762 const os_name = it.next() orelse return error.MissingOperatingSystem;
740 const os = try Os.parse(os_name);763 const os = try Os.parse(os_name);
764 diags.os = os;
765
766 const abi_name = it.next();
741 const abi = if (abi_name) |n| try Abi.parse(n) else Abi.default(arch, os);767 const abi = if (abi_name) |n| try Abi.parse(n) else Abi.default(arch, os);
768 diags.abi = abi;
769
770 if (it.next() != null) return error.UnexpectedExtraField;
742771
743 const all_features = arch.allFeaturesList();772 const all_features = arch.allFeaturesList();
744 var index: usize = 0;773 var index: usize = 0;
...@@ -749,6 +778,8 @@ pub const Target = union(enum) {...@@ -749,6 +778,8 @@ pub const Target = union(enum) {
749 index += 1;778 index += 1;
750 }779 }
751 const cpu_name = args.cpu_features[0..index];780 const cpu_name = args.cpu_features[0..index];
781 diags.cpu_name = cpu_name;
782
752 const cpu: Cpu = if (mem.eql(u8, cpu_name, "baseline")) Cpu.baseline(arch) else blk: {783 const cpu: Cpu = if (mem.eql(u8, cpu_name, "baseline")) Cpu.baseline(arch) else blk: {
753 const cpu_model = try arch.parseCpuModel(cpu_name);784 const cpu_model = try arch.parseCpuModel(cpu_name);
754785
...@@ -775,6 +806,7 @@ pub const Target = union(enum) {...@@ -775,6 +806,7 @@ pub const Target = union(enum) {
775 break;806 break;
776 }807 }
777 } else {808 } else {
809 diags.unknown_feature_name = feature_name;
778 return error.UnknownCpuFeature;810 return error.UnknownCpuFeature;
779 }811 }
780 }812 }
src-self-hosted/stage2.zig+32-3
...@@ -661,9 +661,7 @@ export fn stage2_target_parse(...@@ -661,9 +661,7 @@ export fn stage2_target_parse(
661 error.MissingOperatingSystem => return .MissingOperatingSystem,661 error.MissingOperatingSystem => return .MissingOperatingSystem,
662 error.MissingArchitecture => return .MissingArchitecture,662 error.MissingArchitecture => return .MissingArchitecture,
663 error.InvalidLlvmCpuFeaturesFormat => return .InvalidLlvmCpuFeaturesFormat,663 error.InvalidLlvmCpuFeaturesFormat => return .InvalidLlvmCpuFeaturesFormat,
664 error.UnknownCpu => return .UnknownCpu,
665 error.UnexpectedExtraField => return .SemanticAnalyzeFail,664 error.UnexpectedExtraField => return .SemanticAnalyzeFail,
666 error.UnknownCpuFeature => return .UnknownCpuFeature,
667 };665 };
668 return .None;666 return .None;
669}667}
...@@ -676,7 +674,38 @@ fn stage2TargetParse(...@@ -676,7 +674,38 @@ fn stage2TargetParse(
676 const target: Target = if (zig_triple_oz) |zig_triple_z| blk: {674 const target: Target = if (zig_triple_oz) |zig_triple_z| blk: {
677 const zig_triple = mem.toSliceConst(u8, zig_triple_z);675 const zig_triple = mem.toSliceConst(u8, zig_triple_z);
678 const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else "baseline";676 const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else "baseline";
679 break :blk try Target.parse(.{ .arch_os_abi = zig_triple, .cpu_features = mcpu });677 var diags: std.Target.ParseOptions.Diagnostics = .{};
678 break :blk Target.parse(.{
679 .arch_os_abi = zig_triple,
680 .cpu_features = mcpu,
681 .diagnostics = &diags,
682 }) catch |err| switch (err) {
683 error.UnknownCpu => {
684 std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{
685 diags.cpu_name.?,
686 @tagName(diags.arch.?),
687 });
688 for (diags.arch.?.allCpuModels()) |cpu| {
689 std.debug.warn(" {}\n", .{cpu.name});
690 }
691 process.exit(1);
692 },
693 error.UnknownCpuFeature => {
694 std.debug.warn(
695 \\Unknown CPU feature: '{}'
696 \\Available CPU features for architecture '{}':
697 \\
698 , .{
699 diags.unknown_feature_name,
700 @tagName(diags.arch.?),
701 });
702 for (diags.arch.?.allFeaturesList()) |feature| {
703 std.debug.warn(" {}: {}\n", .{ feature.name, feature.description });
704 }
705 process.exit(1);
706 },
707 else => |e| return e,
708 };
680 } else Target.Native;709 } else Target.Native;
681710
682 try stage1_target.fromTarget(target);711 try stage1_target.fromTarget(target);