Auto merge of #128037 - beetrees:repr128-c-style-use-natvis, r=michaelwoerister
Use the `enum2$` Natvis visualiser for repr128 C-style enums Use the preexisting `enum2$` Natvis visualiser to allow PDB debuggers to display fieldless `#[repr(u128)]]`/`#[repr(i128)]]` enums correctly. Tracking issue: #56071 try-job: x86_64-msvc
This commit is contained in:
commit
026e9ed3f0
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name;
|
use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name;
|
||||||
use rustc_codegen_ssa::debuginfo::wants_c_like_enum_debuginfo;
|
use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo};
|
||||||
use rustc_codegen_ssa::traits::ConstMethods;
|
use rustc_codegen_ssa::traits::ConstMethods;
|
||||||
use rustc_index::IndexVec;
|
use rustc_index::IndexVec;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
@ -12,7 +12,7 @@
|
|||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
|
|
||||||
use crate::common::CodegenCx;
|
use crate::common::CodegenCx;
|
||||||
use crate::debuginfo::metadata::enums::{tag_base_type, DiscrResult};
|
use crate::debuginfo::metadata::enums::DiscrResult;
|
||||||
use crate::debuginfo::metadata::type_map::{self, Stub, UniqueTypeId};
|
use crate::debuginfo::metadata::type_map::{self, Stub, UniqueTypeId};
|
||||||
use crate::debuginfo::metadata::{
|
use crate::debuginfo::metadata::{
|
||||||
build_field_di_node, file_metadata, size_and_align_of, type_di_node, unknown_file_metadata,
|
build_field_di_node, file_metadata, size_and_align_of, type_di_node, unknown_file_metadata,
|
||||||
@ -190,7 +190,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
|
|||||||
let enum_type_and_layout = cx.layout_of(enum_type);
|
let enum_type_and_layout = cx.layout_of(enum_type);
|
||||||
let enum_type_name = compute_debuginfo_type_name(cx.tcx, enum_type, false);
|
let enum_type_name = compute_debuginfo_type_name(cx.tcx, enum_type, false);
|
||||||
|
|
||||||
assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
|
assert!(!wants_c_like_enum_debuginfo(cx.tcx, enum_type_and_layout));
|
||||||
|
|
||||||
type_map::build_type_with_children(
|
type_map::build_type_with_children(
|
||||||
cx,
|
cx,
|
||||||
@ -265,7 +265,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
|
|||||||
let coroutine_type_and_layout = cx.layout_of(coroutine_type);
|
let coroutine_type_and_layout = cx.layout_of(coroutine_type);
|
||||||
let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
|
let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
|
||||||
|
|
||||||
assert!(!wants_c_like_enum_debuginfo(coroutine_type_and_layout));
|
assert!(!wants_c_like_enum_debuginfo(cx.tcx, coroutine_type_and_layout));
|
||||||
|
|
||||||
type_map::build_type_with_children(
|
type_map::build_type_with_children(
|
||||||
cx,
|
cx,
|
||||||
@ -381,7 +381,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
|
|||||||
tag_field: usize,
|
tag_field: usize,
|
||||||
untagged_variant_index: Option<VariantIdx>,
|
untagged_variant_index: Option<VariantIdx>,
|
||||||
) -> SmallVec<&'ll DIType> {
|
) -> SmallVec<&'ll DIType> {
|
||||||
let tag_base_type = super::tag_base_type(cx, enum_type_and_layout);
|
let tag_base_type = tag_base_type(cx.tcx, enum_type_and_layout);
|
||||||
|
|
||||||
let variant_names_type_di_node = build_variant_names_type_di_node(
|
let variant_names_type_di_node = build_variant_names_type_di_node(
|
||||||
cx,
|
cx,
|
||||||
@ -676,7 +676,7 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>(
|
|||||||
let variant_range = coroutine_args.variant_range(coroutine_def_id, cx.tcx);
|
let variant_range = coroutine_args.variant_range(coroutine_def_id, cx.tcx);
|
||||||
let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
|
let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
|
||||||
|
|
||||||
let tag_base_type = tag_base_type(cx, coroutine_type_and_layout);
|
let tag_base_type = tag_base_type(cx.tcx, coroutine_type_and_layout);
|
||||||
|
|
||||||
let variant_names_type_di_node = build_variant_names_type_di_node(
|
let variant_names_type_di_node = build_variant_names_type_di_node(
|
||||||
cx,
|
cx,
|
||||||
@ -803,7 +803,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
|
cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
|
||||||
cx.size_and_align_of(super::tag_base_type(cx, enum_type_and_layout))
|
cx.size_and_align_of(self::tag_base_type(cx.tcx, enum_type_and_layout))
|
||||||
);
|
);
|
||||||
|
|
||||||
// ... and a field for the tag. If the tag is 128 bits wide, this will actually
|
// ... and a field for the tag. If the tag is 128 bits wide, this will actually
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use rustc_codegen_ssa::debuginfo::type_names::{compute_debuginfo_type_name, cpp_like_debuginfo};
|
use rustc_codegen_ssa::debuginfo::type_names::{compute_debuginfo_type_name, cpp_like_debuginfo};
|
||||||
use rustc_codegen_ssa::debuginfo::wants_c_like_enum_debuginfo;
|
use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo};
|
||||||
use rustc_hir::def::CtorKind;
|
use rustc_hir::def::CtorKind;
|
||||||
use rustc_index::IndexSlice;
|
use rustc_index::IndexSlice;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::mir::CoroutineLayout;
|
use rustc_middle::mir::CoroutineLayout;
|
||||||
use rustc_middle::ty::layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout};
|
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||||
use rustc_middle::ty::{self, AdtDef, CoroutineArgs, CoroutineArgsExt, Ty, VariantDef};
|
use rustc_middle::ty::{self, AdtDef, CoroutineArgs, CoroutineArgsExt, Ty, VariantDef};
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
use rustc_target::abi::{
|
use rustc_target::abi::{FieldIdx, TagEncoding, VariantIdx, Variants};
|
||||||
FieldIdx, HasDataLayout, Integer, Primitive, TagEncoding, VariantIdx, Variants,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::type_map::{DINodeCreationResult, UniqueTypeId};
|
use super::type_map::{DINodeCreationResult, UniqueTypeId};
|
||||||
use super::{size_and_align_of, SmallVec};
|
use super::{size_and_align_of, SmallVec};
|
||||||
@ -39,7 +37,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
|
|||||||
|
|
||||||
let enum_type_and_layout = cx.layout_of(enum_type);
|
let enum_type_and_layout = cx.layout_of(enum_type);
|
||||||
|
|
||||||
if wants_c_like_enum_debuginfo(enum_type_and_layout) {
|
if wants_c_like_enum_debuginfo(cx.tcx, enum_type_and_layout) {
|
||||||
return build_c_style_enum_di_node(cx, enum_adt_def, enum_type_and_layout);
|
return build_c_style_enum_di_node(cx, enum_adt_def, enum_type_and_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +72,7 @@ fn build_c_style_enum_di_node<'ll, 'tcx>(
|
|||||||
di_node: build_enumeration_type_di_node(
|
di_node: build_enumeration_type_di_node(
|
||||||
cx,
|
cx,
|
||||||
&compute_debuginfo_type_name(cx.tcx, enum_type_and_layout.ty, false),
|
&compute_debuginfo_type_name(cx.tcx, enum_type_and_layout.ty, false),
|
||||||
tag_base_type(cx, enum_type_and_layout),
|
tag_base_type(cx.tcx, enum_type_and_layout),
|
||||||
enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
|
enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| {
|
||||||
let name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
|
let name = Cow::from(enum_adt_def.variant(variant_index).name.as_str());
|
||||||
(name, discr.val)
|
(name, discr.val)
|
||||||
@ -85,48 +83,6 @@ fn build_c_style_enum_di_node<'ll, 'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the type with which we want to describe the tag of the given enum or coroutine.
|
|
||||||
fn tag_base_type<'ll, 'tcx>(
|
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
|
||||||
enum_type_and_layout: TyAndLayout<'tcx>,
|
|
||||||
) -> Ty<'tcx> {
|
|
||||||
assert!(match enum_type_and_layout.ty.kind() {
|
|
||||||
ty::Coroutine(..) => true,
|
|
||||||
ty::Adt(adt_def, _) => adt_def.is_enum(),
|
|
||||||
_ => false,
|
|
||||||
});
|
|
||||||
|
|
||||||
match enum_type_and_layout.layout.variants() {
|
|
||||||
// A single-variant enum has no discriminant.
|
|
||||||
Variants::Single { .. } => {
|
|
||||||
bug!("tag_base_type() called for enum without tag: {:?}", enum_type_and_layout)
|
|
||||||
}
|
|
||||||
|
|
||||||
Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, tag, .. } => {
|
|
||||||
// Niche tags are always normalized to unsized integers of the correct size.
|
|
||||||
match tag.primitive() {
|
|
||||||
Primitive::Int(t, _) => t,
|
|
||||||
Primitive::Float(f) => Integer::from_size(f.size()).unwrap(),
|
|
||||||
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
|
|
||||||
Primitive::Pointer(_) => {
|
|
||||||
// If the niche is the NULL value of a reference, then `discr_enum_ty` will be
|
|
||||||
// a RawPtr. CodeView doesn't know what to do with enums whose base type is a
|
|
||||||
// pointer so we fix this up to just be `usize`.
|
|
||||||
// DWARF might be able to deal with this but with an integer type we are on
|
|
||||||
// the safe side there too.
|
|
||||||
cx.data_layout().ptr_sized_integer()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.to_ty(cx.tcx, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
Variants::Multiple { tag_encoding: TagEncoding::Direct, tag, .. } => {
|
|
||||||
// Direct tags preserve the sign.
|
|
||||||
tag.primitive().to_ty(cx.tcx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build a DW_TAG_enumeration_type debuginfo node, with the given base type and variants.
|
/// Build a DW_TAG_enumeration_type debuginfo node, with the given base type and variants.
|
||||||
/// This is a helper function and does not register anything in the type map by itself.
|
/// This is a helper function and does not register anything in the type map by itself.
|
||||||
///
|
///
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name;
|
use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name;
|
||||||
use rustc_codegen_ssa::debuginfo::wants_c_like_enum_debuginfo;
|
use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo};
|
||||||
use rustc_codegen_ssa::traits::ConstMethods;
|
use rustc_codegen_ssa::traits::ConstMethods;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||||
@ -11,7 +11,6 @@
|
|||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
|
|
||||||
use crate::common::CodegenCx;
|
use crate::common::CodegenCx;
|
||||||
use crate::debuginfo::metadata::enums::tag_base_type;
|
|
||||||
use crate::debuginfo::metadata::type_map::{self, Stub, StubInfo, UniqueTypeId};
|
use crate::debuginfo::metadata::type_map::{self, Stub, StubInfo, UniqueTypeId};
|
||||||
use crate::debuginfo::metadata::{
|
use crate::debuginfo::metadata::{
|
||||||
file_metadata, size_and_align_of, type_di_node, unknown_file_metadata, visibility_di_flags,
|
file_metadata, size_and_align_of, type_di_node, unknown_file_metadata, visibility_di_flags,
|
||||||
@ -54,7 +53,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
|
|||||||
|
|
||||||
let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
|
let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
|
||||||
|
|
||||||
assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
|
assert!(!wants_c_like_enum_debuginfo(cx.tcx, enum_type_and_layout));
|
||||||
|
|
||||||
type_map::build_type_with_children(
|
type_map::build_type_with_children(
|
||||||
cx,
|
cx,
|
||||||
@ -131,7 +130,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
|
|||||||
let containing_scope = get_namespace_for_item(cx, coroutine_def_id);
|
let containing_scope = get_namespace_for_item(cx, coroutine_def_id);
|
||||||
let coroutine_type_and_layout = cx.layout_of(coroutine_type);
|
let coroutine_type_and_layout = cx.layout_of(coroutine_type);
|
||||||
|
|
||||||
assert!(!wants_c_like_enum_debuginfo(coroutine_type_and_layout));
|
assert!(!wants_c_like_enum_debuginfo(cx.tcx, coroutine_type_and_layout));
|
||||||
|
|
||||||
let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
|
let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
|
||||||
|
|
||||||
@ -321,7 +320,7 @@ fn build_discr_member_di_node<'ll, 'tcx>(
|
|||||||
&Variants::Single { .. } => None,
|
&Variants::Single { .. } => None,
|
||||||
|
|
||||||
&Variants::Multiple { tag_field, .. } => {
|
&Variants::Multiple { tag_field, .. } => {
|
||||||
let tag_base_type = tag_base_type(cx, enum_or_coroutine_type_and_layout);
|
let tag_base_type = tag_base_type(cx.tcx, enum_or_coroutine_type_and_layout);
|
||||||
let (size, align) = cx.size_and_align_of(tag_base_type);
|
let (size, align) = cx.size_and_align_of(tag_base_type);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use rustc_middle::ty::layout::TyAndLayout;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::{self};
|
use rustc_middle::ty::layout::{IntegerExt, PrimitiveExt, TyAndLayout};
|
||||||
use rustc_target::abi::Size;
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
|
use rustc_target::abi::{Integer, Primitive, Size, TagEncoding, Variants};
|
||||||
|
|
||||||
// FIXME(eddyb) find a place for this (or a way to replace it).
|
// FIXME(eddyb) find a place for this (or a way to replace it).
|
||||||
pub mod type_names;
|
pub mod type_names;
|
||||||
@ -11,13 +12,25 @@
|
|||||||
/// NOTE: This is somewhat inconsistent right now: For empty enums and enums with a single
|
/// NOTE: This is somewhat inconsistent right now: For empty enums and enums with a single
|
||||||
/// fieldless variant, we generate DW_TAG_struct_type, although a
|
/// fieldless variant, we generate DW_TAG_struct_type, although a
|
||||||
/// DW_TAG_enumeration_type would be a better fit.
|
/// DW_TAG_enumeration_type would be a better fit.
|
||||||
pub fn wants_c_like_enum_debuginfo(enum_type_and_layout: TyAndLayout<'_>) -> bool {
|
pub fn wants_c_like_enum_debuginfo<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
enum_type_and_layout: TyAndLayout<'tcx>,
|
||||||
|
) -> bool {
|
||||||
match enum_type_and_layout.ty.kind() {
|
match enum_type_and_layout.ty.kind() {
|
||||||
ty::Adt(adt_def, _) => {
|
ty::Adt(adt_def, _) => {
|
||||||
if !adt_def.is_enum() {
|
if !adt_def.is_enum() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if type_names::cpp_like_debuginfo(tcx)
|
||||||
|
&& tag_base_type_opt(tcx, enum_type_and_layout)
|
||||||
|
.map(|ty| ty.primitive_size(tcx).bits())
|
||||||
|
== Some(128)
|
||||||
|
{
|
||||||
|
// C++-like debuginfo never uses the C-like representation for 128-bit enums.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
match adt_def.variants().len() {
|
match adt_def.variants().len() {
|
||||||
0 => false,
|
0 => false,
|
||||||
1 => {
|
1 => {
|
||||||
@ -33,3 +46,51 @@ pub fn wants_c_like_enum_debuginfo(enum_type_and_layout: TyAndLayout<'_>) -> boo
|
|||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extract the type with which we want to describe the tag of the given enum or coroutine.
|
||||||
|
pub fn tag_base_type<'tcx>(tcx: TyCtxt<'tcx>, enum_type_and_layout: TyAndLayout<'tcx>) -> Ty<'tcx> {
|
||||||
|
tag_base_type_opt(tcx, enum_type_and_layout).unwrap_or_else(|| {
|
||||||
|
bug!("tag_base_type() called for enum without tag: {:?}", enum_type_and_layout)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tag_base_type_opt<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
enum_type_and_layout: TyAndLayout<'tcx>,
|
||||||
|
) -> Option<Ty<'tcx>> {
|
||||||
|
assert!(match enum_type_and_layout.ty.kind() {
|
||||||
|
ty::Coroutine(..) => true,
|
||||||
|
ty::Adt(adt_def, _) => adt_def.is_enum(),
|
||||||
|
_ => false,
|
||||||
|
});
|
||||||
|
|
||||||
|
match enum_type_and_layout.layout.variants() {
|
||||||
|
// A single-variant enum has no discriminant.
|
||||||
|
Variants::Single { .. } => None,
|
||||||
|
|
||||||
|
Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, tag, .. } => {
|
||||||
|
// Niche tags are always normalized to unsized integers of the correct size.
|
||||||
|
Some(
|
||||||
|
match tag.primitive() {
|
||||||
|
Primitive::Int(t, _) => t,
|
||||||
|
Primitive::Float(f) => Integer::from_size(f.size()).unwrap(),
|
||||||
|
// FIXME(erikdesjardins): handle non-default addrspace ptr sizes
|
||||||
|
Primitive::Pointer(_) => {
|
||||||
|
// If the niche is the NULL value of a reference, then `discr_enum_ty` will be
|
||||||
|
// a RawPtr. CodeView doesn't know what to do with enums whose base type is a
|
||||||
|
// pointer so we fix this up to just be `usize`.
|
||||||
|
// DWARF might be able to deal with this but with an integer type we are on
|
||||||
|
// the safe side there too.
|
||||||
|
tcx.data_layout.ptr_sized_integer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.to_ty(tcx, false),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Variants::Multiple { tag_encoding: TagEncoding::Direct, tag, .. } => {
|
||||||
|
// Direct tags preserve the sign.
|
||||||
|
Some(tag.primitive().to_ty(tcx))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -85,7 +85,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() {
|
let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() {
|
||||||
match tcx.layout_of(ParamEnv::reveal_all().and(t)) {
|
match tcx.layout_of(ParamEnv::reveal_all().and(t)) {
|
||||||
Ok(layout) => {
|
Ok(layout) => {
|
||||||
if !wants_c_like_enum_debuginfo(layout) {
|
if !wants_c_like_enum_debuginfo(tcx, layout) {
|
||||||
Some(layout)
|
Some(layout)
|
||||||
} else {
|
} else {
|
||||||
// This is a C-like enum so we don't want to use the fallback encoding
|
// This is a C-like enum so we don't want to use the fallback encoding
|
||||||
@ -106,6 +106,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
|
|
||||||
if let Some(ty_and_layout) = layout_for_cpp_like_fallback {
|
if let Some(ty_and_layout) = layout_for_cpp_like_fallback {
|
||||||
msvc_enum_fallback(
|
msvc_enum_fallback(
|
||||||
|
tcx,
|
||||||
ty_and_layout,
|
ty_and_layout,
|
||||||
&|output, visited| {
|
&|output, visited| {
|
||||||
push_item_name(tcx, def.did(), true, output);
|
push_item_name(tcx, def.did(), true, output);
|
||||||
@ -421,6 +422,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
if cpp_like_debuginfo && t.is_coroutine() {
|
if cpp_like_debuginfo && t.is_coroutine() {
|
||||||
let ty_and_layout = tcx.layout_of(ParamEnv::reveal_all().and(t)).unwrap();
|
let ty_and_layout = tcx.layout_of(ParamEnv::reveal_all().and(t)).unwrap();
|
||||||
msvc_enum_fallback(
|
msvc_enum_fallback(
|
||||||
|
tcx,
|
||||||
ty_and_layout,
|
ty_and_layout,
|
||||||
&|output, visited| {
|
&|output, visited| {
|
||||||
push_closure_or_coroutine_name(tcx, def_id, args, true, output, visited);
|
push_closure_or_coroutine_name(tcx, def_id, args, true, output, visited);
|
||||||
@ -455,12 +457,13 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
// debugger. For more information, look in
|
// debugger. For more information, look in
|
||||||
// rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs.
|
// rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs.
|
||||||
fn msvc_enum_fallback<'tcx>(
|
fn msvc_enum_fallback<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
ty_and_layout: TyAndLayout<'tcx>,
|
ty_and_layout: TyAndLayout<'tcx>,
|
||||||
push_inner: &dyn Fn(/*output*/ &mut String, /*visited*/ &mut FxHashSet<Ty<'tcx>>),
|
push_inner: &dyn Fn(/*output*/ &mut String, /*visited*/ &mut FxHashSet<Ty<'tcx>>),
|
||||||
output: &mut String,
|
output: &mut String,
|
||||||
visited: &mut FxHashSet<Ty<'tcx>>,
|
visited: &mut FxHashSet<Ty<'tcx>>,
|
||||||
) {
|
) {
|
||||||
assert!(!wants_c_like_enum_debuginfo(ty_and_layout));
|
assert!(!wants_c_like_enum_debuginfo(tcx, ty_and_layout));
|
||||||
output.push_str("enum2$<");
|
output.push_str("enum2$<");
|
||||||
push_inner(output, visited);
|
push_inner(output, visited);
|
||||||
push_close_angle_bracket(true, output);
|
push_close_angle_bracket(true, output);
|
||||||
|
@ -206,6 +206,30 @@
|
|||||||
// cdb-command: dx -r2 arbitrary_discr2,d
|
// cdb-command: dx -r2 arbitrary_discr2,d
|
||||||
// cdb-check: arbitrary_discr2,d : Def [Type: enum2$<msvc_pretty_enums::ArbitraryDiscr>]
|
// cdb-check: arbitrary_discr2,d : Def [Type: enum2$<msvc_pretty_enums::ArbitraryDiscr>]
|
||||||
// cdb-check: [+0x[...]] __0 : 5678 [Type: unsigned int]
|
// cdb-check: [+0x[...]] __0 : 5678 [Type: unsigned int]
|
||||||
|
//
|
||||||
|
// cdb-command: dx c_style_u128_a
|
||||||
|
// cdb-check: c_style_u128_a : A [Type: enum2$<msvc_pretty_enums::CStyleU128>]
|
||||||
|
//
|
||||||
|
// cdb-command: dx c_style_u128_b
|
||||||
|
// cdb-check: c_style_u128_b : B [Type: enum2$<msvc_pretty_enums::CStyleU128>]
|
||||||
|
//
|
||||||
|
// cdb-command: dx c_style_u128_c
|
||||||
|
// cdb-check: c_style_u128_c : C [Type: enum2$<msvc_pretty_enums::CStyleU128>]
|
||||||
|
//
|
||||||
|
// cdb-command: dx c_style_u128_d
|
||||||
|
// cdb-check: c_style_u128_d : D [Type: enum2$<msvc_pretty_enums::CStyleU128>]
|
||||||
|
//
|
||||||
|
// cdb-command: dx c_style_i128_a
|
||||||
|
// cdb-check: c_style_i128_a : A [Type: enum2$<msvc_pretty_enums::CStyleI128>]
|
||||||
|
//
|
||||||
|
// cdb-command: dx c_style_i128_b
|
||||||
|
// cdb-check: c_style_i128_b : B [Type: enum2$<msvc_pretty_enums::CStyleI128>]
|
||||||
|
//
|
||||||
|
// cdb-command: dx c_style_i128_c
|
||||||
|
// cdb-check: c_style_i128_c : C [Type: enum2$<msvc_pretty_enums::CStyleI128>]
|
||||||
|
//
|
||||||
|
// cdb-command: dx c_style_i128_d
|
||||||
|
// cdb-check: c_style_i128_d : D [Type: enum2$<msvc_pretty_enums::CStyleI128>]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(repr128)]
|
#![feature(repr128)]
|
||||||
#![feature(arbitrary_enum_discriminant)]
|
#![feature(arbitrary_enum_discriminant)]
|
||||||
@ -270,6 +294,22 @@ enum ArbitraryDiscr {
|
|||||||
Def(u32) = 5000_000,
|
Def(u32) = 5000_000,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(u128)]
|
||||||
|
pub enum CStyleU128 {
|
||||||
|
A = 0_u128,
|
||||||
|
B = 1_u128,
|
||||||
|
C = u64::MAX as u128 + 1,
|
||||||
|
D = u128::MAX,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(i128)]
|
||||||
|
pub enum CStyleI128 {
|
||||||
|
A = 0_i128,
|
||||||
|
B = -1_i128,
|
||||||
|
C = i128::MIN,
|
||||||
|
D = i128::MAX,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let a = Some(CStyleEnum::Low);
|
let a = Some(CStyleEnum::Low);
|
||||||
let b = Option::<CStyleEnum>::None;
|
let b = Option::<CStyleEnum>::None;
|
||||||
@ -313,6 +353,16 @@ fn main() {
|
|||||||
let arbitrary_discr1 = ArbitraryDiscr::Abc(1234);
|
let arbitrary_discr1 = ArbitraryDiscr::Abc(1234);
|
||||||
let arbitrary_discr2 = ArbitraryDiscr::Def(5678);
|
let arbitrary_discr2 = ArbitraryDiscr::Def(5678);
|
||||||
|
|
||||||
|
let c_style_u128_a = CStyleU128::A;
|
||||||
|
let c_style_u128_b = CStyleU128::B;
|
||||||
|
let c_style_u128_c = CStyleU128::C;
|
||||||
|
let c_style_u128_d = CStyleU128::D;
|
||||||
|
|
||||||
|
let c_style_i128_a = CStyleI128::A;
|
||||||
|
let c_style_i128_b = CStyleI128::B;
|
||||||
|
let c_style_i128_c = CStyleI128::C;
|
||||||
|
let c_style_i128_d = CStyleI128::D;
|
||||||
|
|
||||||
zzz(); // #break
|
zzz(); // #break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user