// tidy-alphabetical-start
#![feature(deref_patterns)]
#![feature(file_buffered)]
#![feature(negative_impls)]
#![feature(option_into_flat_iter)]
#![feature(trait_alias)]
#![feature(try_blocks)]
#![recursion_limit = "256"]
// tidy-alphabetical-end
#![cfg_attr(bootstrap, feature(string_from_utf8_lossy_owned))]

//! This crate contains codegen code that is used by all codegen backends (LLVM and others).
//! The backend-agnostic functions of this crate use functions defined in various traits that
//! have to be implemented by each backend.

use std::collections::BTreeSet;
use std::io;
use std::path::{Path, PathBuf};
use std::sync::Arc;

use rustc_abi::Size;
use rustc_crate_store::{self as cstore, CrateSource};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_hir::CRATE_HIR_ID;
use rustc_hir::attrs::{CfgEntry, NativeLibKind, WindowsSubsystemKind};
use rustc_hir::def_id::CrateNum;
use rustc_lint_defs::builtin::LINKER_INFO;
use rustc_macros::{Decodable, Encodable};
use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::lint::StableLevelSpec;
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
use rustc_middle::middle::dependency_format::Dependencies;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
use rustc_middle::ty::TyCtxt;
use rustc_middle::util::Providers;
use rustc_serialize::opaque::{FileEncoder, MemDecoder};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_session::Session;
use rustc_session::config::{CrateType, OutputFilenames, OutputType};
use rustc_session::lint::builtin::LINKER_MESSAGES;
use rustc_span::{Span, Symbol};

pub mod assert_module_sources;
pub mod back;
pub mod base;
pub mod codegen_attrs;
pub mod common;
pub mod debuginfo;
pub mod diagnostics;
pub mod meth;
pub mod mir;
pub mod mono_item;
pub mod size_of_val;
pub mod target_features;
pub mod traits;

pub struct ModuleCodegen<M> {
    /// The name of the module. When the crate may be saved between
    /// compilations, incremental compilation requires that name be
    /// unique amongst **all** crates. Therefore, it should contain
    /// something unique to this crate (e.g., a module path) as well
    /// as the crate name and disambiguator.
    /// We currently generate these names via CodegenUnit::build_cgu_name().
    pub name: String,
    pub module_llvm: M,
    pub kind: ModuleKind,
    /// Saving the ThinLTO buffer for embedding in the object file.
    pub thin_lto_buffer: Option<Vec<u8>>,
}

impl<M> ModuleCodegen<M> {
    pub fn new_regular(name: impl Into<String>, module: M) -> Self {
        Self {
            name: name.into(),
            module_llvm: module,
            kind: ModuleKind::Regular,
            thin_lto_buffer: None,
        }
    }

    pub fn new_allocator(name: impl Into<String>, module: M) -> Self {
        Self {
            name: name.into(),
            module_llvm: module,
            kind: ModuleKind::Allocator,
            thin_lto_buffer: None,
        }
    }

    pub fn into_compiled_module(
        self,
        emit_obj: bool,
        emit_dwarf_obj: bool,
        emit_bc: bool,
        emit_asm: bool,
        emit_ir: bool,
        outputs: &OutputFilenames,
    ) -> CompiledModule {
        let object = emit_obj.then(|| outputs.temp_path_for_cgu(OutputType::Object, &self.name));
        let dwarf_object = emit_dwarf_obj.then(|| outputs.temp_path_dwo_for_cgu(&self.name));
        let bytecode = emit_bc.then(|| outputs.temp_path_for_cgu(OutputType::Bitcode, &self.name));
        let assembly =
            emit_asm.then(|| outputs.temp_path_for_cgu(OutputType::Assembly, &self.name));
        let llvm_ir =
            emit_ir.then(|| outputs.temp_path_for_cgu(OutputType::LlvmAssembly, &self.name));

        CompiledModule {
            name: self.name,
            kind: self.kind,
            object,
            global_asm_object: None,
            dwarf_object,
            bytecode,
            assembly,
            llvm_ir,
            links_from_incr_cache: Vec::new(),
        }
    }
}

