Skip to content

Commit 24a728a

Browse files
committed
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 #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.
1 parent f8eb81b commit 24a728a

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

src/librustc_codegen_llvm/debuginfo/metadata.rs

+71-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::llvm::debuginfo::{
1919
use crate::value::Value;
2020

2121
use log::debug;
22+
use rustc_ast::ast;
2223
use rustc_codegen_ssa::traits::*;
2324
use rustc_data_structures::const_cstr;
2425
use rustc_data_structures::fingerprint::Fingerprint;
@@ -824,14 +825,60 @@ fn file_metadata_raw(
824825
}
825826
}
826827

828+
trait MsvcBasicName {
829+
fn msvc_basic_name(self) -> &'static str;
830+
}
831+
832+
impl MsvcBasicName for ast::IntTy {
833+
fn msvc_basic_name(self) -> &'static str {
834+
match self {
835+
ast::IntTy::Isize => "ptrdiff_t",
836+
ast::IntTy::I8 => "__int8",
837+
ast::IntTy::I16 => "__int16",
838+
ast::IntTy::I32 => "__int32",
839+
ast::IntTy::I64 => "__int64",
840+
ast::IntTy::I128 => "__int128",
841+
}
842+
}
843+
}
844+
845+
impl MsvcBasicName for ast::UintTy {
846+
fn msvc_basic_name(self) -> &'static str {
847+
match self {
848+
ast::UintTy::Usize => "size_t",
849+
ast::UintTy::U8 => "unsigned __int8",
850+
ast::UintTy::U16 => "unsigned __int16",
851+
ast::UintTy::U32 => "unsigned __int32",
852+
ast::UintTy::U64 => "unsigned __int64",
853+
ast::UintTy::U128 => "unsigned __int128",
854+
}
855+
}
856+
}
857+
858+
impl MsvcBasicName for ast::FloatTy {
859+
fn msvc_basic_name(self) -> &'static str {
860+
match self {
861+
ast::FloatTy::F32 => "float",
862+
ast::FloatTy::F64 => "double",
863+
}
864+
}
865+
}
866+
827867
fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
828868
debug!("basic_type_metadata: {:?}", t);
829869

870+
// When targeting MSVC, emit MSVC style type names for compatibility with
871+
// .natvis visualizers (and perhaps other existing native debuggers?)
872+
let msvc_like_names = cx.tcx.sess.target.target.options.is_like_msvc;
873+
830874
let (name, encoding) = match t.kind {
831875
ty::Never => ("!", DW_ATE_unsigned),
832876
ty::Tuple(ref elements) if elements.is_empty() => ("()", DW_ATE_unsigned),
833877
ty::Bool => ("bool", DW_ATE_boolean),
834878
ty::Char => ("char", DW_ATE_unsigned_char),
879+
ty::Int(int_ty) if msvc_like_names => (int_ty.msvc_basic_name(), DW_ATE_signed),
880+
ty::Uint(uint_ty) if msvc_like_names => (uint_ty.msvc_basic_name(), DW_ATE_unsigned),
881+
ty::Float(float_ty) if msvc_like_names => (float_ty.msvc_basic_name(), DW_ATE_float),
835882
ty::Int(int_ty) => (int_ty.name_str(), DW_ATE_signed),
836883
ty::Uint(uint_ty) => (uint_ty.name_str(), DW_ATE_unsigned),
837884
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 {
848895
)
849896
};
850897

851-
ty_metadata
898+
if !msvc_like_names {
899+
return ty_metadata;
900+
}
901+
902+
let typedef_name = match t.kind {
903+
ty::Int(int_ty) => int_ty.name_str(),
904+
ty::Uint(uint_ty) => uint_ty.name_str(),
905+
ty::Float(float_ty) => float_ty.name_str(),
906+
_ => return ty_metadata,
907+
};
908+
909+
let typedef_metadata = unsafe {
910+
llvm::LLVMRustDIBuilderCreateTypedef(
911+
DIB(cx),
912+
ty_metadata,
913+
typedef_name.as_ptr().cast(),
914+
typedef_name.len(),
915+
unknown_file_metadata(cx),
916+
0,
917+
None,
918+
)
919+
};
920+
921+
typedef_metadata
852922
}
853923

854924
fn foreign_type_metadata(

src/librustc_codegen_llvm/llvm/ffi.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1699,6 +1699,16 @@ extern "C" {
16991699
Encoding: c_uint,
17001700
) -> &'a DIBasicType;
17011701

1702+
pub fn LLVMRustDIBuilderCreateTypedef(
1703+
Builder: &DIBuilder<'a>,
1704+
Type: &'a DIBasicType,
1705+
Name: *const c_char,
1706+
NameLen: size_t,
1707+
File: &'a DIFile,
1708+
LineNo: c_uint,
1709+
Scope: Option<&'a DIScope>,
1710+
) -> &'a DIDerivedType;
1711+
17021712
pub fn LLVMRustDIBuilderCreatePointerType(
17031713
Builder: &DIBuilder<'a>,
17041714
PointeeTy: &'a DIType,

src/rustllvm/RustWrapper.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,14 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
759759
return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
760760
}
761761

762+
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateTypedef(
763+
LLVMRustDIBuilderRef Builder, LLVMMetadataRef Type, const char *Name, size_t NameLen,
764+
LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Scope) {
765+
return wrap(Builder->createTypedef(
766+
unwrap<DIType>(Type), StringRef(Name, NameLen), unwrap<DIFile>(File),
767+
LineNo, unwrap<DIScope>(Scope)));
768+
}
769+
762770
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
763771
LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
764772
uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,

0 commit comments

Comments
 (0)