Change ast::meta_name_value to accept any literal, not just string

This isn't useful for much of anything yet, since metadata::encoder doesn't
know how to handle the non-string variants.

Issue #611
This commit is contained in:
Brian Anderson 2011-07-05 17:01:23 -07:00
parent 8261d2e6fb
commit 2cb129355b
10 changed files with 94 additions and 51 deletions

View file

@ -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;
@ -294,18 +295,20 @@ 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);
} 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]; }
}
case (_) {
} else {
cmh_items += [meta];
}
}
}
ret rec(name = name,
vers = vers,
cmh_items = cmh_items);
@ -318,6 +321,10 @@ fn build_link_meta(&session::session sess, &ast::crate c,
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);
sha.reset();
@ -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));

View file

@ -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()),

View file

@ -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;
@ -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;
@ -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);
}
@ -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 }
}
}
@ -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));
}

View file

@ -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
@ -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 */ }
}
}
}

View file

@ -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)) {

View file

@ -429,6 +429,8 @@ fn encode_meta_item(&ebml::writer ebml_w, &meta_item mi) {
ebml::end_tag(ebml_w);
}
case (meta_name_value(?name, ?value)) {
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));
@ -438,6 +440,9 @@ fn encode_meta_item(&ebml::writer ebml_w, &meta_item mi) {
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);
ebml::start_tag(ebml_w, tag_meta_item_name);
@ -475,9 +480,9 @@ 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",
auto name_item = attr::mk_name_value_item_str("name",
cx.link_meta.name);
auto vers_item = attr::mk_name_value_item("vers",
auto vers_item = attr::mk_name_value_item_str("vers",
cx.link_meta.vers);
auto other_items = {

View file

@ -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_];

View file

@ -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 lit = parse_lit(p);
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");
}
}
ret @spanned(lo, hi, ast::meta_name_value(ident, lit));
}
case (token::LPAREN) {
auto inner_items = parse_meta_seq(p);

View file

@ -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);

View file

@ -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() {
}