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