about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-07-11 08:53:13 -0700
committerGitHub <noreply@github.com>2020-07-11 08:53:13 -0700
commit084ac77cf29e786df7251392bed0b6e6c7ea8786 (patch)
tree15255db5e83787345ba5062ead32274a4786c51e
parent90f1d724c8d9b364b4b0c81817484afa04c73009 (diff)
parent24a728a8eb4832568509eb757c2374934a76cb98 (diff)
downloadrust-084ac77cf29e786df7251392bed0b6e6c7ea8786.tar.gz
rust-084ac77cf29e786df7251392bed0b6e6c7ea8786.zip
Rollup merge of #73715 - MaulingMonkey:pr-natvis-tuples, r=Amanieu
debuginfo:  Mangle tuples to be natvis friendly, typedef basic types

These changes are meant to unblock rust-lang/rust#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, ...>`)
-rw-r--r--src/etc/natvis/intrinsic.natvis124
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs72
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs10
-rw-r--r--src/librustc_codegen_ssa/debuginfo/type_names.rs14
-rw-r--r--src/rustllvm/RustWrapper.cpp8
-rw-r--r--src/test/debuginfo/simple-tuple.rs42
-rw-r--r--src/test/debuginfo/tuple-in-tuple.rs67
7 files changed, 334 insertions, 3 deletions
diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis
index 1611d8660ef..874550da8b0 100644
--- a/src/etc/natvis/intrinsic.natvis
+++ b/src/etc/natvis/intrinsic.natvis
@@ -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>
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index dab85b8fb86..f2e042cf86a 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -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;
@@ -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),
@@ -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(
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 7beb4fc8974..64f5e103f0b 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -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,
diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs
index a64489c04c8..20d440433cb 100644
--- a/src/librustc_codegen_ssa/debuginfo/type_names.rs
+++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs
@@ -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(", ");
@@ -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 {
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp
index 063b6acc604..c92cf65f98a 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -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,
diff --git a/src/test/debuginfo/simple-tuple.rs b/src/test/debuginfo/simple-tuple.rs
index c2db5218e68..b7fcfeef090 100644
--- a/src/test/debuginfo/simple-tuple.rs
+++ b/src/test/debuginfo/simple-tuple.rs
@@ -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)]
diff --git a/src/test/debuginfo/tuple-in-tuple.rs b/src/test/debuginfo/tuple-in-tuple.rs
index e0f940ca7a1..0447d8e9dde 100644
--- a/src/test/debuginfo/tuple-in-tuple.rs
+++ b/src/test/debuginfo/tuple-in-tuple.rs
@@ -59,6 +59,73 @@
 // lldbg-check:[...]$6 = { 0 = { 0 = 21 1 = 22 } 1 = 23 }
 // lldbr-check:(((i32, i16), i32)) padding_at_end2 = { 0 = { 0 = 21 1 = 22 } 1 = 23 }
 
