Skip to content

Commit e75a203

Browse files
authored
Rollup merge of rust-lang#55010 - tromey:Bug-9224-generic-parameters, r=michaelwoerister
Add template parameter debuginfo to generic types This changes debuginfo generation to add template parameters to generic types. With this change the DWARF now has DW_TAG_template_type_param for types, not just for functions, like: <2><40d>: Abbrev Number: 6 (DW_TAG_structure_type) <40e> DW_AT_name : (indirect string, offset: 0x375): Generic<i32> <412> DW_AT_byte_size : 4 <413> DW_AT_alignment : 4 ... <3><41f>: Abbrev Number: 8 (DW_TAG_template_type_param) <420> DW_AT_type : <0x42a> <424> DW_AT_name : (indirect string, offset: 0xa65e): T Closes rust-lang#9224
2 parents eed093c + 8a3bb9a commit e75a203

File tree

4 files changed

+96
-11
lines changed

4 files changed

+96
-11
lines changed

src/librustc_codegen_llvm/debuginfo/metadata.rs

+58-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use abi;
2121
use value::Value;
2222

2323
use llvm;
24-
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
24+
use llvm::debuginfo::{DIArray, DIType, DIFile, DIScope, DIDescriptor,
2525
DICompositeType, DILexicalBlock, DIFlags};
2626

2727
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -34,6 +34,7 @@ use rustc::ty::Instance;
3434
use common::CodegenCx;
3535
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
3636
use rustc::ty::layout::{self, Align, LayoutOf, PrimitiveExt, Size, TyLayout};
37+
use rustc::ty::subst::UnpackedKind;
3738
use rustc::session::config;
3839
use rustc::util::nodemap::FxHashMap;
3940
use rustc_fs_util::path2cstr;
@@ -266,6 +267,7 @@ impl RecursiveTypeDescription<'ll, 'tcx> {
266267

267268
// ... and attach them to the stub to complete it.
268269
set_members_of_composite_type(cx,
270+
unfinished_type,
269271
metadata_stub,
270272
member_descriptions);
271273
return MetadataCreationResult::new(metadata_stub, true);
@@ -1174,6 +1176,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
11741176
member_description_factory.create_member_descriptions(cx);
11751177

11761178
set_members_of_composite_type(cx,
1179+
self.enum_type,
11771180
variant_type_metadata,
11781181
member_descriptions);
11791182
vec![
@@ -1204,6 +1207,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
12041207
.create_member_descriptions(cx);
12051208

12061209
set_members_of_composite_type(cx,
1210+
self.enum_type,
12071211
variant_type_metadata,
12081212
member_descriptions);
12091213
MemberDescription {
@@ -1231,6 +1235,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
12311235
member_description_factory.create_member_descriptions(cx);
12321236

12331237
set_members_of_composite_type(cx,
1238+
self.enum_type,
12341239
variant_type_metadata,
12351240
variant_member_descriptions);
12361241

@@ -1534,13 +1539,15 @@ fn composite_type_metadata(
15341539
containing_scope);
15351540
// ... and immediately create and add the member descriptions.
15361541
set_members_of_composite_type(cx,
1542+
composite_type,
15371543
composite_type_metadata,
15381544
member_descriptions);
15391545

15401546
composite_type_metadata
15411547
}
15421548

1543-
fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>,
1549+
fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>,
1550+
composite_type: Ty<'tcx>,
15441551
composite_type_metadata: &'ll DICompositeType,
15451552
member_descriptions: Vec<MemberDescription<'ll>>) {
15461553
// In some rare cases LLVM metadata uniquing would lead to an existing type
@@ -1580,10 +1587,57 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>,
15801587
})
15811588
.collect();
15821589

