@@ -1208,33 +1208,108 @@ fn pointer_type_metadata(cx: &CrateContext,
1208
1208
return ptr_metadata;
1209
1209
}
1210
1210
1211
+ //=-------------------------------------------------------------------------------------------------
1212
+ // Common facilities for record-like types (structs, enums, tuples)
1213
+ //=-------------------------------------------------------------------------------------------------
1214
+
1215
+ enum MemberOffset {
1216
+ FixedMemberOffset { bytes : uint } ,
1217
+ // For ComputedMemberOffset, the offset is read from the llvm type definition
1218
+ ComputedMemberOffset
1219
+ }
1220
+
1221
+ // Description of a type member, which can either be a regular field (as in structs or tuples) or
1222
+ // an enum variant
1223
+ struct MemberDescription {
1224
+ name : String ,
1225
+ llvm_type : Type ,
1226
+ type_metadata : DIType ,
1227
+ offset : MemberOffset ,
1228
+ }
1229
+
1230
+ // A factory for MemberDescriptions. It produces a list of member descriptions for some record-like
1231
+ // type. MemberDescriptionFactories are used to defer the creation of type member descriptions in
1232
+ // order to break cycles arising from recursive type definitions.
1211
1233
enum MemberDescriptionFactory {
1212
- StructMD ( StructMemberDescriptionFactory ) ,
1213
- TupleMD ( TupleMemberDescriptionFactory ) ,
1214
- GeneralMD ( GeneralMemberDescriptionFactory ) ,
1215
- EnumVariantMD ( EnumVariantMemberDescriptionFactory )
1234
+ StructMDF ( StructMemberDescriptionFactory ) ,
1235
+ TupleMDF ( TupleMemberDescriptionFactory ) ,
1236
+ EnumMDF ( EnumMemberDescriptionFactory ) ,
1237
+ VariantMDF ( VariantMemberDescriptionFactory )
1216
1238
}
1217
1239
1218
1240
impl MemberDescriptionFactory {
1219
- fn create_member_descriptions ( & self , cx : & CrateContext )
1220
- -> Vec < MemberDescription > {
1241
+ fn create_member_descriptions ( & self , cx : & CrateContext ) -> Vec < MemberDescription > {
1221
1242
match * self {
1222
- StructMD ( ref this) => {
1243
+ StructMDF ( ref this) => {
1223
1244
this. create_member_descriptions ( cx)
1224
1245
}
1225
- TupleMD ( ref this) => {
1246
+ TupleMDF ( ref this) => {
1226
1247
this. create_member_descriptions ( cx)
1227
1248
}
1228
- GeneralMD ( ref this) => {
1249
+ EnumMDF ( ref this) => {
1229
1250
this. create_member_descriptions ( cx)
1230
1251
}
1231
- EnumVariantMD ( ref this) => {
1252
+ VariantMDF ( ref this) => {
1232
1253
this. create_member_descriptions ( cx)
1233
1254
}
1234
1255
}
1235
1256
}
1236
1257
}
1237
1258
1259
+ // A description of some recursive type. It can either be already finished (as with FinalMetadata)
1260
+ // or it is not yet finished, but contains all information needed to generate the missing parts of
1261
+ // the description. See the documentation section on Recursive Types at the top of this file for
1262
+ // more information.
1263
+ enum RecursiveTypeDescription {
1264
+ UnfinishedMetadata {
1265
+ cache_id : uint ,
1266
+ metadata_stub : DICompositeType ,
1267
+ llvm_type : Type ,
1268
+ file_metadata : DIFile ,
1269
+ member_description_factory : MemberDescriptionFactory ,
1270
+ } ,
1271
+ FinalMetadata ( DICompositeType )
1272
+ }
1273
+
1274
+ impl RecursiveTypeDescription {
1275
+ // Finishes up the description of the type in question (mostly by providing description of the
1276
+ // fields of the given type) and returns the final type metadata.
1277
+ fn finalize ( & self , cx : & CrateContext ) -> DICompositeType {
1278
+ match * self {
1279
+ FinalMetadata ( metadata) => metadata,
1280
+ UnfinishedMetadata {
1281
+ cache_id,
1282
+ metadata_stub,
1283
+ llvm_type,
1284
+ file_metadata,
1285
+ ref member_description_factory
1286
+ } => {
1287
+ // Insert the stub into the cache in order to allow recursive references ...
1288
+ debug_context ( cx) . created_types . borrow_mut ( )
1289
+ . insert ( cache_id, metadata_stub) ;
1290
+
1291
+ // ... then create the member descriptions ...
1292
+ let member_descriptions = member_description_factory. create_member_descriptions ( cx) ;
1293
+
1294
+ // ... and attach them to the stub to complete it.
1295
+ set_members_of_composite_type ( cx,
1296
+ metadata_stub,
1297
+ llvm_type,
1298
+ member_descriptions. as_slice ( ) ,
1299
+ file_metadata,
1300
+ codemap:: DUMMY_SP ) ;
1301
+ return metadata_stub;
1302
+ }
1303
+ }
1304
+ }
1305
+ }
1306
+
1307
+
1308
+ //=-------------------------------------------------------------------------------------------------
1309
+ // Structs
1310
+ //=-------------------------------------------------------------------------------------------------
1311
+
1312
+ // Creates MemberDescriptions for the fields of a struct
1238
1313
struct StructMemberDescriptionFactory {
1239
1314
fields : Vec < ty:: field > ,
1240
1315
is_simd : bool ,
@@ -1248,7 +1323,7 @@ impl StructMemberDescriptionFactory {
1248
1323
}
1249
1324
1250
1325
let field_size = if self . is_simd {
1251
- machine:: llsize_of_alloc ( cx, type_of:: type_of ( cx, self . fields . get ( 0 ) . mt . ty ) )
1326
+ machine:: llsize_of_alloc ( cx, type_of:: type_of ( cx, self . fields . get ( 0 ) . mt . ty ) ) as uint
1252
1327
} else {
1253
1328
0xdeadbeef
1254
1329
} ;
@@ -1262,7 +1337,7 @@ impl StructMemberDescriptionFactory {
1262
1337
1263
1338
let offset = if self . is_simd {
1264
1339
assert ! ( field_size != 0xdeadbeef ) ;
1265
- FixedMemberOffset { bytes : i as u64 * field_size }
1340
+ FixedMemberOffset { bytes : i * field_size }
1266
1341
} else {
1267
1342
ComputedMemberOffset
1268
1343
} ;
@@ -1305,57 +1380,20 @@ fn prepare_struct_metadata(cx: &CrateContext,
1305
1380
metadata_stub : struct_metadata_stub,
1306
1381
llvm_type : struct_llvm_type,
1307
1382
file_metadata : file_metadata,
1308
- member_description_factory : StructMD ( StructMemberDescriptionFactory {
1383
+ member_description_factory : StructMDF ( StructMemberDescriptionFactory {
1309
1384
fields : fields,
1310
1385
is_simd : ty:: type_is_simd ( cx. tcx ( ) , struct_type) ,
1311
1386
span : span,
1312
1387
} ) ,
1313
1388
}
1314
1389
}
1315
1390
1316
- enum RecursiveTypeDescription {
1317
- UnfinishedMetadata {
1318
- cache_id : uint ,
1319
- metadata_stub : DICompositeType ,
1320
- llvm_type : Type ,
1321
- file_metadata : DIFile ,
1322
- member_description_factory : MemberDescriptionFactory ,
1323
- } ,
1324
- FinalMetadata ( DICompositeType )
1325
- }
1326
-
1327
- impl RecursiveTypeDescription {
1328
-
1329
- fn finalize ( & self , cx : & CrateContext ) -> DICompositeType {
1330
- match * self {
1331
- FinalMetadata ( metadata) => metadata,
1332
- UnfinishedMetadata {
1333
- cache_id,
1334
- metadata_stub,
1335
- llvm_type,
1336
- file_metadata,
1337
- ref member_description_factory
1338
- } => {
1339
- // Insert the stub into the cache in order to allow recursive references ...
1340
- debug_context ( cx) . created_types . borrow_mut ( )
1341
- . insert ( cache_id, metadata_stub) ;
1342
-
1343
- // ... then create the member descriptions ...
1344
- let member_descriptions = member_description_factory. create_member_descriptions ( cx) ;
1345
1391
1346
- // ... and attach them to the stub to complete it.
1347
- set_members_of_composite_type ( cx,
1348
- metadata_stub,
1349
- llvm_type,
1350
- member_descriptions. as_slice ( ) ,
1351
- file_metadata,
1352
- codemap:: DUMMY_SP ) ;
1353
- return metadata_stub;
1354
- }
1355
- }
1356
- }
1357
- }
1392
+ //=-------------------------------------------------------------------------------------------------
1393
+ // Tuples
1394
+ //=-------------------------------------------------------------------------------------------------
1358
1395
1396
+ // Creates MemberDescriptions for the fields of a tuple
1359
1397
struct TupleMemberDescriptionFactory {
1360
1398
component_types : Vec < ty:: t > ,
1361
1399
span : Span ,
@@ -1396,25 +1434,33 @@ fn prepare_tuple_metadata(cx: &CrateContext,
1396
1434
span) ,
1397
1435
llvm_type : tuple_llvm_type,
1398
1436
file_metadata : file_metadata,
1399
- member_description_factory : TupleMD ( TupleMemberDescriptionFactory {
1437
+ member_description_factory : TupleMDF ( TupleMemberDescriptionFactory {
1400
1438
component_types : Vec :: from_slice ( component_types) ,
1401
1439
span : span,
1402
1440
} )
1403
1441
}
1404
1442
}
1405
1443
1406
- struct GeneralMemberDescriptionFactory {
1444
+
1445
+ //=-------------------------------------------------------------------------------------------------
1446
+ // Enums
1447
+ //=-------------------------------------------------------------------------------------------------
1448
+
1449
+ // Describes the members of an enum value: An enum is described as a union of structs in DWARF. This
1450
+ // MemberDescriptionFactory provides the description for the members of this union; so for every
1451
+ // variant of the given enum, this factory will produce one MemberDescription (all with no name and
1452
+ // a fixed offset of zero bytes).
1453
+ struct EnumMemberDescriptionFactory {
1407
1454
type_rep : Rc < adt:: Repr > ,
1408
1455
variants : Rc < Vec < Rc < ty:: VariantInfo > > > ,
1409
- discriminant_type_metadata : ValueRef ,
1456
+ discriminant_type_metadata : DIType ,
1410
1457
containing_scope : DIScope ,
1411
1458
file_metadata : DIFile ,
1412
1459
span : Span ,
1413
1460
}
1414
1461
1415
- impl GeneralMemberDescriptionFactory {
1416
- fn create_member_descriptions ( & self , cx : & CrateContext )
1417
- -> Vec < MemberDescription > {
1462
+ impl EnumMemberDescriptionFactory {
1463
+ fn create_member_descriptions ( & self , cx : & CrateContext ) -> Vec < MemberDescription > {
1418
1464
// Capture type_rep, so we don't have to copy the struct_defs array
1419
1465
let struct_defs = match * self . type_rep {
1420
1466
adt:: General ( _, ref struct_defs) => struct_defs,
@@ -1429,7 +1475,7 @@ impl GeneralMemberDescriptionFactory {
1429
1475
describe_enum_variant ( cx,
1430
1476
struct_def,
1431
1477
& * * self . variants . get ( i) ,
1432
- Some ( self . discriminant_type_metadata ) ,
1478
+ RegularDiscriminant ( self . discriminant_type_metadata ) ,
1433
1479
self . containing_scope ,
1434
1480
self . file_metadata ,
1435
1481
self . span ) ;
@@ -1453,15 +1499,15 @@ impl GeneralMemberDescriptionFactory {
1453
1499
}
1454
1500
}
1455
1501
1456
- struct EnumVariantMemberDescriptionFactory {
1502
+ // Creates MemberDescriptions for the fields of a single enum variant
1503
+ struct VariantMemberDescriptionFactory {
1457
1504
args : Vec < ( String , ty:: t ) > ,
1458
1505
discriminant_type_metadata : Option < DIType > ,
1459
1506
span : Span ,
1460
1507
}
1461
1508
1462
- impl EnumVariantMemberDescriptionFactory {
1463
- fn create_member_descriptions ( & self , cx : & CrateContext )
1464
- -> Vec < MemberDescription > {
1509
+ impl VariantMemberDescriptionFactory {
1510
+ fn create_member_descriptions ( & self , cx : & CrateContext ) -> Vec < MemberDescription > {
1465
1511
self . args . iter ( ) . enumerate ( ) . map ( |( i, & ( ref name, ty) ) | {
1466
1512
MemberDescription {
1467
1513
name : name. to_string ( ) ,
@@ -1476,10 +1522,19 @@ impl EnumVariantMemberDescriptionFactory {
1476
1522
}
1477
1523
}
1478
1524
1525
+ enum EnumDiscriminantInfo {
1526
+ RegularDiscriminant ( DIType ) ,
1527
+ OptimizedDiscriminant ( uint ) ,
1528
+ NoDiscriminant
1529
+ }
1530
+
1531
+ // Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type of the variant, and
1532
+ // (3) a MemberDescriptionFactory for producing the descriptions of the fields of the variant. This
1533
+ // is a rudimentary version of a full RecursiveTypeDescription.
1479
1534
fn describe_enum_variant ( cx : & CrateContext ,
1480
1535
struct_def : & adt:: Struct ,
1481
1536
variant_info : & ty:: VariantInfo ,
1482
- discriminant_type_metadata : Option < DIType > ,
1537
+ discriminant_info : EnumDiscriminantInfo ,
1483
1538
containing_scope : DIScope ,
1484
1539
file_metadata : DIFile ,
1485
1540
span : Span )
@@ -1520,9 +1575,10 @@ fn describe_enum_variant(cx: &CrateContext,
1520
1575
} ;
1521
1576
1522
1577
// If this is not a univariant enum, there is also the (unnamed) discriminant field
1523
- if discriminant_type_metadata. is_some ( ) {
1524
- arg_names. insert ( 0 , "" . to_string ( ) ) ;
1525
- }
1578
+ match discriminant_info {
1579
+ RegularDiscriminant ( _) => arg_names. insert ( 0 , "" . to_string ( ) ) ,
1580
+ _ => { /* do nothing */ }
1581
+ } ;
1526
1582
1527
1583
// Build an array of (field name, field type) pairs to be captured in the factory closure.
1528
1584
let args: Vec < ( String , ty:: t ) > = arg_names. iter ( )
@@ -1531,9 +1587,12 @@ fn describe_enum_variant(cx: &CrateContext,
1531
1587
. collect ( ) ;
1532
1588
1533
1589
let member_description_factory =
1534
- EnumVariantMD ( EnumVariantMemberDescriptionFactory {
1590
+ VariantMDF ( VariantMemberDescriptionFactory {
1535
1591
args : args,
1536
- discriminant_type_metadata : discriminant_type_metadata,
1592
+ discriminant_type_metadata : match discriminant_info {
1593
+ RegularDiscriminant ( discriminant_type_metadata) => Some ( discriminant_type_metadata) ,
1594
+ _ => None
1595
+ } ,
1537
1596
span : span,
1538
1597
} ) ;
1539
1598
@@ -1638,7 +1697,7 @@ fn prepare_enum_metadata(cx: &CrateContext,
1638
1697
describe_enum_variant ( cx,
1639
1698
struct_def,
1640
1699
& * * variants. get ( 0 ) ,
1641
- None ,
1700
+ NoDiscriminant ,
1642
1701
containing_scope,
1643
1702
file_metadata,
1644
1703
span) ;
@@ -1680,7 +1739,7 @@ fn prepare_enum_metadata(cx: &CrateContext,
1680
1739
metadata_stub : enum_metadata,
1681
1740
llvm_type : enum_llvm_type,
1682
1741
file_metadata : file_metadata,
1683
- member_description_factory : GeneralMD ( GeneralMemberDescriptionFactory {
1742
+ member_description_factory : EnumMDF ( EnumMemberDescriptionFactory {
1684
1743
type_rep : type_rep. clone ( ) ,
1685
1744
variants : variants,
1686
1745
discriminant_type_metadata : discriminant_type_metadata,
@@ -1693,14 +1752,14 @@ fn prepare_enum_metadata(cx: &CrateContext,
1693
1752
adt:: RawNullablePointer { nnty, .. } => {
1694
1753
FinalMetadata ( type_metadata ( cx, nnty, span) )
1695
1754
}
1696
- adt:: StructWrappedNullablePointer { nonnull : ref struct_def, nndiscr, .. } => {
1755
+ adt:: StructWrappedNullablePointer { nonnull : ref struct_def, nndiscr, ptrfield , .. } => {
1697
1756
let ( metadata_stub,
1698
1757
variant_llvm_type,
1699
1758
member_description_factory) =
1700
1759
describe_enum_variant ( cx,
1701
1760
struct_def,
1702
1761
& * * variants. get ( nndiscr as uint ) ,
1703
- None ,
1762
+ OptimizedDiscriminant ( ptrfield ) ,
1704
1763
containing_scope,
1705
1764
file_metadata,
1706
1765
span) ;
@@ -1725,19 +1784,6 @@ fn prepare_enum_metadata(cx: &CrateContext,
1725
1784
}
1726
1785
}
1727
1786
1728
- enum MemberOffset {
1729
- FixedMemberOffset { bytes : u64 } ,
1730
- // For ComputedMemberOffset, the offset is read from the llvm type definition
1731
- ComputedMemberOffset
1732
- }
1733
-
1734
- struct MemberDescription {
1735
- name : String ,
1736
- llvm_type : Type ,
1737
- type_metadata : DIType ,
1738
- offset : MemberOffset ,
1739
- }
1740
-
1741
1787
/// Creates debug information for a composite type, that is, anything that results in a LLVM struct.
1742
1788
///
1743
1789
/// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
0 commit comments