use util::ppaux::{Repr, ty_to_string};
use std::c_str::ToCStr;
-use std::gc::Gc;
use std::vec;
use libc::c_uint;
use syntax::{ast, ast_util};
+use syntax::ptr::P;
-pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: ast::Lit)
+pub fn const_lit(cx: &CrateContext, e: &ast::Expr, lit: &ast::Lit)
-> ValueRef {
let _icx = push_ctxt("trans_lit");
debug!("const_lit: {}", lit);
pub fn const_ptrcast(cx: &CrateContext, a: ValueRef, t: Type) -> ValueRef {
unsafe {
let b = llvm::LLVMConstPointerCast(a, t.ptr_to().to_ref());
- assert!(cx.const_globals.borrow_mut().insert(b as int, a));
+ assert!(cx.const_globals().borrow_mut().insert(b as int, a));
b
}
}
}
fn const_vec(cx: &CrateContext, e: &ast::Expr,
- es: &[Gc<ast::Expr>], is_local: bool) -> (ValueRef, Type, bool) {
+ es: &[P<ast::Expr>], is_local: bool) -> (ValueRef, Type, bool) {
let vec_ty = ty::expr_ty(cx.tcx(), e);
let unit_ty = ty::sequence_element_type(cx.tcx(), vec_ty);
let llunitty = type_of::type_of(cx, unit_ty);
pub fn const_addr_of(cx: &CrateContext, cv: ValueRef, mutbl: ast::Mutability) -> ValueRef {
unsafe {
let gv = "const".with_c_str(|name| {
- llvm::LLVMAddGlobal(cx.llmod, val_ty(cv).to_ref(), name)
+ llvm::LLVMAddGlobal(cx.llmod(), val_ty(cv).to_ref(), name)
});
llvm::LLVMSetInitializer(gv, cv);
llvm::LLVMSetGlobalConstant(gv,
}
fn const_deref_ptr(cx: &CrateContext, v: ValueRef) -> ValueRef {
- let v = match cx.const_globals.borrow().find(&(v as int)) {
+ let v = match cx.const_globals().borrow().find(&(v as int)) {
Some(&v) => v,
None => v
};
pub fn get_const_val(cx: &CrateContext,
mut def_id: ast::DefId) -> (ValueRef, bool) {
- let contains_key = cx.const_values.borrow().contains_key(&def_id.node);
+ let contains_key = cx.const_values().borrow().contains_key(&def_id.node);
if !ast_util::is_local(def_id) || !contains_key {
if !ast_util::is_local(def_id) {
def_id = inline::maybe_instantiate_inline(cx, def_id);
}
- match cx.tcx.map.expect_item(def_id.node).node {
+ match cx.tcx().map.expect_item(def_id.node).node {
ast::ItemStatic(_, ast::MutImmutable, _) => {
trans_const(cx, ast::MutImmutable, def_id.node);
}
}
}
- (cx.const_values.borrow().get_copy(&def_id.node),
- !cx.non_inlineable_statics.borrow().contains(&def_id.node))
+ (cx.const_values().borrow().get_copy(&def_id.node),
+ !cx.non_inlineable_statics().borrow().contains(&def_id.node))
}
pub fn const_expr(cx: &CrateContext, e: &ast::Expr, is_local: bool) -> (ValueRef, bool, ty::t) {
let mut inlineable = inlineable;
let ety = ty::expr_ty(cx.tcx(), e);
let mut ety_adjusted = ty::expr_ty_adjusted(cx.tcx(), e);
- let opt_adj = cx.tcx.adjustments.borrow().find_copy(&e.id);
+ let opt_adj = cx.tcx().adjustments.borrow().find_copy(&e.id);
match opt_adj {
None => { }
Some(adj) => {
match adj {
- ty::AutoAddEnv(ty::RegionTraitStore(ty::ReStatic, _)) => {
+ ty::AdjustAddEnv(ty::RegionTraitStore(ty::ReStatic, _)) => {
let def = ty::resolve_expr(cx.tcx(), e);
let wrapper = closure::get_wrapper_for_bare_fn(cx,
ety_adjusted,
is_local);
llconst = C_struct(cx, [wrapper, C_null(Type::i8p(cx))], false)
}
- ty::AutoAddEnv(store) => {
+ ty::AdjustAddEnv(store) => {
cx.sess()
.span_bug(e.span,
format!("unexpected static function: {:?}",
store).as_slice())
}
- ty::AutoDerefRef(ref adj) => {
+ ty::AdjustDerefRef(ref adj) => {
let mut ty = ety;
// Save the last autoderef in case we can avoid it.
if adj.autoderefs > 0 {
// if it's assigned to a static.
fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
is_local: bool) -> (ValueRef, bool) {
- let map_list = |exprs: &[Gc<ast::Expr>]| {
+ let map_list = |exprs: &[P<ast::Expr>]| {
exprs.iter().map(|e| first_two(const_expr(cx, &**e, is_local)))
.fold((Vec::new(), true),
|(l, all_inlineable), (val, inlineable)| {
let _icx = push_ctxt("const_expr");
return match e.node {
ast::ExprLit(ref lit) => {
- (consts::const_lit(cx, e, (**lit).clone()), true)
+ (consts::const_lit(cx, e, &**lit), true)
}
ast::ExprBinary(b, ref e1, ref e2) => {
let (te1, _, _) = const_expr(cx, &**e1, is_local);
(adt::const_get_field(cx, &*brepr, bv, discr, ix), inlineable)
})
}
+ ast::ExprTupField(ref base, idx, _) => {
+ let (bv, inlineable, bt) = const_expr(cx, &**base, is_local);
+ let brepr = adt::represent_type(cx, bt);
+ expr::with_field_tys(cx.tcx(), bt, None, |discr, _| {
+ (adt::const_get_field(cx, &*brepr, bv, discr, idx.node), inlineable)
+ })
+ }
ast::ExprIndex(ref base, ref index) => {
let (bv, inlineable, bt) = const_expr(cx, &**base, is_local);
(expr::cast_enum, expr::cast_integral) => {
let repr = adt::represent_type(cx, basety);
let discr = adt::const_get_discrim(cx, &*repr, v);
- let iv = C_integral(cx.int_type, discr, false);
+ let iv = C_integral(cx.int_type(), discr, false);
let ety_cast = expr::cast_type_kind(cx.tcx(), ety);
match ety_cast {
expr::cast_integral => {
}
}
}
- ast::ExprCall(callee, ref args) => {
+ ast::ExprCall(ref callee, ref args) => {
let opt_def = cx.tcx().def_map.borrow().find_copy(&callee.id);
match opt_def {
Some(def::DefStruct(_)) => {
let g = base::get_item_val(ccx, id);
// At this point, get_item_val has already translated the
// constant's initializer to determine its LLVM type.
- let v = ccx.const_values.borrow().get_copy(&id);
+ let v = ccx.const_values().borrow().get_copy(&id);
llvm::LLVMSetInitializer(g, v);
+
+ // `get_item_val` left `g` with external linkage, but we just set an
+ // initializer for it. But we don't know yet if `g` should really be
+ // defined in this compilation unit, so we set its linkage to
+ // `AvailableExternallyLinkage`. (It's still a definition, but acts
+ // like a declaration for most purposes.) If `g` really should be
+ // declared here, then `trans_item` will fix up the linkage later on.
+ llvm::SetLinkage(g, llvm::AvailableExternallyLinkage);
+
if m != ast::MutMutable {
llvm::LLVMSetGlobalConstant(g, True);
}