+
+// === CDB TESTS ==================================================================================
+
+// cdb-command: g
+
+// cdb-command:dx no_padding1,d
+// cdb-check:no_padding1,d [...]: ((0, 1), 2, 3) [Type: tuple<tuple<u32, u32>, u32, u32>]
+// cdb-check:[...][0]              : (0, 1) [Type: tuple<u32, u32>]
+// cdb-check:[...][1]              : 2 [Type: [...]]
+// cdb-check:[...][2]              : 3 [Type: [...]]
+// cdb-command:dx no_padding1.__0,d
+// cdb-check:no_padding1.__0,d [...]: (0, 1) [Type: tuple<u32, u32>]
+// cdb-check:[...][0]              : 0 [Type: [...]]
+// cdb-check:[...][1]              : 1 [Type: [...]]
+// cdb-command:dx no_padding2,d
+// cdb-check:no_padding2,d [...]: (4, (5, 6), 7) [Type: tuple<u32, tuple<u32, u32>, u32>]
+// cdb-check:[...][0]              : 4 [Type: [...]]
+// cdb-check:[...][1]              : (5, 6) [Type: tuple<u32, u32>]
+// cdb-check:[...][2]              : 7 [Type: [...]]
+// cdb-command:dx no_padding2.__1,d
+// cdb-check:no_padding2.__1,d [...]: (5, 6) [Type: tuple<u32, u32>]
+// cdb-check:[...][0]              : 5 [Type: [...]]
+// cdb-check:[...][1]              : 6 [Type: [...]]
+// cdb-command:dx no_padding3,d
+// cdb-check:no_padding3,d [...]: (8, 9, (10, 11)) [Type: tuple<u32, u32, tuple<u32, u32>>]
+// cdb-check:[...][0]              : 8 [Type: [...]]
+// cdb-check:[...][1]              : 9 [Type: [...]]
+// cdb-check:[...][2]              : (10, 11) [Type: tuple<u32, u32>]
+// cdb-command:dx no_padding3.__2,d
+// cdb-check:no_padding3.__2,d [...]: (10, 11) [Type: tuple<u32, u32>]
+// cdb-check:[...][0]              : 10 [Type: [...]]
+// cdb-check:[...][1]              : 11 [Type: [...]]
+
+// cdb-command:dx internal_padding1,d
+// cdb-check:internal_padding1,d [...]: (12, (13, 14)) [Type: tuple<i16, tuple<i32, i32>>]
+// cdb-check:[...][0]              : 12 [Type: [...]]
+// cdb-check:[...][1]              : (13, 14) [Type: tuple<i32, i32>]
+// cdb-command:dx internal_padding1.__1,d
+// cdb-check:internal_padding1.__1,d [...]: (13, 14) [Type: tuple<i32, i32>]
+// cdb-check:[...][0]              : 13 [Type: [...]]
+// cdb-check:[...][1]              : 14 [Type: [...]]
+// cdb-command:dx internal_padding2,d
+// cdb-check:internal_padding2,d [...]: (15, (16, 17)) [Type: tuple<i16, tuple<i16, i32>>]
+// cdb-check:[...][0]              : 15 [Type: [...]]
+// cdb-check:[...][1]              : (16, 17) [Type: tuple<i16, i32>]
+// cdb-command:dx internal_padding2.__1,d
+// cdb-check:internal_padding2.__1,d [...]: (16, 17) [Type: tuple<i16, i32>]
+// cdb-check:[...][0]              : 16 [Type: [...]]
+// cdb-check:[...][1]              : 17 [Type: [...]]
+
+// cdb-command:dx padding_at_end1,d
+// cdb-check:padding_at_end1,d [...]: (18, (19, 20)) [Type: tuple<i32, tuple<i32, i16>>]
+// cdb-check:[...][0]              : 18 [Type: [...]]
+// cdb-check:[...][1]              : (19, 20) [Type: tuple<i32, i16>]
+// cdb-command:dx padding_at_end1.__1,d
+// cdb-check:padding_at_end1.__1,d [...][Type: tuple<i32, i16>]
+// cdb-check:[...][0]              : 19 [Type: [...]]
+// cdb-check:[...][1]              : 20 [Type: [...]]
+// cdb-command:dx padding_at_end2,d
+// cdb-check:padding_at_end2,d [...]: ((21, 22), 23) [Type: tuple<tuple<i32, i16>, i32>]
+// cdb-check:[...][0]              : (21, 22) [Type: tuple<i32, i16>]
+// cdb-check:[...][1]              : 23 [Type: [...]]
+// cdb-command:dx padding_at_end2.__0,d
+// cdb-check:padding_at_end2.__0,d [...]: (21, 22) [Type: tuple<i32, i16>]
+// cdb-check:[...][0]              : 21 [Type: [...]]
+// cdb-check:[...][1]              : 22 [Type: [...]]
+
 #![allow(unused_variables)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]