#[derive(Debug, Encodable, Decodable)]
pub struct CompiledModule {
    pub name: String,
    pub kind: ModuleKind,
    pub object: Option<PathBuf>,
    pub global_asm_object: Option<PathBuf>,
    pub dwarf_object: Option<PathBuf>,
    pub bytecode: Option<PathBuf>,
    pub assembly: Option<PathBuf>, // --emit=asm
    pub llvm_ir: Option<PathBuf>,  // --emit=llvm-ir, llvm-bc is in bytecode
    pub links_from_incr_cache: Vec<PathBuf>,
}

impl CompiledModule {
    /// Call `emit` function with every artifact type currently compiled
    pub fn for_each_output(&self, mut emit: impl FnMut(&Path, OutputType)) {
        if let Some(path) = self.object.as_deref() {
            emit(path, OutputType::Object);
        }
        if let Some(path) = self.bytecode.as_deref() {
            emit(path, OutputType::Bitcode);
        }
        if let Some(path) = self.llvm_ir.as_deref() {
            emit(path, OutputType::LlvmAssembly);
        }
        if let Some(path) = self.assembly.as_deref() {
            emit(path, OutputType::Assembly);
        }
    }
}

pub(crate) struct CachedModuleCodegen {
    pub name: String,
    pub source: WorkProduct,
}

#[derive(Copy, Clone, Debug, PartialEq, Encodable, Decodable)]
pub enum ModuleKind {
    Regular,
    Allocator,
}

bitflags::bitflags! {
    /// This previously had an `UNALIGNED` variant, but that should never be done via flags.
    /// If you want something to be unaligned, see [`mir::place::PlaceRef::unaligned`].
    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
    pub struct MemFlags: u8 {
        const VOLATILE = 1 << 0;
        const NONTEMPORAL = 1 << 1;
        /// Indicates that writing through the stored pointer is undefined behavior.
        /// Only valid on stores of pointers, or pairs where the first element is a pointer.
        /// In the latter case, the flag only applies to the first element of the pair.
        const CAPTURES_READ_ONLY = 1 << 3;
    }
}

#[derive(Debug, Copy, Clone)]
pub struct RetagInfo<V> {
    /// The size of the initial range within the allocation that is
    /// associated with the permission created by the retag.
    pub size: Size,
    /// Encoded type information used to determine the kind of permission
    /// created by the retag.
    pub flags: RetagFlags,
    /// A pointer to a constant array of (offset, size) pairs describing
    /// the ranges covered by `UnsafeCell` within the pointee type.
    pub im_layout: V,
    /// A pointer to a constant array of (offset, size) pairs describing
    /// the ranges covered by `UnsafePinned` within the pointee type.
    pub pin_layout: V,
}

bitflags::bitflags! {
    #[repr(C)]
    #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
    pub struct RetagFlags: u8 {
        /// If this is a function-entry retag.
        const IS_PROTECTED = 1 << 0;
        /// If this is a mutable reference or a `Box`.
        const IS_MUTABLE = 1 << 1;
        /// If this is a `Box`.
        const IS_BOX = 1 << 2;
        /// If the pointee type is `Freeze`
        const IS_FREEZE = 1 << 3;
    }
}

// This is the same as `rustc_crate_store::NativeLib`, except:
// - (important) the `foreign_module` field is missing, because it contains a `DefId`, which can't
//   be encoded with `FileEncoder`.
// - (less important) the `verbatim` field is a `bool` rather than an `Option<bool>`, because here
//   we can treat `false` and `absent` the same.
#[derive(Clone, Debug, Encodable, Decodable)]
pub struct NativeLib {
    pub kind: NativeLibKind,
    pub name: Symbol,
    pub cfg: Option<CfgEntry>,
    pub verbatim: bool,
    pub dll_imports: Vec<cstore::DllImport>,
}

impl From<&cstore::NativeLib> for NativeLib {
    fn from(lib: &cstore::NativeLib) -> Self {
        NativeLib {
            kind: lib.kind,
            name: lib.name,
            cfg: lib.cfg.clone(),
            verbatim: lib.verbatim.unwrap_or(false),
            dll_imports: lib.dll_imports.clone(),
        }
    }
}

/// A symbol to make visible from a linked artifact.
#[derive(Clone, Debug, Encodable, Decodable)]
pub struct SymbolExport {
    /// Name to make visible from the linked artifact.
    pub name: String,
    /// Kind of symbol, used for target-specific export directives and name decoration.
    pub kind: SymbolExportKind,
    /// Name of the symbol as seen by the linker, when it differs from `name`.
    pub link_name: Option<String>,
}

impl SymbolExport {
    pub fn new(name: String, kind: SymbolExportKind) -> SymbolExport {
        SymbolExport { name, kind, link_name: None }
    }

    pub fn with_link_name(name: String, kind: SymbolExportKind, link_name: String) -> SymbolExport {
        let link_name = if link_name == name { None } else { Some(link_name) };
        SymbolExport { name, kind, link_name }
    }
}

#[derive(Clone, Debug, Encodable, Decodable)]
pub struct EiiLinkageImplInfo {
    pub span: Span,
    pub impl_crate: CrateNum,
}

#[derive(Clone, Debug, Encodable, Decodable)]
pub struct EiiLinkageInfo {
    pub name: Symbol,
    pub impls: Vec<EiiLinkageImplInfo>,
    pub default_impl: Option<EiiLinkageImplInfo>,
}

/// Misc info we load from metadata to persist beyond the tcx.
///
/// Note: though `CrateNum` is only meaningful within the same tcx, information within `CrateInfo`
/// is self-contained. `CrateNum` can be viewed as a unique identifier within a `CrateInfo`, where
/// `used_crate_source` contains all `CrateSource` of the dependents, and maintains a mapping from
/// identifiers (`CrateNum`) to `CrateSource`. The other fields map `CrateNum` to the crate's own
/// additional properties, so that effectively we can retrieve each dependent crate's `CrateSource`
/// and the corresponding properties without referencing information outside of a `CrateInfo`.
// rustc_codegen_cranelift needs a Clone impl for its jit mode, which isn't tested in rust CI
#[derive(Clone, Debug, Encodable, Decodable)]
pub struct CrateInfo {
    pub target_cpu: String,
    pub target_features: Vec<String>,
    pub crate_types: Vec<CrateType>,
    pub exported_symbols: UnordMap<CrateType, Vec<SymbolExport>>,
    pub linked_symbols: FxIndexMap<CrateType, Vec<(String, SymbolExportKind)>>,
    pub local_crate_name: Symbol,
    pub compiler_builtins: Option<CrateNum>,
    pub profiler_runtime: Option<CrateNum>,
    pub is_no_builtins: FxHashSet<CrateNum>,
    pub native_libraries: FxIndexMap<CrateNum, Vec<NativeLib>>,
    pub crate_name: UnordMap<CrateNum, Symbol>,
    pub used_libraries: Vec<NativeLib>,
    pub used_crate_source: UnordMap<CrateNum, Arc<CrateSource>>,
    pub used_crates: Vec<CrateNum>,
    pub dependency_formats: Arc<Dependencies>,
    /// EII implementations used by the link-time duplicate check, so `-Zno-link` can serialize the data needed by a
    /// later `-Zlink-only` invocation.
    pub eii_linkage: Vec<EiiLinkageInfo>,
    pub windows_subsystem: Option<WindowsSubsystemKind>,
    pub natvis_debugger_visualizers: BTreeSet<DebuggerVisualizerFile>,
    pub lint_level_specs: CodegenLintLevelSpecs,
    pub metadata_symbol: String,
    pub symbol_rename_suffix: String,
    pub each_linked_rlib_file_for_lto: Vec<PathBuf>,
    pub exported_symbols_for_lto: Vec<String>,
}

/// Target-specific options that get set in `sess`/`cfg(...)`.
///
/// RUSTC_SPECIFIC_FEATURES should be skipped here, those are handled outside codegen.
pub struct TargetConfig {
    /// Options to be set in `sess.internal_target_features`.
    pub internal_target_features: UnordSet<Symbol>,
    /// Option for `cfg(target_has_reliable_f16)`, true if `f16` basic arithmetic works.
    pub has_reliable_f16: bool,
    /// Option for `cfg(target_has_reliable_f16_math)`, true if `f16` math calls work.
    pub has_reliable_f16_math: bool,
    /// Option for `cfg(target_has_reliable_f128)`, true if `f128` basic arithmetic works.
    pub has_reliable_f128: bool,
    /// Option for `cfg(target_has_reliable_f128_math)`, true if `f128` math calls work.
    pub has_reliable_f128_math: bool,
}

