1 use self::RecursiveTypeDescription
::*;
2 use self::MemberDescriptionFactory
::*;
3 use self::EnumDiscriminantInfo
::*;
5 use super::utils
::{debug_context
, DIB
, span_start
,
6 get_namespace_for_item
, create_DIArray
, is_node_local_to_unit
};
7 use super::namespace
::mangled_name_of_instance
;
8 use super::type_names
::compute_debuginfo_type_name
;
9 use super::CrateDebugContext
;
12 use crate::common
::CodegenCx
;
14 use crate::llvm
::debuginfo
::{DIArray
, DIType
, DIFile
, DIScope
, DIDescriptor
,
15 DICompositeType
, DILexicalBlock
, DIFlags
, DebugEmissionKind
};
17 use crate::value
::Value
;
19 use rustc_codegen_ssa
::traits
::*;
20 use rustc_index
::vec
::{Idx, IndexVec}
;
21 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher}
;
22 use rustc
::hir
::CodegenFnAttrFlags
;
23 use rustc
::hir
::def
::CtorKind
;
24 use rustc
::hir
::def_id
::{DefId, CrateNum, LOCAL_CRATE}
;
25 use rustc
::ich
::NodeIdHashingMode
;
26 use rustc
::mir
::{self, Field, GeneratorLayout}
;
27 use rustc
::mir
::interpret
::truncate
;
28 use rustc_data_structures
::fingerprint
::Fingerprint
;
29 use rustc
::ty
::Instance
;
30 use rustc
::ty
::{self, AdtKind, ParamEnv, Ty, TyCtxt}
;
31 use rustc
::ty
::layout
::{self, Align
, Integer
, IntegerExt
, LayoutOf
,
32 PrimitiveExt
, Size
, TyLayout
, VariantIdx
};
33 use rustc
::ty
::subst
::{GenericArgKind, SubstsRef}
;
34 use rustc
::session
::config
::{self, DebugInfo}
;
35 use rustc
::util
::nodemap
::FxHashMap
;
36 use rustc_fs_util
::path_to_c_string
;
37 use rustc_data_structures
::small_c_str
::SmallCStr
;
38 use rustc_data_structures
::const_cstr
;
39 use rustc_target
::abi
::HasDataLayout
;
41 use syntax
::symbol
::{Interner, Symbol}
;
42 use syntax_pos
::{self, Span, FileName}
;
43 use rustc
::{bug, span_bug}
;
46 use libc
::{c_uint, c_longlong}
;
47 use std
::collections
::hash_map
::Entry
;
48 use std
::ffi
::CString
;
49 use std
::fmt
::{self, Write}
;
50 use std
::hash
::{Hash, Hasher}
;
53 use std
::path
::{Path, PathBuf}
;
55 impl PartialEq
for llvm
::Metadata
{
56 fn eq(&self, other
: &Self) -> bool
{
61 impl Eq
for llvm
::Metadata {}
63 impl Hash
for llvm
::Metadata
{
64 fn hash
<H
: Hasher
>(&self, hasher
: &mut H
) {
65 (self as *const Self).hash(hasher
);
69 impl fmt
::Debug
for llvm
::Metadata
{
70 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
71 (self as *const Self).fmt(f
)
76 // See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1.
77 const DW_LANG_RUST
: c_uint
= 0x1c;
78 #[allow(non_upper_case_globals)]
79 const DW_ATE_boolean
: c_uint
= 0x02;
80 #[allow(non_upper_case_globals)]
81 const DW_ATE_float
: c_uint
= 0x04;
82 #[allow(non_upper_case_globals)]
83 const DW_ATE_signed
: c_uint
= 0x05;
84 #[allow(non_upper_case_globals)]
85 const DW_ATE_unsigned
: c_uint
= 0x07;
86 #[allow(non_upper_case_globals)]
87 const DW_ATE_unsigned_char
: c_uint
= 0x08;
89 pub const UNKNOWN_LINE_NUMBER
: c_uint
= 0;
90 pub const UNKNOWN_COLUMN_NUMBER
: c_uint
= 0;
92 pub const NO_SCOPE_METADATA
: Option
<&DIScope
> = None
;
94 #[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
95 pub struct UniqueTypeId(ast
::Name
);
97 /// The `TypeMap` is where the `CrateDebugContext` holds the type metadata nodes
98 /// created so far. The metadata nodes are indexed by `UniqueTypeId`, and, for
99 /// faster lookup, also by `Ty`. The `TypeMap` is responsible for creating
102 pub struct TypeMap
<'ll
, 'tcx
> {
103 /// The `UniqueTypeId`s created so far.
104 unique_id_interner
: Interner
,
105 /// A map from `UniqueTypeId` to debuginfo metadata for that type. This is a 1:1 mapping.
106 unique_id_to_metadata
: FxHashMap
<UniqueTypeId
, &'ll DIType
>,
107 /// A map from types to debuginfo metadata. This is an N:1 mapping.
108 type_to_metadata
: FxHashMap
<Ty
<'tcx
>, &'ll DIType
>,
109 /// A map from types to `UniqueTypeId`. This is an N:1 mapping.
110 type_to_unique_id
: FxHashMap
<Ty
<'tcx
>, UniqueTypeId
>
113 impl TypeMap
<'ll
, 'tcx
> {
114 /// Adds a Ty to metadata mapping to the TypeMap. The method will fail if
115 /// the mapping already exists.
116 fn register_type_with_metadata(
119 metadata
: &'ll DIType
,
121 if self.type_to_metadata
.insert(type_
, metadata
).is_some() {
122 bug
!("type metadata for `Ty` '{}' is already in the `TypeMap`!", type_
);
126 /// Removes a `Ty`-to-metadata mapping.
127 /// This is useful when computing the metadata for a potentially
128 /// recursive type (e.g., a function pointer of the form:
130 /// fn foo() -> impl Copy { foo }
132 /// This kind of type cannot be properly represented
133 /// via LLVM debuginfo. As a workaround,
134 /// we register a temporary Ty to metadata mapping
135 /// for the function before we compute its actual metadata.
136 /// If the metadata computation ends up recursing back to the
137 /// original function, it will use the temporary mapping
138 /// for the inner self-reference, preventing us from
139 /// recursing forever.
141 /// This function is used to remove the temporary metadata
142 /// mapping after we've computed the actual metadata.
147 if self.type_to_metadata
.remove(type_
).is_none() {
148 bug
!("type metadata `Ty` '{}' is not in the `TypeMap`!", type_
);
152 /// Adds a `UniqueTypeId` to metadata mapping to the `TypeMap`. The method will
153 /// fail if the mapping already exists.
154 fn register_unique_id_with_metadata(
156 unique_type_id
: UniqueTypeId
,
157 metadata
: &'ll DIType
,
159 if self.unique_id_to_metadata
.insert(unique_type_id
, metadata
).is_some() {
160 bug
!("type metadata for unique ID '{}' is already in the `TypeMap`!",
161 self.get_unique_type_id_as_string(unique_type_id
));
165 fn find_metadata_for_type(&self, type_
: Ty
<'tcx
>) -> Option
<&'ll DIType
> {
166 self.type_to_metadata
.get(&type_
).cloned()
169 fn find_metadata_for_unique_id(&self, unique_type_id
: UniqueTypeId
) -> Option
<&'ll DIType
> {
170 self.unique_id_to_metadata
.get(&unique_type_id
).cloned()
173 /// Gets the string representation of a `UniqueTypeId`. This method will fail if
174 /// the ID is unknown.
175 fn get_unique_type_id_as_string(&self, unique_type_id
: UniqueTypeId
) -> &str {
176 let UniqueTypeId(interner_key
) = unique_type_id
;
177 self.unique_id_interner
.get(interner_key
)
180 /// Gets the `UniqueTypeId` for the given type. If the `UniqueTypeId` for the given
181 /// type has been requested before, this is just a table lookup. Otherwise, an
182 /// ID will be generated and stored for later lookup.
183 fn get_unique_type_id_of_type
<'a
>(&mut self, cx
: &CodegenCx
<'a
, 'tcx
>,
184 type_
: Ty
<'tcx
>) -> UniqueTypeId
{
185 // Let's see if we already have something in the cache.
186 if let Some(unique_type_id
) = self.type_to_unique_id
.get(&type_
).cloned() {
187 return unique_type_id
;
189 // If not, generate one.
191 // The hasher we are using to generate the UniqueTypeId. We want
192 // something that provides more than the 64 bits of the DefaultHasher.
193 let mut hasher
= StableHasher
::new();
194 let mut hcx
= cx
.tcx
.create_stable_hashing_context();
195 let type_
= cx
.tcx
.erase_regions(&type_
);
196 hcx
.while_hashing_spans(false, |hcx
| {
197 hcx
.with_node_id_hashing_mode(NodeIdHashingMode
::HashDefPath
, |hcx
| {
198 type_
.hash_stable(hcx
, &mut hasher
);
201 let unique_type_id
= hasher
.finish
::<Fingerprint
>().to_hex();
203 let key
= self.unique_id_interner
.intern(&unique_type_id
);
204 self.type_to_unique_id
.insert(type_
, UniqueTypeId(key
));
206 return UniqueTypeId(key
);
209 /// Gets the `UniqueTypeId` for an enum variant. Enum variants are not really
210 /// types of their own, so they need special handling. We still need a
211 /// `UniqueTypeId` for them, since to debuginfo they *are* real types.
212 fn get_unique_type_id_of_enum_variant
<'a
>(&mut self,
213 cx
: &CodegenCx
<'a
, 'tcx
>,
217 let enum_type_id
= self.get_unique_type_id_of_type(cx
, enum_type
);
218 let enum_variant_type_id
= format
!("{}::{}",
219 self.get_unique_type_id_as_string(enum_type_id
),
221 let interner_key
= self.unique_id_interner
.intern(&enum_variant_type_id
);
222 UniqueTypeId(interner_key
)
225 /// Gets the unique type ID string for an enum variant part.
226 /// Variant parts are not types and shouldn't really have their own ID,
227 /// but it makes `set_members_of_composite_type()` simpler.
228 fn get_unique_type_id_str_of_enum_variant_part(&mut self, enum_type_id
: UniqueTypeId
) -> &str {
229 let variant_part_type_id
= format
!("{}_variant_part",
230 self.get_unique_type_id_as_string(enum_type_id
));
231 let interner_key
= self.unique_id_interner
.intern(&variant_part_type_id
);
232 self.unique_id_interner
.get(interner_key
)
236 /// A description of some recursive type. It can either be already finished (as
237 /// with `FinalMetadata`) or it is not yet finished, but contains all information
238 /// needed to generate the missing parts of the description. See the
239 /// documentation section on Recursive Types at the top of this file for more
241 enum RecursiveTypeDescription
<'ll
, 'tcx
> {
243 unfinished_type
: Ty
<'tcx
>,
244 unique_type_id
: UniqueTypeId
,
245 metadata_stub
: &'ll DICompositeType
,
246 member_holding_stub
: &'ll DICompositeType
,
247 member_description_factory
: MemberDescriptionFactory
<'ll
, 'tcx
>,
249 FinalMetadata(&'ll DICompositeType
)
252 fn create_and_register_recursive_type_forward_declaration(
253 cx
: &CodegenCx
<'ll
, 'tcx
>,
254 unfinished_type
: Ty
<'tcx
>,
255 unique_type_id
: UniqueTypeId
,
256 metadata_stub
: &'ll DICompositeType
,
257 member_holding_stub
: &'ll DICompositeType
,
258 member_description_factory
: MemberDescriptionFactory
<'ll
, 'tcx
>,
259 ) -> RecursiveTypeDescription
<'ll
, 'tcx
> {
261 // Insert the stub into the `TypeMap` in order to allow for recursive references.
262 let mut type_map
= debug_context(cx
).type_map
.borrow_mut();
263 type_map
.register_unique_id_with_metadata(unique_type_id
, metadata_stub
);
264 type_map
.register_type_with_metadata(unfinished_type
, metadata_stub
);
271 member_description_factory
,
275 impl RecursiveTypeDescription
<'ll
, 'tcx
> {
276 /// Finishes up the description of the type in question (mostly by providing
277 /// descriptions of the fields of the given type) and returns the final type
279 fn finalize(&self, cx
: &CodegenCx
<'ll
, 'tcx
>) -> MetadataCreationResult
<'ll
> {
281 FinalMetadata(metadata
) => MetadataCreationResult
::new(metadata
, false),
287 ref member_description_factory
,
289 // Make sure that we have a forward declaration of the type in
290 // the TypeMap so that recursive references are possible. This
291 // will always be the case if the RecursiveTypeDescription has
292 // been properly created through the
293 // `create_and_register_recursive_type_forward_declaration()`
296 let type_map
= debug_context(cx
).type_map
.borrow();
297 if type_map
.find_metadata_for_unique_id(unique_type_id
).is_none() ||
298 type_map
.find_metadata_for_type(unfinished_type
).is_none() {
299 bug
!("Forward declaration of potentially recursive type \
300 '{:?}' was not found in TypeMap!",
305 // ... then create the member descriptions ...
306 let member_descriptions
=
307 member_description_factory
.create_member_descriptions(cx
);
309 // ... and attach them to the stub to complete it.
310 set_members_of_composite_type(cx
,
313 member_descriptions
);
314 return MetadataCreationResult
::new(metadata_stub
, true);
320 /// Returns from the enclosing function if the type metadata with the given
321 /// unique ID can be found in the type map.
322 macro_rules
! return_if_metadata_created_in_meantime
{
323 ($cx
: expr
, $unique_type_id
: expr
) => (
324 if let Some(metadata
) = debug_context($cx
).type_map
326 .find_metadata_for_unique_id($unique_type_id
)
328 return MetadataCreationResult
::new(metadata
, true);
333 fn fixed_vec_metadata(
334 cx
: &CodegenCx
<'ll
, 'tcx
>,
335 unique_type_id
: UniqueTypeId
,
336 array_or_slice_type
: Ty
<'tcx
>,
337 element_type
: Ty
<'tcx
>,
339 ) -> MetadataCreationResult
<'ll
> {
340 let element_type_metadata
= type_metadata(cx
, element_type
, span
);
342 return_if_metadata_created_in_meantime
!(cx
, unique_type_id
);
344 let (size
, align
) = cx
.size_and_align_of(array_or_slice_type
);
346 let upper_bound
= match array_or_slice_type
.kind
{
347 ty
::Array(_
, len
) => len
.eval_usize(cx
.tcx
, ty
::ParamEnv
::reveal_all()) as c_longlong
,
351 let subrange
= unsafe {
352 Some(llvm
::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx
), 0, upper_bound
))
355 let subscripts
= create_DIArray(DIB(cx
), &[subrange
]);
356 let metadata
= unsafe {
357 llvm
::LLVMRustDIBuilderCreateArrayType(
361 element_type_metadata
,
365 return MetadataCreationResult
::new(metadata
, false);
368 fn vec_slice_metadata(
369 cx
: &CodegenCx
<'ll
, 'tcx
>,
370 slice_ptr_type
: Ty
<'tcx
>,
371 element_type
: Ty
<'tcx
>,
372 unique_type_id
: UniqueTypeId
,
374 ) -> MetadataCreationResult
<'ll
> {
375 let data_ptr_type
= cx
.tcx
.mk_imm_ptr(element_type
);
377 let data_ptr_metadata
= type_metadata(cx
, data_ptr_type
, span
);
379 return_if_metadata_created_in_meantime
!(cx
, unique_type_id
);
381 let slice_type_name
= compute_debuginfo_type_name(cx
.tcx
, slice_ptr_type
, true);
383 let (pointer_size
, pointer_align
) = cx
.size_and_align_of(data_ptr_type
);
384 let (usize_size
, usize_align
) = cx
.size_and_align_of(cx
.tcx
.types
.usize);
386 let member_descriptions
= vec
![
388 name
: "data_ptr".to_owned(),
389 type_metadata
: data_ptr_metadata
,
392 align
: pointer_align
,
393 flags
: DIFlags
::FlagZero
,
397 name
: "length".to_owned(),
398 type_metadata
: type_metadata(cx
, cx
.tcx
.types
.usize, span
),
399 offset
: pointer_size
,
402 flags
: DIFlags
::FlagZero
,
407 let file_metadata
= unknown_file_metadata(cx
);
409 let metadata
= composite_type_metadata(cx
,
411 &slice_type_name
[..],
417 MetadataCreationResult
::new(metadata
, false)
420 fn subroutine_type_metadata(
421 cx
: &CodegenCx
<'ll
, 'tcx
>,
422 unique_type_id
: UniqueTypeId
,
423 signature
: ty
::PolyFnSig
<'tcx
>,
425 ) -> MetadataCreationResult
<'ll
> {
426 let signature
= cx
.tcx
.normalize_erasing_late_bound_regions(
427 ty
::ParamEnv
::reveal_all(),
431 let signature_metadata
: Vec
<_
> = iter
::once(
433 match signature
.output().kind
{
434 ty
::Tuple(ref tys
) if tys
.is_empty() => None
,
435 _
=> Some(type_metadata(cx
, signature
.output(), span
))
439 signature
.inputs().iter().map(|argument_type
| {
440 Some(type_metadata(cx
, argument_type
, span
))
444 return_if_metadata_created_in_meantime
!(cx
, unique_type_id
);
446 return MetadataCreationResult
::new(
448 llvm
::LLVMRustDIBuilderCreateSubroutineType(
450 unknown_file_metadata(cx
),
451 create_DIArray(DIB(cx
), &signature_metadata
[..]))
456 // FIXME(1563): This is all a bit of a hack because 'trait pointer' is an ill-
457 // defined concept. For the case of an actual trait pointer (i.e., `Box<Trait>`,
458 // `&Trait`), `trait_object_type` should be the whole thing (e.g, `Box<Trait>`) and
459 // `trait_type` should be the actual trait (e.g., `Trait`). Where the trait is part
460 // of a DST struct, there is no `trait_object_type` and the results of this
461 // function will be a little bit weird.
462 fn trait_pointer_metadata(
463 cx
: &CodegenCx
<'ll
, 'tcx
>,
464 trait_type
: Ty
<'tcx
>,
465 trait_object_type
: Option
<Ty
<'tcx
>>,
466 unique_type_id
: UniqueTypeId
,
468 // The implementation provided here is a stub. It makes sure that the trait
469 // type is assigned the correct name, size, namespace, and source location.
470 // However, it does not describe the trait's methods.
472 let containing_scope
= match trait_type
.kind
{
473 ty
::Dynamic(ref data
, ..) =>
474 data
.principal_def_id().map(|did
| get_namespace_for_item(cx
, did
)),
476 bug
!("debuginfo: unexpected trait-object type in \
477 trait_pointer_metadata(): {:?}",
482 let trait_object_type
= trait_object_type
.unwrap_or(trait_type
);
483 let trait_type_name
=
484 compute_debuginfo_type_name(cx
.tcx
, trait_object_type
, false);
486 let file_metadata
= unknown_file_metadata(cx
);
488 let layout
= cx
.layout_of(cx
.tcx
.mk_mut_ptr(trait_type
));
490 assert_eq
!(abi
::FAT_PTR_ADDR
, 0);
491 assert_eq
!(abi
::FAT_PTR_EXTRA
, 1);
493 let data_ptr_field
= layout
.field(cx
, 0);
494 let vtable_field
= layout
.field(cx
, 1);
495 let member_descriptions
= vec
![
497 name
: "pointer".to_owned(),
498 type_metadata
: type_metadata(cx
,
499 cx
.tcx
.mk_mut_ptr(cx
.tcx
.types
.u8),
500 syntax_pos
::DUMMY_SP
),
501 offset
: layout
.fields
.offset(0),
502 size
: data_ptr_field
.size
,
503 align
: data_ptr_field
.align
.abi
,
504 flags
: DIFlags
::FlagArtificial
,
508 name
: "vtable".to_owned(),
509 type_metadata
: type_metadata(cx
, vtable_field
.ty
, syntax_pos
::DUMMY_SP
),
510 offset
: layout
.fields
.offset(1),
511 size
: vtable_field
.size
,
512 align
: vtable_field
.align
.abi
,
513 flags
: DIFlags
::FlagArtificial
,
518 composite_type_metadata(cx
,
520 &trait_type_name
[..],
525 syntax_pos
::DUMMY_SP
)
528 pub fn type_metadata(
529 cx
: &CodegenCx
<'ll
, 'tcx
>,
531 usage_site_span
: Span
,
533 // Get the unique type ID of this type.
534 let unique_type_id
= {
535 let mut type_map
= debug_context(cx
).type_map
.borrow_mut();
536 // First, try to find the type in `TypeMap`. If we have seen it before, we
537 // can exit early here.
538 match type_map
.find_metadata_for_type(t
) {
543 // The Ty is not in the `TypeMap` but maybe we have already seen
544 // an equivalent type (e.g., only differing in region arguments).
545 // In order to find out, generate the unique type ID and look
547 let unique_type_id
= type_map
.get_unique_type_id_of_type(cx
, t
);
548 match type_map
.find_metadata_for_unique_id(unique_type_id
) {
550 // There is already an equivalent type in the TypeMap.
551 // Register this Ty as an alias in the cache and
552 // return the cached metadata.
553 type_map
.register_type_with_metadata(t
, metadata
);
557 // There really is no type metadata for this type, so
558 // proceed by creating it.
566 debug
!("type_metadata: {:?}", t
);
568 let ptr_metadata
= |ty
: Ty
<'tcx
>| {
571 Ok(vec_slice_metadata(cx
, t
, typ
, unique_type_id
, usage_site_span
))
574 Ok(vec_slice_metadata(cx
, t
, cx
.tcx
.types
.u8, unique_type_id
, usage_site_span
))
577 Ok(MetadataCreationResult
::new(
578 trait_pointer_metadata(cx
, ty
, Some(t
), unique_type_id
),
582 let pointee_metadata
= type_metadata(cx
, ty
, usage_site_span
);
584 if let Some(metadata
) = debug_context(cx
).type_map
586 .find_metadata_for_unique_id(unique_type_id
)
588 return Err(metadata
);
591 Ok(MetadataCreationResult
::new(pointer_type_metadata(cx
, t
, pointee_metadata
),
597 let MetadataCreationResult { metadata, already_stored_in_typemap }
= match t
.kind
{
604 MetadataCreationResult
::new(basic_type_metadata(cx
, t
), false)
606 ty
::Tuple(ref elements
) if elements
.is_empty() => {
607 MetadataCreationResult
::new(basic_type_metadata(cx
, t
), false)
611 fixed_vec_metadata(cx
, unique_type_id
, t
, typ
, usage_site_span
)
614 fixed_vec_metadata(cx
, unique_type_id
, t
, cx
.tcx
.types
.i8, usage_site_span
)
617 MetadataCreationResult
::new(
618 trait_pointer_metadata(cx
, t
, None
, unique_type_id
),
622 MetadataCreationResult
::new(
623 foreign_type_metadata(cx
, t
, unique_type_id
),
626 ty
::RawPtr(ty
::TypeAndMut{ty, ..}
) |
627 ty
::Ref(_
, ty
, _
) => {
628 match ptr_metadata(ty
) {
630 Err(metadata
) => return metadata
,
633 ty
::Adt(def
, _
) if def
.is_box() => {
634 match ptr_metadata(t
.boxed_ty()) {
636 Err(metadata
) => return metadata
,
639 ty
::FnDef(..) | ty
::FnPtr(_
) => {
641 if let Some(metadata
) = debug_context(cx
).type_map
643 .find_metadata_for_unique_id(unique_type_id
)
648 // It's possible to create a self-referential
649 // type in Rust by using 'impl trait':
651 // fn foo() -> impl Copy { foo }
653 // See `TypeMap::remove_type` for more detals
654 // about the workaround.
658 // The choice of type here is pretty arbitrary -
659 // anything reading the debuginfo for a recursive
660 // type is going to see *somthing* weird - the only
661 // question is what exactly it will see.
662 let (size
, align
) = cx
.size_and_align_of(t
);
663 llvm
::LLVMRustDIBuilderCreateBasicType(
665 SmallCStr
::new("<recur_type>").as_ptr(),
672 let type_map
= &debug_context(cx
).type_map
;
673 type_map
.borrow_mut().register_type_with_metadata(t
, temp_type
);
675 let fn_metadata
= subroutine_type_metadata(cx
,
678 usage_site_span
).metadata
;
680 type_map
.borrow_mut().remove_type(t
);
683 // This is actually a function pointer, so wrap it in pointer DI.
684 MetadataCreationResult
::new(pointer_type_metadata(cx
, t
, fn_metadata
), false)
687 ty
::Closure(def_id
, substs
) => {
688 let upvar_tys
: Vec
<_
> = substs
.as_closure().upvar_tys(def_id
, cx
.tcx
).collect();
689 let containing_scope
= get_namespace_for_item(cx
, def_id
);
690 prepare_tuple_metadata(cx
,
695 Some(containing_scope
)).finalize(cx
)
697 ty
::Generator(def_id
, substs
, _
) => {
698 let upvar_tys
: Vec
<_
> = substs
699 .as_generator().prefix_tys(def_id
, cx
.tcx
).map(|t
| {
700 cx
.tcx
.normalize_erasing_regions(ParamEnv
::reveal_all(), t
)
702 prepare_enum_metadata(cx
,
707 upvar_tys
).finalize(cx
)
709 ty
::Adt(def
, ..) => match def
.adt_kind() {
711 prepare_struct_metadata(cx
,
714 usage_site_span
).finalize(cx
)
717 prepare_union_metadata(cx
,
720 usage_site_span
).finalize(cx
)
723 prepare_enum_metadata(cx
,
731 ty
::Tuple(ref elements
) => {
732 let tys
: Vec
<_
> = elements
.iter().map(|k
| k
.expect_ty()).collect();
733 prepare_tuple_metadata(cx
,
738 NO_SCOPE_METADATA
).finalize(cx
)
741 bug
!("debuginfo: unexpected type in type_metadata: {:?}", t
)
746 let mut type_map
= debug_context(cx
).type_map
.borrow_mut();
748 if already_stored_in_typemap
{
749 // Also make sure that we already have a `TypeMap` entry for the unique type ID.
750 let metadata_for_uid
= match type_map
.find_metadata_for_unique_id(unique_type_id
) {
751 Some(metadata
) => metadata
,
753 span_bug
!(usage_site_span
,
754 "expected type metadata for unique \
755 type ID '{}' to already be in \
756 the `debuginfo::TypeMap` but it \
758 type_map
.get_unique_type_id_as_string(unique_type_id
),
763 match type_map
.find_metadata_for_type(t
) {
765 if metadata
!= metadata_for_uid
{
766 span_bug
!(usage_site_span
,
767 "mismatch between `Ty` and \
768 `UniqueTypeId` maps in \
769 `debuginfo::TypeMap`. \
770 UniqueTypeId={}, Ty={}",
771 type_map
.get_unique_type_id_as_string(unique_type_id
),
776 type_map
.register_type_with_metadata(t
, metadata
);
780 type_map
.register_type_with_metadata(t
, metadata
);
781 type_map
.register_unique_id_with_metadata(unique_type_id
, metadata
);
788 pub fn file_metadata(cx
: &CodegenCx
<'ll
, '_
>,
789 file_name
: &FileName
,
790 defining_crate
: CrateNum
) -> &'ll DIFile
{
791 debug
!("file_metadata: file_name: {}, defining_crate: {}",
795 let file_name
= Some(file_name
.to_string());
796 let directory
= if defining_crate
== LOCAL_CRATE
{
797 Some(cx
.sess().working_dir
.0.to_string_lossy().to_string())
799 // If the path comes from an upstream crate we assume it has been made
800 // independent of the compiler's working directory one way or another.
803 file_metadata_raw(cx
, file_name
, directory
)
806 pub fn unknown_file_metadata(cx
: &CodegenCx
<'ll
, '_
>) -> &'ll DIFile
{
807 file_metadata_raw(cx
, None
, None
)
810 fn file_metadata_raw(cx
: &CodegenCx
<'ll
, '_
>,
811 file_name
: Option
<String
>,
812 directory
: Option
<String
>)
814 let key
= (file_name
, directory
);
816 match debug_context(cx
).created_files
.borrow_mut().entry(key
) {
817 Entry
::Occupied(o
) => return o
.get(),
818 Entry
::Vacant(v
) => {
819 let (file_name
, directory
) = v
.key();
820 debug
!("file_metadata: file_name: {:?}, directory: {:?}", file_name
, directory
);
822 let file_name
= SmallCStr
::new(
823 if let Some(file_name
) = file_name { &file_name }
else { "<unknown>" }
);
824 let directory
= SmallCStr
::new(
825 if let Some(directory
) = directory { &directory }
else { "" }
);
827 let file_metadata
= unsafe {
828 llvm
::LLVMRustDIBuilderCreateFile(DIB(cx
),
833 v
.insert(file_metadata
);
839 fn basic_type_metadata(cx
: &CodegenCx
<'ll
, 'tcx
>, t
: Ty
<'tcx
>) -> &'ll DIType
{
840 debug
!("basic_type_metadata: {:?}", t
);
842 let (name
, encoding
) = match t
.kind
{
843 ty
::Never
=> ("!", DW_ATE_unsigned
),
844 ty
::Tuple(ref elements
) if elements
.is_empty() =>
845 ("()", DW_ATE_unsigned
),
846 ty
::Bool
=> ("bool", DW_ATE_boolean
),
847 ty
::Char
=> ("char", DW_ATE_unsigned_char
),
849 (int_ty
.name_str(), DW_ATE_signed
)
851 ty
::Uint(uint_ty
) => {
852 (uint_ty
.name_str(), DW_ATE_unsigned
)
854 ty
::Float(float_ty
) => {
855 (float_ty
.name_str(), DW_ATE_float
)
857 _
=> bug
!("debuginfo::basic_type_metadata - `t` is invalid type")
860 let (size
, align
) = cx
.size_and_align_of(t
);
861 let name
= SmallCStr
::new(name
);
862 let ty_metadata
= unsafe {
863 llvm
::LLVMRustDIBuilderCreateBasicType(
874 fn foreign_type_metadata(
875 cx
: &CodegenCx
<'ll
, 'tcx
>,
877 unique_type_id
: UniqueTypeId
,
879 debug
!("foreign_type_metadata: {:?}", t
);
881 let name
= compute_debuginfo_type_name(cx
.tcx
, t
, false);
882 create_struct_stub(cx
, t
, &name
, unique_type_id
, NO_SCOPE_METADATA
)
885 fn pointer_type_metadata(
886 cx
: &CodegenCx
<'ll
, 'tcx
>,
887 pointer_type
: Ty
<'tcx
>,
888 pointee_type_metadata
: &'ll DIType
,
890 let (pointer_size
, pointer_align
) = cx
.size_and_align_of(pointer_type
);
891 let name
= compute_debuginfo_type_name(cx
.tcx
, pointer_type
, false);
892 let name
= SmallCStr
::new(&name
);
894 llvm
::LLVMRustDIBuilderCreatePointerType(
896 pointee_type_metadata
,
898 pointer_align
.bits() as u32,
903 pub fn compile_unit_metadata(
905 codegen_unit_name
: &str,
906 debug_context
: &CrateDebugContext
<'ll
, '_
>,
907 ) -> &'ll DIDescriptor
{
908 let mut name_in_debuginfo
= match tcx
.sess
.local_crate_source_file
{
909 Some(ref path
) => path
.clone(),
910 None
=> PathBuf
::from(&*tcx
.crate_name(LOCAL_CRATE
).as_str()),
913 // The OSX linker has an idiosyncrasy where it will ignore some debuginfo
914 // if multiple object files with the same `DW_AT_name` are linked together.
915 // As a workaround we generate unique names for each object file. Those do
916 // not correspond to an actual source file but that should be harmless.
917 if tcx
.sess
.target
.target
.options
.is_like_osx
{
918 name_in_debuginfo
.push("@");
919 name_in_debuginfo
.push(codegen_unit_name
);
922 debug
!("compile_unit_metadata: {:?}", name_in_debuginfo
);
923 let rustc_producer
= format
!(
925 option_env
!("CFG_VERSION").expect("CFG_VERSION"),
927 // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
928 let producer
= format
!("clang LLVM ({})", rustc_producer
);
930 let name_in_debuginfo
= name_in_debuginfo
.to_string_lossy();
931 let name_in_debuginfo
= SmallCStr
::new(&name_in_debuginfo
);
932 let work_dir
= SmallCStr
::new(&tcx
.sess
.working_dir
.0.to_string_lossy());
933 let producer
= CString
::new(producer
).unwrap();
935 let split_name
= "\0";
939 // This should actually be
941 // let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
943 // That is, we should set LLVM's emission kind to `LineTablesOnly` if
944 // we are compiling with "limited" debuginfo. However, some of the
945 // existing tools relied on slightly more debuginfo being generated than
946 // would be the case with `LineTablesOnly`, and we did not want to break
947 // these tools in a "drive-by fix", without a good idea or plan about
948 // what limited debuginfo should exactly look like. So for now we keep
949 // the emission kind as `FullDebug`.
951 // See https://github.com/rust-lang/rust/issues/60020 for details.
952 let kind
= DebugEmissionKind
::FullDebug
;
953 assert
!(tcx
.sess
.opts
.debuginfo
!= DebugInfo
::None
);
956 let file_metadata
= llvm
::LLVMRustDIBuilderCreateFile(
957 debug_context
.builder
, name_in_debuginfo
.as_ptr(), work_dir
.as_ptr());
959 let unit_metadata
= llvm
::LLVMRustDIBuilderCreateCompileUnit(
960 debug_context
.builder
,
964 tcx
.sess
.opts
.optimize
!= config
::OptLevel
::No
,
965 flags
.as_ptr().cast(),
967 split_name
.as_ptr().cast(),
970 if tcx
.sess
.opts
.debugging_opts
.profile
{
971 let cu_desc_metadata
= llvm
::LLVMRustMetadataAsValue(debug_context
.llcontext
,
975 path_to_mdstring(debug_context
.llcontext
,
976 &tcx
.output_filenames(LOCAL_CRATE
).with_extension("gcno")),
977 path_to_mdstring(debug_context
.llcontext
,
978 &tcx
.output_filenames(LOCAL_CRATE
).with_extension("gcda")),
981 let gcov_metadata
= llvm
::LLVMMDNodeInContext(debug_context
.llcontext
,
982 gcov_cu_info
.as_ptr(),
983 gcov_cu_info
.len() as c_uint
);
985 let llvm_gcov_ident
= const_cstr
!("llvm.gcov");
986 llvm
::LLVMAddNamedMetadataOperand(debug_context
.llmod
,
987 llvm_gcov_ident
.as_ptr(),
991 // Insert `llvm.ident` metadata on the wasm32 targets since that will
992 // get hooked up to the "producer" sections `processed-by` information.
993 if tcx
.sess
.opts
.target_triple
.triple().starts_with("wasm32") {
994 let name_metadata
= llvm
::LLVMMDStringInContext(
995 debug_context
.llcontext
,
996 rustc_producer
.as_ptr().cast(),
997 rustc_producer
.as_bytes().len() as c_uint
,
999 llvm
::LLVMAddNamedMetadataOperand(
1000 debug_context
.llmod
,
1001 const_cstr
!("llvm.ident").as_ptr(),
1002 llvm
::LLVMMDNodeInContext(debug_context
.llcontext
, &name_metadata
, 1),
1006 return unit_metadata
;
1009 fn path_to_mdstring(llcx
: &'ll llvm
::Context
, path
: &Path
) -> &'ll Value
{
1010 let path_str
= path_to_c_string(path
);
1012 llvm
::LLVMMDStringInContext(llcx
,
1014 path_str
.as_bytes().len() as c_uint
)
1019 struct MetadataCreationResult
<'ll
> {
1020 metadata
: &'ll DIType
,
1021 already_stored_in_typemap
: bool
1024 impl MetadataCreationResult
<'ll
> {
1025 fn new(metadata
: &'ll DIType
, already_stored_in_typemap
: bool
) -> Self {
1026 MetadataCreationResult
{
1028 already_stored_in_typemap
,
1033 /// Description of a type member, which can either be a regular field (as in
1034 /// structs or tuples) or an enum variant.
1036 struct MemberDescription
<'ll
> {
1038 type_metadata
: &'ll DIType
,
1043 discriminant
: Option
<u64>,
1046 impl<'ll
> MemberDescription
<'ll
> {
1047 fn into_metadata(self,
1048 cx
: &CodegenCx
<'ll
, '_
>,
1049 composite_type_metadata
: &'ll DIScope
) -> &'ll DIType
{
1050 let member_name
= CString
::new(self.name
).unwrap();
1052 llvm
::LLVMRustDIBuilderCreateVariantMemberType(
1054 composite_type_metadata
,
1055 member_name
.as_ptr(),
1056 unknown_file_metadata(cx
),
1057 UNKNOWN_LINE_NUMBER
,
1059 self.align
.bits() as u32,
1061 match self.discriminant
{
1063 Some(value
) => Some(cx
.const_u64(value
)),
1071 /// A factory for `MemberDescription`s. It produces a list of member descriptions
1072 /// for some record-like type. `MemberDescriptionFactory`s are used to defer the
1073 /// creation of type member descriptions in order to break cycles arising from
1074 /// recursive type definitions.
1075 enum MemberDescriptionFactory
<'ll
, 'tcx
> {
1076 StructMDF(StructMemberDescriptionFactory
<'tcx
>),
1077 TupleMDF(TupleMemberDescriptionFactory
<'tcx
>),
1078 EnumMDF(EnumMemberDescriptionFactory
<'ll
, 'tcx
>),
1079 UnionMDF(UnionMemberDescriptionFactory
<'tcx
>),
1080 VariantMDF(VariantMemberDescriptionFactory
<'ll
, 'tcx
>)
1083 impl MemberDescriptionFactory
<'ll
, 'tcx
> {
1084 fn create_member_descriptions(&self, cx
: &CodegenCx
<'ll
, 'tcx
>)
1085 -> Vec
<MemberDescription
<'ll
>> {
1087 StructMDF(ref this
) => {
1088 this
.create_member_descriptions(cx
)
1090 TupleMDF(ref this
) => {
1091 this
.create_member_descriptions(cx
)
1093 EnumMDF(ref this
) => {
1094 this
.create_member_descriptions(cx
)
1096 UnionMDF(ref this
) => {
1097 this
.create_member_descriptions(cx
)
1099 VariantMDF(ref this
) => {
1100 this
.create_member_descriptions(cx
)
1106 //=-----------------------------------------------------------------------------
1108 //=-----------------------------------------------------------------------------
1110 /// Creates `MemberDescription`s for the fields of a struct.
1111 struct StructMemberDescriptionFactory
<'tcx
> {
1113 variant
: &'tcx ty
::VariantDef
,
1117 impl<'tcx
> StructMemberDescriptionFactory
<'tcx
> {
1118 fn create_member_descriptions(&self, cx
: &CodegenCx
<'ll
, 'tcx
>)
1119 -> Vec
<MemberDescription
<'ll
>> {
1120 let layout
= cx
.layout_of(self.ty
);
1121 self.variant
.fields
.iter().enumerate().map(|(i
, f
)| {
1122 let name
= if self.variant
.ctor_kind
== CtorKind
::Fn
{
1127 let field
= layout
.field(cx
, i
);
1130 type_metadata
: type_metadata(cx
, field
.ty
, self.span
),
1131 offset
: layout
.fields
.offset(i
),
1133 align
: field
.align
.abi
,
1134 flags
: DIFlags
::FlagZero
,
1142 fn prepare_struct_metadata(
1143 cx
: &CodegenCx
<'ll
, 'tcx
>,
1144 struct_type
: Ty
<'tcx
>,
1145 unique_type_id
: UniqueTypeId
,
1147 ) -> RecursiveTypeDescription
<'ll
, 'tcx
> {
1148 let struct_name
= compute_debuginfo_type_name(cx
.tcx
, struct_type
, false);
1150 let (struct_def_id
, variant
) = match struct_type
.kind
{
1151 ty
::Adt(def
, _
) => (def
.did
, def
.non_enum_variant()),
1152 _
=> bug
!("prepare_struct_metadata on a non-ADT")
1155 let containing_scope
= get_namespace_for_item(cx
, struct_def_id
);
1157 let struct_metadata_stub
= create_struct_stub(cx
,
1161 Some(containing_scope
));
1163 create_and_register_recursive_type_forward_declaration(
1167 struct_metadata_stub
,
1168 struct_metadata_stub
,
1169 StructMDF(StructMemberDescriptionFactory
{
1177 //=-----------------------------------------------------------------------------
1179 //=-----------------------------------------------------------------------------
1181 /// Creates `MemberDescription`s for the fields of a tuple.
1182 struct TupleMemberDescriptionFactory
<'tcx
> {
1184 component_types
: Vec
<Ty
<'tcx
>>,
1188 impl<'tcx
> TupleMemberDescriptionFactory
<'tcx
> {
1189 fn create_member_descriptions(&self, cx
: &CodegenCx
<'ll
, 'tcx
>)
1190 -> Vec
<MemberDescription
<'ll
>> {
1191 let layout
= cx
.layout_of(self.ty
);
1192 self.component_types
.iter().enumerate().map(|(i
, &component_type
)| {
1193 let (size
, align
) = cx
.size_and_align_of(component_type
);
1195 name
: format
!("__{}", i
),
1196 type_metadata
: type_metadata(cx
, component_type
, self.span
),
1197 offset
: layout
.fields
.offset(i
),
1200 flags
: DIFlags
::FlagZero
,
1207 fn prepare_tuple_metadata(
1208 cx
: &CodegenCx
<'ll
, 'tcx
>,
1209 tuple_type
: Ty
<'tcx
>,
1210 component_types
: &[Ty
<'tcx
>],
1211 unique_type_id
: UniqueTypeId
,
1213 containing_scope
: Option
<&'ll DIScope
>,
1214 ) -> RecursiveTypeDescription
<'ll
, 'tcx
> {
1215 let tuple_name
= compute_debuginfo_type_name(cx
.tcx
, tuple_type
, false);
1217 let struct_stub
= create_struct_stub(cx
,
1223 create_and_register_recursive_type_forward_declaration(
1229 TupleMDF(TupleMemberDescriptionFactory
{
1231 component_types
: component_types
.to_vec(),
1237 //=-----------------------------------------------------------------------------
1239 //=-----------------------------------------------------------------------------
1241 struct UnionMemberDescriptionFactory
<'tcx
> {
1242 layout
: TyLayout
<'tcx
>,
1243 variant
: &'tcx ty
::VariantDef
,
1247 impl<'tcx
> UnionMemberDescriptionFactory
<'tcx
> {
1248 fn create_member_descriptions(&self, cx
: &CodegenCx
<'ll
, 'tcx
>)
1249 -> Vec
<MemberDescription
<'ll
>> {
1250 self.variant
.fields
.iter().enumerate().map(|(i
, f
)| {
1251 let field
= self.layout
.field(cx
, i
);
1253 name
: f
.ident
.to_string(),
1254 type_metadata
: type_metadata(cx
, field
.ty
, self.span
),
1257 align
: field
.align
.abi
,
1258 flags
: DIFlags
::FlagZero
,
1265 fn prepare_union_metadata(
1266 cx
: &CodegenCx
<'ll
, 'tcx
>,
1267 union_type
: Ty
<'tcx
>,
1268 unique_type_id
: UniqueTypeId
,
1270 ) -> RecursiveTypeDescription
<'ll
, 'tcx
> {
1271 let union_name
= compute_debuginfo_type_name(cx
.tcx
, union_type
, false);
1273 let (union_def_id
, variant
) = match union_type
.kind
{
1274 ty
::Adt(def
, _
) => (def
.did
, def
.non_enum_variant()),
1275 _
=> bug
!("prepare_union_metadata on a non-ADT")
1278 let containing_scope
= get_namespace_for_item(cx
, union_def_id
);
1280 let union_metadata_stub
= create_union_stub(cx
,
1286 create_and_register_recursive_type_forward_declaration(
1290 union_metadata_stub
,
1291 union_metadata_stub
,
1292 UnionMDF(UnionMemberDescriptionFactory
{
1293 layout
: cx
.layout_of(union_type
),
1300 //=-----------------------------------------------------------------------------
1302 //=-----------------------------------------------------------------------------
1304 /// DWARF variant support is only available starting in LLVM 8.
1305 /// Although the earlier enum debug info output did not work properly
1306 /// in all situations, it is better for the time being to continue to
1307 /// sometimes emit the old style rather than emit something completely
1308 /// useless when rust is compiled against LLVM 6 or older. LLVM 7
1309 /// contains an early version of the DWARF variant support, and will
1310 /// crash when handling the new debug info format. This function
1311 /// decides which representation will be emitted.
1312 fn use_enum_fallback(cx
: &CodegenCx
<'_
, '_
>) -> bool
{
1313 // On MSVC we have to use the fallback mode, because LLVM doesn't
1314 // lower variant parts to PDB.
1315 return cx
.sess().target
.target
.options
.is_like_msvc
1316 // LLVM version 7 did not release with an important bug fix;
1317 // but the required patch is in the LLVM 8. Rust LLVM reports
1319 || llvm_util
::get_major_version() < 8;
1322 // FIXME(eddyb) maybe precompute this? Right now it's computed once
1323 // per generator monomorphization, but it doesn't depend on substs.
1324 fn generator_layout_and_saved_local_names(
1327 ) -> (&'tcx GeneratorLayout
<'tcx
>, IndexVec
<mir
::GeneratorSavedLocal
, Option
<ast
::Name
>>) {
1328 let body
= tcx
.optimized_mir(def_id
);
1329 let generator_layout
= body
.generator_layout
.as_ref().unwrap();
1330 let mut generator_saved_local_names
=
1331 IndexVec
::from_elem(None
, &generator_layout
.field_tys
);
1333 let state_arg
= mir
::PlaceBase
::Local(mir
::Local
::new(1));
1334 for var
in &body
.var_debug_info
{
1335 if var
.place
.base
!= state_arg
{
1338 match var
.place
.projection
[..] {
1340 // Deref of the `Pin<&mut Self>` state argument.
1341 mir
::ProjectionElem
::Field(..),
1342 mir
::ProjectionElem
::Deref
,
1344 // Field of a variant of the state.
1345 mir
::ProjectionElem
::Downcast(_
, variant
),
1346 mir
::ProjectionElem
::Field(field
, _
),
1348 let name
= &mut generator_saved_local_names
[
1349 generator_layout
.variant_fields
[variant
][field
]
1352 name
.replace(var
.name
);
1358 (generator_layout
, generator_saved_local_names
)
1361 /// Describes the members of an enum value; an enum is described as a union of
1362 /// structs in DWARF. This `MemberDescriptionFactory` provides the description for
1363 /// the members of this union; so for every variant of the given enum, this
1364 /// factory will produce one `MemberDescription` (all with no name and a fixed
1365 /// offset of zero bytes).
1366 struct EnumMemberDescriptionFactory
<'ll
, 'tcx
> {
1367 enum_type
: Ty
<'tcx
>,
1368 layout
: TyLayout
<'tcx
>,
1369 discriminant_type_metadata
: Option
<&'ll DIType
>,
1370 containing_scope
: &'ll DIScope
,
1374 impl EnumMemberDescriptionFactory
<'ll
, 'tcx
> {
1375 fn create_member_descriptions(&self, cx
: &CodegenCx
<'ll
, 'tcx
>)
1376 -> Vec
<MemberDescription
<'ll
>> {
1377 let generator_variant_info_data
= match self.enum_type
.kind
{
1378 ty
::Generator(def_id
, ..) => {
1379 Some(generator_layout_and_saved_local_names(cx
.tcx
, def_id
))
1384 let variant_info_for
= |index
: VariantIdx
| {
1385 match self.enum_type
.kind
{
1386 ty
::Adt(adt
, _
) => VariantInfo
::Adt(&adt
.variants
[index
]),
1387 ty
::Generator(_
, substs
, _
) => {
1388 let (generator_layout
, generator_saved_local_names
) =
1389 generator_variant_info_data
.as_ref().unwrap();
1390 VariantInfo
::Generator
{
1392 generator_layout
: *generator_layout
,
1393 generator_saved_local_names
,
1394 variant_index
: index
,
1401 // This will always find the metadata in the type map.
1402 let fallback
= use_enum_fallback(cx
);
1403 let self_metadata
= if fallback
{
1404 self.containing_scope
1406 type_metadata(cx
, self.enum_type
, self.span
)
1409 match self.layout
.variants
{
1410 layout
::Variants
::Single { index }
=> {
1411 if let ty
::Adt(adt
, _
) = &self.enum_type
.kind
{
1412 if adt
.variants
.is_empty() {
1417 let variant_info
= variant_info_for(index
);
1418 let (variant_type_metadata
, member_description_factory
) =
1419 describe_enum_variant(cx
,
1426 let member_descriptions
=
1427 member_description_factory
.create_member_descriptions(cx
);
1429 set_members_of_composite_type(cx
,
1431 variant_type_metadata
,
1432 member_descriptions
);
1438 variant_info
.variant_name()
1440 type_metadata
: variant_type_metadata
,
1442 size
: self.layout
.size
,
1443 align
: self.layout
.align
.abi
,
1444 flags
: DIFlags
::FlagZero
,
1449 layout
::Variants
::Multiple
{
1450 discr_kind
: layout
::DiscriminantKind
::Tag
,
1455 let discriminant_info
= if fallback
{
1456 RegularDiscriminant
{
1457 discr_field
: Field
::from(discr_index
),
1458 discr_type_metadata
: self.discriminant_type_metadata
.unwrap()
1461 // This doesn't matter in this case.
1464 variants
.iter_enumerated().map(|(i
, _
)| {
1465 let variant
= self.layout
.for_variant(cx
, i
);
1466 let variant_info
= variant_info_for(i
);
1467 let (variant_type_metadata
, member_desc_factory
) =
1468 describe_enum_variant(cx
,
1475 let member_descriptions
= member_desc_factory
1476 .create_member_descriptions(cx
);
1478 set_members_of_composite_type(cx
,
1480 variant_type_metadata
,
1481 member_descriptions
);
1487 variant_info
.variant_name()
1489 type_metadata
: variant_type_metadata
,
1491 size
: self.layout
.size
,
1492 align
: self.layout
.align
.abi
,
1493 flags
: DIFlags
::FlagZero
,
1495 self.layout
.ty
.discriminant_for_variant(cx
.tcx
, i
).unwrap().val
as u64
1500 layout
::Variants
::Multiple
{
1501 discr_kind
: layout
::DiscriminantKind
::Niche
{
1511 let variant
= self.layout
.for_variant(cx
, dataful_variant
);
1512 // Create a description of the non-null variant.
1513 let (variant_type_metadata
, member_description_factory
) =
1514 describe_enum_variant(cx
,
1516 variant_info_for(dataful_variant
),
1517 OptimizedDiscriminant
,
1518 self.containing_scope
,
1521 let variant_member_descriptions
=
1522 member_description_factory
.create_member_descriptions(cx
);
1524 set_members_of_composite_type(cx
,
1526 variant_type_metadata
,
1527 variant_member_descriptions
);
1529 // Encode the information about the null variant in the union
1531 let mut name
= String
::from("RUST$ENCODED$ENUM$");
1532 // Right now it's not even going to work for `niche_start > 0`,
1533 // and for multiple niche variants it only supports the first.
1534 fn compute_field_path
<'a
, 'tcx
>(cx
: &CodegenCx
<'a
, 'tcx
>,
1536 layout
: TyLayout
<'tcx
>,
1539 for i
in 0..layout
.fields
.count() {
1540 let field_offset
= layout
.fields
.offset(i
);
1541 if field_offset
> offset
{
1544 let inner_offset
= offset
- field_offset
;
1545 let field
= layout
.field(cx
, i
);
1546 if inner_offset
+ size
<= field
.size
{
1547 write
!(name
, "{}$", i
).unwrap();
1548 compute_field_path(cx
, name
, field
, inner_offset
, size
);
1552 compute_field_path(cx
, &mut name
,
1554 self.layout
.fields
.offset(discr_index
),
1555 self.layout
.field(cx
, discr_index
).size
);
1556 variant_info_for(*niche_variants
.start()).map_struct_name(|variant_name
| {
1557 name
.push_str(variant_name
);
1560 // Create the (singleton) list of descriptions of union members.
1564 type_metadata
: variant_type_metadata
,
1567 align
: variant
.align
.abi
,
1568 flags
: DIFlags
::FlagZero
,
1573 variants
.iter_enumerated().map(|(i
, _
)| {
1574 let variant
= self.layout
.for_variant(cx
, i
);
1575 let variant_info
= variant_info_for(i
);
1576 let (variant_type_metadata
, member_desc_factory
) =
1577 describe_enum_variant(cx
,
1580 OptimizedDiscriminant
,
1584 let member_descriptions
= member_desc_factory
1585 .create_member_descriptions(cx
);
1587 set_members_of_composite_type(cx
,
1589 variant_type_metadata
,
1590 member_descriptions
);
1592 let niche_value
= if i
== dataful_variant
{
1595 let value
= (i
.as_u32() as u128
)
1596 .wrapping_sub(niche_variants
.start().as_u32() as u128
)
1597 .wrapping_add(niche_start
);
1598 let value
= truncate(value
, discr
.value
.size(cx
));
1599 // NOTE(eddyb) do *NOT* remove this assert, until
1600 // we pass the full 128-bit value to LLVM, otherwise
1601 // truncation will be silent and remain undetected.
1602 assert_eq
!(value
as u64 as u128
, value
);
1607 name
: variant_info
.variant_name(),
1608 type_metadata
: variant_type_metadata
,
1610 size
: self.layout
.size
,
1611 align
: self.layout
.align
.abi
,
1612 flags
: DIFlags
::FlagZero
,
1613 discriminant
: niche_value
,
1622 // Creates `MemberDescription`s for the fields of a single enum variant.
1623 struct VariantMemberDescriptionFactory
<'ll
, 'tcx
> {
1624 /// Cloned from the `layout::Struct` describing the variant.
1625 offsets
: Vec
<layout
::Size
>,
1626 args
: Vec
<(String
, Ty
<'tcx
>)>,
1627 discriminant_type_metadata
: Option
<&'ll DIType
>,
1631 impl VariantMemberDescriptionFactory
<'ll
, 'tcx
> {
1632 fn create_member_descriptions(&self, cx
: &CodegenCx
<'ll
, 'tcx
>)
1633 -> Vec
<MemberDescription
<'ll
>> {
1634 self.args
.iter().enumerate().map(|(i
, &(ref name
, ty
))| {
1635 let (size
, align
) = cx
.size_and_align_of(ty
);
1637 name
: name
.to_string(),
1638 type_metadata
: if use_enum_fallback(cx
) {
1639 match self.discriminant_type_metadata
{
1640 // Discriminant is always the first field of our variant
1641 // when using the enum fallback.
1642 Some(metadata
) if i
== 0 => metadata
,
1643 _
=> type_metadata(cx
, ty
, self.span
)
1646 type_metadata(cx
, ty
, self.span
)
1648 offset
: self.offsets
[i
],
1651 flags
: DIFlags
::FlagZero
,
1658 #[derive(Copy, Clone)]
1659 enum EnumDiscriminantInfo
<'ll
> {
1660 RegularDiscriminant{ discr_field: Field, discr_type_metadata: &'ll DIType }
,
1661 OptimizedDiscriminant
,
1665 #[derive(Copy, Clone)]
1666 enum VariantInfo
<'a
, 'tcx
> {
1667 Adt(&'tcx ty
::VariantDef
),
1669 substs
: SubstsRef
<'tcx
>,
1670 generator_layout
: &'tcx GeneratorLayout
<'tcx
>,
1671 generator_saved_local_names
: &'a IndexVec
<mir
::GeneratorSavedLocal
, Option
<ast
::Name
>>,
1672 variant_index
: VariantIdx
,
1676 impl<'tcx
> VariantInfo
<'_
, 'tcx
> {
1677 fn map_struct_name
<R
>(&self, f
: impl FnOnce(&str) -> R
) -> R
{
1679 VariantInfo
::Adt(variant
) => f(&variant
.ident
.as_str()),
1680 VariantInfo
::Generator { substs, variant_index, .. }
=>
1681 f(&substs
.as_generator().variant_name(*variant_index
)),
1685 fn variant_name(&self) -> String
{
1687 VariantInfo
::Adt(variant
) => variant
.ident
.to_string(),
1688 VariantInfo
::Generator { variant_index, .. }
=> {
1689 // Since GDB currently prints out the raw discriminant along
1690 // with every variant, make each variant name be just the value
1691 // of the discriminant. The struct name for the variant includes
1692 // the actual variant description.
1693 format
!("{}", variant_index
.as_usize())
1698 fn field_name(&self, i
: usize) -> String
{
1699 let field_name
= match *self {
1700 VariantInfo
::Adt(variant
) if variant
.ctor_kind
!= CtorKind
::Fn
=>
1701 Some(variant
.fields
[i
].ident
.name
),
1702 VariantInfo
::Generator
{
1704 generator_saved_local_names
,
1707 } => generator_saved_local_names
[
1708 generator_layout
.variant_fields
[variant_index
][i
.into()]
1712 field_name
.map(|name
| name
.to_string()).unwrap_or_else(|| format
!("__{}", i
))
1716 /// Returns a tuple of (1) `type_metadata_stub` of the variant, (2) a
1717 /// `MemberDescriptionFactory` for producing the descriptions of the
1718 /// fields of the variant. This is a rudimentary version of a full
1719 /// `RecursiveTypeDescription`.
1720 fn describe_enum_variant(
1721 cx
: &CodegenCx
<'ll
, 'tcx
>,
1722 layout
: layout
::TyLayout
<'tcx
>,
1723 variant
: VariantInfo
<'_
, 'tcx
>,
1724 discriminant_info
: EnumDiscriminantInfo
<'ll
>,
1725 containing_scope
: &'ll DIScope
,
1727 ) -> (&'ll DICompositeType
, MemberDescriptionFactory
<'ll
, 'tcx
>) {
1728 let metadata_stub
= variant
.map_struct_name(|variant_name
| {
1729 let unique_type_id
= debug_context(cx
).type_map
1731 .get_unique_type_id_of_enum_variant(
1735 create_struct_stub(cx
,
1739 Some(containing_scope
))
1742 // Build an array of (field name, field type) pairs to be captured in the factory closure.
1743 let (offsets
, args
) = if use_enum_fallback(cx
) {
1744 // If this is not a univariant enum, there is also the discriminant field.
1745 let (discr_offset
, discr_arg
) = match discriminant_info
{
1746 RegularDiscriminant { discr_field, .. }
=> {
1747 // We have the layout of an enum variant, we need the layout of the outer enum
1748 let enum_layout
= cx
.layout_of(layout
.ty
);
1749 let offset
= enum_layout
.fields
.offset(discr_field
.as_usize());
1751 "RUST$ENUM$DISR".to_owned(),
1752 enum_layout
.field(cx
, discr_field
.as_usize()).ty
);
1753 (Some(offset
), Some(args
))
1758 discr_offset
.into_iter().chain((0..layout
.fields
.count()).map(|i
| {
1759 layout
.fields
.offset(i
)
1761 discr_arg
.into_iter().chain((0..layout
.fields
.count()).map(|i
| {
1762 (variant
.field_name(i
), layout
.field(cx
, i
).ty
)
1767 (0..layout
.fields
.count()).map(|i
| {
1768 layout
.fields
.offset(i
)
1770 (0..layout
.fields
.count()).map(|i
| {
1771 (variant
.field_name(i
), layout
.field(cx
, i
).ty
)
1776 let member_description_factory
=
1777 VariantMDF(VariantMemberDescriptionFactory
{
1780 discriminant_type_metadata
: match discriminant_info
{
1781 RegularDiscriminant { discr_type_metadata, .. }
=> {
1782 Some(discr_type_metadata
)
1789 (metadata_stub
, member_description_factory
)
1792 fn prepare_enum_metadata(
1793 cx
: &CodegenCx
<'ll
, 'tcx
>,
1794 enum_type
: Ty
<'tcx
>,
1796 unique_type_id
: UniqueTypeId
,
1798 outer_field_tys
: Vec
<Ty
<'tcx
>>,
1799 ) -> RecursiveTypeDescription
<'ll
, 'tcx
> {
1800 let enum_name
= compute_debuginfo_type_name(cx
.tcx
, enum_type
, false);
1802 let containing_scope
= get_namespace_for_item(cx
, enum_def_id
);
1803 // FIXME: This should emit actual file metadata for the enum, but we
1804 // currently can't get the necessary information when it comes to types
1805 // imported from other crates. Formerly we violated the ODR when performing
1806 // LTO because we emitted debuginfo for the same type with varying file
1807 // metadata, so as a workaround we pretend that the type comes from
1809 let file_metadata
= unknown_file_metadata(cx
);
1811 let discriminant_type_metadata
= |discr
: layout
::Primitive
| {
1812 let enumerators_metadata
: Vec
<_
> = match enum_type
.kind
{
1813 ty
::Adt(def
, _
) => def
1814 .discriminants(cx
.tcx
)
1816 .map(|((_
, discr
), v
)| {
1817 let name
= SmallCStr
::new(&v
.ident
.as_str());
1819 Some(llvm
::LLVMRustDIBuilderCreateEnumerator(
1822 // FIXME: what if enumeration has i128 discriminant?
1827 ty
::Generator(_
, substs
, _
) => substs
1829 .variant_range(enum_def_id
, cx
.tcx
)
1830 .map(|variant_index
| {
1831 let name
= SmallCStr
::new(&substs
.as_generator().variant_name(variant_index
));
1833 Some(llvm
::LLVMRustDIBuilderCreateEnumerator(
1836 // FIXME: what if enumeration has i128 discriminant?
1837 variant_index
.as_usize() as u64))
1844 let disr_type_key
= (enum_def_id
, discr
);
1845 let cached_discriminant_type_metadata
= debug_context(cx
).created_enum_disr_types
1847 .get(&disr_type_key
).cloned();
1848 match cached_discriminant_type_metadata
{
1849 Some(discriminant_type_metadata
) => discriminant_type_metadata
,
1851 let (discriminant_size
, discriminant_align
) =
1852 (discr
.size(cx
), discr
.align(cx
));
1853 let discriminant_base_type_metadata
=
1854 type_metadata(cx
, discr
.to_ty(cx
.tcx
), syntax_pos
::DUMMY_SP
);
1856 let discriminant_name
= match enum_type
.kind
{
1857 ty
::Adt(..) => SmallCStr
::new(&cx
.tcx
.item_name(enum_def_id
).as_str()),
1858 ty
::Generator(..) => SmallCStr
::new(&enum_name
),
1862 let discriminant_type_metadata
= unsafe {
1863 llvm
::LLVMRustDIBuilderCreateEnumerationType(
1866 discriminant_name
.as_ptr(),
1868 UNKNOWN_LINE_NUMBER
,
1869 discriminant_size
.bits(),
1870 discriminant_align
.abi
.bits() as u32,
1871 create_DIArray(DIB(cx
), &enumerators_metadata
),
1872 discriminant_base_type_metadata
, true)
1875 debug_context(cx
).created_enum_disr_types
1877 .insert(disr_type_key
, discriminant_type_metadata
);
1879 discriminant_type_metadata
1884 let layout
= cx
.layout_of(enum_type
);
1886 match (&layout
.abi
, &layout
.variants
) {
1887 (&layout
::Abi
::Scalar(_
), &layout
::Variants
::Multiple
{
1888 discr_kind
: layout
::DiscriminantKind
::Tag
,
1891 }) => return FinalMetadata(discriminant_type_metadata(discr
.value
)),
1895 let enum_name
= SmallCStr
::new(&enum_name
);
1896 let unique_type_id_str
= SmallCStr
::new(
1897 debug_context(cx
).type_map
.borrow().get_unique_type_id_as_string(unique_type_id
)
1900 if use_enum_fallback(cx
) {
1901 let discriminant_type_metadata
= match layout
.variants
{
1902 layout
::Variants
::Single { .. }
|
1903 layout
::Variants
::Multiple
{
1904 discr_kind
: layout
::DiscriminantKind
::Niche { .. }
,
1907 layout
::Variants
::Multiple
{
1908 discr_kind
: layout
::DiscriminantKind
::Tag
,
1912 Some(discriminant_type_metadata(discr
.value
))
1916 let enum_metadata
= unsafe {
1917 llvm
::LLVMRustDIBuilderCreateUnionType(
1922 UNKNOWN_LINE_NUMBER
,
1924 layout
.align
.abi
.bits() as u32,
1928 unique_type_id_str
.as_ptr())
1931 return create_and_register_recursive_type_forward_declaration(
1937 EnumMDF(EnumMemberDescriptionFactory
{
1940 discriminant_type_metadata
,
1947 let discriminator_name
= match &enum_type
.kind
{
1948 ty
::Generator(..) => Some(SmallCStr
::new(&"__state")),
1951 let discriminator_name
= discriminator_name
.map(|n
| n
.as_ptr()).unwrap_or(ptr
::null_mut());
1952 let discriminator_metadata
= match layout
.variants
{
1953 // A single-variant enum has no discriminant.
1954 layout
::Variants
::Single { .. }
=> None
,
1956 layout
::Variants
::Multiple
{
1957 discr_kind
: layout
::DiscriminantKind
::Niche { .. }
,
1962 // Find the integer type of the correct size.
1963 let size
= discr
.value
.size(cx
);
1964 let align
= discr
.value
.align(cx
);
1966 let discr_type
= match discr
.value
{
1967 layout
::Int(t
, _
) => t
,
1968 layout
::F32
=> Integer
::I32
,
1969 layout
::F64
=> Integer
::I64
,
1970 layout
::Pointer
=> cx
.data_layout().ptr_sized_integer(),
1971 }.to_ty(cx
.tcx
, false);
1973 let discr_metadata
= basic_type_metadata(cx
, discr_type
);
1975 Some(llvm
::LLVMRustDIBuilderCreateMemberType(
1980 UNKNOWN_LINE_NUMBER
,
1982 align
.abi
.bits() as u32,
1983 layout
.fields
.offset(discr_index
).bits(),
1984 DIFlags
::FlagArtificial
,
1989 layout
::Variants
::Multiple
{
1990 discr_kind
: layout
::DiscriminantKind
::Tag
,
1995 let discr_type
= discr
.value
.to_ty(cx
.tcx
);
1996 let (size
, align
) = cx
.size_and_align_of(discr_type
);
1998 let discr_metadata
= basic_type_metadata(cx
, discr_type
);
2000 Some(llvm
::LLVMRustDIBuilderCreateMemberType(
2005 UNKNOWN_LINE_NUMBER
,
2007 align
.bits() as u32,
2008 layout
.fields
.offset(discr_index
).bits(),
2009 DIFlags
::FlagArtificial
,
2015 let mut outer_fields
= match layout
.variants
{
2016 layout
::Variants
::Single { .. }
=> vec
![],
2017 layout
::Variants
::Multiple { .. }
=> {
2018 let tuple_mdf
= TupleMemberDescriptionFactory
{
2020 component_types
: outer_field_tys
,
2024 .create_member_descriptions(cx
)
2026 .map(|desc
| Some(desc
.into_metadata(cx
, containing_scope
)))
2031 let variant_part_unique_type_id_str
= SmallCStr
::new(
2032 debug_context(cx
).type_map
2034 .get_unique_type_id_str_of_enum_variant_part(unique_type_id
)
2036 let empty_array
= create_DIArray(DIB(cx
), &[]);
2037 let variant_part
= unsafe {
2038 llvm
::LLVMRustDIBuilderCreateVariantPart(
2043 UNKNOWN_LINE_NUMBER
,
2045 layout
.align
.abi
.bits() as u32,
2047 discriminator_metadata
,
2049 variant_part_unique_type_id_str
.as_ptr())
2051 outer_fields
.push(Some(variant_part
));
2053 // The variant part must be wrapped in a struct according to DWARF.
2054 let type_array
= create_DIArray(DIB(cx
), &outer_fields
);
2055 let struct_wrapper
= unsafe {
2056 llvm
::LLVMRustDIBuilderCreateStructType(
2058 Some(containing_scope
),
2061 UNKNOWN_LINE_NUMBER
,
2063 layout
.align
.abi
.bits() as u32,
2069 unique_type_id_str
.as_ptr())
2072 return create_and_register_recursive_type_forward_declaration(
2078 EnumMDF(EnumMemberDescriptionFactory
{
2081 discriminant_type_metadata
: None
,
2088 /// Creates debug information for a composite type, that is, anything that
2089 /// results in a LLVM struct.
2091 /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
2092 fn composite_type_metadata(
2093 cx
: &CodegenCx
<'ll
, 'tcx
>,
2094 composite_type
: Ty
<'tcx
>,
2095 composite_type_name
: &str,
2096 composite_type_unique_id
: UniqueTypeId
,
2097 member_descriptions
: Vec
<MemberDescription
<'ll
>>,
2098 containing_scope
: Option
<&'ll DIScope
>,
2100 // Ignore source location information as long as it
2101 // can't be reconstructed for non-local crates.
2102 _file_metadata
: &'ll DIFile
,
2103 _definition_span
: Span
,
2104 ) -> &'ll DICompositeType
{
2105 // Create the (empty) struct metadata node ...
2106 let composite_type_metadata
= create_struct_stub(cx
,
2108 composite_type_name
,
2109 composite_type_unique_id
,
2111 // ... and immediately create and add the member descriptions.
2112 set_members_of_composite_type(cx
,
2114 composite_type_metadata
,
2115 member_descriptions
);
2117 composite_type_metadata
2120 fn set_members_of_composite_type(cx
: &CodegenCx
<'ll
, 'tcx
>,
2121 composite_type
: Ty
<'tcx
>,
2122 composite_type_metadata
: &'ll DICompositeType
,
2123 member_descriptions
: Vec
<MemberDescription
<'ll
>>) {
2124 // In some rare cases LLVM metadata uniquing would lead to an existing type
2125 // description being used instead of a new one created in
2126 // create_struct_stub. This would cause a hard to trace assertion in
2127 // DICompositeType::SetTypeArray(). The following check makes sure that we
2128 // get a better error message if this should happen again due to some
2131 let mut composite_types_completed
=
2132 debug_context(cx
).composite_types_completed
.borrow_mut();
2133 if !composite_types_completed
.insert(&composite_type_metadata
) {
2134 bug
!("debuginfo::set_members_of_composite_type() - \
2135 Already completed forward declaration re-encountered.");
2139 let member_metadata
: Vec
<_
> = member_descriptions
2141 .map(|desc
| Some(desc
.into_metadata(cx
, composite_type_metadata
)))
2144 let type_params
= compute_type_parameters(cx
, composite_type
);
2146 let type_array
= create_DIArray(DIB(cx
), &member_metadata
[..]);
2147 llvm
::LLVMRustDICompositeTypeReplaceArrays(
2148 DIB(cx
), composite_type_metadata
, Some(type_array
), type_params
);
2152 /// Computes the type parameters for a type, if any, for the given metadata.
2153 fn compute_type_parameters(cx
: &CodegenCx
<'ll
, 'tcx
>, ty
: Ty
<'tcx
>) -> Option
<&'ll DIArray
> {
2154 if let ty
::Adt(def
, substs
) = ty
.kind
{
2155 if !substs
.types().next().is_none() {
2156 let generics
= cx
.tcx
.generics_of(def
.did
);
2157 let names
= get_parameter_names(cx
, generics
);
2158 let template_params
: Vec
<_
> = substs
.iter().zip(names
).filter_map(|(kind
, name
)| {
2159 if let GenericArgKind
::Type(ty
) = kind
.unpack() {
2160 let actual_type
= cx
.tcx
.normalize_erasing_regions(ParamEnv
::reveal_all(), ty
);
2161 let actual_type_metadata
=
2162 type_metadata(cx
, actual_type
, syntax_pos
::DUMMY_SP
);
2163 let name
= SmallCStr
::new(&name
.as_str());
2166 Some(llvm
::LLVMRustDIBuilderCreateTemplateTypeParameter(
2170 actual_type_metadata
,
2171 unknown_file_metadata(cx
),
2181 return Some(create_DIArray(DIB(cx
), &template_params
[..]));
2184 return Some(create_DIArray(DIB(cx
), &[]));
2186 fn get_parameter_names(cx
: &CodegenCx
<'_
, '_
>,
2187 generics
: &ty
::Generics
)
2189 let mut names
= generics
.parent
.map_or(vec
![], |def_id
| {
2190 get_parameter_names(cx
, cx
.tcx
.generics_of(def_id
))
2192 names
.extend(generics
.params
.iter().map(|param
| param
.name
));
2197 /// A convenience wrapper around `LLVMRustDIBuilderCreateStructType()`. Does not do
2198 /// any caching, does not add any fields to the struct. This can be done later
2199 /// with `set_members_of_composite_type()`.
2200 fn create_struct_stub(
2201 cx
: &CodegenCx
<'ll
, 'tcx
>,
2202 struct_type
: Ty
<'tcx
>,
2203 struct_type_name
: &str,
2204 unique_type_id
: UniqueTypeId
,
2205 containing_scope
: Option
<&'ll DIScope
>,
2206 ) -> &'ll DICompositeType
{
2207 let (struct_size
, struct_align
) = cx
.size_and_align_of(struct_type
);
2209 let name
= SmallCStr
::new(struct_type_name
);
2210 let unique_type_id
= SmallCStr
::new(
2211 debug_context(cx
).type_map
.borrow().get_unique_type_id_as_string(unique_type_id
)
2213 let metadata_stub
= unsafe {
2214 // `LLVMRustDIBuilderCreateStructType()` wants an empty array. A null
2215 // pointer will lead to hard to trace and debug LLVM assertions
2216 // later on in `llvm/lib/IR/Value.cpp`.
2217 let empty_array
= create_DIArray(DIB(cx
), &[]);
2219 llvm
::LLVMRustDIBuilderCreateStructType(
2223 unknown_file_metadata(cx
),
2224 UNKNOWN_LINE_NUMBER
,
2226 struct_align
.bits() as u32,
2232 unique_type_id
.as_ptr())
2238 fn create_union_stub(
2239 cx
: &CodegenCx
<'ll
, 'tcx
>,
2240 union_type
: Ty
<'tcx
>,
2241 union_type_name
: &str,
2242 unique_type_id
: UniqueTypeId
,
2243 containing_scope
: &'ll DIScope
,
2244 ) -> &'ll DICompositeType
{
2245 let (union_size
, union_align
) = cx
.size_and_align_of(union_type
);
2247 let name
= SmallCStr
::new(union_type_name
);
2248 let unique_type_id
= SmallCStr
::new(
2249 debug_context(cx
).type_map
.borrow().get_unique_type_id_as_string(unique_type_id
)
2251 let metadata_stub
= unsafe {
2252 // `LLVMRustDIBuilderCreateUnionType()` wants an empty array. A null
2253 // pointer will lead to hard to trace and debug LLVM assertions
2254 // later on in `llvm/lib/IR/Value.cpp`.
2255 let empty_array
= create_DIArray(DIB(cx
), &[]);
2257 llvm
::LLVMRustDIBuilderCreateUnionType(
2261 unknown_file_metadata(cx
),
2262 UNKNOWN_LINE_NUMBER
,
2264 union_align
.bits() as u32,
2268 unique_type_id
.as_ptr())
2274 /// Creates debug information for the given global variable.
2276 /// Adds the created metadata nodes directly to the crate's IR.
2277 pub fn create_global_var_metadata(
2278 cx
: &CodegenCx
<'ll
, '_
>,
2282 if cx
.dbg_cx
.is_none() {
2287 let attrs
= tcx
.codegen_fn_attrs(def_id
);
2289 if attrs
.flags
.contains(CodegenFnAttrFlags
::NO_DEBUG
) {
2293 let no_mangle
= attrs
.flags
.contains(CodegenFnAttrFlags
::NO_MANGLE
);
2294 // We may want to remove the namespace scope if we're in an extern block (see
2295 // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952).
2296 let var_scope
= get_namespace_for_item(cx
, def_id
);
2297 let span
= tcx
.def_span(def_id
);
2299 let (file_metadata
, line_number
) = if !span
.is_dummy() {
2300 let loc
= span_start(cx
, span
);
2301 (file_metadata(cx
, &loc
.file
.name
, LOCAL_CRATE
), loc
.line
as c_uint
)
2303 (unknown_file_metadata(cx
), UNKNOWN_LINE_NUMBER
)
2306 let is_local_to_unit
= is_node_local_to_unit(cx
, def_id
);
2307 let variable_type
= Instance
::mono(cx
.tcx
, def_id
).ty(cx
.tcx
);
2308 let type_metadata
= type_metadata(cx
, variable_type
, span
);
2309 let var_name
= SmallCStr
::new(&tcx
.item_name(def_id
).as_str());
2310 let linkage_name
= if no_mangle
{
2313 let linkage_name
= mangled_name_of_instance(cx
, Instance
::mono(tcx
, def_id
));
2314 Some(SmallCStr
::new(&linkage_name
.name
.as_str()))
2317 let global_align
= cx
.align_of(variable_type
);
2320 llvm
::LLVMRustDIBuilderCreateStaticVariable(DIB(cx
),
2323 // If null, linkage_name field is omitted,
2324 // which is what we want for no_mangle statics
2325 linkage_name
.as_ref()
2326 .map_or(ptr
::null(), |name
| name
.as_ptr()),
2333 global_align
.bytes() as u32,
2338 /// Creates debug information for the given vtable, which is for the
2341 /// Adds the created metadata nodes directly to the crate's IR.
2342 pub fn create_vtable_metadata(cx
: &CodegenCx
<'ll
, 'tcx
>, ty
: Ty
<'tcx
>, vtable
: &'ll Value
) {
2343 if cx
.dbg_cx
.is_none() {
2347 let type_metadata
= type_metadata(cx
, ty
, syntax_pos
::DUMMY_SP
);
2350 // `LLVMRustDIBuilderCreateStructType()` wants an empty array. A null
2351 // pointer will lead to hard to trace and debug LLVM assertions
2352 // later on in `llvm/lib/IR/Value.cpp`.
2353 let empty_array
= create_DIArray(DIB(cx
), &[]);
2355 let name
= const_cstr
!("vtable");
2357 // Create a new one each time. We don't want metadata caching
2358 // here, because each vtable will refer to a unique containing
2360 let vtable_type
= llvm
::LLVMRustDIBuilderCreateStructType(
2364 unknown_file_metadata(cx
),
2365 UNKNOWN_LINE_NUMBER
,
2367 cx
.tcx
.data_layout
.pointer_align
.abi
.bits() as u32,
2368 DIFlags
::FlagArtificial
,
2372 Some(type_metadata
),
2376 llvm
::LLVMRustDIBuilderCreateStaticVariable(DIB(cx
),
2380 unknown_file_metadata(cx
),
2381 UNKNOWN_LINE_NUMBER
,
2390 /// Creates an "extension" of an existing `DIScope` into another file.
2391 pub fn extend_scope_to_file(
2392 cx
: &CodegenCx
<'ll
, '_
>,
2393 scope_metadata
: &'ll DIScope
,
2394 file
: &syntax_pos
::SourceFile
,
2395 defining_crate
: CrateNum
,
2396 ) -> &'ll DILexicalBlock
{
2397 let file_metadata
= file_metadata(cx
, &file
.name
, defining_crate
);
2399 llvm
::LLVMRustDIBuilderCreateLexicalBlockFile(