about summary refs log tree commit diff
path: root/src/comp
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2011-03-29 13:21:16 -0700
committerGraydon Hoare <graydon@mozilla.com>2011-03-29 13:23:51 -0700
commit734abe593dc09edaea0f24978acf4f4270337361 (patch)
treeeaac6bb58a955617ec1ac47e031002a97931ac40 /src/comp
parent6936093992fc66fe544dff5697b593543f02e184 (diff)
downloadrust-734abe593dc09edaea0f24978acf4f4270337361.tar.gz
rust-734abe593dc09edaea0f24978acf4f4270337361.zip
Teach trans to emit undefined references to 'use'd symbols. Can compile and run a simple 'use std;' example now.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/ast.rs22
-rw-r--r--src/comp/front/creader.rs17
-rw-r--r--src/comp/middle/trans.rs21
-rw-r--r--src/comp/rustc.rc1
4 files changed, 61 insertions, 0 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 8458a749d20..4493bea8739 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -43,6 +43,28 @@ tag def {
     def_native_fn(def_id);
 }
 
+fn def_id_of_def(def d) -> def_id {
+    alt (d) {
+        case (def_fn(?id)) { ret id; }
+        case (def_obj(?id)) { ret id; }
+        case (def_obj_field(?id)) { ret id; }
+        case (def_mod(?id)) { ret id; }
+        case (def_native_mod(?id)) { ret id; }
+        case (def_const(?id)) { ret id; }
+        case (def_arg(?id)) { ret id; }
+        case (def_local(?id)) { ret id; }
+        case (def_upvar(?id)) { ret id; }
+        case (def_variant(_, ?id)) { ret id; }
+        case (def_ty(?id)) { ret id; }
+        case (def_ty_arg(?id)) { ret id; }
+        case (def_binding(?id)) { ret id; }
+        case (def_use(?id)) { ret id; }
+        case (def_native_ty(?id)) { ret id; }
+        case (def_native_fn(?id)) { ret id; }
+    }
+    fail;
+}
+
 type crate = spanned[crate_];
 type crate_ = rec(vec[@crate_directive] directives,
                   _mod module);
diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs
index dae18cb4283..735dbcb4ae5 100644
--- a/src/comp/front/creader.rs
+++ b/src/comp/front/creader.rs
@@ -403,6 +403,16 @@ impure fn get_item_kind(&ebml.reader ebml_r) -> u8 {
     ret get_item_generic[u8](ebml_r, metadata.tag_items_kind, f);
 }
 
+impure fn get_item_symbol(&ebml.reader ebml_r) -> str {
+    impure fn converter(vec[u8] data) -> str {
+        auto x = @mutable 3;
+        *x = 5;
+        ret _str.unsafe_from_bytes(data);
+    }
+    auto f = converter;
+    ret get_item_generic[str](ebml_r, metadata.tag_items_symbol, f);
+}
+
 // FIXME: This is a *terrible* botch.
 impure fn impure_parse_def_id(vec[u8] data) -> ast.def_id {
     auto x = @mutable 3;
@@ -573,6 +583,13 @@ fn get_type(session.session sess, ast.def_id def) -> ty.ty_params_and_ty {
     ret tup(tps, t);
 }
 
+fn get_symbol(session.session sess, ast.def_id def) -> str {
+    auto external_crate_id = def._0;
+    auto data = sess.get_external_crate(external_crate_id);
+    auto ebml_r = lookup_item(def._1, data);
+    ret get_item_symbol(ebml_r);
+}
+
 // Local Variables:
 // mode: rust
 // fill-column: 78;
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 3995e1de571..551a63486d5 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -11,6 +11,7 @@ import std.option.some;
 import std.option.none;
 
 import front.ast;
+import front.creader;
 import driver.session;
 import middle.ty;
 import back.x86;
@@ -3606,10 +3607,30 @@ fn lval_generic_fn(@block_ctxt cx,
     ret lv;
 }
 
+fn trans_external_path(@block_ctxt cx, &ast.path p,
+                       ast.def def, ast.ann a) -> lval_result {
+    auto ccx = cx.fcx.ccx;
+    auto ty = node_ann_type(ccx, a);
+    auto name = creader.get_symbol(ccx.sess, ast.def_id_of_def(def));
+    auto v = get_extern_const(ccx.externs, ccx.llmod,
+                              name, type_of(ccx, ty));
+    ret lval_mem(cx, v);
+}
+
+fn def_is_external(@crate_ctxt cx, ast.def d) -> bool {
+    auto id = ast.def_id_of_def(d);
+    ret id._0 != cx.sess.get_targ_crate_num();
+}
+
 fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt,
               &ast.ann ann) -> lval_result {
     alt (dopt) {
         case (some[ast.def](?def)) {
+
+            if (def_is_external(cx.fcx.ccx, def)) {
+                ret trans_external_path(cx, p, def, ann);
+            }
+
             alt (def) {
                 case (ast.def_arg(?did)) {
                     alt (cx.fcx.llargs.find(did)) {
diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc
index 174fdcfaf3b..1ae9be79b95 100644
--- a/src/comp/rustc.rc
+++ b/src/comp/rustc.rc
@@ -45,6 +45,7 @@ auth driver.rustc.main = impure;
 auth front.creader.load_crate = unsafe;
 auth front.creader.lookup_def = impure;
 auth front.creader.get_type = impure;
+auth front.creader.get_symbol = impure;
 auth front.creader.impure_no_op = impure;
 auth middle.metadata = unsafe;
 auth middle.trans = unsafe;