Skip to content

Commit

Permalink
Rollup merge of rust-lang#55010 - tromey:Bug-9224-generic-parameters,…
Browse files Browse the repository at this point in the history
… 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
  • Loading branch information
pietroalbini authored Oct 25, 2018
2 parents eed093c + 8a3bb9a commit e75a203
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 11 deletions.
62 changes: 58 additions & 4 deletions src/librustc_codegen_llvm/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,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 rustc_data_structures::stable_hasher::{HashStable, StableHasher};
Expand All @@ -34,6 +34,7 @@ use rustc::ty::Instance;
use common::CodegenCx;
use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
use rustc::ty::layout::{self, Align, LayoutOf, PrimitiveExt, Size, TyLayout};
use rustc::ty::subst::UnpackedKind;
use rustc::session::config;
use rustc::util::nodemap::FxHashMap;
use rustc_fs_util::path2cstr;
Expand Down Expand Up @@ -266,6 +267,7 @@ impl RecursiveTypeDescription<'ll, 'tcx> {

// ... and attach them to the stub to complete it.
set_members_of_composite_type(cx,
unfinished_type,
metadata_stub,
member_descriptions);
return MetadataCreationResult::new(metadata_stub, true);
Expand Down Expand Up @@ -1174,6 +1176,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![
Expand Down Expand Up @@ -1204,6 +1207,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
.create_member_descriptions(cx);

set_members_of_composite_type(cx,
self.enum_type,
variant_type_metadata,
member_descriptions);
MemberDescription {
Expand Down Expand Up @@ -1231,6 +1235,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);

Expand Down Expand Up @@ -1534,13 +1539,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
Expand Down Expand Up @@ -1580,10 +1587,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 None;

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

Expand Down
7 changes: 4 additions & 3 deletions src/librustc_codegen_llvm/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1419,9 +1419,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,
Expand Down
10 changes: 6 additions & 4 deletions src/rustllvm/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -870,11 +870,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
Expand Down
28 changes: 28 additions & 0 deletions src/test/codegen/generic-debug.rs
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit e75a203

Please sign in to comment.