Skip to content

Commit b3e174e

Browse files
---
yaml --- r: 67038 b: refs/heads/master c: f389bd8 h: refs/heads/master v: v3
1 parent 3c72acd commit b3e174e

File tree

7 files changed

+262
-91
lines changed

7 files changed

+262
-91
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 739f3eece9c341f4f1e70b8a0417853ed2a09cbc
2+
refs/heads/master: f389bd8f2a72020c25e37b81757643abd481bc11
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 18e3db7392d2d0697b7e27d6d986139960144d85
55
refs/heads/try: 7b78b52e602bb3ea8174f9b2006bff3315f03ef9

trunk/src/librustc/lib/llvm.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2115,7 +2115,21 @@ pub mod llvm {
21152115
AlignInBits: c_ulonglong,
21162116
Elements: ValueRef,
21172117
ClassType: ValueRef) -> ValueRef;
2118-
}}
2118+
2119+
#[fast_ffi]
2120+
pub unsafe fn LLVMDIBuilderCreateUnionType(
2121+
Builder: DIBuilderRef,
2122+
Scope: ValueRef,
2123+
Name: *c_char,
2124+
File: ValueRef,
2125+
LineNumber: c_uint,
2126+
SizeInBits: c_ulonglong,
2127+
AlignInBits: c_ulonglong,
2128+
Flags: c_uint ,
2129+
Elements: ValueRef,
2130+
RunTimeLang : c_uint) -> ValueRef;
2131+
}
2132+
}
21192133

