use std::borrow::{Borrow, Cow};
use std::cell::{Cell, RefCell};
use std::ffi::{CStr, c_char, c_uint};
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::str;

use rustc_abi::{HasDataLayout, Size, TargetDataLayout, VariantIdx};
use rustc_codegen_ssa::back::versioned_llvm_target;
use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh};
use rustc_codegen_ssa::errors as ssa_errors;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, ToBaseN};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::middle::codegen_fn_attrs::PatchableFunctionEntry;
use rustc_middle::mono::CodegenUnit;
use rustc_middle::ty::layout::{
    FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
};
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_session::Session;
use rustc_session::config::{
    BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, FunctionReturn, PAuthKey, PacRet,
};
use rustc_span::{DUMMY_SP, Span, Spanned, Symbol};
use rustc_symbol_mangling::mangle_internal_symbol;
use rustc_target::spec::{
    Arch, CfgAbi, Env, HasTargetSpec, Os, RelocModel, SmallDataThresholdSupport, Target, TlsModel,
};
use smallvec::SmallVec;

use crate::abi::to_llvm_calling_convention;
use crate::back::write::to_llvm_code_model;
use crate::builder::gpu_offload::{OffloadGlobals, OffloadKernelGlobals};
use crate::callee::get_fn;
use crate::debuginfo::metadata::apply_vcall_visibility_metadata;
use crate::llvm::{self, Metadata, MetadataKindId, Module, Type, Value};
use crate::{attributes, common, coverageinfo, debuginfo, llvm_util};

/// `TyCtxt` (and related cache datastructures) can't be move between threads.
/// However, there are various cx related functions which we want to be available to the builder and
/// other compiler pieces. Here we define a small subset which has enough information and can be
/// moved around more freely.
pub(crate) struct SCx<'ll> {
    pub llmod: &'ll llvm::Module,
    pub llcx: &'ll llvm::Context,
    pub isize_ty: &'ll Type,
}

impl<'ll> Borrow<SCx<'ll>> for FullCx<'ll, '_> {
    fn borrow(&self) -> &SCx<'ll> {
        &self.scx
    }
}

impl<'ll, 'tcx> Deref for FullCx<'ll, 'tcx> {
    type Target = SimpleCx<'ll>;

    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.scx
    }
}

pub(crate) struct GenericCx<'ll, T: Borrow<SCx<'ll>>>(T, PhantomData<SCx<'ll>>);

impl<'ll, T: Borrow<SCx<'ll>>> Deref for GenericCx<'ll, T> {
    type Target = T;

    #[inline]
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<'ll, T: Borrow<SCx<'ll>>> DerefMut for GenericCx<'ll, T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

pub(crate) type SimpleCx<'ll> = GenericCx<'ll, SCx<'ll>>;

/// There is one `CodegenCx` per codegen unit. Each one has its own LLVM
/// `llvm::Context` so that several codegen units may be processed in parallel.
/// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`.
pub(crate) type CodegenCx<'ll, 'tcx> = GenericCx<'ll, FullCx<'ll, 'tcx>>;

pub(crate) struct FullCx<'ll, 'tcx> {
    pub tcx: TyCtxt<'tcx>,
    pub scx: SimpleCx<'ll>,
    pub use_dll_storage_attrs: bool,
    pub tls_model: llvm::ThreadLocalMode,

    pub codegen_unit: &'tcx CodegenUnit<'tcx>,

    /// Cache instances of monomorphic and polymorphic items
    pub instances: RefCell<FxHashMap<Instance<'tcx>, &'ll Value>>,
    /// Cache instances of intrinsics
    pub intrinsic_instances: RefCell<FxHashMap<Instance<'tcx>, &'ll Value>>,
    /// Cache generated vtables
    pub vtables: RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), &'ll Value>>,
    /// Cache of constant strings,
    pub const_str_cache: RefCell<FxHashMap<String, &'ll Value>>,

    /// Cache of emitted const globals (value -> global)
    pub const_globals: RefCell<FxHashMap<&'ll Value, &'ll Value>>,

    /// List of globals for static variables which need to be passed to the
    /// LLVM function ReplaceAllUsesWith (RAUW) when codegen is complete.
    /// (We have to make sure we don't invalidate any Values referring
    /// to constants.)
    pub statics_to_rauw: RefCell<Vec<(&'ll Value, &'ll Value)>>,

    /// Statics that will be placed in the llvm.used variable
    /// See <https://llvm.org/docs/LangRef.html#the-llvm-used-global-variable> for details
    pub used_statics: Vec<&'ll Value>,

    /// Statics that will be placed in the llvm.compiler.used variable
    /// See <https://llvm.org/docs/LangRef.html#the-llvm-compiler-used-global-variable> for details
    pub compiler_used_statics: RefCell<Vec<&'ll Value>>,

    /// Mapping of non-scalar types to llvm types.
    pub type_lowering: RefCell<FxHashMap<(Ty<'tcx>, Option<VariantIdx>), &'ll Type>>,

    /// Mapping of scalar types to llvm types.
    pub scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, &'ll Type>>,

    /// Extra per-CGU codegen state needed when coverage instrumentation is enabled.
    pub coverage_cx: Option<coverageinfo::CguCoverageContext<'ll, 'tcx>>,
    pub dbg_cx: Option<debuginfo::CodegenUnitDebugContext<'ll, 'tcx>>,

    eh_personality: Cell<Option<&'ll Value>>,
    eh_catch_typeinfo: Cell<Option<&'ll Value>>,
    pub rust_try_fn: Cell<Option<(&'ll Type, &'ll Value)>>,

    intrinsics:
        RefCell<FxHashMap<(Cow<'static, str>, SmallVec<[&'ll Type; 2]>), (&'ll Type, &'ll Value)>>,

    /// A counter that is used for generating local symbol names
    local_gen_sym_counter: Cell<usize>,

    /// `codegen_static` will sometimes create a second global variable with a
    /// different type and clear the symbol name of the original global.
    /// `global_asm!` needs to be able to find this new global so that it can
    /// compute the correct mangled symbol name to insert into the asm.
    pub renamed_statics: RefCell<FxHashMap<DefId, &'ll Value>>,

    /// Cached Objective-C class type
    pub objc_class_t: Cell<Option<&'ll Type>>,

    /// Cache of Objective-C class references
    pub objc_classrefs: RefCell<FxHashMap<Symbol, &'ll Value>>,

    /// Cache of Objective-C selector references
    pub objc_selrefs: RefCell<FxHashMap<Symbol, &'ll Value>>,

    /// Globals shared by the offloading runtime
    pub offload_globals: RefCell<Option<OffloadGlobals<'ll>>>,

    /// Cache of kernel-specific globals
    pub offload_kernel_cache: RefCell<FxHashMap<String, OffloadKernelGlobals<'ll>>>,
}

