From 24a728a8eb4832568509eb757c2374934a76cb98 Mon Sep 17 00:00:00 2001 From: MaulingMonkey Date: Wed, 24 Jun 2020 23:28:00 -0700 Subject: debuginfo: Define int/float types in terms of MSVC-recognized types. PDB debug information doesn't appear to be emitted for basic types. By defining u32 as a typedef for unsigned __int32 when targeting MSVC, we allow CDB and other debuggers to recognize "u32" as a type/expression. This in turn unblocks rust-lang#70052 "Update hashbrown to 0.8.0" by allowing $T1 ..= $T3 to resolve, which would otherwise fail to resolve when builtin types fail to parse. --- src/librustc_codegen_llvm/debuginfo/metadata.rs | 72 ++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) (limited to 'src/librustc_codegen_llvm/debuginfo') diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 8a957a729fb..ac8f28e1609 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; @@ -824,14 +825,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), @@ -848,7 +895,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( -- cgit 1.4.1-3-g733a5