]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
New upstream version 1.71.1+dfsg1
[rustc.git] / compiler / rustc_codegen_llvm / src / debuginfo / metadata.rs
CommitLineData
5e7ed085
FG
1use self::type_map::DINodeCreationResult;
2use self::type_map::Stub;
3use self::type_map::UniqueTypeId;
1a4d82fc 4
0531ce1d 5use super::namespace::mangled_name_of_instance;
c295e0f8 6use super::type_names::{compute_debuginfo_type_name, compute_debuginfo_vtable_name};
dfeec247 7use super::utils::{
ba9703b0 8 create_DIArray, debug_context, get_namespace_for_item, is_node_local_to_unit, DIB,
dfeec247 9};
5e7ed085 10use super::CodegenUnitDebugContext;
d9579d0f 11
60c5eb7d
XL
12use crate::abi;
13use crate::common::CodegenCx;
5e7ed085 14use crate::debuginfo::metadata::type_map::build_type_with_children;
5099ac24
FG
15use crate::debuginfo::utils::fat_pointer_kind;
16use crate::debuginfo::utils::FatPtrKind;
9fa01778 17use crate::llvm;
dfeec247 18use crate::llvm::debuginfo::{
5e7ed085 19 DIDescriptor, DIFile, DIFlags, DILexicalBlock, DIScope, DIType, DebugEmissionKind,
dfeec247 20};
60c5eb7d 21use crate::value::Value;
d9579d0f 22
6a06907d 23use cstr::cstr;
a2a8927a 24use rustc_codegen_ssa::debuginfo::type_names::cpp_like_debuginfo;
5099ac24 25use rustc_codegen_ssa::debuginfo::type_names::VTableNameKind;
dfeec247 26use rustc_codegen_ssa::traits::*;
dfeec247
XL
27use rustc_fs_util::path_to_c_string;
28use rustc_hir::def::CtorKind;
29967ef6 29use rustc_hir::def_id::{DefId, LOCAL_CRATE};
5099ac24 30use rustc_middle::bug;
923072b8 31use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
923072b8
FG
32use rustc_middle::ty::{
33 self, AdtKind, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt, Visibility,
34};
35use rustc_session::config::{self, DebugInfo, Lto};
c295e0f8 36use rustc_span::symbol::Symbol;
923072b8
FG
37use rustc_span::FileName;
38use rustc_span::{self, FileNameDisplayPreference, SourceFile};
39use rustc_symbol_mangling::typeid_for_trait_ref;
5e7ed085
FG
40use rustc_target::abi::{Align, Size};
41use smallvec::smallvec;
1a4d82fc 42
923072b8 43use libc::{c_char, c_longlong, c_uint};
5e7ed085 44use std::borrow::Cow;
b7449926
XL
45use std::fmt::{self, Write};
46use std::hash::{Hash, Hasher};
8faf50e0 47use std::iter;
ff7c6d11 48use std::path::{Path, PathBuf};
dfeec247 49use std::ptr;
1a4d82fc 50
b7449926
XL
51impl PartialEq for llvm::Metadata {
52 fn eq(&self, other: &Self) -> bool {
0731742a 53 ptr::eq(self, other)
b7449926
XL
54 }
55}
56
57impl Eq for llvm::Metadata {}
58
59impl Hash for llvm::Metadata {
60 fn hash<H: Hasher>(&self, hasher: &mut H) {
61 (self as *const Self).hash(hasher);
62 }
63}
64
65impl fmt::Debug for llvm::Metadata {
9fa01778 66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
b7449926
XL
67 (self as *const Self).fmt(f)
68 }
69}
c30ab7b3 70
54a0048b 71// From DWARF 5.
60c5eb7d 72// See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1.
54a0048b 73const DW_LANG_RUST: c_uint = 0x1c;
1a4d82fc
JJ
74#[allow(non_upper_case_globals)]
75const DW_ATE_boolean: c_uint = 0x02;
76#[allow(non_upper_case_globals)]
77const DW_ATE_float: c_uint = 0x04;
78#[allow(non_upper_case_globals)]
79const DW_ATE_signed: c_uint = 0x05;
80#[allow(non_upper_case_globals)]
81const DW_ATE_unsigned: c_uint = 0x07;
82#[allow(non_upper_case_globals)]
5e7ed085 83const DW_ATE_UTF: c_uint = 0x10;
1a4d82fc 84
5e7ed085
FG
85pub(super) const UNKNOWN_LINE_NUMBER: c_uint = 0;
86pub(super) const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
5099ac24 87
5e7ed085
FG
88const NO_SCOPE_METADATA: Option<&DIScope> = None;
89/// A function that returns an empty list of generic parameter debuginfo nodes.
90const NO_GENERICS: for<'ll> fn(&CodegenCx<'ll, '_>) -> SmallVec<&'ll DIType> = |_| SmallVec::new();
d9579d0f 91
5e7ed085
FG
92// SmallVec is used quite a bit in this module, so create a shorthand.
93// The actual number of elements is not so important.
94pub type SmallVec<T> = smallvec::SmallVec<[T; 16]>;
d9579d0f 95
5e7ed085
FG
96mod enums;
97mod type_map;
d9579d0f 98
5e7ed085 99pub(crate) use type_map::TypeMap;
d9579d0f 100
5e7ed085 101/// Returns from the enclosing function if the type debuginfo node with the given
60c5eb7d 102/// unique ID can be found in the type map.
5e7ed085 103macro_rules! return_if_di_node_created_in_meantime {
dfeec247 104 ($cx: expr, $unique_type_id: expr) => {
5e7ed085
FG
105 if let Some(di_node) = debug_context($cx).type_map.di_node_for_unique_id($unique_type_id) {
106 return DINodeCreationResult::new(di_node, true);
b039eaaf 107 }
dfeec247 108 };
1a4d82fc
JJ
109}
110
5e7ed085 111/// Extract size and alignment from a TyAndLayout.
f2b60f7d 112#[inline]
9c376795 113fn size_and_align_of(ty_and_layout: TyAndLayout<'_>) -> (Size, Align) {
5e7ed085
FG
114 (ty_and_layout.size, ty_and_layout.align.abi)
115}
116
5099ac24 117/// Creates debuginfo for a fixed size array (e.g. `[u64; 123]`).
5e7ed085
FG
118/// For slices (that is, "arrays" of unknown size) use [build_slice_type_di_node].
119fn build_fixed_size_array_di_node<'ll, 'tcx>(
b7449926 120 cx: &CodegenCx<'ll, 'tcx>,
5e7ed085 121 unique_type_id: UniqueTypeId<'tcx>,
5099ac24 122 array_type: Ty<'tcx>,
5e7ed085 123) -> DINodeCreationResult<'ll> {
5099ac24 124 let ty::Array(element_type, len) = array_type.kind() else {
5e7ed085 125 bug!("build_fixed_size_array_di_node() called with non-ty::Array type `{:?}`", array_type)
5099ac24
FG
126 };
127
5e7ed085 128 let element_type_di_node = type_di_node(cx, *element_type);
d9579d0f 129
5e7ed085 130 return_if_di_node_created_in_meantime!(cx, unique_type_id);
1a4d82fc 131
5099ac24 132 let (size, align) = cx.size_and_align_of(array_type);
1a4d82fc 133
9ffffee4 134 let upper_bound = len.eval_target_usize(cx.tcx, ty::ParamEnv::reveal_all()) as c_longlong;
1a4d82fc 135
dfeec247
XL
136 let subrange =
137 unsafe { Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)) };
1a4d82fc 138
d9579d0f 139 let subscripts = create_DIArray(DIB(cx), &[subrange]);
5e7ed085 140 let di_node = unsafe {
5bcae85e 141 llvm::LLVMRustDIBuilderCreateArrayType(
d9579d0f 142 DIB(cx),
ff7c6d11 143 size.bits(),
a1dfa0c6 144 align.bits() as u32,
5e7ed085 145 element_type_di_node,
dfeec247
XL
146 subscripts,
147 )
d9579d0f 148 };
1a4d82fc 149
5e7ed085 150 DINodeCreationResult::new(di_node, false)
1a4d82fc
JJ
151}
152
5099ac24
FG
153/// Creates debuginfo for built-in pointer-like things:
154///
155/// - ty::Ref
156/// - ty::RawPtr
157/// - ty::Adt in the case it's Box
158///
159/// At some point we might want to remove the special handling of Box
160/// and treat it the same as other smart pointers (like Rc, Arc, ...).
5e7ed085 161fn build_pointer_or_reference_di_node<'ll, 'tcx>(
b7449926 162 cx: &CodegenCx<'ll, 'tcx>,
5099ac24
FG
163 ptr_type: Ty<'tcx>,
164 pointee_type: Ty<'tcx>,
5e7ed085
FG
165 unique_type_id: UniqueTypeId<'tcx>,
166) -> DINodeCreationResult<'ll> {
167 // The debuginfo generated by this function is only valid if `ptr_type` is really just
168 // a (fat) pointer. Make sure it is not called for e.g. `Box<T, NonZSTAllocator>`.
169 debug_assert_eq!(
170 cx.size_and_align_of(ptr_type),
171 cx.size_and_align_of(cx.tcx.mk_mut_ptr(pointee_type))
172 );
173
174 let pointee_type_di_node = type_di_node(cx, pointee_type);
1a4d82fc 175
5e7ed085 176 return_if_di_node_created_in_meantime!(cx, unique_type_id);
1a4d82fc 177
353b0b11 178 let data_layout = &cx.tcx.data_layout;
5099ac24 179 let ptr_type_debuginfo_name = compute_debuginfo_type_name(cx.tcx, ptr_type, true);
1a4d82fc 180
5e7ed085 181 match fat_pointer_kind(cx, pointee_type) {
5099ac24
FG
182 None => {
183 // This is a thin pointer. Create a regular pointer type and give it the correct name.
184 debug_assert_eq!(
353b0b11 185 (data_layout.pointer_size, data_layout.pointer_align.abi),
5e7ed085
FG
186 cx.size_and_align_of(ptr_type),
187 "ptr_type={}, pointee_type={}",
188 ptr_type,
189 pointee_type,
5099ac24 190 );
1a4d82fc 191
5e7ed085 192 let di_node = unsafe {
5099ac24
FG
193 llvm::LLVMRustDIBuilderCreatePointerType(
194 DIB(cx),
5e7ed085 195 pointee_type_di_node,
353b0b11
FG
196 data_layout.pointer_size.bits(),
197 data_layout.pointer_align.abi.bits() as u32,
5099ac24
FG
198 0, // Ignore DWARF address space.
199 ptr_type_debuginfo_name.as_ptr().cast(),
200 ptr_type_debuginfo_name.len(),
201 )
5e7ed085
FG
202 };
203
204 DINodeCreationResult { di_node, already_stored_in_typemap: false }
5099ac24
FG
205 }
206 Some(fat_pointer_kind) => {
5e7ed085
FG
207 type_map::build_type_with_children(
208 cx,
209 type_map::stub(
210 cx,
211 Stub::Struct,
212 unique_type_id,
213 &ptr_type_debuginfo_name,
214 cx.size_and_align_of(ptr_type),
215 NO_SCOPE_METADATA,
216 DIFlags::FlagZero,
217 ),
218 |cx, owner| {
219 // FIXME: If this fat pointer is a `Box` then we don't want to use its
220 // type layout and instead use the layout of the raw pointer inside
221 // of it.
222 // The proper way to handle this is to not treat Box as a pointer
223 // at all and instead emit regular struct debuginfo for it. We just
224 // need to make sure that we don't break existing debuginfo consumers
225 // by doing that (at least not without a warning period).
226 let layout_type =
227 if ptr_type.is_box() { cx.tcx.mk_mut_ptr(pointee_type) } else { ptr_type };
228
229 let layout = cx.layout_of(layout_type);
230 let addr_field = layout.field(cx, abi::FAT_PTR_ADDR);
231 let extra_field = layout.field(cx, abi::FAT_PTR_EXTRA);
232
233 let (addr_field_name, extra_field_name) = match fat_pointer_kind {
234 FatPtrKind::Dyn => ("pointer", "vtable"),
235 FatPtrKind::Slice => ("data_ptr", "length"),
236 };
5099ac24 237
5e7ed085
FG
238 debug_assert_eq!(abi::FAT_PTR_ADDR, 0);
239 debug_assert_eq!(abi::FAT_PTR_EXTRA, 1);
5099ac24 240
5e7ed085
FG
241 // The data pointer type is a regular, thin pointer, regardless of whether this
242 // is a slice or a trait object.
243 let data_ptr_type_di_node = unsafe {
244 llvm::LLVMRustDIBuilderCreatePointerType(
245 DIB(cx),
246 pointee_type_di_node,
247 addr_field.size.bits(),
248 addr_field.align.abi.bits() as u32,
249 0, // Ignore DWARF address space.
250 std::ptr::null(),
251 0,
252 )
253 };
5099ac24 254
5e7ed085
FG
255 smallvec![
256 build_field_di_node(
257 cx,
258 owner,
259 addr_field_name,
260 (addr_field.size, addr_field.align.abi),
261 layout.fields.offset(abi::FAT_PTR_ADDR),
262 DIFlags::FlagZero,
263 data_ptr_type_di_node,
264 ),
265 build_field_di_node(
266 cx,
267 owner,
268 extra_field_name,
269 (extra_field.size, extra_field.align.abi),
270 layout.fields.offset(abi::FAT_PTR_EXTRA),
271 DIFlags::FlagZero,
272 type_di_node(cx, extra_field.ty),
273 ),
274 ]
5099ac24 275 },
5e7ed085 276 NO_GENERICS,
5099ac24
FG
277 )
278 }
5e7ed085 279 }
d9579d0f 280}
1a4d82fc 281
5e7ed085 282fn build_subroutine_type_di_node<'ll, 'tcx>(
b7449926 283 cx: &CodegenCx<'ll, 'tcx>,
5e7ed085
FG
284 unique_type_id: UniqueTypeId<'tcx>,
285) -> DINodeCreationResult<'ll> {
286 // It's possible to create a self-referential
287 // type in Rust by using 'impl trait':
288 //
289 // fn foo() -> impl Copy { foo }
290 //
291 // Unfortunately LLVM's API does not allow us to create recursive subroutine types.
292 // In order to work around that restriction we place a marker type in the type map,
293 // before creating the actual type. If the actual type is recursive, it will hit the
294 // marker type. So we end up with a type that looks like
295 //
296 // fn foo() -> <recursive_type>
297 //
298 // Once that is created, we replace the marker in the typemap with the actual type.
299 debug_context(cx)
300 .type_map
301 .unique_id_to_di_node
302 .borrow_mut()
303 .insert(unique_type_id, recursion_marker_type_di_node(cx));
1a4d82fc 304
5e7ed085
FG
305 let fn_ty = unique_type_id.expect_ty();
306 let signature = cx
307 .tcx
308 .normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), fn_ty.fn_sig(cx.tcx));
309
310 let signature_di_nodes: SmallVec<_> = iter::once(
8faf50e0 311 // return type
1b1a35ee 312 match signature.output().kind() {
5e7ed085
FG
313 ty::Tuple(tys) if tys.is_empty() => {
314 // this is a "void" function
315 None
316 }
317 _ => Some(type_di_node(cx, signature.output())),
dfeec247
XL
318 },
319 )
320 .chain(
8faf50e0 321 // regular arguments
5e7ed085 322 signature.inputs().iter().map(|&argument_type| Some(type_di_node(cx, argument_type))),
dfeec247
XL
323 )
324 .collect();
1a4d82fc 325
5e7ed085 326 debug_context(cx).type_map.unique_id_to_di_node.borrow_mut().remove(&unique_type_id);
1a4d82fc 327
5e7ed085
FG
328 let fn_di_node = unsafe {
329 llvm::LLVMRustDIBuilderCreateSubroutineType(
330 DIB(cx),
331 create_DIArray(DIB(cx), &signature_di_nodes[..]),
332 )
333 };
334
335 // This is actually a function pointer, so wrap it in pointer DI.
336 let name = compute_debuginfo_type_name(cx.tcx, fn_ty, false);
337 let di_node = unsafe {
338 llvm::LLVMRustDIBuilderCreatePointerType(
339 DIB(cx),
340 fn_di_node,
341 cx.tcx.data_layout.pointer_size.bits(),
342 cx.tcx.data_layout.pointer_align.abi.bits() as u32,
343 0, // Ignore DWARF address space.
344 name.as_ptr().cast(),
345 name.len(),
346 )
347 };
348
349 DINodeCreationResult::new(di_node, false)
1a4d82fc
JJ
350}
351
5099ac24
FG
352/// Create debuginfo for `dyn SomeTrait` types. Currently these are empty structs
353/// we with the correct type name (e.g. "dyn SomeTrait<Foo, Item=u32> + Sync").
5e7ed085 354fn build_dyn_type_di_node<'ll, 'tcx>(
b7449926 355 cx: &CodegenCx<'ll, 'tcx>,
5099ac24 356 dyn_type: Ty<'tcx>,
5e7ed085
FG
357 unique_type_id: UniqueTypeId<'tcx>,
358) -> DINodeCreationResult<'ll> {
5099ac24
FG
359 if let ty::Dynamic(..) = dyn_type.kind() {
360 let type_name = compute_debuginfo_type_name(cx.tcx, dyn_type, true);
5e7ed085
FG
361 type_map::build_type_with_children(
362 cx,
363 type_map::stub(
364 cx,
365 Stub::Struct,
366 unique_type_id,
367 &type_name,
368 cx.size_and_align_of(dyn_type),
369 NO_SCOPE_METADATA,
370 DIFlags::FlagZero,
371 ),
372 |_, _| smallvec![],
373 NO_GENERICS,
374 )
5099ac24 375 } else {
5e7ed085
FG
376 bug!(
377 "Only ty::Dynamic is valid for build_dyn_type_di_node(). Found {:?} instead.",
378 dyn_type
379 )
5099ac24
FG
380 }
381}
1a4d82fc 382
5099ac24
FG
383/// Create debuginfo for `[T]` and `str`. These are unsized.
384///
385/// NOTE: We currently emit just emit the debuginfo for the element type here
386/// (i.e. `T` for slices and `u8` for `str`), so that we end up with
387/// `*const T` for the `data_ptr` field of the corresponding fat-pointer
388/// debuginfo of `&[T]`.
389///
390/// It would be preferable and more accurate if we emitted a DIArray of T
391/// without an upper bound instead. That is, LLVM already supports emitting
392/// debuginfo of arrays of unknown size. But GDB currently seems to end up
393/// in an infinite loop when confronted with such a type.
394///
395/// As a side effect of the current encoding every instance of a type like
396/// `struct Foo { unsized_field: [u8] }` will look like
397/// `struct Foo { unsized_field: u8 }` in debuginfo. If the length of the
398/// slice is zero, then accessing `unsized_field` in the debugger would
399/// result in an out-of-bounds access.
5e7ed085 400fn build_slice_type_di_node<'ll, 'tcx>(
5099ac24
FG
401 cx: &CodegenCx<'ll, 'tcx>,
402 slice_type: Ty<'tcx>,
5e7ed085
FG
403 unique_type_id: UniqueTypeId<'tcx>,
404) -> DINodeCreationResult<'ll> {
5099ac24
FG
405 let element_type = match slice_type.kind() {
406 ty::Slice(element_type) => *element_type,
407 ty::Str => cx.tcx.types.u8,
408 _ => {
409 bug!(
5e7ed085 410 "Only ty::Slice is valid for build_slice_type_di_node(). Found {:?} instead.",
5099ac24
FG
411 slice_type
412 )
413 }
136023e0 414 };
1a4d82fc 415
5e7ed085
FG
416 let element_type_di_node = type_di_node(cx, element_type);
417 return_if_di_node_created_in_meantime!(cx, unique_type_id);
418 DINodeCreationResult { di_node: element_type_di_node, already_stored_in_typemap: false }
1a4d82fc
JJ
419}
420
5e7ed085
FG
421/// Get the debuginfo node for the given type.
422///
423/// This function will look up the debuginfo node in the TypeMap. If it can't find it, it
424/// will create the node by dispatching to the corresponding `build_*_di_node()` function.
425pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
426 let unique_type_id = UniqueTypeId::for_ty(cx.tcx, t);
427
428 if let Some(existing_di_node) = debug_context(cx).type_map.di_node_for_unique_id(unique_type_id)
429 {
430 return existing_di_node;
431 }
1a4d82fc 432
5e7ed085 433 debug!("type_di_node: {:?}", t);
1a4d82fc 434
5e7ed085 435 let DINodeCreationResult { di_node, already_stored_in_typemap } = match *t.kind() {
dfeec247 436 ty::Never | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => {
04454e1e 437 build_basic_type_di_node(cx, t)
1a4d82fc 438 }
04454e1e 439 ty::Tuple(elements) if elements.is_empty() => build_basic_type_di_node(cx, t),
5e7ed085
FG
440 ty::Array(..) => build_fixed_size_array_di_node(cx, unique_type_id, t),
441 ty::Slice(_) | ty::Str => build_slice_type_di_node(cx, t, unique_type_id),
442 ty::Dynamic(..) => build_dyn_type_di_node(cx, t, unique_type_id),
443 ty::Foreign(..) => build_foreign_type_di_node(cx, t, unique_type_id),
5099ac24 444 ty::RawPtr(ty::TypeAndMut { ty: pointee_type, .. }) | ty::Ref(_, pointee_type, _) => {
5e7ed085 445 build_pointer_or_reference_di_node(cx, t, pointee_type, unique_type_id)
1a4d82fc 446 }
5e7ed085
FG
447 // Box<T, A> may have a non-ZST allocator A. In that case, we
448 // cannot treat Box<T, A> as just an owned alias of `*mut T`.
449 ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => {
450 build_pointer_or_reference_di_node(cx, t, t.boxed_ty(), unique_type_id)
ea8adc8c 451 }
5e7ed085
FG
452 ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id),
453 ty::Closure(..) => build_closure_env_di_node(cx, unique_type_id),
454 ty::Generator(..) => enums::build_generator_di_node(cx, unique_type_id),
b7449926 455 ty::Adt(def, ..) => match def.adt_kind() {
5e7ed085
FG
456 AdtKind::Struct => build_struct_type_di_node(cx, unique_type_id),
457 AdtKind::Union => build_union_type_di_node(cx, unique_type_id),
458 AdtKind::Enum => enums::build_enum_type_di_node(cx, unique_type_id),
9e0c209e 459 },
5e7ed085 460 ty::Tuple(_) => build_tuple_type_di_node(cx, unique_type_id),
3dfed10e 461 // Type parameters from polymorphized functions.
5e7ed085
FG
462 ty::Param(_) => build_param_type_di_node(cx, t),
463 _ => bug!("debuginfo: unexpected type in type_di_node(): {:?}", t),
1a4d82fc
JJ
464 };
465
466 {
1a4d82fc 467 if already_stored_in_typemap {
5e7ed085
FG
468 // Make sure that we really do have a `TypeMap` entry for the unique type ID.
469 let di_node_for_uid =
470 match debug_context(cx).type_map.di_node_for_unique_id(unique_type_id) {
471 Some(di_node) => di_node,
472 None => {
5099ac24 473 bug!(
5e7ed085
FG
474 "expected type debuginfo node for unique \
475 type ID '{:?}' to already be in \
476 the `debuginfo::TypeMap` but it \
477 was not.",
478 unique_type_id,
dfeec247 479 );
1a4d82fc 480 }
5e7ed085
FG
481 };
482
483 debug_assert_eq!(di_node_for_uid as *const _, di_node as *const _);
1a4d82fc 484 } else {
5e7ed085 485 debug_context(cx).type_map.insert(unique_type_id, di_node);
1a4d82fc
JJ
486 }
487 }
488
5e7ed085
FG
489 di_node
490}
491
492// FIXME(mw): Cache this via a regular UniqueTypeId instead of an extra field in the debug context.
493fn recursion_marker_type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) -> &'ll DIType {
494 *debug_context(cx).recursion_marker_type.get_or_init(move || {
495 unsafe {
496 // The choice of type here is pretty arbitrary -
497 // anything reading the debuginfo for a recursive
498 // type is going to see *something* weird - the only
499 // question is what exactly it will see.
500 //
501 // FIXME: the name `<recur_type>` does not fit the naming scheme
502 // of other types.
503 //
504 // FIXME: it might make sense to use an actual pointer type here
505 // so that debuggers can show the address.
506 let name = "<recur_type>";
507 llvm::LLVMRustDIBuilderCreateBasicType(
508 DIB(cx),
509 name.as_ptr().cast(),
510 name.len(),
511 cx.tcx.data_layout.pointer_size.bits(),
512 DW_ATE_unsigned,
513 )
514 }
515 })
1a4d82fc
JJ
516}
517
ba9703b0
XL
518fn hex_encode(data: &[u8]) -> String {
519 let mut hex_string = String::with_capacity(data.len() * 2);
520 for byte in data.iter() {
521 write!(&mut hex_string, "{:02x}", byte).unwrap();
522 }
523 hex_string
524}
525
a2a8927a 526pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> &'ll DIFile {
923072b8
FG
527 let cache_key = Some((source_file.name_hash, source_file.src_hash));
528 return debug_context(cx)
529 .created_files
530 .borrow_mut()
531 .entry(cache_key)
532 .or_insert_with(|| alloc_new_file_metadata(cx, source_file));
533
534 #[instrument(skip(cx, source_file), level = "debug")]
535 fn alloc_new_file_metadata<'ll>(
536 cx: &CodegenCx<'ll, '_>,
537 source_file: &SourceFile,
538 ) -> &'ll DIFile {
539 debug!(?source_file.name);
540
541 let (directory, file_name) = match &source_file.name {
542 FileName::Real(filename) => {
543 let working_directory = &cx.sess().opts.working_dir;
544 debug!(?working_directory);
545
546 let filename = cx
547 .sess()
548 .source_map()
549 .path_mapping()
550 .to_embeddable_absolute_path(filename.clone(), working_directory);
551
552 // Construct the absolute path of the file
553 let abs_path = filename.remapped_path_if_available();
554 debug!(?abs_path);
555
556 if let Ok(rel_path) =
557 abs_path.strip_prefix(working_directory.remapped_path_if_available())
558 {
559 // If the compiler's working directory (which also is the DW_AT_comp_dir of
560 // the compilation unit) is a prefix of the path we are about to emit, then
561 // only emit the part relative to the working directory.
562 // Because of path remapping we sometimes see strange things here: `abs_path`
563 // might actually look like a relative path
564 // (e.g. `<crate-name-and-version>/src/lib.rs`), so if we emit it without
565 // taking the working directory into account, downstream tooling will
566 // interpret it as `<working-directory>/<crate-name-and-version>/src/lib.rs`,
567 // which makes no sense. Usually in such cases the working directory will also
568 // be remapped to `<crate-name-and-version>` or some other prefix of the path
569 // we are remapping, so we end up with
570 // `<crate-name-and-version>/<crate-name-and-version>/src/lib.rs`.
571 // By moving the working directory portion into the `directory` part of the
572 // DIFile, we allow LLVM to emit just the relative path for DWARF, while
573 // still emitting the correct absolute path for CodeView.
574 (
575 working_directory.to_string_lossy(FileNameDisplayPreference::Remapped),
576 rel_path.to_string_lossy().into_owned(),
577 )
578 } else {
579 ("".into(), abs_path.to_string_lossy().into_owned())
ba9703b0 580 }
923072b8
FG
581 }
582 other => ("".into(), other.prefer_remapped().to_string_lossy().into_owned()),
583 };
ba9703b0 584
923072b8
FG
585 let hash_kind = match source_file.src_hash.kind {
586 rustc_span::SourceFileHashAlgorithm::Md5 => llvm::ChecksumKind::MD5,
587 rustc_span::SourceFileHashAlgorithm::Sha1 => llvm::ChecksumKind::SHA1,
588 rustc_span::SourceFileHashAlgorithm::Sha256 => llvm::ChecksumKind::SHA256,
589 };
590 let hash_value = hex_encode(source_file.src_hash.hash_bytes());
7cac9316 591
923072b8
FG
592 unsafe {
593 llvm::LLVMRustDIBuilderCreateFile(
594 DIB(cx),
595 file_name.as_ptr().cast(),
596 file_name.len(),
597 directory.as_ptr().cast(),
598 directory.len(),
599 hash_kind,
600 hash_value.as_ptr().cast(),
601 hash_value.len(),
602 )
dc9dc135 603 }
e9174d1e 604 }
d9579d0f
AL
605}
606
923072b8
FG
607pub fn unknown_file_metadata<'ll>(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
608 debug_context(cx).created_files.borrow_mut().entry(None).or_insert_with(|| unsafe {
609 let file_name = "<unknown>";
610 let directory = "";
611 let hash_value = "";
612
613 llvm::LLVMRustDIBuilderCreateFile(
614 DIB(cx),
615 file_name.as_ptr().cast(),
616 file_name.len(),
617 directory.as_ptr().cast(),
618 directory.len(),
619 llvm::ChecksumKind::None,
620 hash_value.as_ptr().cast(),
621 hash_value.len(),
622 )
623 })
624}
625
f035d41b
XL
626trait MsvcBasicName {
627 fn msvc_basic_name(self) -> &'static str;
628}
629
5869c6ff 630impl MsvcBasicName for ty::IntTy {
f035d41b
XL
631 fn msvc_basic_name(self) -> &'static str {
632 match self {
5869c6ff
XL
633 ty::IntTy::Isize => "ptrdiff_t",
634 ty::IntTy::I8 => "__int8",
635 ty::IntTy::I16 => "__int16",
636 ty::IntTy::I32 => "__int32",
637 ty::IntTy::I64 => "__int64",
638 ty::IntTy::I128 => "__int128",
f035d41b
XL
639 }
640 }
641}
642
5869c6ff 643impl MsvcBasicName for ty::UintTy {
f035d41b
XL
644 fn msvc_basic_name(self) -> &'static str {
645 match self {
5869c6ff
XL
646 ty::UintTy::Usize => "size_t",
647 ty::UintTy::U8 => "unsigned __int8",
648 ty::UintTy::U16 => "unsigned __int16",
649 ty::UintTy::U32 => "unsigned __int32",
650 ty::UintTy::U64 => "unsigned __int64",
651 ty::UintTy::U128 => "unsigned __int128",
f035d41b
XL
652 }
653 }
654}
655
5869c6ff 656impl MsvcBasicName for ty::FloatTy {
f035d41b
XL
657 fn msvc_basic_name(self) -> &'static str {
658 match self {
5869c6ff
XL
659 ty::FloatTy::F32 => "float",
660 ty::FloatTy::F64 => "double",
f035d41b
XL
661 }
662 }
663}
664
04454e1e
FG
665fn build_basic_type_di_node<'ll, 'tcx>(
666 cx: &CodegenCx<'ll, 'tcx>,
667 t: Ty<'tcx>,
668) -> DINodeCreationResult<'ll> {
5e7ed085 669 debug!("build_basic_type_di_node: {:?}", t);
d9579d0f 670
f035d41b
XL
671 // When targeting MSVC, emit MSVC style type names for compatibility with
672 // .natvis visualizers (and perhaps other existing native debuggers?)
a2a8927a 673 let cpp_like_debuginfo = cpp_like_debuginfo(cx.tcx);
f035d41b 674
1b1a35ee 675 let (name, encoding) = match t.kind() {
b7449926 676 ty::Never => ("!", DW_ATE_unsigned),
04454e1e
FG
677 ty::Tuple(elements) if elements.is_empty() => {
678 if cpp_like_debuginfo {
679 return build_tuple_type_di_node(cx, UniqueTypeId::for_ty(cx.tcx, t));
680 } else {
681 ("()", DW_ATE_unsigned)
682 }
683 }
b7449926 684 ty::Bool => ("bool", DW_ATE_boolean),
5e7ed085 685 ty::Char => ("char", DW_ATE_UTF),
a2a8927a
XL
686 ty::Int(int_ty) if cpp_like_debuginfo => (int_ty.msvc_basic_name(), DW_ATE_signed),
687 ty::Uint(uint_ty) if cpp_like_debuginfo => (uint_ty.msvc_basic_name(), DW_ATE_unsigned),
688 ty::Float(float_ty) if cpp_like_debuginfo => (float_ty.msvc_basic_name(), DW_ATE_float),
dfeec247
XL
689 ty::Int(int_ty) => (int_ty.name_str(), DW_ATE_signed),
690 ty::Uint(uint_ty) => (uint_ty.name_str(), DW_ATE_unsigned),
691 ty::Float(float_ty) => (float_ty.name_str(), DW_ATE_float),
5e7ed085 692 _ => bug!("debuginfo::build_basic_type_di_node - `t` is invalid type"),
d9579d0f
AL
693 };
694
5e7ed085 695 let ty_di_node = unsafe {
5bcae85e 696 llvm::LLVMRustDIBuilderCreateBasicType(
d9579d0f 697 DIB(cx),
74b04a01
XL
698 name.as_ptr().cast(),
699 name.len(),
f9f354fc 700 cx.size_of(t).bits(),
dfeec247
XL
701 encoding,
702 )
d9579d0f
AL
703 };
704
a2a8927a 705 if !cpp_like_debuginfo {
04454e1e 706 return DINodeCreationResult::new(ty_di_node, false);
f035d41b
XL
707 }
708
1b1a35ee 709 let typedef_name = match t.kind() {
f035d41b
XL
710 ty::Int(int_ty) => int_ty.name_str(),
711 ty::Uint(uint_ty) => uint_ty.name_str(),
712 ty::Float(float_ty) => float_ty.name_str(),
04454e1e 713 _ => return DINodeCreationResult::new(ty_di_node, false),
f035d41b
XL
714 };
715
5e7ed085 716 let typedef_di_node = unsafe {
f035d41b
XL
717 llvm::LLVMRustDIBuilderCreateTypedef(
718 DIB(cx),
5e7ed085 719 ty_di_node,
f035d41b
XL
720 typedef_name.as_ptr().cast(),
721 typedef_name.len(),
722 unknown_file_metadata(cx),
723 0,
724 None,
725 )
726 };
727
04454e1e 728 DINodeCreationResult::new(typedef_di_node, false)
d9579d0f
AL
729}
730
5e7ed085 731fn build_foreign_type_di_node<'ll, 'tcx>(
b7449926
XL
732 cx: &CodegenCx<'ll, 'tcx>,
733 t: Ty<'tcx>,
5e7ed085
FG
734 unique_type_id: UniqueTypeId<'tcx>,
735) -> DINodeCreationResult<'ll> {
736 debug!("build_foreign_type_di_node: {:?}", t);
737
738 let &ty::Foreign(def_id) = unique_type_id.expect_ty().kind() else {
739 bug!("build_foreign_type_di_node() called with unexpected type: {:?}", unique_type_id.expect_ty());
740 };
abe05a73 741
5e7ed085 742 build_type_with_children(
5099ac24 743 cx,
5e7ed085
FG
744 type_map::stub(
745 cx,
746 Stub::Struct,
747 unique_type_id,
748 &compute_debuginfo_type_name(cx.tcx, t, false),
749 cx.size_and_align_of(t),
750 Some(get_namespace_for_item(cx, def_id)),
751 DIFlags::FlagZero,
752 ),
753 |_, _| smallvec![],
754 NO_GENERICS,
5099ac24 755 )
d9579d0f
AL
756}
757
5e7ed085
FG
758fn build_param_type_di_node<'ll, 'tcx>(
759 cx: &CodegenCx<'ll, 'tcx>,
760 t: Ty<'tcx>,
761) -> DINodeCreationResult<'ll> {
762 debug!("build_param_type_di_node: {:?}", t);
3dfed10e 763 let name = format!("{:?}", t);
5e7ed085
FG
764 DINodeCreationResult {
765 di_node: unsafe {
766 llvm::LLVMRustDIBuilderCreateBasicType(
767 DIB(cx),
768 name.as_ptr().cast(),
769 name.len(),
770 Size::ZERO.bits(),
771 DW_ATE_unsigned,
772 )
773 },
774 already_stored_in_typemap: false,
3dfed10e
XL
775 }
776}
777
5e7ed085 778pub fn build_compile_unit_di_node<'ll, 'tcx>(
a2a8927a 779 tcx: TyCtxt<'tcx>,
dc9dc135 780 codegen_unit_name: &str,
5e7ed085 781 debug_context: &CodegenUnitDebugContext<'ll, 'tcx>,
dc9dc135 782) -> &'ll DIDescriptor {
9c376795
FG
783 let mut name_in_debuginfo = tcx
784 .sess
785 .local_crate_source_file()
786 .unwrap_or_else(|| PathBuf::from(tcx.crate_name(LOCAL_CRATE).as_str()));
d9579d0f 787
a2a8927a
XL
788 // To avoid breaking split DWARF, we need to ensure that each codegen unit
789 // has a unique `DW_AT_name`. This is because there's a remote chance that
790 // different codegen units for the same module will have entirely
791 // identical DWARF entries for the purpose of the DWO ID, which would
792 // violate Appendix F ("Split Dwarf Object Files") of the DWARF 5
793 // specification. LLVM uses the algorithm specified in section 7.32 "Type
794 // Signature Computation" to compute the DWO ID, which does not include
795 // any fields that would distinguish compilation units. So we must embed
796 // the codegen unit name into the `DW_AT_name`. (Issue #88521.)
797 //
798 // Additionally, the OSX linker has an idiosyncrasy where it will ignore
799 // some debuginfo if multiple object files with the same `DW_AT_name` are
800 // linked together.
801 //
802 // As a workaround for these two issues, we generate unique names for each
803 // object file. Those do not correspond to an actual source file but that
804 // is harmless.
805 name_in_debuginfo.push("@");
806 name_in_debuginfo.push(codegen_unit_name);
7cac9316 807
5e7ed085 808 debug!("build_compile_unit_di_node: {:?}", name_in_debuginfo);
49aad941 809 let rustc_producer = format!("rustc version {}", tcx.sess.cfg_version);
cc61c64b 810 // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
416331ca 811 let producer = format!("clang LLVM ({})", rustc_producer);
d9579d0f 812
b7449926 813 let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
94222f64 814 let work_dir = tcx.sess.opts.working_dir.to_string_lossy(FileNameDisplayPreference::Remapped);
d9579d0f 815 let flags = "\0";
17df50a5 816 let output_filenames = tcx.output_filenames(());
5869c6ff 817 let split_name = if tcx.sess.target_can_use_split_dwarf() {
17df50a5 818 output_filenames
a2a8927a
XL
819 .split_dwarf_path(
820 tcx.sess.split_debuginfo(),
064997fb 821 tcx.sess.opts.unstable_opts.split_dwarf_kind,
a2a8927a
XL
822 Some(codegen_unit_name),
823 )
824 // We get a path relative to the working directory from split_dwarf_path
825 .map(|f| tcx.sess.source_map().path_mapping().map_prefix(f).0)
5869c6ff
XL
826 } else {
827 None
828 }
829 .unwrap_or_default();
fc512014 830 let split_name = split_name.to_str().unwrap();
353b0b11 831 let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
8bb4bdeb
XL
832
833 unsafe {
6a06907d 834 let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile(
dfeec247 835 debug_context.builder,
74b04a01
XL
836 name_in_debuginfo.as_ptr().cast(),
837 name_in_debuginfo.len(),
6a06907d
XL
838 work_dir.as_ptr().cast(),
839 work_dir.len(),
ba9703b0
XL
840 llvm::ChecksumKind::None,
841 ptr::null(),
842 0,
dfeec247 843 );
8bb4bdeb 844
041b39d2 845 let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
5bcae85e 846 debug_context.builder,
d9579d0f 847 DW_LANG_RUST,
6a06907d 848 compile_unit_file,
74b04a01
XL
849 producer.as_ptr().cast(),
850 producer.len(),
2c00a5a8 851 tcx.sess.opts.optimize != config::OptLevel::No,
e74abb32 852 flags.as_ptr().cast(),
d9579d0f 853 0,
6a06907d
XL
854 // NB: this doesn't actually have any perceptible effect, it seems. LLVM will instead
855 // put the path supplied to `MCSplitDwarfFile` into the debug info of the final
856 // output(s).
e74abb32 857 split_name.as_ptr().cast(),
74b04a01 858 split_name.len(),
dfeec247 859 kind,
fc512014 860 0,
064997fb 861 tcx.sess.opts.unstable_opts.split_dwarf_inlining,
dfeec247 862 );
041b39d2 863
064997fb 864 if tcx.sess.opts.unstable_opts.profile {
17df50a5 865 let default_gcda_path = &output_filenames.with_extension("gcda");
f9f354fc 866 let gcda_path =
064997fb 867 tcx.sess.opts.unstable_opts.profile_emit.as_ref().unwrap_or(default_gcda_path);
041b39d2
XL
868
869 let gcov_cu_info = [
17df50a5 870 path_to_mdstring(debug_context.llcontext, &output_filenames.with_extension("gcno")),
c295e0f8 871 path_to_mdstring(debug_context.llcontext, gcda_path),
353b0b11 872 unit_metadata,
041b39d2 873 ];
353b0b11 874 let gcov_metadata = llvm::LLVMMDNodeInContext2(
dfeec247
XL
875 debug_context.llcontext,
876 gcov_cu_info.as_ptr(),
353b0b11 877 gcov_cu_info.len(),
dfeec247 878 );
353b0b11 879 let val = llvm::LLVMMetadataAsValue(debug_context.llcontext, gcov_metadata);
041b39d2 880
6a06907d 881 let llvm_gcov_ident = cstr!("llvm.gcov");
353b0b11 882 llvm::LLVMAddNamedMetadataOperand(debug_context.llmod, llvm_gcov_ident.as_ptr(), val);
041b39d2
XL
883 }
884
cdc7bbd5 885 // Insert `llvm.ident` metadata on the wasm targets since that will
416331ca 886 // get hooked up to the "producer" sections `processed-by` information.
cdc7bbd5 887 if tcx.sess.target.is_like_wasm {
416331ca
XL
888 let name_metadata = llvm::LLVMMDStringInContext(
889 debug_context.llcontext,
e74abb32 890 rustc_producer.as_ptr().cast(),
416331ca
XL
891 rustc_producer.as_bytes().len() as c_uint,
892 );
893 llvm::LLVMAddNamedMetadataOperand(
894 debug_context.llmod,
6a06907d 895 cstr!("llvm.ident").as_ptr(),
416331ca
XL
896 llvm::LLVMMDNodeInContext(debug_context.llcontext, &name_metadata, 1),
897 );
898 }
899
041b39d2 900 return unit_metadata;
d9579d0f 901 };
041b39d2 902
353b0b11 903 fn path_to_mdstring<'ll>(llcx: &'ll llvm::Context, path: &Path) -> &'ll llvm::Metadata {
a1dfa0c6 904 let path_str = path_to_c_string(path);
353b0b11 905 unsafe { llvm::LLVMMDStringInContext2(llcx, path_str.as_ptr(), path_str.as_bytes().len()) }
041b39d2 906 }
d9579d0f
AL
907}
908
5e7ed085
FG
909/// Creates a `DW_TAG_member` entry inside the DIE represented by the given `type_di_node`.
910fn build_field_di_node<'ll, 'tcx>(
911 cx: &CodegenCx<'ll, 'tcx>,
912 owner: &'ll DIScope,
913 name: &str,
914 size_and_align: (Size, Align),
ff7c6d11 915 offset: Size,
476ff2be 916 flags: DIFlags,
5e7ed085
FG
917 type_di_node: &'ll DIType,
918) -> &'ll DIType {
919 unsafe {
920 llvm::LLVMRustDIBuilderCreateMemberType(
921 DIB(cx),
922 owner,
923 name.as_ptr().cast(),
924 name.len(),
925 unknown_file_metadata(cx),
926 UNKNOWN_LINE_NUMBER,
927 size_and_align.0.bits(),
928 size_and_align.1.bits() as u32,
929 offset.bits(),
930 flags,
931 type_di_node,
932 )
48663c56
XL
933 }
934}
935
5e7ed085
FG
936/// Creates the debuginfo node for a Rust struct type. Maybe be a regular struct or a tuple-struct.
937fn build_struct_type_di_node<'ll, 'tcx>(
938 cx: &CodegenCx<'ll, 'tcx>,
939 unique_type_id: UniqueTypeId<'tcx>,
940) -> DINodeCreationResult<'ll> {
941 let struct_type = unique_type_id.expect_ty();
942 let ty::Adt(adt_def, _) = struct_type.kind() else {
943 bug!("build_struct_type_di_node() called with non-struct-type: {:?}", struct_type);
944 };
945 debug_assert!(adt_def.is_struct());
946 let containing_scope = get_namespace_for_item(cx, adt_def.did());
947 let struct_type_and_layout = cx.layout_of(struct_type);
948 let variant_def = adt_def.non_enum_variant();
d9579d0f 949
5e7ed085
FG
950 type_map::build_type_with_children(
951 cx,
952 type_map::stub(
953 cx,
954 Stub::Struct,
955 unique_type_id,
956 &compute_debuginfo_type_name(cx.tcx, struct_type, false),
957 size_and_align_of(struct_type_and_layout),
958 Some(containing_scope),
959 DIFlags::FlagZero,
960 ),
961 // Fields:
962 |cx, owner| {
963 variant_def
964 .fields
965 .iter()
966 .enumerate()
967 .map(|(i, f)| {
487cf647 968 let field_name = if variant_def.ctor_kind() == Some(CtorKind::Fn) {
5e7ed085
FG
969 // This is a tuple struct
970 tuple_field_name(i)
971 } else {
972 // This is struct with named fields
973 Cow::Borrowed(f.name.as_str())
974 };
975 let field_layout = struct_type_and_layout.field(cx, i);
976 build_field_di_node(
977 cx,
978 owner,
979 &field_name[..],
980 (field_layout.size, field_layout.align.abi),
981 struct_type_and_layout.fields.offset(i),
982 DIFlags::FlagZero,
983 type_di_node(cx, field_layout.ty),
984 )
985 })
986 .collect()
987 },
988 |cx| build_generic_type_param_di_nodes(cx, struct_type),
989 )
d9579d0f
AL
990}
991
992//=-----------------------------------------------------------------------------
5e7ed085 993// Tuples
d9579d0f
AL
994//=-----------------------------------------------------------------------------
995
5e7ed085
FG
996/// Builds the DW_TAG_member debuginfo nodes for the upvars of a closure or generator.
997/// For a generator, this will handle upvars shared by all states.
998fn build_upvar_field_di_nodes<'ll, 'tcx>(
999 cx: &CodegenCx<'ll, 'tcx>,
1000 closure_or_generator_ty: Ty<'tcx>,
1001 closure_or_generator_di_node: &'ll DIType,
1002) -> SmallVec<&'ll DIType> {
1003 let (&def_id, up_var_tys) = match closure_or_generator_ty.kind() {
1004 ty::Generator(def_id, substs, _) => {
1005 let upvar_tys: SmallVec<_> = substs.as_generator().prefix_tys().collect();
1006 (def_id, upvar_tys)
1007 }
1008 ty::Closure(def_id, substs) => {
1009 let upvar_tys: SmallVec<_> = substs.as_closure().upvar_tys().collect();
1010 (def_id, upvar_tys)
1011 }
1012 _ => {
1013 bug!(
1014 "build_upvar_field_di_nodes() called with non-closure-or-generator-type: {:?}",
1015 closure_or_generator_ty
1016 )
1017 }
1018 };
1a4d82fc 1019
5e7ed085
FG
1020 debug_assert!(
1021 up_var_tys
dfeec247 1022 .iter()
5e7ed085
FG
1023 .all(|&t| t == cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
1024 );
1025
9c376795 1026 let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id);
5e7ed085
FG
1027 let layout = cx.layout_of(closure_or_generator_ty);
1028
1029 up_var_tys
1030 .into_iter()
1031 .zip(capture_names.iter())
1032 .enumerate()
1033 .map(|(index, (up_var_ty, capture_name))| {
1034 build_field_di_node(
1035 cx,
1036 closure_or_generator_di_node,
1037 capture_name,
1038 cx.size_and_align_of(up_var_ty),
1039 layout.fields.offset(index),
1040 DIFlags::FlagZero,
1041 type_di_node(cx, up_var_ty),
1042 )
1043 })
1044 .collect()
1a4d82fc
JJ
1045}
1046
5e7ed085
FG
1047/// Builds the DW_TAG_structure_type debuginfo node for a Rust tuple type.
1048fn build_tuple_type_di_node<'ll, 'tcx>(
b7449926 1049 cx: &CodegenCx<'ll, 'tcx>,
5e7ed085
FG
1050 unique_type_id: UniqueTypeId<'tcx>,
1051) -> DINodeCreationResult<'ll> {
1052 let tuple_type = unique_type_id.expect_ty();
1053 let &ty::Tuple(component_types) = tuple_type.kind() else {
1054 bug!("build_tuple_type_di_node() called with non-tuple-type: {:?}", tuple_type)
1055 };
a1dfa0c6 1056
5e7ed085
FG
1057 let tuple_type_and_layout = cx.layout_of(tuple_type);
1058 let type_name = compute_debuginfo_type_name(cx.tcx, tuple_type, false);
1059
1060 type_map::build_type_with_children(
d9579d0f 1061 cx,
5e7ed085
FG
1062 type_map::stub(
1063 cx,
1064 Stub::Struct,
1065 unique_type_id,
1066 &type_name,
1067 size_and_align_of(tuple_type_and_layout),
1068 NO_SCOPE_METADATA,
1069 DIFlags::FlagZero,
1070 ),
1071 // Fields:
1072 |cx, tuple_di_node| {
1073 component_types
1074 .into_iter()
1075 .enumerate()
1076 .map(|(index, component_type)| {
1077 build_field_di_node(
1078 cx,
1079 tuple_di_node,
1080 &tuple_field_name(index),
1081 cx.size_and_align_of(component_type),
1082 tuple_type_and_layout.fields.offset(index),
1083 DIFlags::FlagZero,
1084 type_di_node(cx, component_type),
1085 )
1086 })
1087 .collect()
1088 },
1089 NO_GENERICS,
d9579d0f 1090 )
1a4d82fc
JJ
1091}
1092
5e7ed085
FG
1093/// Builds the debuginfo node for a closure environment.
1094fn build_closure_env_di_node<'ll, 'tcx>(
1095 cx: &CodegenCx<'ll, 'tcx>,
1096 unique_type_id: UniqueTypeId<'tcx>,
1097) -> DINodeCreationResult<'ll> {
1098 let closure_env_type = unique_type_id.expect_ty();
1099 let &ty::Closure(def_id, _substs) = closure_env_type.kind() else {
1100 bug!("build_closure_env_di_node() called with non-closure-type: {:?}", closure_env_type)
1101 };
1102 let containing_scope = get_namespace_for_item(cx, def_id);
1103 let type_name = compute_debuginfo_type_name(cx.tcx, closure_env_type, false);
9e0c209e 1104
5e7ed085
FG
1105 type_map::build_type_with_children(
1106 cx,
1107 type_map::stub(
1108 cx,
1109 Stub::Struct,
1110 unique_type_id,
1111 &type_name,
1112 cx.size_and_align_of(closure_env_type),
1113 Some(containing_scope),
1114 DIFlags::FlagZero,
1115 ),
1116 // Fields:
1117 |cx, owner| build_upvar_field_di_nodes(cx, closure_env_type, owner),
1118 NO_GENERICS,
1119 )
9e0c209e
SL
1120}
1121
5e7ed085
FG
1122/// Build the debuginfo node for a Rust `union` type.
1123fn build_union_type_di_node<'ll, 'tcx>(
b7449926 1124 cx: &CodegenCx<'ll, 'tcx>,
5e7ed085
FG
1125 unique_type_id: UniqueTypeId<'tcx>,
1126) -> DINodeCreationResult<'ll> {
1127 let union_type = unique_type_id.expect_ty();
1128 let (union_def_id, variant_def) = match union_type.kind() {
1129 ty::Adt(def, _) => (def.did(), def.non_enum_variant()),
1130 _ => bug!("build_union_type_di_node on a non-ADT"),
9e0c209e 1131 };
041b39d2 1132 let containing_scope = get_namespace_for_item(cx, union_def_id);
5e7ed085
FG
1133 let union_ty_and_layout = cx.layout_of(union_type);
1134 let type_name = compute_debuginfo_type_name(cx.tcx, union_type, false);
9e0c209e 1135
5e7ed085 1136 type_map::build_type_with_children(
9e0c209e 1137 cx,
5e7ed085
FG
1138 type_map::stub(
1139 cx,
1140 Stub::Union,
1141 unique_type_id,
1142 &type_name,
1143 size_and_align_of(union_ty_and_layout),
1144 Some(containing_scope),
1145 DIFlags::FlagZero,
1146 ),
1147 // Fields:
1148 |cx, owner| {
1149 variant_def
1150 .fields
1151 .iter()
1152 .enumerate()
1153 .map(|(i, f)| {
1154 let field_layout = union_ty_and_layout.field(cx, i);
1155 build_field_di_node(
1156 cx,
1157 owner,
1158 f.name.as_str(),
1159 size_and_align_of(field_layout),
1160 Size::ZERO,
1161 DIFlags::FlagZero,
1162 type_di_node(cx, field_layout.ty),
1163 )
1164 })
1165 .collect()
1166 },
1167 // Generics:
1168 |cx| build_generic_type_param_di_nodes(cx, union_type),
9e0c209e
SL
1169 )
1170}
1a4d82fc 1171
60c5eb7d 1172/// Computes the type parameters for a type, if any, for the given metadata.
5e7ed085
FG
1173fn build_generic_type_param_di_nodes<'ll, 'tcx>(
1174 cx: &CodegenCx<'ll, 'tcx>,
1175 ty: Ty<'tcx>,
1176) -> SmallVec<&'ll DIType> {
1b1a35ee 1177 if let ty::Adt(def, substs) = *ty.kind() {
74b04a01 1178 if substs.types().next().is_some() {
5e7ed085 1179 let generics = cx.tcx.generics_of(def.did());
a1dfa0c6 1180 let names = get_parameter_names(cx, generics);
5e7ed085 1181 let template_params: SmallVec<_> = iter::zip(substs, names)
dfeec247 1182 .filter_map(|(kind, name)| {
49aad941 1183 kind.as_type().map(|ty| {
dfeec247
XL
1184 let actual_type =
1185 cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
5e7ed085 1186 let actual_type_di_node = type_di_node(cx, actual_type);
a2a8927a 1187 let name = name.as_str();
49aad941 1188 unsafe {
5e7ed085 1189 llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
dfeec247
XL
1190 DIB(cx),
1191 None,
74b04a01
XL
1192 name.as_ptr().cast(),
1193 name.len(),
5e7ed085
FG
1194 actual_type_di_node,
1195 )
49aad941
FG
1196 }
1197 })
dfeec247
XL
1198 })
1199 .collect();
a1dfa0c6 1200
5e7ed085 1201 return template_params;
a1dfa0c6
XL
1202 }
1203 }
5e7ed085
FG
1204
1205 return smallvec![];
a1dfa0c6 1206
dfeec247
XL
1207 fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) -> Vec<Symbol> {
1208 let mut names = generics
1209 .parent
6a06907d 1210 .map_or_else(Vec::new, |def_id| get_parameter_names(cx, cx.tcx.generics_of(def_id)));
a1dfa0c6
XL
1211 names.extend(generics.params.iter().map(|param| param.name));
1212 names
d9579d0f
AL
1213 }
1214}
1a4d82fc 1215
d9579d0f
AL
1216/// Creates debug information for the given global variable.
1217///
5e7ed085
FG
1218/// Adds the created debuginfo nodes directly to the crate's IR.
1219pub fn build_global_var_di_node<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId, global: &'ll Value) {
2c00a5a8 1220 if cx.dbg_cx.is_none() {
d9579d0f
AL
1221 return;
1222 }
1a4d82fc 1223
ba9703b0
XL
1224 // Only create type information if full debuginfo is enabled
1225 if cx.sess().opts.debuginfo != DebugInfo::Full {
1226 return;
1227 }
1228
2c00a5a8 1229 let tcx = cx.tcx;
0531ce1d 1230
60c5eb7d
XL
1231 // We may want to remove the namespace scope if we're in an extern block (see
1232 // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952).
0531ce1d
XL
1233 let var_scope = get_namespace_for_item(cx, def_id);
1234 let span = tcx.def_span(def_id);
1a4d82fc 1235
8faf50e0 1236 let (file_metadata, line_number) = if !span.is_dummy() {
ba9703b0 1237 let loc = cx.lookup_debug_loc(span.lo());
29967ef6 1238 (file_metadata(cx, &loc.file), loc.line)
d9579d0f 1239 } else {
6a06907d 1240 (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
d9579d0f 1241 };
1a4d82fc 1242
0531ce1d 1243 let is_local_to_unit = is_node_local_to_unit(cx, def_id);
3dfed10e 1244 let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, ty::ParamEnv::reveal_all());
5e7ed085 1245 let type_di_node = type_di_node(cx, variable_type);
a2a8927a
XL
1246 let var_name = tcx.item_name(def_id);
1247 let var_name = var_name.as_str();
3dfed10e 1248 let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id)).name;
74b04a01
XL
1249 // When empty, linkage_name field is omitted,
1250 // which is what we want for no_mangle statics
f035d41b 1251 let linkage_name = if var_name == linkage_name { "" } else { linkage_name };
476ff2be 1252
cc61c64b 1253 let global_align = cx.align_of(variable_type);
476ff2be 1254
d9579d0f 1255 unsafe {
dfeec247
XL
1256 llvm::LLVMRustDIBuilderCreateStaticVariable(
1257 DIB(cx),
1258 Some(var_scope),
74b04a01
XL
1259 var_name.as_ptr().cast(),
1260 var_name.len(),
1261 linkage_name.as_ptr().cast(),
1262 linkage_name.len(),
dfeec247 1263 file_metadata,
6a06907d 1264 line_number,
5e7ed085 1265 type_di_node,
dfeec247
XL
1266 is_local_to_unit,
1267 global,
1268 None,
923072b8 1269 global_align.bits() as u32,
476ff2be 1270 );
d9579d0f
AL
1271 }
1272}
1a4d82fc 1273
c295e0f8 1274/// Generates LLVM debuginfo for a vtable.
5099ac24
FG
1275///
1276/// The vtable type looks like a struct with a field for each function pointer and super-trait
1277/// pointer it contains (plus the `size` and `align` fields).
1278///
1279/// Except for `size`, `align`, and `drop_in_place`, the field names don't try to mirror
1280/// the name of the method they implement. This can be implemented in the future once there
1281/// is a proper disambiguation scheme for dealing with methods from different traits that have
1282/// the same name.
5e7ed085 1283fn build_vtable_type_di_node<'ll, 'tcx>(
c295e0f8
XL
1284 cx: &CodegenCx<'ll, 'tcx>,
1285 ty: Ty<'tcx>,
1286 poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
1287) -> &'ll DIType {
1288 let tcx = cx.tcx;
1289
1290 let vtable_entries = if let Some(poly_trait_ref) = poly_trait_ref {
1291 let trait_ref = poly_trait_ref.with_self_ty(tcx, ty);
1292 let trait_ref = tcx.erase_regions(trait_ref);
1293
1294 tcx.vtable_entries(trait_ref)
1295 } else {
923072b8 1296 TyCtxt::COMMON_VTABLE_ENTRIES
c295e0f8
XL
1297 };
1298
5099ac24
FG
1299 // All function pointers are described as opaque pointers. This could be improved in the future
1300 // by describing them as actual function pointers.
1301 let void_pointer_ty = tcx.mk_imm_ptr(tcx.types.unit);
5e7ed085
FG
1302 let void_pointer_type_di_node = type_di_node(cx, void_pointer_ty);
1303 let usize_di_node = type_di_node(cx, tcx.types.usize);
5099ac24
FG
1304 let (pointer_size, pointer_align) = cx.size_and_align_of(void_pointer_ty);
1305 // If `usize` is not pointer-sized and -aligned then the size and alignment computations
1306 // for the vtable as a whole would be wrong. Let's make sure this holds even on weird
1307 // platforms.
1308 assert_eq!(cx.size_and_align_of(tcx.types.usize), (pointer_size, pointer_align));
1309
1310 let vtable_type_name =
1311 compute_debuginfo_vtable_name(cx.tcx, ty, poly_trait_ref, VTableNameKind::Type);
5e7ed085 1312 let unique_type_id = UniqueTypeId::for_vtable_ty(tcx, ty, poly_trait_ref);
5099ac24
FG
1313 let size = pointer_size * vtable_entries.len() as u64;
1314
1315 // This gets mapped to a DW_AT_containing_type attribute which allows GDB to correlate
1316 // the vtable to the type it is for.
5e7ed085 1317 let vtable_holder = type_di_node(cx, ty);
5099ac24 1318
5e7ed085 1319 build_type_with_children(
5099ac24 1320 cx,
5e7ed085
FG
1321 type_map::stub(
1322 cx,
064997fb 1323 Stub::VTableTy { vtable_holder },
5e7ed085
FG
1324 unique_type_id,
1325 &vtable_type_name,
1326 (size, pointer_align),
1327 NO_SCOPE_METADATA,
1328 DIFlags::FlagArtificial,
1329 ),
1330 |cx, vtable_type_di_node| {
1331 vtable_entries
1332 .iter()
1333 .enumerate()
1334 .filter_map(|(index, vtable_entry)| {
1335 let (field_name, field_type_di_node) = match vtable_entry {
1336 ty::VtblEntry::MetadataDropInPlace => {
1337 ("drop_in_place".to_string(), void_pointer_type_di_node)
1338 }
1339 ty::VtblEntry::Method(_) => {
1340 // Note: This code does not try to give a proper name to each method
1341 // because their might be multiple methods with the same name
1342 // (coming from different traits).
1343 (format!("__method{}", index), void_pointer_type_di_node)
1344 }
1345 ty::VtblEntry::TraitVPtr(_) => {
1346 (format!("__super_trait_ptr{}", index), void_pointer_type_di_node)
1347 }
1348 ty::VtblEntry::MetadataAlign => ("align".to_string(), usize_di_node),
1349 ty::VtblEntry::MetadataSize => ("size".to_string(), usize_di_node),
1350 ty::VtblEntry::Vacant => return None,
1351 };
5099ac24 1352
5e7ed085 1353 let field_offset = pointer_size * index as u64;
c295e0f8 1354
5e7ed085
FG
1355 Some(build_field_di_node(
1356 cx,
1357 vtable_type_di_node,
1358 &field_name,
1359 (pointer_size, pointer_align),
1360 field_offset,
1361 DIFlags::FlagZero,
1362 field_type_di_node,
1363 ))
1364 })
1365 .collect()
1366 },
1367 NO_GENERICS,
1368 )
1369 .di_node
c295e0f8
XL
1370}
1371
923072b8
FG
1372fn vcall_visibility_metadata<'ll, 'tcx>(
1373 cx: &CodegenCx<'ll, 'tcx>,
1374 ty: Ty<'tcx>,
1375 trait_ref: Option<PolyExistentialTraitRef<'tcx>>,
1376 vtable: &'ll Value,
1377) {
1378 enum VCallVisibility {
1379 Public = 0,
1380 LinkageUnit = 1,
1381 TranslationUnit = 2,
1382 }
1383
1384 let Some(trait_ref) = trait_ref else { return };
1385
1386 let trait_ref_self = trait_ref.with_self_ty(cx.tcx, ty);
1387 let trait_ref_self = cx.tcx.erase_regions(trait_ref_self);
1388 let trait_def_id = trait_ref_self.def_id();
1389 let trait_vis = cx.tcx.visibility(trait_def_id);
1390
1391 let cgus = cx.sess().codegen_units();
1392 let single_cgu = cgus == 1;
1393
1394 let lto = cx.sess().lto();
1395
1396 // Since LLVM requires full LTO for the virtual function elimination optimization to apply,
1397 // only the `Lto::Fat` cases are relevant currently.
1398 let vcall_visibility = match (lto, trait_vis, single_cgu) {
1399 // If there is not LTO and the visibility in public, we have to assume that the vtable can
1400 // be seen from anywhere. With multiple CGUs, the vtable is quasi-public.
1401 (Lto::No | Lto::ThinLocal, Visibility::Public, _)
f2b60f7d 1402 | (Lto::No, Visibility::Restricted(_), false) => VCallVisibility::Public,
923072b8
FG
1403 // With LTO and a quasi-public visibility, the usages of the functions of the vtable are
1404 // all known by the `LinkageUnit`.
1405 // FIXME: LLVM only supports this optimization for `Lto::Fat` currently. Once it also
1406 // supports `Lto::Thin` the `VCallVisibility` may have to be adjusted for those.
1407 (Lto::Fat | Lto::Thin, Visibility::Public, _)
f2b60f7d
FG
1408 | (Lto::ThinLocal | Lto::Thin | Lto::Fat, Visibility::Restricted(_), false) => {
1409 VCallVisibility::LinkageUnit
1410 }
923072b8
FG
1411 // If there is only one CGU, private vtables can only be seen by that CGU/translation unit
1412 // and therefore we know of all usages of functions in the vtable.
f2b60f7d 1413 (_, Visibility::Restricted(_), true) => VCallVisibility::TranslationUnit,
923072b8
FG
1414 };
1415
1416 let trait_ref_typeid = typeid_for_trait_ref(cx.tcx, trait_ref);
1417
1418 unsafe {
1419 let typeid = llvm::LLVMMDStringInContext(
1420 cx.llcx,
1421 trait_ref_typeid.as_ptr() as *const c_char,
1422 trait_ref_typeid.as_bytes().len() as c_uint,
1423 );
1424 let v = [cx.const_usize(0), typeid];
1425 llvm::LLVMRustGlobalAddMetadata(
1426 vtable,
1427 llvm::MD_type as c_uint,
1428 llvm::LLVMValueAsMetadata(llvm::LLVMMDNodeInContext(
1429 cx.llcx,
1430 v.as_ptr(),
1431 v.len() as c_uint,
1432 )),
1433 );
1434 let vcall_visibility = llvm::LLVMValueAsMetadata(cx.const_u64(vcall_visibility as u64));
1435 let vcall_visibility_metadata = llvm::LLVMMDNodeInContext2(cx.llcx, &vcall_visibility, 1);
1436 llvm::LLVMGlobalSetMetadata(
1437 vtable,
1438 llvm::MetadataType::MD_vcall_visibility as c_uint,
1439 vcall_visibility_metadata,
1440 );
1441 }
1442}
1443
abe05a73
XL
1444/// Creates debug information for the given vtable, which is for the
1445/// given type.
1446///
1447/// Adds the created metadata nodes directly to the crate's IR.
5e7ed085 1448pub fn create_vtable_di_node<'ll, 'tcx>(
c295e0f8
XL
1449 cx: &CodegenCx<'ll, 'tcx>,
1450 ty: Ty<'tcx>,
1451 poly_trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
1452 vtable: &'ll Value,
1453) {
923072b8
FG
1454 // FIXME(flip1995): The virtual function elimination optimization only works with full LTO in
1455 // LLVM at the moment.
064997fb 1456 if cx.sess().opts.unstable_opts.virtual_function_elimination && cx.sess().lto() == Lto::Fat {
923072b8
FG
1457 vcall_visibility_metadata(cx, ty, poly_trait_ref, vtable);
1458 }
1459
2c00a5a8 1460 if cx.dbg_cx.is_none() {
abe05a73
XL
1461 return;
1462 }
1463
ba9703b0
XL
1464 // Only create type information if full debuginfo is enabled
1465 if cx.sess().opts.debuginfo != DebugInfo::Full {
1466 return;
1467 }
1468
9ffffee4
FG
1469 // When full debuginfo is enabled, we want to try and prevent vtables from being
1470 // merged. Otherwise debuggers will have a hard time mapping from dyn pointer
1471 // to concrete type.
1472 llvm::SetUnnamedAddress(vtable, llvm::UnnamedAddr::No);
1473
5099ac24
FG
1474 let vtable_name =
1475 compute_debuginfo_vtable_name(cx.tcx, ty, poly_trait_ref, VTableNameKind::GlobalVariable);
5e7ed085 1476 let vtable_type_di_node = build_vtable_type_di_node(cx, ty, poly_trait_ref);
5099ac24 1477 let linkage_name = "";
abe05a73
XL
1478
1479 unsafe {
dfeec247
XL
1480 llvm::LLVMRustDIBuilderCreateStaticVariable(
1481 DIB(cx),
1482 NO_SCOPE_METADATA,
c295e0f8
XL
1483 vtable_name.as_ptr().cast(),
1484 vtable_name.len(),
74b04a01
XL
1485 linkage_name.as_ptr().cast(),
1486 linkage_name.len(),
dfeec247
XL
1487 unknown_file_metadata(cx),
1488 UNKNOWN_LINE_NUMBER,
5e7ed085 1489 vtable_type_di_node,
dfeec247
XL
1490 true,
1491 vtable,
1492 None,
1493 0,
1494 );
abe05a73
XL
1495 }
1496}
a1dfa0c6 1497
60c5eb7d 1498/// Creates an "extension" of an existing `DIScope` into another file.
a2a8927a 1499pub fn extend_scope_to_file<'ll>(
a1dfa0c6
XL
1500 cx: &CodegenCx<'ll, '_>,
1501 scope_metadata: &'ll DIScope,
29967ef6 1502 file: &SourceFile,
a1dfa0c6 1503) -> &'ll DILexicalBlock {
29967ef6 1504 let file_metadata = file_metadata(cx, file);
dfeec247 1505 unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlockFile(DIB(cx), scope_metadata, file_metadata) }
a1dfa0c6 1506}
5e7ed085
FG
1507
1508pub fn tuple_field_name(field_index: usize) -> Cow<'static, str> {
1509 const TUPLE_FIELD_NAMES: [&'static str; 16] = [
1510 "__0", "__1", "__2", "__3", "__4", "__5", "__6", "__7", "__8", "__9", "__10", "__11",
1511 "__12", "__13", "__14", "__15",
1512 ];
1513 TUPLE_FIELD_NAMES
1514 .get(field_index)
1515 .map(|s| Cow::from(*s))
1516 .unwrap_or_else(|| Cow::from(format!("__{}", field_index)))
1517}