Skip to content

Commit

Permalink
Change ast::meta_name_value to accept any literal, not just string
Browse files Browse the repository at this point in the history
This isn't useful for much of anything yet, since metadata::encoder doesn't
know how to handle the non-string variants.

Issue #611
  • Loading branch information
brson committed Jul 6, 2011
1 parent 8261d2e commit 2cb1293
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 51 deletions.
25 changes: 16 additions & 9 deletions src/comp/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import std::sha1::sha1;
import std::sort;
import trans::crate_ctxt;
import syntax::ast;
import syntax::print::pprust;
import lib::llvm::llvm::ModuleRef;
import lib::llvm::llvm::ValueRef;
import lib::llvm::mk_pass_manager;
Expand Down Expand Up @@ -294,16 +295,18 @@ fn build_link_meta(&session::session sess, &ast::crate c,
auto linkage_metas = attr::find_linkage_metas(c.node.attrs);
attr::require_unique_names(sess, linkage_metas);
for (@ast::meta_item meta in linkage_metas) {
alt (meta.node) {
case (ast::meta_name_value("name", ?v)) {
name = some(v);
if (attr::get_meta_item_name(meta) == "name") {
alt (attr::get_meta_item_value_str(meta)) {
case (some(?v)) { name = some(v); }
case (none) { cmh_items += [meta]; }
}
case (ast::meta_name_value("vers", ?v)) {
vers = some(v);
}
case (_) {
cmh_items += [meta];
} else if (attr::get_meta_item_name(meta) == "vers") {
alt (attr::get_meta_item_value_str(meta)) {
case (some(?v)) { vers = some(v); }
case (none) { cmh_items += [meta]; }
}
} else {
cmh_items += [meta];
}
}
ret rec(name = name,
Expand All @@ -317,6 +320,10 @@ fn build_link_meta(&session::session sess, &ast::crate c,
fn len_and_str(&str s) -> str {
ret #fmt("%u_%s", str::byte_len(s), s);
}

fn len_and_str_lit(&ast::lit l) -> str {
ret len_and_str(pprust::lit_to_str(@l));
}

auto cmh_items = attr::sort_meta_items(metas.cmh_items);

Expand All @@ -326,7 +333,7 @@ fn build_link_meta(&session::session sess, &ast::crate c,
alt (m.node) {
case (ast::meta_name_value(?key, ?value)) {
sha.input_str(len_and_str(key));
sha.input_str(len_and_str(value));
sha.input_str(len_and_str_lit(value));
}
case (ast::meta_word(?name)) {
sha.input_str(len_and_str(name));
Expand Down
2 changes: 1 addition & 1 deletion src/comp/driver/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ fn default_configuration(session::session sess, str argv0, str input) ->
case (_) { "libc.so" }
};

auto mk = attr::mk_name_value_item;
auto mk = attr::mk_name_value_item_str;

ret [ // Target bindings.
mk("target_os", std::os::target_os()),
Expand Down
33 changes: 30 additions & 3 deletions src/comp/front/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import syntax::ast;
import util::common;
import driver::session;

export attr_meta;
export attr_metas;
export find_linkage_metas;
export find_attrs_by_name;
Expand All @@ -17,6 +18,9 @@ export sort_meta_items;
export remove_meta_items_by_name;
export require_unique_names;
export get_attr_name;
export get_meta_item_name;
export get_meta_item_value_str;
export mk_name_value_item_str;
export mk_name_value_item;
export mk_list_item;
export mk_word_item;
Expand Down Expand Up @@ -78,9 +82,25 @@ fn get_meta_item_name(&@ast::meta_item meta) -> ast::ident {
}
}

// Gets the string value if the meta_item is a meta_name_value variant
// containing a string, otherwise none
fn get_meta_item_value_str(&@ast::meta_item meta) -> option::t[str] {
alt (meta.node) {
case (ast::meta_name_value(_, ?v)) {
alt (v.node) {
case (ast::lit_str(?s, _)) {
option::some(s)
}
case (_) { option::none }
}
}
case (_) { option::none }
}
}

fn attr_meta(&ast::attribute attr) -> @ast::meta_item { @attr.node.value }

// Get the meta_items from inside an attribute
// Get the meta_items from inside a vector of attributes
fn attr_metas(&vec[ast::attribute] attrs) -> vec[@ast::meta_item] {
ret vec::map(attr_meta, attrs);
}
Expand All @@ -95,7 +115,9 @@ fn eq(@ast::meta_item a, @ast::meta_item b) -> bool {
}
case (ast::meta_name_value(?na, ?va)) {
alt (b.node) {
case (ast::meta_name_value(?nb, ?vb)) { na == nb && va == vb }
case (ast::meta_name_value(?nb, ?vb)) {
na == nb && va.node == vb.node
}
case (_) { false }
}
}
Expand Down Expand Up @@ -188,7 +210,12 @@ fn span[T](&T item) -> ast::spanned[T] {
ret rec(node=item, span=rec(lo=0u, hi=0u));
}

fn mk_name_value_item(ast::ident name, str value) -> @ast::meta_item {
fn mk_name_value_item_str(ast::ident name, str value) -> @ast::meta_item {
auto value_lit = span(ast::lit_str(value, ast::sk_rc));
ret mk_name_value_item(name, value_lit);
}

fn mk_name_value_item(ast::ident name, ast::lit value) -> @ast::meta_item {
ret @span(ast::meta_name_value(name, value));
}

Expand Down
20 changes: 8 additions & 12 deletions src/comp/metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ fn find_library_crate(&session::session sess, &ast::ident ident,
auto name_items = attr::find_meta_items_by_name(metas, "name");
alt (vec::last(name_items)) {
case (some(?i)) {
alt (i.node) {
case (ast::meta_name_value(_, ?v)) { v }
alt (attr::get_meta_item_value_str(i)) {
case (some(?n)) { n }
case (_) {
// FIXME: Probably want a warning here since the user
// is using the wrong type of meta item
Expand Down Expand Up @@ -180,17 +180,13 @@ fn visit_item(env e, &@ast::item i) {
if (!e.sess.add_used_library(m.native_name)) {
ret;
}
for (ast::attribute a in i.attrs) {
auto v = a.node.value.node;
alt (v) {
case (ast::meta_name_value(?i, ?s)) {
if (i != "link_args") {
cont;
}
e.sess.add_used_link_args(s);
}
case (_) {
for (ast::attribute a in
attr::find_attrs_by_name(i.attrs, "link_args")) {
alt (attr::get_meta_item_value_str(attr::attr_meta(a))) {
case (some(?linkarg)) {
e.sess.add_used_link_args(linkarg);
}
case (none) { /* fallthrough */ }
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/comp/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,9 @@ fn get_meta_items(&ebml::doc md) -> vec[@ast::meta_item] {
auto vd = ebml::get_doc(meta_item_doc, tag_meta_item_value);
auto n = str::unsafe_from_bytes(ebml::doc_data(nd));
auto v = str::unsafe_from_bytes(ebml::doc_data(vd));
items += [attr::mk_name_value_item(n, v)];
// FIXME (#611): Should be able to decode meta_name_value variants,
// but currently they can't be encoded
items += [attr::mk_name_value_item_str(n, v)];
}
for each (ebml::doc meta_item_doc in
ebml::tagged_docs(md, tag_meta_item_list)) {
Expand Down
29 changes: 17 additions & 12 deletions src/comp/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,14 +429,19 @@ fn encode_meta_item(&ebml::writer ebml_w, &meta_item mi) {
ebml::end_tag(ebml_w);
}
case (meta_name_value(?name, ?value)) {
ebml::start_tag(ebml_w, tag_meta_item_name_value);
ebml::start_tag(ebml_w, tag_meta_item_name);
ebml_w.writer.write(str::bytes(name));
ebml::end_tag(ebml_w);
ebml::start_tag(ebml_w, tag_meta_item_value);
ebml_w.writer.write(str::bytes(value));
ebml::end_tag(ebml_w);
ebml::end_tag(ebml_w);
alt (value.node) {
case (lit_str(?value, _)) {
ebml::start_tag(ebml_w, tag_meta_item_name_value);
ebml::start_tag(ebml_w, tag_meta_item_name);
ebml_w.writer.write(str::bytes(name));
ebml::end_tag(ebml_w);
ebml::start_tag(ebml_w, tag_meta_item_value);
ebml_w.writer.write(str::bytes(value));
ebml::end_tag(ebml_w);
ebml::end_tag(ebml_w);
}
case (_) { /* FIXME (#611) */ }
}
}
case (meta_list(?name, ?items)) {
ebml::start_tag(ebml_w, tag_meta_item_list);
Expand Down Expand Up @@ -475,10 +480,10 @@ fn synthesize_crate_attrs(&@crate_ctxt cx,
assert cx.link_meta.name != "";
assert cx.link_meta.vers != "";

auto name_item = attr::mk_name_value_item("name",
cx.link_meta.name);
auto vers_item = attr::mk_name_value_item("vers",
cx.link_meta.vers);
auto name_item = attr::mk_name_value_item_str("name",
cx.link_meta.name);
auto vers_item = attr::mk_name_value_item_str("vers",
cx.link_meta.vers);

auto other_items = {
auto tmp = attr::remove_meta_items_by_name(items, "name");
Expand Down
2 changes: 1 addition & 1 deletion src/comp/syntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ type meta_item = spanned[meta_item_];
tag meta_item_ {
meta_word(ident);
meta_list(ident, vec[@meta_item]);
meta_name_value(ident, str);
meta_name_value(ident, lit);
}

type block = spanned[block_];
Expand Down
14 changes: 3 additions & 11 deletions src/comp/syntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2172,17 +2172,9 @@ fn parse_meta_item(&parser p) -> @ast::meta_item {
alt (p.peek()) {
case (token::EQ) {
p.bump();
alt (p.peek()) {
case (token::LIT_STR(?s)) {
p.bump();
auto value = p.get_str(s);
auto hi = p.get_hi_pos();
ret @spanned(lo, hi, ast::meta_name_value(ident, value));
}
case (_) {
p.fatal("Metadata items must be string literals");
}
}
auto lit = parse_lit(p);
auto hi = p.get_hi_pos();
ret @spanned(lo, hi, ast::meta_name_value(ident, lit));
}
case (token::LPAREN) {
auto inner_items = parse_meta_seq(p);
Expand Down
2 changes: 1 addition & 1 deletion src/comp/syntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,7 @@ fn print_meta_item(&ps s, &@ast::meta_item item) {
case (ast::meta_name_value(?name, ?value)) {
word_space(s, name);
word_space(s, "=");
print_string(s, value);
print_literal(s, @value);
}
case (ast::meta_list(?name, ?items)) {
word(s.s, name);
Expand Down
14 changes: 14 additions & 0 deletions src/test/run-pass/item-attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,20 @@ mod test_native_items {
}
}

mod test_literals {
#[str = "s"];
#[char = 'c'];
#[int = 100];
#[uint = 100u];
#[mach_int = 100u32];
#[float = 1.0];
#[mach_float = 1.0f32];
// FIXME (#622): Can't parse a nil literal here
//#[nil = ()];
#[bool = true];
mod m {}
}

fn main() {
}

Expand Down

0 comments on commit 2cb1293

Please sign in to comment.