summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-03-28 03:51:51 -0700
committerbors <bors@rust-lang.org>2013-03-28 03:51:51 -0700
commit3dbf2c3c5c2032ad87e6975abdf854d780839d2d (patch)
tree7592710262ef9dab403d3af0c957d299d1177f94
parente549b80e3c214f93fc6ab9d7ead3f49b585faa23 (diff)
parent58338dd3d00075301ef2d43aeb0998f53776eebe (diff)
downloadrust-3dbf2c3c5c2032ad87e6975abdf854d780839d2d.tar.gz
rust-3dbf2c3c5c2032ad87e6975abdf854d780839d2d.zip
auto merge of #5592 : pcwalton/rust/xc-extern-statics, r=pcwalton
-rw-r--r--src/librustc/middle/trans/base.rs6
-rw-r--r--src/librustc/middle/trans/common.rs4
-rw-r--r--src/librustc/middle/trans/expr.rs36
3 files changed, 39 insertions, 7 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index fb05cf0b739..cfbd59073fe 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -2540,8 +2540,9 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::node_id) -> ValueRef {
             }
           }
 
-          _ => {
-            ccx.sess.bug(~"get_item_val(): unexpected variant")
+          ref variant => {
+            ccx.sess.bug(fmt!("get_item_val(): unexpected variant: %?",
+                              variant))
           }
         };
         if !(exprt || ccx.reachable.contains(&id)) {
@@ -3085,6 +3086,7 @@ pub fn trans_crate(sess: session::Session,
               const_cstr_cache: @mut LinearMap::new(),
               const_globals: @mut LinearMap::new(),
               const_values: @mut LinearMap::new(),
+              extern_const_values: @mut LinearMap::new(),
               module_data: @mut LinearMap::new(),
               lltypes: @mut LinearMap::new(),
               llsizingtypes: @mut LinearMap::new(),
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 5805f7fbe3a..541a950fb55 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -201,6 +201,10 @@ pub struct CrateContext {
 
      // Cache of emitted const values
      const_values: @mut LinearMap<ast::node_id, ValueRef>,
+
+     // Cache of external const values
+     extern_const_values: @mut LinearMap<ast::def_id, ValueRef>,
+
      module_data: @mut LinearMap<~str, ValueRef>,
      lltypes: @mut LinearMap<ty::t, TypeRef>,
      llsizingtypes: @mut LinearMap<ty::t, TypeRef>,
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 4ee63f8bf33..c6eec22ef2c 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -124,6 +124,7 @@ use core::prelude::*;
 use back::abi;
 use lib;
 use lib::llvm::{ValueRef, TypeRef, llvm, True};
+use metadata::csearch;
 use middle::borrowck::root_map_key;
 use middle::trans::_match;
 use middle::trans::adt;
@@ -150,6 +151,7 @@ use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn,
 use util::common::indenter;
 use util::ppaux::ty_to_str;
 
+use core::cast::transmute;
 use core::hashmap::linear::LinearMap;
 use syntax::print::pprust::{expr_to_str};
 use syntax::ast;
@@ -1079,11 +1081,35 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
 
                 fn get_val(bcx: block, did: ast::def_id, const_ty: ty::t)
                     -> ValueRef {
-                    // The LLVM global has the type of its initializer,
-                    // which may not be equal to the enum's type for
-                    // non-C-like enums.
-                    PointerCast(bcx, base::get_item_val(bcx.ccx(), did.node),
-                                T_ptr(type_of(bcx.ccx(), const_ty)))
+                    if did.crate == ast::local_crate {
+                        // The LLVM global has the type of its initializer,
+                        // which may not be equal to the enum's type for
+                        // non-C-like enums.
+                        PointerCast(bcx,
+                                    base::get_item_val(bcx.ccx(), did.node),
+                                    T_ptr(type_of(bcx.ccx(), const_ty)))
+                    } else {
+                        // For external constants, we don't inline.
+                        match bcx.ccx().extern_const_values.find(&did) {
+                            None => {
+                                unsafe {
+                                    let llty = type_of(bcx.ccx(), const_ty);
+                                    let symbol = csearch::get_symbol(
+                                        bcx.ccx().sess.cstore,
+                                        did);
+                                    let llval = llvm::LLVMAddGlobal(
+                                        bcx.ccx().llmod,
+                                        llty,
+                                        transmute::<&u8,*i8>(&symbol[0]));
+                                    bcx.ccx().extern_const_values.insert(
+                                        did,
+                                        llval);
+                                    llval
+                                }
+                            }
+                            Some(llval) => *llval
+                        }
+                    }
                 }
 
                 let did = get_did(ccx, did);