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};
20 use rustc_codegen_ssa::traits::*;
25 use llvm::debuginfo::{DIArray, 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, Integer, IntegerExt, LayoutOf,
39 PrimitiveExt, Size, TyLayout};
40 use rustc::ty::subst::UnpackedKind;
41 use rustc::session::config;
42 use rustc::util::nodemap::FxHashMap;
43 use rustc_fs_util::path_to_c_string;
44 use rustc_data_structures::small_c_str::SmallCStr;
45 use rustc_target::abi::HasDataLayout;
47 use libc::{c_uint, c_longlong};
48 use std::ffi::CString;
49 use std::fmt::{self, Write};
50 use std::hash::{Hash, Hasher};
53 use std::path::{Path, PathBuf};
55 use syntax::symbol::{Interner, InternedString, Symbol};
56 use syntax_pos::{self, Span, FileName};
58 impl PartialEq for llvm::Metadata {
59 fn eq(&self, other: &Self) -> bool {
60 self as *const _ == other as *const _
64 impl Eq for llvm::Metadata {}
66 impl Hash for llvm::Metadata {
67 fn hash<H: Hasher>(&self, hasher: &mut H) {
68 (self as *const Self).hash(hasher);
72 impl fmt::Debug for llvm::Metadata {
73 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74 (self as *const Self).fmt(f)
79 // See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1
80 const DW_LANG_RUST: c_uint = 0x1c;
81 #[allow(non_upper_case_globals)]
82 const DW_ATE_boolean: c_uint = 0x02;
83 #[allow(non_upper_case_globals)]
84 const DW_ATE_float: c_uint = 0x04;
85 #[allow(non_upper_case_globals)]
86 const DW_ATE_signed: c_uint = 0x05;
87 #[allow(non_upper_case_globals)]
88 const DW_ATE_unsigned: c_uint = 0x07;
89 #[allow(non_upper_case_globals)]
90 const DW_ATE_unsigned_char: c_uint = 0x08;
92 pub const UNKNOWN_LINE_NUMBER: c_uint = 0;
93 pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
95 pub const NO_SCOPE_METADATA: Option<&DIScope> = None;
97 #[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
98 pub struct UniqueTypeId(ast::Name);
100 // The TypeMap is where the CrateDebugContext holds the type metadata nodes
101 // created so far. The metadata nodes are indexed by UniqueTypeId, and, for
102 // faster lookup, also by Ty. The TypeMap is responsible for creating
105 pub struct TypeMap<'ll, 'tcx> {
106 // The UniqueTypeIds created so far
107 unique_id_interner: Interner,
108 // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
109 unique_id_to_metadata: FxHashMap<UniqueTypeId, &'ll DIType>,
110 // A map from types to debuginfo metadata. This is a N:1 mapping.
111 type_to_metadata: FxHashMap<Ty<'tcx>, &'ll DIType>,
112 // A map from types to UniqueTypeId. This is a N:1 mapping.
113 type_to_unique_id: FxHashMap<Ty<'tcx>, UniqueTypeId>
116 impl TypeMap<'ll, 'tcx> {
117 // Adds a Ty to metadata mapping to the TypeMap. The method will fail if
118 // the mapping already exists.
119 fn register_type_with_metadata(
122 metadata: &'ll DIType,
124 if self.type_to_metadata.insert(type_, metadata).is_some() {
125 bug!("Type metadata for Ty '{}' is already in the TypeMap!", type_);
129 // Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
130 // fail if the mapping already exists.
131 fn register_unique_id_with_metadata(
133 unique_type_id: UniqueTypeId,
134 metadata: &'ll DIType,
136 if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
137 bug!("Type metadata for unique id '{}' is already in the TypeMap!",
138 self.get_unique_type_id_as_string(unique_type_id));
142 fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<&'ll DIType> {
143 self.type_to_metadata.get(&type_).cloned()
146 fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<&'ll DIType> {
147 self.unique_id_to_metadata.get(&unique_type_id).cloned()
150 // Get the string representation of a UniqueTypeId. This method will fail if
151 // the id is unknown.
152 fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> &str {
153 let UniqueTypeId(interner_key) = unique_type_id;
154 self.unique_id_interner.get(interner_key)
157 // Get the UniqueTypeId for the given type. If the UniqueTypeId for the given
158 // type has been requested before, this is just a table lookup. Otherwise an
159 // ID will be generated and stored for later lookup.
160 fn get_unique_type_id_of_type<'a>(&mut self, cx: &CodegenCx<'a, 'tcx>,
161 type_: Ty<'tcx>) -> UniqueTypeId {
162 // Let's see if we already have something in the cache
163 if let Some(unique_type_id) = self.type_to_unique_id.get(&type_).cloned() {
164 return unique_type_id;
166 // if not, generate one
168 // The hasher we are using to generate the UniqueTypeId. We want
169 // something that provides more than the 64 bits of the DefaultHasher.
170 let mut hasher = StableHasher::<Fingerprint>::new();
171 let mut hcx = cx.tcx.create_stable_hashing_context();
172 let type_ = cx.tcx.erase_regions(&type_);
173 hcx.while_hashing_spans(false, |hcx| {
174 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
175 type_.hash_stable(hcx, &mut hasher);
178 let unique_type_id = hasher.finish().to_hex();
180 let key = self.unique_id_interner.intern(&unique_type_id);
181 self.type_to_unique_id.insert(type_, UniqueTypeId(key));
183 return UniqueTypeId(key);
186 // Get the UniqueTypeId for an enum variant. Enum variants are not really
187 // types of their own, so they need special handling. We still need a
188 // UniqueTypeId for them, since to debuginfo they *are* real types.
189 fn get_unique_type_id_of_enum_variant<'a>(&mut self,
190 cx: &CodegenCx<'a, 'tcx>,
194 let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
195 let enum_variant_type_id = format!("{}::{}",
196 self.get_unique_type_id_as_string(enum_type_id),
198 let interner_key = self.unique_id_interner.intern(&enum_variant_type_id);
199 UniqueTypeId(interner_key)
203 // A description of some recursive type. It can either be already finished (as
204 // with FinalMetadata) or it is not yet finished, but contains all information
205 // needed to generate the missing parts of the description. See the
206 // documentation section on Recursive Types at the top of this file for more
208 enum RecursiveTypeDescription<'ll, 'tcx> {
210 unfinished_type: Ty<'tcx>,
211 unique_type_id: UniqueTypeId,
212 metadata_stub: &'ll DICompositeType,
213 member_holding_stub: &'ll DICompositeType,
214 member_description_factory: MemberDescriptionFactory<'ll, 'tcx>,
216 FinalMetadata(&'ll DICompositeType)
219 fn create_and_register_recursive_type_forward_declaration(
220 cx: &CodegenCx<'ll, 'tcx>,
221 unfinished_type: Ty<'tcx>,
222 unique_type_id: UniqueTypeId,
223 metadata_stub: &'ll DICompositeType,
224 member_holding_stub: &'ll DICompositeType,
225 member_description_factory: MemberDescriptionFactory<'ll, 'tcx>,
226 ) -> RecursiveTypeDescription<'ll, 'tcx> {
228 // Insert the stub into the TypeMap in order to allow for recursive references
229 let mut type_map = debug_context(cx).type_map.borrow_mut();
230 type_map.register_unique_id_with_metadata(unique_type_id, metadata_stub);
231 type_map.register_type_with_metadata(unfinished_type, metadata_stub);
238 member_description_factory,
242 impl RecursiveTypeDescription<'ll, 'tcx> {
243 // Finishes up the description of the type in question (mostly by providing
244 // descriptions of the fields of the given type) and returns the final type
246 fn finalize(&self, cx: &CodegenCx<'ll, 'tcx>) -> MetadataCreationResult<'ll> {
248 FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
254 ref member_description_factory,
256 // Make sure that we have a forward declaration of the type in
257 // the TypeMap so that recursive references are possible. This
258 // will always be the case if the RecursiveTypeDescription has
259 // been properly created through the
260 // create_and_register_recursive_type_forward_declaration()
263 let type_map = debug_context(cx).type_map.borrow();
264 if type_map.find_metadata_for_unique_id(unique_type_id).is_none() ||
265 type_map.find_metadata_for_type(unfinished_type).is_none() {
266 bug!("Forward declaration of potentially recursive type \
267 '{:?}' was not found in TypeMap!",
272 // ... then create the member descriptions ...
273 let member_descriptions =
274 member_description_factory.create_member_descriptions(cx);
276 // ... and attach them to the stub to complete it.
277 set_members_of_composite_type(cx,
280 member_descriptions);
281 return MetadataCreationResult::new(metadata_stub, true);
287 // Returns from the enclosing function if the type metadata with the given
288 // unique id can be found in the type map
289 macro_rules! return_if_metadata_created_in_meantime {
290 ($cx: expr, $unique_type_id: expr) => (
291 if let Some(metadata) = debug_context($cx).type_map
293 .find_metadata_for_unique_id($unique_type_id)
295 return MetadataCreationResult::new(metadata, true);
300 fn fixed_vec_metadata(
301 cx: &CodegenCx<'ll, 'tcx>,
302 unique_type_id: UniqueTypeId,
303 array_or_slice_type: Ty<'tcx>,
304 element_type: Ty<'tcx>,
306 ) -> MetadataCreationResult<'ll> {
307 let element_type_metadata = type_metadata(cx, element_type, span);
309 return_if_metadata_created_in_meantime!(cx, unique_type_id);
311 let (size, align) = cx.size_and_align_of(array_or_slice_type);
313 let upper_bound = match array_or_slice_type.sty {
314 ty::Array(_, len) => {
315 len.unwrap_usize(cx.tcx) as c_longlong
320 let subrange = unsafe {
321 Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound))
324 let subscripts = create_DIArray(DIB(cx), &[subrange]);
325 let metadata = unsafe {
326 llvm::LLVMRustDIBuilderCreateArrayType(
330 element_type_metadata,
334 return MetadataCreationResult::new(metadata, false);
337 fn vec_slice_metadata(
338 cx: &CodegenCx<'ll, 'tcx>,
339 slice_ptr_type: Ty<'tcx>,
340 element_type: Ty<'tcx>,
341 unique_type_id: UniqueTypeId,
343 ) -> MetadataCreationResult<'ll> {
344 let data_ptr_type = cx.tcx.mk_imm_ptr(element_type);
346 let data_ptr_metadata = type_metadata(cx, data_ptr_type, span);
348 return_if_metadata_created_in_meantime!(cx, unique_type_id);
350 let slice_type_name = compute_debuginfo_type_name(cx, slice_ptr_type, true);
352 let (pointer_size, pointer_align) = cx.size_and_align_of(data_ptr_type);
353 let (usize_size, usize_align) = cx.size_and_align_of(cx.tcx.types.usize);
355 let member_descriptions = vec![
357 name: "data_ptr".to_owned(),
358 type_metadata: data_ptr_metadata,
361 align: pointer_align,
362 flags: DIFlags::FlagZero,
366 name: "length".to_owned(),
367 type_metadata: type_metadata(cx, cx.tcx.types.usize, span),
368 offset: pointer_size,
371 flags: DIFlags::FlagZero,
376 let file_metadata = unknown_file_metadata(cx);
378 let metadata = composite_type_metadata(cx,
380 &slice_type_name[..],
386 MetadataCreationResult::new(metadata, false)
389 fn subroutine_type_metadata(
390 cx: &CodegenCx<'ll, 'tcx>,
391 unique_type_id: UniqueTypeId,
392 signature: ty::PolyFnSig<'tcx>,
394 ) -> MetadataCreationResult<'ll> {
395 let signature = cx.tcx.normalize_erasing_late_bound_regions(
396 ty::ParamEnv::reveal_all(),
400 let signature_metadata: Vec<_> = iter::once(
402 match signature.output().sty {
403 ty::Tuple(ref tys) if tys.is_empty() => None,
404 _ => Some(type_metadata(cx, signature.output(), span))
408 signature.inputs().iter().map(|argument_type| {
409 Some(type_metadata(cx, argument_type, span))
413 return_if_metadata_created_in_meantime!(cx, unique_type_id);
415 return MetadataCreationResult::new(
417 llvm::LLVMRustDIBuilderCreateSubroutineType(
419 unknown_file_metadata(cx),
420 create_DIArray(DIB(cx), &signature_metadata[..]))
425 // FIXME(1563) This is all a bit of a hack because 'trait pointer' is an ill-
426 // defined concept. For the case of an actual trait pointer (i.e., Box<Trait>,
427 // &Trait), trait_object_type should be the whole thing (e.g, Box<Trait>) and
428 // trait_type should be the actual trait (e.g., Trait). Where the trait is part
429 // of a DST struct, there is no trait_object_type and the results of this
430 // function will be a little bit weird.
431 fn trait_pointer_metadata(
432 cx: &CodegenCx<'ll, 'tcx>,
433 trait_type: Ty<'tcx>,
434 trait_object_type: Option<Ty<'tcx>>,
435 unique_type_id: UniqueTypeId,
437 // The implementation provided here is a stub. It makes sure that the trait
438 // type is assigned the correct name, size, namespace, and source location.
439 // But it does not describe the trait's methods.
441 let containing_scope = match trait_type.sty {
442 ty::Dynamic(ref data, ..) => Some(get_namespace_for_item(cx, data.principal().def_id())),
444 bug!("debuginfo: Unexpected trait-object type in \
445 trait_pointer_metadata(): {:?}",
450 let trait_object_type = trait_object_type.unwrap_or(trait_type);
451 let trait_type_name =
452 compute_debuginfo_type_name(cx, trait_object_type, false);
454 let file_metadata = unknown_file_metadata(cx);
456 let layout = cx.layout_of(cx.tcx.mk_mut_ptr(trait_type));
458 assert_eq!(abi::FAT_PTR_ADDR, 0);
459 assert_eq!(abi::FAT_PTR_EXTRA, 1);
461 let data_ptr_field = layout.field(cx, 0);
462 let vtable_field = layout.field(cx, 1);
463 let member_descriptions = vec![
465 name: "pointer".to_owned(),
466 type_metadata: type_metadata(cx,
467 cx.tcx.mk_mut_ptr(cx.tcx.types.u8),
468 syntax_pos::DUMMY_SP),
469 offset: layout.fields.offset(0),
470 size: data_ptr_field.size,
471 align: data_ptr_field.align.abi,
472 flags: DIFlags::FlagArtificial,
476 name: "vtable".to_owned(),
477 type_metadata: type_metadata(cx, vtable_field.ty, syntax_pos::DUMMY_SP),
478 offset: layout.fields.offset(1),
479 size: vtable_field.size,
480 align: vtable_field.align.abi,
481 flags: DIFlags::FlagArtificial,
486 composite_type_metadata(cx,
488 &trait_type_name[..],
493 syntax_pos::DUMMY_SP)
496 pub fn type_metadata(
497 cx: &CodegenCx<'ll, 'tcx>,
499 usage_site_span: Span,
501 // Get the unique type id of this type.
502 let unique_type_id = {
503 let mut type_map = debug_context(cx).type_map.borrow_mut();
504 // First, try to find the type in TypeMap. If we have seen it before, we
505 // can exit early here.
506 match type_map.find_metadata_for_type(t) {
511 // The Ty is not in the TypeMap but maybe we have already seen
512 // an equivalent type (e.g. only differing in region arguments).
513 // In order to find out, generate the unique type id and look
515 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
516 match type_map.find_metadata_for_unique_id(unique_type_id) {
518 // There is already an equivalent type in the TypeMap.
519 // Register this Ty as an alias in the cache and
520 // return the cached metadata.
521 type_map.register_type_with_metadata(t, metadata);
525 // There really is no type metadata for this type, so
526 // proceed by creating it.
534 debug!("type_metadata: {:?}", t);
536 let ptr_metadata = |ty: Ty<'tcx>| {
539 Ok(vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span))
542 Ok(vec_slice_metadata(cx, t, cx.tcx.types.u8, unique_type_id, usage_site_span))
545 Ok(MetadataCreationResult::new(
546 trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
550 let pointee_metadata = type_metadata(cx, ty, usage_site_span);
552 if let Some(metadata) = debug_context(cx).type_map
554 .find_metadata_for_unique_id(unique_type_id)
556 return Err(metadata);
559 Ok(MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
565 let MetadataCreationResult { metadata, already_stored_in_typemap } = match t.sty {
572 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
574 ty::Tuple(ref elements) if elements.is_empty() => {
575 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
579 fixed_vec_metadata(cx, unique_type_id, t, typ, usage_site_span)
582 fixed_vec_metadata(cx, unique_type_id, t, cx.tcx.types.i8, usage_site_span)
585 MetadataCreationResult::new(
586 trait_pointer_metadata(cx, t, None, unique_type_id),
590 MetadataCreationResult::new(
591 foreign_type_metadata(cx, t, unique_type_id),
594 ty::RawPtr(ty::TypeAndMut{ty, ..}) |
595 ty::Ref(_, ty, _) => {
596 match ptr_metadata(ty) {
598 Err(metadata) => return metadata,
601 ty::Adt(def, _) if def.is_box() => {
602 match ptr_metadata(t.boxed_ty()) {
604 Err(metadata) => return metadata,
607 ty::FnDef(..) | ty::FnPtr(_) => {
608 let fn_metadata = subroutine_type_metadata(cx,
611 usage_site_span).metadata;
612 if let Some(metadata) = debug_context(cx).type_map
614 .find_metadata_for_unique_id(unique_type_id)
619 // This is actually a function pointer, so wrap it in pointer DI
620 MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false)
623 ty::Closure(def_id, substs) => {
624 let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx).collect();
625 prepare_tuple_metadata(cx,
629 usage_site_span).finalize(cx)
631 ty::Generator(def_id, substs, _) => {
632 let upvar_tys : Vec<_> = substs.field_tys(def_id, cx.tcx).map(|t| {
633 cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t)
635 prepare_tuple_metadata(cx,
639 usage_site_span).finalize(cx)
641 ty::Adt(def, ..) => match def.adt_kind() {
643 prepare_struct_metadata(cx,
646 usage_site_span).finalize(cx)
649 prepare_union_metadata(cx,
652 usage_site_span).finalize(cx)
655 prepare_enum_metadata(cx,
659 usage_site_span).finalize(cx)
662 ty::Tuple(ref elements) => {
663 prepare_tuple_metadata(cx,
667 usage_site_span).finalize(cx)
670 bug!("debuginfo: unexpected type in type_metadata: {:?}", t)
675 let mut type_map = debug_context(cx).type_map.borrow_mut();
677 if already_stored_in_typemap {
678 // Also make sure that we already have a TypeMap entry for the unique type id.
679 let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
680 Some(metadata) => metadata,
682 span_bug!(usage_site_span,
683 "Expected type metadata for unique \
684 type id '{}' to already be in \
685 the debuginfo::TypeMap but it \
687 type_map.get_unique_type_id_as_string(unique_type_id),
692 match type_map.find_metadata_for_type(t) {
694 if metadata != metadata_for_uid {
695 span_bug!(usage_site_span,
696 "Mismatch between Ty and \
697 UniqueTypeId maps in \
698 debuginfo::TypeMap. \
699 UniqueTypeId={}, Ty={}",
700 type_map.get_unique_type_id_as_string(unique_type_id),
705 type_map.register_type_with_metadata(t, metadata);
709 type_map.register_type_with_metadata(t, metadata);
710 type_map.register_unique_id_with_metadata(unique_type_id, metadata);
717 pub fn file_metadata(cx: &CodegenCx<'ll, '_>,
718 file_name: &FileName,
719 defining_crate: CrateNum) -> &'ll DIFile {
720 debug!("file_metadata: file_name: {}, defining_crate: {}",
724 let directory = if defining_crate == LOCAL_CRATE {
725 &cx.sess().working_dir.0
727 // If the path comes from an upstream crate we assume it has been made
728 // independent of the compiler's working directory one way or another.
732 file_metadata_raw(cx, &file_name.to_string(), &directory.to_string_lossy())
735 pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
736 file_metadata_raw(cx, "<unknown>", "")
739 fn file_metadata_raw(cx: &CodegenCx<'ll, '_>,
743 let key = (Symbol::intern(file_name), Symbol::intern(directory));
745 if let Some(file_metadata) = debug_context(cx).created_files.borrow().get(&key) {
746 return *file_metadata;
749 debug!("file_metadata: file_name: {}, directory: {}", file_name, directory);
751 let file_name = SmallCStr::new(file_name);
752 let directory = SmallCStr::new(directory);
754 let file_metadata = unsafe {
755 llvm::LLVMRustDIBuilderCreateFile(DIB(cx),
760 let mut created_files = debug_context(cx).created_files.borrow_mut();
761 created_files.insert(key, file_metadata);
765 fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
766 debug!("basic_type_metadata: {:?}", t);
768 let (name, encoding) = match t.sty {
769 ty::Never => ("!", DW_ATE_unsigned),
770 ty::Tuple(ref elements) if elements.is_empty() =>
771 ("()", DW_ATE_unsigned),
772 ty::Bool => ("bool", DW_ATE_boolean),
773 ty::Char => ("char", DW_ATE_unsigned_char),
775 (int_ty.ty_to_string(), DW_ATE_signed)
777 ty::Uint(uint_ty) => {
778 (uint_ty.ty_to_string(), DW_ATE_unsigned)
780 ty::Float(float_ty) => {
781 (float_ty.ty_to_string(), DW_ATE_float)
783 _ => bug!("debuginfo::basic_type_metadata - t is invalid type")
786 let (size, align) = cx.size_and_align_of(t);
787 let name = SmallCStr::new(name);
788 let ty_metadata = unsafe {
789 llvm::LLVMRustDIBuilderCreateBasicType(
800 fn foreign_type_metadata(
801 cx: &CodegenCx<'ll, 'tcx>,
803 unique_type_id: UniqueTypeId,
805 debug!("foreign_type_metadata: {:?}", t);
807 let name = compute_debuginfo_type_name(cx, t, false);
808 create_struct_stub(cx, t, &name, unique_type_id, NO_SCOPE_METADATA)
811 fn pointer_type_metadata(
812 cx: &CodegenCx<'ll, 'tcx>,
813 pointer_type: Ty<'tcx>,
814 pointee_type_metadata: &'ll DIType,
816 let (pointer_size, pointer_align) = cx.size_and_align_of(pointer_type);
817 let name = compute_debuginfo_type_name(cx, pointer_type, false);
818 let name = SmallCStr::new(&name);
820 llvm::LLVMRustDIBuilderCreatePointerType(
822 pointee_type_metadata,
824 pointer_align.bits() as u32,
829 pub fn compile_unit_metadata(tcx: TyCtxt,
830 codegen_unit_name: &str,
831 debug_context: &CrateDebugContext<'ll, '_>)
832 -> &'ll DIDescriptor {
833 let mut name_in_debuginfo = match tcx.sess.local_crate_source_file {
834 Some(ref path) => path.clone(),
835 None => PathBuf::from(&*tcx.crate_name(LOCAL_CRATE).as_str()),
838 // The OSX linker has an idiosyncrasy where it will ignore some debuginfo
839 // if multiple object files with the same DW_AT_name are linked together.
840 // As a workaround we generate unique names for each object file. Those do
841 // not correspond to an actual source file but that should be harmless.
842 if tcx.sess.target.target.options.is_like_osx {
843 name_in_debuginfo.push("@");
844 name_in_debuginfo.push(codegen_unit_name);
847 debug!("compile_unit_metadata: {:?}", name_in_debuginfo);
848 // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
849 let producer = format!("clang LLVM (rustc version {})",
850 (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
852 let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
853 let name_in_debuginfo = SmallCStr::new(&name_in_debuginfo);
854 let work_dir = SmallCStr::new(&tcx.sess.working_dir.0.to_string_lossy());
855 let producer = CString::new(producer).unwrap();
857 let split_name = "\0";
860 let file_metadata = llvm::LLVMRustDIBuilderCreateFile(
861 debug_context.builder, name_in_debuginfo.as_ptr(), work_dir.as_ptr());
863 let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
864 debug_context.builder,
868 tcx.sess.opts.optimize != config::OptLevel::No,
869 flags.as_ptr() as *const _,
871 split_name.as_ptr() as *const _);
873 if tcx.sess.opts.debugging_opts.profile {
874 let cu_desc_metadata = llvm::LLVMRustMetadataAsValue(debug_context.llcontext,
878 path_to_mdstring(debug_context.llcontext,
879 &tcx.output_filenames(LOCAL_CRATE).with_extension("gcno")),
880 path_to_mdstring(debug_context.llcontext,
881 &tcx.output_filenames(LOCAL_CRATE).with_extension("gcda")),
884 let gcov_metadata = llvm::LLVMMDNodeInContext(debug_context.llcontext,
885 gcov_cu_info.as_ptr(),
886 gcov_cu_info.len() as c_uint);
888 let llvm_gcov_ident = const_cstr!("llvm.gcov");
889 llvm::LLVMAddNamedMetadataOperand(debug_context.llmod,
890 llvm_gcov_ident.as_ptr(),
894 return unit_metadata;
897 fn path_to_mdstring(llcx: &'ll llvm::Context, path: &Path) -> &'ll Value {
898 let path_str = path_to_c_string(path);
900 llvm::LLVMMDStringInContext(llcx,
902 path_str.as_bytes().len() as c_uint)
907 struct MetadataCreationResult<'ll> {
908 metadata: &'ll DIType,
909 already_stored_in_typemap: bool
912 impl MetadataCreationResult<'ll> {
913 fn new(metadata: &'ll DIType, already_stored_in_typemap: bool) -> Self {
914 MetadataCreationResult {
916 already_stored_in_typemap,
921 // Description of a type member, which can either be a regular field (as in
922 // structs or tuples) or an enum variant.
924 struct MemberDescription<'ll> {
926 type_metadata: &'ll DIType,
931 discriminant: Option<u64>,
934 // A factory for MemberDescriptions. It produces a list of member descriptions
935 // for some record-like type. MemberDescriptionFactories are used to defer the
936 // creation of type member descriptions in order to break cycles arising from
937 // recursive type definitions.
938 enum MemberDescriptionFactory<'ll, 'tcx> {
939 StructMDF(StructMemberDescriptionFactory<'tcx>),
940 TupleMDF(TupleMemberDescriptionFactory<'tcx>),
941 EnumMDF(EnumMemberDescriptionFactory<'ll, 'tcx>),
942 UnionMDF(UnionMemberDescriptionFactory<'tcx>),
943 VariantMDF(VariantMemberDescriptionFactory<'ll, 'tcx>)
946 impl MemberDescriptionFactory<'ll, 'tcx> {
947 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
948 -> Vec<MemberDescription<'ll>> {
950 StructMDF(ref this) => {
951 this.create_member_descriptions(cx)
953 TupleMDF(ref this) => {
954 this.create_member_descriptions(cx)
956 EnumMDF(ref this) => {
957 this.create_member_descriptions(cx)
959 UnionMDF(ref this) => {
960 this.create_member_descriptions(cx)
962 VariantMDF(ref this) => {
963 this.create_member_descriptions(cx)
969 //=-----------------------------------------------------------------------------
971 //=-----------------------------------------------------------------------------
973 // Creates MemberDescriptions for the fields of a struct
974 struct StructMemberDescriptionFactory<'tcx> {
976 variant: &'tcx ty::VariantDef,
980 impl<'tcx> StructMemberDescriptionFactory<'tcx> {
981 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
982 -> Vec<MemberDescription<'ll>> {
983 let layout = cx.layout_of(self.ty);
984 self.variant.fields.iter().enumerate().map(|(i, f)| {
985 let name = if self.variant.ctor_kind == CtorKind::Fn {
990 let field = layout.field(cx, i);
993 type_metadata: type_metadata(cx, field.ty, self.span),
994 offset: layout.fields.offset(i),
996 align: field.align.abi,
997 flags: DIFlags::FlagZero,
1005 fn prepare_struct_metadata(
1006 cx: &CodegenCx<'ll, 'tcx>,
1007 struct_type: Ty<'tcx>,
1008 unique_type_id: UniqueTypeId,
1010 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1011 let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
1013 let (struct_def_id, variant) = match struct_type.sty {
1014 ty::Adt(def, _) => (def.did, def.non_enum_variant()),
1015 _ => bug!("prepare_struct_metadata on a non-ADT")
1018 let containing_scope = get_namespace_for_item(cx, struct_def_id);
1020 let struct_metadata_stub = create_struct_stub(cx,
1024 Some(containing_scope));
1026 create_and_register_recursive_type_forward_declaration(
1030 struct_metadata_stub,
1031 struct_metadata_stub,
1032 StructMDF(StructMemberDescriptionFactory {
1040 //=-----------------------------------------------------------------------------
1042 //=-----------------------------------------------------------------------------
1044 // Creates MemberDescriptions for the fields of a tuple
1045 struct TupleMemberDescriptionFactory<'tcx> {
1047 component_types: Vec<Ty<'tcx>>,
1051 impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
1052 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1053 -> Vec<MemberDescription<'ll>> {
1054 let layout = cx.layout_of(self.ty);
1055 self.component_types.iter().enumerate().map(|(i, &component_type)| {
1056 let (size, align) = cx.size_and_align_of(component_type);
1058 name: format!("__{}", i),
1059 type_metadata: type_metadata(cx, component_type, self.span),
1060 offset: layout.fields.offset(i),
1063 flags: DIFlags::FlagZero,
1070 fn prepare_tuple_metadata(
1071 cx: &CodegenCx<'ll, 'tcx>,
1072 tuple_type: Ty<'tcx>,
1073 component_types: &[Ty<'tcx>],
1074 unique_type_id: UniqueTypeId,
1076 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1077 let tuple_name = compute_debuginfo_type_name(cx, tuple_type, false);
1079 let struct_stub = create_struct_stub(cx,
1085 create_and_register_recursive_type_forward_declaration(
1091 TupleMDF(TupleMemberDescriptionFactory {
1093 component_types: component_types.to_vec(),
1099 //=-----------------------------------------------------------------------------
1101 //=-----------------------------------------------------------------------------
1103 struct UnionMemberDescriptionFactory<'tcx> {
1104 layout: TyLayout<'tcx>,
1105 variant: &'tcx ty::VariantDef,
1109 impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
1110 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1111 -> Vec<MemberDescription<'ll>> {
1112 self.variant.fields.iter().enumerate().map(|(i, f)| {
1113 let field = self.layout.field(cx, i);
1115 name: f.ident.to_string(),
1116 type_metadata: type_metadata(cx, field.ty, self.span),
1119 align: field.align.abi,
1120 flags: DIFlags::FlagZero,
1127 fn prepare_union_metadata(
1128 cx: &CodegenCx<'ll, 'tcx>,
1129 union_type: Ty<'tcx>,
1130 unique_type_id: UniqueTypeId,
1132 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1133 let union_name = compute_debuginfo_type_name(cx, union_type, false);
1135 let (union_def_id, variant) = match union_type.sty {
1136 ty::Adt(def, _) => (def.did, def.non_enum_variant()),
1137 _ => bug!("prepare_union_metadata on a non-ADT")
1140 let containing_scope = get_namespace_for_item(cx, union_def_id);
1142 let union_metadata_stub = create_union_stub(cx,
1148 create_and_register_recursive_type_forward_declaration(
1152 union_metadata_stub,
1153 union_metadata_stub,
1154 UnionMDF(UnionMemberDescriptionFactory {
1155 layout: cx.layout_of(union_type),
1162 //=-----------------------------------------------------------------------------
1164 //=-----------------------------------------------------------------------------
1166 // DWARF variant support is only available starting in LLVM 7.
1167 // Although the earlier enum debug info output did not work properly
1168 // in all situations, it is better for the time being to continue to
1169 // sometimes emit the old style rather than emit something completely
1170 // useless when rust is compiled against LLVM 6 or older. This
1171 // function decides which representation will be emitted.
1172 fn use_enum_fallback(cx: &CodegenCx) -> bool {
1173 // On MSVC we have to use the fallback mode, because LLVM doesn't
1174 // lower variant parts to PDB.
1175 return cx.sess().target.target.options.is_like_msvc
1176 || llvm_util::get_major_version() < 7;
1179 // Describes the members of an enum value: An enum is described as a union of
1180 // structs in DWARF. This MemberDescriptionFactory provides the description for
1181 // the members of this union; so for every variant of the given enum, this
1182 // factory will produce one MemberDescription (all with no name and a fixed
1183 // offset of zero bytes).
1184 struct EnumMemberDescriptionFactory<'ll, 'tcx> {
1185 enum_type: Ty<'tcx>,
1186 layout: TyLayout<'tcx>,
1187 discriminant_type_metadata: Option<&'ll DIType>,
1188 containing_scope: &'ll DIScope,
1192 impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1193 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1194 -> Vec<MemberDescription<'ll>> {
1195 let adt = &self.enum_type.ty_adt_def().unwrap();
1197 // This will always find the metadata in the type map.
1198 let fallback = use_enum_fallback(cx);
1199 let self_metadata = if fallback {
1200 self.containing_scope
1202 type_metadata(cx, self.enum_type, self.span)
1205 match self.layout.variants {
1206 layout::Variants::Single { .. } if adt.variants.is_empty() => vec![],
1207 layout::Variants::Single { index } => {
1208 let (variant_type_metadata, member_description_factory) =
1209 describe_enum_variant(cx,
1211 &adt.variants[index],
1216 let member_descriptions =
1217 member_description_factory.create_member_descriptions(cx);
1219 set_members_of_composite_type(cx,
1221 variant_type_metadata,
1222 member_descriptions);
1228 adt.variants[index].name.as_str().to_string()
1230 type_metadata: variant_type_metadata,
1232 size: self.layout.size,
1233 align: self.layout.align.abi,
1234 flags: DIFlags::FlagZero,
1239 layout::Variants::Tagged { ref variants, .. } => {
1240 let discriminant_info = if fallback {
1241 RegularDiscriminant(self.discriminant_type_metadata
1244 // This doesn't matter in this case.
1247 variants.iter_enumerated().map(|(i, _)| {
1248 let variant = self.layout.for_variant(cx, i);
1249 let (variant_type_metadata, member_desc_factory) =
1250 describe_enum_variant(cx,
1257 let member_descriptions = member_desc_factory
1258 .create_member_descriptions(cx);
1260 set_members_of_composite_type(cx,
1262 variant_type_metadata,
1263 member_descriptions);
1268 adt.variants[i].name.as_str().to_string()
1270 type_metadata: variant_type_metadata,
1272 size: self.layout.size,
1273 align: self.layout.align.abi,
1274 flags: DIFlags::FlagZero,
1275 discriminant: Some(self.layout.ty.ty_adt_def().unwrap()
1276 .discriminant_for_variant(cx.tcx, i)
1281 layout::Variants::NicheFilling {
1289 let variant = self.layout.for_variant(cx, dataful_variant);
1290 // Create a description of the non-null variant
1291 let (variant_type_metadata, member_description_factory) =
1292 describe_enum_variant(cx,
1294 &adt.variants[dataful_variant],
1295 OptimizedDiscriminant,
1296 self.containing_scope,
1299 let variant_member_descriptions =
1300 member_description_factory.create_member_descriptions(cx);
1302 set_members_of_composite_type(cx,
1304 variant_type_metadata,
1305 variant_member_descriptions);
1307 // Encode the information about the null variant in the union
1309 let mut name = String::from("RUST$ENCODED$ENUM$");
1310 // Right now it's not even going to work for `niche_start > 0`,
1311 // and for multiple niche variants it only supports the first.
1312 fn compute_field_path<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
1314 layout: TyLayout<'tcx>,
1317 for i in 0..layout.fields.count() {
1318 let field_offset = layout.fields.offset(i);
1319 if field_offset > offset {
1322 let inner_offset = offset - field_offset;
1323 let field = layout.field(cx, i);
1324 if inner_offset + size <= field.size {
1325 write!(name, "{}$", i).unwrap();
1326 compute_field_path(cx, name, field, inner_offset, size);
1330 compute_field_path(cx, &mut name,
1332 self.layout.fields.offset(0),
1333 self.layout.field(cx, 0).size);
1334 name.push_str(&adt.variants[*niche_variants.start()].name.as_str());
1336 // Create the (singleton) list of descriptions of union members.
1340 type_metadata: variant_type_metadata,
1343 align: variant.align.abi,
1344 flags: DIFlags::FlagZero,
1349 variants.iter_enumerated().map(|(i, _)| {
1350 let variant = self.layout.for_variant(cx, i);
1351 let (variant_type_metadata, member_desc_factory) =
1352 describe_enum_variant(cx,
1355 OptimizedDiscriminant,
1359 let member_descriptions = member_desc_factory
1360 .create_member_descriptions(cx);
1362 set_members_of_composite_type(cx,
1364 variant_type_metadata,
1365 member_descriptions);
1367 let niche_value = if i == dataful_variant {
1370 let value = (i.as_u32() as u128)
1371 .wrapping_sub(niche_variants.start().as_u32() as u128)
1372 .wrapping_add(niche_start);
1373 let value = value & ((1u128 << niche.value.size(cx).bits()) - 1);
1378 name: adt.variants[i].name.as_str().to_string(),
1379 type_metadata: variant_type_metadata,
1381 size: self.layout.size,
1382 align: self.layout.align.abi,
1383 flags: DIFlags::FlagZero,
1384 discriminant: niche_value,
1393 // Creates MemberDescriptions for the fields of a single enum variant.
1394 struct VariantMemberDescriptionFactory<'ll, 'tcx> {
1395 // Cloned from the layout::Struct describing the variant.
1396 offsets: Vec<layout::Size>,
1397 args: Vec<(String, Ty<'tcx>)>,
1398 discriminant_type_metadata: Option<&'ll DIType>,
1402 impl VariantMemberDescriptionFactory<'ll, 'tcx> {
1403 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1404 -> Vec<MemberDescription<'ll>> {
1405 self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
1406 let (size, align) = cx.size_and_align_of(ty);
1408 name: name.to_string(),
1409 type_metadata: if use_enum_fallback(cx) {
1410 match self.discriminant_type_metadata {
1411 Some(metadata) if i == 0 => metadata,
1412 _ => type_metadata(cx, ty, self.span)
1415 type_metadata(cx, ty, self.span)
1417 offset: self.offsets[i],
1420 flags: DIFlags::FlagZero,
1427 #[derive(Copy, Clone)]
1428 enum EnumDiscriminantInfo<'ll> {
1429 RegularDiscriminant(&'ll DIType),
1430 OptimizedDiscriminant,
1434 // Returns a tuple of (1) type_metadata_stub of the variant, (2) a
1435 // MemberDescriptionFactory for producing the descriptions of the
1436 // fields of the variant. This is a rudimentary version of a full
1437 // RecursiveTypeDescription.
1438 fn describe_enum_variant(
1439 cx: &CodegenCx<'ll, 'tcx>,
1440 layout: layout::TyLayout<'tcx>,
1441 variant: &'tcx ty::VariantDef,
1442 discriminant_info: EnumDiscriminantInfo<'ll>,
1443 containing_scope: &'ll DIScope,
1445 ) -> (&'ll DICompositeType, MemberDescriptionFactory<'ll, 'tcx>) {
1446 let variant_name = variant.name.as_str();
1447 let unique_type_id = debug_context(cx).type_map
1449 .get_unique_type_id_of_enum_variant(
1454 let metadata_stub = create_struct_stub(cx,
1458 Some(containing_scope));
1460 // Build an array of (field name, field type) pairs to be captured in the factory closure.
1461 let (offsets, args) = if use_enum_fallback(cx) {
1462 // If this is not a univariant enum, there is also the discriminant field.
1463 let (discr_offset, discr_arg) = match discriminant_info {
1464 RegularDiscriminant(_) => {
1465 // We have the layout of an enum variant, we need the layout of the outer enum
1466 let enum_layout = cx.layout_of(layout.ty);
1467 (Some(enum_layout.fields.offset(0)),
1468 Some(("RUST$ENUM$DISR".to_owned(), enum_layout.field(cx, 0).ty)))
1473 discr_offset.into_iter().chain((0..layout.fields.count()).map(|i| {
1474 layout.fields.offset(i)
1476 discr_arg.into_iter().chain((0..layout.fields.count()).map(|i| {
1477 let name = if variant.ctor_kind == CtorKind::Fn {
1480 variant.fields[i].ident.to_string()
1482 (name, layout.field(cx, i).ty)
1487 (0..layout.fields.count()).map(|i| {
1488 layout.fields.offset(i)
1490 (0..layout.fields.count()).map(|i| {
1491 let name = if variant.ctor_kind == CtorKind::Fn {
1494 variant.fields[i].ident.to_string()
1496 (name, layout.field(cx, i).ty)
1501 let member_description_factory =
1502 VariantMDF(VariantMemberDescriptionFactory {
1505 discriminant_type_metadata: match discriminant_info {
1506 RegularDiscriminant(discriminant_type_metadata) => {
1507 Some(discriminant_type_metadata)
1514 (metadata_stub, member_description_factory)
1517 fn prepare_enum_metadata(
1518 cx: &CodegenCx<'ll, 'tcx>,
1519 enum_type: Ty<'tcx>,
1521 unique_type_id: UniqueTypeId,
1523 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1524 let enum_name = compute_debuginfo_type_name(cx, enum_type, false);
1526 let containing_scope = get_namespace_for_item(cx, enum_def_id);
1527 // FIXME: This should emit actual file metadata for the enum, but we
1528 // currently can't get the necessary information when it comes to types
1529 // imported from other crates. Formerly we violated the ODR when performing
1530 // LTO because we emitted debuginfo for the same type with varying file
1531 // metadata, so as a workaround we pretend that the type comes from
1533 let file_metadata = unknown_file_metadata(cx);
1535 let discriminant_type_metadata = |discr: layout::Primitive| {
1536 let def = enum_type.ty_adt_def().unwrap();
1537 let enumerators_metadata: Vec<_> = def.discriminants(cx.tcx)
1539 .map(|((_, discr), v)| {
1540 let name = SmallCStr::new(&v.name.as_str());
1542 Some(llvm::LLVMRustDIBuilderCreateEnumerator(
1545 // FIXME: what if enumeration has i128 discriminant?
1551 let disr_type_key = (enum_def_id, discr);
1552 let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
1554 .get(&disr_type_key).cloned();
1555 match cached_discriminant_type_metadata {
1556 Some(discriminant_type_metadata) => discriminant_type_metadata,
1558 let (discriminant_size, discriminant_align) =
1559 (discr.size(cx), discr.align(cx));
1560 let discriminant_base_type_metadata =
1561 type_metadata(cx, discr.to_ty(cx.tcx), syntax_pos::DUMMY_SP);
1562 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id).as_str();
1564 let name = SmallCStr::new(&discriminant_name);
1565 let discriminant_type_metadata = unsafe {
1566 llvm::LLVMRustDIBuilderCreateEnumerationType(
1571 UNKNOWN_LINE_NUMBER,
1572 discriminant_size.bits(),
1573 discriminant_align.abi.bits() as u32,
1574 create_DIArray(DIB(cx), &enumerators_metadata),
1575 discriminant_base_type_metadata, true)
1578 debug_context(cx).created_enum_disr_types
1580 .insert(disr_type_key, discriminant_type_metadata);
1582 discriminant_type_metadata
1587 let layout = cx.layout_of(enum_type);
1589 match (&layout.abi, &layout.variants) {
1590 (&layout::Abi::Scalar(_), &layout::Variants::Tagged {ref tag, .. }) =>
1591 return FinalMetadata(discriminant_type_metadata(tag.value)),
1595 let enum_name = SmallCStr::new(&enum_name);
1596 let unique_type_id_str = SmallCStr::new(
1597 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
1600 if use_enum_fallback(cx) {
1601 let discriminant_type_metadata = match layout.variants {
1602 layout::Variants::Single { .. } |
1603 layout::Variants::NicheFilling { .. } => None,
1604 layout::Variants::Tagged { ref tag, .. } => {
1605 Some(discriminant_type_metadata(tag.value))
1609 let enum_metadata = unsafe {
1610 llvm::LLVMRustDIBuilderCreateUnionType(
1615 UNKNOWN_LINE_NUMBER,
1617 layout.align.abi.bits() as u32,
1621 unique_type_id_str.as_ptr())
1624 return create_and_register_recursive_type_forward_declaration(
1630 EnumMDF(EnumMemberDescriptionFactory {
1633 discriminant_type_metadata,
1640 let discriminator_metadata = match &layout.variants {
1641 // A single-variant enum has no discriminant.
1642 &layout::Variants::Single { .. } => None,
1644 &layout::Variants::NicheFilling { ref niche, .. } => {
1645 // Find the integer type of the correct size.
1646 let size = niche.value.size(cx);
1647 let align = niche.value.align(cx);
1649 let discr_type = match niche.value {
1650 layout::Int(t, _) => t,
1651 layout::Float(layout::FloatTy::F32) => Integer::I32,
1652 layout::Float(layout::FloatTy::F64) => Integer::I64,
1653 layout::Pointer => cx.data_layout().ptr_sized_integer(),
1654 }.to_ty(cx.tcx, false);
1656 let discr_metadata = basic_type_metadata(cx, discr_type);
1658 Some(llvm::LLVMRustDIBuilderCreateMemberType(
1663 UNKNOWN_LINE_NUMBER,
1665 align.abi.bits() as u32,
1666 layout.fields.offset(0).bits(),
1667 DIFlags::FlagArtificial,
1672 &layout::Variants::Tagged { ref tag, .. } => {
1673 let discr_type = tag.value.to_ty(cx.tcx);
1674 let (size, align) = cx.size_and_align_of(discr_type);
1676 let discr_metadata = basic_type_metadata(cx, discr_type);
1678 Some(llvm::LLVMRustDIBuilderCreateMemberType(
1683 UNKNOWN_LINE_NUMBER,
1685 align.bits() as u32,
1686 layout.fields.offset(0).bits(),
1687 DIFlags::FlagArtificial,
1693 let empty_array = create_DIArray(DIB(cx), &[]);
1694 let variant_part = unsafe {
1695 llvm::LLVMRustDIBuilderCreateVariantPart(
1700 UNKNOWN_LINE_NUMBER,
1702 layout.align.abi.bits() as u32,
1704 discriminator_metadata,
1706 unique_type_id_str.as_ptr())
1709 // The variant part must be wrapped in a struct according to DWARF.
1710 let type_array = create_DIArray(DIB(cx), &[Some(variant_part)]);
1711 let struct_wrapper = unsafe {
1712 llvm::LLVMRustDIBuilderCreateStructType(
1714 Some(containing_scope),
1717 UNKNOWN_LINE_NUMBER,
1719 layout.align.abi.bits() as u32,
1725 unique_type_id_str.as_ptr())
1728 return create_and_register_recursive_type_forward_declaration(
1734 EnumMDF(EnumMemberDescriptionFactory {
1737 discriminant_type_metadata: None,
1743 fn get_enum_discriminant_name(cx: &CodegenCx,
1746 cx.tcx.item_name(def_id)
1750 /// Creates debug information for a composite type, that is, anything that
1751 /// results in a LLVM struct.
1753 /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
1754 fn composite_type_metadata(
1755 cx: &CodegenCx<'ll, 'tcx>,
1756 composite_type: Ty<'tcx>,
1757 composite_type_name: &str,
1758 composite_type_unique_id: UniqueTypeId,
1759 member_descriptions: Vec<MemberDescription<'ll>>,
1760 containing_scope: Option<&'ll DIScope>,
1762 // Ignore source location information as long as it
1763 // can't be reconstructed for non-local crates.
1764 _file_metadata: &'ll DIFile,
1765 _definition_span: Span,
1766 ) -> &'ll DICompositeType {
1767 // Create the (empty) struct metadata node ...
1768 let composite_type_metadata = create_struct_stub(cx,
1770 composite_type_name,
1771 composite_type_unique_id,
1773 // ... and immediately create and add the member descriptions.
1774 set_members_of_composite_type(cx,
1776 composite_type_metadata,
1777 member_descriptions);
1779 composite_type_metadata
1782 fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>,
1783 composite_type: Ty<'tcx>,
1784 composite_type_metadata: &'ll DICompositeType,
1785 member_descriptions: Vec<MemberDescription<'ll>>) {
1786 // In some rare cases LLVM metadata uniquing would lead to an existing type
1787 // description being used instead of a new one created in
1788 // create_struct_stub. This would cause a hard to trace assertion in
1789 // DICompositeType::SetTypeArray(). The following check makes sure that we
1790 // get a better error message if this should happen again due to some
1793 let mut composite_types_completed =
1794 debug_context(cx).composite_types_completed.borrow_mut();
1795 if composite_types_completed.contains(&composite_type_metadata) {
1796 bug!("debuginfo::set_members_of_composite_type() - \
1797 Already completed forward declaration re-encountered.");
1799 composite_types_completed.insert(composite_type_metadata);
1803 let member_metadata: Vec<_> = member_descriptions
1805 .map(|member_description| {
1806 let member_name = CString::new(member_description.name).unwrap();
1808 Some(llvm::LLVMRustDIBuilderCreateVariantMemberType(
1810 composite_type_metadata,
1811 member_name.as_ptr(),
1812 unknown_file_metadata(cx),
1813 UNKNOWN_LINE_NUMBER,
1814 member_description.size.bits(),
1815 member_description.align.bits() as u32,
1816 member_description.offset.bits(),
1817 match member_description.discriminant {
1819 Some(value) => Some(cx.const_u64(value)),
1821 member_description.flags,
1822 member_description.type_metadata))
1827 let type_params = compute_type_parameters(cx, composite_type);
1829 let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
1830 llvm::LLVMRustDICompositeTypeReplaceArrays(
1831 DIB(cx), composite_type_metadata, Some(type_array), type_params);
1835 // Compute the type parameters for a type, if any, for the given
1837 fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> Option<&'ll DIArray> {
1838 if let ty::Adt(def, substs) = ty.sty {
1839 if !substs.types().next().is_none() {
1840 let generics = cx.tcx.generics_of(def.did);
1841 let names = get_parameter_names(cx, generics);
1842 let template_params: Vec<_> = substs.iter().zip(names).filter_map(|(kind, name)| {
1843 if let UnpackedKind::Type(ty) = kind.unpack() {
1844 let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
1845 let actual_type_metadata =
1846 type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
1847 let name = SmallCStr::new(&name.as_str());
1850 Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
1854 actual_type_metadata,
1855 unknown_file_metadata(cx),
1865 return Some(create_DIArray(DIB(cx), &template_params[..]));
1868 return Some(create_DIArray(DIB(cx), &[]));
1870 fn get_parameter_names(cx: &CodegenCx,
1871 generics: &ty::Generics)
1872 -> Vec<InternedString> {
1873 let mut names = generics.parent.map_or(vec![], |def_id| {
1874 get_parameter_names(cx, cx.tcx.generics_of(def_id))
1876 names.extend(generics.params.iter().map(|param| param.name));
1881 // A convenience wrapper around LLVMRustDIBuilderCreateStructType(). Does not do
1882 // any caching, does not add any fields to the struct. This can be done later
1883 // with set_members_of_composite_type().
1884 fn create_struct_stub(
1885 cx: &CodegenCx<'ll, 'tcx>,
1886 struct_type: Ty<'tcx>,
1887 struct_type_name: &str,
1888 unique_type_id: UniqueTypeId,
1889 containing_scope: Option<&'ll DIScope>,
1890 ) -> &'ll DICompositeType {
1891 let (struct_size, struct_align) = cx.size_and_align_of(struct_type);
1893 let name = SmallCStr::new(struct_type_name);
1894 let unique_type_id = SmallCStr::new(
1895 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
1897 let metadata_stub = unsafe {
1898 // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
1899 // pointer will lead to hard to trace and debug LLVM assertions
1900 // later on in llvm/lib/IR/Value.cpp.
1901 let empty_array = create_DIArray(DIB(cx), &[]);
1903 llvm::LLVMRustDIBuilderCreateStructType(
1907 unknown_file_metadata(cx),
1908 UNKNOWN_LINE_NUMBER,
1910 struct_align.bits() as u32,
1916 unique_type_id.as_ptr())
1922 fn create_union_stub(
1923 cx: &CodegenCx<'ll, 'tcx>,
1924 union_type: Ty<'tcx>,
1925 union_type_name: &str,
1926 unique_type_id: UniqueTypeId,
1927 containing_scope: &'ll DIScope,
1928 ) -> &'ll DICompositeType {
1929 let (union_size, union_align) = cx.size_and_align_of(union_type);
1931 let name = SmallCStr::new(union_type_name);
1932 let unique_type_id = SmallCStr::new(
1933 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
1935 let metadata_stub = unsafe {
1936 // LLVMRustDIBuilderCreateUnionType() wants an empty array. A null
1937 // pointer will lead to hard to trace and debug LLVM assertions
1938 // later on in llvm/lib/IR/Value.cpp.
1939 let empty_array = create_DIArray(DIB(cx), &[]);
1941 llvm::LLVMRustDIBuilderCreateUnionType(
1945 unknown_file_metadata(cx),
1946 UNKNOWN_LINE_NUMBER,
1948 union_align.bits() as u32,
1952 unique_type_id.as_ptr())
1958 /// Creates debug information for the given global variable.
1960 /// Adds the created metadata nodes directly to the crate's IR.
1961 pub fn create_global_var_metadata(
1962 cx: &CodegenCx<'ll, '_>,
1966 if cx.dbg_cx.is_none() {
1971 let attrs = tcx.codegen_fn_attrs(def_id);
1973 if attrs.flags.contains(CodegenFnAttrFlags::NO_DEBUG) {
1977 let no_mangle = attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE);
1978 // We may want to remove the namespace scope if we're in an extern block, see:
1979 // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952
1980 let var_scope = get_namespace_for_item(cx, def_id);
1981 let span = tcx.def_span(def_id);
1983 let (file_metadata, line_number) = if !span.is_dummy() {
1984 let loc = span_start(cx, span);
1985 (file_metadata(cx, &loc.file.name, LOCAL_CRATE), loc.line as c_uint)
1987 (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
1990 let is_local_to_unit = is_node_local_to_unit(cx, def_id);
1991 let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx);
1992 let type_metadata = type_metadata(cx, variable_type, span);
1993 let var_name = SmallCStr::new(&tcx.item_name(def_id).as_str());
1994 let linkage_name = if no_mangle {
1997 let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id));
1998 Some(SmallCStr::new(&linkage_name.as_str()))
2001 let global_align = cx.align_of(variable_type);
2004 llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
2007 // If null, linkage_name field is omitted,
2008 // which is what we want for no_mangle statics
2009 linkage_name.as_ref()
2010 .map_or(ptr::null(), |name| name.as_ptr()),
2017 global_align.bytes() as u32,
2022 /// Creates debug information for the given vtable, which is for the
2025 /// Adds the created metadata nodes directly to the crate's IR.
2026 pub fn create_vtable_metadata(
2027 cx: &CodegenCx<'ll, 'tcx>,
2031 if cx.dbg_cx.is_none() {
2035 let type_metadata = type_metadata(cx, ty, syntax_pos::DUMMY_SP);
2038 // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
2039 // pointer will lead to hard to trace and debug LLVM assertions
2040 // later on in llvm/lib/IR/Value.cpp.
2041 let empty_array = create_DIArray(DIB(cx), &[]);
2043 let name = const_cstr!("vtable");
2045 // Create a new one each time. We don't want metadata caching
2046 // here, because each vtable will refer to a unique containing
2048 let vtable_type = llvm::LLVMRustDIBuilderCreateStructType(
2052 unknown_file_metadata(cx),
2053 UNKNOWN_LINE_NUMBER,
2055 cx.tcx.data_layout.pointer_align.abi.bits() as u32,
2056 DIFlags::FlagArtificial,
2060 Some(type_metadata),
2064 llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
2068 unknown_file_metadata(cx),
2069 UNKNOWN_LINE_NUMBER,
2078 // Creates an "extension" of an existing DIScope into another file.
2079 pub fn extend_scope_to_file(
2080 cx: &CodegenCx<'ll, '_>,
2081 scope_metadata: &'ll DIScope,
2082 file: &syntax_pos::SourceFile,
2083 defining_crate: CrateNum,
2084 ) -> &'ll DILexicalBlock {
2085 let file_metadata = file_metadata(cx, &file.name, defining_crate);
2087 llvm::LLVMRustDIBuilderCreateLexicalBlockFile(