@@ -25,21 +25,29 @@ fn const_lit(cx: @crate_ctxt, e: @ast::expr, lit: ast::lit)
25
25
ast::lit_float(fs, t) { C_floating(*fs, T_float_ty(cx, t)) }
26
26
ast::lit_bool(b) { C_bool(b) }
27
27
ast::lit_nil { C_nil() }
28
- ast::lit_str(s) {
29
- cx.sess.span_unimpl(lit.span, ~"unique string in this context");
30
- }
28
+ ast::lit_str(s) { C_estr_slice(cx, *s) }
31
29
}
32
30
}
33
31
34
32
// FIXME (#2530): this should do some structural hash-consing to avoid
35
33
// duplicate constants. I think. Maybe LLVM has a magical mode that does so
36
34
// later on?
35
+
36
+ fn const_vec_and_sz(cx: @crate_ctxt, e: @ast::expr, es: &[@ast::expr])
37
+ -> (ValueRef, ValueRef) {
38
+ let vec_ty = ty::expr_ty(cx.tcx, e);
39
+ let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty);
40
+ let llunitty = type_of::type_of(cx, unit_ty);
41
+ let v = C_array(llunitty, es.map(|e| const_expr(cx, e)));
42
+ let unit_sz = shape::llsize_of(cx, llunitty);
43
+ let sz = llvm::LLVMConstMul(C_uint(cx, es.len()), unit_sz);
44
+ return (v, sz);
45
+ }
46
+
37
47
fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
38
48
let _icx = cx.insn_ctxt(~"const_expr");
39
49
alt e.node {
40
50
ast::expr_lit(lit) { consts::const_lit(cx, e, *lit) }
41
- // If we have a vstore, just keep going; it has to be a string
42
- ast::expr_vstore(e, _) { const_expr(cx, e) }
43
51
ast::expr_binary(b, e1, e2) {
44
52
let te1 = const_expr(cx, e1);
45
53
let te2 = const_expr(cx, e2);
@@ -147,6 +155,37 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
147
155
ast::expr_rec(fs, none) {
148
156
C_struct(fs.map(|f| const_expr(cx, f.node.expr)))
149
157
}
158
+ ast::expr_vec(es, m_imm) {
159
+ let (v, _) = const_vec_and_sz(cx, e, es);
160
+ v
161
+ }
162
+ ast::expr_vstore(e, ast::vstore_fixed(_)) {
163
+ const_expr(cx, e)
164
+ }
165
+ ast::expr_vstore(sub, ast::vstore_slice(_)) {
166
+ alt sub.node {
167
+ ast::expr_lit(lit) {
168
+ alt lit.node {
169
+ ast::lit_str(*) => { const_expr(cx, sub) }
170
+ _ => { cx.sess.span_bug(e.span,
171
+ ~"bad const-slice lit") }
172
+ }
173
+ }
174
+ ast::expr_vec(es, m_imm) => {
175
+ let (cv, sz) = const_vec_and_sz(cx, e, es);
176
+ let subty = ty::expr_ty(cx.tcx, sub),
177
+ llty = type_of::type_of(cx, subty);
178
+ let gv = do str::as_c_str("const") |name| {
179
+ llvm::LLVMAddGlobal(cx.llmod, llty, name)
180
+ };
181
+ llvm::LLVMSetInitializer(gv, cv);
182
+ llvm::LLVMSetGlobalConstant(gv, True);
183
+ C_struct(~[gv, sz])
184
+ }
185
+ _ => cx.sess.span_bug(e.span,
186
+ ~"bad const-slice expr")
187
+ }
188
+ }
150
189
ast::expr_path(path) {
151
190
alt cx.tcx.def_map.find(e.id) {
152
191
some(ast::def_const(def_id)) {
0 commit comments