21202134
pub fn SetInstructionCallConv(Instr: ValueRef, CC: CallConv) {
21212135
unsafe {

trunk/src/librustc/middle/trans/debuginfo.rs

Lines changed: 99 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -501,9 +501,9 @@ fn create_struct(cx: &mut CrateContext,
501501
fields: ~[ty::field],
502502
span: span)
503503
-> DICompositeType {
504-
debug!("create_struct: %?", ty::get(struct_type));
505-
506504
let struct_name = ty_to_str(cx.tcx, struct_type);
505+
debug!("create_struct: %s", struct_name);
506+
507507
let struct_llvm_type = type_of::type_of(cx, struct_type);
508508

509509
let field_llvm_types = fields.map(|field| type_of::type_of(cx, field.mt.ty));
@@ -526,7 +526,7 @@ fn create_tuple(cx: &mut CrateContext,
526526
span: span)
527527
-> DICompositeType {
528528

529-
let tuple_name = "tuple"; // this should have a better name
529+
let tuple_name = ty_to_str(cx.tcx, tuple_type);
530530
let tuple_llvm_type = type_of::type_of(cx, tuple_type);
531531
// Create a vec of empty strings. A vec::build_n() function would be nice for this.
532532
let mut component_names : ~[~str] = vec::with_capacity(component_types.len());
@@ -548,61 +548,117 @@ fn create_tuple(cx: &mut CrateContext,
548548
fn create_enum_md(cx: &mut CrateContext,
549549
enum_type: ty::t,
550550
enum_def_id: ast::def_id,
551-
span: span) -> DIType {
551+
substs: &ty::substs,
552+
span: span)
553+
-> DIType {
552554

553555
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);
560556

557+
// For empty enums there is an early exit. Just describe it as an empty struct with the
558+
// appropriate name
561559
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);
560+
return create_composite_type(cx, Type::nil(), enum_name, &[], &[], &[], span);
564561
}
565562

566-
if ty::type_is_c_like_enum(cx.tcx, enum_type) {
563+
// Prepare some data (llvm type, size, align, ...) about the discriminant. This data will be
564+
// needed in all of the following cases.
565+
let discriminant_llvm_type = Type::enum_discrim(cx);
566+
let discriminant_size = machine::llsize_of_alloc(cx, discriminant_llvm_type);
567+
let discriminant_align = machine::llalign_of_min(cx, discriminant_llvm_type);
568+
assert!(Type::enum_discrim(cx) == cx.int_type);
569+
let discriminant_type_md = get_or_create_type(cx, ty::mk_int(), span);
570+
571+
572+
let variants : &[ty::VariantInfo] = *ty::enum_variants(cx.tcx, enum_def_id);
567573

568-
let variants : &[ty::VariantInfo] = *ty::enum_variants(cx.tcx, enum_def_id);
574+
let enumerators : ~[(~str, int)] = variants
575+
.iter()
576+
.transform(|v| (cx.sess.str_of(v.name).to_owned(), v.disr_val))
577+
.collect();
578+
579+
let enumerators_md : ~[DIDescriptor] =
580+
do enumerators.iter().transform |&(name,value)| {
581+
do name.as_c_str |name| { unsafe {
582+
llvm::LLVMDIBuilderCreateEnumerator(
583+
DIB(cx),
584+
name,
585+
value as c_ulonglong)
586+
}}
587+
}.collect();
569588

570-
let enumerators : ~[(~str, int)] = variants
571-
.iter()
572-
.transform(|v| (cx.sess.str_of(v.name).to_owned(), v.disr_val))
573-
.collect();
589+
let loc = span_start(cx, span);
590+
let file_metadata = get_or_create_file(cx, loc.file.name);
574591

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();
592+
let discriminant_type_md = do enum_name.as_c_str |enum_name| { unsafe {
593+
llvm::LLVMDIBuilderCreateEnumerationType(
594+
DIB(cx),
595+
file_metadata,
596+
enum_name,
597+
file_metadata,
598+
loc.line as c_uint,
599+
bytes_to_bits(discriminant_size),
600+
bytes_to_bits(discriminant_align),
601+
create_DIArray(DIB(cx), enumerators_md),
602+
discriminant_type_md)
603+
}};
584604

585-
let loc = span_start(cx, span);
586-
let file_metadata = get_or_create_file(cx, loc.file.name);
605+
if ty::type_is_c_like_enum(cx.tcx, enum_type) {
606+
return discriminant_type_md;
607+
}
587608

588-
return do enum_name.as_c_str |enum_name| { unsafe {
589-
llvm::LLVMDIBuilderCreateEnumerationType(
609+
let variants_md = do variants.map |&vi| {
610+
611+
let raw_types : &[ty::t] = vi.args;
612+
let arg_types = do raw_types.map |&raw_type| { ty::subst(cx.tcx, substs, raw_type) };
613+
let arg_llvm_types = ~[discriminant_llvm_type] + do arg_types.map |&ty| { type_of::type_of(cx, ty) };
614+
let arg_names = ~[~""] + arg_types.map(|_| ~"");
615+
let arg_md = ~[discriminant_type_md] + do arg_types.map |&ty| { get_or_create_type(cx, ty, span) };
616+
617+
let variant_llvm_type = Type::struct_(arg_llvm_types, false);
618+
let variant_type_size = machine::llsize_of_alloc(cx, variant_llvm_type);
619+
let variant_type_align = machine::llalign_of_min(cx, variant_llvm_type);
620+
621+
let variant_type_md = create_composite_type(
622+
cx,
623+
variant_llvm_type,
624+
&"",
625+
arg_llvm_types,
626+
arg_names,
627+
arg_md,
628+
span);
629+
630+
do "".as_c_str |name| { unsafe {
631+
llvm::LLVMDIBuilderCreateMemberType(
590632
DIB(cx),
591633
file_metadata,
592-
enum_name,
634+
name,
593635
file_metadata,
594636
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-
}
637+
bytes_to_bits(variant_type_size),
638+
bytes_to_bits(variant_type_align),
639+
bytes_to_bits(0),
640+
0,
641+
variant_type_md)
642+
}}
643+
};
604644

645+
let enum_llvm_type = type_of::type_of(cx, enum_type);
646+
let enum_type_size = machine::llsize_of_alloc(cx, enum_llvm_type);
647+
let enum_type_align = machine::llalign_of_min(cx, enum_llvm_type);
605648

649+
return do "".as_c_str |enum_name| { unsafe { llvm::LLVMDIBuilderCreateUnionType(
650+
DIB(cx),
651+
file_metadata,
652+
enum_name,
653+
file_metadata,
654+
loc.line as c_uint,
655+
bytes_to_bits(enum_type_size),
656+
bytes_to_bits(enum_type_align),
657+
0, // Flags
658+
create_DIArray(DIB(cx), variants_md),
659+
0) // RuntimeLang
660+
}};
661+
}
606662

607663

608664
/// Creates debug information for a composite type, that is, anything that results in a LLVM struct.
@@ -899,10 +955,8 @@ fn get_or_create_type(cx: &mut CrateContext, t: ty::t, span: span) -> DIType {
899955
}
900956
}
901957
},
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)
958+
ty::ty_enum(def_id, ref substs) => {
959+
create_enum_md(cx, t, def_id, substs, span)
906960
},
907961
ty::ty_box(ref mt) |
908962
ty::ty_uniq(ref mt) => {

0 commit comments

Comments
 (0)