fn to_llvm_tls_model(tls_model: TlsModel) -> llvm::ThreadLocalMode {
    match tls_model {
        TlsModel::GeneralDynamic => llvm::ThreadLocalMode::GeneralDynamic,
        TlsModel::LocalDynamic => llvm::ThreadLocalMode::LocalDynamic,
        TlsModel::InitialExec => llvm::ThreadLocalMode::InitialExec,
        TlsModel::LocalExec => llvm::ThreadLocalMode::LocalExec,
        TlsModel::Emulated => llvm::ThreadLocalMode::GeneralDynamic,
    }
}

pub(crate) unsafe fn create_module<'ll>(
    tcx: TyCtxt<'_>,
    llcx: &'ll llvm::Context,
    mod_name: &str,
) -> &'ll llvm::Module {
    let sess = tcx.sess;
    let mod_name = SmallCStr::new(mod_name);
    let llmod = unsafe { llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx) };

    let cx = SimpleCx::new(llmod, llcx, tcx.data_layout.pointer_size());

    let mut target_data_layout = sess.target.data_layout.to_string();
    let llvm_version = llvm_util::get_version();

    if llvm_version < (22, 0, 0) {
        if sess.target.arch == Arch::Avr {
            // LLVM 22.0 updated the default layout on avr: https://github.com/llvm/llvm-project/pull/153010
            target_data_layout = target_data_layout.replace("n8:16", "n8")
        }
        if sess.target.arch == Arch::Nvptx64 {
            // LLVM 22 updated the NVPTX layout to indicate 256-bit vector load/store: https://github.com/llvm/llvm-project/pull/155198
            target_data_layout = target_data_layout.replace("-i256:256", "");
        }
        if sess.target.arch == Arch::PowerPC64 {
            // LLVM 22 updated the ABI alignment for double on AIX: https://github.com/llvm/llvm-project/pull/144673
            target_data_layout = target_data_layout.replace("-f64:32:64", "");
        }
        if sess.target.arch == Arch::AmdGpu {
            // LLVM 22 specified ELF mangling in the amdgpu data layout:
            // https://github.com/llvm/llvm-project/pull/163011
            target_data_layout = target_data_layout.replace("-m:e", "");
        }
    }
    if llvm_version < (23, 0, 0) {
        if sess.target.arch == Arch::S390x {
            // LLVM 23 updated the s390x layout to specify the stack alignment: https://github.com/llvm/llvm-project/pull/176041
            target_data_layout = target_data_layout.replace("-S64", "");
        }
    }

    // Ensure the data-layout values hardcoded remain the defaults.
    {
        let tm = crate::back::write::create_informational_target_machine(sess, false);
        unsafe {
            llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm.raw());
        }

        let llvm_data_layout = unsafe { llvm::LLVMGetDataLayoutStr(llmod) };
        let llvm_data_layout =
            str::from_utf8(unsafe { CStr::from_ptr(llvm_data_layout) }.to_bytes())
                .expect("got a non-UTF8 data-layout from LLVM");

        if target_data_layout != llvm_data_layout {
            tcx.dcx().emit_err(crate::errors::MismatchedDataLayout {
                rustc_target: sess.opts.target_triple.to_string().as_str(),
                rustc_layout: target_data_layout.as_str(),
                llvm_target: sess.target.llvm_target.borrow(),
                llvm_layout: llvm_data_layout,
            });
        }
    }

    let data_layout = SmallCStr::new(&target_data_layout);
    unsafe {
        llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
    }

    let llvm_target = SmallCStr::new(&versioned_llvm_target(sess));
    unsafe {
        llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
    }

    let reloc_model = sess.relocation_model();
    if matches!(reloc_model, RelocModel::Pic | RelocModel::Pie) {
        unsafe {
            llvm::LLVMRustSetModulePICLevel(llmod);
        }
        // PIE is potentially more effective than PIC, but can only be used in executables.
        // If all our outputs are executables, then we can relax PIC to PIE.
        if reloc_model == RelocModel::Pie
            || tcx.crate_types().iter().all(|ty| *ty == CrateType::Executable)
        {
            unsafe {
                llvm::LLVMRustSetModulePIELevel(llmod);
            }
        }
    }

    // Linking object files with different code models is undefined behavior
    // because the compiler would have to generate additional code (to span
    // longer jumps) if a larger code model is used with a smaller one.
    //
    // See https://reviews.llvm.org/D52322 and https://reviews.llvm.org/D52323.
    unsafe {
        llvm::LLVMRustSetModuleCodeModel(llmod, to_llvm_code_model(sess.code_model()));
    }

    // If skipping the PLT is enabled, we need to add some module metadata
    // to ensure intrinsic calls don't use it.
    if !sess.needs_plt() {
        llvm::add_module_flag_u32(llmod, llvm::ModuleFlagMergeBehavior::Warning, "RtLibUseGOT", 1);
    }

    // Enable canonical jump tables if CFI is enabled. (See https://reviews.llvm.org/D65629.)
    if sess.is_sanitizer_cfi_canonical_jump_tables_enabled() && sess.is_sanitizer_cfi_enabled() {
        llvm::add_module_flag_u32(
            llmod,
            llvm::ModuleFlagMergeBehavior::Override,
            "CFI Canonical Jump Tables",
            1,
        );
    }

    // If we're normalizing integers with CFI, ensure LLVM generated functions do the same.
    // See https://github.com/llvm/llvm-project/pull/104826
    if sess.is_sanitizer_cfi_normalize_integers_enabled() {
        llvm::add_module_flag_u32(
            llmod,
            llvm::ModuleFlagMergeBehavior::Override,
            "cfi-normalize-integers",
            1,
        );
    }

    // Enable LTO unit splitting if specified or if CFI is enabled. (See
    // https://reviews.llvm.org/D53891.)
    if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
        llvm::add_module_flag_u32(
            llmod,
            llvm::ModuleFlagMergeBehavior::Override,
            "EnableSplitLTOUnit",
            1,
        );
    }

    // Add "kcfi" module flag if KCFI is enabled. (See https://reviews.llvm.org/D119296.)
    if sess.is_sanitizer_kcfi_enabled() {
        llvm::add_module_flag_u32(llmod, llvm::ModuleFlagMergeBehavior::Override, "kcfi", 1);

        // Add "kcfi-offset" module flag with -Z patchable-function-entry (See
        // https://reviews.llvm.org/D141172).
        let pfe =
            PatchableFunctionEntry::from_config(sess.opts.unstable_opts.patchable_function_entry);
        if pfe.prefix() > 0 {
            llvm::add_module_flag_u32(
                llmod,
                llvm::ModuleFlagMergeBehavior::Override,
                "kcfi-offset",
                pfe.prefix().into(),
            );
        }

        // Add "kcfi-arity" module flag if KCFI arity indicator is enabled. (See
        // https://github.com/llvm/llvm-project/pull/117121.)
        if sess.is_sanitizer_kcfi_arity_enabled() {
            llvm::add_module_flag_u32(
                llmod,
                llvm::ModuleFlagMergeBehavior::Override,
                "kcfi-arity",
                1,
            );
        }
    }

    // Control Flow Guard is currently only supported by MSVC and LLVM on Windows.
    if sess.target.is_like_msvc
        || (sess.target.options.os == Os::Windows
            && sess.target.options.env == Env::Gnu
            && sess.target.options.cfg_abi == CfgAbi::Llvm)
    {
        match sess.opts.cg.control_flow_guard {
            CFGuard::Disabled => {}
            CFGuard::NoChecks => {
                // Set `cfguard=1` module flag to emit metadata only.
                llvm::add_module_flag_u32(
                    llmod,
                    llvm::ModuleFlagMergeBehavior::Warning,
                    "cfguard",
                    1,
                );
            }
            CFGuard::Checks => {
                // Set `cfguard=2` module flag to emit metadata and checks.
                llvm::add_module_flag_u32(
                    llmod,
                    llvm::ModuleFlagMergeBehavior::Warning,
                    "cfguard",
                    2,
                );
            }
        }
    }

    if let Some(regparm_count) = sess.opts.unstable_opts.regparm {
        llvm::add_module_flag_u32(
            llmod,
            llvm::ModuleFlagMergeBehavior::Error,
            "NumRegisterParameters",
            regparm_count,
        );
    }

    if let Some(BranchProtection { bti, pac_ret, gcs }) = sess.opts.unstable_opts.branch_protection
    {
        if sess.target.arch == Arch::AArch64 {
            llvm::add_module_flag_u32(
                llmod,
                llvm::ModuleFlagMergeBehavior::Min,
                "branch-target-enforcement",
                bti.into(),
            );
            llvm::add_module_flag_u32(
                llmod,
                llvm::ModuleFlagMergeBehavior::Min,
                "sign-return-address",
                pac_ret.is_some().into(),
            );
            let pac_opts = pac_ret.unwrap_or(PacRet { leaf: false, pc: false, key: PAuthKey::A });
            llvm::add_module_flag_u32(
                llmod,
                llvm::ModuleFlagMergeBehavior::Min,
                "branch-protection-pauth-lr",
                pac_opts.pc.into(),
            );
            llvm::add_module_flag_u32(
                llmod,
                llvm::ModuleFlagMergeBehavior::Min,
                "sign-return-address-all",
                pac_opts.leaf.into(),
            );
            llvm::add_module_flag_u32(
                llmod,
                llvm::ModuleFlagMergeBehavior::Min,
                "sign-return-address-with-bkey",
                u32::from(pac_opts.key == PAuthKey::B),
            );
            llvm::add_module_flag_u32(
                llmod,
                llvm::ModuleFlagMergeBehavior::Min,
                "guarded-control-stack",
                gcs.into(),
            );
        } else {
            bug!(
                "branch-protection used on non-AArch64 target; \
                  this should be checked in rustc_session."
            );
        }
    }

    // Pass on the control-flow protection flags to LLVM (equivalent to `-fcf-protection` in Clang).
    if let CFProtection::Branch | CFProtection::Full = sess.opts.unstable_opts.cf_protection {
        llvm::add_module_flag_u32(
            llmod,
            llvm::ModuleFlagMergeBehavior::Override,
            "cf-protection-branch",
            1,
        );
    }
    if let CFProtection::Return | CFProtection::Full = sess.opts.unstable_opts.cf_protection {
        llvm::add_module_flag_u32(
            llmod,
            llvm::ModuleFlagMergeBehavior::Override,
            "cf-protection-return",
            1,
        );
    }

    if sess.opts.unstable_opts.virtual_function_elimination {
        llvm::add_module_flag_u32(
            llmod,
            llvm::ModuleFlagMergeBehavior::Error,
            "Virtual Function Elim",
            1,
        );
    }

    // Set module flag to enable Windows EHCont Guard (/guard:ehcont).
    if sess.opts.unstable_opts.ehcont_guard {
        llvm::add_module_flag_u32(llmod, llvm::ModuleFlagMergeBehavior::Warning, "ehcontguard", 1);
    }

    match sess.opts.unstable_opts.function_return {
        FunctionReturn::Keep => {}
        FunctionReturn::ThunkExtern => {
            llvm::add_module_flag_u32(
                llmod,
                llvm::ModuleFlagMergeBehavior::Override,
                "function_return_thunk_extern",
                1,
            );
        }
    }

    if sess.opts.unstable_opts.indirect_branch_cs_prefix {
        llvm::add_module_flag_u32(
            llmod,
            llvm::ModuleFlagMergeBehavior::Override,
            "indirect_branch_cs_prefix",
            1,
        );
    }

    match (sess.opts.unstable_opts.small_data_threshold, sess.target.small_data_threshold_support())
    {
        // Set up the small-data optimization limit for architectures that use
        // an LLVM module flag to control this.
        (Some(threshold), SmallDataThresholdSupport::LlvmModuleFlag(flag)) => {
            llvm::add_module_flag_u32(
                llmod,
                llvm::ModuleFlagMergeBehavior::Error,
                &flag,
                threshold as u32,
            );
        }
        _ => (),
    };

    // Insert `llvm.ident` metadata.
    //
    // On the wasm targets it will get hooked up to the "producer" sections
    // `processed-by` information.
    #[allow(clippy::option_env_unwrap)]
    let rustc_producer =
        format!("rustc version {}", option_env!("CFG_VERSION").expect("CFG_VERSION"));

    let name_metadata = cx.create_metadata(rustc_producer.as_bytes());
    cx.module_add_named_metadata_node(llmod, c"llvm.ident", &[name_metadata]);

    // Emit RISC-V specific target-abi metadata
    // to workaround lld as the LTO plugin not
    // correctly setting target-abi for the LTO object
    // FIXME: https://github.com/llvm/llvm-project/issues/50591
    let llvm_abiname = &sess.target.options.llvm_abiname;
    if matches!(sess.target.arch, Arch::RiscV32 | Arch::RiscV64) {
        llvm::add_module_flag_str(
            llmod,
            llvm::ModuleFlagMergeBehavior::Error,
            "target-abi",
            llvm_abiname.desc(),
        );
    }

    // Add module flags specified via -Z llvm_module_flag
    for (key, value, merge_behavior) in &sess.opts.unstable_opts.llvm_module_flag {
        let merge_behavior = match merge_behavior.as_str() {
            "error" => llvm::ModuleFlagMergeBehavior::Error,
            "warning" => llvm::ModuleFlagMergeBehavior::Warning,
            "require" => llvm::ModuleFlagMergeBehavior::Require,
            "override" => llvm::ModuleFlagMergeBehavior::Override,
            "append" => llvm::ModuleFlagMergeBehavior::Append,
            "appendunique" => llvm::ModuleFlagMergeBehavior::AppendUnique,
            "max" => llvm::ModuleFlagMergeBehavior::Max,
            "min" => llvm::ModuleFlagMergeBehavior::Min,
            // We already checked this during option parsing
            _ => unreachable!(),
        };
        llvm::add_module_flag_u32(llmod, merge_behavior, key, *value);
    }

    llmod
}

impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
    pub(crate) fn new(
        tcx: TyCtxt<'tcx>,
        codegen_unit: &'tcx CodegenUnit<'tcx>,
        llvm_module: &'ll crate::ModuleLlvm,
    ) -> Self {
        // An interesting part of Windows which MSVC forces our hand on (and
        // apparently MinGW didn't) is the usage of `dllimport` and `dllexport`
        // attributes in LLVM IR as well as native dependencies (in C these
        // correspond to `__declspec(dllimport)`).
        //
        // LD (BFD) in MinGW mode can often correctly guess `dllexport` but
        // relying on that can result in issues like #50176.
        // LLD won't support that and expects symbols with proper attributes.
        // Because of that we make MinGW target emit dllexport just like MSVC.
        // When it comes to dllimport we use it for constants but for functions
        // rely on the linker to do the right thing. Opposed to dllexport this
        // task is easy for them (both LD and LLD) and allows us to easily use
        // symbols from static libraries in shared libraries.
        //
        // Whenever a dynamic library is built on Windows it must have its public
        // interface specified by functions tagged with `dllexport` or otherwise
        // they're not available to be linked against. This poses a few problems
        // for the compiler, some of which are somewhat fundamental, but we use
        // the `use_dll_storage_attrs` variable below to attach the `dllexport`
        // attribute to all LLVM functions that are exported e.g., they're
        // already tagged with external linkage). This is suboptimal for a few
        // reasons:
        //
        // * If an object file will never be included in a dynamic library,
        //   there's no need to attach the dllexport attribute. Most object
        //   files in Rust are not destined to become part of a dll as binaries
        //   are statically linked by default.
        // * If the compiler is emitting both an rlib and a dylib, the same
        //   source object file is currently used but with MSVC this may be less
        //   feasible. The compiler may be able to get around this, but it may
        //   involve some invasive changes to deal with this.
        //
        // The flip side of this situation is that whenever you link to a dll and
        // you import a function from it, the import should be tagged with
        // `dllimport`. At this time, however, the compiler does not emit
        // `dllimport` for any declarations other than constants (where it is
        // required), which is again suboptimal for even more reasons!
        //
        // * Calling a function imported from another dll without using
        //   `dllimport` causes the linker/compiler to have extra overhead (one
        //   `jmp` instruction on x86) when calling the function.
        // * The same object file may be used in different circumstances, so a
        //   function may be imported from a dll if the object is linked into a
        //   dll, but it may be just linked against if linked into an rlib.
        // * The compiler has no knowledge about whether native functions should
        //   be tagged dllimport or not.
        //
        // For now the compiler takes the perf hit (I do not have any numbers to
        // this effect) by marking very little as `dllimport` and praying the
        // linker will take care of everything. Fixing this problem will likely
        // require adding a few attributes to Rust itself (feature gated at the
        // start) and then strongly recommending static linkage on Windows!
        let use_dll_storage_attrs = tcx.sess.target.is_like_windows;

        let tls_model = to_llvm_tls_model(tcx.sess.tls_model());

        let (llcx, llmod) = (&*llvm_module.llcx, llvm_module.llmod());

        let coverage_cx =
            tcx.sess.instrument_coverage().then(coverageinfo::CguCoverageContext::new);

        let dbg_cx = if tcx.sess.opts.debuginfo != DebugInfo::None {
            let dctx = debuginfo::CodegenUnitDebugContext::new(llmod);
            debuginfo::metadata::build_compile_unit_di_node(
                tcx,
                codegen_unit.name().as_str(),
                &dctx,
            );
            Some(dctx)
        } else {
            None
        };

        GenericCx(
            FullCx {
                tcx,
                scx: SimpleCx::new(llmod, llcx, tcx.data_layout.pointer_size()),
                use_dll_storage_attrs,
                tls_model,
                codegen_unit,
                instances: Default::default(),
                intrinsic_instances: Default::default(),
                vtables: Default::default(),
                const_str_cache: Default::default(),
                const_globals: Default::default(),
                statics_to_rauw: RefCell::new(Vec::new()),
                used_statics: Vec::new(),
                compiler_used_statics: Default::default(),
                type_lowering: Default::default(),
                scalar_lltypes: Default::default(),
                coverage_cx,
                dbg_cx,
                eh_personality: Cell::new(None),
                eh_catch_typeinfo: Cell::new(None),
                rust_try_fn: Cell::new(None),
                intrinsics: Default::default(),
                local_gen_sym_counter: Cell::new(0),
                renamed_statics: Default::default(),
                objc_class_t: Cell::new(None),
                objc_classrefs: Default::default(),
                objc_selrefs: Default::default(),
                offload_globals: Default::default(),
                offload_kernel_cache: Default::default(),
            },
            PhantomData,
        )
    }

    pub(crate) fn statics_to_rauw(&self) -> &RefCell<Vec<(&'ll Value, &'ll Value)>> {
        &self.statics_to_rauw
    }

    /// Extra state that is only available when coverage instrumentation is enabled.
    #[inline]
    #[track_caller]
    pub(crate) fn coverage_cx(&self) -> &coverageinfo::CguCoverageContext<'ll, 'tcx> {
        self.coverage_cx.as_ref().expect("only called when coverage instrumentation is enabled")
    }

    pub(crate) fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) {
        let array = self.const_array(self.type_ptr(), values);

        let g = llvm::add_global(self.llmod, self.val_ty(array), name);
        llvm::set_initializer(g, array);
        llvm::set_linkage(g, llvm::Linkage::AppendingLinkage);
        llvm::set_section(g, c"llvm.metadata");
    }

    /// The Objective-C ABI that is used.
    ///
    /// This corresponds to the `-fobjc-abi-version=` flag in Clang / GCC.
    pub(crate) fn objc_abi_version(&self) -> u32 {
        assert!(self.tcx.sess.target.is_like_darwin);
        if self.tcx.sess.target.arch == Arch::X86 && self.tcx.sess.target.os == Os::MacOs {
            // 32-bit x86 macOS uses ABI version 1 (a.k.a. the "fragile ABI").
            1
        } else {
            // All other Darwin-like targets we support use ABI version 2
            // (a.k.a the "non-fragile ABI").
            2
        }
    }

    // We do our best here to match what Clang does when compiling Objective-C natively.
    // See Clang's `CGObjCCommonMac::EmitImageInfo`:
    // https://github.com/llvm/llvm-project/blob/llvmorg-20.1.8/clang/lib/CodeGen/CGObjCMac.cpp#L5085
    pub(crate) fn add_objc_module_flags(&self) {
        let abi_version = self.objc_abi_version();

        llvm::add_module_flag_u32(
            self.llmod,
            llvm::ModuleFlagMergeBehavior::Error,
            "Objective-C Version",
            abi_version,
        );

        llvm::add_module_flag_u32(
            self.llmod,
            llvm::ModuleFlagMergeBehavior::Error,
            "Objective-C Image Info Version",
            0,
        );

        llvm::add_module_flag_str(
            self.llmod,
            llvm::ModuleFlagMergeBehavior::Error,
            "Objective-C Image Info Section",
            match abi_version {
                1 => "__OBJC,__image_info,regular",
                2 => "__DATA,__objc_imageinfo,regular,no_dead_strip",
                _ => unreachable!(),
            },
        );

        if self.tcx.sess.target.env == Env::Sim {
            llvm::add_module_flag_u32(
                self.llmod,
                llvm::ModuleFlagMergeBehavior::Error,
                "Objective-C Is Simulated",
                1 << 5,
            );
        }

        llvm::add_module_flag_u32(
            self.llmod,
            llvm::ModuleFlagMergeBehavior::Error,
            "Objective-C Class Properties",
            1 << 6,
        );
    }
}
impl<'ll> SimpleCx<'ll> {
    pub(crate) fn get_type_of_global(&self, val: &'ll Value) -> &'ll Type {
        unsafe { llvm::LLVMGlobalGetValueType(val) }
    }
    pub(crate) fn val_ty(&self, v: &'ll Value) -> &'ll Type {
        common::val_ty(v)
    }
}
impl<'ll> SimpleCx<'ll> {
    pub(crate) fn new(
        llmod: &'ll llvm::Module,
        llcx: &'ll llvm::Context,
        pointer_size: Size,
    ) -> Self {
        let isize_ty = llvm::LLVMIntTypeInContext(llcx, pointer_size.bits() as c_uint);
        Self(SCx { llmod, llcx, isize_ty }, PhantomData)
    }
}

impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
    pub(crate) fn get_metadata_value(&self, metadata: &'ll Metadata) -> &'ll Value {
        llvm::LLVMMetadataAsValue(self.llcx(), metadata)
    }

    pub(crate) fn get_const_int(&self, ty: &'ll Type, val: u64) -> &'ll Value {
        unsafe { llvm::LLVMConstInt(ty, val, llvm::FALSE) }
    }

    pub(crate) fn get_const_i64(&self, n: u64) -> &'ll Value {
        self.get_const_int(self.type_i64(), n)
    }

    pub(crate) fn get_const_i32(&self, n: u64) -> &'ll Value {
        self.get_const_int(self.type_i32(), n)
    }

    pub(crate) fn get_const_i16(&self, n: u64) -> &'ll Value {
        self.get_const_int(self.type_i16(), n)
    }

    pub(crate) fn get_const_i8(&self, n: u64) -> &'ll Value {
        self.get_const_int(self.type_i8(), n)
    }

    pub(crate) fn get_function(&self, name: &str) -> Option<&'ll Value> {
        let name = SmallCStr::new(name);
        unsafe { llvm::LLVMGetNamedFunction((**self).borrow().llmod, name.as_ptr()) }
    }

    pub(crate) fn get_md_kind_id(&self, name: &str) -> llvm::MetadataKindId {
        unsafe {
            llvm::LLVMGetMDKindIDInContext(
                self.llcx(),
                name.as_ptr() as *const c_char,
                name.len() as c_uint,
            )
        }
    }

    pub(crate) fn create_metadata(&self, name: &[u8]) -> &'ll Metadata {
        unsafe {
            llvm::LLVMMDStringInContext2(self.llcx(), name.as_ptr() as *const c_char, name.len())
        }
    }

    pub(crate) fn get_functions(&self) -> Vec<&'ll Value> {
        let mut functions = vec![];
        let mut func = unsafe { llvm::LLVMGetFirstFunction(self.llmod()) };
        while let Some(f) = func {
            functions.push(f);
            func = unsafe { llvm::LLVMGetNextFunction(f) }
        }
        functions
    }
}

impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
    fn vtables(
        &self,
    ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>), &'ll Value>> {
        &self.vtables
    }

    fn apply_vcall_visibility_metadata(
        &self,
        ty: Ty<'tcx>,
        poly_trait_ref: Option<ty::ExistentialTraitRef<'tcx>>,
        vtable: &'ll Value,
    ) {
        apply_vcall_visibility_metadata(self, ty, poly_trait_ref, vtable);
    }

    fn get_fn(&self, instance: Instance<'tcx>) -> &'ll Value {
        get_fn(self, instance)
    }

    fn get_fn_addr(&self, instance: Instance<'tcx>) -> &'ll Value {
        get_fn(self, instance)
    }

    fn eh_personality(&self) -> &'ll Value {
        // The exception handling personality function.
        //
        // If our compilation unit has the `eh_personality` lang item somewhere
        // within it, then we just need to codegen that. Otherwise, we're
        // building an rlib which will depend on some upstream implementation of
        // this function, so we just codegen a generic reference to it. We don't
        // specify any of the types for the function, we just make it a symbol
        // that LLVM can later use.
        //
        // Note that MSVC is a little special here in that we don't use the
        // `eh_personality` lang item at all. Currently LLVM has support for
        // both Dwarf and SEH unwind mechanisms for MSVC targets and uses the
        // *name of the personality function* to decide what kind of unwind side
        // tables/landing pads to emit. It looks like Dwarf is used by default,
        // injecting a dependency on the `_Unwind_Resume` symbol for resuming
        // an "exception", but for MSVC we want to force SEH. This means that we
        // can't actually have the personality function be our standard
        // `rust_eh_personality` function, but rather we wired it up to the
        // CRT's custom personality function, which forces LLVM to consider
        // landing pads as "landing pads for SEH".
        if let Some(llpersonality) = self.eh_personality.get() {
            return llpersonality;
        }

        let name = if wants_msvc_seh(self.sess()) {
            Some("__CxxFrameHandler3")
        } else if wants_wasm_eh(self.sess()) {
            // LLVM specifically tests for the name of the personality function
            // There is no need for this function to exist anywhere, it will
            // not be called. However, its name has to be "__gxx_wasm_personality_v0"
            // for native wasm exceptions.
            Some("__gxx_wasm_personality_v0")
        } else {
            None
        };

        let tcx = self.tcx;
        let llfn = match tcx.lang_items().eh_personality() {
            Some(def_id) if name.is_none() => self.get_fn_addr(ty::Instance::expect_resolve(
                tcx,
                self.typing_env(),
                def_id,
                ty::List::empty(),
                DUMMY_SP,
            )),
            _ => {
                let name = name.unwrap_or("rust_eh_personality");
                if let Some(llfn) = self.get_declared_value(name) {
                    llfn
                } else {
                    let fty = self.type_variadic_func(&[], self.type_i32());
                    let llfn = self.declare_cfn(name, llvm::UnnamedAddr::Global, fty);
                    let target_cpu = attributes::target_cpu_attr(self, self.sess());
                    attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[target_cpu]);
                    llfn
                }
            }
        };
        self.eh_personality.set(Some(llfn));
        llfn
    }

    fn sess(&self) -> &Session {
        self.tcx.sess
    }

    fn set_frame_pointer_type(&self, llfn: &'ll Value) {
        if let Some(attr) = attributes::frame_pointer_type_attr(self, self.sess()) {
            attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[attr]);
        }
    }

    fn apply_target_cpu_attr(&self, llfn: &'ll Value) {
        let mut attrs = SmallVec::<[_; 2]>::new();
        attrs.push(attributes::target_cpu_attr(self, self.sess()));
        attrs.extend(attributes::tune_cpu_attr(self, self.sess()));
        attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &attrs);
    }

    fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
        let entry_name = self.sess().target.entry_name.as_ref();
        if self.get_declared_value(entry_name).is_none() {
            let llfn = self.declare_entry_fn(
                entry_name,
                to_llvm_calling_convention(self.sess(), self.sess().target.entry_abi),
                llvm::UnnamedAddr::Global,
                fn_type,
            );
            attributes::apply_to_llfn(
                llfn,
                llvm::AttributePlace::Function,
                attributes::target_features_attr(self, self.tcx, vec![]).as_slice(),
            );
            Some(llfn)
        } else {
            // If the symbol already exists, it is an error: for example, the user wrote
            // #[no_mangle] extern "C" fn main(..) {..}
            None
        }
    }
}

