Skip to content

Commit 739f3ee

Browse files
debuginfo: Added support for c-style enums.
1 parent 99ebb81 commit 739f3ee

File tree

7 files changed

+361
-37
lines changed

7 files changed

+361
-37
lines changed

src/librustc/lib/llvm.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,8 +2097,25 @@ pub mod llvm {
20972097
Val: ValueRef,
20982098
VarInfo: DIVariable,
20992099
InsertBefore: ValueRef) -> ValueRef;
2100-
}
2101-
}
2100+
2101+
#[fast_ffi]
2102+
pub unsafe fn LLVMDIBuilderCreateEnumerator(
2103+
Builder: DIBuilderRef,
2104+
Name: *c_char,
2105+
Val: c_ulonglong) -> ValueRef;
2106+
2107+
#[fast_ffi]
2108+
pub unsafe fn LLVMDIBuilderCreateEnumerationType(
2109+
Builder: DIBuilderRef,
2110+
Scope: ValueRef,
2111+
Name: *c_char,
2112+
File: ValueRef,
2113+
LineNumber: c_uint,
2114+
SizeInBits: c_ulonglong,
2115+
AlignInBits: c_ulonglong,
2116+
Elements: ValueRef,
2117+
ClassType: ValueRef) -> ValueRef;
2118+
}}
21022119

21032120
pub fn SetInstructionCallConv(Instr: ValueRef, CC: CallConv) {
21042121
unsafe {

src/librustc/middle/trans/debuginfo.rs

Lines changed: 92 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,11 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable {
143143

144144
let loc = span_start(cx, local.span);
145145
let ty = node_id_type(bcx, local.node.id);
146-
let tymd = get_or_create_ty(cx, ty, local.node.ty.span);
146+
let tymd = get_or_create_type(cx, ty, local.node.ty.span);
147147
let filemd = get_or_create_file(cx, loc.file.name);
148148
let context = match bcx.parent {
149149
None => create_function(bcx.fcx),
150-
Some(_) => create_block(bcx)
150+
Some(_) => get_or_create_block(bcx)
151151
};
152152

153153
let var_md = do as_c_str(name) |name| { unsafe {
@@ -167,7 +167,7 @@ pub fn create_local_var(bcx: block, local: @ast::local) -> DIVariable {
167167
}
168168
};
169169

170-
set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint());
170+
set_debug_location(cx, get_or_create_block(bcx), loc.line, loc.col.to_uint());
171171
unsafe {
172172
let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(DIB(cx), llptr, var_md, bcx.llbb);
173173
llvm::LLVMSetInstDebugLocation(trans::build::B(bcx), instr);
@@ -197,7 +197,7 @@ pub fn create_arg(bcx: block, arg: &ast::arg, span: span) -> Option<DIVariable>
197197
}
198198

199199
let ty = node_id_type(bcx, arg.id);
200-
let tymd = get_or_create_ty(cx, ty, arg.ty.span);
200+
let tymd = get_or_create_type(cx, ty, arg.ty.span);
201201
let filemd = get_or_create_file(cx, loc.file.name);
202202
let context = create_function(fcx);
203203

@@ -222,7 +222,7 @@ pub fn create_arg(bcx: block, arg: &ast::arg, span: span) -> Option<DIVariable>
222222
}};
223223

224224
let llptr = fcx.llargs.get_copy(&arg.id);
225-
set_debug_location(cx, create_block(bcx), loc.line, loc.col.to_uint());
225+
set_debug_location(cx, get_or_create_block(bcx), loc.line, loc.col.to_uint());
226226
unsafe {
227227
let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
228228
DIB(cx), llptr, mdnode, bcx.llbb);
@@ -245,7 +245,7 @@ pub fn update_source_pos(bcx: block, span: span) {
245245
}
246246
debug!("update_source_pos: %s", bcx.sess().codemap.span_to_str(span));
247247
let loc = span_start(bcx.ccx(), span);
248-
set_debug_location(bcx.ccx(), create_block(bcx), loc.line, loc.col.to_uint())
248+
set_debug_location(bcx.ccx(), get_or_create_block(bcx), loc.line, loc.col.to_uint())
249249
}
250250

