Skip to content

Commit 9cd3bef

Browse files
committed
Auto merge of #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 #9224
2 parents 7139e1c + fb204cb commit 9cd3bef

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::path_to_c_string;
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
@@ -1587,9 +1587,10 @@ extern "C" {
15871587
LineNo: c_uint)
15881588
-> &'a DINameSpace;
15891589

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

15941595

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

src/rustllvm/RustWrapper.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -832,11 +832,13 @@ LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder,
832832
}
833833

834834
extern "C" void
835-
LLVMRustDICompositeTypeSetTypeArray(LLVMRustDIBuilderRef Builder,
836-
LLVMMetadataRef CompositeTy,
837-
LLVMMetadataRef TyArray) {
835+
LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
836+
LLVMMetadataRef CompositeTy,
837+
LLVMMetadataRef Elements,
838+
LLVMMetadataRef Params) {
838839
DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
839-
Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(TyArray)));
840+
Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
841+
DINodeArray(unwrap<MDTuple>(Params)));
840842
}
841843

842844
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)