Auto merge of #133990 - Walnut356:static_const, r=workingjubilee
[Debuginfo] Force enum `DISCR_*` to `static const u64` to allow for inspection via LLDB see [here](https://rust-lang.zulipchat.com/#narrow/channel/317568-t-compiler.2Fwg-debugging/topic/Revamping.20Debuginfo/near/486614878) for more info. This change mainly helps `*-msvc` debugged with LLDB. Currently, LLDB cannot inspect `static` struct fields, so the intended visualization for enums is only borderline functional, and niche enums with ranges of discriminant cannot be determined at all . LLDB *can* inspect `static const` values (though for whatever reason, non-enum/non-u64 consts don't work). This change adds the `LLVMRustDIBuilderCreateQualifiedType` to the rust FFI layer to wrap the discr type with a `const` modifier, as well as forcing all generated integer enum `DISCR_*` values to be u64's. Those values will only ever be used by debugger visualizers anyway, so it shouldn't be a huge deal, but I left a fixme comment for it just in case.. The `tag` also still properly reflects the discriminant type, so no information is lost.
This commit is contained in:
commit
3dc3c524f7
4 changed files with 50 additions and 17 deletions
|
@ -73,6 +73,9 @@ const DW_ATE_unsigned: c_uint = 0x07;
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
const DW_ATE_UTF: c_uint = 0x10;
|
const DW_ATE_UTF: c_uint = 0x10;
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
const DW_TAG_const_type: c_uint = 0x26;
|
||||||
|
|
||||||
pub(super) const UNKNOWN_LINE_NUMBER: c_uint = 0;
|
pub(super) const UNKNOWN_LINE_NUMBER: c_uint = 0;
|
||||||
pub(super) const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
|
pub(super) const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ use crate::common::{AsCCharPtr, CodegenCx};
|
||||||
use crate::debuginfo::metadata::enums::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::{
|
||||||
DINodeCreationResult, NO_GENERICS, NO_SCOPE_METADATA, SmallVec, UNKNOWN_LINE_NUMBER,
|
DINodeCreationResult, DW_TAG_const_type, NO_GENERICS, NO_SCOPE_METADATA, SmallVec,
|
||||||
build_field_di_node, file_metadata, file_metadata_from_def_id, size_and_align_of, type_di_node,
|
UNKNOWN_LINE_NUMBER, build_field_di_node, file_metadata, file_metadata_from_def_id,
|
||||||
unknown_file_metadata, visibility_di_flags,
|
size_and_align_of, type_di_node, unknown_file_metadata, visibility_di_flags,
|
||||||
};
|
};
|
||||||
use crate::debuginfo::utils::DIB;
|
use crate::debuginfo::utils::DIB;
|
||||||
use crate::llvm::debuginfo::{DIFile, DIFlags, DIType};
|
use crate::llvm::debuginfo::{DIFile, DIFlags, DIType};
|
||||||
|
@ -566,22 +566,39 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
|
||||||
None,
|
None,
|
||||||
));
|
));
|
||||||
|
|
||||||
let build_assoc_const =
|
let build_assoc_const = |name: &str,
|
||||||
|name: &str, type_di_node: &'ll DIType, value: u64, align: Align| unsafe {
|
type_di_node_: &'ll DIType,
|
||||||
llvm::LLVMRustDIBuilderCreateStaticMemberType(
|
value: u64,
|
||||||
DIB(cx),
|
align: Align| unsafe {
|
||||||
wrapper_struct_type_di_node,
|
// FIXME: Currently we force all DISCR_* values to be u64's as LLDB seems to have
|
||||||
name.as_c_char_ptr(),
|
// problems inspecting other value types. Since DISCR_* is typically only going to be
|
||||||
name.len(),
|
// directly inspected via the debugger visualizer - which compares it to the `tag` value
|
||||||
unknown_file_metadata(cx),
|
// (whose type is not modified at all) it shouldn't cause any real problems.
|
||||||
UNKNOWN_LINE_NUMBER,
|
let (t_di, align) = if name == ASSOC_CONST_DISCR_NAME {
|
||||||
type_di_node,
|
(type_di_node_, align.bits() as u32)
|
||||||
DIFlags::FlagZero,
|
} else {
|
||||||
Some(cx.const_u64(value)),
|
let ty_u64 = Ty::new_uint(cx.tcx, ty::UintTy::U64);
|
||||||
align.bits() as u32,
|
(type_di_node(cx, ty_u64), Align::EIGHT.bits() as u32)
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// must wrap type in a `const` modifier for LLDB to be able to inspect the value of the member
|
||||||
|
let field_type =
|
||||||
|
llvm::LLVMRustDIBuilderCreateQualifiedType(DIB(cx), DW_TAG_const_type, t_di);
|
||||||
|
|
||||||
|
llvm::LLVMRustDIBuilderCreateStaticMemberType(
|
||||||
|
DIB(cx),
|
||||||
|
wrapper_struct_type_di_node,
|
||||||
|
name.as_c_char_ptr(),
|
||||||
|
name.len(),
|
||||||
|
unknown_file_metadata(cx),
|
||||||
|
UNKNOWN_LINE_NUMBER,
|
||||||
|
field_type,
|
||||||
|
DIFlags::FlagZero,
|
||||||
|
Some(cx.const_u64(value)),
|
||||||
|
align,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
// We also always have an associated constant for the discriminant value
|
// We also always have an associated constant for the discriminant value
|
||||||
// of the variant.
|
// of the variant.
|
||||||
fields.push(build_assoc_const(
|
fields.push(build_assoc_const(
|
||||||
|
|
|
@ -2008,6 +2008,12 @@ unsafe extern "C" {
|
||||||
AlignInBits: u32,
|
AlignInBits: u32,
|
||||||
) -> &'a DIDerivedType;
|
) -> &'a DIDerivedType;
|
||||||
|
|
||||||
|
pub fn LLVMRustDIBuilderCreateQualifiedType<'a>(
|
||||||
|
Builder: &DIBuilder<'a>,
|
||||||
|
Tag: c_uint,
|
||||||
|
Type: &'a DIType,
|
||||||
|
) -> &'a DIDerivedType;
|
||||||
|
|
||||||
pub fn LLVMRustDIBuilderCreateLexicalBlock<'a>(
|
pub fn LLVMRustDIBuilderCreateLexicalBlock<'a>(
|
||||||
Builder: &DIBuilder<'a>,
|
Builder: &DIBuilder<'a>,
|
||||||
Scope: &'a DIScope,
|
Scope: &'a DIScope,
|
||||||
|
|
|
@ -1217,6 +1217,13 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticMemberType(
|
||||||
unwrap<llvm::ConstantInt>(val), llvm::dwarf::DW_TAG_member, AlignInBits));
|
unwrap<llvm::ConstantInt>(val), llvm::dwarf::DW_TAG_member, AlignInBits));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" LLVMMetadataRef
|
||||||
|
LLVMRustDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag,
|
||||||
|
LLVMMetadataRef Type) {
|
||||||
|
return wrap(
|
||||||
|
unwrap(Builder)->createQualifiedType(Tag, unwrapDI<DIType>(Type)));
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" LLVMMetadataRef
|
extern "C" LLVMMetadataRef
|
||||||
LLVMRustDIBuilderCreateLexicalBlock(LLVMRustDIBuilderRef Builder,
|
LLVMRustDIBuilderCreateLexicalBlock(LLVMRustDIBuilderRef Builder,
|
||||||
LLVMMetadataRef Scope, LLVMMetadataRef File,
|
LLVMMetadataRef Scope, LLVMMetadataRef File,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue