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
This commit is contained in:
commit
9cd3bef4cf
9 changed files with 115 additions and 18 deletions
|
@ -22,7 +22,7 @@ use abi;
|
|||
use value::Value;
|
||||
|
||||
use llvm;
|
||||
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
|
||||
use llvm::debuginfo::{DIArray, DIType, DIFile, DIScope, DIDescriptor,
|
||||
DICompositeType, DILexicalBlock, DIFlags};
|
||||
use llvm_util;
|
||||
|
||||
|
@ -35,12 +35,14 @@ use rustc_data_structures::fingerprint::Fingerprint;
|
|||
use rustc::ty::Instance;
|
||||
use common::CodegenCx;
|
||||
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
|
||||
use rustc::ty::layout::{self, Align, HasDataLayout, Integer, IntegerExt, LayoutOf,
|
||||
use rustc::ty::layout::{self, Align, Integer, IntegerExt, LayoutOf,
|
||||
PrimitiveExt, Size, TyLayout};
|
||||
use rustc::ty::subst::UnpackedKind;
|
||||
use rustc::session::config;
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_fs_util::path_to_c_string;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_target::abi::HasDataLayout;
|
||||
|
||||
use libc::{c_uint, c_longlong};
|
||||
use std::ffi::CString;
|
||||
|
@ -273,6 +275,7 @@ impl RecursiveTypeDescription<'ll, 'tcx> {
|
|||
|
||||
// ... and attach them to the stub to complete it.
|
||||
set_members_of_composite_type(cx,
|
||||
unfinished_type,
|
||||
member_holding_stub,
|
||||
member_descriptions);
|
||||
return MetadataCreationResult::new(metadata_stub, true);
|
||||
|
@ -1214,6 +1217,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
member_description_factory.create_member_descriptions(cx);
|
||||
|
||||
set_members_of_composite_type(cx,
|
||||
self.enum_type,
|
||||
variant_type_metadata,
|
||||
member_descriptions);
|
||||
vec![
|
||||
|
@ -1254,6 +1258,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
.create_member_descriptions(cx);
|
||||
|
||||
set_members_of_composite_type(cx,
|
||||
self.enum_type,
|
||||
variant_type_metadata,
|
||||
member_descriptions);
|
||||
MemberDescription {
|
||||
|
@ -1295,6 +1300,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
member_description_factory.create_member_descriptions(cx);
|
||||
|
||||
set_members_of_composite_type(cx,
|
||||
self.enum_type,
|
||||
variant_type_metadata,
|
||||
variant_member_descriptions);
|
||||
|
||||
|
@ -1354,6 +1360,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||
.create_member_descriptions(cx);
|
||||
|
||||
set_members_of_composite_type(cx,
|
||||
self.enum_type,
|
||||
variant_type_metadata,
|
||||
member_descriptions);
|
||||
|
||||
|
@ -1765,13 +1772,15 @@ fn composite_type_metadata(
|
|||
containing_scope);
|
||||
// ... and immediately create and add the member descriptions.
|
||||
set_members_of_composite_type(cx,
|
||||
composite_type,
|
||||
composite_type_metadata,
|
||||
member_descriptions);
|
||||
|
||||
composite_type_metadata
|
||||
}
|
||||
|
||||
fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>,
|
||||
fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>,
|
||||
composite_type: Ty<'tcx>,
|
||||
composite_type_metadata: &'ll DICompositeType,
|
||||
member_descriptions: Vec<MemberDescription<'ll>>) {
|
||||
// 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, '_>,
|
|||
})
|
||||
.collect();
|
||||
|
||||
let type_params = compute_type_parameters(cx, composite_type);
|
||||
unsafe {
|
||||
let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
|
||||
llvm::LLVMRustDICompositeTypeSetTypeArray(
|
||||
DIB(cx), composite_type_metadata, type_array);
|
||||
llvm::LLVMRustDICompositeTypeReplaceArrays(
|
||||
DIB(cx), composite_type_metadata, Some(type_array), type_params);
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the type parameters for a type, if any, for the given
|
||||
// metadata.
|
||||
fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> Option<&'ll DIArray> {
|
||||
if let ty::Adt(def, substs) = ty.sty {
|
||||
if !substs.types().next().is_none() {
|
||||
let generics = cx.tcx.generics_of(def.did);
|
||||
let names = get_parameter_names(cx, generics);
|
||||
let template_params: Vec<_> = substs.iter().zip(names).filter_map(|(kind, name)| {
|
||||
if let UnpackedKind::Type(ty) = kind.unpack() {
|
||||
let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
|
||||
let actual_type_metadata =
|
||||
type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
|
||||
let name = SmallCStr::new(&name.as_str());
|
||||
Some(unsafe {
|
||||
|
||||
Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
|
||||
DIB(cx),
|
||||
None,
|
||||
name.as_ptr(),
|
||||
actual_type_metadata,
|
||||
unknown_file_metadata(cx),
|
||||
0,
|
||||
0,
|
||||
))
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).collect();
|
||||
|
||||
return Some(create_DIArray(DIB(cx), &template_params[..]));
|
||||
}
|
||||
}
|
||||
return Some(create_DIArray(DIB(cx), &[]));
|
||||
|
||||
fn get_parameter_names(cx: &CodegenCx,
|
||||
generics: &ty::Generics)
|
||||
-> Vec<InternedString> {
|
||||
let mut names = generics.parent.map_or(vec![], |def_id| {
|
||||
get_parameter_names(cx, cx.tcx.generics_of(def_id))
|
||||
});
|
||||
names.extend(generics.params.iter().map(|param| param.name));
|
||||
names
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1587,9 +1587,10 @@ extern "C" {
|
|||
LineNo: c_uint)
|
||||
-> &'a DINameSpace;
|
||||
|
||||
pub fn LLVMRustDICompositeTypeSetTypeArray(Builder: &DIBuilder<'a>,
|
||||
CompositeType: &'a DIType,
|
||||
TypeArray: &'a DIArray);
|
||||
pub fn LLVMRustDICompositeTypeReplaceArrays(Builder: &DIBuilder<'a>,
|
||||
CompositeType: &'a DIType,
|
||||
Elements: Option<&'a DIArray>,
|
||||
Params: Option<&'a DIArray>);
|
||||
|
||||
|
||||
pub fn LLVMRustDIBuilderCreateDebugLocation(Context: &'a Context,
|
||||
|
|
|
@ -832,11 +832,13 @@ LLVMRustDIBuilderCreateNameSpace(LLVMRustDIBuilderRef Builder,
|
|||
}
|
||||
|
||||
extern "C" void
|
||||
LLVMRustDICompositeTypeSetTypeArray(LLVMRustDIBuilderRef Builder,
|
||||
LLVMMetadataRef CompositeTy,
|
||||
LLVMMetadataRef TyArray) {
|
||||
LLVMRustDICompositeTypeReplaceArrays(LLVMRustDIBuilderRef Builder,
|
||||
LLVMMetadataRef CompositeTy,
|
||||
LLVMMetadataRef Elements,
|
||||
LLVMMetadataRef Params) {
|
||||
DICompositeType *Tmp = unwrapDI<DICompositeType>(CompositeTy);
|
||||
Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(TyArray)));
|
||||
Builder->replaceArrays(Tmp, DINodeArray(unwrap<MDTuple>(Elements)),
|
||||
DINodeArray(unwrap<MDTuple>(Params)));
|
||||
}
|
||||
|
||||
extern "C" LLVMValueRef
|
||||
|
|
28
src/test/codegen/generic-debug.rs
Normal file
28
src/test/codegen/generic-debug.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-tidy-linelength
|
||||
// ignore-windows
|
||||
|
||||
// compile-flags: -g -C no-prepopulate-passes
|
||||
|
||||
// CHECK-LABEL: @main
|
||||
// CHECK: {{.*}}DICompositeType{{.*}}tag: DW_TAG_structure_type,{{.*}}name: "Generic<i32>",{{.*}}
|
||||
// CHECK: {{.*}}DITemplateTypeParameter{{.*}}name: "Type",{{.*}}
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(unused_assignments)]
|
||||
|
||||
pub struct Generic<Type>(Type);
|
||||
|
||||
fn main () {
|
||||
let generic = Generic(10);
|
||||
}
|
|
@ -8,7 +8,9 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// min-lldb-version: 310
|
||||
// Some versions of the non-rust-enabled LLDB print the wrong generic
|
||||
// parameter type names in this test.
|
||||
// rust-lldb
|
||||
|
||||
// compile-flags:-g
|
||||
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
// ignore-tidy-linelength
|
||||
|
||||
// compile-flags:-g
|
||||
// min-lldb-version: 310
|
||||
|
||||
// Some versions of the non-rust-enabled LLDB print the wrong generic
|
||||
// parameter type names in this test.
|
||||
// rust-lldb
|
||||
|
||||
// === GDB TESTS ===================================================================================
|
||||
|
||||
|
|
|
@ -9,7 +9,10 @@
|
|||
// except according to those terms.
|
||||
|
||||
// ignore-tidy-linelength
|
||||
// min-lldb-version: 310
|
||||
|
||||
// Some versions of the non-rust-enabled LLDB print the wrong generic
|
||||
// parameter type names in this test.
|
||||
// rust-lldb
|
||||
|
||||
// compile-flags:-g
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
// lldb-command:run
|
||||
|
||||
// lldb-command:print case1
|
||||
// lldbr-check:(generic_tuple_style_enum::Regular<u16, u32, u64>::Case1) case1 = { = 0 = 31868 = 31868 = 31868 = 31868 }
|
||||
// lldbr-check:(generic_tuple_style_enum::Regular<u16, u32, u64>::Case1) case1 = { __0 = 0 __1 = 31868 __2 = 31868 __3 = 31868 __4 = 31868 }
|
||||
|
||||
// lldb-command:print case2
|
||||
// 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 @@
|
|||
// lldbr-check:(generic_tuple_style_enum::Regular<i16, i32, i64>::Case3) case3 = Regular<i16, i32, i64>::Case3 { Case1: 0, Case2: 6438275382588823897 }
|
||||
|
||||
// lldb-command:print univariant
|
||||
// lldbr-check:(generic_tuple_style_enum::Univariant<i64>) univariant = { TheOnlyCase = { = -1 } }
|
||||
// lldbr-check:(generic_tuple_style_enum::Univariant<i64>) univariant = Univariant<i64> { TheOnlyCase: Univariant<i64>::TheOnlyCase(-1) }
|
||||
|
||||
#![feature(omit_gdb_pretty_printer_section)]
|
||||
#![omit_gdb_pretty_printer_section]
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// min-lldb-version: 310
|
||||
// Some versions of the non-rust-enabled LLDB print the wrong generic
|
||||
// parameter type names in this test.
|
||||
// rust-lldb
|
||||
|
||||
// compile-flags:-g
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue