Skip to content

Commit

Permalink
Rollup merge of #73715 - MaulingMonkey:pr-natvis-tuples, r=Amanieu
Browse files Browse the repository at this point in the history
debuginfo:  Mangle tuples to be natvis friendly, typedef basic types

These changes are meant to unblock #70052 "Update hashbrown to 0.8.0" by allowing the use of `tuple<u64, u64>` as a .natvis expression in MSVC style debuggers (MSVC, WinDbg, CDB, etc.)

* f8eb81b does the actual mangling of `(u64, u64)` -> `tuple<u64, 64>`
* 24a728a allows `u64` to resolve (fixing `$T1` / `$T2` when used to visualize `HashMap<u64, u64, ...>`)
  • Loading branch information
Manishearth committed Jul 11, 2020
2 parents 90f1d72 + 24a728a commit 084ac77
Show file tree
Hide file tree
Showing 7 changed files with 334 additions and 3 deletions.
124 changes: 124 additions & 0 deletions src/etc/natvis/intrinsic.natvis
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,128 @@
</ArrayItems>
</Expand>
</Type>
<Type Name="tuple&lt;&gt;">
<DisplayString>()</DisplayString>
</Type>
<Type Name="tuple&lt;*&gt;">
<DisplayString>({__0})</DisplayString>
<Expand>
<Item Name="[0]">__0</Item>
</Expand>
</Type>
<Type Name="tuple&lt;*,*&gt;">
<DisplayString>({__0}, {__1})</DisplayString>
<Expand>
<Item Name="[0]">__0</Item>
<Item Name="[1]">__1</Item>
</Expand>
</Type>
<Type Name="tuple&lt;*,*,*&gt;">
<DisplayString>({__0}, {__1}, {__2})</DisplayString>
<Expand>
<Item Name="[0]">__0</Item>
<Item Name="[1]">__1</Item>
<Item Name="[2]">__2</Item>
</Expand>
</Type>
<Type Name="tuple&lt;*,*,*,*&gt;">
<DisplayString>({__0}, {__1}, {__2}, {__3})</DisplayString>
<Expand>
<Item Name="[0]">__0</Item>
<Item Name="[1]">__1</Item>
<Item Name="[2]">__2</Item>
<Item Name="[3]">__3</Item>
</Expand>
</Type>
<Type Name="tuple&lt;*,*,*,*,*&gt;">
<DisplayString>({__0}, {__1}, {__2}, {__3}, {__4})</DisplayString>
<Expand>
<Item Name="[0]">__0</Item>
<Item Name="[1]">__1</Item>
<Item Name="[2]">__2</Item>
<Item Name="[3]">__3</Item>
<Item Name="[4]">__4</Item>
</Expand>
</Type>
<Type Name="tuple&lt;*,*,*,*,*,*&gt;">
<DisplayString>({__0}, {__1}, {__2}, {__3}, {__4}, {__5})</DisplayString>
<Expand>
<Item Name="[0]">__0</Item>
<Item Name="[1]">__1</Item>
<Item Name="[2]">__2</Item>
<Item Name="[3]">__3</Item>
<Item Name="[4]">__4</Item>
<Item Name="[5]">__5</Item>
</Expand>
</Type>
<Type Name="tuple&lt;*,*,*,*,*,*,*&gt;">
<DisplayString>({__0}, {__1}, {__2}, {__3}, {__4}, {__5}, {__6})</DisplayString>
<Expand>
<Item Name="[0]">__0</Item>
<Item Name="[1]">__1</Item>
<Item Name="[2]">__2</Item>
<Item Name="[3]">__3</Item>
<Item Name="[4]">__4</Item>
<Item Name="[5]">__5</Item>
<Item Name="[6]">__6</Item>
</Expand>
</Type>
<Type Name="tuple&lt;*,*,*,*,*,*,*,*&gt;">
<DisplayString>({__0}, {__1}, {__2}, {__3}, {__4}, {__5}, {__6}, {__7})</DisplayString>
<Expand>
<Item Name="[0]">__0</Item>
<Item Name="[1]">__1</Item>
<Item Name="[2]">__2</Item>
<Item Name="[3]">__3</Item>
<Item Name="[4]">__4</Item>
<Item Name="[5]">__5</Item>
<Item Name="[6]">__6</Item>
<Item Name="[7]">__7</Item>
</Expand>
</Type>
<Type Name="tuple&lt;*,*,*,*,*,*,*,*,*&gt;">
<DisplayString>({__0}, {__1}, {__2}, {__3}, {__4}, {__5}, {__6}, {__7}, {__8})</DisplayString>
<Expand>
<Item Name="[0]">__0</Item>
<Item Name="[1]">__1</Item>
<Item Name="[2]">__2</Item>
<Item Name="[3]">__3</Item>
<Item Name="[4]">__4</Item>
<Item Name="[5]">__5</Item>
<Item Name="[6]">__6</Item>
<Item Name="[7]">__7</Item>
<Item Name="[8]">__8</Item>
</Expand>
</Type>
<Type Name="tuple&lt;*,*,*,*,*,*,*,*,*,*&gt;">
<DisplayString>({__0}, {__1}, {__2}, {__3}, {__4}, {__5}, {__6}, {__7}, {__8}, {__9})</DisplayString>
<Expand>
<Item Name="[0]">__0</Item>
<Item Name="[1]">__1</Item>
<Item Name="[2]">__2</Item>
<Item Name="[3]">__3</Item>
<Item Name="[4]">__4</Item>
<Item Name="[5]">__5</Item>
<Item Name="[6]">__6</Item>
<Item Name="[7]">__7</Item>
<Item Name="[8]">__8</Item>
<Item Name="[9]">__9</Item>
</Expand>
</Type>
<Type Name="tuple&lt;*,*,*,*,*,*,*,*,*,*,*&gt;">
<DisplayString>({__0}, {__1}, {__2}, {__3}, {__4}, {__5}, {__6}, {__7}, {__8}, {__9}, ...)</DisplayString>
<Expand>
<Item Name="[0]">__0</Item>
<Item Name="[1]">__1</Item>
<Item Name="[2]">__2</Item>
<Item Name="[3]">__3</Item>
<Item Name="[4]">__4</Item>
<Item Name="[5]">__5</Item>
<Item Name="[6]">__6</Item>
<Item Name="[7]">__7</Item>
<Item Name="[8]">__8</Item>
<Item Name="[9]">__9</Item>
<Synthetic Name="[...]"><DisplayString>...</DisplayString></Synthetic>
</Expand>
</Type>
</AutoVisualizer>
72 changes: 71 additions & 1 deletion src/librustc_codegen_llvm/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::llvm::debuginfo::{
use crate::value::Value;

use log::debug;
use rustc_ast::ast;
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::const_cstr;
use rustc_data_structures::fingerprint::Fingerprint;
Expand Down Expand Up @@ -827,14 +828,60 @@ fn file_metadata_raw(
}
}

trait MsvcBasicName {
fn msvc_basic_name(self) -> &'static str;
}

impl MsvcBasicName for ast::IntTy {
fn msvc_basic_name(self) -> &'static str {
match self {
ast::IntTy::Isize => "ptrdiff_t",
ast::IntTy::I8 => "__int8",
ast::IntTy::I16 => "__int16",
ast::IntTy::I32 => "__int32",
ast::IntTy::I64 => "__int64",
ast::IntTy::I128 => "__int128",
}
}
}

impl MsvcBasicName for ast::UintTy {
fn msvc_basic_name(self) -> &'static str {
match self {
ast::UintTy::Usize => "size_t",
ast::UintTy::U8 => "unsigned __int8",
ast::UintTy::U16 => "unsigned __int16",
ast::UintTy::U32 => "unsigned __int32",
ast::UintTy::U64 => "unsigned __int64",
ast::UintTy::U128 => "unsigned __int128",
}
}
}

impl MsvcBasicName for ast::FloatTy {
fn msvc_basic_name(self) -> &'static str {
match self {
ast::FloatTy::F32 => "float",
ast::FloatTy::F64 => "double",
}
}
}

fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
debug!("basic_type_metadata: {:?}", t);

// When targeting MSVC, emit MSVC style type names for compatibility with
// .natvis visualizers (and perhaps other existing native debuggers?)
let msvc_like_names = cx.tcx.sess.target.target.options.is_like_msvc;

let (name, encoding) = match t.kind {
ty::Never => ("!", DW_ATE_unsigned),
ty::Tuple(ref elements) if elements.is_empty() => ("()", DW_ATE_unsigned),
ty::Bool => ("bool", DW_ATE_boolean),
ty::Char => ("char", DW_ATE_unsigned_char),
ty::Int(int_ty) if msvc_like_names => (int_ty.msvc_basic_name(), DW_ATE_signed),
ty::Uint(uint_ty) if msvc_like_names => (uint_ty.msvc_basic_name(), DW_ATE_unsigned),
ty::Float(float_ty) if msvc_like_names => (float_ty.msvc_basic_name(), DW_ATE_float),
ty::Int(int_ty) => (int_ty.name_str(), DW_ATE_signed),
ty::Uint(uint_ty) => (uint_ty.name_str(), DW_ATE_unsigned),
ty::Float(float_ty) => (float_ty.name_str(), DW_ATE_float),
Expand All @@ -851,7 +898,30 @@ fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
)
};

ty_metadata
if !msvc_like_names {
return ty_metadata;
}

let typedef_name = match t.kind {
ty::Int(int_ty) => int_ty.name_str(),
ty::Uint(uint_ty) => uint_ty.name_str(),
ty::Float(float_ty) => float_ty.name_str(),
_ => return ty_metadata,
};

let typedef_metadata = unsafe {
llvm::LLVMRustDIBuilderCreateTypedef(
DIB(cx),
ty_metadata,
typedef_name.as_ptr().cast(),
typedef_name.len(),
unknown_file_metadata(cx),
0,
None,
)
};

typedef_metadata
}

fn foreign_type_metadata(
Expand Down
10 changes: 10 additions & 0 deletions src/librustc_codegen_llvm/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1703,6 +1703,16 @@ extern "C" {
Encoding: c_uint,
) -> &'a DIBasicType;

pub fn LLVMRustDIBuilderCreateTypedef(
Builder: &DIBuilder<'a>,
Type: &'a DIBasicType,
Name: *const c_char,
NameLen: size_t,
File: &'a DIFile,
LineNo: c_uint,
Scope: Option<&'a DIScope>,
) -> &'a DIDerivedType;

pub fn LLVMRustDIBuilderCreatePointerType(
Builder: &DIBuilder<'a>,
PointeeTy: &'a DIType,
Expand Down
14 changes: 12 additions & 2 deletions src/librustc_codegen_ssa/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ pub fn push_debuginfo_type_name<'tcx>(
push_type_params(tcx, substs, output, visited);
}
ty::Tuple(component_types) => {
output.push('(');
if cpp_like_names {
output.push_str("tuple<");
} else {
output.push('(');
}

for component_type in component_types {
push_debuginfo_type_name(tcx, component_type.expect_ty(), true, output, visited);
output.push_str(", ");
Expand All @@ -56,7 +61,12 @@ pub fn push_debuginfo_type_name<'tcx>(
output.pop();
output.pop();
}
output.push(')');

if cpp_like_names {
output.push('>');
} else {
output.push(')');
}
}
ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl }) => {
if !cpp_like_names {
Expand Down
8 changes: 8 additions & 0 deletions src/rustllvm/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,14 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
}

extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
return wrap(Builder->createTypedef(
unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
LineNo, unwrap<DIScope>(Scope)));
}

extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
Expand Down
42 changes: 42 additions & 0 deletions src/test/debuginfo/simple-tuple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,48 @@
// lldbg-check:[...]$6 = { 0 = 15 1 = 16 }
// lldbr-check:((i32, i16)) paddingAtEnd = { 0 = 15 1 = 16 }


// === CDB TESTS ==================================================================================

// cdb-command: g

// cdb-command:dx noPadding8,d
// cdb-check:noPadding8,d [...]: (-100, 100) [Type: tuple<i8, u8>]
// cdb-check:[...][0] : -100 [Type: [...]]
// cdb-check:[...][1] : 100 [Type: [...]]
// cdb-command:dx noPadding16,d
// cdb-check:noPadding16,d [...]: (0, 1, 2) [Type: tuple<i16, i16, u16>]
// cdb-check:[...][0] : 0 [Type: [...]]
// cdb-check:[...][1] : 1 [Type: [...]]
// cdb-check:[...][2] : 2 [Type: [...]]
// cdb-command:dx noPadding32,d
// cdb-check:noPadding32,d [...]: (3, 4.5[...], 5) [Type: tuple<i32, f32, u32>]
// cdb-check:[...][0] : 3 [Type: [...]]
// cdb-check:[...][1] : 4.5[...] [Type: [...]]
// cdb-check:[...][2] : 5 [Type: [...]]
// cdb-command:dx noPadding64,d
// cdb-check:noPadding64,d [...]: (6, 7.5[...], 8) [Type: tuple<i64, f64, u64>]
// cdb-check:[...][0] : 6 [Type: [...]]
// cdb-check:[...][1] : 7.500000 [Type: [...]]
// cdb-check:[...][2] : 8 [Type: [...]]

// cdb-command:dx internalPadding1,d
// cdb-check:internalPadding1,d [...]: (9, 10) [Type: tuple<i16, i32>]
// cdb-check:[...][0] : 9 [Type: short]
// cdb-check:[...][1] : 10 [Type: int]
// cdb-command:dx internalPadding2,d
// cdb-check:internalPadding2,d [...]: (11, 12, 13, 14) [Type: tuple<i16, i32, u32, u64>]
// cdb-check:[...][0] : 11 [Type: [...]]
// cdb-check:[...][1] : 12 [Type: [...]]
// cdb-check:[...][2] : 13 [Type: [...]]
// cdb-check:[...][3] : 14 [Type: [...]]

// cdb-command:dx paddingAtEnd,d
// cdb-check:paddingAtEnd,d [...]: (15, 16) [Type: tuple<i32, i16>]
// cdb-check:[...][0] : 15 [Type: [...]]
// cdb-check:[...][1] : 16 [Type: [...]]


#![allow(unused_variables)]
#![allow(dead_code)]
#![feature(omit_gdb_pretty_printer_section)]
Expand Down
Loading

0 comments on commit 084ac77

Please sign in to comment.