Skip to content

Commit fb204cb

Browse files
committed
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
1 parent 0c1dc62 commit fb204cb

File tree

9 files changed

+115
-18
lines changed

9 files changed

+115
-18
lines changed

src/librustc_codegen_llvm/debuginfo/metadata.rs

+61-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use abi;
2222
use value::Value;
2323

2424
use llvm;
25-
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
25+
use llvm::debuginfo::{DIArray, DIType, DIFile, DIScope, DIDescriptor,
2626
DICompositeType, DILexicalBlock, DIFlags};
2727
use llvm_util;
2828

@@ -35,12 +35,14 @@ use rustc_data_structures::fingerprint::Fingerprint;
3535
use rustc::ty::Instance;
3636
use common::CodegenCx;
3737
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
38-
use rustc::ty::layout::{self, Align, HasDataLayout, Integer, IntegerExt, LayoutOf,
38+
use rustc::ty::layout::{self, Align, Integer, IntegerExt, LayoutOf,
3939
PrimitiveExt, Size, TyLayout};
40+
use rustc::ty::subst::UnpackedKind;
4041
use rustc::session::config;
4142
use rustc::util::nodemap::FxHashMap;
4243
use rustc_fs_util::path2cstr;
4344
use rustc_data_structures::small_c_str::SmallCStr;
45+
use rustc_target::abi::HasDataLayout;
4446

4547
use libc::{c_uint, c_longlong};
4648
use std::ffi::CString;
@@ -273,6 +275,7 @@ impl RecursiveTypeDescription<'ll, 'tcx> {
273275

274276
// ... and attach them to the stub to complete it.
275277
set_members_of_composite_type(cx,
278+
unfinished_type,
276279
member_holding_stub,
277280
member_descriptions);
278281
return MetadataCreationResult::new(metadata_stub, true);
@@ -1214,6 +1217,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
12141217
member_description_factory.create_member_descriptions(cx);
12151218

12161219
set_members_of_composite_type(cx,
1220+
self.enum_type,
12171221
variant_type_metadata,
12181222
member_descriptions);
12191223
vec![
@@ -1254,6 +1258,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
12541258
.create_member_descriptions(cx);
12551259

12561260
set_members_of_composite_type(cx,
1261+
self.enum_type,
12571262
variant_type_metadata,
12581263
member_descriptions);
12591264
MemberDescription {
@@ -1295,6 +1300,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
12951300
member_description_factory.create_member_descriptions(cx);
12961301

12971302
set_members_of_composite_type(cx,
1303+
self.enum_type,
12981304
variant_type_metadata,
12991305
variant_member_descriptions);
13001306

@@ -1354,6 +1360,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
13541360
.create_member_descriptions(cx);
13551361

13561362
set_members_of_composite_type(cx,
1363+
self.enum_type,
13571364
variant_type_metadata,
13581365
member_descriptions);
13591366

@@ -1765,13 +1772,15 @@ fn composite_type_metadata(
17651772
containing_scope);
17661773
// ... and immediately create and add the member descriptions.
17671774
set_members_of_composite_type(cx,
1775+
composite_type,
17681776
composite_type_metadata,
17691777
member_descriptions);
17701778

17711779
composite_type_metadata
17721780
}
17731781

1774-
fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>,
1782+
fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>,
1783+
composite_type: Ty<'tcx>,
17751784
composite_type_metadata: &'ll DICompositeType,
17761785
member_descriptions: Vec<MemberDescription<'ll>>) {
17771786
// In some rare cases LLVM metadata uniquing would lead to an existing type
@@ -1815,10 +1824,57 @@ fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>,
18151824
})
18161825
.collect();
18171826

1827+
let type_params = compute_type_parameters(cx, composite_type);
18181828
unsafe {
18191829
let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
1820-
llvm::LLVMRustDICompositeTypeSetTypeArray(
1821-
DIB(cx), composite_type_metadata, type_array);
1830+
llvm::LLVMRustDICompositeTypeReplaceArrays(
1831+
DIB(cx), composite_type_metadata, Some(type_array), type_params);
1832+
}
1833+
}
1834+
1835+
// Compute the type parameters for a type, if any, for the given
1836+
// metadata.
1837+
fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> Option<&'ll DIArray> {
1838+
if let ty::Adt(def, substs) = ty.sty {
1839+
if !substs.types().next().is_none() {
1840+
let generics = cx.tcx.generics_of(def.did);
1841+
let names = get_parameter_names(cx, generics);
1842+
let template_params: Vec<_> = substs.iter().zip(names).filter_map(|(kind, name)| {
1843+
if let UnpackedKind::Type(ty) = kind.unpack() {
1844+
let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
1845+
let actual_type_metadata =
1846+
type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
1847+
let name = SmallCStr::new(&name.as_str());
1848+
Some(unsafe {
1849+
1850+
Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
1851+
DIB(cx),
1852+
None,
1853+
name.as_ptr(),
1854+
actual_type_metadata,
1855+
unknown_file_metadata(cx),
1856+
0,
1857+
0,
1858+
))
1859+
})
1860+
} else {
1861+
None
1862+
}
1863+
}).collect();
1864+
1865+
return Some(create_DIArray(DIB(cx), &template_params[..]));
1866+
}
1867+
}
1868+
return Some(create_DIArray(DIB(cx), &[]));
1869+
1870+
fn get_parameter_names(cx: &CodegenCx,
1871+
generics: &ty::Generics)
1872+
-> Vec<InternedString> {
1873+
let mut names = generics.parent.map_or(vec![], |def_id| {
1874+
get_parameter_names(cx, cx.tcx.generics_of(def_id))
1875+
});
1876+
names.extend(generics.params.iter().map(|param| param.name));
1877+
names
18221878
}
18231879
}
18241880

