Skip to content

Commit 1380893

Browse files
debuginfo: Add documentation comments to debuginfo.rs
Conflicts: src/librustc/middle/trans/debuginfo.rs
1 parent ff2bf58 commit 1380893

File tree

1 file changed

+134
-88
lines changed

1 file changed

+134
-88
lines changed

src/librustc/middle/trans/debuginfo.rs

Lines changed: 134 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,33 +1208,108 @@ fn pointer_type_metadata(cx: &CrateContext,
12081208
return ptr_metadata;
12091209
}
12101210

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.
12111233
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)
12161238
}
12171239

12181240
impl MemberDescriptionFactory {
1219-
fn create_member_descriptions(&self, cx: &CrateContext)
1220-
-> Vec<MemberDescription> {
1241+
fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
12211242
match *self {
1222-
StructMD(ref this) => {
1243+
StructMDF(ref this) => {
12231244
this.create_member_descriptions(cx)
12241245
}
1225-
TupleMD(ref this) => {
1246+
TupleMDF(ref this) => {
12261247
this.create_member_descriptions(cx)
12271248
}
1228-
GeneralMD(ref this) => {
1249+
EnumMDF(ref this) => {
12291250
this.create_member_descriptions(cx)
12301251
}
1231-
EnumVariantMD(ref this) => {
1252+
VariantMDF(ref this) => {
12321253
this.create_member_descriptions(cx)
12331254
}
12341255
}
12351256
}
12361257
}
12371258

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
12381313
struct StructMemberDescriptionFactory {
12391314
fields: Vec<ty::field>,
12401315
is_simd: bool,
@@ -1248,7 +1323,7 @@ impl StructMemberDescriptionFactory {
12481323
}
12491324

12501325
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
12521327
} else {
12531328
0xdeadbeef
12541329
};
@@ -1262,7 +1337,7 @@ impl StructMemberDescriptionFactory {
12621337

12631338
let offset = if self.is_simd {
12641339
assert!(field_size != 0xdeadbeef);
1265-
FixedMemberOffset { bytes: i as u64 * field_size }
1340+
FixedMemberOffset { bytes: i * field_size }
12661341
} else {
12671342
ComputedMemberOffset
12681343
};
@@ -1305,57 +1380,20 @@ fn prepare_struct_metadata(cx: &CrateContext,
13051380
metadata_stub: struct_metadata_stub,
13061381
llvm_type: struct_llvm_type,
13071382
file_metadata: file_metadata,
1308-
member_description_factory: StructMD(StructMemberDescriptionFactory {
1383+
member_description_factory: StructMDF(StructMemberDescriptionFactory {
13091384
fields: fields,
13101385
is_simd: ty::type_is_simd(cx.tcx(), struct_type),
13111386
span: span,
13121387
}),
13131388
}
13141389
}
13151390

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);
13451391

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+
//=-------------------------------------------------------------------------------------------------
13581395

1396+
// Creates MemberDescriptions for the fields of a tuple
13591397
struct TupleMemberDescriptionFactory {
13601398
component_types: Vec<ty::t> ,
13611399
span: Span,
@@ -1396,25 +1434,33 @@ fn prepare_tuple_metadata(cx: &CrateContext,
13961434
span),
13971435
llvm_type: tuple_llvm_type,
13981436
file_metadata: file_metadata,
1399-
member_description_factory: TupleMD(TupleMemberDescriptionFactory {
1437+
member_description_factory: TupleMDF(TupleMemberDescriptionFactory {
14001438
component_types: Vec::from_slice(component_types),
14011439
span: span,
14021440
})
14031441
}
14041442
}
14051443

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 {
14071454
type_rep: Rc<adt::Repr>,
14081455
variants: Rc<Vec<Rc<ty::VariantInfo>>>,
1409-
discriminant_type_metadata: ValueRef,
1456+
discriminant_type_metadata: DIType,
14101457
containing_scope: DIScope,
14111458
file_metadata: DIFile,
14121459
span: Span,
14131460
}
14141461

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> {
14181464
// Capture type_rep, so we don't have to copy the struct_defs array
14191465
let struct_defs = match *self.type_rep {
14201466
adt::General(_, ref struct_defs) => struct_defs,
@@ -1429,7 +1475,7 @@ impl GeneralMemberDescriptionFactory {
14291475
describe_enum_variant(cx,
14301476
struct_def,
14311477
&**self.variants.get(i),
1432-
Some(self.discriminant_type_metadata),
1478+
RegularDiscriminant(self.discriminant_type_metadata),
14331479
self.containing_scope,
14341480
self.file_metadata,
14351481
self.span);
@@ -1453,15 +1499,15 @@ impl GeneralMemberDescriptionFactory {
14531499
}
14541500
}
14551501

1456-
struct EnumVariantMemberDescriptionFactory {
1502+
// Creates MemberDescriptions for the fields of a single enum variant
1503+
struct VariantMemberDescriptionFactory {
14571504
args: Vec<(String, ty::t)> ,
14581505
discriminant_type_metadata: Option<DIType>,
14591506
span: Span,
14601507
}
14611508

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> {
14651511
self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
14661512
MemberDescription {
14671513
name: name.to_string(),
@@ -1476,10 +1522,19 @@ impl EnumVariantMemberDescriptionFactory {
14761522
}
14771523
}
14781524

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.
14791534
fn describe_enum_variant(cx: &CrateContext,
14801535
struct_def: &adt::Struct,
14811536
variant_info: &ty::VariantInfo,
1482-
discriminant_type_metadata: Option<DIType>,
1537+
discriminant_info: EnumDiscriminantInfo,
14831538
containing_scope: DIScope,
14841539
file_metadata: DIFile,
14851540
span: Span)
@@ -1520,9 +1575,10 @@ fn describe_enum_variant(cx: &CrateContext,
15201575
};
15211576

15221577
// 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+
};
15261582

15271583
// Build an array of (field name, field type) pairs to be captured in the factory closure.
15281584
let args: Vec<(String, ty::t)> = arg_names.iter()
@@ -1531,9 +1587,12 @@ fn describe_enum_variant(cx: &CrateContext,
15311587
.collect();
15321588

15331589
let member_description_factory =
1534-
EnumVariantMD(EnumVariantMemberDescriptionFactory {
1590+
VariantMDF(VariantMemberDescriptionFactory {
15351591
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+
},
15371596
span: span,
15381597
});
15391598

@@ -1638,7 +1697,7 @@ fn prepare_enum_metadata(cx: &CrateContext,
16381697
describe_enum_variant(cx,
16391698
struct_def,
16401699
&**variants.get(0),
1641-
None,
1700+
NoDiscriminant,
16421701
containing_scope,
16431702
file_metadata,
16441703
span);
@@ -1680,7 +1739,7 @@ fn prepare_enum_metadata(cx: &CrateContext,
16801739
metadata_stub: enum_metadata,
16811740
llvm_type: enum_llvm_type,
16821741
file_metadata: file_metadata,
1683-
member_description_factory: GeneralMD(GeneralMemberDescriptionFactory {
1742+
member_description_factory: EnumMDF(EnumMemberDescriptionFactory {
16841743
type_rep: type_rep.clone(),
16851744
variants: variants,
16861745
discriminant_type_metadata: discriminant_type_metadata,
@@ -1693,14 +1752,14 @@ fn prepare_enum_metadata(cx: &CrateContext,
16931752
adt::RawNullablePointer { nnty, .. } => {
16941753
FinalMetadata(type_metadata(cx, nnty, span))
16951754
}
1696-
adt::StructWrappedNullablePointer { nonnull: ref struct_def, nndiscr, .. } => {
1755+
adt::StructWrappedNullablePointer { nonnull: ref struct_def, nndiscr, ptrfield, .. } => {
16971756
let (metadata_stub,
16981757
variant_llvm_type,
16991758
member_description_factory) =
17001759
describe_enum_variant(cx,
17011760
struct_def,
17021761
&**variants.get(nndiscr as uint),
1703-
None,
1762+
OptimizedDiscriminant(ptrfield),
17041763
containing_scope,
17051764
file_metadata,
17061765
span);
@@ -1725,19 +1784,6 @@ fn prepare_enum_metadata(cx: &CrateContext,
17251784
}
17261785
}
17271786

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-
17411787
/// Creates debug information for a composite type, that is, anything that results in a LLVM struct.
17421788
///
17431789
/// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.

0 commit comments

Comments
 (0)