251251
/// Creates debug information for the given function.
@@ -297,7 +297,7 @@ pub fn create_function(fcx: fn_ctxt) -> DISubprogram {
297297
let ret_ty_md = if cx.sess.opts.extra_debuginfo {
298298
match ret_ty.node {
299299
ast::ty_nil => ptr::null(),
300-
_ => get_or_create_ty(cx, ty::node_id_to_type(cx.tcx, id), ret_ty.span)
300+
_ => get_or_create_type(cx, ty::node_id_to_type(cx.tcx, id), ret_ty.span)
301301
}
302302
} else {
303303
ptr::null()
@@ -397,7 +397,7 @@ fn get_or_create_file(cx: &mut CrateContext, full_path: &str) -> DIFile {
397397

398398

399399

400-
fn create_block(bcx: block) -> DILexicalBlock {
400+
fn get_or_create_block(bcx: block) -> DILexicalBlock {
401401
let mut bcx = bcx;
402402
let cx = bcx.ccx();
403403

@@ -415,11 +415,11 @@ fn create_block(bcx: block) -> DILexicalBlock {
415415
None => ()
416416
}
417417

418-
debug!("create_block: %s", bcx.sess().codemap.span_to_str(span));
418+
debug!("get_or_create_block: %s", bcx.sess().codemap.span_to_str(span));
419419

420420
let parent = match bcx.parent {
421421
None => create_function(bcx.fcx),
422-
Some(b) => create_block(b)
422+
Some(b) => get_or_create_block(b)
423423
};
424424
let cx = bcx.ccx();
425425
let loc = span_start(cx, span);
@@ -508,7 +508,7 @@ fn create_struct(cx: &mut CrateContext,
508508

509509
let field_llvm_types = fields.map(|field| type_of::type_of(cx, field.mt.ty));
510510
let field_names = fields.map(|field| cx.sess.str_of(field.ident).to_owned());
511-
let field_types_metadata = fields.map(|field| get_or_create_ty(cx, field.mt.ty, span));
511+
let field_types_metadata = fields.map(|field| get_or_create_type(cx, field.mt.ty, span));
512512

513513
return create_composite_type(
514514
cx,
@@ -533,7 +533,7 @@ fn create_tuple(cx: &mut CrateContext,
533533
component_names.grow_fn(component_types.len(), |_| ~"");
534534

535535
let component_llvm_types = component_types.map(|it| type_of::type_of(cx, *it));
536-
let component_types_metadata = component_types.map(|it| get_or_create_ty(cx, *it, span));
536+
let component_types_metadata = component_types.map(|it| get_or_create_type(cx, *it, span));
537537

538538
return create_composite_type(
539539
cx,
@@ -545,6 +545,66 @@ fn create_tuple(cx: &mut CrateContext,
545545
span);
546546
}
547547

548+
fn create_enum_md(cx: &mut CrateContext,
549+
enum_type: ty::t,
550+
enum_def_id: ast::def_id,
551+
span: span) -> DIType {
552+
553+
let enum_name = ty_to_str(cx.tcx, enum_type);
554+
let discriminator_llvm_type = Type::enum_discrim(cx);
555+
let discriminator_size = machine::llsize_of_alloc(cx, discriminator_llvm_type);
556+
let discriminator_align = machine::llalign_of_min(cx, discriminator_llvm_type);
557+
558+
assert!(Type::enum_discrim(cx) == cx.int_type);
559+
let discriminator_type_md = get_or_create_type(cx, ty::mk_int(), span);
560+
561+
if ty::type_is_empty(cx.tcx, enum_type) {
562+
// XXX: This should not "rename" the type to nil
563+
return get_or_create_type(cx, ty::mk_nil(), span);
564+
}
565+
566+
if ty::type_is_c_like_enum(cx.tcx, enum_type) {
567+
568+
let variants : &[ty::VariantInfo] = *ty::enum_variants(cx.tcx, enum_def_id);
569+
570+
let enumerators : ~[(~str, int)] = variants
571+
.iter()
572+
.transform(|v| (cx.sess.str_of(v.name).to_owned(), v.disr_val))
573+
.collect();
574+
575+
let enumerators_md : ~[DIDescriptor] =
576+
do enumerators.iter().transform |&(name,value)| {
577+
do name.as_c_str |name| { unsafe {
578+
llvm::LLVMDIBuilderCreateEnumerator(
579+
DIB(cx),
580+
name,
581+
value as c_ulonglong)
582+
}}
583+
}.collect();
584+
585+
let loc = span_start(cx, span);
586+
let file_metadata = get_or_create_file(cx, loc.file.name);
587+
588+
return do enum_name.as_c_str |enum_name| { unsafe {
589+
llvm::LLVMDIBuilderCreateEnumerationType(
590+
DIB(cx),
591+
file_metadata,
592+
enum_name,
593+
file_metadata,
594+
loc.line as c_uint,
595+
bytes_to_bits(discriminator_size),
596+
bytes_to_bits(discriminator_align),
597+
create_DIArray(DIB(cx), enumerators_md),
598+
discriminator_type_md)
599+
}};
600+
}
601+
602+
cx.sess.bug("");
603+
}
604+
605+
606+
607+
548608
/// Creates debug information for a composite type, that is, anything that results in a LLVM struct.
549609
///
550610
/// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
@@ -636,10 +696,10 @@ fn create_boxed_type(cx: &mut CrateContext,
636696
let nil_pointer_type = ty::mk_nil_ptr(cx.tcx);
637697

638698
let member_types_metadata = [
639-
get_or_create_ty(cx, int_type, span),
640-
get_or_create_ty(cx, nil_pointer_type, span),
641-
get_or_create_ty(cx, nil_pointer_type, span),
642-
get_or_create_ty(cx, nil_pointer_type, span),
699+
get_or_create_type(cx, int_type, span),
700+
get_or_create_type(cx, nil_pointer_type, span),
701+
get_or_create_type(cx, nil_pointer_type, span),
702+
get_or_create_type(cx, nil_pointer_type, span),
643703
content_type_metadata
644704
];
645705

@@ -671,7 +731,7 @@ fn create_fixed_vec(cx: &mut CrateContext, _vec_t: ty::t, elem_t: ty::t,
671731
len: uint, span: span) -> DIType {
672732
debug!("create_fixed_vec: %?", ty::get(_vec_t));
673733

674-
let elem_ty_md = get_or_create_ty(cx, elem_t, span);
734+
let elem_ty_md = get_or_create_type(cx, elem_t, span);
675735
let (size, align) = size_and_align_of(cx, elem_t);
676736

677737
let subrange = unsafe { llvm::LLVMDIBuilderGetOrCreateSubrange(
@@ -695,15 +755,15 @@ fn create_boxed_vec(cx: &mut CrateContext,
695755
span: span)
696756
-> DICompositeType {
697757

698-
let element_type_metadata = get_or_create_ty(cx, element_type, span);
758+
let element_type_metadata = get_or_create_type(cx, element_type, span);
699759
let element_llvm_type = type_of::type_of(cx, element_type);
700760
let vec_llvm_type = Type::vec(cx.sess.targ_cfg.arch, &element_llvm_type);
701761
let vec_type_name = &"vec";
702762

703763
let member_llvm_types = vec_llvm_type.field_types();
704764
let member_names = &[~"fill", ~"alloc", ~"elements"];
705765

706-
let int_type_md = get_or_create_ty(cx, ty::mk_int(), span);
766+
let int_type_md = get_or_create_type(cx, ty::mk_int(), span);
707767
let array_type_md = unsafe { llvm::LLVMDIBuilderCreateArrayType(
708768
DIB(cx),
709769
bytes_to_bits(machine::llsize_of_alloc(cx, element_llvm_type)),
@@ -746,8 +806,8 @@ fn create_vec_slice(cx: &mut CrateContext,
746806
let data_ptr_type = ty::mk_ptr(cx.tcx, ty::mt { ty: element_type, mutbl: ast::m_const });
747807

748808
let member_type_metadata = &[
749-
get_or_create_ty(cx, data_ptr_type, span),
750-
get_or_create_ty(cx, ty::mk_uint(), span)
809+
get_or_create_type(cx, data_ptr_type, span),
810+
get_or_create_type(cx, ty::mk_uint(), span)
751811
];
752812

753813
return create_composite_type(
@@ -776,9 +836,9 @@ fn create_fn_ty(cx: &mut CrateContext, _fn_ty: ty::t, inputs: ~[ty::t], output:
776836
let loc = span_start(cx, span);
777837
let file_md = get_or_create_file(cx, loc.file.name);
778838
let (vp, _, _) = voidptr(cx);
779-
let output_md = get_or_create_ty(cx, output, span);
839+
let output_md = get_or_create_type(cx, output, span);
780840
let output_ptr_md = create_pointer_type(cx, output, span, output_md);
781-
let inputs_vals = do inputs.map |arg| { get_or_create_ty(cx, *arg, span) };
841+
let inputs_vals = do inputs.map |arg| { get_or_create_type(cx, *arg, span) };
782842
let members = ~[output_ptr_md, vp] + inputs_vals;
783843

784844
return unsafe {
@@ -804,14 +864,14 @@ fn create_unimpl_ty(cx: &mut CrateContext, t: ty::t) -> DIType {
804864
return md;
805865
}
806866

807-
fn get_or_create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType {
867+
fn get_or_create_type(cx: &mut CrateContext, t: ty::t, span: span) -> DIType {
808868
let ty_id = ty::type_id(t);
809869
match dbg_cx(cx).created_types.find(&ty_id) {
810870
Some(ty_md) => return *ty_md,
811871
None => ()
812872
}
813873

814-
debug!("get_or_create_ty: %?", ty::get(t));
874+
debug!("get_or_create_type: %?", ty::get(t));
815875

816876
let sty = copy ty::get(t).sty;
817877
let ty_md = match sty {
@@ -839,14 +899,15 @@ fn get_or_create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType {
839899
}
840900
}
841901
},
842-
ty::ty_enum(_did, ref _substs) => {
843-
cx.sess.span_note(span, "debuginfo for enum NYI");
844-
create_unimpl_ty(cx, t)
902+
ty::ty_enum(def_id, ref _substs) => {
903+
//cx.sess.span_note(span, "debuginfo for enum NYI");
904+
//create_unimpl_ty(cx, t)
905+
create_enum_md(cx, t, def_id, span)
845906
},
846907
ty::ty_box(ref mt) |
847908
ty::ty_uniq(ref mt) => {
848909
let content_llvm_type = type_of::type_of(cx, mt.ty);
849-
let content_type_metadata = get_or_create_ty(cx, mt.ty, span);
910+
let content_type_metadata = get_or_create_type(cx, mt.ty, span);
850911

851912
let box_metadata = create_boxed_type(cx,
852913
content_llvm_type,
@@ -872,7 +933,7 @@ fn get_or_create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType {
872933
},
873934
ty::ty_ptr(ref mt) |
874935
ty::ty_rptr(_, ref mt) => {
875-
let pointee = get_or_create_ty(cx, mt.ty, span);
936+
let pointee = get_or_create_type(cx, mt.ty, span);
876937
create_pointer_type(cx, t, span, pointee)
877938
},
878939
ty::ty_bare_fn(ref barefnty) => {
@@ -895,7 +956,7 @@ fn get_or_create_ty(cx: &mut CrateContext, t: ty::t, span: span) -> DIType {
895956
ty::ty_tup(ref elements) => {
896957
create_tuple(cx, t, *elements, span)
897958
},
898-
_ => cx.sess.bug("debuginfo: unexpected type in get_or_create_ty")
959+
_ => cx.sess.bug("debuginfo: unexpected type in get_or_create_type")
899960
};
900961

901962
dbg_cx(cx).created_types.insert(ty_id, ty_md);

src/rustllvm/RustWrapper.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,3 +785,33 @@ extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
785785
unwrapDI<DIVariable>(VarInfo),
786786
unwrap<Instruction>(InsertBefore)));
787787
}
788+
789+
extern "C" LLVMValueRef LLVMDIBuilderCreateEnumerator(
790+
DIBuilderRef Builder,
791+
const char* Name,
792+
uint64_t Val)
793+
{
794+
return wrap(Builder->createEnumerator(Name, Val));
795+
}
796+
797+
extern "C" LLVMValueRef LLVMDIBuilderCreateEnumerationType(
798+
DIBuilderRef Builder,
799+
LLVMValueRef Scope,
800+
const char* Name,
801+
LLVMValueRef File,
802+
unsigned LineNumber,
803+
uint64_t SizeInBits,
804+
uint64_t AlignInBits,
805+
LLVMValueRef Elements,
806+
LLVMValueRef ClassType)
807+
{
808+
return wrap(Builder->createEnumerationType(
809+
unwrapDI<DIDescriptor>(Scope),
810+
Name,
811+
unwrapDI<DIFile>(File),
812+
LineNumber,
813+
SizeInBits,
814+
AlignInBits,
815+
unwrapDI<DIArray>(Elements),
816+
unwrapDI<DIType>(ClassType)));
817+
}

src/test/debug-info/borrowed-basic.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@
1010

1111
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
1212

13-
// Caveats - gdb prints any 8-bit value (meaning rust i8 and u8 values)
14-
// as its numerical value along with its associated ASCII char, there
15-
// doesn't seem to be any way around this. Also, gdb doesn't know
16-
// about UTF-32 character encoding and will print a rust char as only
13+
// Gdb doesn't know about UTF-32 character encoding and will print a rust char as only
1714
// its numerical value.
1815

1916
// compile-flags:-Z extra-debug-info

0 commit comments

Comments
 (0)