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};
11 use crate::value::Value;
12 use rustc_codegen_ssa::traits::*;
15 use crate::llvm::debuginfo::{DIArray, DIType, DIFile, DIScope, DIDescriptor,
16 DICompositeType, DILexicalBlock, DIFlags, DebugEmissionKind};
19 use crate::common::CodegenCx;
20 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
21 use rustc::hir::CodegenFnAttrFlags;
22 use rustc::hir::def::CtorKind;
23 use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
24 use rustc::ich::NodeIdHashingMode;
25 use rustc::mir::interpret::truncate;
26 use rustc_data_structures::fingerprint::Fingerprint;
27 use rustc::ty::Instance;
28 use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
29 use rustc::ty::layout::{self, Align, Integer, IntegerExt, LayoutOf,
30 PrimitiveExt, Size, TyLayout};
31 use rustc::ty::subst::UnpackedKind;
32 use rustc::session::config;
33 use rustc::util::nodemap::FxHashMap;
34 use rustc_fs_util::path_to_c_string;
35 use rustc_data_structures::small_c_str::SmallCStr;
36 use rustc_target::abi::HasDataLayout;
38 use libc::{c_uint, c_longlong};
39 use std::ffi::CString;
40 use std::fmt::{self, Write};
41 use std::hash::{Hash, Hasher};
44 use std::path::{Path, PathBuf};
46 use syntax::symbol::{Interner, InternedString, Symbol};
47 use syntax_pos::{self, Span, FileName};
49 impl PartialEq for llvm::Metadata {
50 fn eq(&self, other: &Self) -> bool {
55 impl Eq for llvm::Metadata {}
57 impl Hash for llvm::Metadata {
58 fn hash<H: Hasher>(&self, hasher: &mut H) {
59 (self as *const Self).hash(hasher);
63 impl fmt::Debug for llvm::Metadata {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 (self as *const Self).fmt(f)
70 // See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1
71 const DW_LANG_RUST: c_uint = 0x1c;
72 #[allow(non_upper_case_globals)]
73 const DW_ATE_boolean: c_uint = 0x02;
74 #[allow(non_upper_case_globals)]
75 const DW_ATE_float: c_uint = 0x04;
76 #[allow(non_upper_case_globals)]
77 const DW_ATE_signed: c_uint = 0x05;
78 #[allow(non_upper_case_globals)]
79 const DW_ATE_unsigned: c_uint = 0x07;
80 #[allow(non_upper_case_globals)]
81 const DW_ATE_unsigned_char: c_uint = 0x08;
83 pub const UNKNOWN_LINE_NUMBER: c_uint = 0;
84 pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
86 pub const NO_SCOPE_METADATA: Option<&DIScope> = None;
88 #[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
89 pub struct UniqueTypeId(ast::Name);
91 // The TypeMap is where the CrateDebugContext holds the type metadata nodes
92 // created so far. The metadata nodes are indexed by UniqueTypeId, and, for
93 // faster lookup, also by Ty. The TypeMap is responsible for creating
96 pub struct TypeMap<'ll, 'tcx> {
97 // The UniqueTypeIds created so far
98 unique_id_interner: Interner,
99 // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
100 unique_id_to_metadata: FxHashMap<UniqueTypeId, &'ll DIType>,
101 // A map from types to debuginfo metadata. This is a N:1 mapping.
102 type_to_metadata: FxHashMap<Ty<'tcx>, &'ll DIType>,
103 // A map from types to UniqueTypeId. This is a N:1 mapping.
104 type_to_unique_id: FxHashMap<Ty<'tcx>, UniqueTypeId>
107 impl TypeMap<'ll, 'tcx> {
108 // Adds a Ty to metadata mapping to the TypeMap. The method will fail if
109 // the mapping already exists.
110 fn register_type_with_metadata(
113 metadata: &'ll DIType,
115 if self.type_to_metadata.insert(type_, metadata).is_some() {
116 bug!("Type metadata for Ty '{}' is already in the TypeMap!", type_);
120 // Removes a Ty to metadata mapping
121 // This is useful when computing the metadata for a potentially
122 // recursive type (e.g. a function ptr of the form:
124 // fn foo() -> impl Copy { foo }
126 // This kind of type cannot be properly represented
127 // via LLVM debuginfo. As a workaround,
128 // we register a temporary Ty to metadata mapping
129 // for the function before we compute its actual metadat.a
130 // If the metadata computation ends up recursing back to the
131 // original function, it will use the temporary mapping
132 // for the inner self-reference, preventing us from
133 // recursing forever.
135 // This function is used to remove the temporary metadata
136 // mapping after we've computed the actual metadat
141 if self.type_to_metadata.remove(type_).is_none() {
142 bug!("Type metadata Ty '{}' is not in the TypeMap!", type_);
146 // Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
147 // fail if the mapping already exists.
148 fn register_unique_id_with_metadata(
150 unique_type_id: UniqueTypeId,
151 metadata: &'ll DIType,
153 if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
154 bug!("Type metadata for unique id '{}' is already in the TypeMap!",
155 self.get_unique_type_id_as_string(unique_type_id));
159 fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<&'ll DIType> {
160 self.type_to_metadata.get(&type_).cloned()
163 fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<&'ll DIType> {
164 self.unique_id_to_metadata.get(&unique_type_id).cloned()
167 // Get the string representation of a UniqueTypeId. This method will fail if
168 // the id is unknown.
169 fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> &str {
170 let UniqueTypeId(interner_key) = unique_type_id;
171 self.unique_id_interner.get(interner_key)
174 // Get the UniqueTypeId for the given type. If the UniqueTypeId for the given
175 // type has been requested before, this is just a table lookup. Otherwise an
176 // ID will be generated and stored for later lookup.
177 fn get_unique_type_id_of_type<'a>(&mut self, cx: &CodegenCx<'a, 'tcx>,
178 type_: Ty<'tcx>) -> UniqueTypeId {
179 // Let's see if we already have something in the cache
180 if let Some(unique_type_id) = self.type_to_unique_id.get(&type_).cloned() {
181 return unique_type_id;
183 // if not, generate one
185 // The hasher we are using to generate the UniqueTypeId. We want
186 // something that provides more than the 64 bits of the DefaultHasher.
187 let mut hasher = StableHasher::<Fingerprint>::new();
188 let mut hcx = cx.tcx.create_stable_hashing_context();
189 let type_ = cx.tcx.erase_regions(&type_);
190 hcx.while_hashing_spans(false, |hcx| {
191 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
192 type_.hash_stable(hcx, &mut hasher);
195 let unique_type_id = hasher.finish().to_hex();
197 let key = self.unique_id_interner.intern(&unique_type_id);
198 self.type_to_unique_id.insert(type_, UniqueTypeId(key));
200 return UniqueTypeId(key);
203 // Get the UniqueTypeId for an enum variant. Enum variants are not really
204 // types of their own, so they need special handling. We still need a
205 // UniqueTypeId for them, since to debuginfo they *are* real types.
206 fn get_unique_type_id_of_enum_variant<'a>(&mut self,
207 cx: &CodegenCx<'a, 'tcx>,
211 let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
212 let enum_variant_type_id = format!("{}::{}",
213 self.get_unique_type_id_as_string(enum_type_id),
215 let interner_key = self.unique_id_interner.intern(&enum_variant_type_id);
216 UniqueTypeId(interner_key)
219 // Get the unique type id string for an enum variant part.
220 // Variant parts are not types and shouldn't really have their own id,
221 // but it makes set_members_of_composite_type() simpler.
222 fn get_unique_type_id_str_of_enum_variant_part<'a>(&mut self,
223 enum_type_id: UniqueTypeId) -> &str {
224 let variant_part_type_id = format!("{}_variant_part",
225 self.get_unique_type_id_as_string(enum_type_id));
226 let interner_key = self.unique_id_interner.intern(&variant_part_type_id);
227 self.unique_id_interner.get(interner_key)
231 // A description of some recursive type. It can either be already finished (as
232 // with FinalMetadata) or it is not yet finished, but contains all information
233 // needed to generate the missing parts of the description. See the
234 // documentation section on Recursive Types at the top of this file for more
236 enum RecursiveTypeDescription<'ll, 'tcx> {
238 unfinished_type: Ty<'tcx>,
239 unique_type_id: UniqueTypeId,
240 metadata_stub: &'ll DICompositeType,
241 member_holding_stub: &'ll DICompositeType,
242 member_description_factory: MemberDescriptionFactory<'ll, 'tcx>,
244 FinalMetadata(&'ll DICompositeType)
247 fn create_and_register_recursive_type_forward_declaration(
248 cx: &CodegenCx<'ll, 'tcx>,
249 unfinished_type: Ty<'tcx>,
250 unique_type_id: UniqueTypeId,
251 metadata_stub: &'ll DICompositeType,
252 member_holding_stub: &'ll DICompositeType,
253 member_description_factory: MemberDescriptionFactory<'ll, 'tcx>,
254 ) -> RecursiveTypeDescription<'ll, 'tcx> {
256 // Insert the stub into the TypeMap in order to allow for recursive references
257 let mut type_map = debug_context(cx).type_map.borrow_mut();
258 type_map.register_unique_id_with_metadata(unique_type_id, metadata_stub);
259 type_map.register_type_with_metadata(unfinished_type, metadata_stub);
266 member_description_factory,
270 impl RecursiveTypeDescription<'ll, 'tcx> {
271 // Finishes up the description of the type in question (mostly by providing
272 // descriptions of the fields of the given type) and returns the final type
274 fn finalize(&self, cx: &CodegenCx<'ll, 'tcx>) -> MetadataCreationResult<'ll> {
276 FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
282 ref member_description_factory,
284 // Make sure that we have a forward declaration of the type in
285 // the TypeMap so that recursive references are possible. This
286 // will always be the case if the RecursiveTypeDescription has
287 // been properly created through the
288 // create_and_register_recursive_type_forward_declaration()
291 let type_map = debug_context(cx).type_map.borrow();
292 if type_map.find_metadata_for_unique_id(unique_type_id).is_none() ||
293 type_map.find_metadata_for_type(unfinished_type).is_none() {
294 bug!("Forward declaration of potentially recursive type \
295 '{:?}' was not found in TypeMap!",
300 // ... then create the member descriptions ...
301 let member_descriptions =
302 member_description_factory.create_member_descriptions(cx);
304 // ... and attach them to the stub to complete it.
305 set_members_of_composite_type(cx,
308 member_descriptions);
309 return MetadataCreationResult::new(metadata_stub, true);
315 // Returns from the enclosing function if the type metadata with the given
316 // unique id can be found in the type map
317 macro_rules! return_if_metadata_created_in_meantime {
318 ($cx: expr, $unique_type_id: expr) => (
319 if let Some(metadata) = debug_context($cx).type_map
321 .find_metadata_for_unique_id($unique_type_id)
323 return MetadataCreationResult::new(metadata, true);
328 fn fixed_vec_metadata(
329 cx: &CodegenCx<'ll, 'tcx>,
330 unique_type_id: UniqueTypeId,
331 array_or_slice_type: Ty<'tcx>,
332 element_type: Ty<'tcx>,
334 ) -> MetadataCreationResult<'ll> {
335 let element_type_metadata = type_metadata(cx, element_type, span);
337 return_if_metadata_created_in_meantime!(cx, unique_type_id);
339 let (size, align) = cx.size_and_align_of(array_or_slice_type);
341 let upper_bound = match array_or_slice_type.sty {
342 ty::Array(_, len) => {
343 len.unwrap_usize(cx.tcx) as c_longlong
348 let subrange = unsafe {
349 Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound))
352 let subscripts = create_DIArray(DIB(cx), &[subrange]);
353 let metadata = unsafe {
354 llvm::LLVMRustDIBuilderCreateArrayType(
358 element_type_metadata,
362 return MetadataCreationResult::new(metadata, false);
365 fn vec_slice_metadata(
366 cx: &CodegenCx<'ll, 'tcx>,
367 slice_ptr_type: Ty<'tcx>,
368 element_type: Ty<'tcx>,
369 unique_type_id: UniqueTypeId,
371 ) -> MetadataCreationResult<'ll> {
372 let data_ptr_type = cx.tcx.mk_imm_ptr(element_type);
374 let data_ptr_metadata = type_metadata(cx, data_ptr_type, span);
376 return_if_metadata_created_in_meantime!(cx, unique_type_id);
378 let slice_type_name = compute_debuginfo_type_name(cx, slice_ptr_type, true);
380 let (pointer_size, pointer_align) = cx.size_and_align_of(data_ptr_type);
381 let (usize_size, usize_align) = cx.size_and_align_of(cx.tcx.types.usize);
383 let member_descriptions = vec![
385 name: "data_ptr".to_owned(),
386 type_metadata: data_ptr_metadata,
389 align: pointer_align,
390 flags: DIFlags::FlagZero,
394 name: "length".to_owned(),
395 type_metadata: type_metadata(cx, cx.tcx.types.usize, span),
396 offset: pointer_size,
399 flags: DIFlags::FlagZero,
404 let file_metadata = unknown_file_metadata(cx);
406 let metadata = composite_type_metadata(cx,
408 &slice_type_name[..],
414 MetadataCreationResult::new(metadata, false)
417 fn subroutine_type_metadata(
418 cx: &CodegenCx<'ll, 'tcx>,
419 unique_type_id: UniqueTypeId,
420 signature: ty::PolyFnSig<'tcx>,
422 ) -> MetadataCreationResult<'ll> {
423 let signature = cx.tcx.normalize_erasing_late_bound_regions(
424 ty::ParamEnv::reveal_all(),
428 let signature_metadata: Vec<_> = iter::once(
430 match signature.output().sty {
431 ty::Tuple(ref tys) if tys.is_empty() => None,
432 _ => Some(type_metadata(cx, signature.output(), span))
436 signature.inputs().iter().map(|argument_type| {
437 Some(type_metadata(cx, argument_type, span))
441 return_if_metadata_created_in_meantime!(cx, unique_type_id);
443 return MetadataCreationResult::new(
445 llvm::LLVMRustDIBuilderCreateSubroutineType(
447 unknown_file_metadata(cx),
448 create_DIArray(DIB(cx), &signature_metadata[..]))
453 // FIXME(1563) This is all a bit of a hack because 'trait pointer' is an ill-
454 // defined concept. For the case of an actual trait pointer (i.e., Box<Trait>,
455 // &Trait), trait_object_type should be the whole thing (e.g, Box<Trait>) and
456 // trait_type should be the actual trait (e.g., Trait). Where the trait is part
457 // of a DST struct, there is no trait_object_type and the results of this
458 // function will be a little bit weird.
459 fn trait_pointer_metadata(
460 cx: &CodegenCx<'ll, 'tcx>,
461 trait_type: Ty<'tcx>,
462 trait_object_type: Option<Ty<'tcx>>,
463 unique_type_id: UniqueTypeId,
465 // The implementation provided here is a stub. It makes sure that the trait
466 // type is assigned the correct name, size, namespace, and source location.
467 // But it does not describe the trait's methods.
469 let containing_scope = match trait_type.sty {
470 ty::Dynamic(ref data, ..) =>
471 data.principal_def_id().map(|did| get_namespace_for_item(cx, did)),
473 bug!("debuginfo: Unexpected trait-object type in \
474 trait_pointer_metadata(): {:?}",
479 let trait_object_type = trait_object_type.unwrap_or(trait_type);
480 let trait_type_name =
481 compute_debuginfo_type_name(cx, trait_object_type, false);
483 let file_metadata = unknown_file_metadata(cx);
485 let layout = cx.layout_of(cx.tcx.mk_mut_ptr(trait_type));
487 assert_eq!(abi::FAT_PTR_ADDR, 0);
488 assert_eq!(abi::FAT_PTR_EXTRA, 1);
490 let data_ptr_field = layout.field(cx, 0);
491 let vtable_field = layout.field(cx, 1);
492 let member_descriptions = vec![
494 name: "pointer".to_owned(),
495 type_metadata: type_metadata(cx,
496 cx.tcx.mk_mut_ptr(cx.tcx.types.u8),
497 syntax_pos::DUMMY_SP),
498 offset: layout.fields.offset(0),
499 size: data_ptr_field.size,
500 align: data_ptr_field.align.abi,
501 flags: DIFlags::FlagArtificial,
505 name: "vtable".to_owned(),
506 type_metadata: type_metadata(cx, vtable_field.ty, syntax_pos::DUMMY_SP),
507 offset: layout.fields.offset(1),
508 size: vtable_field.size,
509 align: vtable_field.align.abi,
510 flags: DIFlags::FlagArtificial,
515 composite_type_metadata(cx,
517 &trait_type_name[..],
522 syntax_pos::DUMMY_SP)
525 pub fn type_metadata(
526 cx: &CodegenCx<'ll, 'tcx>,
528 usage_site_span: Span,
530 // Get the unique type id of this type.
531 let unique_type_id = {
532 let mut type_map = debug_context(cx).type_map.borrow_mut();
533 // First, try to find the type in TypeMap. If we have seen it before, we
534 // can exit early here.
535 match type_map.find_metadata_for_type(t) {
540 // The Ty is not in the TypeMap but maybe we have already seen
541 // an equivalent type (e.g., only differing in region arguments).
542 // In order to find out, generate the unique type id and look
544 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
545 match type_map.find_metadata_for_unique_id(unique_type_id) {
547 // There is already an equivalent type in the TypeMap.
548 // Register this Ty as an alias in the cache and
549 // return the cached metadata.
550 type_map.register_type_with_metadata(t, metadata);
554 // There really is no type metadata for this type, so
555 // proceed by creating it.
563 debug!("type_metadata: {:?}", t);
565 let ptr_metadata = |ty: Ty<'tcx>| {
568 Ok(vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span))
571 Ok(vec_slice_metadata(cx, t, cx.tcx.types.u8, unique_type_id, usage_site_span))
574 Ok(MetadataCreationResult::new(
575 trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
579 let pointee_metadata = type_metadata(cx, ty, usage_site_span);
581 if let Some(metadata) = debug_context(cx).type_map
583 .find_metadata_for_unique_id(unique_type_id)
585 return Err(metadata);
588 Ok(MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
594 let MetadataCreationResult { metadata, already_stored_in_typemap } = match t.sty {
601 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
603 ty::Tuple(ref elements) if elements.is_empty() => {
604 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
608 fixed_vec_metadata(cx, unique_type_id, t, typ, usage_site_span)
611 fixed_vec_metadata(cx, unique_type_id, t, cx.tcx.types.i8, usage_site_span)
614 MetadataCreationResult::new(
615 trait_pointer_metadata(cx, t, None, unique_type_id),
619 MetadataCreationResult::new(
620 foreign_type_metadata(cx, t, unique_type_id),
623 ty::RawPtr(ty::TypeAndMut{ty, ..}) |
624 ty::Ref(_, ty, _) => {
625 match ptr_metadata(ty) {
627 Err(metadata) => return metadata,
630 ty::Adt(def, _) if def.is_box() => {
631 match ptr_metadata(t.boxed_ty()) {
633 Err(metadata) => return metadata,
636 ty::FnDef(..) | ty::FnPtr(_) => {
638 if let Some(metadata) = debug_context(cx).type_map
640 .find_metadata_for_unique_id(unique_type_id)
645 // It's possible to create a self-referential
646 // type in Rust by using 'impl trait':
648 // fn foo() -> impl Copy { foo }
650 // See TypeMap::remove_type for more detals
651 // about the workaround
655 // The choice of type here is pretty arbitrary -
656 // anything reading the debuginfo for a recursive
657 // type is going to see *somthing* weird - the only
658 // question is what exactly it will see
659 let (size, align) = cx.size_and_align_of(t);
660 llvm::LLVMRustDIBuilderCreateBasicType(
662 SmallCStr::new("<recur_type>").as_ptr(),
671 let type_map = &debug_context(cx).type_map;
672 type_map.borrow_mut().register_type_with_metadata(t, temp_type);
674 let fn_metadata = subroutine_type_metadata(cx,
677 usage_site_span).metadata;
679 type_map.borrow_mut().remove_type(t);
682 // This is actually a function pointer, so wrap it in pointer DI
683 MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false)
686 ty::Closure(def_id, substs) => {
687 let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx).collect();
688 prepare_tuple_metadata(cx,
692 usage_site_span).finalize(cx)
694 ty::Generator(def_id, substs, _) => {
695 let upvar_tys : Vec<_> = substs.field_tys(def_id, cx.tcx).map(|t| {
696 cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t)
698 prepare_tuple_metadata(cx,
702 usage_site_span).finalize(cx)
704 ty::Adt(def, ..) => match def.adt_kind() {
706 prepare_struct_metadata(cx,
709 usage_site_span).finalize(cx)
712 prepare_union_metadata(cx,
715 usage_site_span).finalize(cx)
718 prepare_enum_metadata(cx,
722 usage_site_span).finalize(cx)
725 ty::Tuple(ref elements) => {
726 prepare_tuple_metadata(cx,
730 usage_site_span).finalize(cx)
733 bug!("debuginfo: unexpected type in type_metadata: {:?}", t)
738 let mut type_map = debug_context(cx).type_map.borrow_mut();
740 if already_stored_in_typemap {
741 // Also make sure that we already have a TypeMap entry for the unique type id.
742 let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
743 Some(metadata) => metadata,
745 span_bug!(usage_site_span,
746 "Expected type metadata for unique \
747 type id '{}' to already be in \
748 the debuginfo::TypeMap but it \
750 type_map.get_unique_type_id_as_string(unique_type_id),
755 match type_map.find_metadata_for_type(t) {
757 if metadata != metadata_for_uid {
758 span_bug!(usage_site_span,
759 "Mismatch between Ty and \
760 UniqueTypeId maps in \
761 debuginfo::TypeMap. \
762 UniqueTypeId={}, Ty={}",
763 type_map.get_unique_type_id_as_string(unique_type_id),
768 type_map.register_type_with_metadata(t, metadata);
772 type_map.register_type_with_metadata(t, metadata);
773 type_map.register_unique_id_with_metadata(unique_type_id, metadata);
780 pub fn file_metadata(cx: &CodegenCx<'ll, '_>,
781 file_name: &FileName,
782 defining_crate: CrateNum) -> &'ll DIFile {
783 debug!("file_metadata: file_name: {}, defining_crate: {}",
787 let directory = if defining_crate == LOCAL_CRATE {
788 &cx.sess().working_dir.0
790 // If the path comes from an upstream crate we assume it has been made
791 // independent of the compiler's working directory one way or another.
795 file_metadata_raw(cx, &file_name.to_string(), &directory.to_string_lossy())
798 pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
799 file_metadata_raw(cx, "<unknown>", "")
802 fn file_metadata_raw(cx: &CodegenCx<'ll, '_>,
806 let key = (Symbol::intern(file_name), Symbol::intern(directory));
808 if let Some(file_metadata) = debug_context(cx).created_files.borrow().get(&key) {
809 return *file_metadata;
812 debug!("file_metadata: file_name: {}, directory: {}", file_name, directory);
814 let file_name = SmallCStr::new(file_name);
815 let directory = SmallCStr::new(directory);
817 let file_metadata = unsafe {
818 llvm::LLVMRustDIBuilderCreateFile(DIB(cx),
823 let mut created_files = debug_context(cx).created_files.borrow_mut();
824 created_files.insert(key, file_metadata);
828 fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
829 debug!("basic_type_metadata: {:?}", t);
831 let (name, encoding) = match t.sty {
832 ty::Never => ("!", DW_ATE_unsigned),
833 ty::Tuple(ref elements) if elements.is_empty() =>
834 ("()", DW_ATE_unsigned),
835 ty::Bool => ("bool", DW_ATE_boolean),
836 ty::Char => ("char", DW_ATE_unsigned_char),
838 (int_ty.ty_to_string(), DW_ATE_signed)
840 ty::Uint(uint_ty) => {
841 (uint_ty.ty_to_string(), DW_ATE_unsigned)
843 ty::Float(float_ty) => {
844 (float_ty.ty_to_string(), DW_ATE_float)
846 _ => bug!("debuginfo::basic_type_metadata - t is invalid type")
849 let (size, align) = cx.size_and_align_of(t);
850 let name = SmallCStr::new(name);
851 let ty_metadata = unsafe {
852 llvm::LLVMRustDIBuilderCreateBasicType(
863 fn foreign_type_metadata(
864 cx: &CodegenCx<'ll, 'tcx>,
866 unique_type_id: UniqueTypeId,
868 debug!("foreign_type_metadata: {:?}", t);
870 let name = compute_debuginfo_type_name(cx, t, false);
871 create_struct_stub(cx, t, &name, unique_type_id, NO_SCOPE_METADATA)
874 fn pointer_type_metadata(
875 cx: &CodegenCx<'ll, 'tcx>,
876 pointer_type: Ty<'tcx>,
877 pointee_type_metadata: &'ll DIType,
879 let (pointer_size, pointer_align) = cx.size_and_align_of(pointer_type);
880 let name = compute_debuginfo_type_name(cx, pointer_type, false);
881 let name = SmallCStr::new(&name);
883 llvm::LLVMRustDIBuilderCreatePointerType(
885 pointee_type_metadata,
887 pointer_align.bits() as u32,
892 pub fn compile_unit_metadata(tcx: TyCtxt<'_, '_, '_>,
893 codegen_unit_name: &str,
894 debug_context: &CrateDebugContext<'ll, '_>)
895 -> &'ll DIDescriptor {
896 let mut name_in_debuginfo = match tcx.sess.local_crate_source_file {
897 Some(ref path) => path.clone(),
898 None => PathBuf::from(&*tcx.crate_name(LOCAL_CRATE).as_str()),
901 // The OSX linker has an idiosyncrasy where it will ignore some debuginfo
902 // if multiple object files with the same DW_AT_name are linked together.
903 // As a workaround we generate unique names for each object file. Those do
904 // not correspond to an actual source file but that should be harmless.
905 if tcx.sess.target.target.options.is_like_osx {
906 name_in_debuginfo.push("@");
907 name_in_debuginfo.push(codegen_unit_name);
910 debug!("compile_unit_metadata: {:?}", name_in_debuginfo);
911 // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
912 let producer = format!("clang LLVM (rustc version {})",
913 (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
915 let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
916 let name_in_debuginfo = SmallCStr::new(&name_in_debuginfo);
917 let work_dir = SmallCStr::new(&tcx.sess.working_dir.0.to_string_lossy());
918 let producer = CString::new(producer).unwrap();
920 let split_name = "\0";
921 let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
924 let file_metadata = llvm::LLVMRustDIBuilderCreateFile(
925 debug_context.builder, name_in_debuginfo.as_ptr(), work_dir.as_ptr());
927 let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
928 debug_context.builder,
932 tcx.sess.opts.optimize != config::OptLevel::No,
933 flags.as_ptr() as *const _,
935 split_name.as_ptr() as *const _,
938 if tcx.sess.opts.debugging_opts.profile {
939 let cu_desc_metadata = llvm::LLVMRustMetadataAsValue(debug_context.llcontext,
943 path_to_mdstring(debug_context.llcontext,
944 &tcx.output_filenames(LOCAL_CRATE).with_extension("gcno")),
945 path_to_mdstring(debug_context.llcontext,
946 &tcx.output_filenames(LOCAL_CRATE).with_extension("gcda")),
949 let gcov_metadata = llvm::LLVMMDNodeInContext(debug_context.llcontext,
950 gcov_cu_info.as_ptr(),
951 gcov_cu_info.len() as c_uint);
953 let llvm_gcov_ident = const_cstr!("llvm.gcov");
954 llvm::LLVMAddNamedMetadataOperand(debug_context.llmod,
955 llvm_gcov_ident.as_ptr(),
959 return unit_metadata;
962 fn path_to_mdstring(llcx: &'ll llvm::Context, path: &Path) -> &'ll Value {
963 let path_str = path_to_c_string(path);
965 llvm::LLVMMDStringInContext(llcx,
967 path_str.as_bytes().len() as c_uint)
972 struct MetadataCreationResult<'ll> {
973 metadata: &'ll DIType,
974 already_stored_in_typemap: bool
977 impl MetadataCreationResult<'ll> {
978 fn new(metadata: &'ll DIType, already_stored_in_typemap: bool) -> Self {
979 MetadataCreationResult {
981 already_stored_in_typemap,
986 // Description of a type member, which can either be a regular field (as in
987 // structs or tuples) or an enum variant.
989 struct MemberDescription<'ll> {
991 type_metadata: &'ll DIType,
996 discriminant: Option<u64>,
999 // A factory for MemberDescriptions. It produces a list of member descriptions
1000 // for some record-like type. MemberDescriptionFactories are used to defer the
1001 // creation of type member descriptions in order to break cycles arising from
1002 // recursive type definitions.
1003 enum MemberDescriptionFactory<'ll, 'tcx> {
1004 StructMDF(StructMemberDescriptionFactory<'tcx>),
1005 TupleMDF(TupleMemberDescriptionFactory<'tcx>),
1006 EnumMDF(EnumMemberDescriptionFactory<'ll, 'tcx>),
1007 UnionMDF(UnionMemberDescriptionFactory<'tcx>),
1008 VariantMDF(VariantMemberDescriptionFactory<'ll, 'tcx>)
1011 impl MemberDescriptionFactory<'ll, 'tcx> {
1012 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1013 -> Vec<MemberDescription<'ll>> {
1015 StructMDF(ref this) => {
1016 this.create_member_descriptions(cx)
1018 TupleMDF(ref this) => {
1019 this.create_member_descriptions(cx)
1021 EnumMDF(ref this) => {
1022 this.create_member_descriptions(cx)
1024 UnionMDF(ref this) => {
1025 this.create_member_descriptions(cx)
1027 VariantMDF(ref this) => {
1028 this.create_member_descriptions(cx)
1034 //=-----------------------------------------------------------------------------
1036 //=-----------------------------------------------------------------------------
1038 // Creates MemberDescriptions for the fields of a struct
1039 struct StructMemberDescriptionFactory<'tcx> {
1041 variant: &'tcx ty::VariantDef,
1045 impl<'tcx> StructMemberDescriptionFactory<'tcx> {
1046 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1047 -> Vec<MemberDescription<'ll>> {
1048 let layout = cx.layout_of(self.ty);
1049 self.variant.fields.iter().enumerate().map(|(i, f)| {
1050 let name = if self.variant.ctor_kind == CtorKind::Fn {
1055 let field = layout.field(cx, i);
1058 type_metadata: type_metadata(cx, field.ty, self.span),
1059 offset: layout.fields.offset(i),
1061 align: field.align.abi,
1062 flags: DIFlags::FlagZero,
1070 fn prepare_struct_metadata(
1071 cx: &CodegenCx<'ll, 'tcx>,
1072 struct_type: Ty<'tcx>,
1073 unique_type_id: UniqueTypeId,
1075 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1076 let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
1078 let (struct_def_id, variant) = match struct_type.sty {
1079 ty::Adt(def, _) => (def.did, def.non_enum_variant()),
1080 _ => bug!("prepare_struct_metadata on a non-ADT")
1083 let containing_scope = get_namespace_for_item(cx, struct_def_id);
1085 let struct_metadata_stub = create_struct_stub(cx,
1089 Some(containing_scope));
1091 create_and_register_recursive_type_forward_declaration(
1095 struct_metadata_stub,
1096 struct_metadata_stub,
1097 StructMDF(StructMemberDescriptionFactory {
1105 //=-----------------------------------------------------------------------------
1107 //=-----------------------------------------------------------------------------
1109 // Creates MemberDescriptions for the fields of a tuple
1110 struct TupleMemberDescriptionFactory<'tcx> {
1112 component_types: Vec<Ty<'tcx>>,
1116 impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
1117 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1118 -> Vec<MemberDescription<'ll>> {
1119 let layout = cx.layout_of(self.ty);
1120 self.component_types.iter().enumerate().map(|(i, &component_type)| {
1121 let (size, align) = cx.size_and_align_of(component_type);
1123 name: format!("__{}", i),
1124 type_metadata: type_metadata(cx, component_type, self.span),
1125 offset: layout.fields.offset(i),
1128 flags: DIFlags::FlagZero,
1135 fn prepare_tuple_metadata(
1136 cx: &CodegenCx<'ll, 'tcx>,
1137 tuple_type: Ty<'tcx>,
1138 component_types: &[Ty<'tcx>],
1139 unique_type_id: UniqueTypeId,
1141 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1142 let tuple_name = compute_debuginfo_type_name(cx, tuple_type, false);
1144 let struct_stub = create_struct_stub(cx,
1150 create_and_register_recursive_type_forward_declaration(
1156 TupleMDF(TupleMemberDescriptionFactory {
1158 component_types: component_types.to_vec(),
1164 //=-----------------------------------------------------------------------------
1166 //=-----------------------------------------------------------------------------
1168 struct UnionMemberDescriptionFactory<'tcx> {
1169 layout: TyLayout<'tcx>,
1170 variant: &'tcx ty::VariantDef,
1174 impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
1175 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1176 -> Vec<MemberDescription<'ll>> {
1177 self.variant.fields.iter().enumerate().map(|(i, f)| {
1178 let field = self.layout.field(cx, i);
1180 name: f.ident.to_string(),
1181 type_metadata: type_metadata(cx, field.ty, self.span),
1184 align: field.align.abi,
1185 flags: DIFlags::FlagZero,
1192 fn prepare_union_metadata(
1193 cx: &CodegenCx<'ll, 'tcx>,
1194 union_type: Ty<'tcx>,
1195 unique_type_id: UniqueTypeId,
1197 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1198 let union_name = compute_debuginfo_type_name(cx, union_type, false);
1200 let (union_def_id, variant) = match union_type.sty {
1201 ty::Adt(def, _) => (def.did, def.non_enum_variant()),
1202 _ => bug!("prepare_union_metadata on a non-ADT")
1205 let containing_scope = get_namespace_for_item(cx, union_def_id);
1207 let union_metadata_stub = create_union_stub(cx,
1213 create_and_register_recursive_type_forward_declaration(
1217 union_metadata_stub,
1218 union_metadata_stub,
1219 UnionMDF(UnionMemberDescriptionFactory {
1220 layout: cx.layout_of(union_type),
1227 //=-----------------------------------------------------------------------------
1229 //=-----------------------------------------------------------------------------
1231 // DWARF variant support is only available starting in LLVM 8.
1232 // Although the earlier enum debug info output did not work properly
1233 // in all situations, it is better for the time being to continue to
1234 // sometimes emit the old style rather than emit something completely
1235 // useless when rust is compiled against LLVM 6 or older. LLVM 7
1236 // contains an early version of the DWARF variant support, and will
1237 // crash when handling the new debug info format. This function
1238 // decides which representation will be emitted.
1239 fn use_enum_fallback(cx: &CodegenCx<'_, '_>) -> bool {
1240 // On MSVC we have to use the fallback mode, because LLVM doesn't
1241 // lower variant parts to PDB.
1242 return cx.sess().target.target.options.is_like_msvc
1243 // LLVM version 7 did not release with an important bug fix;
1244 // but the required patch is in the LLVM 8. Rust LLVM reports
1246 || llvm_util::get_major_version() < 8;
1249 // Describes the members of an enum value: An enum is described as a union of
1250 // structs in DWARF. This MemberDescriptionFactory provides the description for
1251 // the members of this union; so for every variant of the given enum, this
1252 // factory will produce one MemberDescription (all with no name and a fixed
1253 // offset of zero bytes).
1254 struct EnumMemberDescriptionFactory<'ll, 'tcx> {
1255 enum_type: Ty<'tcx>,
1256 layout: TyLayout<'tcx>,
1257 discriminant_type_metadata: Option<&'ll DIType>,
1258 containing_scope: &'ll DIScope,
1262 impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1263 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1264 -> Vec<MemberDescription<'ll>> {
1265 let adt = &self.enum_type.ty_adt_def().unwrap();
1267 // This will always find the metadata in the type map.
1268 let fallback = use_enum_fallback(cx);
1269 let self_metadata = if fallback {
1270 self.containing_scope
1272 type_metadata(cx, self.enum_type, self.span)
1275 match self.layout.variants {
1276 layout::Variants::Single { .. } if adt.variants.is_empty() => vec![],
1277 layout::Variants::Single { index } => {
1278 let (variant_type_metadata, member_description_factory) =
1279 describe_enum_variant(cx,
1281 &adt.variants[index],
1286 let member_descriptions =
1287 member_description_factory.create_member_descriptions(cx);
1289 set_members_of_composite_type(cx,
1291 variant_type_metadata,
1292 member_descriptions);
1298 adt.variants[index].ident.as_str().to_string()
1300 type_metadata: variant_type_metadata,
1302 size: self.layout.size,
1303 align: self.layout.align.abi,
1304 flags: DIFlags::FlagZero,
1309 layout::Variants::Multiple {
1310 discr_kind: layout::DiscriminantKind::Tag,
1314 let discriminant_info = if fallback {
1315 RegularDiscriminant(self.discriminant_type_metadata
1318 // This doesn't matter in this case.
1321 variants.iter_enumerated().map(|(i, _)| {
1322 let variant = self.layout.for_variant(cx, i);
1323 let (variant_type_metadata, member_desc_factory) =
1324 describe_enum_variant(cx,
1331 let member_descriptions = member_desc_factory
1332 .create_member_descriptions(cx);
1334 set_members_of_composite_type(cx,
1336 variant_type_metadata,
1337 member_descriptions);
1342 adt.variants[i].ident.as_str().to_string()
1344 type_metadata: variant_type_metadata,
1346 size: self.layout.size,
1347 align: self.layout.align.abi,
1348 flags: DIFlags::FlagZero,
1349 discriminant: Some(self.layout.ty.ty_adt_def().unwrap()
1350 .discriminant_for_variant(cx.tcx, i)
1355 layout::Variants::Multiple {
1356 discr_kind: layout::DiscriminantKind::Niche {
1365 let variant = self.layout.for_variant(cx, dataful_variant);
1366 // Create a description of the non-null variant
1367 let (variant_type_metadata, member_description_factory) =
1368 describe_enum_variant(cx,
1370 &adt.variants[dataful_variant],
1371 OptimizedDiscriminant,
1372 self.containing_scope,
1375 let variant_member_descriptions =
1376 member_description_factory.create_member_descriptions(cx);
1378 set_members_of_composite_type(cx,
1380 variant_type_metadata,
1381 variant_member_descriptions);
1383 // Encode the information about the null variant in the union
1385 let mut name = String::from("RUST$ENCODED$ENUM$");
1386 // Right now it's not even going to work for `niche_start > 0`,
1387 // and for multiple niche variants it only supports the first.
1388 fn compute_field_path<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
1390 layout: TyLayout<'tcx>,
1393 for i in 0..layout.fields.count() {
1394 let field_offset = layout.fields.offset(i);
1395 if field_offset > offset {
1398 let inner_offset = offset - field_offset;
1399 let field = layout.field(cx, i);
1400 if inner_offset + size <= field.size {
1401 write!(name, "{}$", i).unwrap();
1402 compute_field_path(cx, name, field, inner_offset, size);
1406 compute_field_path(cx, &mut name,
1408 self.layout.fields.offset(0),
1409 self.layout.field(cx, 0).size);
1410 name.push_str(&adt.variants[*niche_variants.start()].ident.as_str());
1412 // Create the (singleton) list of descriptions of union members.
1416 type_metadata: variant_type_metadata,
1419 align: variant.align.abi,
1420 flags: DIFlags::FlagZero,
1425 variants.iter_enumerated().map(|(i, _)| {
1426 let variant = self.layout.for_variant(cx, i);
1427 let (variant_type_metadata, member_desc_factory) =
1428 describe_enum_variant(cx,
1431 OptimizedDiscriminant,
1435 let member_descriptions = member_desc_factory
1436 .create_member_descriptions(cx);
1438 set_members_of_composite_type(cx,
1440 variant_type_metadata,
1441 member_descriptions);
1443 let niche_value = if i == dataful_variant {
1446 let value = (i.as_u32() as u128)
1447 .wrapping_sub(niche_variants.start().as_u32() as u128)
1448 .wrapping_add(niche_start);
1449 let value = truncate(value, discr.value.size(cx));
1450 // NOTE(eddyb) do *NOT* remove this assert, until
1451 // we pass the full 128-bit value to LLVM, otherwise
1452 // truncation will be silent and remain undetected.
1453 assert_eq!(value as u64 as u128, value);
1458 name: adt.variants[i].ident.as_str().to_string(),
1459 type_metadata: variant_type_metadata,
1461 size: self.layout.size,
1462 align: self.layout.align.abi,
1463 flags: DIFlags::FlagZero,
1464 discriminant: niche_value,
1473 // Creates MemberDescriptions for the fields of a single enum variant.
1474 struct VariantMemberDescriptionFactory<'ll, 'tcx> {
1475 // Cloned from the layout::Struct describing the variant.
1476 offsets: Vec<layout::Size>,
1477 args: Vec<(String, Ty<'tcx>)>,
1478 discriminant_type_metadata: Option<&'ll DIType>,
1482 impl VariantMemberDescriptionFactory<'ll, 'tcx> {
1483 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1484 -> Vec<MemberDescription<'ll>> {
1485 self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
1486 let (size, align) = cx.size_and_align_of(ty);
1488 name: name.to_string(),
1489 type_metadata: if use_enum_fallback(cx) {
1490 match self.discriminant_type_metadata {
1491 Some(metadata) if i == 0 => metadata,
1492 _ => type_metadata(cx, ty, self.span)
1495 type_metadata(cx, ty, self.span)
1497 offset: self.offsets[i],
1500 flags: DIFlags::FlagZero,
1507 #[derive(Copy, Clone)]
1508 enum EnumDiscriminantInfo<'ll> {
1509 RegularDiscriminant(&'ll DIType),
1510 OptimizedDiscriminant,
1514 // Returns a tuple of (1) type_metadata_stub of the variant, (2) a
1515 // MemberDescriptionFactory for producing the descriptions of the
1516 // fields of the variant. This is a rudimentary version of a full
1517 // RecursiveTypeDescription.
1518 fn describe_enum_variant(
1519 cx: &CodegenCx<'ll, 'tcx>,
1520 layout: layout::TyLayout<'tcx>,
1521 variant: &'tcx ty::VariantDef,
1522 discriminant_info: EnumDiscriminantInfo<'ll>,
1523 containing_scope: &'ll DIScope,
1525 ) -> (&'ll DICompositeType, MemberDescriptionFactory<'ll, 'tcx>) {
1526 let variant_name = variant.ident.as_str();
1527 let unique_type_id = debug_context(cx).type_map
1529 .get_unique_type_id_of_enum_variant(
1534 let metadata_stub = create_struct_stub(cx,
1538 Some(containing_scope));
1540 // Build an array of (field name, field type) pairs to be captured in the factory closure.
1541 let (offsets, args) = if use_enum_fallback(cx) {
1542 // If this is not a univariant enum, there is also the discriminant field.
1543 let (discr_offset, discr_arg) = match discriminant_info {
1544 RegularDiscriminant(_) => {
1545 // We have the layout of an enum variant, we need the layout of the outer enum
1546 let enum_layout = cx.layout_of(layout.ty);
1547 (Some(enum_layout.fields.offset(0)),
1548 Some(("RUST$ENUM$DISR".to_owned(), enum_layout.field(cx, 0).ty)))
1553 discr_offset.into_iter().chain((0..layout.fields.count()).map(|i| {
1554 layout.fields.offset(i)
1556 discr_arg.into_iter().chain((0..layout.fields.count()).map(|i| {
1557 let name = if variant.ctor_kind == CtorKind::Fn {
1560 variant.fields[i].ident.to_string()
1562 (name, layout.field(cx, i).ty)
1567 (0..layout.fields.count()).map(|i| {
1568 layout.fields.offset(i)
1570 (0..layout.fields.count()).map(|i| {
1571 let name = if variant.ctor_kind == CtorKind::Fn {
1574 variant.fields[i].ident.to_string()
1576 (name, layout.field(cx, i).ty)
1581 let member_description_factory =
1582 VariantMDF(VariantMemberDescriptionFactory {
1585 discriminant_type_metadata: match discriminant_info {
1586 RegularDiscriminant(discriminant_type_metadata) => {
1587 Some(discriminant_type_metadata)
1594 (metadata_stub, member_description_factory)
1597 fn prepare_enum_metadata(
1598 cx: &CodegenCx<'ll, 'tcx>,
1599 enum_type: Ty<'tcx>,
1601 unique_type_id: UniqueTypeId,
1603 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1604 let enum_name = compute_debuginfo_type_name(cx, enum_type, false);
1606 let containing_scope = get_namespace_for_item(cx, enum_def_id);
1607 // FIXME: This should emit actual file metadata for the enum, but we
1608 // currently can't get the necessary information when it comes to types
1609 // imported from other crates. Formerly we violated the ODR when performing
1610 // LTO because we emitted debuginfo for the same type with varying file
1611 // metadata, so as a workaround we pretend that the type comes from
1613 let file_metadata = unknown_file_metadata(cx);
1615 let discriminant_type_metadata = |discr: layout::Primitive| {
1616 let def = enum_type.ty_adt_def().unwrap();
1617 let enumerators_metadata: Vec<_> = def.discriminants(cx.tcx)
1619 .map(|((_, discr), v)| {
1620 let name = SmallCStr::new(&v.ident.as_str());
1622 Some(llvm::LLVMRustDIBuilderCreateEnumerator(
1625 // FIXME: what if enumeration has i128 discriminant?
1631 let disr_type_key = (enum_def_id, discr);
1632 let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
1634 .get(&disr_type_key).cloned();
1635 match cached_discriminant_type_metadata {
1636 Some(discriminant_type_metadata) => discriminant_type_metadata,
1638 let (discriminant_size, discriminant_align) =
1639 (discr.size(cx), discr.align(cx));
1640 let discriminant_base_type_metadata =
1641 type_metadata(cx, discr.to_ty(cx.tcx), syntax_pos::DUMMY_SP);
1642 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id).as_str();
1644 let name = SmallCStr::new(&discriminant_name);
1645 let discriminant_type_metadata = unsafe {
1646 llvm::LLVMRustDIBuilderCreateEnumerationType(
1651 UNKNOWN_LINE_NUMBER,
1652 discriminant_size.bits(),
1653 discriminant_align.abi.bits() as u32,
1654 create_DIArray(DIB(cx), &enumerators_metadata),
1655 discriminant_base_type_metadata, true)
1658 debug_context(cx).created_enum_disr_types
1660 .insert(disr_type_key, discriminant_type_metadata);
1662 discriminant_type_metadata
1667 let layout = cx.layout_of(enum_type);
1669 match (&layout.abi, &layout.variants) {
1670 (&layout::Abi::Scalar(_), &layout::Variants::Multiple {
1671 discr_kind: layout::DiscriminantKind::Tag,
1674 }) => return FinalMetadata(discriminant_type_metadata(discr.value)),
1678 let enum_name = SmallCStr::new(&enum_name);
1679 let unique_type_id_str = SmallCStr::new(
1680 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
1683 if use_enum_fallback(cx) {
1684 let discriminant_type_metadata = match layout.variants {
1685 layout::Variants::Single { .. } |
1686 layout::Variants::Multiple {
1687 discr_kind: layout::DiscriminantKind::Niche { .. },
1690 layout::Variants::Multiple {
1691 discr_kind: layout::DiscriminantKind::Tag,
1695 Some(discriminant_type_metadata(discr.value))
1699 let enum_metadata = unsafe {
1700 llvm::LLVMRustDIBuilderCreateUnionType(
1705 UNKNOWN_LINE_NUMBER,
1707 layout.align.abi.bits() as u32,
1711 unique_type_id_str.as_ptr())
1714 return create_and_register_recursive_type_forward_declaration(
1720 EnumMDF(EnumMemberDescriptionFactory {
1723 discriminant_type_metadata,
1730 let discriminator_metadata = match layout.variants {
1731 // A single-variant enum has no discriminant.
1732 layout::Variants::Single { .. } => None,
1734 layout::Variants::Multiple {
1735 discr_kind: layout::DiscriminantKind::Niche { .. },
1739 // Find the integer type of the correct size.
1740 let size = discr.value.size(cx);
1741 let align = discr.value.align(cx);
1743 let discr_type = match discr.value {
1744 layout::Int(t, _) => t,
1745 layout::Float(layout::FloatTy::F32) => Integer::I32,
1746 layout::Float(layout::FloatTy::F64) => Integer::I64,
1747 layout::Pointer => cx.data_layout().ptr_sized_integer(),
1748 }.to_ty(cx.tcx, false);
1750 let discr_metadata = basic_type_metadata(cx, discr_type);
1752 Some(llvm::LLVMRustDIBuilderCreateMemberType(
1757 UNKNOWN_LINE_NUMBER,
1759 align.abi.bits() as u32,
1760 layout.fields.offset(0).bits(),
1761 DIFlags::FlagArtificial,
1766 layout::Variants::Multiple {
1767 discr_kind: layout::DiscriminantKind::Tag,
1771 let discr_type = discr.value.to_ty(cx.tcx);
1772 let (size, align) = cx.size_and_align_of(discr_type);
1774 let discr_metadata = basic_type_metadata(cx, discr_type);
1776 Some(llvm::LLVMRustDIBuilderCreateMemberType(
1781 UNKNOWN_LINE_NUMBER,
1783 align.bits() as u32,
1784 layout.fields.offset(0).bits(),
1785 DIFlags::FlagArtificial,
1791 let variant_part_unique_type_id_str = SmallCStr::new(
1792 debug_context(cx).type_map
1794 .get_unique_type_id_str_of_enum_variant_part(unique_type_id)
1796 let empty_array = create_DIArray(DIB(cx), &[]);
1797 let variant_part = unsafe {
1798 llvm::LLVMRustDIBuilderCreateVariantPart(
1803 UNKNOWN_LINE_NUMBER,
1805 layout.align.abi.bits() as u32,
1807 discriminator_metadata,
1809 variant_part_unique_type_id_str.as_ptr())
1812 // The variant part must be wrapped in a struct according to DWARF.
1813 let type_array = create_DIArray(DIB(cx), &[Some(variant_part)]);
1814 let struct_wrapper = unsafe {
1815 llvm::LLVMRustDIBuilderCreateStructType(
1817 Some(containing_scope),
1820 UNKNOWN_LINE_NUMBER,
1822 layout.align.abi.bits() as u32,
1828 unique_type_id_str.as_ptr())
1831 return create_and_register_recursive_type_forward_declaration(
1837 EnumMDF(EnumMemberDescriptionFactory {
1840 discriminant_type_metadata: None,
1846 fn get_enum_discriminant_name(cx: &CodegenCx<'_, '_>,
1849 cx.tcx.item_name(def_id)
1853 /// Creates debug information for a composite type, that is, anything that
1854 /// results in a LLVM struct.
1856 /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
1857 fn composite_type_metadata(
1858 cx: &CodegenCx<'ll, 'tcx>,
1859 composite_type: Ty<'tcx>,
1860 composite_type_name: &str,
1861 composite_type_unique_id: UniqueTypeId,
1862 member_descriptions: Vec<MemberDescription<'ll>>,
1863 containing_scope: Option<&'ll DIScope>,
1865 // Ignore source location information as long as it
1866 // can't be reconstructed for non-local crates.
1867 _file_metadata: &'ll DIFile,
1868 _definition_span: Span,
1869 ) -> &'ll DICompositeType {
1870 // Create the (empty) struct metadata node ...
1871 let composite_type_metadata = create_struct_stub(cx,
1873 composite_type_name,
1874 composite_type_unique_id,
1876 // ... and immediately create and add the member descriptions.
1877 set_members_of_composite_type(cx,
1879 composite_type_metadata,
1880 member_descriptions);
1882 composite_type_metadata
1885 fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>,
1886 composite_type: Ty<'tcx>,
1887 composite_type_metadata: &'ll DICompositeType,
1888 member_descriptions: Vec<MemberDescription<'ll>>) {
1889 // In some rare cases LLVM metadata uniquing would lead to an existing type
1890 // description being used instead of a new one created in
1891 // create_struct_stub. This would cause a hard to trace assertion in
1892 // DICompositeType::SetTypeArray(). The following check makes sure that we
1893 // get a better error message if this should happen again due to some
1896 let mut composite_types_completed =
1897 debug_context(cx).composite_types_completed.borrow_mut();
1898 if composite_types_completed.contains(&composite_type_metadata) {
1899 bug!("debuginfo::set_members_of_composite_type() - \
1900 Already completed forward declaration re-encountered.");
1902 composite_types_completed.insert(composite_type_metadata);
1906 let member_metadata: Vec<_> = member_descriptions
1908 .map(|member_description| {
1909 let member_name = CString::new(member_description.name).unwrap();
1911 Some(llvm::LLVMRustDIBuilderCreateVariantMemberType(
1913 composite_type_metadata,
1914 member_name.as_ptr(),
1915 unknown_file_metadata(cx),
1916 UNKNOWN_LINE_NUMBER,
1917 member_description.size.bits(),
1918 member_description.align.bits() as u32,
1919 member_description.offset.bits(),
1920 match member_description.discriminant {
1922 Some(value) => Some(cx.const_u64(value)),
1924 member_description.flags,
1925 member_description.type_metadata))
1930 let type_params = compute_type_parameters(cx, composite_type);
1932 let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
1933 llvm::LLVMRustDICompositeTypeReplaceArrays(
1934 DIB(cx), composite_type_metadata, Some(type_array), type_params);
1938 // Compute the type parameters for a type, if any, for the given
1940 fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> Option<&'ll DIArray> {
1941 if let ty::Adt(def, substs) = ty.sty {
1942 if !substs.types().next().is_none() {
1943 let generics = cx.tcx.generics_of(def.did);
1944 let names = get_parameter_names(cx, generics);
1945 let template_params: Vec<_> = substs.iter().zip(names).filter_map(|(kind, name)| {
1946 if let UnpackedKind::Type(ty) = kind.unpack() {
1947 let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
1948 let actual_type_metadata =
1949 type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
1950 let name = SmallCStr::new(&name.as_str());
1953 Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
1957 actual_type_metadata,
1958 unknown_file_metadata(cx),
1968 return Some(create_DIArray(DIB(cx), &template_params[..]));
1971 return Some(create_DIArray(DIB(cx), &[]));
1973 fn get_parameter_names(cx: &CodegenCx<'_, '_>,
1974 generics: &ty::Generics)
1975 -> Vec<InternedString> {
1976 let mut names = generics.parent.map_or(vec![], |def_id| {
1977 get_parameter_names(cx, cx.tcx.generics_of(def_id))
1979 names.extend(generics.params.iter().map(|param| param.name));
1984 // A convenience wrapper around LLVMRustDIBuilderCreateStructType(). Does not do
1985 // any caching, does not add any fields to the struct. This can be done later
1986 // with set_members_of_composite_type().
1987 fn create_struct_stub(
1988 cx: &CodegenCx<'ll, 'tcx>,
1989 struct_type: Ty<'tcx>,
1990 struct_type_name: &str,
1991 unique_type_id: UniqueTypeId,
1992 containing_scope: Option<&'ll DIScope>,
1993 ) -> &'ll DICompositeType {
1994 let (struct_size, struct_align) = cx.size_and_align_of(struct_type);
1996 let name = SmallCStr::new(struct_type_name);
1997 let unique_type_id = SmallCStr::new(
1998 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
2000 let metadata_stub = unsafe {
2001 // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
2002 // pointer will lead to hard to trace and debug LLVM assertions
2003 // later on in llvm/lib/IR/Value.cpp.
2004 let empty_array = create_DIArray(DIB(cx), &[]);
2006 llvm::LLVMRustDIBuilderCreateStructType(
2010 unknown_file_metadata(cx),
2011 UNKNOWN_LINE_NUMBER,
2013 struct_align.bits() as u32,
2019 unique_type_id.as_ptr())
2025 fn create_union_stub(
2026 cx: &CodegenCx<'ll, 'tcx>,
2027 union_type: Ty<'tcx>,
2028 union_type_name: &str,
2029 unique_type_id: UniqueTypeId,
2030 containing_scope: &'ll DIScope,
2031 ) -> &'ll DICompositeType {
2032 let (union_size, union_align) = cx.size_and_align_of(union_type);
2034 let name = SmallCStr::new(union_type_name);
2035 let unique_type_id = SmallCStr::new(
2036 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
2038 let metadata_stub = unsafe {
2039 // LLVMRustDIBuilderCreateUnionType() wants an empty array. A null
2040 // pointer will lead to hard to trace and debug LLVM assertions
2041 // later on in llvm/lib/IR/Value.cpp.
2042 let empty_array = create_DIArray(DIB(cx), &[]);
2044 llvm::LLVMRustDIBuilderCreateUnionType(
2048 unknown_file_metadata(cx),
2049 UNKNOWN_LINE_NUMBER,
2051 union_align.bits() as u32,
2055 unique_type_id.as_ptr())
2061 /// Creates debug information for the given global variable.
2063 /// Adds the created metadata nodes directly to the crate's IR.
2064 pub fn create_global_var_metadata(
2065 cx: &CodegenCx<'ll, '_>,
2069 if cx.dbg_cx.is_none() {
2074 let attrs = tcx.codegen_fn_attrs(def_id);
2076 if attrs.flags.contains(CodegenFnAttrFlags::NO_DEBUG) {
2080 let no_mangle = attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE);
2081 // We may want to remove the namespace scope if we're in an extern block, see:
2082 // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952
2083 let var_scope = get_namespace_for_item(cx, def_id);
2084 let span = tcx.def_span(def_id);
2086 let (file_metadata, line_number) = if !span.is_dummy() {
2087 let loc = span_start(cx, span);
2088 (file_metadata(cx, &loc.file.name, LOCAL_CRATE), loc.line as c_uint)
2090 (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
2093 let is_local_to_unit = is_node_local_to_unit(cx, def_id);
2094 let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx);
2095 let type_metadata = type_metadata(cx, variable_type, span);
2096 let var_name = SmallCStr::new(&tcx.item_name(def_id).as_str());
2097 let linkage_name = if no_mangle {
2100 let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id));
2101 Some(SmallCStr::new(&linkage_name.as_str()))
2104 let global_align = cx.align_of(variable_type);
2107 llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
2110 // If null, linkage_name field is omitted,
2111 // which is what we want for no_mangle statics
2112 linkage_name.as_ref()
2113 .map_or(ptr::null(), |name| name.as_ptr()),
2120 global_align.bytes() as u32,
2125 /// Creates debug information for the given vtable, which is for the
2128 /// Adds the created metadata nodes directly to the crate's IR.
2129 pub fn create_vtable_metadata(
2130 cx: &CodegenCx<'ll, 'tcx>,
2134 if cx.dbg_cx.is_none() {
2138 let type_metadata = type_metadata(cx, ty, syntax_pos::DUMMY_SP);
2141 // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
2142 // pointer will lead to hard to trace and debug LLVM assertions
2143 // later on in llvm/lib/IR/Value.cpp.
2144 let empty_array = create_DIArray(DIB(cx), &[]);
2146 let name = const_cstr!("vtable");
2148 // Create a new one each time. We don't want metadata caching
2149 // here, because each vtable will refer to a unique containing
2151 let vtable_type = llvm::LLVMRustDIBuilderCreateStructType(
2155 unknown_file_metadata(cx),
2156 UNKNOWN_LINE_NUMBER,
2158 cx.tcx.data_layout.pointer_align.abi.bits() as u32,
2159 DIFlags::FlagArtificial,
2163 Some(type_metadata),
2167 llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
2171 unknown_file_metadata(cx),
2172 UNKNOWN_LINE_NUMBER,
2181 // Creates an "extension" of an existing DIScope into another file.
2182 pub fn extend_scope_to_file(
2183 cx: &CodegenCx<'ll, '_>,
2184 scope_metadata: &'ll DIScope,
2185 file: &syntax_pos::SourceFile,
2186 defining_crate: CrateNum,
2187 ) -> &'ll DILexicalBlock {
2188 let file_metadata = file_metadata(cx, &file.name, defining_crate);
2190 llvm::LLVMRustDIBuilderCreateLexicalBlockFile(