//! Set and unset common attributes on LLVM values.

use std::ffi::CString;

use rustc::hir::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::session::Session;
use rustc::session::config::{Sanitizer, OptLevel};
use rustc::ty::{self, TyCtxt, PolyFnSig};
use rustc::ty::layout::HasTyCtxt;
use rustc::ty::query::Providers;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_data_structures::fx::FxHashMap;
use rustc_target::spec::PanicStrategy;
use rustc_codegen_ssa::traits::*;

use crate::abi::Abi;
use crate::attributes;
use crate::llvm::{self, Attribute};
use crate::llvm::AttributePlace::Function;
use crate::llvm_util;
pub use syntax::attr::{self, InlineAttr, OptimizeAttr};

use crate::context::CodegenCx;
use crate::value::Value;

/// Mark LLVM function to use provided inline heuristic.
#[inline]
pub fn inline(cx: &CodegenCx<'ll, '_>, val: &'ll Value, inline: InlineAttr) {
    use self::InlineAttr::*;
    match inline {
        Hint   => Attribute::InlineHint.apply_llfn(Function, val),
        Always => Attribute::AlwaysInline.apply_llfn(Function, val),
        Never  => {
            if cx.tcx().sess.target.target.arch != "amdgpu" {
                Attribute::NoInline.apply_llfn(Function, val);
            }
        },
        None   => {
            Attribute::InlineHint.unapply_llfn(Function, val);
            Attribute::AlwaysInline.unapply_llfn(Function, val);
            Attribute::NoInline.unapply_llfn(Function, val);
        },
    };
}

/// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
#[inline]
pub fn emit_uwtable(val: &'ll Value, emit: bool) {
    Attribute::UWTable.toggle_llfn(Function, val, emit);
}

/// Tell LLVM whether the function can or cannot unwind.
#[inline]
fn unwind(val: &'ll Value, can_unwind: bool) {
    Attribute::NoUnwind.toggle_llfn(Function, val, !can_unwind);
}

/// Tell LLVM if this function should be 'naked', i.e., skip the epilogue and prologue.
#[inline]
pub fn naked(val: &'ll Value, is_naked: bool) {
    Attribute::Naked.toggle_llfn(Function, val, is_naked);
}

pub fn set_frame_pointer_elimination(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
    if cx.sess().must_not_eliminate_frame_pointers() {
        llvm::AddFunctionAttrStringValue(
            llfn, llvm::AttributePlace::Function,
            const_cstr!("no-frame-pointer-elim"), const_cstr!("true"));
    }
}

/// Tell LLVM what instrument function to insert.
#[inline]
pub fn set_instrument_function(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
    if cx.sess().instrument_mcount() {
        // Similar to `clang -pg` behavior. Handled by the
        // `post-inline-ee-instrument` LLVM pass.

        // The function name varies on platforms.
        // See test/CodeGen/mcount.c in clang.
        let mcount_name = CString::new(
            cx.sess().target.target.options.target_mcount.as_str().as_bytes()).unwrap();

        llvm::AddFunctionAttrStringValue(
            llfn, llvm::AttributePlace::Function,
            const_cstr!("instrument-function-entry-inlined"), &mcount_name);
    }
}

pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
    // Only use stack probes if the target specification indicates that we
    // should be using stack probes
    if !cx.sess().target.target.options.stack_probes {
        return
    }

    // Currently stack probes seem somewhat incompatible with the address
    // sanitizer. With asan we're already protected from stack overflow anyway
    // so we don't really need stack probes regardless.
    if let Some(Sanitizer::Address) = cx.sess().opts.debugging_opts.sanitizer {
        return
    }

    // probestack doesn't play nice either with `-C profile-generate`.
    if cx.sess().opts.cg.profile_generate.enabled() {
        return;
    }

    // probestack doesn't play nice either with gcov profiling.
    if cx.sess().opts.debugging_opts.profile {
        return;
    }

    // Flag our internal `__rust_probestack` function as the stack probe symbol.
    // This is defined in the `compiler-builtins` crate for each architecture.
    llvm::AddFunctionAttrStringValue(
        llfn, llvm::AttributePlace::Function,
        const_cstr!("probe-stack"), const_cstr!("__rust_probestack"));
}

fn translate_obsolete_target_features(feature: &str) -> &str {
    const LLVM9_FEATURE_CHANGES: &[(&str, &str)] = &[
        ("+fp-only-sp", "-fp64"),
        ("-fp-only-sp", "+fp64"),
        ("+d16", "-d32"),
        ("-d16", "+d32"),
    ];
    if llvm_util::get_major_version() >= 9 {
        for &(old, new) in LLVM9_FEATURE_CHANGES {
            if feature == old {
                return new;
            }
        }
    } else {
        for &(old, new) in LLVM9_FEATURE_CHANGES {
            if feature == new {
                return old;
            }
        }
    }
    feature
}

pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
    const RUSTC_SPECIFIC_FEATURES: &[&str] = &[
        "crt-static",
    ];

    let cmdline = sess.opts.cg.target_feature.split(',')
        .filter(|f| !RUSTC_SPECIFIC_FEATURES.iter().any(|s| f.contains(s)));
    sess.target.target.options.features.split(',')
        .chain(cmdline)
        .filter(|l| !l.is_empty())
        .map(translate_obsolete_target_features)
}

pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
    let target_cpu = SmallCStr::new(llvm_util::target_cpu(cx.tcx.sess));
    llvm::AddFunctionAttrStringValue(
            llfn,
            llvm::AttributePlace::Function,
            const_cstr!("target-cpu"),
            target_cpu.as_c_str());
}

/// Sets the `NonLazyBind` LLVM attribute on a given function,
/// assuming the codegen options allow skipping the PLT.
pub fn non_lazy_bind(sess: &Session, llfn: &'ll Value) {
    // Don't generate calls through PLT if it's not necessary
    if !sess.needs_plt() {
        Attribute::NonLazyBind.apply_llfn(Function, llfn);
    }
}

pub(crate) fn default_optimisation_attrs(sess: &Session, llfn: &'ll Value) {
    match sess.opts.optimize {
        OptLevel::Size => {
            llvm::Attribute::MinSize.unapply_llfn(Function, llfn);
            llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn);
            llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn);
        },
        OptLevel::SizeMin => {
            llvm::Attribute::MinSize.apply_llfn(Function, llfn);
            llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn);
            llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn);
        }
        OptLevel::No => {
            llvm::Attribute::MinSize.unapply_llfn(Function, llfn);
            llvm::Attribute::OptimizeForSize.unapply_llfn(Function, llfn);
            llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn);
        }
        _ => {}
    }
}


/// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
/// attributes.
pub fn from_fn_attrs(
    cx: &CodegenCx<'ll, 'tcx>,
    llfn: &'ll Value,
    id: Option<DefId>,
    sig: PolyFnSig<'tcx>,
) {
    let codegen_fn_attrs = id.map(|id| cx.tcx.codegen_fn_attrs(id))
        .unwrap_or_else(|| CodegenFnAttrs::new());

    match codegen_fn_attrs.optimize {
        OptimizeAttr::None => {
            default_optimisation_attrs(cx.tcx.sess, llfn);
        }
        OptimizeAttr::Speed => {
            llvm::Attribute::MinSize.unapply_llfn(Function, llfn);
            llvm::Attribute::OptimizeForSize.unapply_llfn(Function, llfn);
            llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn);
        }
        OptimizeAttr::Size => {
            llvm::Attribute::MinSize.apply_llfn(Function, llfn);
            llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn);
            llvm::Attribute::OptimizeNone.unapply_llfn(Function, llfn);
        }
    }

    inline(cx, llfn, codegen_fn_attrs.inline);

    // The `uwtable` attribute according to LLVM is:
    //
    //     This attribute indicates that the ABI being targeted requires that an
    //     unwind table entry be produced for this function even if we can show
    //     that no exceptions passes by it. This is normally the case for the
    //     ELF x86-64 abi, but it can be disabled for some compilation units.
    //
    // Typically when we're compiling with `-C panic=abort` (which implies this
    // `no_landing_pads` check) we don't need `uwtable` because we can't
    // generate any exceptions! On Windows, however, exceptions include other
    // events such as illegal instructions, segfaults, etc. This means that on
    // Windows we end up still needing the `uwtable` attribute even if the `-C
    // panic=abort` flag is passed.
    //
    // You can also find more info on why Windows is whitelisted here in:
    //      https://bugzilla.mozilla.org/show_bug.cgi?id=1302078
    if !cx.sess().no_landing_pads() ||
       cx.sess().target.target.options.requires_uwtable {
        attributes::emit_uwtable(llfn, true);
    }

    set_frame_pointer_elimination(cx, llfn);
    set_instrument_function(cx, llfn);
    set_probestack(cx, llfn);

    if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::COLD) {
        Attribute::Cold.apply_llfn(Function, llfn);
    }
    if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_RETURNS_TWICE) {
        Attribute::ReturnsTwice.apply_llfn(Function, llfn);
    }
    if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
        naked(llfn, true);
    }
    if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) {
        Attribute::NoAlias.apply_llfn(
            llvm::AttributePlace::ReturnValue, llfn);
    }

    unwind(llfn, if cx.tcx.sess.panic_strategy() != PanicStrategy::Unwind {
        // In panic=abort mode we assume nothing can unwind anywhere, so
        // optimize based on this!
        false
    } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) {
        // If a specific #[unwind] attribute is present, use that
        true
    } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) {
        // Special attribute for allocator functions, which can't unwind
        false
    } else if let Some(id) = id {
        let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
        if cx.tcx.is_foreign_item(id) {
            // Foreign items like `extern "C" { fn foo(); }` are assumed not to
            // unwind
            false
        } else if sig.abi != Abi::Rust && sig.abi != Abi::RustCall {
            // Any items defined in Rust that *don't* have the `extern` ABI are
            // defined to not unwind. We insert shims to abort if an unwind
            // happens to enforce this.
            false
        } else {
            // Anything else defined in Rust is assumed that it can possibly
            // unwind
            true
        }
    } else {
        // assume this can possibly unwind, avoiding the application of a
        // `nounwind` attribute below.
        true
    });

    // Always annotate functions with the target-cpu they are compiled for.
    // Without this, ThinLTO won't inline Rust functions into Clang generated
    // functions (because Clang annotates functions this way too).
    apply_target_cpu_attr(cx, llfn);

    let features = llvm_target_features(cx.tcx.sess)
        .map(|s| s.to_string())
        .chain(
            codegen_fn_attrs.target_features
                .iter()
                .map(|f| {
                    let feature = &*f.as_str();
                    format!("+{}", llvm_util::to_llvm_feature(cx.tcx.sess, feature))
                })
        )
        .collect::<Vec<String>>()
        .join(",");

    if !features.is_empty() {
        let val = CString::new(features).unwrap();
        llvm::AddFunctionAttrStringValue(
            llfn, llvm::AttributePlace::Function,
            const_cstr!("target-features"), &val);
    }

    // Note that currently the `wasm-import-module` doesn't do anything, but
    // eventually LLVM 7 should read this and ferry the appropriate import
    // module to the output file.
    if let Some(id) = id {
        if cx.tcx.sess.target.target.arch == "wasm32" {
            if let Some(module) = wasm_import_module(cx.tcx, id) {
                llvm::AddFunctionAttrStringValue(
                    llfn,
                    llvm::AttributePlace::Function,
                    const_cstr!("wasm-import-module"),
                    &module,
                );
            }
        }
    }
}

pub fn provide(providers: &mut Providers<'_>) {
    providers.target_features_whitelist = |tcx, cnum| {
        assert_eq!(cnum, LOCAL_CRATE);
        if tcx.sess.opts.actually_rustdoc {
            // rustdoc needs to be able to document functions that use all the features, so
            // whitelist them all
            tcx.arena.alloc(llvm_util::all_known_features()
                .map(|(a, b)| (a.to_string(), b))
                .collect())
        } else {
            tcx.arena.alloc(llvm_util::target_feature_whitelist(tcx.sess)
                .iter()
                .map(|&(a, b)| (a.to_string(), b))
                .collect())
        }
    };

    provide_extern(providers);
}

pub fn provide_extern(providers: &mut Providers<'_>) {
    providers.wasm_import_module_map = |tcx, cnum| {
        // Build up a map from DefId to a `NativeLibrary` structure, where
        // `NativeLibrary` internally contains information about
        // `#[link(wasm_import_module = "...")]` for example.
        let native_libs = tcx.native_libraries(cnum);

        let def_id_to_native_lib = native_libs.iter().filter_map(|lib|
            if let Some(id) = lib.foreign_module {
                Some((id, lib))
            } else {
                None
            }
        ).collect::<FxHashMap<_, _>>();

        let mut ret = FxHashMap::default();
        for lib in tcx.foreign_modules(cnum).iter() {
            let module = def_id_to_native_lib
                .get(&lib.def_id)
                .and_then(|s| s.wasm_import_module);
            let module = match module {
                Some(s) => s,
                None => continue,
            };
            ret.extend(lib.foreign_items.iter().map(|id| {
                assert_eq!(id.krate, cnum);
                (*id, module.to_string())
            }));
        }

        tcx.arena.alloc(ret)
    };
}

fn wasm_import_module(tcx: TyCtxt<'_>, id: DefId) -> Option<CString> {
    tcx.wasm_import_module_map(id.krate)
        .get(&id)
        .map(|s| CString::new(&s[..]).unwrap())
}
