Extract attribute handling code into a module
This commit causes no change in trans semantics, it just moves some functions around and deduplicates them.
This commit is contained in:
parent
d36c4db96d
commit
c71970eea2
7 changed files with 176 additions and 135 deletions
|
|
@ -157,7 +157,7 @@ bitflags! {
|
|||
#[derive(Copy, Clone)]
|
||||
pub enum OtherAttribute {
|
||||
// The following are not really exposed in
|
||||
// the LLVM c api so instead to add these
|
||||
// the LLVM C api so instead to add these
|
||||
// we call a wrapper function in RustWrapper
|
||||
// that uses the C++ api.
|
||||
SanitizeAddressAttribute = 1 << 32,
|
||||
|
|
@ -958,6 +958,7 @@ extern {
|
|||
pub fn LLVMAddFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
|
||||
pub fn LLVMRemoveFunctionAttrString(Fn: ValueRef, index: c_uint, Name: *const c_char);
|
||||
pub fn LLVMGetFunctionAttr(Fn: ValueRef) -> c_ulonglong;
|
||||
pub fn LLVMRemoveFunctionAttr(Fn: ValueRef, val: c_ulonglong);
|
||||
|
||||
/* Operations on parameters */
|
||||
pub fn LLVMCountParams(Fn: ValueRef) -> c_uint;
|
||||
|
|
|
|||
108
src/librustc_trans/trans/attributes.rs
Normal file
108
src/librustc_trans/trans/attributes.rs
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
//! Set and unset common attributes on LLVM values.
|
||||
|
||||
use llvm::{self, ValueRef, AttrHelper};
|
||||
use syntax::ast;
|
||||
use syntax::attr::InlineAttr;
|
||||
pub use syntax::attr::InlineAttr::*;
|
||||
use trans::context::CrateContext;
|
||||
|
||||
use libc::{c_uint, c_ulonglong};
|
||||
|
||||
/// Mark LLVM function to use split stack.
|
||||
#[inline]
|
||||
pub fn split_stack(val: ValueRef, set: bool) {
|
||||
unsafe {
|
||||
let attr = "split-stack\0".as_ptr() as *const _;
|
||||
if set {
|
||||
llvm::LLVMAddFunctionAttrString(val, llvm::FunctionIndex as c_uint, attr);
|
||||
} else {
|
||||
llvm::LLVMRemoveFunctionAttrString(val, llvm::FunctionIndex as c_uint, attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Mark LLVM function to use provided inline heuristic.
|
||||
#[inline]
|
||||
pub fn inline(val: ValueRef, inline: InlineAttr) {
|
||||
match inline {
|
||||
InlineHint => llvm::SetFunctionAttribute(val, llvm::InlineHintAttribute),
|
||||
InlineAlways => llvm::SetFunctionAttribute(val, llvm::AlwaysInlineAttribute),
|
||||
InlineNever => llvm::SetFunctionAttribute(val, llvm::NoInlineAttribute),
|
||||
InlineNone => {
|
||||
let attr = llvm::InlineHintAttribute |
|
||||
llvm::AlwaysInlineAttribute |
|
||||
llvm::NoInlineAttribute;
|
||||
unsafe {
|
||||
llvm::LLVMRemoveFunctionAttr(val, attr.bits() as c_ulonglong)
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
|
||||
#[inline]
|
||||
pub fn emit_uwtable(val: ValueRef, emit: bool) {
|
||||
if emit {
|
||||
llvm::SetFunctionAttribute(val, llvm::UWTableAttribute);
|
||||
} else {
|
||||
unsafe {
|
||||
llvm::LLVMRemoveFunctionAttr(val, llvm::UWTableAttribute.bits() as c_ulonglong);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Tell LLVM whether the function can or cannot unwind.
|
||||
#[inline]
|
||||
#[allow(dead_code)] // possibly useful function
|
||||
pub fn unwind(val: ValueRef, can_unwind: bool) {
|
||||
if can_unwind {
|
||||
unsafe {
|
||||
llvm::LLVMRemoveFunctionAttr(val, llvm::NoUnwindAttribute.bits() as c_ulonglong);
|
||||
}
|
||||
} else {
|
||||
llvm::SetFunctionAttribute(val, llvm::NoUnwindAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
/// Tell LLVM whether it should optimise function for size.
|
||||
#[inline]
|
||||
#[allow(dead_code)] // possibly useful function
|
||||
pub fn set_optimize_for_size(val: ValueRef, optimize: bool) {
|
||||
if optimize {
|
||||
llvm::SetFunctionAttribute(val, llvm::OptimizeForSizeAttribute);
|
||||
} else {
|
||||
unsafe {
|
||||
llvm::LLVMRemoveFunctionAttr(val, llvm::OptimizeForSizeAttribute.bits() as c_ulonglong);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
|
||||
/// attributes.
|
||||
pub fn convert_fn_attrs_to_llvm(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) {
|
||||
use syntax::attr::*;
|
||||
inline(llfn, find_inline_attr(Some(ccx.sess().diagnostic()), attrs));
|
||||
|
||||
for attr in attrs {
|
||||
if attr.check_name("no_stack_check") {
|
||||
split_stack(llfn, false);
|
||||
} else if attr.check_name("cold") {
|
||||
unsafe {
|
||||
llvm::LLVMAddFunctionAttribute(llfn,
|
||||
llvm::FunctionIndex as c_uint,
|
||||
llvm::ColdAttribute as u64)
|
||||
}
|
||||
} else if attr.check_name("allocator") {
|
||||
llvm::NoAliasAttribute.apply_llfn(llvm::ReturnIndex as c_uint, llfn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -7,21 +7,20 @@
|
|||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// trans.rs: Translate the completed AST to the LLVM IR.
|
||||
//
|
||||
// Some functions here, such as trans_block and trans_expr, return a value --
|
||||
// the result of the translation to LLVM -- while others, such as trans_fn,
|
||||
// trans_impl, and trans_item, are called only for the side effect of adding a
|
||||
// particular definition to the LLVM IR output we're producing.
|
||||
//
|
||||
// Hopefully useful general knowledge about trans:
|
||||
//
|
||||
// * There's no way to find out the Ty type of a ValueRef. Doing so
|
||||
// would be "trying to get the eggs out of an omelette" (credit:
|
||||
// pcwalton). You can, instead, find out its TypeRef by calling val_ty,
|
||||
// but one TypeRef corresponds to many `Ty`s; for instance, tup(int, int,
|
||||
// int) and rec(x=int, y=int, z=int) will have the same TypeRef.
|
||||
//! Translate the completed AST to the LLVM IR.
|
||||
//!
|
||||
//! Some functions here, such as trans_block and trans_expr, return a value --
|
||||
//! the result of the translation to LLVM -- while others, such as trans_fn,
|
||||
//! trans_impl, and trans_item, are called only for the side effect of adding a
|
||||
//! particular definition to the LLVM IR output we're producing.
|
||||
//!
|
||||
//! Hopefully useful general knowledge about trans:
|
||||
//!
|
||||
//! * There's no way to find out the Ty type of a ValueRef. Doing so
|
||||
//! would be "trying to get the eggs out of an omelette" (credit:
|
||||
//! pcwalton). You can, instead, find out its TypeRef by calling val_ty,
|
||||
//! but one TypeRef corresponds to many `Ty`s; for instance, tup(int, int,
|
||||
//! int) and rec(x=int, y=int, z=int) will have the same TypeRef.
|
||||
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
|
|
@ -33,7 +32,7 @@ use super::ModuleTranslation;
|
|||
use back::link::mangle_exported_name;
|
||||
use back::{link, abi};
|
||||
use lint;
|
||||
use llvm::{AttrHelper, BasicBlockRef, Linkage, ValueRef, Vector, get_param};
|
||||
use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
|
||||
use llvm;
|
||||
use metadata::{csearch, encoder, loader};
|
||||
use middle::astencode;
|
||||
|
|
@ -46,6 +45,7 @@ use session::config::{self, NoDebugInfo};
|
|||
use session::Session;
|
||||
use trans::_match;
|
||||
use trans::adt;
|
||||
use trans::attributes;
|
||||
use trans::build::*;
|
||||
use trans::builder::{Builder, noname};
|
||||
use trans::callee;
|
||||
|
|
@ -204,7 +204,7 @@ pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
|
|||
llvm::SetUnnamedAddr(llfn, true);
|
||||
|
||||
if ccx.is_split_stack_supported() && !ccx.sess().opts.cg.no_stack_check {
|
||||
set_split_stack(llfn);
|
||||
attributes::split_stack(llfn, true);
|
||||
}
|
||||
|
||||
llfn
|
||||
|
|
@ -245,7 +245,7 @@ fn get_extern_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<'tcx>,
|
|||
let f = decl_rust_fn(ccx, fn_ty, name);
|
||||
|
||||
let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did);
|
||||
set_llvm_fn_attrs(ccx, &attrs[..], f);
|
||||
attributes::convert_fn_attrs_to_llvm(ccx, &attrs[..], f);
|
||||
|
||||
ccx.externs().borrow_mut().insert(name.to_string(), f);
|
||||
f
|
||||
|
|
@ -390,77 +390,6 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // useful
|
||||
pub fn set_optimize_for_size(f: ValueRef) {
|
||||
llvm::SetFunctionAttribute(f, llvm::OptimizeForSizeAttribute)
|
||||
}
|
||||
|
||||
pub fn set_no_inline(f: ValueRef) {
|
||||
llvm::SetFunctionAttribute(f, llvm::NoInlineAttribute)
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // useful
|
||||
pub fn set_no_unwind(f: ValueRef) {
|
||||
llvm::SetFunctionAttribute(f, llvm::NoUnwindAttribute)
|
||||
}
|
||||
|
||||
// Tell LLVM to emit the information necessary to unwind the stack for the
|
||||
// function f.
|
||||
pub fn set_uwtable(f: ValueRef) {
|
||||
llvm::SetFunctionAttribute(f, llvm::UWTableAttribute)
|
||||
}
|
||||
|
||||
pub fn set_inline_hint(f: ValueRef) {
|
||||
llvm::SetFunctionAttribute(f, llvm::InlineHintAttribute)
|
||||
}
|
||||
|
||||
pub fn set_llvm_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) {
|
||||
use syntax::attr::{find_inline_attr, InlineAttr};
|
||||
// Set the inline hint if there is one
|
||||
match find_inline_attr(Some(ccx.sess().diagnostic()), attrs) {
|
||||
InlineAttr::Hint => set_inline_hint(llfn),
|
||||
InlineAttr::Always => set_always_inline(llfn),
|
||||
InlineAttr::Never => set_no_inline(llfn),
|
||||
InlineAttr::None => { /* fallthrough */ }
|
||||
}
|
||||
|
||||
for attr in attrs {
|
||||
let mut used = true;
|
||||
match &attr.name()[..] {
|
||||
"no_stack_check" => unset_split_stack(llfn),
|
||||
"cold" => unsafe {
|
||||
llvm::LLVMAddFunctionAttribute(llfn,
|
||||
llvm::FunctionIndex as c_uint,
|
||||
llvm::ColdAttribute as uint64_t)
|
||||
},
|
||||
"allocator" => {
|
||||
llvm::NoAliasAttribute.apply_llfn(llvm::ReturnIndex as c_uint, llfn);
|
||||
}
|
||||
_ => used = false,
|
||||
}
|
||||
if used {
|
||||
attr::mark_used(attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_always_inline(f: ValueRef) {
|
||||
llvm::SetFunctionAttribute(f, llvm::AlwaysInlineAttribute)
|
||||
}
|
||||
|
||||
pub fn set_split_stack(f: ValueRef) {
|
||||
unsafe {
|
||||
llvm::LLVMAddFunctionAttrString(f, llvm::FunctionIndex as c_uint,
|
||||
"split-stack\0".as_ptr() as *const _);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unset_split_stack(f: ValueRef) {
|
||||
unsafe {
|
||||
llvm::LLVMRemoveFunctionAttrString(f, llvm::FunctionIndex as c_uint,
|
||||
"split-stack\0".as_ptr() as *const _);
|
||||
}
|
||||
}
|
||||
|
||||
// Double-check that we never ask LLVM to declare the same symbol twice. It
|
||||
// silently mangles such symbols, breaking our linkage model.
|
||||
|
|
@ -898,7 +827,7 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
_ => {
|
||||
let llfn = foreign::register_foreign_item_fn(ccx, fn_ty.abi, t, &name[..]);
|
||||
let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did);
|
||||
set_llvm_fn_attrs(ccx, &attrs, llfn);
|
||||
attributes::convert_fn_attrs_to_llvm(ccx, &attrs, llfn);
|
||||
llfn
|
||||
}
|
||||
}
|
||||
|
|
@ -1708,7 +1637,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
ccx.stats().n_closures.set(ccx.stats().n_closures.get() + 1);
|
||||
|
||||
let _icx = push_ctxt("trans_closure");
|
||||
set_uwtable(llfndecl);
|
||||
attributes::emit_uwtable(llfndecl, true);
|
||||
|
||||
debug!("trans_closure(..., param_substs={})",
|
||||
param_substs.repr(ccx.tcx()));
|
||||
|
|
@ -2312,7 +2241,7 @@ fn finish_register_fn(ccx: &CrateContext, sp: Span, sym: String, node_id: ast::N
|
|||
// eh_personality functions need to be externally linkable.
|
||||
let def = ast_util::local_def(node_id);
|
||||
if ccx.tcx().lang_items.stack_exhausted() == Some(def) {
|
||||
unset_split_stack(llfn);
|
||||
attributes::split_stack(llfn, false);
|
||||
llvm::SetLinkage(llfn, llvm::ExternalLinkage);
|
||||
}
|
||||
if ccx.tcx().lang_items.eh_personality() == Some(def) {
|
||||
|
|
@ -2733,7 +2662,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
|
|||
sym,
|
||||
i.id)
|
||||
};
|
||||
set_llvm_fn_attrs(ccx, &i.attrs, llfn);
|
||||
attributes::convert_fn_attrs_to_llvm(ccx, &i.attrs, llfn);
|
||||
llfn
|
||||
}
|
||||
|
||||
|
|
@ -2794,7 +2723,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
|
|||
let ty = ty::node_id_to_type(ccx.tcx(), ni.id);
|
||||
let name = foreign::link_name(&*ni);
|
||||
let llfn = foreign::register_foreign_item_fn(ccx, abi, ty, &name);
|
||||
set_llvm_fn_attrs(ccx, &ni.attrs, llfn);
|
||||
attributes::convert_fn_attrs_to_llvm(ccx, &ni.attrs, llfn);
|
||||
llfn
|
||||
}
|
||||
ast::ForeignItemStatic(..) => {
|
||||
|
|
@ -2826,7 +2755,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
|
|||
}
|
||||
_ => ccx.sess().bug("NodeVariant, shouldn't happen")
|
||||
};
|
||||
set_inline_hint(llfn);
|
||||
attributes::inline(llfn, attributes::InlineHint);
|
||||
llfn
|
||||
}
|
||||
|
||||
|
|
@ -2848,7 +2777,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
|
|||
&struct_item.attrs);
|
||||
let llfn = register_fn(ccx, struct_item.span,
|
||||
sym, ctor_id, ty);
|
||||
set_inline_hint(llfn);
|
||||
attributes::inline(llfn, attributes::InlineHint);
|
||||
llfn
|
||||
}
|
||||
|
||||
|
|
@ -2883,7 +2812,7 @@ fn register_method(ccx: &CrateContext, id: ast::NodeId,
|
|||
} else {
|
||||
foreign::register_rust_fn_with_foreign_abi(ccx, span, sym, id)
|
||||
};
|
||||
set_llvm_fn_attrs(ccx, &attrs, llfn);
|
||||
attributes::convert_fn_attrs_to_llvm(ccx, &attrs, llfn);
|
||||
return llfn;
|
||||
} else {
|
||||
ccx.sess().span_bug(span, "expected bare rust function");
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use back::link::{self, mangle_internal_name_by_path_and_seq};
|
|||
use llvm::{ValueRef, get_param};
|
||||
use middle::mem_categorization::Typer;
|
||||
use trans::adt;
|
||||
use trans::attributes;
|
||||
use trans::base::*;
|
||||
use trans::build::*;
|
||||
use trans::callee::{self, ArgVals, Callee, TraitItem, MethodData};
|
||||
|
|
@ -164,7 +165,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
|
|||
let llfn = decl_internal_rust_fn(ccx, function_type, &symbol[..]);
|
||||
|
||||
// set an inline hint for all closures
|
||||
set_inline_hint(llfn);
|
||||
attributes::inline(llfn, attributes::InlineHint);
|
||||
|
||||
debug!("get_or_create_declaration_if_closure(): inserting new \
|
||||
closure {:?} (type {})",
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use back::link;
|
|||
use llvm::{ValueRef, CallConv, get_param};
|
||||
use llvm;
|
||||
use middle::weak_lang_items;
|
||||
use trans::attributes;
|
||||
use trans::base::{llvm_linkage_by_name, push_ctxt};
|
||||
use trans::base;
|
||||
use trans::build::*;
|
||||
|
|
@ -612,7 +613,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
id, t.repr(tcx));
|
||||
|
||||
let llfn = base::decl_internal_rust_fn(ccx, t, &ps[..]);
|
||||
base::set_llvm_fn_attrs(ccx, attrs, llfn);
|
||||
attributes::convert_fn_attrs_to_llvm(ccx, attrs, llfn);
|
||||
base::trans_fn(ccx, decl, body, llfn, param_substs, id, &[]);
|
||||
llfn
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,43 +19,44 @@ pub use self::common::gensym_name;
|
|||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
mod inline;
|
||||
mod monomorphize;
|
||||
mod controlflow;
|
||||
mod glue;
|
||||
mod datum;
|
||||
mod callee;
|
||||
mod expr;
|
||||
mod common;
|
||||
mod context;
|
||||
mod consts;
|
||||
mod type_of;
|
||||
mod adt;
|
||||
mod asm;
|
||||
mod attributes;
|
||||
mod base;
|
||||
mod basic_block;
|
||||
mod build;
|
||||
mod builder;
|
||||
mod base;
|
||||
mod _match;
|
||||
mod closure;
|
||||
mod tvec;
|
||||
mod meth;
|
||||
mod cabi;
|
||||
mod cabi_aarch64;
|
||||
mod cabi_arm;
|
||||
mod cabi_mips;
|
||||
mod cabi_powerpc;
|
||||
mod cabi_x86;
|
||||
mod cabi_x86_64;
|
||||
mod cabi_x86_win64;
|
||||
mod cabi_arm;
|
||||
mod cabi_aarch64;
|
||||
mod cabi_mips;
|
||||
mod cabi_powerpc;
|
||||
mod foreign;
|
||||
mod intrinsic;
|
||||
mod debuginfo;
|
||||
mod machine;
|
||||
mod adt;
|
||||
mod asm;
|
||||
mod type_;
|
||||
mod value;
|
||||
mod basic_block;
|
||||
mod llrepr;
|
||||
mod callee;
|
||||
mod cleanup;
|
||||
mod closure;
|
||||
mod common;
|
||||
mod consts;
|
||||
mod context;
|
||||
mod controlflow;
|
||||
mod datum;
|
||||
mod debuginfo;
|
||||
mod expr;
|
||||
mod foreign;
|
||||
mod glue;
|
||||
mod inline;
|
||||
mod intrinsic;
|
||||
mod llrepr;
|
||||
mod machine;
|
||||
mod _match;
|
||||
mod meth;
|
||||
mod monomorphize;
|
||||
mod tvec;
|
||||
mod type_;
|
||||
mod type_of;
|
||||
mod value;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ModuleTranslation {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use middle::subst;
|
|||
use middle::subst::{Subst, Substs};
|
||||
use middle::traits;
|
||||
use middle::ty_fold::{TypeFolder, TypeFoldable};
|
||||
use trans::base::{set_llvm_fn_attrs, set_inline_hint};
|
||||
use trans::attributes;
|
||||
use trans::base::{trans_enum_variant, push_ctxt, get_item_val};
|
||||
use trans::base::{trans_fn, decl_internal_rust_fn};
|
||||
use trans::base;
|
||||
|
|
@ -151,7 +151,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
};
|
||||
let setup_lldecl = |lldecl, attrs: &[ast::Attribute]| {
|
||||
base::update_linkage(ccx, lldecl, None, base::OriginalTranslation);
|
||||
set_llvm_fn_attrs(ccx, attrs, lldecl);
|
||||
attributes::convert_fn_attrs_to_llvm(ccx, attrs, lldecl);
|
||||
|
||||
let is_first = !ccx.available_monomorphizations().borrow().contains(&s);
|
||||
if is_first {
|
||||
|
|
@ -200,7 +200,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
let tvs = ty::enum_variants(ccx.tcx(), local_def(parent));
|
||||
let this_tv = tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap();
|
||||
let d = mk_lldecl(abi::Rust);
|
||||
set_inline_hint(d);
|
||||
attributes::inline(d, attributes::InlineHint);
|
||||
match v.node.kind {
|
||||
ast::TupleVariantKind(ref args) => {
|
||||
trans_enum_variant(ccx,
|
||||
|
|
@ -259,7 +259,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
}
|
||||
ast_map::NodeStructCtor(struct_def) => {
|
||||
let d = mk_lldecl(abi::Rust);
|
||||
set_inline_hint(d);
|
||||
attributes::inline(d, attributes::InlineHint);
|
||||
base::trans_tuple_struct(ccx,
|
||||
&struct_def.fields,
|
||||
struct_def.ctor_id.expect("ast-mapped tuple struct \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue