Skip to content

Commit 2a3084b

Browse files
committed
Start implementing structured constants.
1 parent 285fc53 commit 2a3084b

File tree

6 files changed

+196
-172
lines changed

6 files changed

+196
-172
lines changed

src/rustc/middle/check_const.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ fn check_expr(sess: session, def_map: resolve3::DefMap,
101101
}
102102
}
103103
}
104+
expr_tup(*) |
105+
expr_rec(*) { }
104106
_ {
105107
sess.span_err(e.span,
106108
~"constant contains unimplemented expression type");

src/rustc/middle/trans/alt.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,14 @@ fn trans_opt(bcx: block, o: opt) -> opt_result {
5858
}
5959
_ {
6060
ret single_result(
61-
rslt(bcx, trans_const_expr(ccx, l)));
61+
rslt(bcx, consts::const_expr(ccx, l)));
6262
}
6363
}
6464
}
6565
var(disr_val, _) { ret single_result(rslt(bcx, C_int(ccx, disr_val))); }
6666
range(l1, l2) {
67-
ret range_result(rslt(bcx, trans_const_expr(ccx, l1)),
68-
rslt(bcx, trans_const_expr(ccx, l2)));
67+
ret range_result(rslt(bcx, consts::const_expr(ccx, l1)),
68+
rslt(bcx, consts::const_expr(ccx, l2)));
6969
}
7070
}
7171
}

src/rustc/middle/trans/base.rs

Lines changed: 2 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,48 +1420,18 @@ fn store_temp_expr(cx: block, action: copy_action, dst: ValueRef,
14201420
ret move_val(cx, action, dst, src, t);
14211421
}
14221422

1423-
fn trans_crate_lit(cx: @crate_ctxt, e: @ast::expr, lit: ast::lit)
1424-
-> ValueRef {
1425-
let _icx = cx.insn_ctxt(~"trans_crate_lit");
1426-
alt lit.node {
1427-
ast::lit_int(i, t) { C_integral(T_int_ty(cx, t), i as u64, True) }
1428-
ast::lit_uint(u, t) { C_integral(T_uint_ty(cx, t), u, False) }
1429-
ast::lit_int_unsuffixed(i) {
1430-
let lit_int_ty = ty::node_id_to_type(cx.tcx, e.id);
1431-
alt ty::get(lit_int_ty).struct {
1432-
ty::ty_int(t) {
1433-
C_integral(T_int_ty(cx, t), i as u64, True)
1434-
}
1435-
ty::ty_uint(t) {
1436-
C_integral(T_uint_ty(cx, t), i as u64, False)
1437-
}
1438-
_ { cx.sess.span_bug(lit.span,
1439-
~"integer literal doesn't have a type");
1440-
}
1441-
}
1442-
}
1443-
ast::lit_float(fs, t) { C_floating(*fs, T_float_ty(cx, t)) }
1444-
ast::lit_bool(b) { C_bool(b) }
1445-
ast::lit_nil { C_nil() }
1446-
ast::lit_str(s) {
1447-
cx.sess.span_unimpl(lit.span, ~"unique string in this context");
1448-
}
1449-
}
1450-
}
1451-
14521423
fn trans_lit(cx: block, e: @ast::expr, lit: ast::lit, dest: dest) -> block {
14531424
let _icx = cx.insn_ctxt(~"trans_lit");
14541425
if dest == ignore { ret cx; }
14551426
alt lit.node {
14561427
ast::lit_str(s) { tvec::trans_estr(cx, s,
14571428
ast::vstore_fixed(none), dest) }
14581429
_ {
1459-
store_in_dest(cx, trans_crate_lit(cx.ccx(), e, lit), dest)
1430+
store_in_dest(cx, consts::const_lit(cx.ccx(), e, lit), dest)
14601431
}
14611432
}
14621433
}
14631434

