1
- import std:: { vec, str, option, unsafe, fs, sys} ;
1
+ import std:: { vec, str, option, unsafe, fs, sys, ctypes } ;
2
2
import std:: map:: hashmap;
3
3
import lib:: llvm:: llvm;
4
4
import lib:: llvm:: llvm:: ValueRef ;
5
5
import middle:: trans_common:: * ;
6
6
import middle:: ty;
7
7
import syntax:: { ast, codemap} ;
8
8
import ast:: ty;
9
+ import util:: ppaux:: ty_to_str;
9
10
10
11
const LLVMDebugVersion : int = ( 9 << 16 ) ;
11
12
@@ -21,6 +22,9 @@ const AutoVariableTag: int = 256;
21
22
const ArgVariableTag : int = 257 ;
22
23
const ReturnVariableTag : int = 258 ;
23
24
const LexicalBlockTag : int = 11 ;
25
+ const PointerTypeTag : int = 15 ;
26
+ const StructureTypeTag : int = 19 ;
27
+ const MemberTag : int = 13 ;
24
28
25
29
const DW_ATE_boolean : int = 0x02 ;
26
30
const DW_ATE_float : int = 0x04 ;
@@ -219,31 +223,21 @@ fn get_block_metadata(cx: @block_ctxt) -> @metadata<block_md> {
219
223
ret mdval;
220
224
}
221
225
222
- fn get_ty_metadata ( cx : @crate_ctxt , t : ty:: t , ty : @ast:: ty ) -> @metadata < tydesc_md > {
226
+ fn size_and_align_of < T > ( ) -> ( int , int ) {
227
+ ( sys:: size_of :: < T > ( ) as int , sys:: align_of :: < T > ( ) as int )
228
+ }
229
+
230
+ fn get_basic_type_metadata ( cx : @crate_ctxt , t : ty:: t , ty : @ast:: ty )
231
+ -> @metadata < tydesc_md > {
223
232
let cache = cx. llmetadata ;
233
+ let tg = BasicTypeDescriptorTag ;
224
234
alt cached_metadata :: < @metadata < tydesc_md > > (
225
- cache, BasicTypeDescriptorTag ,
235
+ cache, tg ,
226
236
{ |md| ty:: hash_ty ( t) == ty:: hash_ty ( md. data . hash ) } ) {
227
237
option:: some ( md) { ret md; }
228
238
option:: none. { }
229
239
}
230
- fn size_and_align_of < T > ( ) -> ( int , int ) {
231
- ( sys:: size_of :: < T > ( ) as int , sys:: align_of :: < T > ( ) as int )
232
- }
233
- let ast_ty = alt ty. node {
234
- ast:: ty_infer. {
235
- alt ty :: struct( ccx_tcx ( cx) , t) {
236
- ty:: ty_bool. { ast:: ty_bool }
237
- ty:: ty_int. { ast:: ty_int }
238
- ty:: ty_uint. { ast:: ty_uint }
239
- ty:: ty_float. { ast:: ty_float }
240
- ty:: ty_machine ( m) { ast:: ty_machine ( m) }
241
- ty:: ty_char. { ast:: ty_char }
242
- }
243
- }
244
- _ { ty. node }
245
- } ;
246
- let ( name, ( size, align) , encoding) = alt ast_ty {
240
+ let ( name, ( size, align) , encoding) = alt ty. node {
247
241
ast:: ty_bool. { ( "bool" , size_and_align_of :: < bool > ( ) , DW_ATE_boolean ) }
248
242
ast:: ty_int. { ( "int" , size_and_align_of :: < int > ( ) , DW_ATE_signed ) }
249
243
ast:: ty_uint. { ( "uint" , size_and_align_of :: < uint > ( ) , DW_ATE_unsigned ) }
@@ -265,7 +259,7 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata<tydesc_
265
259
let fname = filename_from_span ( cx, ty. span ) ;
266
260
let file_node = get_file_metadata ( cx, fname) ;
267
261
let cu_node = get_compile_unit_metadata ( cx, fname) ;
268
- let lldata = [ lltag ( BasicTypeDescriptorTag ) ,
262
+ let lldata = [ lltag ( tg ) ,
269
263
cu_node. node ,
270
264
llstr ( name) ,
271
265
file_node. node ,
@@ -277,13 +271,160 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata<tydesc_
277
271
lli32 ( encoding) ] ;
278
272
let llnode = llmdnode ( lldata) ;
279
273
let mdval = @{ node: llnode, data : { hash : ty:: hash_ty ( t) } } ;
280
- update_cache ( cache, BasicTypeDescriptorTag , tydesc_metadata ( mdval) ) ;
274
+ update_cache ( cache, tg, tydesc_metadata ( mdval) ) ;
275
+ llvm:: LLVMAddNamedMetadataOperand ( cx. llmod , as_buf ( "llvm.dbg.ty" ) ,
276
+ str:: byte_len ( "llvm.dbg.ty" ) ,
277
+ llnode) ;
278
+ ret mdval;
279
+ }
280
+
281
+ fn get_pointer_type_metadata ( cx : @crate_ctxt , t : ty:: t , span : codemap:: span ,
282
+ pointee : @metadata < tydesc_md > )
283
+ -> @metadata < tydesc_md > {
284
+ let tg = PointerTypeTag ;
285
+ /*let cache = cx.llmetadata;
286
+ alt cached_metadata::<@metadata<tydesc_md>>(
287
+ cache, tg, {|md| ty::hash_ty(t) == ty::hash_ty(md.data.hash)}) {
288
+ option::some(md) { ret md; }
289
+ option::none. {}
290
+ }*/
291
+ let ( size, align) = size_and_align_of :: < ctypes:: intptr_t > ( ) ;
292
+ let fname = filename_from_span ( cx, span) ;
293
+ let file_node = get_file_metadata ( cx, fname) ;
294
+ //let cu_node = get_compile_unit_metadata(cx, fname);
295
+ let lldata = [ lltag ( tg) ,
296
+ file_node. node ,
297
+ llstr ( "" ) ,
298
+ file_node. node ,
299
+ lli32 ( 0 ) , //XXX source line
300
+ lli64 ( size * 8 ) , // size in bits
301
+ lli64 ( align * 8 ) , // alignment in bits
302
+ lli64 ( 0 ) , //XXX offset?
303
+ lli32 ( 0 ) ,
304
+ pointee. node ] ;
305
+ let llnode = llmdnode ( lldata) ;
306
+ let mdval = @{ node: llnode, data : { hash : ty:: hash_ty ( t) } } ;
307
+ //update_cache(cache, tg, tydesc_metadata(mdval));
308
+ llvm:: LLVMAddNamedMetadataOperand ( cx. llmod , as_buf ( "llvm.dbg.ty" ) ,
309
+ str:: byte_len ( "llvm.dbg.ty" ) ,
310
+ llnode) ;
311
+ ret mdval;
312
+ }
313
+
314
+ fn get_boxed_type_metadata ( cx : @crate_ctxt , outer : ty:: t , inner : ty:: t ,
315
+ span : codemap:: span , boxed : @metadata < tydesc_md > )
316
+ -> @metadata < tydesc_md > {
317
+ let tg = StructureTypeTag ;
318
+ /*let cache = cx.llmetadata;
319
+ alt cached_metadata::<@metadata<tydesc_md>>(
320
+ cache, tg, {|md| ty::hash_ty(outer) == ty::hash_ty(md.data.hash)}) {
321
+ option::some(md) { ret md; }
322
+ option::none. {}
323
+ }*/
324
+ let ( size, align) = size_and_align_of :: < @int > ( ) ;
325
+ let fname = filename_from_span ( cx, span) ;
326
+ let file_node = get_file_metadata ( cx, fname) ;
327
+ //let cu_node = get_compile_unit_metadata(cx, fname);
328
+ let tcx = ccx_tcx ( cx) ;
329
+ let uint_t = ty:: mk_uint ( tcx) ;
330
+ let uint_ty = @{ node: ast:: ty_uint, span: span} ;
331
+ let refcount_type = get_basic_type_metadata ( cx, uint_t, uint_ty) ;
332
+ /*let refcount_ptr_type = get_pointer_type_metadata(cx,
333
+ ty::mk_imm_uniq(tcx, uint_t),
334
+ span, refcount_type);*/
335
+ /*let boxed_ptr_type = get_pointer_type_metadata(cx, ty::mk_imm_uniq(tcx, inner),
336
+ span, boxed);*/
337
+ //let ptr_size = sys::size_of::<ctypes::intptr_t>() as int;
338
+ //let ptr_align = sys::align_of::<ctypes::intptr_t>() as int;
339
+ let size = sys:: size_of :: < uint > ( ) as int * 8 ;
340
+ let total_size = size;
341
+ let refcount = [ lltag ( MemberTag ) ,
342
+ file_node. node ,
343
+ llstr ( "refcnt" ) ,
344
+ file_node. node ,
345
+ lli32 ( 0 ) ,
346
+ lli64 ( size) ,
347
+ lli64 ( sys:: align_of :: < uint > ( ) as int * 8 ) ,
348
+ lli64 ( 0 ) ,
349
+ lli32 ( 0 ) ,
350
+ refcount_type. node ] ;
351
+ let size = 64 ; //XXX size of inner
352
+ let boxed_member = [ lltag ( MemberTag ) ,
353
+ file_node. node ,
354
+ llstr ( "boxed" ) ,
355
+ file_node. node ,
356
+ lli32 ( 0 ) ,
357
+ lli64 ( size) ,
358
+ lli64 ( 64 ) , //XXX align of inner
359
+ lli64 ( total_size) ,
360
+ lli32 ( 0 ) ,
361
+ boxed. node ] ;
362
+ total_size += size;
363
+ let members = [ llmdnode ( refcount) , llmdnode ( boxed_member) ] ;
364
+ let lldata = [ lltag ( tg) ,
365
+ file_node. node ,
366
+ llstr ( ty_to_str ( ccx_tcx ( cx) , outer) ) ,
367
+ file_node. node ,
368
+ lli32 ( 0 ) , //XXX source line
369
+ lli64 ( total_size) , // size in bits
370
+ lli64 ( align * 8 ) , // alignment in bits
371
+ lli64 ( 0 ) , //XXX offset?
372
+ lli32 ( 0 ) , //XXX flags
373
+ llnull ( ) , // derived from
374
+ llmdnode ( members) , // members
375
+ lli32 ( 0 ) // runtime language
376
+ ] ;
377
+ let llnode = llmdnode ( lldata) ;
378
+ let mdval = @{ node: llnode, data : { hash : ty:: hash_ty ( outer) } } ;
379
+ //update_cache(cache, tg, tydesc_metadata(mdval));
281
380
llvm:: LLVMAddNamedMetadataOperand ( cx. llmod , as_buf ( "llvm.dbg.ty" ) ,
282
381
str:: byte_len ( "llvm.dbg.ty" ) ,
283
382
llnode) ;
284
383
ret mdval;
285
384
}
286
385
386
+ fn get_ty_metadata ( cx : @crate_ctxt , t : ty:: t , ty : @ast:: ty ) -> @metadata < tydesc_md > {
387
+ fn t_to_ty ( cx : @crate_ctxt , t : ty:: t , span : codemap:: span ) -> @ast:: ty {
388
+ let ty = alt ty:: struct ( ccx_tcx ( cx) , t) {
389
+ ty:: ty_nil. { ast:: ty_nil }
390
+ ty:: ty_bot. { ast:: ty_bot }
391
+ ty:: ty_bool. { ast:: ty_bool }
392
+ ty:: ty_int. { ast:: ty_int }
393
+ ty:: ty_float. { ast:: ty_float }
394
+ ty:: ty_uint. { ast:: ty_uint }
395
+ ty:: ty_machine ( mt) { ast:: ty_machine ( mt) }
396
+ ty:: ty_char. { ast:: ty_char }
397
+ ty:: ty_box ( mt) { ast:: ty_box ( { ty: t_to_ty ( cx, mt. ty , span) ,
398
+ mut: mt. mut } ) }
399
+ ty:: ty_uniq ( mt) { ast:: ty_uniq ( { ty: t_to_ty ( cx, mt. ty , span) ,
400
+ mut: mt. mut } ) }
401
+ } ;
402
+ ret @{ node : ty, span : span} ;
403
+ }
404
+ alt ty. node {
405
+ ast:: ty_box ( mt) {
406
+ let inner_t = alt ty:: struct ( ccx_tcx ( cx) , t) {
407
+ ty:: ty_box ( boxed) { boxed. ty }
408
+ } ;
409
+ let md = get_ty_metadata ( cx, inner_t, mt. ty ) ;
410
+ let box = get_boxed_type_metadata ( cx, t, inner_t, ty. span , md) ;
411
+ ret get_pointer_type_metadata ( cx, t, ty. span , box) ;
412
+ }
413
+ ast:: ty_uniq ( mt) {
414
+ let inner_t = alt ty:: struct ( ccx_tcx ( cx) , t) {
415
+ ty:: ty_uniq ( boxed) { boxed. ty }
416
+ } ;
417
+ let md = get_ty_metadata ( cx, inner_t, mt. ty ) ;
418
+ ret get_pointer_type_metadata ( cx, t, ty. span , md) ;
419
+ }
420
+ ast:: ty_infer. {
421
+ let inferred = t_to_ty ( cx, t, ty. span ) ;
422
+ ret get_ty_metadata ( cx, t, inferred) ;
423
+ }
424
+ _ { ret get_basic_type_metadata( cx, t, ty) ; }
425
+ } ;
426
+ }
427
+
287
428
fn function_metadata_from_block ( bcx : @block_ctxt ) -> @metadata < subprogram_md > {
288
429
let cx = bcx_ccx ( bcx) ;
289
430
let fcx = bcx_fcx ( bcx) ;
0 commit comments