src/librustc_codegen_llvm/llvm/ffi.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1586,9 +1586,10 @@ extern "C" {
15861586
LineNo: c_uint)
15871587
-> &'a DINameSpace;
15881588

1589-
pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: &DIBuilder<'a>,
1590-
CompositeType: &'a DIType,
1591-
TypeArray: &'a DIArray);
1589+
pub fn LLVMRustDICompositeTypeReplaceArrays(Builder: &DIBuilder<'a>,
1590+
CompositeType: &'a DIType,
1591+
Elements: Option<&'a DIArray>,
1592+
Params: Option<&'a DIArray>);
15921593

15931594

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

src/rustllvm/RustWrapper.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -824,11 +824,13 @@ LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder,
824824
}
825825

826826
extern "C" void
827-
LLVMRustDICompositeTypeSetTypeArray(LLVMRustDIBuilderRef Builder,
828-
LLVMMetadataRef CompositeTy,
829-
LLVMMetadataRef TyArray) {
827+
LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
828+
LLVMMetadataRef CompositeTy,
829+
LLVMMetadataRef Elements,
830+
LLVMMetadataRef Params) {
830831
DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
831-
Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(TyArray)));
832+
Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
833+
DINodeArray(unwrap<MDTuple>(Params)));
832834
}
833835

834836
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+
}

src/test/debuginfo/associated-types.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// min-lldb-version: 310
11+
// Some versions of the non-rust-enabled LLDB print the wrong generic
12+
// parameter type names in this test.
13+
// rust-lldb
1214

1315
// compile-flags:-g
1416

src/test/debuginfo/generic-method-on-generic-struct.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
// ignore-tidy-linelength
1212

1313
// compile-flags:-g
14-
// min-lldb-version: 310
14+
15+
// Some versions of the non-rust-enabled LLDB print the wrong generic
16+
// parameter type names in this test.
17+
// rust-lldb
1518

1619
// === GDB TESTS ===================================================================================
1720

src/test/debuginfo/generic-struct.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
// except according to those terms.
1010

1111
// ignore-tidy-linelength
12-
// min-lldb-version: 310
12+
13+
// Some versions of the non-rust-enabled LLDB print the wrong generic
14+
// parameter type names in this test.
15+
// rust-lldb
1316

1417
// compile-flags:-g
1518

src/test/debuginfo/generic-tuple-style-enum.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
// lldb-command:run
4242

4343
// lldb-command:print case1
44-
// lldbr-check:(generic_tuple_style_enum::Regular<u16, u32, u64>::Case1) case1 = { = 0 = 31868 = 31868 = 31868 = 31868 }
44+
// lldbr-check:(generic_tuple_style_enum::Regular<u16, u32, u64>::Case1) case1 = { __0 = 0 __1 = 31868 __2 = 31868 __3 = 31868 __4 = 31868 }
4545

4646
// lldb-command:print case2
4747
// lldbr-check:(generic_tuple_style_enum::Regular<i16, i32, i64>::Case2) case2 = Regular<i16, i32, i64>::Case2 { Case1: 0, Case2: 286331153, Case3: 286331153 }
@@ -50,7 +50,7 @@
5050
// lldbr-check:(generic_tuple_style_enum::Regular<i16, i32, i64>::Case3) case3 = Regular<i16, i32, i64>::Case3 { Case1: 0, Case2: 6438275382588823897 }
5151

5252
// lldb-command:print univariant
53-
// lldbr-check:(generic_tuple_style_enum::Univariant<i64>) univariant = { TheOnlyCase = { = -1 } }
53+
// lldbr-check:(generic_tuple_style_enum::Univariant<i64>) univariant = Univariant<i64> { TheOnlyCase: Univariant<i64>::TheOnlyCase(-1) }
5454

5555
#![feature(omit_gdb_pretty_printer_section)]
5656
#![omit_gdb_pretty_printer_section]

src/test/debuginfo/method-on-generic-struct.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// min-lldb-version: 310
11+
// Some versions of the non-rust-enabled LLDB print the wrong generic
12+
// parameter type names in this test.
13+
// rust-lldb
1214

1315
// compile-flags:-g
1416

0 commit comments

Comments
 (0)