summaryrefslogtreecommitdiffstats
path: root/third_party/rust/target-lexicon-0.9.0
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/target-lexicon-0.9.0
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/target-lexicon-0.9.0')
-rw-r--r--third_party/rust/target-lexicon-0.9.0/.cargo-checksum.json1
-rw-r--r--third_party/rust/target-lexicon-0.9.0/Cargo.lock6
-rw-r--r--third_party/rust/target-lexicon-0.9.0/Cargo.toml33
-rw-r--r--third_party/rust/target-lexicon-0.9.0/LICENSE220
-rw-r--r--third_party/rust/target-lexicon-0.9.0/README.md20
-rw-r--r--third_party/rust/target-lexicon-0.9.0/build.rs162
-rw-r--r--third_party/rust/target-lexicon-0.9.0/examples/host.rs12
-rw-r--r--third_party/rust/target-lexicon-0.9.0/examples/misc.rs14
-rwxr-xr-xthird_party/rust/target-lexicon-0.9.0/newlist7
-rw-r--r--third_party/rust/target-lexicon-0.9.0/src/host.rs56
-rw-r--r--third_party/rust/target-lexicon-0.9.0/src/lib.rs34
-rw-r--r--third_party/rust/target-lexicon-0.9.0/src/parse_error.rs34
-rw-r--r--third_party/rust/target-lexicon-0.9.0/src/targets.rs1123
-rw-r--r--third_party/rust/target-lexicon-0.9.0/src/triple.rs369
-rwxr-xr-xthird_party/rust/target-lexicon-0.9.0/test.sh11
15 files changed, 2102 insertions, 0 deletions
diff --git a/third_party/rust/target-lexicon-0.9.0/.cargo-checksum.json b/third_party/rust/target-lexicon-0.9.0/.cargo-checksum.json
new file mode 100644
index 0000000000..5551ea9293
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.lock":"a1a162e6ce8fc2234a6ddf7090410006a1920ace8738772e32a5b50e4780c19d","Cargo.toml":"f3b545fa0f184fd0d3624e6e5c205fcbdf1ad0934a2e08406549ad53c2a62ac3","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"c3467056d91be3f59562158ee9604c729b5b5f473efbefb036032803eb76809e","build.rs":"723100e9cdc30cd8c48407233c2cffa10f5b10703a0a11bac1230d8b86e49ccf","examples/host.rs":"503bafddfb372123fe4dc0e7b8037808beb5bfe6df60c00d3315922bd3792c6c","examples/misc.rs":"49a579845450b7b020ed5c97dca142fc548725893cbc82f6f750ee0caab2beca","newlist":"89564342916321c5bc35e772d374a7f0af22cc9ae6dcc0027eca48d2269f18cb","src/host.rs":"fb543df4f362e9119a58523563e453110f4e3a426f0995911d0ca386657cf1d9","src/lib.rs":"4414353c30f25d44df6cc14f7f9eea9991222289c6aa662b74406f6923235970","src/parse_error.rs":"b3735eabc0fd0a9dfdd6375662f20ec96a79852a00a05a98fb2e421545285e53","src/targets.rs":"9ccc0849cff06d8906dacbdc15136cc47fab85ccd795033ddfdde1397dfcfe32","src/triple.rs":"949bd83b043b53b18f643ebc3fbebbfe02a13998b787fda432a5d36aa27d20bd","test.sh":"22e3c630a6c84e90d5c70c367a6712be8eeca1e7682c00d1f65bf53e330e9191"},"package":"6f4c118a7a38378f305a9e111fcb2f7f838c0be324bfb31a77ea04f7f6e684b4"} \ No newline at end of file
diff --git a/third_party/rust/target-lexicon-0.9.0/Cargo.lock b/third_party/rust/target-lexicon-0.9.0/Cargo.lock
new file mode 100644
index 0000000000..a882b1f2ce
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "target-lexicon"
+version = "0.9.0"
+
diff --git a/third_party/rust/target-lexicon-0.9.0/Cargo.toml b/third_party/rust/target-lexicon-0.9.0/Cargo.toml
new file mode 100644
index 0000000000..a00824bfb1
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/Cargo.toml
@@ -0,0 +1,33 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "target-lexicon"
+version = "0.9.0"
+authors = ["Dan Gohman <sunfish@mozilla.com>"]
+description = "Targeting utilities for compilers and related tools"
+documentation = "https://docs.rs/target-lexicon/"
+readme = "README.md"
+keywords = ["target", "host", "triple", "compiler", "jit"]
+categories = ["no-std"]
+license = "Apache-2.0 WITH LLVM-exception"
+repository = "https://github.com/CraneStation/target-lexicon"
+
+[features]
+default = []
+std = []
+[badges.maintenance]
+status = "passively-maintained"
+
+[badges.travis-ci]
+repository = "CraneStation/target-lexicon"
diff --git a/third_party/rust/target-lexicon-0.9.0/LICENSE b/third_party/rust/target-lexicon-0.9.0/LICENSE
new file mode 100644
index 0000000000..f9d81955f4
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/LICENSE
@@ -0,0 +1,220 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+--- LLVM Exceptions to the Apache 2.0 License ----
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into an Object form of such source code, you
+may redistribute such embedded portions in such Object form without complying
+with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
+
+In addition, if you combine or link compiled forms of this Software with
+software that is licensed under the GPLv2 ("Combined Software") and if a
+court of competent jurisdiction determines that the patent provision (Section
+3), the indemnity provision (Section 9) or other Section of the License
+conflicts with the conditions of the GPLv2, you may retroactively and
+prospectively choose to deem waived or otherwise exclude such Section(s) of
+the License, but only in their entirety and only with respect to the Combined
+Software.
+
diff --git a/third_party/rust/target-lexicon-0.9.0/README.md b/third_party/rust/target-lexicon-0.9.0/README.md
new file mode 100644
index 0000000000..2e539eb716
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/README.md
@@ -0,0 +1,20 @@
+This is a library for managing targets for compilers and related tools.
+
+Currently, the main feature is support for decoding "triples", which
+are strings that identify a particular target configuration. They're named
+"triples" because historically they contained three fields, though over time
+they've added additional fields. This library provides a `Triple` struct
+containing enums for each of fields of a triple. `Triple` implements
+`FromStr` and `fmt::Display` so it can be converted to and from the
+conventional string representation of a triple.
+
+`Triple` also has functions for querying a triple's endianness,
+pointer bit width, and binary format.
+
+And, `Triple` and the enum types have `host()` constructors, for targeting
+the host.
+
+It supports all triples currently used by rustc and rustup.
+
+It does not support reading JSON target files itself. To use it with a JSON
+target file, construct a `Triple` using the value of the "llvm-target" field.
diff --git a/third_party/rust/target-lexicon-0.9.0/build.rs b/third_party/rust/target-lexicon-0.9.0/build.rs
new file mode 100644
index 0000000000..a0ba3b7304
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/build.rs
@@ -0,0 +1,162 @@
+//! build.rs file to obtain the host information.
+
+// Allow dead code in triple.rs and targets.rs for our purposes here.
+#![allow(dead_code)]
+
+use std::env;
+use std::fs::File;
+use std::io::{self, Write};
+use std::path::PathBuf;
+use std::str::FromStr;
+
+extern crate alloc;
+
+// Include triple.rs and targets.rs so we can parse the TARGET environment variable.
+mod triple {
+ include!("src/triple.rs");
+}
+mod targets {
+ include!("src/targets.rs");
+}
+
+// Stub out `ParseError` to minimally support triple.rs and targets.rs.
+mod parse_error {
+ #[derive(Debug)]
+ pub enum ParseError {
+ UnrecognizedArchitecture(String),
+ UnrecognizedVendor(String),
+ UnrecognizedOperatingSystem(String),
+ UnrecognizedEnvironment(String),
+ UnrecognizedBinaryFormat(String),
+ UnrecognizedField(String),
+ }
+}
+
+use self::triple::Triple;
+
+fn main() {
+ let out_dir =
+ PathBuf::from(env::var("OUT_DIR").expect("The OUT_DIR environment variable must be set"));
+ let target = env::var("TARGET").expect("The TARGET environment variable must be set");
+ let triple = Triple::from_str(&target).expect(&format!("Invalid target name: '{}'", target));
+ let out = File::create(out_dir.join("host.rs")).expect("error creating host.rs");
+ write_host_rs(out, triple).expect("error writing host.rs");
+}
+
+fn write_host_rs(mut out: File, triple: Triple) -> io::Result<()> {
+ // The generated Debug implementation for the inner architecture variants
+ // doesn't print the enum name qualifier, so import them here. There
+ // shouldn't be any conflicts because these enums all share a namespace
+ // in the triple string format.
+ writeln!(out, "#[allow(unused_imports)]")?;
+ writeln!(out, "use crate::Aarch64Architecture::*;")?;
+ writeln!(out, "#[allow(unused_imports)]")?;
+ writeln!(out, "use crate::ArmArchitecture::*;")?;
+ writeln!(out)?;
+ writeln!(out, "/// The `Triple` of the current host.")?;
+ writeln!(out, "pub const HOST: Triple = Triple {{")?;
+ writeln!(
+ out,
+ " architecture: Architecture::{:?},",
+ triple.architecture
+ )?;
+ writeln!(out, " vendor: Vendor::{:?},", triple.vendor)?;
+ writeln!(
+ out,
+ " operating_system: OperatingSystem::{:?},",
+ triple.operating_system
+ )?;
+ writeln!(
+ out,
+ " environment: Environment::{:?},",
+ triple.environment
+ )?;
+ writeln!(
+ out,
+ " binary_format: BinaryFormat::{:?},",
+ triple.binary_format
+ )?;
+ writeln!(out, "}};")?;
+ writeln!(out)?;
+
+ writeln!(out, "impl Architecture {{")?;
+ writeln!(out, " /// Return the architecture for the current host.")?;
+ writeln!(out, " pub const fn host() -> Self {{")?;
+ writeln!(out, " Architecture::{:?}", triple.architecture)?;
+ writeln!(out, " }}")?;
+ writeln!(out, "}}")?;
+ writeln!(out)?;
+
+ writeln!(out, "impl Vendor {{")?;
+ writeln!(out, " /// Return the vendor for the current host.")?;
+ writeln!(out, " pub const fn host() -> Self {{")?;
+ writeln!(out, " Vendor::{:?}", triple.vendor)?;
+ writeln!(out, " }}")?;
+ writeln!(out, "}}")?;
+ writeln!(out)?;
+
+ writeln!(out, "impl OperatingSystem {{")?;
+ writeln!(
+ out,
+ " /// Return the operating system for the current host."
+ )?;
+ writeln!(out, " pub const fn host() -> Self {{")?;
+ writeln!(
+ out,
+ " OperatingSystem::{:?}",
+ triple.operating_system
+ )?;
+ writeln!(out, " }}")?;
+ writeln!(out, "}}")?;
+ writeln!(out)?;
+
+ writeln!(out, "impl Environment {{")?;
+ writeln!(out, " /// Return the environment for the current host.")?;
+ writeln!(out, " pub const fn host() -> Self {{")?;
+ writeln!(out, " Environment::{:?}", triple.environment)?;
+ writeln!(out, " }}")?;
+ writeln!(out, "}}")?;
+ writeln!(out)?;
+
+ writeln!(out, "impl BinaryFormat {{")?;
+ writeln!(
+ out,
+ " /// Return the binary format for the current host."
+ )?;
+ writeln!(out, " pub const fn host() -> Self {{")?;
+ writeln!(out, " BinaryFormat::{:?}", triple.binary_format)?;
+ writeln!(out, " }}")?;
+ writeln!(out, "}}")?;
+ writeln!(out)?;
+
+ writeln!(out, "impl Triple {{")?;
+ writeln!(out, " /// Return the triple for the current host.")?;
+ writeln!(out, " pub const fn host() -> Self {{")?;
+ writeln!(out, " Self {{")?;
+ writeln!(
+ out,
+ " architecture: Architecture::{:?},",
+ triple.architecture
+ )?;
+ writeln!(out, " vendor: Vendor::{:?},", triple.vendor)?;
+ writeln!(
+ out,
+ " operating_system: OperatingSystem::{:?},",
+ triple.operating_system
+ )?;
+ writeln!(
+ out,
+ " environment: Environment::{:?},",
+ triple.environment
+ )?;
+ writeln!(
+ out,
+ " binary_format: BinaryFormat::{:?},",
+ triple.binary_format
+ )?;
+ writeln!(out, " }}")?;
+ writeln!(out, " }}")?;
+ writeln!(out, "}}")?;
+
+ Ok(())
+}
diff --git a/third_party/rust/target-lexicon-0.9.0/examples/host.rs b/third_party/rust/target-lexicon-0.9.0/examples/host.rs
new file mode 100644
index 0000000000..055e0bffdb
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/examples/host.rs
@@ -0,0 +1,12 @@
+extern crate target_lexicon;
+
+use target_lexicon::HOST;
+
+fn main() {
+ println!(
+ "{}",
+ HOST.pointer_width()
+ .expect("architecture should be known")
+ .bytes()
+ );
+}
diff --git a/third_party/rust/target-lexicon-0.9.0/examples/misc.rs b/third_party/rust/target-lexicon-0.9.0/examples/misc.rs
new file mode 100644
index 0000000000..25c99e8677
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/examples/misc.rs
@@ -0,0 +1,14 @@
+extern crate target_lexicon;
+
+use core::str::FromStr;
+use target_lexicon::{Triple, HOST};
+
+fn main() {
+ println!("The host triple is {}.", HOST);
+
+ let e = Triple::from_str("riscv32-unknown-unknown")
+ .expect("expected to recognize the RISC-V target")
+ .endianness()
+ .expect("expected to know the endianness of RISC-V");
+ println!("The endianness of RISC-V is {:?}.", e);
+}
diff --git a/third_party/rust/target-lexicon-0.9.0/newlist b/third_party/rust/target-lexicon-0.9.0/newlist
new file mode 100755
index 0000000000..922950d0a0
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/newlist
@@ -0,0 +1,7 @@
+#!/bin/bash
+set -euo pipefail
+
+rustup target list | sed 's/ (.*//' > list.txt
+rustc +nightly --print target-list >> list.txt
+cat list.txt | sort | uniq |sed 's/\(.*\)/ "\1",/' > sorted.txt
+rm list.txt
diff --git a/third_party/rust/target-lexicon-0.9.0/src/host.rs b/third_party/rust/target-lexicon-0.9.0/src/host.rs
new file mode 100644
index 0000000000..4c6ad5ba54
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/src/host.rs
@@ -0,0 +1,56 @@
+use crate::{Architecture, BinaryFormat, Environment, OperatingSystem, Triple, Vendor};
+
+// Include the implementations of the `HOST` object containing information
+// about the current host.
+include!(concat!(env!("OUT_DIR"), "/host.rs"));
+
+#[cfg(test)]
+mod tests {
+ #[cfg(target_os = "linux")]
+ #[test]
+ fn test_linux() {
+ use super::*;
+ assert_eq!(OperatingSystem::host(), OperatingSystem::Linux);
+ }
+
+ #[cfg(target_os = "macos")]
+ #[test]
+ fn test_macos() {
+ use super::*;
+ assert_eq!(OperatingSystem::host(), OperatingSystem::Darwin);
+ }
+
+ #[cfg(windows)]
+ #[test]
+ fn test_windows() {
+ use super::*;
+ assert_eq!(OperatingSystem::host(), OperatingSystem::Windows);
+ }
+
+ #[cfg(target_pointer_width = "16")]
+ #[test]
+ fn test_ptr16() {
+ use super::*;
+ assert_eq!(Architecture::host().pointer_width().unwrap().bits(), 16);
+ }
+
+ #[cfg(target_pointer_width = "32")]
+ #[test]
+ fn test_ptr32() {
+ use super::*;
+ assert_eq!(Architecture::host().pointer_width().unwrap().bits(), 32);
+ }
+
+ #[cfg(target_pointer_width = "64")]
+ #[test]
+ fn test_ptr64() {
+ use super::*;
+ assert_eq!(Architecture::host().pointer_width().unwrap().bits(), 64);
+ }
+
+ #[test]
+ fn host_object() {
+ use super::*;
+ assert_eq!(HOST, Triple::host());
+ }
+}
diff --git a/third_party/rust/target-lexicon-0.9.0/src/lib.rs b/third_party/rust/target-lexicon-0.9.0/src/lib.rs
new file mode 100644
index 0000000000..8d6da8dcfc
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/src/lib.rs
@@ -0,0 +1,34 @@
+//! Target triple support.
+
+#![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
+#![warn(unused_import_braces)]
+#![cfg_attr(
+ feature = "cargo-clippy",
+ warn(
+ clippy::float_arithmetic,
+ clippy::mut_mut,
+ clippy::nonminimal_bool,
+ clippy::option_map_unwrap_or,
+ clippy::option_map_unwrap_or_else,
+ clippy::print_stdout,
+ clippy::unicode_not_nfc,
+ clippy::use_self
+ )
+)]
+#![cfg_attr(not(feature = "std"), no_std)]
+
+extern crate alloc;
+
+mod host;
+mod parse_error;
+mod targets;
+#[macro_use]
+mod triple;
+
+pub use self::host::HOST;
+pub use self::parse_error::ParseError;
+pub use self::targets::{
+ Aarch64Architecture, Architecture, ArmArchitecture, BinaryFormat, Environment, OperatingSystem,
+ Vendor,
+};
+pub use self::triple::{CallingConvention, Endianness, PointerWidth, Triple};
diff --git a/third_party/rust/target-lexicon-0.9.0/src/parse_error.rs b/third_party/rust/target-lexicon-0.9.0/src/parse_error.rs
new file mode 100644
index 0000000000..03ca4aedb9
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/src/parse_error.rs
@@ -0,0 +1,34 @@
+use alloc::string::String;
+
+use core::fmt;
+
+/// An error returned from parsing a triple.
+#[derive(Clone, Debug, PartialEq, Eq)]
+#[allow(missing_docs)]
+pub enum ParseError {
+ UnrecognizedArchitecture(String),
+ UnrecognizedVendor(String),
+ UnrecognizedOperatingSystem(String),
+ UnrecognizedEnvironment(String),
+ UnrecognizedBinaryFormat(String),
+ UnrecognizedField(String),
+}
+
+impl fmt::Display for ParseError {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ use ParseError::*;
+ match self {
+ UnrecognizedArchitecture(msg) => write!(fmt, "Unrecognized architecture: {}", msg),
+ UnrecognizedVendor(msg) => write!(fmt, "Unrecognized vendor: {}", msg),
+ UnrecognizedOperatingSystem(msg) => {
+ write!(fmt, "Unrecognized operating system: {}", msg)
+ }
+ UnrecognizedEnvironment(msg) => write!(fmt, "Unrecognized environment: {}", msg),
+ UnrecognizedBinaryFormat(msg) => write!(fmt, "Unrecognized binary format: {}", msg),
+ UnrecognizedField(msg) => write!(fmt, "Unrecognized field: {}", msg),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for ParseError {}
diff --git a/third_party/rust/target-lexicon-0.9.0/src/targets.rs b/third_party/rust/target-lexicon-0.9.0/src/targets.rs
new file mode 100644
index 0000000000..6ae570ebe8
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/src/targets.rs
@@ -0,0 +1,1123 @@
+// This file defines all the identifier enums and target-aware logic.
+
+use crate::triple::{Endianness, PointerWidth, Triple};
+use core::fmt;
+use core::str::FromStr;
+
+/// The "architecture" field, which in some cases also specifies a specific
+/// subarchitecture.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum Architecture {
+ Unknown,
+ Arm(ArmArchitecture),
+ AmdGcn,
+ Aarch64(Aarch64Architecture),
+ Asmjs,
+ Hexagon,
+ I386,
+ I586,
+ I686,
+ Mips,
+ Mips64,
+ Mips64el,
+ Mipsel,
+ Mipsisa32r6,
+ Mipsisa32r6el,
+ Mipsisa64r6,
+ Mipsisa64r6el,
+ Msp430,
+ Nvptx64,
+ Powerpc,
+ Powerpc64,
+ Powerpc64le,
+ Riscv32,
+ Riscv32i,
+ Riscv32imac,
+ Riscv32imc,
+ Riscv64,
+ Riscv64gc,
+ Riscv64imac,
+ S390x,
+ Sparc,
+ Sparc64,
+ Sparcv9,
+ Wasm32,
+ X86_64,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum ArmArchitecture {
+ Arm, // Generic arm
+ Armeb,
+ Armv4,
+ Armv4t,
+ Armv5t,
+ Armv5te,
+ Armv5tej,
+ Armv6,
+ Armv6j,
+ Armv6k,
+ Armv6z,
+ Armv6kz,
+ Armv6t2,
+ Armv6m,
+ Armv7,
+ Armv7a,
+ Armv7ve,
+ Armv7m,
+ Armv7r,
+ Armv7s,
+ Armv8,
+ Armv8a,
+ Armv8_1a,
+ Armv8_2a,
+ Armv8_3a,
+ Armv8_4a,
+ Armv8_5a,
+ Armv8mBase,
+ Armv8mMain,
+ Armv8r,
+
+ Armebv7r,
+
+ Thumbeb,
+ Thumbv6m,
+ Thumbv7a,
+ Thumbv7em,
+ Thumbv7m,
+ Thumbv7neon,
+ Thumbv8mBase,
+ Thumbv8mMain,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum Aarch64Architecture {
+ Aarch64,
+ Aarch64be,
+}
+
+// #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+// #[allow(missing_docs)]
+// pub enum ArmFpu {
+// Vfp,
+// Vfpv2,
+// Vfpv3,
+// Vfpv3Fp16,
+// Vfpv3Xd,
+// Vfpv3XdFp16,
+// Neon,
+// NeonVfpv3,
+// NeonVfpv4,
+// Vfpv4,
+// Vfpv4D16,
+// Fpv4SpD16,
+// Fpv5SpD16,
+// Fpv5D16,
+// FpArmv8,
+// NeonFpArmv8,
+// CryptoNeonFpArmv8,
+// }
+
+impl ArmArchitecture {
+ /// Test if this architecture uses the Thumb instruction set.
+ pub fn is_thumb(self) -> bool {
+ match self {
+ ArmArchitecture::Arm
+ | ArmArchitecture::Armeb
+ | ArmArchitecture::Armv4
+ | ArmArchitecture::Armv4t
+ | ArmArchitecture::Armv5t
+ | ArmArchitecture::Armv5te
+ | ArmArchitecture::Armv5tej
+ | ArmArchitecture::Armv6
+ | ArmArchitecture::Armv6j
+ | ArmArchitecture::Armv6k
+ | ArmArchitecture::Armv6z
+ | ArmArchitecture::Armv6kz
+ | ArmArchitecture::Armv6t2
+ | ArmArchitecture::Armv6m
+ | ArmArchitecture::Armv7
+ | ArmArchitecture::Armv7a
+ | ArmArchitecture::Armv7ve
+ | ArmArchitecture::Armv7m
+ | ArmArchitecture::Armv7r
+ | ArmArchitecture::Armv7s
+ | ArmArchitecture::Armv8
+ | ArmArchitecture::Armv8a
+ | ArmArchitecture::Armv8_1a
+ | ArmArchitecture::Armv8_2a
+ | ArmArchitecture::Armv8_3a
+ | ArmArchitecture::Armv8_4a
+ | ArmArchitecture::Armv8_5a
+ | ArmArchitecture::Armv8mBase
+ | ArmArchitecture::Armv8mMain
+ | ArmArchitecture::Armv8r
+ | ArmArchitecture::Armebv7r => false,
+ ArmArchitecture::Thumbeb
+ | ArmArchitecture::Thumbv6m
+ | ArmArchitecture::Thumbv7a
+ | ArmArchitecture::Thumbv7em
+ | ArmArchitecture::Thumbv7m
+ | ArmArchitecture::Thumbv7neon
+ | ArmArchitecture::Thumbv8mBase
+ | ArmArchitecture::Thumbv8mMain => true,
+ }
+ }
+
+ // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> {
+
+ // }
+
+ /// Return the pointer bit width of this target's architecture.
+ pub fn pointer_width(self) -> PointerWidth {
+ match self {
+ ArmArchitecture::Arm
+ | ArmArchitecture::Armeb
+ | ArmArchitecture::Armv4
+ | ArmArchitecture::Armv4t
+ | ArmArchitecture::Armv5t
+ | ArmArchitecture::Armv5te
+ | ArmArchitecture::Armv5tej
+ | ArmArchitecture::Armv6
+ | ArmArchitecture::Armv6j
+ | ArmArchitecture::Armv6k
+ | ArmArchitecture::Armv6z
+ | ArmArchitecture::Armv6kz
+ | ArmArchitecture::Armv6t2
+ | ArmArchitecture::Armv6m
+ | ArmArchitecture::Armv7
+ | ArmArchitecture::Armv7a
+ | ArmArchitecture::Armv7ve
+ | ArmArchitecture::Armv7m
+ | ArmArchitecture::Armv7r
+ | ArmArchitecture::Armv7s
+ | ArmArchitecture::Armv8
+ | ArmArchitecture::Armv8a
+ | ArmArchitecture::Armv8_1a
+ | ArmArchitecture::Armv8_2a
+ | ArmArchitecture::Armv8_3a
+ | ArmArchitecture::Armv8_4a
+ | ArmArchitecture::Armv8_5a
+ | ArmArchitecture::Armv8mBase
+ | ArmArchitecture::Armv8mMain
+ | ArmArchitecture::Armv8r
+ | ArmArchitecture::Armebv7r
+ | ArmArchitecture::Thumbeb
+ | ArmArchitecture::Thumbv6m
+ | ArmArchitecture::Thumbv7a
+ | ArmArchitecture::Thumbv7em
+ | ArmArchitecture::Thumbv7m
+ | ArmArchitecture::Thumbv7neon
+ | ArmArchitecture::Thumbv8mBase
+ | ArmArchitecture::Thumbv8mMain => PointerWidth::U32,
+ }
+ }
+
+ /// Return the endianness of this architecture.
+ pub fn endianness(self) -> Endianness {
+ match self {
+ ArmArchitecture::Arm
+ | ArmArchitecture::Armv4
+ | ArmArchitecture::Armv4t
+ | ArmArchitecture::Armv5t
+ | ArmArchitecture::Armv5te
+ | ArmArchitecture::Armv5tej
+ | ArmArchitecture::Armv6
+ | ArmArchitecture::Armv6j
+ | ArmArchitecture::Armv6k
+ | ArmArchitecture::Armv6z
+ | ArmArchitecture::Armv6kz
+ | ArmArchitecture::Armv6t2
+ | ArmArchitecture::Armv6m
+ | ArmArchitecture::Armv7
+ | ArmArchitecture::Armv7a
+ | ArmArchitecture::Armv7ve
+ | ArmArchitecture::Armv7m
+ | ArmArchitecture::Armv7r
+ | ArmArchitecture::Armv7s
+ | ArmArchitecture::Armv8
+ | ArmArchitecture::Armv8a
+ | ArmArchitecture::Armv8_1a
+ | ArmArchitecture::Armv8_2a
+ | ArmArchitecture::Armv8_3a
+ | ArmArchitecture::Armv8_4a
+ | ArmArchitecture::Armv8_5a
+ | ArmArchitecture::Armv8mBase
+ | ArmArchitecture::Armv8mMain
+ | ArmArchitecture::Armv8r
+ | ArmArchitecture::Thumbv6m
+ | ArmArchitecture::Thumbv7a
+ | ArmArchitecture::Thumbv7em
+ | ArmArchitecture::Thumbv7m
+ | ArmArchitecture::Thumbv7neon
+ | ArmArchitecture::Thumbv8mBase
+ | ArmArchitecture::Thumbv8mMain => Endianness::Little,
+ ArmArchitecture::Armeb | ArmArchitecture::Armebv7r | ArmArchitecture::Thumbeb => {
+ Endianness::Big
+ }
+ }
+ }
+}
+
+impl Aarch64Architecture {
+ /// Test if this architecture uses the Thumb instruction set.
+ pub fn is_thumb(self) -> bool {
+ match self {
+ Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => false,
+ }
+ }
+
+ // pub fn has_fpu(self) -> Result<&'static [ArmFpu], ()> {
+
+ // }
+
+ /// Return the pointer bit width of this target's architecture.
+ pub fn pointer_width(self) -> PointerWidth {
+ match self {
+ Aarch64Architecture::Aarch64 | Aarch64Architecture::Aarch64be => PointerWidth::U64,
+ }
+ }
+
+ /// Return the endianness of this architecture.
+ pub fn endianness(self) -> Endianness {
+ match self {
+ Aarch64Architecture::Aarch64 => Endianness::Little,
+ Aarch64Architecture::Aarch64be => Endianness::Big,
+ }
+ }
+}
+
+/// The "vendor" field, which in practice is little more than an arbitrary
+/// modifier.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum Vendor {
+ Unknown,
+ Amd,
+ Apple,
+ Experimental,
+ Fortanix,
+ Nvidia,
+ Pc,
+ Rumprun,
+ Sun,
+ Uwp,
+ Wrs,
+}
+
+/// The "operating system" field, which sometimes implies an environment, and
+/// sometimes isn't an actual operating system.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum OperatingSystem {
+ Unknown,
+ AmdHsa,
+ Bitrig,
+ Cloudabi,
+ Cuda,
+ Darwin,
+ Dragonfly,
+ Emscripten,
+ Freebsd,
+ Fuchsia,
+ Haiku,
+ Hermit,
+ Ios,
+ L4re,
+ Linux,
+ MacOSX { major: u16, minor: u16, patch: u16 },
+ Nebulet,
+ Netbsd,
+ None_,
+ Openbsd,
+ Redox,
+ Solaris,
+ Uefi,
+ VxWorks,
+ Wasi,
+ Windows,
+}
+
+/// The "environment" field, which specifies an ABI environment on top of the
+/// operating system. In many configurations, this field is omitted, and the
+/// environment is implied by the operating system.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum Environment {
+ Unknown,
+ AmdGiz,
+ Android,
+ Androideabi,
+ Eabi,
+ Eabihf,
+ Gnu,
+ Gnuabi64,
+ Gnueabi,
+ Gnueabihf,
+ Gnuspe,
+ Gnux32,
+ Musl,
+ Musleabi,
+ Musleabihf,
+ Muslabi64,
+ Msvc,
+ Kernel,
+ Uclibc,
+ Sgx,
+ Softfloat,
+ Spe,
+}
+
+/// The "binary format" field, which is usually omitted, and the binary format
+/// is implied by the other fields.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum BinaryFormat {
+ Unknown,
+ Elf,
+ Coff,
+ Macho,
+ Wasm,
+}
+
+impl Architecture {
+ /// Return the endianness of this architecture.
+ pub fn endianness(self) -> Result<Endianness, ()> {
+ match self {
+ Architecture::Unknown => Err(()),
+ Architecture::Arm(arm) => Ok(arm.endianness()),
+ Architecture::Aarch64(aarch) => Ok(aarch.endianness()),
+ Architecture::AmdGcn
+ | Architecture::Asmjs
+ | Architecture::Hexagon
+ | Architecture::I386
+ | Architecture::I586
+ | Architecture::I686
+ | Architecture::Mips64el
+ | Architecture::Mipsel
+ | Architecture::Mipsisa32r6el
+ | Architecture::Mipsisa64r6el
+ | Architecture::Msp430
+ | Architecture::Nvptx64
+ | Architecture::Powerpc64le
+ | Architecture::Riscv32
+ | Architecture::Riscv32i
+ | Architecture::Riscv32imac
+ | Architecture::Riscv32imc
+ | Architecture::Riscv64
+ | Architecture::Riscv64gc
+ | Architecture::Riscv64imac
+ | Architecture::Wasm32
+ | Architecture::X86_64 => Ok(Endianness::Little),
+ Architecture::Mips
+ | Architecture::Mips64
+ | Architecture::Mipsisa32r6
+ | Architecture::Mipsisa64r6
+ | Architecture::Powerpc
+ | Architecture::Powerpc64
+ | Architecture::S390x
+ | Architecture::Sparc
+ | Architecture::Sparc64
+ | Architecture::Sparcv9 => Ok(Endianness::Big),
+ }
+ }
+
+ /// Return the pointer bit width of this target's architecture.
+ pub fn pointer_width(self) -> Result<PointerWidth, ()> {
+ match self {
+ Architecture::Unknown => Err(()),
+ Architecture::Msp430 => Ok(PointerWidth::U16),
+ Architecture::Arm(arm) => Ok(arm.pointer_width()),
+ Architecture::Aarch64(aarch) => Ok(aarch.pointer_width()),
+ Architecture::Asmjs
+ | Architecture::Hexagon
+ | Architecture::I386
+ | Architecture::I586
+ | Architecture::I686
+ | Architecture::Mipsel
+ | Architecture::Mipsisa32r6
+ | Architecture::Mipsisa32r6el
+ | Architecture::Riscv32
+ | Architecture::Riscv32i
+ | Architecture::Riscv32imac
+ | Architecture::Riscv32imc
+ | Architecture::Sparc
+ | Architecture::Wasm32
+ | Architecture::Mips
+ | Architecture::Powerpc => Ok(PointerWidth::U32),
+ Architecture::AmdGcn
+ | Architecture::Mips64el
+ | Architecture::Mipsisa64r6
+ | Architecture::Mipsisa64r6el
+ | Architecture::Powerpc64le
+ | Architecture::Riscv64
+ | Architecture::Riscv64gc
+ | Architecture::Riscv64imac
+ | Architecture::X86_64
+ | Architecture::Mips64
+ | Architecture::Nvptx64
+ | Architecture::Powerpc64
+ | Architecture::S390x
+ | Architecture::Sparc64
+ | Architecture::Sparcv9 => Ok(PointerWidth::U64),
+ }
+ }
+}
+
+/// Return the binary format implied by this target triple, ignoring its
+/// `binary_format` field.
+pub(crate) fn default_binary_format(triple: &Triple) -> BinaryFormat {
+ match triple.operating_system {
+ OperatingSystem::None_ => match triple.environment {
+ Environment::Eabi | Environment::Eabihf => BinaryFormat::Elf,
+ _ => BinaryFormat::Unknown,
+ },
+ OperatingSystem::Darwin | OperatingSystem::Ios | OperatingSystem::MacOSX { .. } => {
+ BinaryFormat::Macho
+ }
+ OperatingSystem::Windows => BinaryFormat::Coff,
+ OperatingSystem::Nebulet
+ | OperatingSystem::Emscripten
+ | OperatingSystem::VxWorks
+ | OperatingSystem::Wasi
+ | OperatingSystem::Unknown => match triple.architecture {
+ Architecture::Wasm32 => BinaryFormat::Wasm,
+ _ => BinaryFormat::Unknown,
+ },
+ _ => BinaryFormat::Elf,
+ }
+}
+
+impl fmt::Display for ArmArchitecture {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let s = match *self {
+ ArmArchitecture::Arm => "arm",
+ ArmArchitecture::Armeb => "armeb",
+ ArmArchitecture::Armv4 => "armv4",
+ ArmArchitecture::Armv4t => "armv4t",
+ ArmArchitecture::Armv5t => "armv5t",
+ ArmArchitecture::Armv5te => "armv5te",
+ ArmArchitecture::Armv5tej => "armv5tej",
+ ArmArchitecture::Armv6 => "armv6",
+ ArmArchitecture::Armv6j => "armv6j",
+ ArmArchitecture::Armv6k => "armv6k",
+ ArmArchitecture::Armv6z => "armv6z",
+ ArmArchitecture::Armv6kz => "armv6kz",
+ ArmArchitecture::Armv6t2 => "armv6t2",
+ ArmArchitecture::Armv6m => "armv6m",
+ ArmArchitecture::Armv7 => "armv7",
+ ArmArchitecture::Armv7a => "armv7a",
+ ArmArchitecture::Armv7ve => "armv7ve",
+ ArmArchitecture::Armv7m => "armv7m",
+ ArmArchitecture::Armv7r => "armv7r",
+ ArmArchitecture::Armv7s => "armv7s",
+ ArmArchitecture::Armv8 => "armv8",
+ ArmArchitecture::Armv8a => "armv8a",
+ ArmArchitecture::Armv8_1a => "armv8.1a",
+ ArmArchitecture::Armv8_2a => "armv8.2a",
+ ArmArchitecture::Armv8_3a => "armv8.3a",
+ ArmArchitecture::Armv8_4a => "armv8.4a",
+ ArmArchitecture::Armv8_5a => "armv8.5a",
+ ArmArchitecture::Armv8mBase => "armv8m.base",
+ ArmArchitecture::Armv8mMain => "armv8m.main",
+ ArmArchitecture::Armv8r => "armv8r",
+ ArmArchitecture::Thumbeb => "thumbeb",
+ ArmArchitecture::Thumbv6m => "thumbv6m",
+ ArmArchitecture::Thumbv7a => "thumbv7a",
+ ArmArchitecture::Thumbv7em => "thumbv7em",
+ ArmArchitecture::Thumbv7m => "thumbv7m",
+ ArmArchitecture::Thumbv7neon => "thumbv7neon",
+ ArmArchitecture::Thumbv8mBase => "thumbv8m.base",
+ ArmArchitecture::Thumbv8mMain => "thumbv8m.main",
+ ArmArchitecture::Armebv7r => "armebv7r",
+ };
+ f.write_str(s)
+ }
+}
+
+impl fmt::Display for Aarch64Architecture {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let s = match *self {
+ Aarch64Architecture::Aarch64 => "aarch64",
+ Aarch64Architecture::Aarch64be => "aarch64be",
+ };
+ f.write_str(s)
+ }
+}
+
+impl fmt::Display for Architecture {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ Architecture::Arm(arm) => arm.fmt(f),
+ Architecture::Aarch64(aarch) => aarch.fmt(f),
+ Architecture::Unknown => f.write_str("unknown"),
+ Architecture::AmdGcn => f.write_str("amdgcn"),
+ Architecture::Asmjs => f.write_str("asmjs"),
+ Architecture::Hexagon => f.write_str("hexagon"),
+ Architecture::I386 => f.write_str("i386"),
+ Architecture::I586 => f.write_str("i586"),
+ Architecture::I686 => f.write_str("i686"),
+ Architecture::Mips => f.write_str("mips"),
+ Architecture::Mips64 => f.write_str("mips64"),
+ Architecture::Mips64el => f.write_str("mips64el"),
+ Architecture::Mipsel => f.write_str("mipsel"),
+ Architecture::Mipsisa32r6 => f.write_str("mipsisa32r6"),
+ Architecture::Mipsisa32r6el => f.write_str("mipsisa32r6el"),
+ Architecture::Mipsisa64r6 => f.write_str("mipsisa64r6"),
+ Architecture::Mipsisa64r6el => f.write_str("mipsisa64r6el"),
+ Architecture::Msp430 => f.write_str("msp430"),
+ Architecture::Nvptx64 => f.write_str("nvptx64"),
+ Architecture::Powerpc => f.write_str("powerpc"),
+ Architecture::Powerpc64 => f.write_str("powerpc64"),
+ Architecture::Powerpc64le => f.write_str("powerpc64le"),
+ Architecture::Riscv32 => f.write_str("riscv32"),
+ Architecture::Riscv32i => f.write_str("riscv32i"),
+ Architecture::Riscv32imac => f.write_str("riscv32imac"),
+ Architecture::Riscv32imc => f.write_str("riscv32imc"),
+ Architecture::Riscv64 => f.write_str("riscv64"),
+ Architecture::Riscv64gc => f.write_str("riscv64gc"),
+ Architecture::Riscv64imac => f.write_str("riscv64imac"),
+ Architecture::S390x => f.write_str("s390x"),
+ Architecture::Sparc => f.write_str("sparc"),
+ Architecture::Sparc64 => f.write_str("sparc64"),
+ Architecture::Sparcv9 => f.write_str("sparcv9"),
+ Architecture::Wasm32 => f.write_str("wasm32"),
+ Architecture::X86_64 => f.write_str("x86_64"),
+ }
+ }
+}
+
+impl FromStr for ArmArchitecture {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ Ok(match s {
+ "arm" => ArmArchitecture::Arm,
+ "armeb" => ArmArchitecture::Armeb,
+ "armv4" => ArmArchitecture::Armv4,
+ "armv4t" => ArmArchitecture::Armv4t,
+ "armv5t" => ArmArchitecture::Armv5t,
+ "armv5te" => ArmArchitecture::Armv5te,
+ "armv5tej" => ArmArchitecture::Armv5tej,
+ "armv6" => ArmArchitecture::Armv6,
+ "armv6j" => ArmArchitecture::Armv6j,
+ "armv6k" => ArmArchitecture::Armv6k,
+ "armv6z" => ArmArchitecture::Armv6z,
+ "armv6kz" => ArmArchitecture::Armv6kz,
+ "armv6t2" => ArmArchitecture::Armv6t2,
+ "armv6m" => ArmArchitecture::Armv6m,
+ "armv7" => ArmArchitecture::Armv7,
+ "armv7a" => ArmArchitecture::Armv7a,
+ "armv7ve" => ArmArchitecture::Armv7ve,
+ "armv7m" => ArmArchitecture::Armv7m,
+ "armv7r" => ArmArchitecture::Armv7r,
+ "armv7s" => ArmArchitecture::Armv7s,
+ "armv8" => ArmArchitecture::Armv8,
+ "armv8a" => ArmArchitecture::Armv8a,
+ "armv8.1a" => ArmArchitecture::Armv8_1a,
+ "armv8.2a" => ArmArchitecture::Armv8_2a,
+ "armv8.3a" => ArmArchitecture::Armv8_3a,
+ "armv8.4a" => ArmArchitecture::Armv8_4a,
+ "armv8.5a" => ArmArchitecture::Armv8_5a,
+ "armv8m.base" => ArmArchitecture::Armv8mBase,
+ "armv8m.main" => ArmArchitecture::Armv8mMain,
+ "armv8r" => ArmArchitecture::Armv8r,
+ "thumbeb" => ArmArchitecture::Thumbeb,
+ "thumbv6m" => ArmArchitecture::Thumbv6m,
+ "thumbv7a" => ArmArchitecture::Thumbv7a,
+ "thumbv7em" => ArmArchitecture::Thumbv7em,
+ "thumbv7m" => ArmArchitecture::Thumbv7m,
+ "thumbv7neon" => ArmArchitecture::Thumbv7neon,
+ "thumbv8m.base" => ArmArchitecture::Thumbv8mBase,
+ "thumbv8m.main" => ArmArchitecture::Thumbv8mMain,
+ "armebv7r" => ArmArchitecture::Armebv7r,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl FromStr for Aarch64Architecture {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ Ok(match s {
+ "aarch64" => Aarch64Architecture::Aarch64,
+ "arm64" => Aarch64Architecture::Aarch64,
+ "aarch64be" => Aarch64Architecture::Aarch64be,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl FromStr for Architecture {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ Ok(match s {
+ "unknown" => Architecture::Unknown,
+ "amdgcn" => Architecture::AmdGcn,
+ "asmjs" => Architecture::Asmjs,
+ "hexagon" => Architecture::Hexagon,
+ "i386" => Architecture::I386,
+ "i586" => Architecture::I586,
+ "i686" => Architecture::I686,
+ "mips" => Architecture::Mips,
+ "mips64" => Architecture::Mips64,
+ "mips64el" => Architecture::Mips64el,
+ "mipsel" => Architecture::Mipsel,
+ "mipsisa32r6" => Architecture::Mipsisa32r6,
+ "mipsisa32r6el" => Architecture::Mipsisa32r6el,
+ "mipsisa64r6" => Architecture::Mipsisa64r6,
+ "mipsisa64r6el" => Architecture::Mipsisa64r6el,
+ "msp430" => Architecture::Msp430,
+ "nvptx64" => Architecture::Nvptx64,
+ "powerpc" => Architecture::Powerpc,
+ "powerpc64" => Architecture::Powerpc64,
+ "powerpc64le" => Architecture::Powerpc64le,
+ "riscv32" => Architecture::Riscv32,
+ "riscv32i" => Architecture::Riscv32i,
+ "riscv32imac" => Architecture::Riscv32imac,
+ "riscv32imc" => Architecture::Riscv32imc,
+ "riscv64" => Architecture::Riscv64,
+ "riscv64gc" => Architecture::Riscv64gc,
+ "riscv64imac" => Architecture::Riscv64imac,
+ "s390x" => Architecture::S390x,
+ "sparc" => Architecture::Sparc,
+ "sparc64" => Architecture::Sparc64,
+ "sparcv9" => Architecture::Sparcv9,
+ "wasm32" => Architecture::Wasm32,
+ "x86_64" => Architecture::X86_64,
+ _ => {
+ if let Ok(arm) = ArmArchitecture::from_str(s) {
+ Architecture::Arm(arm)
+ } else if let Ok(aarch64) = Aarch64Architecture::from_str(s) {
+ Architecture::Aarch64(aarch64)
+ } else {
+ return Err(());
+ }
+ }
+ })
+ }
+}
+
+impl fmt::Display for Vendor {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let s = match *self {
+ Vendor::Unknown => "unknown",
+ Vendor::Amd => "amd",
+ Vendor::Apple => "apple",
+ Vendor::Experimental => "experimental",
+ Vendor::Fortanix => "fortanix",
+ Vendor::Nvidia => "nvidia",
+ Vendor::Pc => "pc",
+ Vendor::Rumprun => "rumprun",
+ Vendor::Sun => "sun",
+ Vendor::Uwp => "uwp",
+ Vendor::Wrs => "wrs",
+ };
+ f.write_str(s)
+ }
+}
+
+impl FromStr for Vendor {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ Ok(match s {
+ "unknown" => Vendor::Unknown,
+ "amd" => Vendor::Amd,
+ "apple" => Vendor::Apple,
+ "experimental" => Vendor::Experimental,
+ "fortanix" => Vendor::Fortanix,
+ "nvidia" => Vendor::Nvidia,
+ "pc" => Vendor::Pc,
+ "rumprun" => Vendor::Rumprun,
+ "sun" => Vendor::Sun,
+ "uwp" => Vendor::Uwp,
+ "wrs" => Vendor::Wrs,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl fmt::Display for OperatingSystem {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let s = match *self {
+ OperatingSystem::Unknown => "unknown",
+ OperatingSystem::AmdHsa => "amdhsa",
+ OperatingSystem::Bitrig => "bitrig",
+ OperatingSystem::Cloudabi => "cloudabi",
+ OperatingSystem::Cuda => "cuda",
+ OperatingSystem::Darwin => "darwin",
+ OperatingSystem::Dragonfly => "dragonfly",
+ OperatingSystem::Emscripten => "emscripten",
+ OperatingSystem::Freebsd => "freebsd",
+ OperatingSystem::Fuchsia => "fuchsia",
+ OperatingSystem::Haiku => "haiku",
+ OperatingSystem::Hermit => "hermit",
+ OperatingSystem::Ios => "ios",
+ OperatingSystem::L4re => "l4re",
+ OperatingSystem::Linux => "linux",
+ OperatingSystem::MacOSX {
+ major,
+ minor,
+ patch,
+ } => {
+ return write!(f, "macosx{}.{}.{}", major, minor, patch);
+ }
+ OperatingSystem::Nebulet => "nebulet",
+ OperatingSystem::Netbsd => "netbsd",
+ OperatingSystem::None_ => "none",
+ OperatingSystem::Openbsd => "openbsd",
+ OperatingSystem::Redox => "redox",
+ OperatingSystem::Solaris => "solaris",
+ OperatingSystem::Uefi => "uefi",
+ OperatingSystem::VxWorks => "vxworks",
+ OperatingSystem::Wasi => "wasi",
+ OperatingSystem::Windows => "windows",
+ };
+ f.write_str(s)
+ }
+}
+
+impl FromStr for OperatingSystem {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ // TODO also parse version number for darwin and ios OSes
+ if s.starts_with("macosx") {
+ // Parse operating system names like `macosx10.7.0`.
+ let s = &s["macosx".len()..];
+ let mut parts = s.split('.').map(|num| num.parse::<u16>());
+
+ macro_rules! get_part {
+ () => {
+ if let Some(Ok(part)) = parts.next() {
+ part
+ } else {
+ return Err(());
+ }
+ };
+ }
+
+ let major = get_part!();
+ let minor = get_part!();
+ let patch = get_part!();
+
+ if parts.next().is_some() {
+ return Err(());
+ }
+
+ return Ok(OperatingSystem::MacOSX {
+ major,
+ minor,
+ patch,
+ });
+ }
+
+ Ok(match s {
+ "unknown" => OperatingSystem::Unknown,
+ "amdhsa" => OperatingSystem::AmdHsa,
+ "bitrig" => OperatingSystem::Bitrig,
+ "cloudabi" => OperatingSystem::Cloudabi,
+ "cuda" => OperatingSystem::Cuda,
+ "darwin" => OperatingSystem::Darwin,
+ "dragonfly" => OperatingSystem::Dragonfly,
+ "emscripten" => OperatingSystem::Emscripten,
+ "freebsd" => OperatingSystem::Freebsd,
+ "fuchsia" => OperatingSystem::Fuchsia,
+ "haiku" => OperatingSystem::Haiku,
+ "hermit" => OperatingSystem::Hermit,
+ "ios" => OperatingSystem::Ios,
+ "l4re" => OperatingSystem::L4re,
+ "linux" => OperatingSystem::Linux,
+ "nebulet" => OperatingSystem::Nebulet,
+ "netbsd" => OperatingSystem::Netbsd,
+ "none" => OperatingSystem::None_,
+ "openbsd" => OperatingSystem::Openbsd,
+ "redox" => OperatingSystem::Redox,
+ "solaris" => OperatingSystem::Solaris,
+ "uefi" => OperatingSystem::Uefi,
+ "vxworks" => OperatingSystem::VxWorks,
+ "wasi" => OperatingSystem::Wasi,
+ "windows" => OperatingSystem::Windows,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl fmt::Display for Environment {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let s = match *self {
+ Environment::Unknown => "unknown",
+ Environment::AmdGiz => "amdgiz",
+ Environment::Android => "android",
+ Environment::Androideabi => "androideabi",
+ Environment::Eabi => "eabi",
+ Environment::Eabihf => "eabihf",
+ Environment::Gnu => "gnu",
+ Environment::Gnuabi64 => "gnuabi64",
+ Environment::Gnueabi => "gnueabi",
+ Environment::Gnueabihf => "gnueabihf",
+ Environment::Gnuspe => "gnuspe",
+ Environment::Gnux32 => "gnux32",
+ Environment::Musl => "musl",
+ Environment::Musleabi => "musleabi",
+ Environment::Musleabihf => "musleabihf",
+ Environment::Muslabi64 => "muslabi64",
+ Environment::Msvc => "msvc",
+ Environment::Kernel => "kernel",
+ Environment::Uclibc => "uclibc",
+ Environment::Sgx => "sgx",
+ Environment::Softfloat => "softfloat",
+ Environment::Spe => "spe",
+ };
+ f.write_str(s)
+ }
+}
+
+impl FromStr for Environment {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ Ok(match s {
+ "unknown" => Environment::Unknown,
+ "amdgiz" => Environment::AmdGiz,
+ "android" => Environment::Android,
+ "androideabi" => Environment::Androideabi,
+ "eabi" => Environment::Eabi,
+ "eabihf" => Environment::Eabihf,
+ "gnu" => Environment::Gnu,
+ "gnuabi64" => Environment::Gnuabi64,
+ "gnueabi" => Environment::Gnueabi,
+ "gnueabihf" => Environment::Gnueabihf,
+ "gnuspe" => Environment::Gnuspe,
+ "gnux32" => Environment::Gnux32,
+ "musl" => Environment::Musl,
+ "musleabi" => Environment::Musleabi,
+ "musleabihf" => Environment::Musleabihf,
+ "muslabi64" => Environment::Muslabi64,
+ "msvc" => Environment::Msvc,
+ "kernel" => Environment::Kernel,
+ "uclibc" => Environment::Uclibc,
+ "sgx" => Environment::Sgx,
+ "softfloat" => Environment::Softfloat,
+ "spe" => Environment::Spe,
+ _ => return Err(()),
+ })
+ }
+}
+
+impl fmt::Display for BinaryFormat {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let s = match *self {
+ BinaryFormat::Unknown => "unknown",
+ BinaryFormat::Elf => "elf",
+ BinaryFormat::Coff => "coff",
+ BinaryFormat::Macho => "macho",
+ BinaryFormat::Wasm => "wasm",
+ };
+ f.write_str(s)
+ }
+}
+
+impl FromStr for BinaryFormat {
+ type Err = ();
+
+ fn from_str(s: &str) -> Result<Self, ()> {
+ Ok(match s {
+ "unknown" => BinaryFormat::Unknown,
+ "elf" => BinaryFormat::Elf,
+ "coff" => BinaryFormat::Coff,
+ "macho" => BinaryFormat::Macho,
+ "wasm" => BinaryFormat::Wasm,
+ _ => return Err(()),
+ })
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use alloc::string::ToString;
+
+ #[test]
+ fn roundtrip_known_triples() {
+ // This list is constructed from:
+ // - targets emitted by "rustup target list"
+ // - targets emitted by "rustc +nightly --print target-list"
+ // - targets contributors have added
+ let targets = [
+ "aarch64-apple-ios",
+ "aarch64-fuchsia",
+ "aarch64-linux-android",
+ "aarch64-pc-windows-msvc",
+ "aarch64-unknown-cloudabi",
+ "aarch64-unknown-freebsd",
+ "aarch64-unknown-hermit",
+ "aarch64-unknown-linux-gnu",
+ "aarch64-unknown-linux-musl",
+ "aarch64-unknown-netbsd",
+ "aarch64-unknown-none",
+ "aarch64-unknown-none-softfloat",
+ "aarch64-unknown-openbsd",
+ "aarch64-unknown-redox",
+ "aarch64-uwp-windows-msvc",
+ "aarch64-wrs-vxworks",
+ "amdgcn-amd-amdhsa",
+ "amdgcn-amd-amdhsa-amdgiz",
+ "armebv7r-none-eabi",
+ "armebv7r-none-eabihf",
+ "arm-linux-androideabi",
+ "arm-unknown-linux-gnueabi",
+ "arm-unknown-linux-gnueabihf",
+ "arm-unknown-linux-musleabi",
+ "arm-unknown-linux-musleabihf",
+ "armv4t-unknown-linux-gnueabi",
+ "armv5te-unknown-linux-gnueabi",
+ "armv5te-unknown-linux-musleabi",
+ "armv6-unknown-freebsd",
+ "armv6-unknown-netbsd-eabihf",
+ "armv7-apple-ios",
+ "armv7-linux-androideabi",
+ "armv7r-none-eabi",
+ "armv7r-none-eabihf",
+ "armv7s-apple-ios",
+ "armv7-unknown-cloudabi-eabihf",
+ "armv7-unknown-freebsd",
+ "armv7-unknown-linux-gnueabi",
+ "armv7-unknown-linux-gnueabihf",
+ "armv7-unknown-linux-musleabi",
+ "armv7-unknown-linux-musleabihf",
+ "armv7-unknown-netbsd-eabihf",
+ "armv7-wrs-vxworks-eabihf",
+ "asmjs-unknown-emscripten",
+ "hexagon-unknown-linux-musl",
+ "i386-apple-ios",
+ "i586-pc-windows-msvc",
+ "i586-unknown-linux-gnu",
+ "i586-unknown-linux-musl",
+ "i686-apple-darwin",
+ "i686-linux-android",
+ "i686-apple-macosx10.7.0",
+ "i686-pc-windows-gnu",
+ "i686-pc-windows-msvc",
+ "i686-unknown-cloudabi",
+ "i686-unknown-dragonfly",
+ "i686-unknown-freebsd",
+ "i686-unknown-haiku",
+ "i686-unknown-linux-gnu",
+ "i686-unknown-linux-musl",
+ "i686-unknown-netbsd",
+ "i686-unknown-openbsd",
+ "i686-unknown-uefi",
+ "i686-uwp-windows-gnu",
+ "i686-uwp-windows-msvc",
+ "i686-wrs-vxworks",
+ "mips64el-unknown-linux-gnuabi64",
+ "mips64el-unknown-linux-muslabi64",
+ "mips64-unknown-linux-gnuabi64",
+ "mips64-unknown-linux-muslabi64",
+ "mipsel-unknown-linux-gnu",
+ "mipsel-unknown-linux-musl",
+ "mipsel-unknown-linux-uclibc",
+ "mipsisa32r6el-unknown-linux-gnu",
+ "mipsisa32r6-unknown-linux-gnu",
+ "mipsisa64r6el-unknown-linux-gnuabi64",
+ "mipsisa64r6-unknown-linux-gnuabi64",
+ "mips-unknown-linux-gnu",
+ "mips-unknown-linux-musl",
+ "mips-unknown-linux-uclibc",
+ "msp430-none-elf",
+ "nvptx64-nvidia-cuda",
+ "powerpc64le-unknown-linux-gnu",
+ "powerpc64le-unknown-linux-musl",
+ "powerpc64-unknown-freebsd",
+ "powerpc64-unknown-linux-gnu",
+ "powerpc64-unknown-linux-musl",
+ "powerpc64-wrs-vxworks",
+ "powerpc-unknown-linux-gnu",
+ "powerpc-unknown-linux-gnuspe",
+ "powerpc-unknown-linux-musl",
+ "powerpc-unknown-netbsd",
+ "powerpc-wrs-vxworks",
+ "powerpc-wrs-vxworks-spe",
+ "riscv32imac-unknown-none-elf",
+ "riscv32imc-unknown-none-elf",
+ "riscv32i-unknown-none-elf",
+ "riscv64gc-unknown-none-elf",
+ "riscv64imac-unknown-none-elf",
+ "s390x-unknown-linux-gnu",
+ "sparc64-unknown-linux-gnu",
+ "sparc64-unknown-netbsd",
+ "sparc64-unknown-openbsd",
+ "sparc-unknown-linux-gnu",
+ "sparcv9-sun-solaris",
+ "thumbv6m-none-eabi",
+ "thumbv7a-pc-windows-msvc",
+ "thumbv7em-none-eabi",
+ "thumbv7em-none-eabihf",
+ "thumbv7m-none-eabi",
+ "thumbv7neon-linux-androideabi",
+ "thumbv7neon-unknown-linux-gnueabihf",
+ "thumbv8m.base-none-eabi",
+ "thumbv8m.main-none-eabi",
+ "thumbv8m.main-none-eabihf",
+ "wasm32-experimental-emscripten",
+ "wasm32-unknown-emscripten",
+ "wasm32-unknown-unknown",
+ "wasm32-wasi",
+ "x86_64-apple-darwin",
+ "x86_64-apple-ios",
+ "x86_64-fortanix-unknown-sgx",
+ "x86_64-fuchsia",
+ "x86_64-linux-android",
+ "x86_64-linux-kernel",
+ "x86_64-apple-macosx10.7.0",
+ "x86_64-pc-solaris",
+ "x86_64-pc-windows-gnu",
+ "x86_64-pc-windows-msvc",
+ "x86_64-rumprun-netbsd",
+ "x86_64-sun-solaris",
+ "x86_64-unknown-bitrig",
+ "x86_64-unknown-cloudabi",
+ "x86_64-unknown-dragonfly",
+ "x86_64-unknown-freebsd",
+ "x86_64-unknown-haiku",
+ "x86_64-unknown-hermit",
+ "x86_64-unknown-l4re-uclibc",
+ "x86_64-unknown-linux-gnu",
+ "x86_64-unknown-linux-gnux32",
+ "x86_64-unknown-linux-musl",
+ "x86_64-unknown-netbsd",
+ "x86_64-unknown-openbsd",
+ "x86_64-unknown-redox",
+ "x86_64-unknown-uefi",
+ "x86_64-uwp-windows-gnu",
+ "x86_64-uwp-windows-msvc",
+ "x86_64-wrs-vxworks",
+ ];
+
+ for target in targets.iter() {
+ let t = Triple::from_str(target).expect("can't parse target");
+ assert_ne!(t.architecture, Architecture::Unknown);
+ assert_eq!(t.to_string(), *target);
+ }
+ }
+
+ #[test]
+ fn thumbv7em_none_eabihf() {
+ let t = Triple::from_str("thumbv7em-none-eabihf").expect("can't parse target");
+ assert_eq!(
+ t.architecture,
+ Architecture::Arm(ArmArchitecture::Thumbv7em)
+ );
+ assert_eq!(t.vendor, Vendor::Unknown);
+ assert_eq!(t.operating_system, OperatingSystem::None_);
+ assert_eq!(t.environment, Environment::Eabihf);
+ assert_eq!(t.binary_format, BinaryFormat::Elf);
+ }
+}
diff --git a/third_party/rust/target-lexicon-0.9.0/src/triple.rs b/third_party/rust/target-lexicon-0.9.0/src/triple.rs
new file mode 100644
index 0000000000..36dcd9aa00
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/src/triple.rs
@@ -0,0 +1,369 @@
+// This file defines the `Triple` type and support code shared by all targets.
+
+use crate::parse_error::ParseError;
+use crate::targets::{
+ default_binary_format, Architecture, ArmArchitecture, BinaryFormat, Environment,
+ OperatingSystem, Vendor,
+};
+use alloc::borrow::ToOwned;
+use core::fmt;
+use core::str::FromStr;
+
+/// The target memory endianness.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum Endianness {
+ Little,
+ Big,
+}
+
+/// The width of a pointer (in the default address space).
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum PointerWidth {
+ U16,
+ U32,
+ U64,
+}
+
+impl PointerWidth {
+ /// Return the number of bits in a pointer.
+ pub fn bits(self) -> u8 {
+ match self {
+ PointerWidth::U16 => 16,
+ PointerWidth::U32 => 32,
+ PointerWidth::U64 => 64,
+ }
+ }
+
+ /// Return the number of bytes in a pointer.
+ ///
+ /// For these purposes, there are 8 bits in a byte.
+ pub fn bytes(self) -> u8 {
+ match self {
+ PointerWidth::U16 => 2,
+ PointerWidth::U32 => 4,
+ PointerWidth::U64 => 8,
+ }
+ }
+}
+
+/// The calling convention, which specifies things like which registers are
+/// used for passing arguments, which registers are callee-saved, and so on.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[allow(missing_docs)]
+pub enum CallingConvention {
+ /// "System V", which is used on most Unix-like platfoms. Note that the
+ /// specific conventions vary between hardware architectures; for example,
+ /// x86-32's "System V" is entirely different from x86-64's "System V".
+ SystemV,
+
+ /// The WebAssembly C ABI.
+ /// https://github.com/WebAssembly/tool-conventions/blob/master/BasicCABI.md
+ WasmBasicCAbi,
+
+ /// "Windows Fastcall", which is used on Windows. Note that like "System V",
+ /// this varies between hardware architectures. On x86-32 it describes what
+ /// Windows documentation calls "fastcall", and on x86-64 it describes what
+ /// Windows documentation often just calls the Windows x64 calling convention
+ /// (though the compiler still recognizes "fastcall" as an alias for it).
+ WindowsFastcall,
+}
+
+/// A target "triple". Historically such things had three fields, though they've
+/// added additional fields over time.
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct Triple {
+ /// The "architecture" (and sometimes the subarchitecture).
+ pub architecture: Architecture,
+ /// The "vendor" (whatever that means).
+ pub vendor: Vendor,
+ /// The "operating system" (sometimes also the environment).
+ pub operating_system: OperatingSystem,
+ /// The "environment" on top of the operating system (often omitted for
+ /// operating systems with a single predominant environment).
+ pub environment: Environment,
+ /// The "binary format" (rarely used).
+ pub binary_format: BinaryFormat,
+}
+
+impl Triple {
+ /// Return the endianness of this target's architecture.
+ pub fn endianness(&self) -> Result<Endianness, ()> {
+ self.architecture.endianness()
+ }
+
+ /// Return the pointer width of this target's architecture.
+ pub fn pointer_width(&self) -> Result<PointerWidth, ()> {
+ self.architecture.pointer_width()
+ }
+
+ /// Return the default calling convention for the given target triple.
+ pub fn default_calling_convention(&self) -> Result<CallingConvention, ()> {
+ Ok(match self.operating_system {
+ OperatingSystem::Bitrig
+ | OperatingSystem::Cloudabi
+ | OperatingSystem::Darwin
+ | OperatingSystem::Dragonfly
+ | OperatingSystem::Freebsd
+ | OperatingSystem::Fuchsia
+ | OperatingSystem::Haiku
+ | OperatingSystem::Ios
+ | OperatingSystem::L4re
+ | OperatingSystem::Linux
+ | OperatingSystem::MacOSX { .. }
+ | OperatingSystem::Netbsd
+ | OperatingSystem::Openbsd
+ | OperatingSystem::Redox
+ | OperatingSystem::Solaris => CallingConvention::SystemV,
+ OperatingSystem::Windows => CallingConvention::WindowsFastcall,
+ OperatingSystem::Nebulet
+ | OperatingSystem::Emscripten
+ | OperatingSystem::Wasi
+ | OperatingSystem::Unknown => match self.architecture {
+ Architecture::Wasm32 => CallingConvention::WasmBasicCAbi,
+ _ => return Err(()),
+ },
+ _ => return Err(()),
+ })
+ }
+}
+
+impl Default for Triple {
+ fn default() -> Self {
+ Self {
+ architecture: Architecture::Unknown,
+ vendor: Vendor::Unknown,
+ operating_system: OperatingSystem::Unknown,
+ environment: Environment::Unknown,
+ binary_format: BinaryFormat::Unknown,
+ }
+ }
+}
+
+impl Default for Architecture {
+ fn default() -> Self {
+ Architecture::Unknown
+ }
+}
+
+impl Default for Vendor {
+ fn default() -> Self {
+ Vendor::Unknown
+ }
+}
+
+impl Default for OperatingSystem {
+ fn default() -> Self {
+ OperatingSystem::Unknown
+ }
+}
+
+impl Default for Environment {
+ fn default() -> Self {
+ Environment::Unknown
+ }
+}
+
+impl Default for BinaryFormat {
+ fn default() -> Self {
+ BinaryFormat::Unknown
+ }
+}
+
+impl fmt::Display for Triple {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ let implied_binary_format = default_binary_format(&self);
+
+ write!(f, "{}", self.architecture)?;
+ if self.vendor == Vendor::Unknown
+ && ((self.operating_system == OperatingSystem::Linux
+ && (self.environment == Environment::Android
+ || self.environment == Environment::Androideabi
+ || self.environment == Environment::Kernel))
+ || self.operating_system == OperatingSystem::Fuchsia
+ || self.operating_system == OperatingSystem::Wasi
+ || (self.operating_system == OperatingSystem::None_
+ && (self.architecture == Architecture::Arm(ArmArchitecture::Armebv7r)
+ || self.architecture == Architecture::Arm(ArmArchitecture::Armv7r)
+ || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv6m)
+ || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv7em)
+ || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv7m)
+ || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv8mBase)
+ || self.architecture == Architecture::Arm(ArmArchitecture::Thumbv8mMain)
+ || self.architecture == Architecture::Msp430
+ || self.architecture == Architecture::X86_64)))
+ {
+ // As a special case, omit the vendor for Android, Fuchsia, Wasi, and sometimes
+ // None_, depending on the hardware architecture. This logic is entirely
+ // ad-hoc, and is just sufficient to handle the current set of recognized
+ // triples.
+ write!(f, "-{}", self.operating_system)?;
+ } else {
+ write!(f, "-{}-{}", self.vendor, self.operating_system)?;
+ }
+ if self.environment != Environment::Unknown {
+ write!(f, "-{}", self.environment)?;
+ }
+
+ if self.binary_format != implied_binary_format {
+ write!(f, "-{}", self.binary_format)?;
+ }
+ Ok(())
+ }
+}
+
+impl FromStr for Triple {
+ type Err = ParseError;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ let mut parts = s.split('-');
+ let mut result = Self::default();
+ let mut current_part;
+
+ current_part = parts.next();
+ if let Some(s) = current_part {
+ if let Ok(architecture) = Architecture::from_str(s) {
+ result.architecture = architecture;
+ current_part = parts.next();
+ } else {
+ // Insist that the triple start with a valid architecture.
+ return Err(ParseError::UnrecognizedArchitecture(s.to_owned()));
+ }
+ }
+
+ let mut has_vendor = false;
+ let mut has_operating_system = false;
+ if let Some(s) = current_part {
+ if let Ok(vendor) = Vendor::from_str(s) {
+ has_vendor = true;
+ result.vendor = vendor;
+ current_part = parts.next();
+ }
+ }
+
+ if !has_operating_system {
+ if let Some(s) = current_part {
+ if let Ok(operating_system) = OperatingSystem::from_str(s) {
+ has_operating_system = true;
+ result.operating_system = operating_system;
+ current_part = parts.next();
+ }
+ }
+ }
+
+ let mut has_environment = false;
+ if let Some(s) = current_part {
+ if let Ok(environment) = Environment::from_str(s) {
+ has_environment = true;
+ result.environment = environment;
+ current_part = parts.next();
+ }
+ }
+
+ let mut has_binary_format = false;
+ if let Some(s) = current_part {
+ if let Ok(binary_format) = BinaryFormat::from_str(s) {
+ has_binary_format = true;
+ result.binary_format = binary_format;
+ current_part = parts.next();
+ }
+ }
+
+ // The binary format is frequently omitted; if that's the case here,
+ // infer it from the other fields.
+ if !has_binary_format {
+ result.binary_format = default_binary_format(&result);
+ }
+
+ if let Some(s) = current_part {
+ Err(
+ if !has_vendor && !has_operating_system && !has_environment && !has_binary_format {
+ ParseError::UnrecognizedVendor(s.to_owned())
+ } else if !has_operating_system && !has_environment && !has_binary_format {
+ ParseError::UnrecognizedOperatingSystem(s.to_owned())
+ } else if !has_environment && !has_binary_format {
+ ParseError::UnrecognizedEnvironment(s.to_owned())
+ } else if !has_binary_format {
+ ParseError::UnrecognizedBinaryFormat(s.to_owned())
+ } else {
+ ParseError::UnrecognizedField(s.to_owned())
+ },
+ )
+ } else {
+ Ok(result)
+ }
+ }
+}
+
+/// A convenient syntax for triple literals.
+///
+/// This currently expands to code that just calls `Triple::from_str` and does
+/// an `expect`, though in the future it would be cool to use procedural macros
+/// or so to report errors at compile time instead.
+#[macro_export]
+macro_rules! triple {
+ ($str:tt) => {
+ target_lexicon::Triple::from_str($str).expect("invalid triple literal")
+ };
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn parse_errors() {
+ assert_eq!(
+ Triple::from_str(""),
+ Err(ParseError::UnrecognizedArchitecture("".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("foo"),
+ Err(ParseError::UnrecognizedArchitecture("foo".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("unknown-foo"),
+ Err(ParseError::UnrecognizedVendor("foo".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("unknown-unknown-foo"),
+ Err(ParseError::UnrecognizedOperatingSystem("foo".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("unknown-unknown-unknown-foo"),
+ Err(ParseError::UnrecognizedEnvironment("foo".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("unknown-unknown-unknown-unknown-foo"),
+ Err(ParseError::UnrecognizedBinaryFormat("foo".to_owned()))
+ );
+ assert_eq!(
+ Triple::from_str("unknown-unknown-unknown-unknown-unknown-foo"),
+ Err(ParseError::UnrecognizedField("foo".to_owned()))
+ );
+ }
+
+ #[test]
+ fn defaults() {
+ assert_eq!(
+ Triple::from_str("unknown-unknown-unknown"),
+ Ok(Triple::default())
+ );
+ assert_eq!(
+ Triple::from_str("unknown-unknown-unknown-unknown"),
+ Ok(Triple::default())
+ );
+ assert_eq!(
+ Triple::from_str("unknown-unknown-unknown-unknown-unknown"),
+ Ok(Triple::default())
+ );
+ }
+
+ #[test]
+ fn unknown_properties() {
+ assert_eq!(Triple::default().endianness(), Err(()));
+ assert_eq!(Triple::default().pointer_width(), Err(()));
+ assert_eq!(Triple::default().default_calling_convention(), Err(()));
+ }
+}
diff --git a/third_party/rust/target-lexicon-0.9.0/test.sh b/third_party/rust/target-lexicon-0.9.0/test.sh
new file mode 100755
index 0000000000..dcff63a4e2
--- /dev/null
+++ b/third_party/rust/target-lexicon-0.9.0/test.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+set -oeu pipefail
+
+
+for trip in wasm32-unknown-unknown wasm32-wasi arm-unknown-linux-gnueabi aarch64-unknown-linux-gnu; do
+ echo TARGET $trip
+ cargo build --target $trip --all
+ cp target/$trip/debug/build/target-lexicon-*/out/host.rs host.rs
+ rustfmt host.rs
+ diff -u target/$trip/debug/build/target-lexicon-*/out/host.rs host.rs
+done