1590+
let type_params = compute_type_parameters(cx, composite_type);
15831591
unsafe {
15841592
let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
1585-
llvm::LLVMRustDICompositeTypeSetTypeArray(
1586-
DIB(cx), composite_type_metadata, type_array);
1593+
llvm::LLVMRustDICompositeTypeReplaceArrays(
1594+
DIB(cx), composite_type_metadata, Some(type_array), type_params);
1595+
}
1596+
}
1597+
1598+
// Compute the type parameters for a type, if any, for the given
1599+
// metadata.
1600+
fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> Option<&'ll DIArray> {
1601+
if let ty::Adt(def, substs) = ty.sty {
1602+
if !substs.types().next().is_none() {
1603+
let generics = cx.tcx.generics_of(def.did);
1604+
let names = get_parameter_names(cx, generics);
1605+
let template_params: Vec<_> = substs.iter().zip(names).filter_map(|(kind, name)| {
1606+
if let UnpackedKind::Type(ty) = kind.unpack() {
1607+
let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
1608+
let actual_type_metadata =
1609+
type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
1610+
let name = SmallCStr::new(&name.as_str());
1611+
Some(unsafe {
1612+
1613+
Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
1614+
DIB(cx),
1615+
None,
1616+
name.as_ptr(),
1617+
actual_type_metadata,
1618+
unknown_file_metadata(cx),
1619+
0,
1620+
0,
1621+
))
1622+
})
1623+
} else {
1624+
None
1625+
}
1626+
}).collect();
1627+
1628+
return Some(create_DIArray(DIB(cx), &template_params[..]));
1629+
}
1630+
}
1631+
return None;
1632+
1633+
fn get_parameter_names(cx: &CodegenCx,
1634+
generics: &ty::Generics)
1635+
-> Vec<InternedString> {
1636+
let mut names = generics.parent.map_or(vec![], |def_id| {
1637+
get_parameter_names(cx, cx.tcx.generics_of(def_id))
1638+
});
1639+
names.extend(generics.params.iter().map(|param| param.name));
1640+
names
15871641
}
15881642
}
15891643

src/librustc_codegen_llvm/llvm/ffi.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1419,9 +1419,10 @@ extern "C" {
14191419
LineNo: c_uint)
14201420
-> &'a DINameSpace;
14211421

1422-
pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: &DIBuilder<'a>,
1423-
CompositeType: &'a DIType,
1424-
TypeArray: &'a DIArray);
1422+
pub fn LLVMRustDICompositeTypeReplaceArrays(Builder: &DIBuilder<'a>,
1423+
CompositeType: &'a DIType,
1424+
Elements: Option<&'a DIArray>,
1425+
Params: Option<&'a DIArray>);
14251426

14261427

14271428
pub fn LLVMRustDIBuilderCreateDebugLocation(Context: &'a Context,

src/rustllvm/RustWrapper.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -870,11 +870,13 @@ LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder,
870870
}
871871

872872
extern "C" void
873-
LLVMRustDICompositeTypeSetTypeArray(LLVMRustDIBuilderRef Builder,
874-
LLVMMetadataRef CompositeTy,
875-
LLVMMetadataRef TyArray) {
873+
LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
874+
LLVMMetadataRef CompositeTy,
875+
LLVMMetadataRef Elements,
876+
LLVMMetadataRef Params) {
876877
DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
877-
Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(TyArray)));
878+
Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
879+
DINodeArray(unwrap<MDTuple>(Params)));
878880
}
879881

880882
extern "C" LLVMValueRef

src/test/codegen/generic-debug.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// ignore-tidy-linelength
12+
// ignore-windows
13+
14+
// compile-flags: -g -C no-prepopulate-passes
15+
16+
// CHECK-LABEL: @main
17+
// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_structure_type,{{.*}}name: "Generic<i32>",{{.*}}
18+
// CHECK: {{.*}}DITemplateTypeParameter{{.*}}name: "Type",{{.*}}
19+
20+
#![allow(dead_code)]
21+
#![allow(unused_variables)]
22+
#![allow(unused_assignments)]
23+
24+
pub struct Generic<Type>(Type);
25+
26+
fn main () {
27+
let generic = Generic(10);
28+
}

0 commit comments

Comments
 (0)