@@ -130,6 +130,7 @@ use driver::session::{FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
130
130
use lib:: llvm:: llvm;
131
131
use lib:: llvm:: { ModuleRef , ContextRef , ValueRef } ;
132
132
use lib:: llvm:: debuginfo:: * ;
133
+ use metadata:: csearch;
133
134
use middle:: trans:: adt;
134
135
use middle:: trans:: common:: * ;
135
136
use middle:: trans:: datum:: { Datum , Lvalue } ;
@@ -178,6 +179,7 @@ pub struct CrateDebugContext {
178
179
current_debug_location : Cell < DebugLocation > ,
179
180
created_files : RefCell < HashMap < ~str , DIFile > > ,
180
181
created_types : RefCell < HashMap < uint , DIType > > ,
182
+ created_enum_disr_types : RefCell < HashMap < ast:: DefId , DIType > > ,
181
183
namespace_map : RefCell < HashMap < Vec < ast:: Name > , @NamespaceTreeNode > > ,
182
184
// This collection is used to assert that composite types (structs, enums, ...) have their
183
185
// members only set once:
@@ -196,6 +198,7 @@ impl CrateDebugContext {
196
198
current_debug_location : Cell :: new ( UnknownLocation ) ,
197
199
created_files : RefCell :: new ( HashMap :: new ( ) ) ,
198
200
created_types : RefCell :: new ( HashMap :: new ( ) ) ,
201
+ created_enum_disr_types : RefCell :: new ( HashMap :: new ( ) ) ,
199
202
namespace_map : RefCell :: new ( HashMap :: new ( ) ) ,
200
203
composite_types_completed : RefCell :: new ( HashSet :: new ( ) ) ,
201
204
} ;
@@ -1542,24 +1545,45 @@ fn prepare_enum_metadata(cx: &CrateContext,
1542
1545
. collect ( ) ;
1543
1546
1544
1547
let discriminant_type_metadata = |inttype| {
1545
- let discriminant_llvm_type = adt:: ll_inttype ( cx, inttype) ;
1546
- let ( discriminant_size, discriminant_align) = size_and_align_of ( cx, discriminant_llvm_type) ;
1547
- let discriminant_base_type_metadata = type_metadata ( cx, adt:: ty_of_inttype ( inttype) ,
1548
- codemap:: DUMMY_SP ) ;
1549
- enum_name. with_c_str ( |enum_name| {
1550
- unsafe {
1551
- llvm:: LLVMDIBuilderCreateEnumerationType (
1552
- DIB ( cx) ,
1553
- containing_scope,
1554
- enum_name,
1555
- file_metadata,
1556
- loc. line as c_uint ,
1557
- bytes_to_bits ( discriminant_size) ,
1558
- bytes_to_bits ( discriminant_align) ,
1559
- create_DIArray ( DIB ( cx) , enumerators_metadata. as_slice ( ) ) ,
1560
- discriminant_base_type_metadata)
1548
+ // We can reuse the type of the discriminant for all monomorphized instances of an enum
1549
+ // because it doesn't depend on any type parameters. The def_id, uniquely identifying the
1550
+ // enum's polytype acts as key in this cache.
1551
+ let cached_discriminant_type_metadata = debug_context ( cx) . created_enum_disr_types
1552
+ . borrow ( )
1553
+ . find_copy ( & enum_def_id) ;
1554
+ match cached_discriminant_type_metadata {
1555
+ Some ( discriminant_type_metadata) => discriminant_type_metadata,
1556
+ None => {
1557
+ let discriminant_llvm_type = adt:: ll_inttype ( cx, inttype) ;
1558
+ let ( discriminant_size, discriminant_align) =
1559
+ size_and_align_of ( cx, discriminant_llvm_type) ;
1560
+ let discriminant_base_type_metadata = type_metadata ( cx,
1561
+ adt:: ty_of_inttype ( inttype) ,
1562
+ codemap:: DUMMY_SP ) ;
1563
+ let discriminant_name = get_enum_discriminant_name ( cx, enum_def_id) ;
1564
+
1565
+ let discriminant_type_metadata = discriminant_name. get ( ) . with_c_str ( |name| {
1566
+ unsafe {
1567
+ llvm:: LLVMDIBuilderCreateEnumerationType (
1568
+ DIB ( cx) ,
1569
+ containing_scope,
1570
+ name,
1571
+ file_metadata,
1572
+ loc. line as c_uint ,
1573
+ bytes_to_bits ( discriminant_size) ,
1574
+ bytes_to_bits ( discriminant_align) ,
1575
+ create_DIArray ( DIB ( cx) , enumerators_metadata. as_slice ( ) ) ,
1576
+ discriminant_base_type_metadata)
1577
+ }
1578
+ } ) ;
1579
+
1580
+ debug_context ( cx) . created_enum_disr_types
1581
+ . borrow_mut ( )
1582
+ . insert ( enum_def_id, discriminant_type_metadata) ;
1583
+
1584
+ discriminant_type_metadata
1561
1585
}
1562
- } )
1586
+ }
1563
1587
} ;
1564
1588
1565
1589
let type_rep = adt:: represent_type ( cx, enum_type) ;
@@ -1648,6 +1672,16 @@ fn prepare_enum_metadata(cx: &CrateContext,
1648
1672
}
1649
1673
}
1650
1674
} ;
1675
+
1676
+ fn get_enum_discriminant_name ( cx : & CrateContext , def_id : ast:: DefId ) -> token:: InternedString {
1677
+ let name = if def_id. krate == ast:: LOCAL_CRATE {
1678
+ cx. tcx . map . get_path_elem ( def_id. node ) . name ( )
1679
+ } else {
1680
+ csearch:: get_item_path ( & cx. tcx , def_id) . last ( ) . unwrap ( ) . name ( )
1681
+ } ;
1682
+
1683
+ token:: get_name ( name)
1684
+ }
1651
1685
}
1652
1686
1653
1687
enum MemberOffset {
0 commit comments