1464-
14651435
fn trans_boxed_expr(bcx: block, contents: @ast::expr,
14661436
t: ty::t, heap: heap,
14671437
dest: dest) -> block {
@@ -1473,7 +1443,6 @@ fn trans_boxed_expr(bcx: block, contents: @ast::expr,
14731443
ret store_in_dest(bcx, box, dest);
14741444
}
14751445

1476-
14771446
fn trans_unary(bcx: block, op: ast::unop, e: @ast::expr,
14781447
un_expr: @ast::expr, dest: dest) -> block {
14791448
let _icx = bcx.insn_ctxt(~"trans_unary");
@@ -4716,142 +4685,6 @@ fn trans_enum_variant(ccx: @crate_ctxt, enum_id: ast::node_id,
47164685
finish_fn(fcx, lltop);
47174686
}
47184687

4719-
4720-
// FIXME (#2530): this should do some structural hash-consing to avoid
4721-
// duplicate constants. I think. Maybe LLVM has a magical mode that does so
4722-
// later on?
4723-
fn trans_const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
4724-
let _icx = cx.insn_ctxt(~"trans_const_expr");
4725-
alt e.node {
4726-
ast::expr_lit(lit) { trans_crate_lit(cx, e, *lit) }
4727-
// If we have a vstore, just keep going; it has to be a string
4728-
ast::expr_vstore(e, _) { trans_const_expr(cx, e) }
4729-
ast::expr_binary(b, e1, e2) {
4730-
let te1 = trans_const_expr(cx, e1);
4731-
let te2 = trans_const_expr(cx, e2);
4732-
4733-
let te2 = cast_shift_const_rhs(b, te1, te2);
4734-
4735-
/* Neither type is bottom, and we expect them to be unified already,
4736-
* so the following is safe. */
4737-
let ty = ty::expr_ty(cx.tcx, e1);
4738-
let is_float = ty::type_is_fp(ty);
4739-
let signed = ty::type_is_signed(ty);
4740-
ret alt b {
4741-
ast::add {
4742-
if is_float { llvm::LLVMConstFAdd(te1, te2) }
4743-
else { llvm::LLVMConstAdd(te1, te2) }
4744-
}
4745-
ast::subtract {
4746-
if is_float { llvm::LLVMConstFSub(te1, te2) }
4747-
else { llvm::LLVMConstSub(te1, te2) }
4748-
}
4749-
ast::mul {
4750-
if is_float { llvm::LLVMConstFMul(te1, te2) }
4751-
else { llvm::LLVMConstMul(te1, te2) }
4752-
}
4753-
ast::div {
4754-
if is_float { llvm::LLVMConstFDiv(te1, te2) }
4755-
else if signed { llvm::LLVMConstSDiv(te1, te2) }
4756-
else { llvm::LLVMConstUDiv(te1, te2) }
4757-
}
4758-
ast::rem {
4759-
if is_float { llvm::LLVMConstFRem(te1, te2) }
4760-
else if signed { llvm::LLVMConstSRem(te1, te2) }
4761-
else { llvm::LLVMConstURem(te1, te2) }
4762-
}
4763-
ast::and |
4764-
ast::or { cx.sess.span_unimpl(e.span, ~"binop logic"); }
4765-
ast::bitxor { llvm::LLVMConstXor(te1, te2) }
4766-
ast::bitand { llvm::LLVMConstAnd(te1, te2) }
4767-
ast::bitor { llvm::LLVMConstOr(te1, te2) }
4768-
ast::shl { llvm::LLVMConstShl(te1, te2) }
4769-
ast::shr {
4770-
if signed { llvm::LLVMConstAShr(te1, te2) }
4771-
else { llvm::LLVMConstLShr(te1, te2) }
4772-
}
4773-
ast::eq |
4774-
ast::lt |
4775-
ast::le |
4776-
ast::ne |
4777-
ast::ge |
4778-
ast::gt { cx.sess.span_unimpl(e.span, ~"binop comparator"); }
4779-
}
4780-
}
4781-
ast::expr_unary(u, e) {
4782-
let te = trans_const_expr(cx, e);
4783-
let ty = ty::expr_ty(cx.tcx, e);
4784-
let is_float = ty::type_is_fp(ty);
4785-
ret alt u {
4786-
ast::box(_) |
4787-
ast::uniq(_) |
4788-
ast::deref { cx.sess.span_bug(e.span,
4789-
~"bad unop type in trans_const_expr"); }
4790-
ast::not { llvm::LLVMConstNot(te) }
4791-
ast::neg {
4792-
if is_float { llvm::LLVMConstFNeg(te) }
4793-
else { llvm::LLVMConstNeg(te) }
4794-
}
4795-
}
4796-
}
4797-
ast::expr_cast(base, tp) {
4798-
let ety = ty::expr_ty(cx.tcx, e), llty = type_of(cx, ety);
4799-
let basety = ty::expr_ty(cx.tcx, base);
4800-
let v = trans_const_expr(cx, base);
4801-
alt check (cast_type_kind(basety), cast_type_kind(ety)) {
4802-
(cast_integral, cast_integral) {
4803-
let s = if ty::type_is_signed(basety) { True } else { False };
4804-
llvm::LLVMConstIntCast(v, llty, s)
4805-
}
4806-
(cast_integral, cast_float) {
4807-
if ty::type_is_signed(basety) { llvm::LLVMConstSIToFP(v, llty) }
4808-
else { llvm::LLVMConstUIToFP(v, llty) }
4809-
}
4810-
(cast_float, cast_float) { llvm::LLVMConstFPCast(v, llty) }
4811-
(cast_float, cast_integral) {
4812-
if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty) }
4813-
else { llvm::LLVMConstFPToUI(v, llty) }
4814-
}
4815-
}
4816-
}
4817-
ast::expr_path(path) {
4818-
alt cx.tcx.def_map.find(e.id) {
4819-
some(ast::def_const(def_id)) {
4820-
// Don't know how to handle external consts
4821-
assert ast_util::is_local(def_id);
4822-
alt cx.tcx.items.get(def_id.node) {
4823-
ast_map::node_item(@{
4824-
node: ast::item_const(_, subexpr), _
4825-
}, _) {
4826-
// FIXME (#2530): Instead of recursing here to regenerate
4827-
// the values for other constants, we should just look up
4828-
// the already-defined value.
4829-
trans_const_expr(cx, subexpr)
4830-
}
4831-
_ {
4832-
cx.sess.span_bug(e.span, ~"expected item");
4833-
}
4834-
}
4835-
}
4836-
_ { cx.sess.span_bug(e.span, ~"expected to find a const def") }
4837-
}
4838-
}
4839-
_ { cx.sess.span_bug(e.span,
4840-
~"bad constant expression type in trans_const_expr"); }
4841-
}
4842-
}
4843-
4844-
fn trans_const(ccx: @crate_ctxt, e: @ast::expr, id: ast::node_id) {
4845-
let _icx = ccx.insn_ctxt(~"trans_const");
4846-
let v = trans_const_expr(ccx, e);
4847-
4848-
// The scalars come back as 1st class LLVM vals
4849-
// which we have to stick into global constants.
4850-
let g = get_item_val(ccx, id);
4851-
llvm::LLVMSetInitializer(g, v);
4852-
llvm::LLVMSetGlobalConstant(g, True);
4853-
}
4854-
48554688
fn trans_class_ctor(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
48564689
body: ast::blk, llctor_decl: ValueRef,
48574690
psubsts: param_substs, ctor_id: ast::node_id,
@@ -5008,7 +4841,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
50084841
}
50094842
}
50104843
}
5011-
ast::item_const(_, expr) { trans_const(ccx, expr, item.id); }
4844+
ast::item_const(_, expr) { consts::trans_const(ccx, expr, item.id); }
50124845
ast::item_foreign_mod(foreign_mod) {
50134846
let abi = alt attr::foreign_abi(item.attrs) {
50144847
either::right(abi_) { abi_ }

0 commit comments

Comments
 (0)