1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use self::RecursiveTypeDescription::*;
12 use self::MemberDescriptionFactory::*;
13 use self::EnumDiscriminantInfo::*;
15 use super::utils::{debug_context, DIB, span_start,
16 get_namespace_for_item, create_DIArray, is_node_local_to_unit};
17 use super::namespace::mangled_name_of_instance;
18 use super::type_names::compute_debuginfo_type_name;
19 use super::{CrateDebugContext};
21 use interfaces::CommonMethods;
25 use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
26 DICompositeType, DILexicalBlock, DIFlags};
29 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
30 use rustc::hir::CodegenFnAttrFlags;
31 use rustc::hir::def::CtorKind;
32 use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
33 use rustc::ich::NodeIdHashingMode;
34 use rustc_data_structures::fingerprint::Fingerprint;
35 use rustc::ty::Instance;
36 use common::CodegenCx;
37 use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
38 use rustc::ty::layout::{self, Align, HasDataLayout, Integer, IntegerExt, LayoutOf,
39 PrimitiveExt, Size, TyLayout};
40 use rustc::session::config;
41 use rustc::util::nodemap::FxHashMap;
42 use rustc_fs_util::path2cstr;
43 use rustc_data_structures::small_c_str::SmallCStr;
45 use libc::{c_uint, c_longlong};
46 use std::ffi::CString;
47 use std::fmt::{self, Write};
48 use std::hash::{Hash, Hasher};
51 use std::path::{Path, PathBuf};
53 use syntax::symbol::{Interner, InternedString, Symbol};
54 use syntax_pos::{self, Span, FileName};
56 impl PartialEq for llvm::Metadata {
57 fn eq(&self, other: &Self) -> bool {
58 self as *const _ == other as *const _
62 impl Eq for llvm::Metadata {}
64 impl Hash for llvm::Metadata {
65 fn hash<H: Hasher>(&self, hasher: &mut H) {
66 (self as *const Self).hash(hasher);
70 impl fmt::Debug for llvm::Metadata {
71 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72 (self as *const Self).fmt(f)
77 // See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1
78 const DW_LANG_RUST: c_uint = 0x1c;
79 #[allow(non_upper_case_globals)]
80 const DW_ATE_boolean: c_uint = 0x02;
81 #[allow(non_upper_case_globals)]
82 const DW_ATE_float: c_uint = 0x04;
83 #[allow(non_upper_case_globals)]
84 const DW_ATE_signed: c_uint = 0x05;
85 #[allow(non_upper_case_globals)]
86 const DW_ATE_unsigned: c_uint = 0x07;
87 #[allow(non_upper_case_globals)]
88 const DW_ATE_unsigned_char: c_uint = 0x08;
90 pub const UNKNOWN_LINE_NUMBER: c_uint = 0;
91 pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
93 pub const NO_SCOPE_METADATA: Option<&DIScope> = None;
95 #[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
96 pub struct UniqueTypeId(ast::Name);
98 // The TypeMap is where the CrateDebugContext holds the type metadata nodes
99 // created so far. The metadata nodes are indexed by UniqueTypeId, and, for
100 // faster lookup, also by Ty. The TypeMap is responsible for creating
103 pub struct TypeMap<'ll, 'tcx> {
104 // The UniqueTypeIds created so far
105 unique_id_interner: Interner,
106 // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
107 unique_id_to_metadata: FxHashMap<UniqueTypeId, &'ll DIType>,
108 // A map from types to debuginfo metadata. This is a N:1 mapping.
109 type_to_metadata: FxHashMap<Ty<'tcx>, &'ll DIType>,
110 // A map from types to UniqueTypeId. This is a N:1 mapping.
111 type_to_unique_id: FxHashMap<Ty<'tcx>, UniqueTypeId>
114 impl TypeMap<'ll, 'tcx> {
115 // Adds a Ty to metadata mapping to the TypeMap. The method will fail if
116 // the mapping already exists.
117 fn register_type_with_metadata(
120 metadata: &'ll DIType,
122 if self.type_to_metadata.insert(type_, metadata).is_some() {
123 bug!("Type metadata for Ty '{}' is already in the TypeMap!", type_);
127 // Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
128 // fail if the mapping already exists.
129 fn register_unique_id_with_metadata(
131 unique_type_id: UniqueTypeId,
132 metadata: &'ll DIType,
134 if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
135 bug!("Type metadata for unique id '{}' is already in the TypeMap!",
136 self.get_unique_type_id_as_string(unique_type_id));
140 fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<&'ll DIType> {
141 self.type_to_metadata.get(&type_).cloned()
144 fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<&'ll DIType> {
145 self.unique_id_to_metadata.get(&unique_type_id).cloned()
148 // Get the string representation of a UniqueTypeId. This method will fail if
149 // the id is unknown.
150 fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> &str {
151 let UniqueTypeId(interner_key) = unique_type_id;
152 self.unique_id_interner.get(interner_key)
155 // Get the UniqueTypeId for the given type. If the UniqueTypeId for the given
156 // type has been requested before, this is just a table lookup. Otherwise an
157 // ID will be generated and stored for later lookup.
158 fn get_unique_type_id_of_type<'a>(&mut self, cx: &CodegenCx<'a, 'tcx>,
159 type_: Ty<'tcx>) -> UniqueTypeId {
160 // Let's see if we already have something in the cache
161 if let Some(unique_type_id) = self.type_to_unique_id.get(&type_).cloned() {
162 return unique_type_id;
164 // if not, generate one
166 // The hasher we are using to generate the UniqueTypeId. We want
167 // something that provides more than the 64 bits of the DefaultHasher.
168 let mut hasher = StableHasher::<Fingerprint>::new();
169 let mut hcx = cx.tcx.create_stable_hashing_context();
170 let type_ = cx.tcx.erase_regions(&type_);
171 hcx.while_hashing_spans(false, |hcx| {
172 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
173 type_.hash_stable(hcx, &mut hasher);
176 let unique_type_id = hasher.finish().to_hex();
178 let key = self.unique_id_interner.intern(&unique_type_id);
179 self.type_to_unique_id.insert(type_, UniqueTypeId(key));
181 return UniqueTypeId(key);
184 // Get the UniqueTypeId for an enum variant. Enum variants are not really
185 // types of their own, so they need special handling. We still need a
186 // UniqueTypeId for them, since to debuginfo they *are* real types.
187 fn get_unique_type_id_of_enum_variant<'a>(&mut self,
188 cx: &CodegenCx<'a, 'tcx>,
192 let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
193 let enum_variant_type_id = format!("{}::{}",
194 self.get_unique_type_id_as_string(enum_type_id),
196 let interner_key = self.unique_id_interner.intern(&enum_variant_type_id);
197 UniqueTypeId(interner_key)
201 // A description of some recursive type. It can either be already finished (as
202 // with FinalMetadata) or it is not yet finished, but contains all information
203 // needed to generate the missing parts of the description. See the
204 // documentation section on Recursive Types at the top of this file for more
206 enum RecursiveTypeDescription<'ll, 'tcx> {
208 unfinished_type: Ty<'tcx>,
209 unique_type_id: UniqueTypeId,
210 metadata_stub: &'ll DICompositeType,
211 member_holding_stub: &'ll DICompositeType,
212 member_description_factory: MemberDescriptionFactory<'ll, 'tcx>,
214 FinalMetadata(&'ll DICompositeType)
217 fn create_and_register_recursive_type_forward_declaration(
218 cx: &CodegenCx<'ll, 'tcx>,
219 unfinished_type: Ty<'tcx>,
220 unique_type_id: UniqueTypeId,
221 metadata_stub: &'ll DICompositeType,
222 member_holding_stub: &'ll DICompositeType,
223 member_description_factory: MemberDescriptionFactory<'ll, 'tcx>,
224 ) -> RecursiveTypeDescription<'ll, 'tcx> {
226 // Insert the stub into the TypeMap in order to allow for recursive references
227 let mut type_map = debug_context(cx).type_map.borrow_mut();
228 type_map.register_unique_id_with_metadata(unique_type_id, metadata_stub);
229 type_map.register_type_with_metadata(unfinished_type, metadata_stub);
236 member_description_factory,
240 impl RecursiveTypeDescription<'ll, 'tcx> {
241 // Finishes up the description of the type in question (mostly by providing
242 // descriptions of the fields of the given type) and returns the final type
244 fn finalize(&self, cx: &CodegenCx<'ll, 'tcx>) -> MetadataCreationResult<'ll> {
246 FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
252 ref member_description_factory,
254 // Make sure that we have a forward declaration of the type in
255 // the TypeMap so that recursive references are possible. This
256 // will always be the case if the RecursiveTypeDescription has
257 // been properly created through the
258 // create_and_register_recursive_type_forward_declaration()
261 let type_map = debug_context(cx).type_map.borrow();
262 if type_map.find_metadata_for_unique_id(unique_type_id).is_none() ||
263 type_map.find_metadata_for_type(unfinished_type).is_none() {
264 bug!("Forward declaration of potentially recursive type \
265 '{:?}' was not found in TypeMap!",
270 // ... then create the member descriptions ...
271 let member_descriptions =
272 member_description_factory.create_member_descriptions(cx);
274 // ... and attach them to the stub to complete it.
275 set_members_of_composite_type(cx,
277 member_descriptions);
278 return MetadataCreationResult::new(metadata_stub, true);
284 // Returns from the enclosing function if the type metadata with the given
285 // unique id can be found in the type map
286 macro_rules! return_if_metadata_created_in_meantime {
287 ($cx: expr, $unique_type_id: expr) => (
288 if let Some(metadata) = debug_context($cx).type_map
290 .find_metadata_for_unique_id($unique_type_id)
292 return MetadataCreationResult::new(metadata, true);
297 fn fixed_vec_metadata(
298 cx: &CodegenCx<'ll, 'tcx>,
299 unique_type_id: UniqueTypeId,
300 array_or_slice_type: Ty<'tcx>,
301 element_type: Ty<'tcx>,
303 ) -> MetadataCreationResult<'ll> {
304 let element_type_metadata = type_metadata(cx, element_type, span);
306 return_if_metadata_created_in_meantime!(cx, unique_type_id);
308 let (size, align) = cx.size_and_align_of(array_or_slice_type);
310 let upper_bound = match array_or_slice_type.sty {
311 ty::Array(_, len) => {
312 len.unwrap_usize(cx.tcx) as c_longlong
317 let subrange = unsafe {
318 Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound))
321 let subscripts = create_DIArray(DIB(cx), &[subrange]);
322 let metadata = unsafe {
323 llvm::LLVMRustDIBuilderCreateArrayType(
326 align.abi_bits() as u32,
327 element_type_metadata,
331 return MetadataCreationResult::new(metadata, false);
334 fn vec_slice_metadata(
335 cx: &CodegenCx<'ll, 'tcx>,
336 slice_ptr_type: Ty<'tcx>,
337 element_type: Ty<'tcx>,
338 unique_type_id: UniqueTypeId,
340 ) -> MetadataCreationResult<'ll> {
341 let data_ptr_type = cx.tcx.mk_imm_ptr(element_type);
343 let data_ptr_metadata = type_metadata(cx, data_ptr_type, span);
345 return_if_metadata_created_in_meantime!(cx, unique_type_id);
347 let slice_type_name = compute_debuginfo_type_name(cx, slice_ptr_type, true);
349 let (pointer_size, pointer_align) = cx.size_and_align_of(data_ptr_type);
350 let (usize_size, usize_align) = cx.size_and_align_of(cx.tcx.types.usize);
352 let member_descriptions = vec![
354 name: "data_ptr".to_owned(),
355 type_metadata: data_ptr_metadata,
358 align: pointer_align,
359 flags: DIFlags::FlagZero,
363 name: "length".to_owned(),
364 type_metadata: type_metadata(cx, cx.tcx.types.usize, span),
365 offset: pointer_size,
368 flags: DIFlags::FlagZero,
373 let file_metadata = unknown_file_metadata(cx);
375 let metadata = composite_type_metadata(cx,
377 &slice_type_name[..],
383 MetadataCreationResult::new(metadata, false)
386 fn subroutine_type_metadata(
387 cx: &CodegenCx<'ll, 'tcx>,
388 unique_type_id: UniqueTypeId,
389 signature: ty::PolyFnSig<'tcx>,
391 ) -> MetadataCreationResult<'ll> {
392 let signature = cx.tcx.normalize_erasing_late_bound_regions(
393 ty::ParamEnv::reveal_all(),
397 let signature_metadata: Vec<_> = iter::once(
399 match signature.output().sty {
400 ty::Tuple(ref tys) if tys.is_empty() => None,
401 _ => Some(type_metadata(cx, signature.output(), span))
405 signature.inputs().iter().map(|argument_type| {
406 Some(type_metadata(cx, argument_type, span))
410 return_if_metadata_created_in_meantime!(cx, unique_type_id);
412 return MetadataCreationResult::new(
414 llvm::LLVMRustDIBuilderCreateSubroutineType(
416 unknown_file_metadata(cx),
417 create_DIArray(DIB(cx), &signature_metadata[..]))
422 // FIXME(1563) This is all a bit of a hack because 'trait pointer' is an ill-
423 // defined concept. For the case of an actual trait pointer (i.e., Box<Trait>,
424 // &Trait), trait_object_type should be the whole thing (e.g, Box<Trait>) and
425 // trait_type should be the actual trait (e.g., Trait). Where the trait is part
426 // of a DST struct, there is no trait_object_type and the results of this
427 // function will be a little bit weird.
428 fn trait_pointer_metadata(
429 cx: &CodegenCx<'ll, 'tcx>,
430 trait_type: Ty<'tcx>,
431 trait_object_type: Option<Ty<'tcx>>,
432 unique_type_id: UniqueTypeId,
434 // The implementation provided here is a stub. It makes sure that the trait
435 // type is assigned the correct name, size, namespace, and source location.
436 // But it does not describe the trait's methods.
438 let containing_scope = match trait_type.sty {
439 ty::Dynamic(ref data, ..) => Some(get_namespace_for_item(cx, data.principal().def_id())),
441 bug!("debuginfo: Unexpected trait-object type in \
442 trait_pointer_metadata(): {:?}",
447 let trait_object_type = trait_object_type.unwrap_or(trait_type);
448 let trait_type_name =
449 compute_debuginfo_type_name(cx, trait_object_type, false);
451 let file_metadata = unknown_file_metadata(cx);
453 let layout = cx.layout_of(cx.tcx.mk_mut_ptr(trait_type));
455 assert_eq!(abi::FAT_PTR_ADDR, 0);
456 assert_eq!(abi::FAT_PTR_EXTRA, 1);
458 let data_ptr_field = layout.field(cx, 0);
459 let vtable_field = layout.field(cx, 1);
460 let member_descriptions = vec![
462 name: "pointer".to_owned(),
463 type_metadata: type_metadata(cx,
464 cx.tcx.mk_mut_ptr(cx.tcx.types.u8),
465 syntax_pos::DUMMY_SP),
466 offset: layout.fields.offset(0),
467 size: data_ptr_field.size,
468 align: data_ptr_field.align,
469 flags: DIFlags::FlagArtificial,
473 name: "vtable".to_owned(),
474 type_metadata: type_metadata(cx, vtable_field.ty, syntax_pos::DUMMY_SP),
475 offset: layout.fields.offset(1),
476 size: vtable_field.size,
477 align: vtable_field.align,
478 flags: DIFlags::FlagArtificial,
483 composite_type_metadata(cx,
485 &trait_type_name[..],
490 syntax_pos::DUMMY_SP)
493 pub fn type_metadata(
494 cx: &CodegenCx<'ll, 'tcx>,
496 usage_site_span: Span,
498 // Get the unique type id of this type.
499 let unique_type_id = {
500 let mut type_map = debug_context(cx).type_map.borrow_mut();
501 // First, try to find the type in TypeMap. If we have seen it before, we
502 // can exit early here.
503 match type_map.find_metadata_for_type(t) {
508 // The Ty is not in the TypeMap but maybe we have already seen
509 // an equivalent type (e.g. only differing in region arguments).
510 // In order to find out, generate the unique type id and look
512 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
513 match type_map.find_metadata_for_unique_id(unique_type_id) {
515 // There is already an equivalent type in the TypeMap.
516 // Register this Ty as an alias in the cache and
517 // return the cached metadata.
518 type_map.register_type_with_metadata(t, metadata);
522 // There really is no type metadata for this type, so
523 // proceed by creating it.
531 debug!("type_metadata: {:?}", t);
533 let ptr_metadata = |ty: Ty<'tcx>| {
536 Ok(vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span))
539 Ok(vec_slice_metadata(cx, t, cx.tcx.types.u8, unique_type_id, usage_site_span))
542 Ok(MetadataCreationResult::new(
543 trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
547 let pointee_metadata = type_metadata(cx, ty, usage_site_span);
549 if let Some(metadata) = debug_context(cx).type_map
551 .find_metadata_for_unique_id(unique_type_id)
553 return Err(metadata);
556 Ok(MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
562 let MetadataCreationResult { metadata, already_stored_in_typemap } = match t.sty {
569 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
571 ty::Tuple(ref elements) if elements.is_empty() => {
572 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
576 fixed_vec_metadata(cx, unique_type_id, t, typ, usage_site_span)
579 fixed_vec_metadata(cx, unique_type_id, t, cx.tcx.types.i8, usage_site_span)
582 MetadataCreationResult::new(
583 trait_pointer_metadata(cx, t, None, unique_type_id),
587 MetadataCreationResult::new(
588 foreign_type_metadata(cx, t, unique_type_id),
591 ty::RawPtr(ty::TypeAndMut{ty, ..}) |
592 ty::Ref(_, ty, _) => {
593 match ptr_metadata(ty) {
595 Err(metadata) => return metadata,
598 ty::Adt(def, _) if def.is_box() => {
599 match ptr_metadata(t.boxed_ty()) {
601 Err(metadata) => return metadata,
604 ty::FnDef(..) | ty::FnPtr(_) => {
605 let fn_metadata = subroutine_type_metadata(cx,
608 usage_site_span).metadata;
609 if let Some(metadata) = debug_context(cx).type_map
611 .find_metadata_for_unique_id(unique_type_id)
616 // This is actually a function pointer, so wrap it in pointer DI
617 MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false)
620 ty::Closure(def_id, substs) => {
621 let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx).collect();
622 prepare_tuple_metadata(cx,
626 usage_site_span).finalize(cx)
628 ty::Generator(def_id, substs, _) => {
629 let upvar_tys : Vec<_> = substs.field_tys(def_id, cx.tcx).map(|t| {
630 cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t)
632 prepare_tuple_metadata(cx,
636 usage_site_span).finalize(cx)
638 ty::Adt(def, ..) => match def.adt_kind() {
640 prepare_struct_metadata(cx,
643 usage_site_span).finalize(cx)
646 prepare_union_metadata(cx,
649 usage_site_span).finalize(cx)
652 prepare_enum_metadata(cx,
656 usage_site_span).finalize(cx)
659 ty::Tuple(ref elements) => {
660 prepare_tuple_metadata(cx,
664 usage_site_span).finalize(cx)
667 bug!("debuginfo: unexpected type in type_metadata: {:?}", t)
672 let mut type_map = debug_context(cx).type_map.borrow_mut();
674 if already_stored_in_typemap {
675 // Also make sure that we already have a TypeMap entry for the unique type id.
676 let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
677 Some(metadata) => metadata,
679 span_bug!(usage_site_span,
680 "Expected type metadata for unique \
681 type id '{}' to already be in \
682 the debuginfo::TypeMap but it \
684 type_map.get_unique_type_id_as_string(unique_type_id),
689 match type_map.find_metadata_for_type(t) {
691 if metadata != metadata_for_uid {
692 span_bug!(usage_site_span,
693 "Mismatch between Ty and \
694 UniqueTypeId maps in \
695 debuginfo::TypeMap. \
696 UniqueTypeId={}, Ty={}",
697 type_map.get_unique_type_id_as_string(unique_type_id),
702 type_map.register_type_with_metadata(t, metadata);
706 type_map.register_type_with_metadata(t, metadata);
707 type_map.register_unique_id_with_metadata(unique_type_id, metadata);
714 pub fn file_metadata(cx: &CodegenCx<'ll, '_>,
715 file_name: &FileName,
716 defining_crate: CrateNum) -> &'ll DIFile {
717 debug!("file_metadata: file_name: {}, defining_crate: {}",
721 let directory = if defining_crate == LOCAL_CRATE {
722 &cx.sess().working_dir.0
724 // If the path comes from an upstream crate we assume it has been made
725 // independent of the compiler's working directory one way or another.
729 file_metadata_raw(cx, &file_name.to_string(), &directory.to_string_lossy())
732 pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
733 file_metadata_raw(cx, "<unknown>", "")
736 fn file_metadata_raw(cx: &CodegenCx<'ll, '_>,
740 let key = (Symbol::intern(file_name), Symbol::intern(directory));
742 if let Some(file_metadata) = debug_context(cx).created_files.borrow().get(&key) {
743 return *file_metadata;
746 debug!("file_metadata: file_name: {}, directory: {}", file_name, directory);
748 let file_name = SmallCStr::new(file_name);
749 let directory = SmallCStr::new(directory);
751 let file_metadata = unsafe {
752 llvm::LLVMRustDIBuilderCreateFile(DIB(cx),
757 let mut created_files = debug_context(cx).created_files.borrow_mut();
758 created_files.insert(key, file_metadata);
762 fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
763 debug!("basic_type_metadata: {:?}", t);
765 let (name, encoding) = match t.sty {
766 ty::Never => ("!", DW_ATE_unsigned),
767 ty::Tuple(ref elements) if elements.is_empty() =>
768 ("()", DW_ATE_unsigned),
769 ty::Bool => ("bool", DW_ATE_boolean),
770 ty::Char => ("char", DW_ATE_unsigned_char),
772 (int_ty.ty_to_string(), DW_ATE_signed)
774 ty::Uint(uint_ty) => {
775 (uint_ty.ty_to_string(), DW_ATE_unsigned)
777 ty::Float(float_ty) => {
778 (float_ty.ty_to_string(), DW_ATE_float)
780 _ => bug!("debuginfo::basic_type_metadata - t is invalid type")
783 let (size, align) = cx.size_and_align_of(t);
784 let name = SmallCStr::new(name);
785 let ty_metadata = unsafe {
786 llvm::LLVMRustDIBuilderCreateBasicType(
790 align.abi_bits() as u32,
797 fn foreign_type_metadata(
798 cx: &CodegenCx<'ll, 'tcx>,
800 unique_type_id: UniqueTypeId,
802 debug!("foreign_type_metadata: {:?}", t);
804 let name = compute_debuginfo_type_name(cx, t, false);
805 create_struct_stub(cx, t, &name, unique_type_id, NO_SCOPE_METADATA)
808 fn pointer_type_metadata(
809 cx: &CodegenCx<'ll, 'tcx>,
810 pointer_type: Ty<'tcx>,
811 pointee_type_metadata: &'ll DIType,
813 let (pointer_size, pointer_align) = cx.size_and_align_of(pointer_type);
814 let name = compute_debuginfo_type_name(cx, pointer_type, false);
815 let name = SmallCStr::new(&name);
817 llvm::LLVMRustDIBuilderCreatePointerType(
819 pointee_type_metadata,
821 pointer_align.abi_bits() as u32,
826 pub fn compile_unit_metadata(tcx: TyCtxt,
827 codegen_unit_name: &str,
828 debug_context: &CrateDebugContext<'ll, '_>)
829 -> &'ll DIDescriptor {
830 let mut name_in_debuginfo = match tcx.sess.local_crate_source_file {
831 Some(ref path) => path.clone(),
832 None => PathBuf::from(&*tcx.crate_name(LOCAL_CRATE).as_str()),
835 // The OSX linker has an idiosyncrasy where it will ignore some debuginfo
836 // if multiple object files with the same DW_AT_name are linked together.
837 // As a workaround we generate unique names for each object file. Those do
838 // not correspond to an actual source file but that should be harmless.
839 if tcx.sess.target.target.options.is_like_osx {
840 name_in_debuginfo.push("@");
841 name_in_debuginfo.push(codegen_unit_name);
844 debug!("compile_unit_metadata: {:?}", name_in_debuginfo);
845 // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
846 let producer = format!("clang LLVM (rustc version {})",
847 (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
849 let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
850 let name_in_debuginfo = SmallCStr::new(&name_in_debuginfo);
851 let work_dir = SmallCStr::new(&tcx.sess.working_dir.0.to_string_lossy());
852 let producer = CString::new(producer).unwrap();
854 let split_name = "\0";
857 let file_metadata = llvm::LLVMRustDIBuilderCreateFile(
858 debug_context.builder, name_in_debuginfo.as_ptr(), work_dir.as_ptr());
860 let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
861 debug_context.builder,
865 tcx.sess.opts.optimize != config::OptLevel::No,
866 flags.as_ptr() as *const _,
868 split_name.as_ptr() as *const _);
870 if tcx.sess.opts.debugging_opts.profile {
871 let cu_desc_metadata = llvm::LLVMRustMetadataAsValue(debug_context.llcontext,
875 path_to_mdstring(debug_context.llcontext,
876 &tcx.output_filenames(LOCAL_CRATE).with_extension("gcno")),
877 path_to_mdstring(debug_context.llcontext,
878 &tcx.output_filenames(LOCAL_CRATE).with_extension("gcda")),
881 let gcov_metadata = llvm::LLVMMDNodeInContext(debug_context.llcontext,
882 gcov_cu_info.as_ptr(),
883 gcov_cu_info.len() as c_uint);
885 let llvm_gcov_ident = const_cstr!("llvm.gcov");
886 llvm::LLVMAddNamedMetadataOperand(debug_context.llmod,
887 llvm_gcov_ident.as_ptr(),
891 return unit_metadata;
894 fn path_to_mdstring(llcx: &'ll llvm::Context, path: &Path) -> &'ll Value {
895 let path_str = path2cstr(path);
897 llvm::LLVMMDStringInContext(llcx,
899 path_str.as_bytes().len() as c_uint)
904 struct MetadataCreationResult<'ll> {
905 metadata: &'ll DIType,
906 already_stored_in_typemap: bool
909 impl MetadataCreationResult<'ll> {
910 fn new(metadata: &'ll DIType, already_stored_in_typemap: bool) -> Self {
911 MetadataCreationResult {
913 already_stored_in_typemap,
918 // Description of a type member, which can either be a regular field (as in
919 // structs or tuples) or an enum variant.
921 struct MemberDescription<'ll> {
923 type_metadata: &'ll DIType,
928 discriminant: Option<u64>,
931 // A factory for MemberDescriptions. It produces a list of member descriptions
932 // for some record-like type. MemberDescriptionFactories are used to defer the
933 // creation of type member descriptions in order to break cycles arising from
934 // recursive type definitions.
935 enum MemberDescriptionFactory<'ll, 'tcx> {
936 StructMDF(StructMemberDescriptionFactory<'tcx>),
937 TupleMDF(TupleMemberDescriptionFactory<'tcx>),
938 EnumMDF(EnumMemberDescriptionFactory<'ll, 'tcx>),
939 UnionMDF(UnionMemberDescriptionFactory<'tcx>),
940 VariantMDF(VariantMemberDescriptionFactory<'ll, 'tcx>)
943 impl MemberDescriptionFactory<'ll, 'tcx> {
944 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
945 -> Vec<MemberDescription<'ll>> {
947 StructMDF(ref this) => {
948 this.create_member_descriptions(cx)
950 TupleMDF(ref this) => {
951 this.create_member_descriptions(cx)
953 EnumMDF(ref this) => {
954 this.create_member_descriptions(cx)
956 UnionMDF(ref this) => {
957 this.create_member_descriptions(cx)
959 VariantMDF(ref this) => {
960 this.create_member_descriptions(cx)
966 //=-----------------------------------------------------------------------------
968 //=-----------------------------------------------------------------------------
970 // Creates MemberDescriptions for the fields of a struct
971 struct StructMemberDescriptionFactory<'tcx> {
973 variant: &'tcx ty::VariantDef,
977 impl<'tcx> StructMemberDescriptionFactory<'tcx> {
978 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
979 -> Vec<MemberDescription<'ll>> {
980 let layout = cx.layout_of(self.ty);
981 self.variant.fields.iter().enumerate().map(|(i, f)| {
982 let name = if self.variant.ctor_kind == CtorKind::Fn {
987 let field = layout.field(cx, i);
988 let (size, align) = field.size_and_align();
991 type_metadata: type_metadata(cx, field.ty, self.span),
992 offset: layout.fields.offset(i),
995 flags: DIFlags::FlagZero,
1003 fn prepare_struct_metadata(
1004 cx: &CodegenCx<'ll, 'tcx>,
1005 struct_type: Ty<'tcx>,
1006 unique_type_id: UniqueTypeId,
1008 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1009 let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
1011 let (struct_def_id, variant) = match struct_type.sty {
1012 ty::Adt(def, _) => (def.did, def.non_enum_variant()),
1013 _ => bug!("prepare_struct_metadata on a non-ADT")
1016 let containing_scope = get_namespace_for_item(cx, struct_def_id);
1018 let struct_metadata_stub = create_struct_stub(cx,
1022 Some(containing_scope));
1024 create_and_register_recursive_type_forward_declaration(
1028 struct_metadata_stub,
1029 struct_metadata_stub,
1030 StructMDF(StructMemberDescriptionFactory {
1038 //=-----------------------------------------------------------------------------
1040 //=-----------------------------------------------------------------------------
1042 // Creates MemberDescriptions for the fields of a tuple
1043 struct TupleMemberDescriptionFactory<'tcx> {
1045 component_types: Vec<Ty<'tcx>>,
1049 impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
1050 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1051 -> Vec<MemberDescription<'ll>> {
1052 let layout = cx.layout_of(self.ty);
1053 self.component_types.iter().enumerate().map(|(i, &component_type)| {
1054 let (size, align) = cx.size_and_align_of(component_type);
1056 name: format!("__{}", i),
1057 type_metadata: type_metadata(cx, component_type, self.span),
1058 offset: layout.fields.offset(i),
1061 flags: DIFlags::FlagZero,
1068 fn prepare_tuple_metadata(
1069 cx: &CodegenCx<'ll, 'tcx>,
1070 tuple_type: Ty<'tcx>,
1071 component_types: &[Ty<'tcx>],
1072 unique_type_id: UniqueTypeId,
1074 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1075 let tuple_name = compute_debuginfo_type_name(cx, tuple_type, false);
1077 let struct_stub = create_struct_stub(cx,
1083 create_and_register_recursive_type_forward_declaration(
1089 TupleMDF(TupleMemberDescriptionFactory {
1091 component_types: component_types.to_vec(),
1097 //=-----------------------------------------------------------------------------
1099 //=-----------------------------------------------------------------------------
1101 struct UnionMemberDescriptionFactory<'tcx> {
1102 layout: TyLayout<'tcx>,
1103 variant: &'tcx ty::VariantDef,
1107 impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
1108 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1109 -> Vec<MemberDescription<'ll>> {
1110 self.variant.fields.iter().enumerate().map(|(i, f)| {
1111 let field = self.layout.field(cx, i);
1112 let (size, align) = field.size_and_align();
1114 name: f.ident.to_string(),
1115 type_metadata: type_metadata(cx, field.ty, self.span),
1119 flags: DIFlags::FlagZero,
1126 fn prepare_union_metadata(
1127 cx: &CodegenCx<'ll, 'tcx>,
1128 union_type: Ty<'tcx>,
1129 unique_type_id: UniqueTypeId,
1131 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1132 let union_name = compute_debuginfo_type_name(cx, union_type, false);
1134 let (union_def_id, variant) = match union_type.sty {
1135 ty::Adt(def, _) => (def.did, def.non_enum_variant()),
1136 _ => bug!("prepare_union_metadata on a non-ADT")
1139 let containing_scope = get_namespace_for_item(cx, union_def_id);
1141 let union_metadata_stub = create_union_stub(cx,
1147 create_and_register_recursive_type_forward_declaration(
1151 union_metadata_stub,
1152 union_metadata_stub,
1153 UnionMDF(UnionMemberDescriptionFactory {
1154 layout: cx.layout_of(union_type),
1161 //=-----------------------------------------------------------------------------
1163 //=-----------------------------------------------------------------------------
1165 // DWARF variant support is only available starting in LLVM 7.
1166 // Although the earlier enum debug info output did not work properly
1167 // in all situations, it is better for the time being to continue to
1168 // sometimes emit the old style rather than emit something completely
1169 // useless when rust is compiled against LLVM 6 or older. This
1170 // function decides which representation will be emitted.
1171 fn use_enum_fallback(cx: &CodegenCx) -> bool {
1172 // On MSVC we have to use the fallback mode, because LLVM doesn't
1173 // lower variant parts to PDB.
1174 return cx.sess().target.target.options.is_like_msvc
1175 || llvm_util::get_major_version() < 7;
1178 // Describes the members of an enum value: An enum is described as a union of
1179 // structs in DWARF. This MemberDescriptionFactory provides the description for
1180 // the members of this union; so for every variant of the given enum, this
1181 // factory will produce one MemberDescription (all with no name and a fixed
1182 // offset of zero bytes).
1183 struct EnumMemberDescriptionFactory<'ll, 'tcx> {
1184 enum_type: Ty<'tcx>,
1185 layout: TyLayout<'tcx>,
1186 discriminant_type_metadata: Option<&'ll DIType>,
1187 containing_scope: &'ll DIScope,
1191 impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1192 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1193 -> Vec<MemberDescription<'ll>> {
1194 let adt = &self.enum_type.ty_adt_def().unwrap();
1196 // This will always find the metadata in the type map.
1197 let fallback = use_enum_fallback(cx);
1198 let self_metadata = if fallback {
1199 self.containing_scope
1201 type_metadata(cx, self.enum_type, self.span)
1204 match self.layout.variants {
1205 layout::Variants::Single { .. } if adt.variants.is_empty() => vec![],
1206 layout::Variants::Single { index } => {
1207 let (variant_type_metadata, member_description_factory) =
1208 describe_enum_variant(cx,
1210 &adt.variants[index],
1215 let member_descriptions =
1216 member_description_factory.create_member_descriptions(cx);
1218 set_members_of_composite_type(cx,
1219 variant_type_metadata,
1220 member_descriptions);
1226 adt.variants[index].name.as_str().to_string()
1228 type_metadata: variant_type_metadata,
1230 size: self.layout.size,
1231 align: self.layout.align,
1232 flags: DIFlags::FlagZero,
1237 layout::Variants::Tagged { ref variants, .. } => {
1238 let discriminant_info = if fallback {
1239 RegularDiscriminant(self.discriminant_type_metadata
1242 // This doesn't matter in this case.
1245 variants.iter_enumerated().map(|(i, _)| {
1246 let variant = self.layout.for_variant(cx, i);
1247 let (variant_type_metadata, member_desc_factory) =
1248 describe_enum_variant(cx,
1255 let member_descriptions = member_desc_factory
1256 .create_member_descriptions(cx);
1258 set_members_of_composite_type(cx,
1259 variant_type_metadata,
1260 member_descriptions);
1265 adt.variants[i].name.as_str().to_string()
1267 type_metadata: variant_type_metadata,
1269 size: self.layout.size,
1270 align: self.layout.align,
1271 flags: DIFlags::FlagZero,
1272 discriminant: Some(self.layout.ty.ty_adt_def().unwrap()
1273 .discriminant_for_variant(cx.tcx, i)
1278 layout::Variants::NicheFilling {
1286 let variant = self.layout.for_variant(cx, dataful_variant);
1287 // Create a description of the non-null variant
1288 let (variant_type_metadata, member_description_factory) =
1289 describe_enum_variant(cx,
1291 &adt.variants[dataful_variant],
1292 OptimizedDiscriminant,
1293 self.containing_scope,
1296 let variant_member_descriptions =
1297 member_description_factory.create_member_descriptions(cx);
1299 set_members_of_composite_type(cx,
1300 variant_type_metadata,
1301 variant_member_descriptions);
1303 // Encode the information about the null variant in the union
1305 let mut name = String::from("RUST$ENCODED$ENUM$");
1306 // Right now it's not even going to work for `niche_start > 0`,
1307 // and for multiple niche variants it only supports the first.
1308 fn compute_field_path<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
1310 layout: TyLayout<'tcx>,
1313 for i in 0..layout.fields.count() {
1314 let field_offset = layout.fields.offset(i);
1315 if field_offset > offset {
1318 let inner_offset = offset - field_offset;
1319 let field = layout.field(cx, i);
1320 if inner_offset + size <= field.size {
1321 write!(name, "{}$", i).unwrap();
1322 compute_field_path(cx, name, field, inner_offset, size);
1326 compute_field_path(cx, &mut name,
1328 self.layout.fields.offset(0),
1329 self.layout.field(cx, 0).size);
1330 name.push_str(&adt.variants[*niche_variants.start()].name.as_str());
1332 // Create the (singleton) list of descriptions of union members.
1336 type_metadata: variant_type_metadata,
1339 align: variant.align,
1340 flags: DIFlags::FlagZero,
1345 variants.iter_enumerated().map(|(i, _)| {
1346 let variant = self.layout.for_variant(cx, i);
1347 let (variant_type_metadata, member_desc_factory) =
1348 describe_enum_variant(cx,
1351 OptimizedDiscriminant,
1355 let member_descriptions = member_desc_factory
1356 .create_member_descriptions(cx);
1358 set_members_of_composite_type(cx,
1359 variant_type_metadata,
1360 member_descriptions);
1362 let niche_value = if i == dataful_variant {
1365 let value = (i.as_u32() as u128)
1366 .wrapping_sub(niche_variants.start().as_u32() as u128)
1367 .wrapping_add(niche_start);
1368 let value = value & ((1u128 << niche.value.size(cx).bits()) - 1);
1373 name: adt.variants[i].name.as_str().to_string(),
1374 type_metadata: variant_type_metadata,
1376 size: self.layout.size,
1377 align: self.layout.align,
1378 flags: DIFlags::FlagZero,
1379 discriminant: niche_value,
1388 // Creates MemberDescriptions for the fields of a single enum variant.
1389 struct VariantMemberDescriptionFactory<'ll, 'tcx> {
1390 // Cloned from the layout::Struct describing the variant.
1391 offsets: Vec<layout::Size>,
1392 args: Vec<(String, Ty<'tcx>)>,
1393 discriminant_type_metadata: Option<&'ll DIType>,
1397 impl VariantMemberDescriptionFactory<'ll, 'tcx> {
1398 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1399 -> Vec<MemberDescription<'ll>> {
1400 self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
1401 let (size, align) = cx.size_and_align_of(ty);
1403 name: name.to_string(),
1404 type_metadata: if use_enum_fallback(cx) {
1405 match self.discriminant_type_metadata {
1406 Some(metadata) if i == 0 => metadata,
1407 _ => type_metadata(cx, ty, self.span)
1410 type_metadata(cx, ty, self.span)
1412 offset: self.offsets[i],
1415 flags: DIFlags::FlagZero,
1422 #[derive(Copy, Clone)]
1423 enum EnumDiscriminantInfo<'ll> {
1424 RegularDiscriminant(&'ll DIType),
1425 OptimizedDiscriminant,
1429 // Returns a tuple of (1) type_metadata_stub of the variant, (2) a
1430 // MemberDescriptionFactory for producing the descriptions of the
1431 // fields of the variant. This is a rudimentary version of a full
1432 // RecursiveTypeDescription.
1433 fn describe_enum_variant(
1434 cx: &CodegenCx<'ll, 'tcx>,
1435 layout: layout::TyLayout<'tcx>,
1436 variant: &'tcx ty::VariantDef,
1437 discriminant_info: EnumDiscriminantInfo<'ll>,
1438 containing_scope: &'ll DIScope,
1440 ) -> (&'ll DICompositeType, MemberDescriptionFactory<'ll, 'tcx>) {
1441 let variant_name = variant.name.as_str();
1442 let unique_type_id = debug_context(cx).type_map
1444 .get_unique_type_id_of_enum_variant(
1449 let metadata_stub = create_struct_stub(cx,
1453 Some(containing_scope));
1455 // Build an array of (field name, field type) pairs to be captured in the factory closure.
1456 let (offsets, args) = if use_enum_fallback(cx) {
1457 // If this is not a univariant enum, there is also the discriminant field.
1458 let (discr_offset, discr_arg) = match discriminant_info {
1459 RegularDiscriminant(_) => {
1460 // We have the layout of an enum variant, we need the layout of the outer enum
1461 let enum_layout = cx.layout_of(layout.ty);
1462 (Some(enum_layout.fields.offset(0)),
1463 Some(("RUST$ENUM$DISR".to_owned(), enum_layout.field(cx, 0).ty)))
1468 discr_offset.into_iter().chain((0..layout.fields.count()).map(|i| {
1469 layout.fields.offset(i)
1471 discr_arg.into_iter().chain((0..layout.fields.count()).map(|i| {
1472 let name = if variant.ctor_kind == CtorKind::Fn {
1475 variant.fields[i].ident.to_string()
1477 (name, layout.field(cx, i).ty)
1482 (0..layout.fields.count()).map(|i| {
1483 layout.fields.offset(i)
1485 (0..layout.fields.count()).map(|i| {
1486 let name = if variant.ctor_kind == CtorKind::Fn {
1489 variant.fields[i].ident.to_string()
1491 (name, layout.field(cx, i).ty)
1496 let member_description_factory =
1497 VariantMDF(VariantMemberDescriptionFactory {
1500 discriminant_type_metadata: match discriminant_info {
1501 RegularDiscriminant(discriminant_type_metadata) => {
1502 Some(discriminant_type_metadata)
1509 (metadata_stub, member_description_factory)
1512 fn prepare_enum_metadata(
1513 cx: &CodegenCx<'ll, 'tcx>,
1514 enum_type: Ty<'tcx>,
1516 unique_type_id: UniqueTypeId,
1518 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1519 let enum_name = compute_debuginfo_type_name(cx, enum_type, false);
1521 let containing_scope = get_namespace_for_item(cx, enum_def_id);
1522 // FIXME: This should emit actual file metadata for the enum, but we
1523 // currently can't get the necessary information when it comes to types
1524 // imported from other crates. Formerly we violated the ODR when performing
1525 // LTO because we emitted debuginfo for the same type with varying file
1526 // metadata, so as a workaround we pretend that the type comes from
1528 let file_metadata = unknown_file_metadata(cx);
1530 let discriminant_type_metadata = |discr: layout::Primitive| {
1531 let def = enum_type.ty_adt_def().unwrap();
1532 let enumerators_metadata: Vec<_> = def.discriminants(cx.tcx)
1534 .map(|((_, discr), v)| {
1535 let name = SmallCStr::new(&v.name.as_str());
1537 Some(llvm::LLVMRustDIBuilderCreateEnumerator(
1540 // FIXME: what if enumeration has i128 discriminant?
1546 let disr_type_key = (enum_def_id, discr);
1547 let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
1549 .get(&disr_type_key).cloned();
1550 match cached_discriminant_type_metadata {
1551 Some(discriminant_type_metadata) => discriminant_type_metadata,
1553 let (discriminant_size, discriminant_align) =
1554 (discr.size(cx), discr.align(cx));
1555 let discriminant_base_type_metadata =
1556 type_metadata(cx, discr.to_ty(cx.tcx), syntax_pos::DUMMY_SP);
1557 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id).as_str();
1559 let name = SmallCStr::new(&discriminant_name);
1560 let discriminant_type_metadata = unsafe {
1561 llvm::LLVMRustDIBuilderCreateEnumerationType(
1566 UNKNOWN_LINE_NUMBER,
1567 discriminant_size.bits(),
1568 discriminant_align.abi_bits() as u32,
1569 create_DIArray(DIB(cx), &enumerators_metadata),
1570 discriminant_base_type_metadata, true)
1573 debug_context(cx).created_enum_disr_types
1575 .insert(disr_type_key, discriminant_type_metadata);
1577 discriminant_type_metadata
1582 let layout = cx.layout_of(enum_type);
1584 match (&layout.abi, &layout.variants) {
1585 (&layout::Abi::Scalar(_), &layout::Variants::Tagged {ref tag, .. }) =>
1586 return FinalMetadata(discriminant_type_metadata(tag.value)),
1590 let (enum_type_size, enum_type_align) = layout.size_and_align();
1592 let enum_name = SmallCStr::new(&enum_name);
1593 let unique_type_id_str = SmallCStr::new(
1594 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
1597 if use_enum_fallback(cx) {
1598 let discriminant_type_metadata = match layout.variants {
1599 layout::Variants::Single { .. } |
1600 layout::Variants::NicheFilling { .. } => None,
1601 layout::Variants::Tagged { ref tag, .. } => {
1602 Some(discriminant_type_metadata(tag.value))
1606 let enum_metadata = unsafe {
1607 llvm::LLVMRustDIBuilderCreateUnionType(
1612 UNKNOWN_LINE_NUMBER,
1613 enum_type_size.bits(),
1614 enum_type_align.abi_bits() as u32,
1618 unique_type_id_str.as_ptr())
1621 return create_and_register_recursive_type_forward_declaration(
1627 EnumMDF(EnumMemberDescriptionFactory {
1630 discriminant_type_metadata,
1637 let discriminator_metadata = match &layout.variants {
1638 // A single-variant enum has no discriminant.
1639 &layout::Variants::Single { .. } => None,
1641 &layout::Variants::NicheFilling { ref niche, .. } => {
1642 // Find the integer type of the correct size.
1643 let size = niche.value.size(cx);
1644 let align = niche.value.align(cx);
1646 let discr_type = match niche.value {
1647 layout::Int(t, _) => t,
1648 layout::Float(layout::FloatTy::F32) => Integer::I32,
1649 layout::Float(layout::FloatTy::F64) => Integer::I64,
1650 layout::Pointer => cx.data_layout().ptr_sized_integer(),
1651 }.to_ty(cx.tcx, false);
1653 let discr_metadata = basic_type_metadata(cx, discr_type);
1655 Some(llvm::LLVMRustDIBuilderCreateMemberType(
1660 UNKNOWN_LINE_NUMBER,
1662 align.abi_bits() as u32,
1663 layout.fields.offset(0).bits(),
1664 DIFlags::FlagArtificial,
1669 &layout::Variants::Tagged { ref tag, .. } => {
1670 let discr_type = tag.value.to_ty(cx.tcx);
1671 let (size, align) = cx.size_and_align_of(discr_type);
1673 let discr_metadata = basic_type_metadata(cx, discr_type);
1675 Some(llvm::LLVMRustDIBuilderCreateMemberType(
1680 UNKNOWN_LINE_NUMBER,
1682 align.abi_bits() as u32,
1683 layout.fields.offset(0).bits(),
1684 DIFlags::FlagArtificial,
1690 let empty_array = create_DIArray(DIB(cx), &[]);
1691 let variant_part = unsafe {
1692 llvm::LLVMRustDIBuilderCreateVariantPart(
1697 UNKNOWN_LINE_NUMBER,
1698 enum_type_size.bits(),
1699 enum_type_align.abi_bits() as u32,
1701 discriminator_metadata,
1703 unique_type_id_str.as_ptr())
1706 // The variant part must be wrapped in a struct according to DWARF.
1707 let type_array = create_DIArray(DIB(cx), &[Some(variant_part)]);
1708 let struct_wrapper = unsafe {
1709 llvm::LLVMRustDIBuilderCreateStructType(
1711 Some(containing_scope),
1714 UNKNOWN_LINE_NUMBER,
1715 enum_type_size.bits(),
1716 enum_type_align.abi_bits() as u32,
1722 unique_type_id_str.as_ptr())
1725 return create_and_register_recursive_type_forward_declaration(
1731 EnumMDF(EnumMemberDescriptionFactory {
1734 discriminant_type_metadata: None,
1740 fn get_enum_discriminant_name(cx: &CodegenCx,
1743 cx.tcx.item_name(def_id)
1747 /// Creates debug information for a composite type, that is, anything that
1748 /// results in a LLVM struct.
1750 /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
1751 fn composite_type_metadata(
1752 cx: &CodegenCx<'ll, 'tcx>,
1753 composite_type: Ty<'tcx>,
1754 composite_type_name: &str,
1755 composite_type_unique_id: UniqueTypeId,
1756 member_descriptions: Vec<MemberDescription<'ll>>,
1757 containing_scope: Option<&'ll DIScope>,
1759 // Ignore source location information as long as it
1760 // can't be reconstructed for non-local crates.
1761 _file_metadata: &'ll DIFile,
1762 _definition_span: Span,
1763 ) -> &'ll DICompositeType {
1764 // Create the (empty) struct metadata node ...
1765 let composite_type_metadata = create_struct_stub(cx,
1767 composite_type_name,
1768 composite_type_unique_id,
1770 // ... and immediately create and add the member descriptions.
1771 set_members_of_composite_type(cx,
1772 composite_type_metadata,
1773 member_descriptions);
1775 composite_type_metadata
1778 fn set_members_of_composite_type(cx: &CodegenCx<'ll, '_>,
1779 composite_type_metadata: &'ll DICompositeType,
1780 member_descriptions: Vec<MemberDescription<'ll>>) {
1781 // In some rare cases LLVM metadata uniquing would lead to an existing type
1782 // description being used instead of a new one created in
1783 // create_struct_stub. This would cause a hard to trace assertion in
1784 // DICompositeType::SetTypeArray(). The following check makes sure that we
1785 // get a better error message if this should happen again due to some
1788 let mut composite_types_completed =
1789 debug_context(cx).composite_types_completed.borrow_mut();
1790 if composite_types_completed.contains(&composite_type_metadata) {
1791 bug!("debuginfo::set_members_of_composite_type() - \
1792 Already completed forward declaration re-encountered.");
1794 composite_types_completed.insert(composite_type_metadata);
1798 let member_metadata: Vec<_> = member_descriptions
1800 .map(|member_description| {
1801 let member_name = CString::new(member_description.name).unwrap();
1803 Some(llvm::LLVMRustDIBuilderCreateVariantMemberType(
1805 composite_type_metadata,
1806 member_name.as_ptr(),
1807 unknown_file_metadata(cx),
1808 UNKNOWN_LINE_NUMBER,
1809 member_description.size.bits(),
1810 member_description.align.abi_bits() as u32,
1811 member_description.offset.bits(),
1812 match member_description.discriminant {
1814 Some(value) => Some(cx.c_u64(value)),
1816 member_description.flags,
1817 member_description.type_metadata))
1823 let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
1824 llvm::LLVMRustDICompositeTypeSetTypeArray(
1825 DIB(cx), composite_type_metadata, type_array);
1829 // A convenience wrapper around LLVMRustDIBuilderCreateStructType(). Does not do
1830 // any caching, does not add any fields to the struct. This can be done later
1831 // with set_members_of_composite_type().
1832 fn create_struct_stub(
1833 cx: &CodegenCx<'ll, 'tcx>,
1834 struct_type: Ty<'tcx>,
1835 struct_type_name: &str,
1836 unique_type_id: UniqueTypeId,
1837 containing_scope: Option<&'ll DIScope>,
1838 ) -> &'ll DICompositeType {
1839 let (struct_size, struct_align) = cx.size_and_align_of(struct_type);
1841 let name = SmallCStr::new(struct_type_name);
1842 let unique_type_id = SmallCStr::new(
1843 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
1845 let metadata_stub = unsafe {
1846 // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
1847 // pointer will lead to hard to trace and debug LLVM assertions
1848 // later on in llvm/lib/IR/Value.cpp.
1849 let empty_array = create_DIArray(DIB(cx), &[]);
1851 llvm::LLVMRustDIBuilderCreateStructType(
1855 unknown_file_metadata(cx),
1856 UNKNOWN_LINE_NUMBER,
1858 struct_align.abi_bits() as u32,
1864 unique_type_id.as_ptr())
1870 fn create_union_stub(
1871 cx: &CodegenCx<'ll, 'tcx>,
1872 union_type: Ty<'tcx>,
1873 union_type_name: &str,
1874 unique_type_id: UniqueTypeId,
1875 containing_scope: &'ll DIScope,
1876 ) -> &'ll DICompositeType {
1877 let (union_size, union_align) = cx.size_and_align_of(union_type);
1879 let name = SmallCStr::new(union_type_name);
1880 let unique_type_id = SmallCStr::new(
1881 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
1883 let metadata_stub = unsafe {
1884 // LLVMRustDIBuilderCreateUnionType() wants an empty array. A null
1885 // pointer will lead to hard to trace and debug LLVM assertions
1886 // later on in llvm/lib/IR/Value.cpp.
1887 let empty_array = create_DIArray(DIB(cx), &[]);
1889 llvm::LLVMRustDIBuilderCreateUnionType(
1893 unknown_file_metadata(cx),
1894 UNKNOWN_LINE_NUMBER,
1896 union_align.abi_bits() as u32,
1900 unique_type_id.as_ptr())
1906 /// Creates debug information for the given global variable.
1908 /// Adds the created metadata nodes directly to the crate's IR.
1909 pub fn create_global_var_metadata(
1910 cx: &CodegenCx<'ll, '_>,
1914 if cx.dbg_cx.is_none() {
1919 let attrs = tcx.codegen_fn_attrs(def_id);
1921 if attrs.flags.contains(CodegenFnAttrFlags::NO_DEBUG) {
1925 let no_mangle = attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE);
1926 // We may want to remove the namespace scope if we're in an extern block, see:
1927 // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952
1928 let var_scope = get_namespace_for_item(cx, def_id);
1929 let span = tcx.def_span(def_id);
1931 let (file_metadata, line_number) = if !span.is_dummy() {
1932 let loc = span_start(cx, span);
1933 (file_metadata(cx, &loc.file.name, LOCAL_CRATE), loc.line as c_uint)
1935 (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
1938 let is_local_to_unit = is_node_local_to_unit(cx, def_id);
1939 let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx);
1940 let type_metadata = type_metadata(cx, variable_type, span);
1941 let var_name = SmallCStr::new(&tcx.item_name(def_id).as_str());
1942 let linkage_name = if no_mangle {
1945 let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id));
1946 Some(SmallCStr::new(&linkage_name.as_str()))
1949 let global_align = cx.align_of(variable_type);
1952 llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
1955 // If null, linkage_name field is omitted,
1956 // which is what we want for no_mangle statics
1957 linkage_name.as_ref()
1958 .map_or(ptr::null(), |name| name.as_ptr()),
1965 global_align.abi() as u32,
1970 // Creates an "extension" of an existing DIScope into another file.
1971 pub fn extend_scope_to_file(
1972 cx: &CodegenCx<'ll, '_>,
1973 scope_metadata: &'ll DIScope,
1974 file: &syntax_pos::SourceFile,
1975 defining_crate: CrateNum,
1976 ) -> &'ll DILexicalBlock {
1977 let file_metadata = file_metadata(cx, &file.name, defining_crate);
1979 llvm::LLVMRustDIBuilderCreateLexicalBlockFile(
1986 /// Creates debug information for the given vtable, which is for the
1989 /// Adds the created metadata nodes directly to the crate's IR.
1990 pub fn create_vtable_metadata(
1991 cx: &CodegenCx<'ll, 'tcx>,
1995 if cx.dbg_cx.is_none() {
1999 let type_metadata = type_metadata(cx, ty, syntax_pos::DUMMY_SP);
2002 // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
2003 // pointer will lead to hard to trace and debug LLVM assertions
2004 // later on in llvm/lib/IR/Value.cpp.
2005 let empty_array = create_DIArray(DIB(cx), &[]);
2007 let name = const_cstr!("vtable");
2009 // Create a new one each time. We don't want metadata caching
2010 // here, because each vtable will refer to a unique containing
2012 let vtable_type = llvm::LLVMRustDIBuilderCreateStructType(
2016 unknown_file_metadata(cx),
2017 UNKNOWN_LINE_NUMBER,
2019 cx.tcx.data_layout.pointer_align.abi_bits() as u32,
2020 DIFlags::FlagArtificial,
2024 Some(type_metadata),
2028 llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
2032 unknown_file_metadata(cx),
2033 UNKNOWN_LINE_NUMBER,