#[derive(Encodable, Decodable)]
pub struct CompiledModules {
    pub modules: Vec<CompiledModule>,
    pub allocator_module: Option<CompiledModule>,
}

pub enum CodegenError {
    WrongFileType,
    EmptyVersionNumber,
    EncodingVersionMismatch { version_array: String, rlink_version: u32 },
    RustcVersionMismatch { rustc_version: String },
    CorruptFile,
}

pub fn provide(providers: &mut Providers) {
    crate::back::symbol_export::provide(providers);
    crate::base::provide(&mut providers.queries);
    crate::target_features::provide(&mut providers.queries);
    crate::codegen_attrs::provide(&mut providers.queries);
    providers.queries.global_backend_features = |_tcx: TyCtxt<'_>, ()| vec![];
}

const RLINK_VERSION: u32 = 1;
const RLINK_MAGIC: &[u8] = b"rustlink";

impl CompiledModules {
    pub fn serialize_rlink(
        sess: &Session,
        rlink_file: &Path,
        compiled_modules: &CompiledModules,
        crate_info: &CrateInfo,
        metadata: &EncodedMetadata,
        outputs: &OutputFilenames,
    ) -> Result<usize, io::Error> {
        let mut encoder = FileEncoder::new(rlink_file)?;
        encoder.emit_raw_bytes(RLINK_MAGIC);
        // `emit_raw_bytes` is used to make sure that the version representation does not depend on
        // Encoder's inner representation of `u32`.
        encoder.emit_raw_bytes(&RLINK_VERSION.to_be_bytes());
        encoder.emit_str(sess.cfg_version);
        Encodable::encode(compiled_modules, &mut encoder);
        Encodable::encode(crate_info, &mut encoder);
        Encodable::encode(metadata, &mut encoder);
        Encodable::encode(outputs, &mut encoder);
        encoder.finish().map_err(|(_path, err)| err)
    }

    pub fn deserialize_rlink(
        sess: &Session,
        data: Vec<u8>,
    ) -> Result<(Self, CrateInfo, EncodedMetadata, OutputFilenames), CodegenError> {
        // The Decodable machinery is not used here because it panics if the input data is invalid
        // and because its internal representation may change.
        if !data.starts_with(RLINK_MAGIC) {
            return Err(CodegenError::WrongFileType);
        }
        let data = &data[RLINK_MAGIC.len()..];
        if data.len() < 4 {
            return Err(CodegenError::EmptyVersionNumber);
        }

        let mut version_array: [u8; 4] = Default::default();
        version_array.copy_from_slice(&data[..4]);
        if u32::from_be_bytes(version_array) != RLINK_VERSION {
            return Err(CodegenError::EncodingVersionMismatch {
                version_array: String::from_utf8_lossy(&version_array).to_string(),
                rlink_version: RLINK_VERSION,
            });
        }

        let Ok(mut decoder) = MemDecoder::new(&data[4..], 0) else {
            return Err(CodegenError::CorruptFile);
        };
        let rustc_version = decoder.read_str();
        if rustc_version != sess.cfg_version {
            return Err(CodegenError::RustcVersionMismatch {
                rustc_version: rustc_version.to_string(),
            });
        }

        let compiled_modules = CompiledModules::decode(&mut decoder);
        let crate_info = CrateInfo::decode(&mut decoder);
        let metadata = EncodedMetadata::decode(&mut decoder);
        let outputs = OutputFilenames::decode(&mut decoder);
        Ok((compiled_modules, crate_info, metadata, outputs))
    }
}

/// A list of lint levels used in codegen.
///
/// When using `-Z link-only`, we don't have access to the tcx and must work
/// solely from the `.rlink` file. `Lint`s are defined too early to be encodeable.
/// Instead, encode exactly the information we need.
#[derive(Copy, Clone, Debug, Encodable, Decodable)]
pub struct CodegenLintLevelSpecs {
    linker_messages: StableLevelSpec,
    linker_info: StableLevelSpec,
}

impl CodegenLintLevelSpecs {
    pub fn from_tcx(tcx: TyCtxt<'_>) -> Self {
        Self {
            linker_messages: tcx.lint_level_spec_at_node(LINKER_MESSAGES, CRATE_HIR_ID),
            linker_info: tcx.lint_level_spec_at_node(LINKER_INFO, CRATE_HIR_ID),
        }
    }
}
