Skip to content

Commit 134585b

Browse files
committed
Add debug information for boxed and unique values.
1 parent e25f6d0 commit 134585b

File tree

1 file changed

+163
-22
lines changed

1 file changed

+163
-22
lines changed

src/comp/middle/debuginfo.rs

Lines changed: 163 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import std::{vec, str, option, unsafe, fs, sys};
1+
import std::{vec, str, option, unsafe, fs, sys, ctypes};
22
import std::map::hashmap;
33
import lib::llvm::llvm;
44
import lib::llvm::llvm::ValueRef;
55
import middle::trans_common::*;
66
import middle::ty;
77
import syntax::{ast, codemap};
88
import ast::ty;
9+
import util::ppaux::ty_to_str;
910

1011
const LLVMDebugVersion: int = (9 << 16);
1112

@@ -21,6 +22,9 @@ const AutoVariableTag: int = 256;
2122
const ArgVariableTag: int = 257;
2223
const ReturnVariableTag: int = 258;
2324
const LexicalBlockTag: int = 11;
25+
const PointerTypeTag: int = 15;
26+
const StructureTypeTag: int = 19;
27+
const MemberTag: int = 13;
2428

2529
const DW_ATE_boolean: int = 0x02;
2630
const DW_ATE_float: int = 0x04;
@@ -219,31 +223,21 @@ fn get_block_metadata(cx: @block_ctxt) -> @metadata<block_md> {
219223
ret mdval;
220224
}
221225

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> {
223232
let cache = cx.llmetadata;
233+
let tg = BasicTypeDescriptorTag;
224234
alt cached_metadata::<@metadata<tydesc_md>>(
225-
cache, BasicTypeDescriptorTag,
235+
cache, tg,
226236
{|md| ty::hash_ty(t) == ty::hash_ty(md.data.hash)}) {
227237
option::some(md) { ret md; }
228238
option::none. {}
229239
}
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 {
247241
ast::ty_bool. {("bool", size_and_align_of::<bool>(), DW_ATE_boolean)}
248242
ast::ty_int. {("int", size_and_align_of::<int>(), DW_ATE_signed)}
249243
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_
265259
let fname = filename_from_span(cx, ty.span);
266260
let file_node = get_file_metadata(cx, fname);
267261
let cu_node = get_compile_unit_metadata(cx, fname);
268-
let lldata = [lltag(BasicTypeDescriptorTag),
262+
let lldata = [lltag(tg),
269263
cu_node.node,
270264
llstr(name),
271265
file_node.node,
@@ -277,13 +271,160 @@ fn get_ty_metadata(cx: @crate_ctxt, t: ty::t, ty: @ast::ty) -> @metadata<tydesc_
277271
lli32(encoding)];
278272
let llnode = llmdnode(lldata);
279273
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));
281380
llvm::LLVMAddNamedMetadataOperand(cx.llmod, as_buf("llvm.dbg.ty"),
282381
str::byte_len("llvm.dbg.ty"),
283382
llnode);
284383
ret mdval;
285384
}
286385

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+
287428
fn function_metadata_from_block(bcx: @block_ctxt) -> @metadata<subprogram_md> {
288429
let cx = bcx_ccx(bcx);
289430
let fcx = bcx_fcx(bcx);

0 commit comments

Comments
 (0)