impl<'ll> CodegenCx<'ll, '_> {
    pub(crate) fn get_intrinsic(
        &self,
        base_name: Cow<'static, str>,
        type_params: &[&'ll Type],
    ) -> (&'ll Type, &'ll Value) {
        *self
            .intrinsics
            .borrow_mut()
            .entry((base_name, SmallVec::from_slice(type_params)))
            .or_insert_with_key(|(base_name, type_params)| {
                self.declare_intrinsic(base_name, type_params)
            })
    }

    fn declare_intrinsic(
        &self,
        base_name: &str,
        type_params: &[&'ll Type],
    ) -> (&'ll Type, &'ll Value) {
        // This isn't an "LLVM intrinsic", but LLVM's optimization passes
        // recognize it like one (including turning it into `bcmp` sometimes)
        // and we use it to implement intrinsics like `raw_eq` and `compare_bytes`
        if base_name == "memcmp" {
            let fn_ty = self
                .type_func(&[self.type_ptr(), self.type_ptr(), self.type_isize()], self.type_int());
            let f = self.declare_cfn("memcmp", llvm::UnnamedAddr::No, fn_ty);

            return (fn_ty, f);
        }

        let intrinsic = llvm::Intrinsic::lookup(base_name.as_bytes())
            .unwrap_or_else(|| bug!("Unknown intrinsic: `{base_name}`"));
        let f = intrinsic.get_declaration(self.llmod, &type_params);

        (self.get_type_of_global(f), f)
    }

    pub(crate) fn eh_catch_typeinfo(&self) -> &'ll Value {
        if let Some(eh_catch_typeinfo) = self.eh_catch_typeinfo.get() {
            return eh_catch_typeinfo;
        }
        let tcx = self.tcx;
        assert!(self.sess().target.os == Os::Emscripten);
        let eh_catch_typeinfo = match tcx.lang_items().eh_catch_typeinfo() {
            Some(def_id) => self.get_static(def_id),
            _ => {
                let ty = self.type_struct(&[self.type_ptr(), self.type_ptr()], false);
                self.declare_global(&mangle_internal_symbol(self.tcx, "rust_eh_catch_typeinfo"), ty)
            }
        };
        self.eh_catch_typeinfo.set(Some(eh_catch_typeinfo));
        eh_catch_typeinfo
    }
}

