diff --git a/src/etc/natvis/intrinsic.natvis b/src/etc/natvis/intrinsic.natvis
new file mode 100644
index 0000000000000..1611d8660ef65
--- /dev/null
+++ b/src/etc/natvis/intrinsic.natvis
@@ -0,0 +1,24 @@
+
+
+
+ {data_ptr,[length]s8}
+ data_ptr,[length]s8
+
+ - length
+
+ length
+ data_ptr
+
+
+
+
+ {{ length={length} }}
+
+ - length
+
+ length
+ data_ptr
+
+
+
+
diff --git a/src/etc/natvis/liballoc.natvis b/src/etc/natvis/liballoc.natvis
index 1f6d17748ab00..e3d99e34b3579 100644
--- a/src/etc/natvis/liballoc.natvis
+++ b/src/etc/natvis/liballoc.natvis
@@ -42,8 +42,8 @@
- {*(char**)this,[vec.len]}
- *(char**)this,[vec.len]
+ {*(char**)this,[vec.len]s8}
+ *(char**)this,[vec.len]s8
- vec.len
- vec.buf.cap
diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs
index 0b15886083a4e..d3f2d5923a3bc 100644
--- a/src/librustc_trans/back/linker.rs
+++ b/src/librustc_trans/back/linker.rs
@@ -475,6 +475,27 @@ impl<'a> Linker for MsvcLinker<'a> {
// This will cause the Microsoft linker to generate a PDB file
// from the CodeView line tables in the object files.
self.cmd.arg("/DEBUG");
+
+ // This will cause the Microsoft linker to embed .natvis info into the the PDB file
+ let sysroot = self.sess.sysroot();
+ let natvis_dir_path = sysroot.join("lib\\rustlib\\etc");
+ if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
+ for entry in natvis_dir {
+ match entry {
+ Ok(entry) => {
+ let path = entry.path();
+ if path.extension() == Some("natvis".as_ref()) {
+ let mut arg = OsString::from("/NATVIS:");
+ arg.push(path);
+ self.cmd.arg(arg);
+ }
+ },
+ Err(err) => {
+ self.sess.warn(&format!("error enumerating natvis directory: {}", err));
+ },
+ }
+ }
+ }
}
// Currently the compiler doesn't use `dllexport` (an LLVM attribute) to
diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs
index bfca4fec706ed..6e36073107b56 100644
--- a/src/librustc_trans/debuginfo/type_names.rs
+++ b/src/librustc_trans/debuginfo/type_names.rs
@@ -36,6 +36,10 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
t: Ty<'tcx>,
qualified: bool,
output: &mut String) {
+ // When targeting MSVC, emit C++ style type names for compatability with
+ // .natvis visualizers (and perhaps other existing native debuggers?)
+ let cpp_like_names = cx.sess().target.target.options.is_like_msvc;
+
match t.sty {
ty::TyBool => output.push_str("bool"),
ty::TyChar => output.push_str("char"),
@@ -61,21 +65,33 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
output.push(')');
},
ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => {
- output.push('*');
+ if !cpp_like_names {
+ output.push('*');
+ }
match mutbl {
hir::MutImmutable => output.push_str("const "),
hir::MutMutable => output.push_str("mut "),
}
push_debuginfo_type_name(cx, inner_type, true, output);
+
+ if cpp_like_names {
+ output.push('*');
+ }
},
ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => {
- output.push('&');
+ if !cpp_like_names {
+ output.push('&');
+ }
if mutbl == hir::MutMutable {
output.push_str("mut ");
}
push_debuginfo_type_name(cx, inner_type, true, output);
+
+ if cpp_like_names {
+ output.push('*');
+ }
},
ty::TyArray(inner_type, len) => {
output.push('[');
@@ -84,9 +100,19 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
output.push(']');
},
ty::TySlice(inner_type) => {
- output.push('[');
+ if cpp_like_names {
+ output.push_str("slice<");
+ } else {
+ output.push('[');
+ }
+
push_debuginfo_type_name(cx, inner_type, true, output);
- output.push(']');
+
+ if cpp_like_names {
+ output.push('>');
+ } else {
+ output.push(']');
+ }
},
ty::TyDynamic(ref trait_data, ..) => {
if let Some(principal) = trait_data.principal() {