Skip to content

Commit e0108a4

Browse files
debuginfo: DI generation for enums uses adt::represent_type() now.
1 parent 70e5c08 commit e0108a4

File tree

8 files changed

+163
-7
lines changed

8 files changed

+163
-7
lines changed

src/librustc/middle/trans/adt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ pub enum Repr {
9494
}
9595

9696
/// For structs, and struct-like parts of anything fancier.
97-
struct Struct {
97+
pub struct Struct {
9898
size: u64,
9999
align: u64,
100100
packed: bool,

src/librustc/middle/trans/debuginfo.rs

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ use middle::trans::common::*;
5050
use middle::trans::machine;
5151
use middle::trans::type_of;
5252
use middle::trans::type_::Type;
53+
use middle::trans::adt;
5354
use middle::trans;
5455
use middle::ty;
5556
use util::ppaux::ty_to_str;
@@ -560,6 +561,161 @@ fn create_tuple_metadata(cx: &mut CrateContext,
560561
span);
561562
}
562563

564+
// The stage0 snapshot does not yet support the fixes from PR #7557, so there are two versions of
565+
// following function for now
566+
#[cfg(not(stage0))]
567+
fn create_enum_metadata(cx: &mut CrateContext,
568+
enum_type: ty::t,
569+
enum_def_id: ast::def_id,
570+
substs: &ty::substs,
571+
span: span)
572+
-> DIType {
573+
574+
let enum_name = ty_to_str(cx.tcx, enum_type);
575+
576+
// For empty enums there is an early exit. Just describe it as an empty struct with the
577+
// appropriate type name
578+
if ty::type_is_empty(cx.tcx, enum_type) {
579+
return create_composite_type_metadata(cx, Type::nil(), enum_name, &[], &[], &[], span);
580+
}
581+
582+
// Prepare some data (llvm type, size, align, ...) about the discriminant. This data will be
583+
// needed in all of the following cases.
584+
let discriminant_llvm_type = Type::enum_discrim(cx);
585+
let (discriminant_size, discriminant_align) = size_and_align_of(cx, discriminant_llvm_type);
586+
587+
assert!(Type::enum_discrim(cx) == cx.int_type);
588+
let discriminant_type_metadata = get_or_create_type_metadata(cx, ty::mk_int(), span);
589+
590+
let variants : &[@ty::VariantInfo] = *ty::enum_variants(cx.tcx, enum_def_id);
591+
592+
let enumerators_metadata : ~[DIDescriptor] = variants
593+
.iter()
594+
.transform(|v| {
595+
let name : &str = cx.sess.str_of(v.name);
596+
let discriminant_value = v.disr_val as c_ulonglong;
597+
598+
do name.as_c_str |name| { unsafe {
599+
llvm::LLVMDIBuilderCreateEnumerator(
600+
DIB(cx),
601+
name,
602+
discriminant_value)
603+
}}
604+
})
605+
.collect();
606+
607+
let loc = span_start(cx, span);
608+
let file_metadata = get_or_create_file_metadata(cx, loc.file.name);
609+
610+
let discriminant_type_metadata = do enum_name.as_c_str |enum_name| { unsafe {
611+
llvm::LLVMDIBuilderCreateEnumerationType(
612+
DIB(cx),
613+
file_metadata,
614+
enum_name,
615+
file_metadata,
616+
loc.line as c_uint,
617+
bytes_to_bits(discriminant_size),
618+
bytes_to_bits(discriminant_align),
619+
create_DIArray(DIB(cx), enumerators_metadata),
620+
discriminant_type_metadata)
621+
}};
622+
623+
let type_rep = adt::represent_type(cx, enum_type);
624+
625+
match *type_rep {
626+
adt::CEnum(*) => {
627+
return discriminant_type_metadata;
628+
}
629+
adt::Univariant(ref struct_def, _destroyed_flag) => {
630+
assert!(variants.len() == 1);
631+
return create_adt_struct_metadata(cx, struct_def, variants[0], None, span);
632+
}
633+
adt::General(ref struct_defs) => {
634+
let variants_member_metadata : ~[DIDescriptor] = do struct_defs
635+
.iter()
636+
.enumerate()
637+
.transform |(i, struct_def)| {
638+
let variant_type_metadata = create_adt_struct_metadata(
639+
cx,
640+
struct_def,
641+
variants[i],
642+
Some(discriminant_type_metadata),
643+
span);
644+
645+
do "".as_c_str |name| { unsafe {
646+
llvm::LLVMDIBuilderCreateMemberType(
647+
DIB(cx),
648+
file_metadata,
649+
name,
650+
file_metadata,
651+
loc.line as c_uint,
652+
bytes_to_bits(struct_def.size as uint),
653+
bytes_to_bits(struct_def.align as uint),
654+
bytes_to_bits(0),
655+
0,
656+
variant_type_metadata)
657+
}}
658+
}.collect();
659+
660+
let enum_llvm_type = type_of::type_of(cx, enum_type);
661+
let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
662+
663+
return do enum_name.as_c_str |enum_name| { unsafe { llvm::LLVMDIBuilderCreateUnionType(
664+
DIB(cx),
665+
file_metadata,
666+
enum_name,
667+
file_metadata,
668+
loc.line as c_uint,
669+
bytes_to_bits(enum_type_size),
670+
bytes_to_bits(enum_type_align),
671+
0, // Flags
672+
create_DIArray(DIB(cx), variants_member_metadata),
673+
0) // RuntimeLang
674+
}};
675+
}
676+
_ => { return ptr::null(); }
677+
}
678+
679+
fn create_adt_struct_metadata(cx: &mut CrateContext,
680+
struct_def: &adt::Struct,
681+
variant_info: &ty::VariantInfo,
682+
discriminant_type_metadata: Option<DIType>,
683+
span: span)
684+
-> DICompositeType
685+
{
686+
let arg_llvm_types : ~[Type] = do struct_def.fields.map |&ty| { type_of::type_of(cx, ty) };
687+
let arg_metadata : ~[DIType] = do struct_def.fields.iter().enumerate()
688+
.transform |(i, &ty)| {
689+
match discriminant_type_metadata {
690+
Some(metadata) if i == 0 => metadata,
691+
_ => get_or_create_type_metadata(cx, ty, span)
692+
}
693+
}.collect();
694+
695+
let mut arg_names = match variant_info.arg_names {
696+
Some(ref names) => do names.map |ident| { cx.sess.str_of(*ident).to_owned() },
697+
None => do variant_info.args.map |_| { ~"" }
698+
};
699+
700+
if (discriminant_type_metadata.is_some()) {
701+
arg_names.insert(0, ~"");
702+
}
703+
704+
let variant_llvm_type = Type::struct_(arg_llvm_types, struct_def.packed);
705+
let variant_name : &str = cx.sess.str_of(variant_info.name);
706+
707+
return create_composite_type_metadata(
708+
cx,
709+
variant_llvm_type,
710+
variant_name,
711+
arg_llvm_types,
712+
arg_names,
713+
arg_metadata,
714+
span);
715+
}
716+
}
717+
718+
#[cfg(stage0)]
563719
fn create_enum_metadata(cx: &mut CrateContext,
564720
enum_type: ty::t,
565721
enum_def_id: ast::def_id,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
// check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}}
2323

2424
// debugger:print *univariant_ref
25-
// check:$3 = {{4820353753753434}}
25+
// check:$3 = {4820353753753434}
2626

2727
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
2828
// the size of the discriminant value is machine dependent, this has be taken into account when

src/test/debug-info/managed-enum.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
// check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}}
2323

2424
// debugger:print univariant->val
25-
// check:$3 = {{-9747455}}
25+
// check:$3 = {-9747455}
2626

2727
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
2828
// the size of the discriminant value is machine dependent, this has be taken into account when

src/test/debug-info/struct-in-enum.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
// check:$2 = {{Case2, 0, {x = 286331153, y = 286331153, z = 4369}}, {Case2, 0, 1229782938247303441, 4369}}
2222

2323
// debugger:print univariant
24-
// check:$3 = {{{x = 123, y = 456, z = 789}}}
24+
// check:$3 = {{x = 123, y = 456, z = 789}}
2525

2626
struct Struct {
2727
x: u32,

src/test/debug-info/struct-style-enum.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
// check:$3 = {{Case3, a = 0, b = 22873, c = 22873, d = 22873, e = 22873}, {Case3, a = 0, b = 1499027801, c = 1499027801}, {Case3, a = 0, b = 6438275382588823897}}
2525

2626
// debugger:print univariant
27-
// check:$4 = {{a = -1}}
27+
// check:$4 = {a = -1}
2828

2929
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
3030
// the size of the discriminant value is machine dependent, this has be taken into account when

src/test/debug-info/tuple-style-enum.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
// check:$3 = {{Case3, 0, 22873, 22873, 22873, 22873}, {Case3, 0, 1499027801, 1499027801}, {Case3, 0, 6438275382588823897}}
2525

2626
// debugger:print univariant
27-
// check:$4 = {{-1}}
27+
// check:$4 = {-1}
2828

2929
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
3030
// the size of the discriminant value is machine dependent, this has be taken into account when

src/test/debug-info/unique-enum.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
// check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}}
2323

2424
// debugger:print *univariant
25-
// check:$3 = {{123234}}
25+
// check:$3 = {123234}
2626

2727
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
2828
// the size of the discriminant value is machine dependent, this has be taken into account when

0 commit comments

Comments
 (0)