Translate const vecs, most of const slices. More for #2317.
This commit is contained in:
parent
f23674394f
commit
edfc79cc47
4 changed files with 58 additions and 10 deletions
|
|
@ -66,10 +66,7 @@ fn check_expr(sess: session, def_map: resolve3::DefMap,
|
|||
~"disallowed operator in constant expression");
|
||||
return;
|
||||
}
|
||||
expr_lit(@{node: lit_str(_), _}) {
|
||||
sess.span_err(e.span,
|
||||
~"string constants are not supported");
|
||||
}
|
||||
expr_lit(@{node: lit_str(_), _}) { }
|
||||
expr_binary(_, _, _) | expr_unary(_, _) {
|
||||
if method_map.contains_key(e.id) {
|
||||
sess.span_err(e.span, ~"user-defined operators are not \
|
||||
|
|
@ -101,6 +98,9 @@ fn check_expr(sess: session, def_map: resolve3::DefMap,
|
|||
}
|
||||
}
|
||||
}
|
||||
expr_vstore(_, vstore_slice(_)) |
|
||||
expr_vstore(_, vstore_fixed(_)) |
|
||||
expr_vec(_, m_imm) |
|
||||
expr_addr_of(m_imm, _) |
|
||||
expr_tup(*) |
|
||||
expr_rec(*) { }
|
||||
|
|
|
|||
|
|
@ -25,21 +25,29 @@ fn const_lit(cx: @crate_ctxt, e: @ast::expr, lit: ast::lit)
|
|||
ast::lit_float(fs, t) { C_floating(*fs, T_float_ty(cx, t)) }
|
||||
ast::lit_bool(b) { C_bool(b) }
|
||||
ast::lit_nil { C_nil() }
|
||||
ast::lit_str(s) {
|
||||
cx.sess.span_unimpl(lit.span, ~"unique string in this context");
|
||||
}
|
||||
ast::lit_str(s) { C_estr_slice(cx, *s) }
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME (#2530): this should do some structural hash-consing to avoid
|
||||
// duplicate constants. I think. Maybe LLVM has a magical mode that does so
|
||||
// later on?
|
||||
|
||||
fn const_vec_and_sz(cx: @crate_ctxt, e: @ast::expr, es: &[@ast::expr])
|
||||
-> (ValueRef, ValueRef) {
|
||||
let vec_ty = ty::expr_ty(cx.tcx, e);
|
||||
let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
|
||||
let llunitty = type_of::type_of(cx, unit_ty);
|
||||
let v = C_array(llunitty, es.map(|e| const_expr(cx, e)));
|
||||
let unit_sz = shape::llsize_of(cx, llunitty);
|
||||
let sz = llvm::LLVMConstMul(C_uint(cx, es.len()), unit_sz);
|
||||
return (v, sz);
|
||||
}
|
||||
|
||||
fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
|
||||
let _icx = cx.insn_ctxt(~"const_expr");
|
||||
alt e.node {
|
||||
ast::expr_lit(lit) { consts::const_lit(cx, e, *lit) }
|
||||
// If we have a vstore, just keep going; it has to be a string
|
||||
ast::expr_vstore(e, _) { const_expr(cx, e) }
|
||||
ast::expr_binary(b, e1, e2) {
|
||||
let te1 = const_expr(cx, e1);
|
||||
let te2 = const_expr(cx, e2);
|
||||
|
|
@ -147,6 +155,37 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
|
|||
ast::expr_rec(fs, none) {
|
||||
C_struct(fs.map(|f| const_expr(cx, f.node.expr)))
|
||||
}
|
||||
ast::expr_vec(es, m_imm) {
|
||||
let (v, _) = const_vec_and_sz(cx, e, es);
|
||||
v
|
||||
}
|
||||
ast::expr_vstore(e, ast::vstore_fixed(_)) {
|
||||
const_expr(cx, e)
|
||||
}
|
||||
ast::expr_vstore(sub, ast::vstore_slice(_)) {
|
||||
alt sub.node {
|
||||
ast::expr_lit(lit) {
|
||||
alt lit.node {
|
||||
ast::lit_str(*) => { const_expr(cx, sub) }
|
||||
_ => { cx.sess.span_bug(e.span,
|
||||
~"bad const-slice lit") }
|
||||
}
|
||||
}
|
||||
ast::expr_vec(es, m_imm) => {
|
||||
let (cv, sz) = const_vec_and_sz(cx, e, es);
|
||||
let subty = ty::expr_ty(cx.tcx, sub),
|
||||
llty = type_of::type_of(cx, subty);
|
||||
let gv = do str::as_c_str("const") |name| {
|
||||
llvm::LLVMAddGlobal(cx.llmod, llty, name)
|
||||
};
|
||||
llvm::LLVMSetInitializer(gv, cv);
|
||||
llvm::LLVMSetGlobalConstant(gv, True);
|
||||
C_struct(~[gv, sz])
|
||||
}
|
||||
_ => cx.sess.span_bug(e.span,
|
||||
~"bad const-slice expr")
|
||||
}
|
||||
}
|
||||
ast::expr_path(path) {
|
||||
alt cx.tcx.def_map.find(e.id) {
|
||||
some(ast::def_const(def_id)) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ const x: &int = &10;
|
|||
const y: &{a: int, b: &int} = &{a: 15, b: x};
|
||||
|
||||
fn main() {
|
||||
io::println(fmt!("x = %?", x));
|
||||
io::println(fmt!("x = %?", *x));
|
||||
io::println(fmt!("y = {a: %?, b: %?}", y.a, *(y.b)));
|
||||
assert *x == 10;
|
||||
assert *(y.b) == 10;
|
||||
}
|
||||
|
|
|
|||
7
src/test/run-pass/const-vecs-and-slices.rs
Normal file
7
src/test/run-pass/const-vecs-and-slices.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
const x : [int]/4 = [1,2,3,4];
|
||||
|
||||
fn main() {
|
||||
io::println(fmt!("%?", x[1]));
|
||||
assert x[1] == 2;
|
||||
assert x[3] == 4;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue