Vendor deps.

This commit is contained in:
jimmy committed 2026-09-16 20:10:35 -04:00
1 parent 294527085e
commit 91e18fde3a
1714 files changed
+556667 -7

No files matched your search

+1
View File
@@ -0,0 +1 @@
{"files":{".cargo_vcs_info.json":"43cf58c3feef557572d099bb89ada7ac33863b5fcea2d60f1f6fe1d407442eef",".github/actions/install-rust/README.md":"ec3413893c747ac6a33cdf3331a5d17b9dfdb5b938c8d8edeb124c739feddfdf","Cargo.lock":"536bb6dd71e6b51e31e7166f7300b3289aca58467a2f7a836d72bb1b51748e9e","Cargo.toml":"68c92fd64e0ba0311fffd938aa03a2c58a13341c37523da1dd465c7eea9269ea","Cargo.toml.orig":"c9ab3fc97cf1702b3d4a4adc83d50959eb4bb4131460a29f0c015cecbfa8084a","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"608a98115ed2846984e68cbbea120473f9803c04297898c06435336a24bf4c32","build.rs":"678ba872ef2254e8901d6a00536f64d74d375d919f845113bd3ded709b6edb4a","src/data_model.rs":"17d2a169891723972f726c95d03a20c4a1482464c685028685f48ca976482a1c","src/host.rs":"f51aae5e56e531648b94afd85012f73aad5615e634df64d2b1445a0e0285d8ba","src/lib.rs":"c372de38d232f90d1aa7142702fd122b00f3b8fcb87b9bb0a2177ed9b7c4b6e7","src/parse_error.rs":"b3735eabc0fd0a9dfdd6375662f20ec96a79852a00a05a98fb2e421545285e53","src/targets.rs":"e51c256e555be425b8a912460e7c68c42b2788d3ea611908bc6727f7bb4f678a","src/triple.rs":"76ca408aeb22b5ac334483dba9024975a65c7d470ae71c9bfd0cf7b8bfa1b5ec"},"package":"adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"}
+6
View File
@@ -0,0 +1,6 @@
{
"git": {
"sha1": "6647bd7d681d3e218c88568d8285dfd8cae2dd97"
},
"path_in_vcs": ""
}
@@ -0,0 +1,18 @@
# install-rust
A small github action to install `rustup` and a Rust toolchain. This is
generally expressed inline, but it was repeated enough in this repository it
seemed worthwhile to extract.
Some gotchas:
* Can't `--self-update` on Windows due to permission errors (a bug in Github
Actions)
* `rustup` isn't installed on macOS (a bug in Github Actions)
When the above are fixed we should delete this action and just use this inline:
```yml
- run: rustup update $toolchain && rustup default $toolchain
shell: bash
```
+96
View File
@@ -0,0 +1,96 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "memchr"
version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "proc-macro2"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "target-lexicon"
version = "0.13.5"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+71
View File
@@ -0,0 +1,71 @@
# 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 are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
name = "target-lexicon"
version = "0.13.5"
authors = ["Dan Gohman <sunfish@mozilla.com>"]
build = "build.rs"
include = [
"Cargo.toml",
"README.md",
"LICENSE",
"build.rs",
"src/**/*.rs",
]
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "LLVM target triple types"
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/bytecodealliance/target-lexicon"
[badges.maintenance]
status = "passively-maintained"
[features]
arch_z80 = []
arch_zkasm = []
default = []
serde_support = [
"serde",
"std",
]
std = []
[lib]
name = "target_lexicon"
path = "src/lib.rs"
[dependencies.serde]
version = "1.0"
optional = true
[dev-dependencies.serde_json]
version = "1.0"
[lints.rust.unexpected_cfgs]
level = "warn"
priority = 0
check-cfg = ['cfg(feature, values("rust_1_40", "cargo-clippy"))']
+34
View File
@@ -0,0 +1,34 @@
[package]
name = "target-lexicon"
version = "0.13.5"
authors = ["Dan Gohman <sunfish@mozilla.com>"]
description = "LLVM target triple types"
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/bytecodealliance/target-lexicon"
edition = "2018"
include = ["Cargo.toml", "README.md", "LICENSE", "build.rs", "src/**/*.rs"]
[dependencies]
serde = { version = "1.0", optional = true }
[dev-dependencies]
serde_json = "1.0"
[features]
default = []
serde_support = ["serde", "std"]
std = []
# Enable (unstable) support for the zkasm architecture.
arch_zkasm = []
# Enable (unstable) support for the z80 architecture.
arch_z80 = []
[badges]
maintenance = { status = "passively-maintained" }
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(feature, values("rust_1_40", "cargo-clippy"))'] }
+220
View File
@@ -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.
+24
View File
@@ -0,0 +1,24 @@
This is a library for managing targets for compilers and related tools.
Currently, the main feature is support for decoding [LLVM "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 somewhat supports reading triples currently used by `rustc` and rustup,
though beware that the mapping between `rustc` and LLVM triples is not
one-to-one.
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.
[LLVM "triples"]: https://clang.llvm.org/docs/CrossCompilation.html#target-triple
+179
View File
@@ -0,0 +1,179 @@
//! 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::process::Command;
use std::str::FromStr;
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std as alloc;
// Include triple.rs and targets.rs so we can parse the TARGET environment variable.
// targets.rs depends on data_model
mod data_model {
include!("src/data_model.rs");
}
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::targets::Vendor;
use self::triple::Triple;
fn main() {
let out_dir = PathBuf::from(
env::var_os("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).unwrap_or_else(|_| panic!("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");
if using_1_40() {
println!("cargo:rustc-cfg=feature=\"rust_1_40\"");
}
}
fn using_1_40() -> bool {
match (|| {
let rustc = env::var_os("RUSTC").unwrap();
let output = Command::new(rustc).arg("--version").output().ok()?;
let stdout = if output.status.success() {
output.stdout
} else {
return None;
};
std::str::from_utf8(&stdout)
.ok()?
.split(' ')
.nth(1)?
.split('.')
.nth(1)?
.parse::<i32>()
.ok()
})() {
Some(version) => version >= 40,
None => true, // assume we're using an up-to-date compiler
}
}
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,
r#"
#[allow(unused_imports)]
use crate::Aarch64Architecture::*;
#[allow(unused_imports)]
use crate::ArmArchitecture::*;
#[allow(unused_imports)]
use crate::CustomVendor;
#[allow(unused_imports)]
use crate::Mips32Architecture::*;
#[allow(unused_imports)]
use crate::Mips64Architecture::*;
#[allow(unused_imports)]
use crate::Riscv32Architecture::*;
#[allow(unused_imports)]
use crate::Riscv64Architecture::*;
#[allow(unused_imports)]
use crate::X86_32Architecture::*;
/// The `Triple` of the current host.
pub const HOST: Triple = Triple {{
architecture: Architecture::{architecture:?},
vendor: Vendor::{vendor},
operating_system: OperatingSystem::{operating_system:?},
environment: Environment::{environment:?},
binary_format: BinaryFormat::{binary_format:?},
}};
impl Architecture {{
/// Return the architecture for the current host.
pub const fn host() -> Self {{
Architecture::{architecture:?}
}}
}}
impl Vendor {{
/// Return the vendor for the current host.
pub const fn host() -> Self {{
Vendor::{vendor}
}}
}}
impl OperatingSystem {{
/// Return the operating system for the current host.
pub const fn host() -> Self {{
OperatingSystem::{operating_system:?}
}}
}}
impl Environment {{
/// Return the environment for the current host.
pub const fn host() -> Self {{
Environment::{environment:?}
}}
}}
impl BinaryFormat {{
/// Return the binary format for the current host.
pub const fn host() -> Self {{
BinaryFormat::{binary_format:?}
}}
}}
impl Triple {{
/// Return the triple for the current host.
pub const fn host() -> Self {{
Self {{
architecture: Architecture::{architecture:?},
vendor: Vendor::{vendor},
operating_system: OperatingSystem::{operating_system:?},
environment: Environment::{environment:?},
binary_format: BinaryFormat::{binary_format:?},
}}
}}
}}"#,
architecture = triple.architecture,
vendor = vendor_display(&triple.vendor),
operating_system = triple.operating_system,
environment = triple.environment,
binary_format = triple.binary_format,
)?;
Ok(())
}
fn vendor_display(vendor: &Vendor) -> String {
match vendor {
Vendor::Custom(custom) => format!("Custom(CustomVendor::Static({:?}))", custom.as_str()),
known => format!("{:?}", known),
}
}
+120
View File
@@ -0,0 +1,120 @@
/// The size of a type.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[allow(missing_docs)]
pub enum Size {
U8,
U16,
U32,
U64,
}
impl Size {
/// Return the number of bits this `Size` represents.
pub fn bits(self) -> u8 {
use Size::*;
match self {
U8 => 8,
U16 => 16,
U32 => 32,
U64 => 64,
}
}
/// Return the number of bytes in a size.
///
/// A byte is assumed to be 8 bits.
pub fn bytes(self) -> u8 {
use Size::*;
match self {
U8 => 1,
U16 => 2,
U32 => 4,
U64 => 8,
}
}
}
/// The C data model used on a target.
///
/// See also https://en.cppreference.com/w/c/language/arithmetic_types
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
pub enum CDataModel {
/// The data model used most commonly on Win16. `long` and `pointer` are 32 bits.
LP32,
/// The data model used most commonly on Win32 and 32-bit Unix systems.
///
/// `int`, `long`, and `pointer` are all 32 bits.
ILP32,
/// The data model used most commonly on Win64
///
/// `long long`, and `pointer` are 64 bits.
LLP64,
/// The data model used most commonly on 64-bit Unix systems
///
/// `long`, and `pointer` are 64 bits.
LP64,
/// A rare data model used on early 64-bit Unix systems
///
/// `int`, `long`, and `pointer` are all 64 bits.
ILP64,
}
impl CDataModel {
/// The width of a pointer (in the default address space).
pub fn pointer_width(self) -> Size {
use CDataModel::*;
match self {
LP32 | ILP32 => Size::U32,
LLP64 | LP64 | ILP64 => Size::U64,
}
}
/// The size of a C `short`. This is required to be at least 16 bits.
pub fn short_size(self) -> Size {
use CDataModel::*;
match self {
LP32 | ILP32 | LLP64 | LP64 | ILP64 => Size::U16,
}
}
/// The size of a C `int`. This is required to be at least 16 bits.
pub fn int_size(self) -> Size {
use CDataModel::*;
match self {
LP32 => Size::U16,
ILP32 | LLP64 | LP64 => Size::U32,
ILP64 => Size::U64,
}
}
/// The size of a C `long`. This is required to be at least 32 bits.
pub fn long_size(self) -> Size {
use CDataModel::*;
match self {
LP32 | ILP32 | LLP64 => Size::U32,
LP64 | ILP64 => Size::U64,
}
}
/// The size of a C `long long`. This is required (in C99+) to be at least 64 bits.
pub fn long_long_size(self) -> Size {
use CDataModel::*;
match self {
LP32 | ILP32 | LLP64 | ILP64 | LP64 => Size::U64,
}
}
/// The size of a C `float`.
pub fn float_size(self) -> Size {
// TODO: this is probably wrong on at least one architecture
Size::U32
}
/// The size of a C `double`.
pub fn double_size(self) -> Size {
// TODO: this is probably wrong on at least one architecture
Size::U64
}
}
+70
View File
@@ -0,0 +1,70 @@
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 = "aix")]
#[test]
fn test_aix() {
use super::*;
assert_eq!(OperatingSystem::host(), OperatingSystem::Aix);
}
#[cfg(target_os = "cygwin")]
#[test]
fn test_cygwin() {
use super::*;
assert_eq!(OperatingSystem::host(), OperatingSystem::Cygwin);
}
#[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(None));
}
#[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());
}
}
+109
View File
@@ -0,0 +1,109 @@
//! LLVM target triple types.
#![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)]
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std as alloc;
mod data_model;
mod host;
mod parse_error;
mod targets;
#[macro_use]
mod triple;
pub use self::data_model::{CDataModel, Size};
pub use self::host::HOST;
pub use self::parse_error::ParseError;
pub use self::targets::{
Aarch64Architecture, Architecture, ArmArchitecture, BinaryFormat, CleverArchitecture,
CustomVendor, DeploymentTarget, Environment, Mips32Architecture, Mips64Architecture,
OperatingSystem, Riscv32Architecture, Riscv64Architecture, Vendor, X86_32Architecture,
};
pub use self::triple::{CallingConvention, Endianness, PointerWidth, Triple};
/// A simple wrapper around `Triple` that provides an implementation of
/// `Default` which defaults to `Triple::host()`.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct DefaultToHost(pub Triple);
impl Default for DefaultToHost {
fn default() -> Self {
Self(Triple::host())
}
}
/// A simple wrapper around `Triple` that provides an implementation of
/// `Default` which defaults to `Triple::unknown()`.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct DefaultToUnknown(pub Triple);
impl Default for DefaultToUnknown {
fn default() -> Self {
Self(Triple::unknown())
}
}
// For some reason, the below `serde` impls don't work when they're in the
// `triple` module.
#[cfg(feature = "serde_support")]
impl serde::Serialize for Triple {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&self.to_string())
}
}
#[cfg(feature = "serde_support")]
impl<'de> serde::de::Deserialize<'de> for Triple {
fn deserialize<D: serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let s = String::deserialize(deserializer)?;
s.parse().map_err(serde::de::Error::custom)
}
}
#[cfg(feature = "serde_support")]
#[test]
fn test_serialize() {
let triples: Vec<Triple> = vec![
"x86_64-unknown-linux-gnu".parse().unwrap(),
"i686-pc-windows-gnu".parse().unwrap(),
];
let json = serde_json::to_string(&triples).unwrap();
assert_eq!(
json,
r#"["x86_64-unknown-linux-gnu","i686-pc-windows-gnu"]"#
);
}
#[cfg(feature = "serde_support")]
#[test]
fn test_deserialize() {
let triples: Vec<Triple> = vec![
"x86_64-unknown-linux-gnu".parse().unwrap(),
"i686-pc-windows-gnu".parse().unwrap(),
];
let vals: Vec<Triple> =
serde_json::from_str(r#"["x86_64-unknown-linux-gnu","i686-pc-windows-gnu"]"#).unwrap();
assert_eq!(vals, triples);
}
+34
View File
@@ -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 {}
File diff suppressed because it is too large. Load diff
+554
View File
@@ -0,0 +1,554 @@
// This file defines the `Triple` type and support code shared by all targets.
use crate::data_model::CDataModel;
use crate::parse_error::ParseError;
use crate::targets::{
default_binary_format, Architecture, ArmArchitecture, BinaryFormat, Environment,
OperatingSystem, Riscv32Architecture, Vendor,
};
#[cfg(not(feature = "std"))]
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.
#[cfg_attr(feature = "rust_1_40", non_exhaustive)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
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,
/// Apple Aarch64 platforms use their own variant of the common Aarch64
/// calling convention.
///
/// <https://developer.apple.com/documentation/xcode/writing_arm64_code_for_apple_platforms>
AppleAarch64,
}
/// An LLVM target "triple". Historically such things had three fields, though
/// they've added additional fields over time.
///
/// Note that `Triple` doesn't implement `Default` itself. If you want a type
/// which defaults to the host triple, or defaults to unknown-unknown-unknown,
/// use `DefaultToHost` or `DefaultToUnknown`, respectively.
#[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.
///
/// This function is aware of x32 and ilp32 ABIs on 64-bit architectures.
pub fn pointer_width(&self) -> Result<PointerWidth, ()> {
// Some ABIs have a different pointer width than the CPU architecture.
match self.environment {
Environment::Gnux32 | Environment::GnuIlp32 => return Ok(PointerWidth::U32),
_ => {}
}
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 {
os if os.is_like_darwin() => match self.architecture {
Architecture::Aarch64(_) => CallingConvention::AppleAarch64,
_ => CallingConvention::SystemV,
},
OperatingSystem::Aix
| OperatingSystem::Bitrig
| OperatingSystem::Cloudabi
| OperatingSystem::Dragonfly
| OperatingSystem::Freebsd
| OperatingSystem::Fuchsia
| OperatingSystem::Haiku
| OperatingSystem::Hermit
| OperatingSystem::Hurd
| OperatingSystem::L4re
| OperatingSystem::Linux
| 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(()),
})
}
/// The C data model for a given target. If the model is not known, returns `Err(())`.
pub fn data_model(&self) -> Result<CDataModel, ()> {
match self.pointer_width()? {
PointerWidth::U64 => {
if self.operating_system == OperatingSystem::Windows {
Ok(CDataModel::LLP64)
} else if self.default_calling_convention() == Ok(CallingConvention::SystemV)
|| self.architecture == Architecture::Wasm64
|| self.default_calling_convention() == Ok(CallingConvention::AppleAarch64)
{
Ok(CDataModel::LP64)
} else {
Err(())
}
}
PointerWidth::U32 => {
if self.operating_system == OperatingSystem::Windows
|| self.default_calling_convention() == Ok(CallingConvention::SystemV)
|| self.architecture == Architecture::Wasm32
{
Ok(CDataModel::ILP32)
} else {
Err(())
}
}
// TODO: on 16-bit machines there is usually a distinction
// between near-pointers and far-pointers.
// Additionally, code pointers sometimes have a different size than data pointers.
// We don't handle this case.
PointerWidth::U16 => Err(()),
}
}
/// Return a `Triple` with all unknown fields.
pub fn unknown() -> Self {
Self {
architecture: Architecture::Unknown,
vendor: Vendor::Unknown,
operating_system: OperatingSystem::Unknown,
environment: Environment::Unknown,
binary_format: BinaryFormat::Unknown,
}
}
}
impl fmt::Display for Triple {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(res) = self.special_case_display(f) {
return res;
}
let implied_binary_format = default_binary_format(&self);
write!(f, "{}", self.architecture)?;
if self.vendor == Vendor::Unknown
&& (self.environment != Environment::HermitKernel
&& self.environment != Environment::LinuxKernel)
&& ((self.operating_system == OperatingSystem::Linux
&& (self.environment == Environment::Android
|| self.environment == Environment::Androideabi
|| self.environment == Environment::Kernel))
|| self.operating_system == OperatingSystem::Wasi
|| self.operating_system == OperatingSystem::WasiP1
|| self.operating_system == OperatingSystem::WasiP2
|| (self.operating_system == OperatingSystem::None_
&& (self.architecture == Architecture::Arm(ArmArchitecture::Armv4t)
|| self.architecture == Architecture::Arm(ArmArchitecture::Armv5te)
|| self.architecture == Architecture::Arm(ArmArchitecture::Armebv7r)
|| self.architecture == Architecture::Arm(ArmArchitecture::Armv7a)
|| self.architecture == Architecture::Arm(ArmArchitecture::Armv7r)
|| self.architecture == Architecture::Arm(ArmArchitecture::Armv8r)
|| self.architecture == Architecture::Arm(ArmArchitecture::Thumbv4t)
|| self.architecture == Architecture::Arm(ArmArchitecture::Thumbv5te)
|| 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)))
{
// As a special case, omit the vendor for Android, 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 if self.architecture.is_clever() && self.operating_system == OperatingSystem::Unknown
{
write!(f, "-{}", self.vendor)?;
} else {
write!(f, "-{}-{}", self.vendor, self.operating_system)?;
}
match (&self.vendor, self.operating_system, self.environment) {
(Vendor::Nintendo, OperatingSystem::Horizon, Environment::Newlib)
| (Vendor::Espressif, OperatingSystem::Espidf, Environment::Newlib) => {
// The triple representations of these platforms don't have an environment field.
}
(_, _, Environment::Unknown) => {
// Don't print out the environment if it is unknown.
}
_ => {
write!(f, "-{}", self.environment)?;
}
}
if self.binary_format != implied_binary_format || show_binary_format_with_no_os(self) {
// As a special case, omit a non-default binary format for some
// targets which happen to exclude it.
write!(f, "-{}", self.binary_format)?;
}
Ok(())
}
}
fn show_binary_format_with_no_os(triple: &Triple) -> bool {
if triple.binary_format == BinaryFormat::Unknown {
return false;
}
#[cfg(feature = "arch_zkasm")]
{
if triple.architecture == Architecture::ZkAsm {
return false;
}
}
triple.environment != Environment::Eabi
&& triple.environment != Environment::Eabihf
&& triple.environment != Environment::Sgx
&& triple.architecture != Architecture::Avr
&& triple.architecture != Architecture::Wasm32
&& triple.architecture != Architecture::Wasm64
&& (triple.operating_system == OperatingSystem::None_
|| triple.operating_system == OperatingSystem::Unknown)
}
impl FromStr for Triple {
type Err = ParseError;
/// Parse a triple from an LLVM target triple.
///
/// This may also be able to parse `rustc` target triples, though support
/// for that is secondary.
fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Some(triple) = Triple::special_case_from_str(s) {
return Ok(triple);
}
let mut parts = s.split('-');
let mut result = Self::unknown();
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 !has_environment {
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)
}
}
}
impl Triple {
/// Handle special cases in the `Display` implementation.
fn special_case_display(&self, f: &mut fmt::Formatter) -> Option<fmt::Result> {
let res = match self {
Triple {
architecture: Architecture::Arm(ArmArchitecture::Armv6k),
vendor: Vendor::Nintendo,
operating_system: OperatingSystem::Horizon,
..
} => write!(f, "{}-{}-3ds", self.architecture, self.vendor),
Triple {
architecture: Architecture::Riscv32(Riscv32Architecture::Riscv32imc),
vendor: Vendor::Espressif,
operating_system: OperatingSystem::Espidf,
..
} => write!(f, "{}-esp-{}", self.architecture, self.operating_system),
_ => return None,
};
Some(res)
}
/// Handle special cases in the `FromStr` implementation.
fn special_case_from_str(s: &str) -> Option<Self> {
let mut triple = Triple::unknown();
match s {
"armv6k-nintendo-3ds" => {
triple.architecture = Architecture::Arm(ArmArchitecture::Armv6k);
triple.vendor = Vendor::Nintendo;
triple.operating_system = OperatingSystem::Horizon;
triple.environment = Environment::Newlib;
triple.binary_format = default_binary_format(&triple);
}
"riscv32imc-esp-espidf" => {
triple.architecture = Architecture::Riscv32(Riscv32Architecture::Riscv32imc);
triple.vendor = Vendor::Espressif;
triple.operating_system = OperatingSystem::Espidf;
triple.environment = Environment::Newlib;
triple.binary_format = default_binary_format(&triple);
}
_ => return None,
}
Some(triple)
}
}
/// 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) => {
<$crate::Triple as core::str::FromStr>::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-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::unknown())
);
assert_eq!(
Triple::from_str("unknown-unknown-unknown-unknown"),
Ok(Triple::unknown())
);
assert_eq!(
Triple::from_str("unknown-unknown-unknown-unknown-unknown"),
Ok(Triple::unknown())
);
}
#[test]
fn unknown_properties() {
assert_eq!(Triple::unknown().endianness(), Err(()));
assert_eq!(Triple::unknown().pointer_width(), Err(()));
assert_eq!(Triple::unknown().default_calling_convention(), Err(()));
}
#[test]
fn apple_calling_convention() {
for triple in &[
"aarch64-apple-darwin",
"aarch64-apple-ios",
"aarch64-apple-ios-macabi",
"aarch64-apple-tvos",
"aarch64-apple-watchos",
] {
let triple = Triple::from_str(triple).unwrap();
assert_eq!(
triple.default_calling_convention().unwrap(),
CallingConvention::AppleAarch64
);
assert_eq!(triple.data_model().unwrap(), CDataModel::LP64);
}
for triple in &["aarch64-linux-android", "x86_64-apple-ios"] {
assert_eq!(
Triple::from_str(triple)
.unwrap()
.default_calling_convention()
.unwrap(),
CallingConvention::SystemV
);
}
}
#[test]
fn p32_abi() {
// Test that special 32-bit pointer ABIs on 64-bit architectures are
// reported as having 32-bit pointers.
for triple in &[
"x86_64-unknown-linux-gnux32",
"aarch64_be-unknown-linux-gnu_ilp32",
"aarch64-unknown-linux-gnu_ilp32",
] {
assert_eq!(
Triple::from_str(triple).unwrap().pointer_width().unwrap(),
PointerWidth::U32
);
}
// Test that the corresponding ABIs have 64-bit pointers.
for triple in &[
"x86_64-unknown-linux-gnu",
"aarch64_be-unknown-linux-gnu",
"aarch64-unknown-linux-gnu",
] {
assert_eq!(
Triple::from_str(triple).unwrap().pointer_width().unwrap(),
PointerWidth::U64
);
}
}
}