Skip to content

Commit 3dc3c52

Browse files
committed
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.
2 parents 1891c28 + a1191e3 commit 3dc3c52

File tree

4 files changed

+50
-17
lines changed

4 files changed

+50
-17
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+3
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ const DW_ATE_unsigned: c_uint = 0x07;
7373
#[allow(non_upper_case_globals)]
7474
const DW_ATE_UTF: c_uint = 0x10;
7575

76+
#[allow(non_upper_case_globals)]
77+
const DW_TAG_const_type: c_uint = 0x26;
78+
7679
pub(super) const UNKNOWN_LINE_NUMBER: c_uint = 0;
7780
pub(super) const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
7881

compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs

+34-17
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ use crate::common::{AsCCharPtr, CodegenCx};
1515
use crate::debuginfo::metadata::enums::DiscrResult;
1616
use crate::debuginfo::metadata::type_map::{self, Stub, UniqueTypeId};
1717
use crate::debuginfo::metadata::{
18-
DINodeCreationResult, NO_GENERICS, NO_SCOPE_METADATA, SmallVec, UNKNOWN_LINE_NUMBER,
19-
build_field_di_node, file_metadata, file_metadata_from_def_id, size_and_align_of, type_di_node,
20-
unknown_file_metadata, visibility_di_flags,
18+
DINodeCreationResult, DW_TAG_const_type, NO_GENERICS, NO_SCOPE_METADATA, SmallVec,
19+
UNKNOWN_LINE_NUMBER, build_field_di_node, file_metadata, file_metadata_from_def_id,
20+
size_and_align_of, type_di_node, unknown_file_metadata, visibility_di_flags,
2121
};
2222
use crate::debuginfo::utils::DIB;
2323
use crate::llvm::debuginfo::{DIFile, DIFlags, DIType};
@@ -566,22 +566,39 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
566566
None,
567567
));
568568

569-
let build_assoc_const =
570-
|name: &str, type_di_node: &'ll DIType, value: u64, align: Align| unsafe {
571-
llvm::LLVMRustDIBuilderCreateStaticMemberType(
572-
DIB(cx),
573-
wrapper_struct_type_di_node,
574-
name.as_c_char_ptr(),
575-
name.len(),
576-
unknown_file_metadata(cx),
577-
UNKNOWN_LINE_NUMBER,
578-
type_di_node,
579-
DIFlags::FlagZero,
580-
Some(cx.const_u64(value)),
581-
align.bits() as u32,
582-
)
569+
let build_assoc_const = |name: &str,
570+
type_di_node_: &'ll DIType,
571+
value: u64,
572+
align: Align| unsafe {
573+
// FIXME: Currently we force all DISCR_* values to be u64's as LLDB seems to have
574+
// problems inspecting other value types. Since DISCR_* is typically only going to be
575+
// directly inspected via the debugger visualizer - which compares it to the `tag` value
576+
// (whose type is not modified at all) it shouldn't cause any real problems.
577+
let (t_di, align) = if name == ASSOC_CONST_DISCR_NAME {
578+
(type_di_node_, align.bits() as u32)
579+
} else {
580+
let ty_u64 = Ty::new_uint(cx.tcx, ty::UintTy::U64);
581+
(type_di_node(cx, ty_u64), Align::EIGHT.bits() as u32)
583582
};
584583

584+
// must wrap type in a `const` modifier for LLDB to be able to inspect the value of the member
585+
let field_type =
586+
llvm::LLVMRustDIBuilderCreateQualifiedType(DIB(cx), DW_TAG_const_type, t_di);
587+
588+
llvm::LLVMRustDIBuilderCreateStaticMemberType(
589+
DIB(cx),
590+
wrapper_struct_type_di_node,
591+
name.as_c_char_ptr(),
592+
name.len(),
593+
unknown_file_metadata(cx),
594+
UNKNOWN_LINE_NUMBER,
595+
field_type,
596+
DIFlags::FlagZero,
597+
Some(cx.const_u64(value)),
598+
align,
599+
)
600+
};
601+
585602
// We also always have an associated constant for the discriminant value
586603
// of the variant.
587604
fields.push(build_assoc_const(

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2008,6 +2008,12 @@ unsafe extern "C" {
20082008
AlignInBits: u32,
20092009
) -> &'a DIDerivedType;
20102010

2011+
pub fn LLVMRustDIBuilderCreateQualifiedType<'a>(
2012+
Builder: &DIBuilder<'a>,
2013+
Tag: c_uint,
2014+
Type: &'a DIType,
2015+
) -> &'a DIDerivedType;
2016+
20112017
pub fn LLVMRustDIBuilderCreateLexicalBlock<'a>(
20122018
Builder: &DIBuilder<'a>,
20132019
Scope: &'a DIScope,

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,13 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticMemberType(
12171217
unwrap<llvm::ConstantInt>(val), llvm::dwarf::DW_TAG_member, AlignInBits));
12181218
}
12191219

1220+
extern "C" LLVMMetadataRef
1221+
LLVMRustDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag,
1222+
LLVMMetadataRef Type) {
1223+
return wrap(
1224+
unwrap(Builder)->createQualifiedType(Tag, unwrapDI<DIType>(Type)));
1225+
}
1226+
12201227
extern "C" LLVMMetadataRef
12211228
LLVMRustDIBuilderCreateLexicalBlock(LLVMRustDIBuilderRef Builder,
12221229
LLVMMetadataRef Scope, LLVMMetadataRef File,

0 commit comments

Comments
 (0)