//! Some stuff used by rustc that doesn't have many dependencies
//!
//! Originally extracted from rustc::back, which was nominally the
//! compiler 'backend', though LLVM is rustc's backend, so rustc_target
//! is really just odds-and-ends relating to code gen and linking.
//! This crate mostly exists to make rustc smaller, so we might put
//! more 'stuff' here in the future. It does not have a dependency on
//! LLVM.

// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(debug_closure_helpers))]
#![expect(internal_features)]
#![feature(iter_intersperse)]
#![feature(rustc_attrs)]
// tidy-alphabetical-end

use std::path::{Path, PathBuf};

pub mod asm;
pub mod callconv;
pub mod json;
pub mod spec;
pub mod target_features;

#[cfg(test)]
mod tests;

use rustc_abi::HashStableContext;

/// The name of rustc's own place to organize libraries.
///
/// Used to be `rustc`, now the default is `rustlib`.
const RUST_LIB_DIR: &str = "rustlib";

/// Returns a `rustlib` path for this particular target, relative to the provided sysroot.
///
/// For example: `target_sysroot_path("/usr", "x86_64-unknown-linux-gnu")` =>
/// `"lib*/rustlib/x86_64-unknown-linux-gnu"`.
pub fn relative_target_rustlib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
    let libdir = find_relative_libdir(sysroot);
    Path::new(libdir.as_ref()).join(RUST_LIB_DIR).join(target_triple)
}

/// The name of the directory rustc expects libraries to be located.
fn find_relative_libdir(sysroot: &Path) -> std::borrow::Cow<'static, str> {
    // FIXME: This is a quick hack to make the rustc binary able to locate
    // Rust libraries in Linux environments where libraries might be installed
    // to lib64/lib32. This would be more foolproof by basing the sysroot off
    // of the directory where `librustc_driver` is located, rather than
    // where the rustc binary is.
    // If --libdir is set during configuration to the value other than
    // "lib" (i.e., non-default), this value is used (see issue #16552).

    #[cfg(target_pointer_width = "64")]
    const PRIMARY_LIB_DIR: &str = "lib64";

    #[cfg(target_pointer_width = "32")]
    const PRIMARY_LIB_DIR: &str = "lib32";

    const SECONDARY_LIB_DIR: &str = "lib";

    match option_env!("CFG_LIBDIR_RELATIVE") {
        None | Some("lib") => {
            if sysroot.join(PRIMARY_LIB_DIR).join(RUST_LIB_DIR).exists() {
                PRIMARY_LIB_DIR.into()
            } else {
                SECONDARY_LIB_DIR.into()
            }
        }
        Some(libdir) => libdir.into(),
    }
}

macro_rules! target_spec_enum {
    (
        $( #[$attr:meta] )*
        pub enum $Name:ident {
            $(
                $( #[$variant_attr:meta] )*
                $Variant:ident = $string:literal,
            )*
        }
        parse_error_type = $parse_error_type:literal;
    ) => {
        $( #[$attr] )*
        #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
        #[derive(schemars::JsonSchema)]
        pub enum $Name {
            $(
                $( #[$variant_attr] )*
                #[serde(rename = $string)] // for JSON schema generation only
                $Variant,
            )*
        }

        impl FromStr for $Name {
            type Err = String;

            fn from_str(s: &str) -> Result<Self, Self::Err> {
                Ok(match s {
                    $( $string => Self::$Variant, )*
                    _ => {
                        let all = [$( concat!("'", $string, "'") ),*].join(", ");
                        return Err(format!("invalid {}: '{s}'. allowed values: {all}", $parse_error_type));
                    }
                })
            }
        }

        impl $Name {
            pub const ALL: &'static [$Name] = &[ $( $Name::$Variant, )* ];
            pub fn desc(&self) -> &'static str {
                match self {
                    $( Self::$Variant => $string, )*
                }
            }
        }

        crate::target_spec_enum!(@common_impls $Name);
    };

    (
        $( #[$attr:meta] )*
        pub enum $Name:ident {
            $(
                $( #[$variant_attr:meta] )*
                $Variant:ident = $string:literal,
            )*
        }
        $( #[$other_variant_attr:meta] )*
        other_variant = $OtherVariant:ident;
    ) => {
        $( #[$attr] )*
        #[derive(Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
        pub enum $Name {
            $(
                $( #[$variant_attr:meta] )*
                $Variant,
            )*
            /// The vast majority of the time, the compiler deals with a fixed
            /// set of values, so it is convenient for them to be represented in
            /// an enum. However, it is possible to have arbitrary values in a
            /// target JSON file (which can be parsed when `--target` is
            /// specified). This might occur, for example, for an out-of-tree
            /// codegen backend that supports a value (e.g. architecture or OS)
            /// that rustc currently doesn't know about. This variant exists as
            /// an escape hatch for such cases.
            $( #[$other_variant_attr] )*
            $OtherVariant(crate::spec::StaticCow<str>),
        }

        impl schemars::JsonSchema for $Name {
            fn schema_name() -> std::borrow::Cow<'static, str> {
                std::borrow::Cow::Borrowed(stringify!($Name))
            }

            fn json_schema(_: &mut schemars::SchemaGenerator) -> schemars::Schema {
                schemars::json_schema!({
                    "type": "string"
                })
            }
        }

        impl FromStr for $Name {
            type Err = core::convert::Infallible;

            fn from_str(s: &str) -> Result<Self, Self::Err> {
                Ok(match s {
                    $( $string => Self::$Variant, )*
                    _ => Self::$OtherVariant(s.to_owned().into()),
                })
            }
        }

        impl $Name {
            pub fn desc(&self) -> &str {
                match self {
                    $( Self::$Variant => $string, )*
                    Self::$OtherVariant(name) => name.as_ref(),
                }
            }
        }

        crate::target_spec_enum!(@common_impls $Name);
    };

    (@common_impls $Name:ident) => {
        impl crate::json::ToJson for $Name {
            fn to_json(&self) -> crate::json::Json {
                self.desc().to_json()
            }
        }

        crate::json::serde_deserialize_from_str!($Name);


        impl std::fmt::Display for $Name {
            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                f.write_str(self.desc())
            }
        }
    };
}
use target_spec_enum;
