diff options
| author | Patrick Walton <[email protected]> | 2011-03-25 17:53:46 -0700 |
|---|---|---|
| committer | Patrick Walton <[email protected]> | 2011-03-25 17:54:48 -0700 |
| commit | 94c19a18ae8ddf70d0c6a21b296e0858dc154d2a (patch) | |
| tree | 8f8a88da05e45ba03c48cf82f9670a9d00991b7a /src/comp | |
| parent | Trans nomenclature tidy-up: upcall vs. native vs. extern. (diff) | |
| download | rust-94c19a18ae8ddf70d0c6a21b296e0858dc154d2a.tar.xz rust-94c19a18ae8ddf70d0c6a21b296e0858dc154d2a.zip | |
rustc: Look up names in "use"d crates
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/front/creader.rs | 124 | ||||
| -rw-r--r-- | src/comp/rustc.rc | 1 |
2 files changed, 120 insertions, 5 deletions
diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs index 08705715..977b7186 100644 --- a/src/comp/front/creader.rs +++ b/src/comp/front/creader.rs @@ -8,6 +8,7 @@ import lib.llvm.llvmext; import lib.llvm.mk_object_file; import lib.llvm.mk_section_iter; import middle.fold; +import middle.metadata; import middle.ty; import middle.typeck; import back.x86; @@ -16,8 +17,11 @@ import util.common.span; import std._str; import std._vec; +import std.ebml; import std.fs; +import std.io; import std.option; +import std.option.none; import std.option.some; import std.os; import std.map.hashmap; @@ -30,6 +34,11 @@ type env = @rec( mutable int next_crate_num ); +tag resolve_result { + rr_ok(ast.def_id); + rr_not_found(vec[ast.ident], ast.ident); +} + // Type decoding // Compact string representation for ty.t values. API ty_str & parse_from_str. @@ -213,10 +222,96 @@ impure fn parse_ty_fn(@pstate st, str_def sd) -> tup(vec[ty.arg], @ty.t) { // Rust metadata parsing -// TODO +fn parse_def_id(str s) -> ast.def_id { + ret tup(1, 0); // TODO +} + +// Given a path and serialized crate metadata, returns the ID of the +// definition the path refers to. +impure fn resolve_path(vec[ast.ident] path, vec[u8] data) -> resolve_result { + impure fn resolve_path_inner(vec[ast.ident] path, &ebml.reader ebml_r) + -> resolve_result { + auto i = 0u; + auto len = _vec.len[ast.ident](path); + while (i < len) { + auto name = path.(i); + auto last = i == len - 1u; + + // Search this level for the identifier. + auto found = false; + while (ebml.bytes_left(ebml_r) > 0u && !found) { + auto ebml_tag = ebml.peek(ebml_r); + check ((ebml_tag.id == metadata.tag_paths_item) || + (ebml_tag.id == metadata.tag_paths_mod)); + + ebml.move_to_first_child(ebml_r); + auto did_opt = none[ast.def_id]; + auto name_opt = none[ast.ident]; + while (ebml.bytes_left(ebml_r) > 0u) { + auto inner_tag = ebml.peek(ebml_r); + if (inner_tag.id == metadata.tag_paths_name) { + ebml.move_to_first_child(ebml_r); + auto name_data = ebml.read_data(ebml_r); + ebml.move_to_parent(ebml_r); + auto nm = _str.unsafe_from_bytes(name_data); + name_opt = some[ast.ident](nm); + } else if (inner_tag.id == metadata.tag_items_def_id) { + ebml.move_to_first_child(ebml_r); + auto did_data = ebml.read_data(ebml_r); + ebml.move_to_parent(ebml_r); + auto did_str = _str.unsafe_from_bytes(did_data); + log "did_str: " + did_str; + did_opt = some[ast.def_id](parse_def_id(did_str)); + } + ebml.move_to_next_sibling(ebml_r); + } + ebml.move_to_parent(ebml_r); + + if (_str.eq(option.get[ast.ident](name_opt), name)) { + // Matched! + if (last) { + ret rr_ok(option.get[ast.def_id](did_opt)); + } + + // Move to the module/item we found for the next iteration + // of the loop... + ebml.move_to_first_child(ebml_r); + found = true; + } + + ebml.move_to_next_sibling(ebml_r); + } + + if (!found) { + auto prev = _vec.slice[ast.ident](path, 0u, i); + ret rr_not_found(prev, name); + } + + i += 1u; + } + + fail; // not reached + } + + auto io_r = io.new_reader_(io.new_byte_buf_reader(data)); + auto ebml_r = ebml.create_reader(io_r); + while (ebml.bytes_left(ebml_r) > 0u) { + auto ebml_tag = ebml.peek(ebml_r); + log #fmt("outer ebml tag id: %u", ebml_tag.id); + if (ebml_tag.id == metadata.tag_paths) { + ebml.move_to_first_child(ebml_r); + ret resolve_path_inner(path, ebml_r); + } + ebml.move_to_next_sibling(ebml_r); + } + + log "resolve_path(): no names in file"; + fail; +} fn load_crate(session.session sess, + int cnum, ast.ident ident, vec[str] library_search_paths) { auto filename = parser.default_native_name(sess, ident); @@ -235,6 +330,8 @@ fn load_crate(session.session sess, auto cbuf = llvmext.LLVMGetSectionContents(si.llsi); auto csz = llvmext.LLVMGetSectionSize(si.llsi); auto cvbuf = cbuf as _vec.vbuf; + auto cvec = _vec.vec_from_vbuf[u8](cvbuf, csz); + sess.set_external_crate(cnum, cvec); ret; } llvmext.LLVMMoveToNextSection(si.llsi); @@ -252,8 +349,8 @@ fn fold_view_item_use(&env e, &span sp, ast.ident ident, -> @ast.view_item { auto cnum; if (!e.crate_cache.contains_key(ident)) { - load_crate(e.sess, ident, e.library_search_paths); cnum = e.next_crate_num; + load_crate(e.sess, cnum, ident, e.library_search_paths); e.crate_cache.insert(ident, e.next_crate_num); e.next_crate_num += 1; } else { @@ -280,10 +377,27 @@ fn read_crates(session.session sess, ret fold.fold_crate[env](e, fld, crate); } + +// Crate metadata queries + fn lookup_def(session.session sess, &span sp, int cnum, vec[ast.ident] path) - -> ast.def { - // FIXME: fill in. - fail; + -> ast.def { + auto data = sess.get_external_crate(cnum); + + auto did; + alt (resolve_path(path, data)) { + case (rr_ok(?di)) { did = di; } + case (rr_not_found(?prev, ?name)) { + sess.span_err(sp, + #fmt("unbound name '%s' (no item named '%s' found in '%s')", + _str.connect(path, "."), name, _str.connect(prev, "."))); + fail; + } + } + + // TODO: Look up item type, use that to determine the type of def. + + fail; } fn get_type(session.session sess, ast.def_id def) -> typeck.ty_and_params { diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc index db1f1b24..64da7ad0 100644 --- a/src/comp/rustc.rc +++ b/src/comp/rustc.rc @@ -43,6 +43,7 @@ mod util { auth driver.rustc.main = impure; auth front.creader.load_crate = unsafe; +auth front.creader.lookup_def = impure; auth middle.metadata = unsafe; auth middle.trans = unsafe; auth middle.trans.copy_args_to_allocas = impure; |