mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-05 14:37:37 +00:00
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.
This commit is contained in:
parent
f8eb81ba4e
commit
24a728a8eb
@ -19,6 +19,7 @@ use crate::llvm::debuginfo::{
|
|||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
|
|
||||||
use log::debug;
|
use log::debug;
|
||||||
|
use rustc_ast::ast;
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use rustc_data_structures::const_cstr;
|
use rustc_data_structures::const_cstr;
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
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 {
|
fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
|
||||||
debug!("basic_type_metadata: {:?}", t);
|
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 {
|
let (name, encoding) = match t.kind {
|
||||||
ty::Never => ("!", DW_ATE_unsigned),
|
ty::Never => ("!", DW_ATE_unsigned),
|
||||||
ty::Tuple(ref elements) if elements.is_empty() => ("()", DW_ATE_unsigned),
|
ty::Tuple(ref elements) if elements.is_empty() => ("()", DW_ATE_unsigned),
|
||||||
ty::Bool => ("bool", DW_ATE_boolean),
|
ty::Bool => ("bool", DW_ATE_boolean),
|
||||||
ty::Char => ("char", DW_ATE_unsigned_char),
|
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::Int(int_ty) => (int_ty.name_str(), DW_ATE_signed),
|
||||||
ty::Uint(uint_ty) => (uint_ty.name_str(), DW_ATE_unsigned),
|
ty::Uint(uint_ty) => (uint_ty.name_str(), DW_ATE_unsigned),
|
||||||
ty::Float(float_ty) => (float_ty.name_str(), DW_ATE_float),
|
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(
|
fn foreign_type_metadata(
|
||||||
|
@ -1699,6 +1699,16 @@ extern "C" {
|
|||||||
Encoding: c_uint,
|
Encoding: c_uint,
|
||||||
) -> &'a DIBasicType;
|
) -> &'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(
|
pub fn LLVMRustDIBuilderCreatePointerType(
|
||||||
Builder: &DIBuilder<'a>,
|
Builder: &DIBuilder<'a>,
|
||||||
PointeeTy: &'a DIType,
|
PointeeTy: &'a DIType,
|
||||||
|
@ -759,6 +759,14 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
|
|||||||
return wrap(Builder->createBasicType(StringRef(Name, NameLen), SizeInBits, Encoding));
|
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(
|
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreatePointerType(
|
||||||
LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
|
LLVMRustDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
|
||||||
uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
|
uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
|
||||||
|
Loading…
Reference in New Issue
Block a user