impl CodegenCx<'_, '_> {
    /// Generates a new symbol name with the given prefix. This symbol name must
    /// only be used for definitions with `internal` or `private` linkage.
    pub(crate) fn generate_local_symbol_name(&self, prefix: &str) -> String {
        let idx = self.local_gen_sym_counter.get();
        self.local_gen_sym_counter.set(idx + 1);
        // Include a '.' character, so there can be no accidental conflicts with
        // user defined names
        let mut name = String::with_capacity(prefix.len() + 6);
        name.push_str(prefix);
        name.push('.');
        name.push_str(&(idx as u64).to_base(ALPHANUMERIC_ONLY));
        name
    }
}

impl<'ll, CX: Borrow<SCx<'ll>>> GenericCx<'ll, CX> {
    /// Wrapper for `LLVMMDNodeInContext2`, i.e. `llvm::MDNode::get`.
    pub(crate) fn md_node_in_context(&self, md_list: &[&'ll Metadata]) -> &'ll Metadata {
        unsafe { llvm::LLVMMDNodeInContext2(self.llcx(), md_list.as_ptr(), md_list.len()) }
    }

    /// A wrapper for [`llvm::LLVMSetMetadata`], but it takes `Metadata` as a parameter instead of `Value`.
    pub(crate) fn set_metadata<'a>(
        &self,
        val: &'a Value,
        kind_id: MetadataKindId,
        md: &'ll Metadata,
    ) {
        let node = self.get_metadata_value(md);
        llvm::LLVMSetMetadata(val, kind_id, node);
    }

    /// Helper method for the sequence of calls:
    /// - `LLVMMDNodeInContext2` (to create an `llvm::MDNode` from a list of metadata)
    /// - `LLVMMetadataAsValue` (to adapt that node to an `llvm::Value`)
    /// - `LLVMSetMetadata` (to set that node as metadata of `kind_id` for `instruction`)
    pub(crate) fn set_metadata_node(
        &self,
        instruction: &'ll Value,
        kind_id: MetadataKindId,
        md_list: &[&'ll Metadata],
    ) {
        let md = self.md_node_in_context(md_list);
        self.set_metadata(instruction, kind_id, md);
    }

    /// Helper method for the sequence of calls:
    /// - `LLVMMDNodeInContext2` (to create an `llvm::MDNode` from a list of metadata)
    /// - `LLVMMetadataAsValue` (to adapt that node to an `llvm::Value`)
    /// - `LLVMAddNamedMetadataOperand` (to set that node as metadata of `kind_name` for `module`)
    pub(crate) fn module_add_named_metadata_node(
        &self,
        module: &'ll Module,
        kind_name: &CStr,
        md_list: &[&'ll Metadata],
    ) {
        let md = self.md_node_in_context(md_list);
        let md_as_val = self.get_metadata_value(md);
        unsafe { llvm::LLVMAddNamedMetadataOperand(module, kind_name.as_ptr(), md_as_val) };
    }

    /// Helper method for the sequence of calls:
    /// - `LLVMMDNodeInContext2` (to create an `llvm::MDNode` from a list of metadata)
    /// - `LLVMRustGlobalAddMetadata` (to set that node as metadata of `kind_id` for `global`)
    pub(crate) fn global_add_metadata_node(
        &self,
        global: &'ll Value,
        kind_id: MetadataKindId,
        md_list: &[&'ll Metadata],
    ) {
        let md = self.md_node_in_context(md_list);
        unsafe { llvm::LLVMRustGlobalAddMetadata(global, kind_id, md) };
    }

    /// Helper method for the sequence of calls:
    /// - `LLVMMDNodeInContext2` (to create an `llvm::MDNode` from a list of metadata)
    /// - `LLVMGlobalSetMetadata` (to set that node as metadata of `kind_id` for `global`)
    pub(crate) fn global_set_metadata_node(
        &self,
        global: &'ll Value,
        kind_id: MetadataKindId,
        md_list: &[&'ll Metadata],
    ) {
        let md = self.md_node_in_context(md_list);
        unsafe { llvm::LLVMGlobalSetMetadata(global, kind_id, md) };
    }
}

impl HasDataLayout for CodegenCx<'_, '_> {
    #[inline]
    fn data_layout(&self) -> &TargetDataLayout {
        &self.tcx.data_layout
    }
}

impl HasTargetSpec for CodegenCx<'_, '_> {
    #[inline]
    fn target_spec(&self) -> &Target {
        &self.tcx.sess.target
    }
}

impl<'tcx> ty::layout::HasTyCtxt<'tcx> for CodegenCx<'_, 'tcx> {
    #[inline]
    fn tcx(&self) -> TyCtxt<'tcx> {
        self.tcx
    }
}

impl<'tcx, 'll> HasTypingEnv<'tcx> for CodegenCx<'ll, 'tcx> {
    fn typing_env(&self) -> ty::TypingEnv<'tcx> {
        ty::TypingEnv::fully_monomorphized()
    }
}

impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
    #[inline]
    fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
        if let LayoutError::SizeOverflow(_)
        | LayoutError::ReferencesError(_)
        | LayoutError::InvalidSimd { .. } = err
        {
            self.tcx.dcx().span_fatal(span, err.to_string())
        } else {
            self.tcx.dcx().emit_fatal(ssa_errors::FailedToGetLayout { span, ty, err })
        }
    }
}

impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
    #[inline]
    fn handle_fn_abi_err(
        &self,
        err: FnAbiError<'tcx>,
        span: Span,
        fn_abi_request: FnAbiRequest<'tcx>,
    ) -> ! {
        match err {
            FnAbiError::Layout(LayoutError::SizeOverflow(_) | LayoutError::InvalidSimd { .. }) => {
                self.tcx.dcx().emit_fatal(Spanned { span, node: err });
            }
            _ => match fn_abi_request {
                FnAbiRequest::OfFnPtr { sig, extra_args } => {
                    span_bug!(span, "`fn_abi_of_fn_ptr({sig}, {extra_args:?})` failed: {err:?}",);
                }
                FnAbiRequest::OfInstance { instance, extra_args } => {
                    span_bug!(
                        span,
                        "`fn_abi_of_instance({instance}, {extra_args:?})` failed: {err:?}",
                    );
                }
            },
        }
    }
}
