]> git.proxmox.com Git - rustc.git/blob - src/librustc_codegen_llvm/debuginfo/metadata.rs
New upstream version 1.41.1+dfsg1
[rustc.git] / src / librustc_codegen_llvm / debuginfo / metadata.rs
1 use self::RecursiveTypeDescription::*;
2 use self::MemberDescriptionFactory::*;
3 use self::EnumDiscriminantInfo::*;
4
5 use super::utils::{debug_context, DIB, span_start,
6 get_namespace_for_item, create_DIArray, is_node_local_to_unit};
7 use super::namespace::mangled_name_of_instance;
8 use super::type_names::compute_debuginfo_type_name;
9 use super::CrateDebugContext;
10
11 use crate::abi;
12 use crate::common::CodegenCx;
13 use crate::llvm;
14 use crate::llvm::debuginfo::{DIArray, DIType, DIFile, DIScope, DIDescriptor,
15 DICompositeType, DILexicalBlock, DIFlags, DebugEmissionKind};
16 use crate::llvm_util;
17 use crate::value::Value;
18
19 use rustc_codegen_ssa::traits::*;
20 use rustc_index::vec::{Idx, IndexVec};
21 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
22 use rustc::hir::CodegenFnAttrFlags;
23 use rustc::hir::def::CtorKind;
24 use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
25 use rustc::ich::NodeIdHashingMode;
26 use rustc::mir::{self, Field, GeneratorLayout};
27 use rustc::mir::interpret::truncate;
28 use rustc_data_structures::fingerprint::Fingerprint;
29 use rustc::ty::Instance;
30 use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
31 use rustc::ty::layout::{self, Align, Integer, IntegerExt, LayoutOf,
32 PrimitiveExt, Size, TyLayout, VariantIdx};
33 use rustc::ty::subst::{GenericArgKind, SubstsRef};
34 use rustc::session::config::{self, DebugInfo};
35 use rustc::util::nodemap::FxHashMap;
36 use rustc_fs_util::path_to_c_string;
37 use rustc_data_structures::small_c_str::SmallCStr;
38 use rustc_data_structures::const_cstr;
39 use rustc_target::abi::HasDataLayout;
40 use syntax::ast;
41 use syntax::symbol::{Interner, Symbol};
42 use syntax_pos::{self, Span, FileName};
43 use rustc::{bug, span_bug};
44 use log::debug;
45
46 use libc::{c_uint, c_longlong};
47 use std::collections::hash_map::Entry;
48 use std::ffi::CString;
49 use std::fmt::{self, Write};
50 use std::hash::{Hash, Hasher};
51 use std::iter;
52 use std::ptr;
53 use std::path::{Path, PathBuf};
54
55 impl PartialEq for llvm::Metadata {
56 fn eq(&self, other: &Self) -> bool {
57 ptr::eq(self, other)
58 }
59 }
60
61 impl Eq for llvm::Metadata {}
62
63 impl Hash for llvm::Metadata {
64 fn hash<H: Hasher>(&self, hasher: &mut H) {
65 (self as *const Self).hash(hasher);
66 }
67 }
68
69 impl fmt::Debug for llvm::Metadata {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 (self as *const Self).fmt(f)
72 }
73 }
74
75 // From DWARF 5.
76 // See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1.
77 const DW_LANG_RUST: c_uint = 0x1c;
78 #[allow(non_upper_case_globals)]
79 const DW_ATE_boolean: c_uint = 0x02;
80 #[allow(non_upper_case_globals)]
81 const DW_ATE_float: c_uint = 0x04;
82 #[allow(non_upper_case_globals)]
83 const DW_ATE_signed: c_uint = 0x05;
84 #[allow(non_upper_case_globals)]
85 const DW_ATE_unsigned: c_uint = 0x07;
86 #[allow(non_upper_case_globals)]
87 const DW_ATE_unsigned_char: c_uint = 0x08;
88
89 pub const UNKNOWN_LINE_NUMBER: c_uint = 0;
90 pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
91
92 pub const NO_SCOPE_METADATA: Option<&DIScope> = None;
93
94 #[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
95 pub struct UniqueTypeId(ast::Name);
96
97 /// The `TypeMap` is where the `CrateDebugContext` holds the type metadata nodes
98 /// created so far. The metadata nodes are indexed by `UniqueTypeId`, and, for
99 /// faster lookup, also by `Ty`. The `TypeMap` is responsible for creating
100 /// `UniqueTypeId`s.
101 #[derive(Default)]
102 pub struct TypeMap<'ll, 'tcx> {
103 /// The `UniqueTypeId`s created so far.
104 unique_id_interner: Interner,
105 /// A map from `UniqueTypeId` to debuginfo metadata for that type. This is a 1:1 mapping.
106 unique_id_to_metadata: FxHashMap<UniqueTypeId, &'ll DIType>,
107 /// A map from types to debuginfo metadata. This is an N:1 mapping.
108 type_to_metadata: FxHashMap<Ty<'tcx>, &'ll DIType>,
109 /// A map from types to `UniqueTypeId`. This is an N:1 mapping.
110 type_to_unique_id: FxHashMap<Ty<'tcx>, UniqueTypeId>
111 }
112
113 impl TypeMap<'ll, 'tcx> {
114 /// Adds a Ty to metadata mapping to the TypeMap. The method will fail if
115 /// the mapping already exists.
116 fn register_type_with_metadata(
117 &mut self,
118 type_: Ty<'tcx>,
119 metadata: &'ll DIType,
120 ) {
121 if self.type_to_metadata.insert(type_, metadata).is_some() {
122 bug!("type metadata for `Ty` '{}' is already in the `TypeMap`!", type_);
123 }
124 }
125
126 /// Removes a `Ty`-to-metadata mapping.
127 /// This is useful when computing the metadata for a potentially
128 /// recursive type (e.g., a function pointer of the form:
129 ///
130 /// fn foo() -> impl Copy { foo }
131 ///
132 /// This kind of type cannot be properly represented
133 /// via LLVM debuginfo. As a workaround,
134 /// we register a temporary Ty to metadata mapping
135 /// for the function before we compute its actual metadata.
136 /// If the metadata computation ends up recursing back to the
137 /// original function, it will use the temporary mapping
138 /// for the inner self-reference, preventing us from
139 /// recursing forever.
140 ///
141 /// This function is used to remove the temporary metadata
142 /// mapping after we've computed the actual metadata.
143 fn remove_type(
144 &mut self,
145 type_: Ty<'tcx>,
146 ) {
147 if self.type_to_metadata.remove(type_).is_none() {
148 bug!("type metadata `Ty` '{}' is not in the `TypeMap`!", type_);
149 }
150 }
151
152 /// Adds a `UniqueTypeId` to metadata mapping to the `TypeMap`. The method will
153 /// fail if the mapping already exists.
154 fn register_unique_id_with_metadata(
155 &mut self,
156 unique_type_id: UniqueTypeId,
157 metadata: &'ll DIType,
158 ) {
159 if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
160 bug!("type metadata for unique ID '{}' is already in the `TypeMap`!",
161 self.get_unique_type_id_as_string(unique_type_id));
162 }
163 }
164
165 fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<&'ll DIType> {
166 self.type_to_metadata.get(&type_).cloned()
167 }
168
169 fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<&'ll DIType> {
170 self.unique_id_to_metadata.get(&unique_type_id).cloned()
171 }
172
173 /// Gets the string representation of a `UniqueTypeId`. This method will fail if
174 /// the ID is unknown.
175 fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> &str {
176 let UniqueTypeId(interner_key) = unique_type_id;
177 self.unique_id_interner.get(interner_key)
178 }
179
180 /// Gets the `UniqueTypeId` for the given type. If the `UniqueTypeId` for the given
181 /// type has been requested before, this is just a table lookup. Otherwise, an
182 /// ID will be generated and stored for later lookup.
183 fn get_unique_type_id_of_type<'a>(&mut self, cx: &CodegenCx<'a, 'tcx>,
184 type_: Ty<'tcx>) -> UniqueTypeId {
185 // Let's see if we already have something in the cache.
186 if let Some(unique_type_id) = self.type_to_unique_id.get(&type_).cloned() {
187 return unique_type_id;
188 }
189 // If not, generate one.
190
191 // The hasher we are using to generate the UniqueTypeId. We want
192 // something that provides more than the 64 bits of the DefaultHasher.
193 let mut hasher = StableHasher::new();
194 let mut hcx = cx.tcx.create_stable_hashing_context();
195 let type_ = cx.tcx.erase_regions(&type_);
196 hcx.while_hashing_spans(false, |hcx| {
197 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
198 type_.hash_stable(hcx, &mut hasher);
199 });
200 });
201 let unique_type_id = hasher.finish::<Fingerprint>().to_hex();
202
203 let key = self.unique_id_interner.intern(&unique_type_id);
204 self.type_to_unique_id.insert(type_, UniqueTypeId(key));
205
206 return UniqueTypeId(key);
207 }
208
209 /// Gets the `UniqueTypeId` for an enum variant. Enum variants are not really
210 /// types of their own, so they need special handling. We still need a
211 /// `UniqueTypeId` for them, since to debuginfo they *are* real types.
212 fn get_unique_type_id_of_enum_variant<'a>(&mut self,
213 cx: &CodegenCx<'a, 'tcx>,
214 enum_type: Ty<'tcx>,
215 variant_name: &str)
216 -> UniqueTypeId {
217 let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
218 let enum_variant_type_id = format!("{}::{}",
219 self.get_unique_type_id_as_string(enum_type_id),
220 variant_name);
221 let interner_key = self.unique_id_interner.intern(&enum_variant_type_id);
222 UniqueTypeId(interner_key)
223 }
224
225 /// Gets the unique type ID string for an enum variant part.
226 /// Variant parts are not types and shouldn't really have their own ID,
227 /// but it makes `set_members_of_composite_type()` simpler.
228 fn get_unique_type_id_str_of_enum_variant_part(&mut self, enum_type_id: UniqueTypeId) -> &str {
229 let variant_part_type_id = format!("{}_variant_part",
230 self.get_unique_type_id_as_string(enum_type_id));
231 let interner_key = self.unique_id_interner.intern(&variant_part_type_id);
232 self.unique_id_interner.get(interner_key)
233 }
234 }
235
236 /// A description of some recursive type. It can either be already finished (as
237 /// with `FinalMetadata`) or it is not yet finished, but contains all information
238 /// needed to generate the missing parts of the description. See the
239 /// documentation section on Recursive Types at the top of this file for more
240 /// information.
241 enum RecursiveTypeDescription<'ll, 'tcx> {
242 UnfinishedMetadata {
243 unfinished_type: Ty<'tcx>,
244 unique_type_id: UniqueTypeId,
245 metadata_stub: &'ll DICompositeType,
246 member_holding_stub: &'ll DICompositeType,
247 member_description_factory: MemberDescriptionFactory<'ll, 'tcx>,
248 },
249 FinalMetadata(&'ll DICompositeType)
250 }
251
252 fn create_and_register_recursive_type_forward_declaration(
253 cx: &CodegenCx<'ll, 'tcx>,
254 unfinished_type: Ty<'tcx>,
255 unique_type_id: UniqueTypeId,
256 metadata_stub: &'ll DICompositeType,
257 member_holding_stub: &'ll DICompositeType,
258 member_description_factory: MemberDescriptionFactory<'ll, 'tcx>,
259 ) -> RecursiveTypeDescription<'ll, 'tcx> {
260
261 // Insert the stub into the `TypeMap` in order to allow for recursive references.
262 let mut type_map = debug_context(cx).type_map.borrow_mut();
263 type_map.register_unique_id_with_metadata(unique_type_id, metadata_stub);
264 type_map.register_type_with_metadata(unfinished_type, metadata_stub);
265
266 UnfinishedMetadata {
267 unfinished_type,
268 unique_type_id,
269 metadata_stub,
270 member_holding_stub,
271 member_description_factory,
272 }
273 }
274
275 impl RecursiveTypeDescription<'ll, 'tcx> {
276 /// Finishes up the description of the type in question (mostly by providing
277 /// descriptions of the fields of the given type) and returns the final type
278 /// metadata.
279 fn finalize(&self, cx: &CodegenCx<'ll, 'tcx>) -> MetadataCreationResult<'ll> {
280 match *self {
281 FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
282 UnfinishedMetadata {
283 unfinished_type,
284 unique_type_id,
285 metadata_stub,
286 member_holding_stub,
287 ref member_description_factory,
288 } => {
289 // Make sure that we have a forward declaration of the type in
290 // the TypeMap so that recursive references are possible. This
291 // will always be the case if the RecursiveTypeDescription has
292 // been properly created through the
293 // `create_and_register_recursive_type_forward_declaration()`
294 // function.
295 {
296 let type_map = debug_context(cx).type_map.borrow();
297 if type_map.find_metadata_for_unique_id(unique_type_id).is_none() ||
298 type_map.find_metadata_for_type(unfinished_type).is_none() {
299 bug!("Forward declaration of potentially recursive type \
300 '{:?}' was not found in TypeMap!",
301 unfinished_type);
302 }
303 }
304
305 // ... then create the member descriptions ...
306 let member_descriptions =
307 member_description_factory.create_member_descriptions(cx);
308
309 // ... and attach them to the stub to complete it.
310 set_members_of_composite_type(cx,
311 unfinished_type,
312 member_holding_stub,
313 member_descriptions);
314 return MetadataCreationResult::new(metadata_stub, true);
315 }
316 }
317 }
318 }
319
320 /// Returns from the enclosing function if the type metadata with the given
321 /// unique ID can be found in the type map.
322 macro_rules! return_if_metadata_created_in_meantime {
323 ($cx: expr, $unique_type_id: expr) => (
324 if let Some(metadata) = debug_context($cx).type_map
325 .borrow()
326 .find_metadata_for_unique_id($unique_type_id)
327 {
328 return MetadataCreationResult::new(metadata, true);
329 }
330 )
331 }
332
333 fn fixed_vec_metadata(
334 cx: &CodegenCx<'ll, 'tcx>,
335 unique_type_id: UniqueTypeId,
336 array_or_slice_type: Ty<'tcx>,
337 element_type: Ty<'tcx>,
338 span: Span,
339 ) -> MetadataCreationResult<'ll> {
340 let element_type_metadata = type_metadata(cx, element_type, span);
341
342 return_if_metadata_created_in_meantime!(cx, unique_type_id);
343
344 let (size, align) = cx.size_and_align_of(array_or_slice_type);
345
346 let upper_bound = match array_or_slice_type.kind {
347 ty::Array(_, len) => len.eval_usize(cx.tcx, ty::ParamEnv::reveal_all()) as c_longlong,
348 _ => -1
349 };
350
351 let subrange = unsafe {
352 Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound))
353 };
354
355 let subscripts = create_DIArray(DIB(cx), &[subrange]);
356 let metadata = unsafe {
357 llvm::LLVMRustDIBuilderCreateArrayType(
358 DIB(cx),
359 size.bits(),
360 align.bits() as u32,
361 element_type_metadata,
362 subscripts)
363 };
364
365 return MetadataCreationResult::new(metadata, false);
366 }
367
368 fn vec_slice_metadata(
369 cx: &CodegenCx<'ll, 'tcx>,
370 slice_ptr_type: Ty<'tcx>,
371 element_type: Ty<'tcx>,
372 unique_type_id: UniqueTypeId,
373 span: Span,
374 ) -> MetadataCreationResult<'ll> {
375 let data_ptr_type = cx.tcx.mk_imm_ptr(element_type);
376
377 let data_ptr_metadata = type_metadata(cx, data_ptr_type, span);
378
379 return_if_metadata_created_in_meantime!(cx, unique_type_id);
380
381 let slice_type_name = compute_debuginfo_type_name(cx.tcx, slice_ptr_type, true);
382
383 let (pointer_size, pointer_align) = cx.size_and_align_of(data_ptr_type);
384 let (usize_size, usize_align) = cx.size_and_align_of(cx.tcx.types.usize);
385
386 let member_descriptions = vec![
387 MemberDescription {
388 name: "data_ptr".to_owned(),
389 type_metadata: data_ptr_metadata,
390 offset: Size::ZERO,
391 size: pointer_size,
392 align: pointer_align,
393 flags: DIFlags::FlagZero,
394 discriminant: None,
395 },
396 MemberDescription {
397 name: "length".to_owned(),
398 type_metadata: type_metadata(cx, cx.tcx.types.usize, span),
399 offset: pointer_size,
400 size: usize_size,
401 align: usize_align,
402 flags: DIFlags::FlagZero,
403 discriminant: None,
404 },
405 ];
406
407 let file_metadata = unknown_file_metadata(cx);
408
409 let metadata = composite_type_metadata(cx,
410 slice_ptr_type,
411 &slice_type_name[..],
412 unique_type_id,
413 member_descriptions,
414 NO_SCOPE_METADATA,
415 file_metadata,
416 span);
417 MetadataCreationResult::new(metadata, false)
418 }
419
420 fn subroutine_type_metadata(
421 cx: &CodegenCx<'ll, 'tcx>,
422 unique_type_id: UniqueTypeId,
423 signature: ty::PolyFnSig<'tcx>,
424 span: Span,
425 ) -> MetadataCreationResult<'ll> {
426 let signature = cx.tcx.normalize_erasing_late_bound_regions(
427 ty::ParamEnv::reveal_all(),
428 &signature,
429 );
430
431 let signature_metadata: Vec<_> = iter::once(
432 // return type
433 match signature.output().kind {
434 ty::Tuple(ref tys) if tys.is_empty() => None,
435 _ => Some(type_metadata(cx, signature.output(), span))
436 }
437 ).chain(
438 // regular arguments
439 signature.inputs().iter().map(|argument_type| {
440 Some(type_metadata(cx, argument_type, span))
441 })
442 ).collect();
443
444 return_if_metadata_created_in_meantime!(cx, unique_type_id);
445
446 return MetadataCreationResult::new(
447 unsafe {
448 llvm::LLVMRustDIBuilderCreateSubroutineType(
449 DIB(cx),
450 unknown_file_metadata(cx),
451 create_DIArray(DIB(cx), &signature_metadata[..]))
452 },
453 false);
454 }
455
456 // FIXME(1563): This is all a bit of a hack because 'trait pointer' is an ill-
457 // defined concept. For the case of an actual trait pointer (i.e., `Box<Trait>`,
458 // `&Trait`), `trait_object_type` should be the whole thing (e.g, `Box<Trait>`) and
459 // `trait_type` should be the actual trait (e.g., `Trait`). Where the trait is part
460 // of a DST struct, there is no `trait_object_type` and the results of this
461 // function will be a little bit weird.
462 fn trait_pointer_metadata(
463 cx: &CodegenCx<'ll, 'tcx>,
464 trait_type: Ty<'tcx>,
465 trait_object_type: Option<Ty<'tcx>>,
466 unique_type_id: UniqueTypeId,
467 ) -> &'ll DIType {
468 // The implementation provided here is a stub. It makes sure that the trait
469 // type is assigned the correct name, size, namespace, and source location.
470 // However, it does not describe the trait's methods.
471
472 let containing_scope = match trait_type.kind {
473 ty::Dynamic(ref data, ..) =>
474 data.principal_def_id().map(|did| get_namespace_for_item(cx, did)),
475 _ => {
476 bug!("debuginfo: unexpected trait-object type in \
477 trait_pointer_metadata(): {:?}",
478 trait_type);
479 }
480 };
481
482 let trait_object_type = trait_object_type.unwrap_or(trait_type);
483 let trait_type_name =
484 compute_debuginfo_type_name(cx.tcx, trait_object_type, false);
485
486 let file_metadata = unknown_file_metadata(cx);
487
488 let layout = cx.layout_of(cx.tcx.mk_mut_ptr(trait_type));
489
490 assert_eq!(abi::FAT_PTR_ADDR, 0);
491 assert_eq!(abi::FAT_PTR_EXTRA, 1);
492
493 let data_ptr_field = layout.field(cx, 0);
494 let vtable_field = layout.field(cx, 1);
495 let member_descriptions = vec![
496 MemberDescription {
497 name: "pointer".to_owned(),
498 type_metadata: type_metadata(cx,
499 cx.tcx.mk_mut_ptr(cx.tcx.types.u8),
500 syntax_pos::DUMMY_SP),
501 offset: layout.fields.offset(0),
502 size: data_ptr_field.size,
503 align: data_ptr_field.align.abi,
504 flags: DIFlags::FlagArtificial,
505 discriminant: None,
506 },
507 MemberDescription {
508 name: "vtable".to_owned(),
509 type_metadata: type_metadata(cx, vtable_field.ty, syntax_pos::DUMMY_SP),
510 offset: layout.fields.offset(1),
511 size: vtable_field.size,
512 align: vtable_field.align.abi,
513 flags: DIFlags::FlagArtificial,
514 discriminant: None,
515 },
516 ];
517
518 composite_type_metadata(cx,
519 trait_object_type,
520 &trait_type_name[..],
521 unique_type_id,
522 member_descriptions,
523 containing_scope,
524 file_metadata,
525 syntax_pos::DUMMY_SP)
526 }
527
528 pub fn type_metadata(
529 cx: &CodegenCx<'ll, 'tcx>,
530 t: Ty<'tcx>,
531 usage_site_span: Span,
532 ) -> &'ll DIType {
533 // Get the unique type ID of this type.
534 let unique_type_id = {
535 let mut type_map = debug_context(cx).type_map.borrow_mut();
536 // First, try to find the type in `TypeMap`. If we have seen it before, we
537 // can exit early here.
538 match type_map.find_metadata_for_type(t) {
539 Some(metadata) => {
540 return metadata;
541 },
542 None => {
543 // The Ty is not in the `TypeMap` but maybe we have already seen
544 // an equivalent type (e.g., only differing in region arguments).
545 // In order to find out, generate the unique type ID and look
546 // that up.
547 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
548 match type_map.find_metadata_for_unique_id(unique_type_id) {
549 Some(metadata) => {
550 // There is already an equivalent type in the TypeMap.
551 // Register this Ty as an alias in the cache and
552 // return the cached metadata.
553 type_map.register_type_with_metadata(t, metadata);
554 return metadata;
555 },
556 None => {
557 // There really is no type metadata for this type, so
558 // proceed by creating it.
559 unique_type_id
560 }
561 }
562 }
563 }
564 };
565
566 debug!("type_metadata: {:?}", t);
567
568 let ptr_metadata = |ty: Ty<'tcx>| {
569 match ty.kind {
570 ty::Slice(typ) => {
571 Ok(vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span))
572 }
573 ty::Str => {
574 Ok(vec_slice_metadata(cx, t, cx.tcx.types.u8, unique_type_id, usage_site_span))
575 }
576 ty::Dynamic(..) => {
577 Ok(MetadataCreationResult::new(
578 trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
579 false))
580 }
581 _ => {
582 let pointee_metadata = type_metadata(cx, ty, usage_site_span);
583
584 if let Some(metadata) = debug_context(cx).type_map
585 .borrow()
586 .find_metadata_for_unique_id(unique_type_id)
587 {
588 return Err(metadata);
589 }
590
591 Ok(MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
592 false))
593 }
594 }
595 };
596
597 let MetadataCreationResult { metadata, already_stored_in_typemap } = match t.kind {
598 ty::Never |
599 ty::Bool |
600 ty::Char |
601 ty::Int(_) |
602 ty::Uint(_) |
603 ty::Float(_) => {
604 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
605 }
606 ty::Tuple(ref elements) if elements.is_empty() => {
607 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
608 }
609 ty::Array(typ, _) |
610 ty::Slice(typ) => {
611 fixed_vec_metadata(cx, unique_type_id, t, typ, usage_site_span)
612 }
613 ty::Str => {
614 fixed_vec_metadata(cx, unique_type_id, t, cx.tcx.types.i8, usage_site_span)
615 }
616 ty::Dynamic(..) => {
617 MetadataCreationResult::new(
618 trait_pointer_metadata(cx, t, None, unique_type_id),
619 false)
620 }
621 ty::Foreign(..) => {
622 MetadataCreationResult::new(
623 foreign_type_metadata(cx, t, unique_type_id),
624 false)
625 }
626 ty::RawPtr(ty::TypeAndMut{ty, ..}) |
627 ty::Ref(_, ty, _) => {
628 match ptr_metadata(ty) {
629 Ok(res) => res,
630 Err(metadata) => return metadata,
631 }
632 }
633 ty::Adt(def, _) if def.is_box() => {
634 match ptr_metadata(t.boxed_ty()) {
635 Ok(res) => res,
636 Err(metadata) => return metadata,
637 }
638 }
639 ty::FnDef(..) | ty::FnPtr(_) => {
640
641 if let Some(metadata) = debug_context(cx).type_map
642 .borrow()
643 .find_metadata_for_unique_id(unique_type_id)
644 {
645 return metadata;
646 }
647
648 // It's possible to create a self-referential
649 // type in Rust by using 'impl trait':
650 //
651 // fn foo() -> impl Copy { foo }
652 //
653 // See `TypeMap::remove_type` for more detals
654 // about the workaround.
655
656 let temp_type = {
657 unsafe {
658 // The choice of type here is pretty arbitrary -
659 // anything reading the debuginfo for a recursive
660 // type is going to see *somthing* weird - the only
661 // question is what exactly it will see.
662 let (size, align) = cx.size_and_align_of(t);
663 llvm::LLVMRustDIBuilderCreateBasicType(
664 DIB(cx),
665 SmallCStr::new("<recur_type>").as_ptr(),
666 size.bits(),
667 align.bits() as u32,
668 DW_ATE_unsigned)
669 }
670 };
671
672 let type_map = &debug_context(cx).type_map;
673 type_map.borrow_mut().register_type_with_metadata(t, temp_type);
674
675 let fn_metadata = subroutine_type_metadata(cx,
676 unique_type_id,
677 t.fn_sig(cx.tcx),
678 usage_site_span).metadata;
679
680 type_map.borrow_mut().remove_type(t);
681
682
683 // This is actually a function pointer, so wrap it in pointer DI.
684 MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false)
685
686 }
687 ty::Closure(def_id, substs) => {
688 let upvar_tys : Vec<_> = substs.as_closure().upvar_tys(def_id, cx.tcx).collect();
689 let containing_scope = get_namespace_for_item(cx, def_id);
690 prepare_tuple_metadata(cx,
691 t,
692 &upvar_tys,
693 unique_type_id,
694 usage_site_span,
695 Some(containing_scope)).finalize(cx)
696 }
697 ty::Generator(def_id, substs, _) => {
698 let upvar_tys : Vec<_> = substs
699 .as_generator().prefix_tys(def_id, cx.tcx).map(|t| {
700 cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t)
701 }).collect();
702 prepare_enum_metadata(cx,
703 t,
704 def_id,
705 unique_type_id,
706 usage_site_span,
707 upvar_tys).finalize(cx)
708 }
709 ty::Adt(def, ..) => match def.adt_kind() {
710 AdtKind::Struct => {
711 prepare_struct_metadata(cx,
712 t,
713 unique_type_id,
714 usage_site_span).finalize(cx)
715 }
716 AdtKind::Union => {
717 prepare_union_metadata(cx,
718 t,
719 unique_type_id,
720 usage_site_span).finalize(cx)
721 }
722 AdtKind::Enum => {
723 prepare_enum_metadata(cx,
724 t,
725 def.did,
726 unique_type_id,
727 usage_site_span,
728 vec![]).finalize(cx)
729 }
730 },
731 ty::Tuple(ref elements) => {
732 let tys: Vec<_> = elements.iter().map(|k| k.expect_ty()).collect();
733 prepare_tuple_metadata(cx,
734 t,
735 &tys,
736 unique_type_id,
737 usage_site_span,
738 NO_SCOPE_METADATA).finalize(cx)
739 }
740 _ => {
741 bug!("debuginfo: unexpected type in type_metadata: {:?}", t)
742 }
743 };
744
745 {
746 let mut type_map = debug_context(cx).type_map.borrow_mut();
747
748 if already_stored_in_typemap {
749 // Also make sure that we already have a `TypeMap` entry for the unique type ID.
750 let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
751 Some(metadata) => metadata,
752 None => {
753 span_bug!(usage_site_span,
754 "expected type metadata for unique \
755 type ID '{}' to already be in \
756 the `debuginfo::TypeMap` but it \
757 was not. (Ty = {})",
758 type_map.get_unique_type_id_as_string(unique_type_id),
759 t);
760 }
761 };
762
763 match type_map.find_metadata_for_type(t) {
764 Some(metadata) => {
765 if metadata != metadata_for_uid {
766 span_bug!(usage_site_span,
767 "mismatch between `Ty` and \
768 `UniqueTypeId` maps in \
769 `debuginfo::TypeMap`. \
770 UniqueTypeId={}, Ty={}",
771 type_map.get_unique_type_id_as_string(unique_type_id),
772 t);
773 }
774 }
775 None => {
776 type_map.register_type_with_metadata(t, metadata);
777 }
778 }
779 } else {
780 type_map.register_type_with_metadata(t, metadata);
781 type_map.register_unique_id_with_metadata(unique_type_id, metadata);
782 }
783 }
784
785 metadata
786 }
787
788 pub fn file_metadata(cx: &CodegenCx<'ll, '_>,
789 file_name: &FileName,
790 defining_crate: CrateNum) -> &'ll DIFile {
791 debug!("file_metadata: file_name: {}, defining_crate: {}",
792 file_name,
793 defining_crate);
794
795 let file_name = Some(file_name.to_string());
796 let directory = if defining_crate == LOCAL_CRATE {
797 Some(cx.sess().working_dir.0.to_string_lossy().to_string())
798 } else {
799 // If the path comes from an upstream crate we assume it has been made
800 // independent of the compiler's working directory one way or another.
801 None
802 };
803 file_metadata_raw(cx, file_name, directory)
804 }
805
806 pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
807 file_metadata_raw(cx, None, None)
808 }
809
810 fn file_metadata_raw(cx: &CodegenCx<'ll, '_>,
811 file_name: Option<String>,
812 directory: Option<String>)
813 -> &'ll DIFile {
814 let key = (file_name, directory);
815
816 match debug_context(cx).created_files.borrow_mut().entry(key) {
817 Entry::Occupied(o) => return o.get(),
818 Entry::Vacant(v) => {
819 let (file_name, directory) = v.key();
820 debug!("file_metadata: file_name: {:?}, directory: {:?}", file_name, directory);
821
822 let file_name = SmallCStr::new(
823 if let Some(file_name) = file_name { &file_name } else { "<unknown>" });
824 let directory = SmallCStr::new(
825 if let Some(directory) = directory { &directory } else { "" });
826
827 let file_metadata = unsafe {
828 llvm::LLVMRustDIBuilderCreateFile(DIB(cx),
829 file_name.as_ptr(),
830 directory.as_ptr())
831 };
832
833 v.insert(file_metadata);
834 file_metadata
835 }
836 }
837 }
838
839 fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
840 debug!("basic_type_metadata: {:?}", t);
841
842 let (name, encoding) = match t.kind {
843 ty::Never => ("!", DW_ATE_unsigned),
844 ty::Tuple(ref elements) if elements.is_empty() =>
845 ("()", DW_ATE_unsigned),
846 ty::Bool => ("bool", DW_ATE_boolean),
847 ty::Char => ("char", DW_ATE_unsigned_char),
848 ty::Int(int_ty) => {
849 (int_ty.name_str(), DW_ATE_signed)
850 },
851 ty::Uint(uint_ty) => {
852 (uint_ty.name_str(), DW_ATE_unsigned)
853 },
854 ty::Float(float_ty) => {
855 (float_ty.name_str(), DW_ATE_float)
856 },
857 _ => bug!("debuginfo::basic_type_metadata - `t` is invalid type")
858 };
859
860 let (size, align) = cx.size_and_align_of(t);
861 let name = SmallCStr::new(name);
862 let ty_metadata = unsafe {
863 llvm::LLVMRustDIBuilderCreateBasicType(
864 DIB(cx),
865 name.as_ptr(),
866 size.bits(),
867 align.bits() as u32,
868 encoding)
869 };
870
871 return ty_metadata;
872 }
873
874 fn foreign_type_metadata(
875 cx: &CodegenCx<'ll, 'tcx>,
876 t: Ty<'tcx>,
877 unique_type_id: UniqueTypeId,
878 ) -> &'ll DIType {
879 debug!("foreign_type_metadata: {:?}", t);
880
881 let name = compute_debuginfo_type_name(cx.tcx, t, false);
882 create_struct_stub(cx, t, &name, unique_type_id, NO_SCOPE_METADATA)
883 }
884
885 fn pointer_type_metadata(
886 cx: &CodegenCx<'ll, 'tcx>,
887 pointer_type: Ty<'tcx>,
888 pointee_type_metadata: &'ll DIType,
889 ) -> &'ll DIType {
890 let (pointer_size, pointer_align) = cx.size_and_align_of(pointer_type);
891 let name = compute_debuginfo_type_name(cx.tcx, pointer_type, false);
892 let name = SmallCStr::new(&name);
893 unsafe {
894 llvm::LLVMRustDIBuilderCreatePointerType(
895 DIB(cx),
896 pointee_type_metadata,
897 pointer_size.bits(),
898 pointer_align.bits() as u32,
899 name.as_ptr())
900 }
901 }
902
903 pub fn compile_unit_metadata(
904 tcx: TyCtxt<'_>,
905 codegen_unit_name: &str,
906 debug_context: &CrateDebugContext<'ll, '_>,
907 ) -> &'ll DIDescriptor {
908 let mut name_in_debuginfo = match tcx.sess.local_crate_source_file {
909 Some(ref path) => path.clone(),
910 None => PathBuf::from(&*tcx.crate_name(LOCAL_CRATE).as_str()),
911 };
912
913 // The OSX linker has an idiosyncrasy where it will ignore some debuginfo
914 // if multiple object files with the same `DW_AT_name` are linked together.
915 // As a workaround we generate unique names for each object file. Those do
916 // not correspond to an actual source file but that should be harmless.
917 if tcx.sess.target.target.options.is_like_osx {
918 name_in_debuginfo.push("@");
919 name_in_debuginfo.push(codegen_unit_name);
920 }
921
922 debug!("compile_unit_metadata: {:?}", name_in_debuginfo);
923 let rustc_producer = format!(
924 "rustc version {}",
925 option_env!("CFG_VERSION").expect("CFG_VERSION"),
926 );
927 // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
928 let producer = format!("clang LLVM ({})", rustc_producer);
929
930 let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
931 let name_in_debuginfo = SmallCStr::new(&name_in_debuginfo);
932 let work_dir = SmallCStr::new(&tcx.sess.working_dir.0.to_string_lossy());
933 let producer = CString::new(producer).unwrap();
934 let flags = "\0";
935 let split_name = "\0";
936
937 // FIXME(#60020):
938 //
939 // This should actually be
940 //
941 // let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
942 //
943 // That is, we should set LLVM's emission kind to `LineTablesOnly` if
944 // we are compiling with "limited" debuginfo. However, some of the
945 // existing tools relied on slightly more debuginfo being generated than
946 // would be the case with `LineTablesOnly`, and we did not want to break
947 // these tools in a "drive-by fix", without a good idea or plan about
948 // what limited debuginfo should exactly look like. So for now we keep
949 // the emission kind as `FullDebug`.
950 //
951 // See https://github.com/rust-lang/rust/issues/60020 for details.
952 let kind = DebugEmissionKind::FullDebug;
953 assert!(tcx.sess.opts.debuginfo != DebugInfo::None);
954
955 unsafe {
956 let file_metadata = llvm::LLVMRustDIBuilderCreateFile(
957 debug_context.builder, name_in_debuginfo.as_ptr(), work_dir.as_ptr());
958
959 let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
960 debug_context.builder,
961 DW_LANG_RUST,
962 file_metadata,
963 producer.as_ptr(),
964 tcx.sess.opts.optimize != config::OptLevel::No,
965 flags.as_ptr().cast(),
966 0,
967 split_name.as_ptr().cast(),
968 kind);
969
970 if tcx.sess.opts.debugging_opts.profile {
971 let cu_desc_metadata = llvm::LLVMRustMetadataAsValue(debug_context.llcontext,
972 unit_metadata);
973
974 let gcov_cu_info = [
975 path_to_mdstring(debug_context.llcontext,
976 &tcx.output_filenames(LOCAL_CRATE).with_extension("gcno")),
977 path_to_mdstring(debug_context.llcontext,
978 &tcx.output_filenames(LOCAL_CRATE).with_extension("gcda")),
979 cu_desc_metadata,
980 ];
981 let gcov_metadata = llvm::LLVMMDNodeInContext(debug_context.llcontext,
982 gcov_cu_info.as_ptr(),
983 gcov_cu_info.len() as c_uint);
984
985 let llvm_gcov_ident = const_cstr!("llvm.gcov");
986 llvm::LLVMAddNamedMetadataOperand(debug_context.llmod,
987 llvm_gcov_ident.as_ptr(),
988 gcov_metadata);
989 }
990
991 // Insert `llvm.ident` metadata on the wasm32 targets since that will
992 // get hooked up to the "producer" sections `processed-by` information.
993 if tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
994 let name_metadata = llvm::LLVMMDStringInContext(
995 debug_context.llcontext,
996 rustc_producer.as_ptr().cast(),
997 rustc_producer.as_bytes().len() as c_uint,
998 );
999 llvm::LLVMAddNamedMetadataOperand(
1000 debug_context.llmod,
1001 const_cstr!("llvm.ident").as_ptr(),
1002 llvm::LLVMMDNodeInContext(debug_context.llcontext, &name_metadata, 1),
1003 );
1004 }
1005
1006 return unit_metadata;
1007 };
1008
1009 fn path_to_mdstring(llcx: &'ll llvm::Context, path: &Path) -> &'ll Value {
1010 let path_str = path_to_c_string(path);
1011 unsafe {
1012 llvm::LLVMMDStringInContext(llcx,
1013 path_str.as_ptr(),
1014 path_str.as_bytes().len() as c_uint)
1015 }
1016 }
1017 }
1018
1019 struct MetadataCreationResult<'ll> {
1020 metadata: &'ll DIType,
1021 already_stored_in_typemap: bool
1022 }
1023
1024 impl MetadataCreationResult<'ll> {
1025 fn new(metadata: &'ll DIType, already_stored_in_typemap: bool) -> Self {
1026 MetadataCreationResult {
1027 metadata,
1028 already_stored_in_typemap,
1029 }
1030 }
1031 }
1032
1033 /// Description of a type member, which can either be a regular field (as in
1034 /// structs or tuples) or an enum variant.
1035 #[derive(Debug)]
1036 struct MemberDescription<'ll> {
1037 name: String,
1038 type_metadata: &'ll DIType,
1039 offset: Size,
1040 size: Size,
1041 align: Align,
1042 flags: DIFlags,
1043 discriminant: Option<u64>,
1044 }
1045
1046 impl<'ll> MemberDescription<'ll> {
1047 fn into_metadata(self,
1048 cx: &CodegenCx<'ll, '_>,
1049 composite_type_metadata: &'ll DIScope) -> &'ll DIType {
1050 let member_name = CString::new(self.name).unwrap();
1051 unsafe {
1052 llvm::LLVMRustDIBuilderCreateVariantMemberType(
1053 DIB(cx),
1054 composite_type_metadata,
1055 member_name.as_ptr(),
1056 unknown_file_metadata(cx),
1057 UNKNOWN_LINE_NUMBER,
1058 self.size.bits(),
1059 self.align.bits() as u32,
1060 self.offset.bits(),
1061 match self.discriminant {
1062 None => None,
1063 Some(value) => Some(cx.const_u64(value)),
1064 },
1065 self.flags,
1066 self.type_metadata)
1067 }
1068 }
1069 }
1070
1071 /// A factory for `MemberDescription`s. It produces a list of member descriptions
1072 /// for some record-like type. `MemberDescriptionFactory`s are used to defer the
1073 /// creation of type member descriptions in order to break cycles arising from
1074 /// recursive type definitions.
1075 enum MemberDescriptionFactory<'ll, 'tcx> {
1076 StructMDF(StructMemberDescriptionFactory<'tcx>),
1077 TupleMDF(TupleMemberDescriptionFactory<'tcx>),
1078 EnumMDF(EnumMemberDescriptionFactory<'ll, 'tcx>),
1079 UnionMDF(UnionMemberDescriptionFactory<'tcx>),
1080 VariantMDF(VariantMemberDescriptionFactory<'ll, 'tcx>)
1081 }
1082
1083 impl MemberDescriptionFactory<'ll, 'tcx> {
1084 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1085 -> Vec<MemberDescription<'ll>> {
1086 match *self {
1087 StructMDF(ref this) => {
1088 this.create_member_descriptions(cx)
1089 }
1090 TupleMDF(ref this) => {
1091 this.create_member_descriptions(cx)
1092 }
1093 EnumMDF(ref this) => {
1094 this.create_member_descriptions(cx)
1095 }
1096 UnionMDF(ref this) => {
1097 this.create_member_descriptions(cx)
1098 }
1099 VariantMDF(ref this) => {
1100 this.create_member_descriptions(cx)
1101 }
1102 }
1103 }
1104 }
1105
1106 //=-----------------------------------------------------------------------------
1107 // Structs
1108 //=-----------------------------------------------------------------------------
1109
1110 /// Creates `MemberDescription`s for the fields of a struct.
1111 struct StructMemberDescriptionFactory<'tcx> {
1112 ty: Ty<'tcx>,
1113 variant: &'tcx ty::VariantDef,
1114 span: Span,
1115 }
1116
1117 impl<'tcx> StructMemberDescriptionFactory<'tcx> {
1118 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1119 -> Vec<MemberDescription<'ll>> {
1120 let layout = cx.layout_of(self.ty);
1121 self.variant.fields.iter().enumerate().map(|(i, f)| {
1122 let name = if self.variant.ctor_kind == CtorKind::Fn {
1123 format!("__{}", i)
1124 } else {
1125 f.ident.to_string()
1126 };
1127 let field = layout.field(cx, i);
1128 MemberDescription {
1129 name,
1130 type_metadata: type_metadata(cx, field.ty, self.span),
1131 offset: layout.fields.offset(i),
1132 size: field.size,
1133 align: field.align.abi,
1134 flags: DIFlags::FlagZero,
1135 discriminant: None,
1136 }
1137 }).collect()
1138 }
1139 }
1140
1141
1142 fn prepare_struct_metadata(
1143 cx: &CodegenCx<'ll, 'tcx>,
1144 struct_type: Ty<'tcx>,
1145 unique_type_id: UniqueTypeId,
1146 span: Span,
1147 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1148 let struct_name = compute_debuginfo_type_name(cx.tcx, struct_type, false);
1149
1150 let (struct_def_id, variant) = match struct_type.kind {
1151 ty::Adt(def, _) => (def.did, def.non_enum_variant()),
1152 _ => bug!("prepare_struct_metadata on a non-ADT")
1153 };
1154
1155 let containing_scope = get_namespace_for_item(cx, struct_def_id);
1156
1157 let struct_metadata_stub = create_struct_stub(cx,
1158 struct_type,
1159 &struct_name,
1160 unique_type_id,
1161 Some(containing_scope));
1162
1163 create_and_register_recursive_type_forward_declaration(
1164 cx,
1165 struct_type,
1166 unique_type_id,
1167 struct_metadata_stub,
1168 struct_metadata_stub,
1169 StructMDF(StructMemberDescriptionFactory {
1170 ty: struct_type,
1171 variant,
1172 span,
1173 })
1174 )
1175 }
1176
1177 //=-----------------------------------------------------------------------------
1178 // Tuples
1179 //=-----------------------------------------------------------------------------
1180
1181 /// Creates `MemberDescription`s for the fields of a tuple.
1182 struct TupleMemberDescriptionFactory<'tcx> {
1183 ty: Ty<'tcx>,
1184 component_types: Vec<Ty<'tcx>>,
1185 span: Span,
1186 }
1187
1188 impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
1189 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1190 -> Vec<MemberDescription<'ll>> {
1191 let layout = cx.layout_of(self.ty);
1192 self.component_types.iter().enumerate().map(|(i, &component_type)| {
1193 let (size, align) = cx.size_and_align_of(component_type);
1194 MemberDescription {
1195 name: format!("__{}", i),
1196 type_metadata: type_metadata(cx, component_type, self.span),
1197 offset: layout.fields.offset(i),
1198 size,
1199 align,
1200 flags: DIFlags::FlagZero,
1201 discriminant: None,
1202 }
1203 }).collect()
1204 }
1205 }
1206
1207 fn prepare_tuple_metadata(
1208 cx: &CodegenCx<'ll, 'tcx>,
1209 tuple_type: Ty<'tcx>,
1210 component_types: &[Ty<'tcx>],
1211 unique_type_id: UniqueTypeId,
1212 span: Span,
1213 containing_scope: Option<&'ll DIScope>,
1214 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1215 let tuple_name = compute_debuginfo_type_name(cx.tcx, tuple_type, false);
1216
1217 let struct_stub = create_struct_stub(cx,
1218 tuple_type,
1219 &tuple_name[..],
1220 unique_type_id,
1221 containing_scope);
1222
1223 create_and_register_recursive_type_forward_declaration(
1224 cx,
1225 tuple_type,
1226 unique_type_id,
1227 struct_stub,
1228 struct_stub,
1229 TupleMDF(TupleMemberDescriptionFactory {
1230 ty: tuple_type,
1231 component_types: component_types.to_vec(),
1232 span,
1233 })
1234 )
1235 }
1236
1237 //=-----------------------------------------------------------------------------
1238 // Unions
1239 //=-----------------------------------------------------------------------------
1240
1241 struct UnionMemberDescriptionFactory<'tcx> {
1242 layout: TyLayout<'tcx>,
1243 variant: &'tcx ty::VariantDef,
1244 span: Span,
1245 }
1246
1247 impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
1248 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1249 -> Vec<MemberDescription<'ll>> {
1250 self.variant.fields.iter().enumerate().map(|(i, f)| {
1251 let field = self.layout.field(cx, i);
1252 MemberDescription {
1253 name: f.ident.to_string(),
1254 type_metadata: type_metadata(cx, field.ty, self.span),
1255 offset: Size::ZERO,
1256 size: field.size,
1257 align: field.align.abi,
1258 flags: DIFlags::FlagZero,
1259 discriminant: None,
1260 }
1261 }).collect()
1262 }
1263 }
1264
1265 fn prepare_union_metadata(
1266 cx: &CodegenCx<'ll, 'tcx>,
1267 union_type: Ty<'tcx>,
1268 unique_type_id: UniqueTypeId,
1269 span: Span,
1270 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1271 let union_name = compute_debuginfo_type_name(cx.tcx, union_type, false);
1272
1273 let (union_def_id, variant) = match union_type.kind {
1274 ty::Adt(def, _) => (def.did, def.non_enum_variant()),
1275 _ => bug!("prepare_union_metadata on a non-ADT")
1276 };
1277
1278 let containing_scope = get_namespace_for_item(cx, union_def_id);
1279
1280 let union_metadata_stub = create_union_stub(cx,
1281 union_type,
1282 &union_name,
1283 unique_type_id,
1284 containing_scope);
1285
1286 create_and_register_recursive_type_forward_declaration(
1287 cx,
1288 union_type,
1289 unique_type_id,
1290 union_metadata_stub,
1291 union_metadata_stub,
1292 UnionMDF(UnionMemberDescriptionFactory {
1293 layout: cx.layout_of(union_type),
1294 variant,
1295 span,
1296 })
1297 )
1298 }
1299
1300 //=-----------------------------------------------------------------------------
1301 // Enums
1302 //=-----------------------------------------------------------------------------
1303
1304 /// DWARF variant support is only available starting in LLVM 8.
1305 /// Although the earlier enum debug info output did not work properly
1306 /// in all situations, it is better for the time being to continue to
1307 /// sometimes emit the old style rather than emit something completely
1308 /// useless when rust is compiled against LLVM 6 or older. LLVM 7
1309 /// contains an early version of the DWARF variant support, and will
1310 /// crash when handling the new debug info format. This function
1311 /// decides which representation will be emitted.
1312 fn use_enum_fallback(cx: &CodegenCx<'_, '_>) -> bool {
1313 // On MSVC we have to use the fallback mode, because LLVM doesn't
1314 // lower variant parts to PDB.
1315 return cx.sess().target.target.options.is_like_msvc
1316 // LLVM version 7 did not release with an important bug fix;
1317 // but the required patch is in the LLVM 8. Rust LLVM reports
1318 // 8 as well.
1319 || llvm_util::get_major_version() < 8;
1320 }
1321
1322 // FIXME(eddyb) maybe precompute this? Right now it's computed once
1323 // per generator monomorphization, but it doesn't depend on substs.
1324 fn generator_layout_and_saved_local_names(
1325 tcx: TyCtxt<'tcx>,
1326 def_id: DefId,
1327 ) -> (&'tcx GeneratorLayout<'tcx>, IndexVec<mir::GeneratorSavedLocal, Option<ast::Name>>) {
1328 let body = tcx.optimized_mir(def_id);
1329 let generator_layout = body.generator_layout.as_ref().unwrap();
1330 let mut generator_saved_local_names =
1331 IndexVec::from_elem(None, &generator_layout.field_tys);
1332
1333 let state_arg = mir::PlaceBase::Local(mir::Local::new(1));
1334 for var in &body.var_debug_info {
1335 if var.place.base != state_arg {
1336 continue;
1337 }
1338 match var.place.projection[..] {
1339 [
1340 // Deref of the `Pin<&mut Self>` state argument.
1341 mir::ProjectionElem::Field(..),
1342 mir::ProjectionElem::Deref,
1343
1344 // Field of a variant of the state.
1345 mir::ProjectionElem::Downcast(_, variant),
1346 mir::ProjectionElem::Field(field, _),
1347 ] => {
1348 let name = &mut generator_saved_local_names[
1349 generator_layout.variant_fields[variant][field]
1350 ];
1351 if name.is_none() {
1352 name.replace(var.name);
1353 }
1354 }
1355 _ => {}
1356 }
1357 }
1358 (generator_layout, generator_saved_local_names)
1359 }
1360
1361 /// Describes the members of an enum value; an enum is described as a union of
1362 /// structs in DWARF. This `MemberDescriptionFactory` provides the description for
1363 /// the members of this union; so for every variant of the given enum, this
1364 /// factory will produce one `MemberDescription` (all with no name and a fixed
1365 /// offset of zero bytes).
1366 struct EnumMemberDescriptionFactory<'ll, 'tcx> {
1367 enum_type: Ty<'tcx>,
1368 layout: TyLayout<'tcx>,
1369 discriminant_type_metadata: Option<&'ll DIType>,
1370 containing_scope: &'ll DIScope,
1371 span: Span,
1372 }
1373
1374 impl EnumMemberDescriptionFactory<'ll, 'tcx> {
1375 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1376 -> Vec<MemberDescription<'ll>> {
1377 let generator_variant_info_data = match self.enum_type.kind {
1378 ty::Generator(def_id, ..) => {
1379 Some(generator_layout_and_saved_local_names(cx.tcx, def_id))
1380 }
1381 _ => None,
1382 };
1383
1384 let variant_info_for = |index: VariantIdx| {
1385 match self.enum_type.kind {
1386 ty::Adt(adt, _) => VariantInfo::Adt(&adt.variants[index]),
1387 ty::Generator(_, substs, _) => {
1388 let (generator_layout, generator_saved_local_names) =
1389 generator_variant_info_data.as_ref().unwrap();
1390 VariantInfo::Generator {
1391 substs,
1392 generator_layout: *generator_layout,
1393 generator_saved_local_names,
1394 variant_index: index,
1395 }
1396 }
1397 _ => bug!(),
1398 }
1399 };
1400
1401 // This will always find the metadata in the type map.
1402 let fallback = use_enum_fallback(cx);
1403 let self_metadata = if fallback {
1404 self.containing_scope
1405 } else {
1406 type_metadata(cx, self.enum_type, self.span)
1407 };
1408
1409 match self.layout.variants {
1410 layout::Variants::Single { index } => {
1411 if let ty::Adt(adt, _) = &self.enum_type.kind {
1412 if adt.variants.is_empty() {
1413 return vec![];
1414 }
1415 }
1416
1417 let variant_info = variant_info_for(index);
1418 let (variant_type_metadata, member_description_factory) =
1419 describe_enum_variant(cx,
1420 self.layout,
1421 variant_info,
1422 NoDiscriminant,
1423 self_metadata,
1424 self.span);
1425
1426 let member_descriptions =
1427 member_description_factory.create_member_descriptions(cx);
1428
1429 set_members_of_composite_type(cx,
1430 self.enum_type,
1431 variant_type_metadata,
1432 member_descriptions);
1433 vec![
1434 MemberDescription {
1435 name: if fallback {
1436 String::new()
1437 } else {
1438 variant_info.variant_name()
1439 },
1440 type_metadata: variant_type_metadata,
1441 offset: Size::ZERO,
1442 size: self.layout.size,
1443 align: self.layout.align.abi,
1444 flags: DIFlags::FlagZero,
1445 discriminant: None,
1446 }
1447 ]
1448 }
1449 layout::Variants::Multiple {
1450 discr_kind: layout::DiscriminantKind::Tag,
1451 discr_index,
1452 ref variants,
1453 ..
1454 } => {
1455 let discriminant_info = if fallback {
1456 RegularDiscriminant {
1457 discr_field: Field::from(discr_index),
1458 discr_type_metadata: self.discriminant_type_metadata.unwrap()
1459 }
1460 } else {
1461 // This doesn't matter in this case.
1462 NoDiscriminant
1463 };
1464 variants.iter_enumerated().map(|(i, _)| {
1465 let variant = self.layout.for_variant(cx, i);
1466 let variant_info = variant_info_for(i);
1467 let (variant_type_metadata, member_desc_factory) =
1468 describe_enum_variant(cx,
1469 variant,
1470 variant_info,
1471 discriminant_info,
1472 self_metadata,
1473 self.span);
1474
1475 let member_descriptions = member_desc_factory
1476 .create_member_descriptions(cx);
1477
1478 set_members_of_composite_type(cx,
1479 self.enum_type,
1480 variant_type_metadata,
1481 member_descriptions);
1482
1483 MemberDescription {
1484 name: if fallback {
1485 String::new()
1486 } else {
1487 variant_info.variant_name()
1488 },
1489 type_metadata: variant_type_metadata,
1490 offset: Size::ZERO,
1491 size: self.layout.size,
1492 align: self.layout.align.abi,
1493 flags: DIFlags::FlagZero,
1494 discriminant: Some(
1495 self.layout.ty.discriminant_for_variant(cx.tcx, i).unwrap().val as u64
1496 ),
1497 }
1498 }).collect()
1499 }
1500 layout::Variants::Multiple {
1501 discr_kind: layout::DiscriminantKind::Niche {
1502 ref niche_variants,
1503 niche_start,
1504 dataful_variant,
1505 },
1506 ref discr,
1507 ref variants,
1508 discr_index,
1509 } => {
1510 if fallback {
1511 let variant = self.layout.for_variant(cx, dataful_variant);
1512 // Create a description of the non-null variant.
1513 let (variant_type_metadata, member_description_factory) =
1514 describe_enum_variant(cx,
1515 variant,
1516 variant_info_for(dataful_variant),
1517 OptimizedDiscriminant,
1518 self.containing_scope,
1519 self.span);
1520
1521 let variant_member_descriptions =
1522 member_description_factory.create_member_descriptions(cx);
1523
1524 set_members_of_composite_type(cx,
1525 self.enum_type,
1526 variant_type_metadata,
1527 variant_member_descriptions);
1528
1529 // Encode the information about the null variant in the union
1530 // member's name.
1531 let mut name = String::from("RUST$ENCODED$ENUM$");
1532 // Right now it's not even going to work for `niche_start > 0`,
1533 // and for multiple niche variants it only supports the first.
1534 fn compute_field_path<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
1535 name: &mut String,
1536 layout: TyLayout<'tcx>,
1537 offset: Size,
1538 size: Size) {
1539 for i in 0..layout.fields.count() {
1540 let field_offset = layout.fields.offset(i);
1541 if field_offset > offset {
1542 continue;
1543 }
1544 let inner_offset = offset - field_offset;
1545 let field = layout.field(cx, i);
1546 if inner_offset + size <= field.size {
1547 write!(name, "{}$", i).unwrap();
1548 compute_field_path(cx, name, field, inner_offset, size);
1549 }
1550 }
1551 }
1552 compute_field_path(cx, &mut name,
1553 self.layout,
1554 self.layout.fields.offset(discr_index),
1555 self.layout.field(cx, discr_index).size);
1556 variant_info_for(*niche_variants.start()).map_struct_name(|variant_name| {
1557 name.push_str(variant_name);
1558 });
1559
1560 // Create the (singleton) list of descriptions of union members.
1561 vec![
1562 MemberDescription {
1563 name,
1564 type_metadata: variant_type_metadata,
1565 offset: Size::ZERO,
1566 size: variant.size,
1567 align: variant.align.abi,
1568 flags: DIFlags::FlagZero,
1569 discriminant: None,
1570 }
1571 ]
1572 } else {
1573 variants.iter_enumerated().map(|(i, _)| {
1574 let variant = self.layout.for_variant(cx, i);
1575 let variant_info = variant_info_for(i);
1576 let (variant_type_metadata, member_desc_factory) =
1577 describe_enum_variant(cx,
1578 variant,
1579 variant_info,
1580 OptimizedDiscriminant,
1581 self_metadata,
1582 self.span);
1583
1584 let member_descriptions = member_desc_factory
1585 .create_member_descriptions(cx);
1586
1587 set_members_of_composite_type(cx,
1588 self.enum_type,
1589 variant_type_metadata,
1590 member_descriptions);
1591
1592 let niche_value = if i == dataful_variant {
1593 None
1594 } else {
1595 let value = (i.as_u32() as u128)
1596 .wrapping_sub(niche_variants.start().as_u32() as u128)
1597 .wrapping_add(niche_start);
1598 let value = truncate(value, discr.value.size(cx));
1599 // NOTE(eddyb) do *NOT* remove this assert, until
1600 // we pass the full 128-bit value to LLVM, otherwise
1601 // truncation will be silent and remain undetected.
1602 assert_eq!(value as u64 as u128, value);
1603 Some(value as u64)
1604 };
1605
1606 MemberDescription {
1607 name: variant_info.variant_name(),
1608 type_metadata: variant_type_metadata,
1609 offset: Size::ZERO,
1610 size: self.layout.size,
1611 align: self.layout.align.abi,
1612 flags: DIFlags::FlagZero,
1613 discriminant: niche_value,
1614 }
1615 }).collect()
1616 }
1617 }
1618 }
1619 }
1620 }
1621
1622 // Creates `MemberDescription`s for the fields of a single enum variant.
1623 struct VariantMemberDescriptionFactory<'ll, 'tcx> {
1624 /// Cloned from the `layout::Struct` describing the variant.
1625 offsets: Vec<layout::Size>,
1626 args: Vec<(String, Ty<'tcx>)>,
1627 discriminant_type_metadata: Option<&'ll DIType>,
1628 span: Span,
1629 }
1630
1631 impl VariantMemberDescriptionFactory<'ll, 'tcx> {
1632 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>)
1633 -> Vec<MemberDescription<'ll>> {
1634 self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
1635 let (size, align) = cx.size_and_align_of(ty);
1636 MemberDescription {
1637 name: name.to_string(),
1638 type_metadata: if use_enum_fallback(cx) {
1639 match self.discriminant_type_metadata {
1640 // Discriminant is always the first field of our variant
1641 // when using the enum fallback.
1642 Some(metadata) if i == 0 => metadata,
1643 _ => type_metadata(cx, ty, self.span)
1644 }
1645 } else {
1646 type_metadata(cx, ty, self.span)
1647 },
1648 offset: self.offsets[i],
1649 size,
1650 align,
1651 flags: DIFlags::FlagZero,
1652 discriminant: None,
1653 }
1654 }).collect()
1655 }
1656 }
1657
1658 #[derive(Copy, Clone)]
1659 enum EnumDiscriminantInfo<'ll> {
1660 RegularDiscriminant{ discr_field: Field, discr_type_metadata: &'ll DIType },
1661 OptimizedDiscriminant,
1662 NoDiscriminant
1663 }
1664
1665 #[derive(Copy, Clone)]
1666 enum VariantInfo<'a, 'tcx> {
1667 Adt(&'tcx ty::VariantDef),
1668 Generator {
1669 substs: SubstsRef<'tcx>,
1670 generator_layout: &'tcx GeneratorLayout<'tcx>,
1671 generator_saved_local_names: &'a IndexVec<mir::GeneratorSavedLocal, Option<ast::Name>>,
1672 variant_index: VariantIdx,
1673 },
1674 }
1675
1676 impl<'tcx> VariantInfo<'_, 'tcx> {
1677 fn map_struct_name<R>(&self, f: impl FnOnce(&str) -> R) -> R {
1678 match self {
1679 VariantInfo::Adt(variant) => f(&variant.ident.as_str()),
1680 VariantInfo::Generator { substs, variant_index, .. } =>
1681 f(&substs.as_generator().variant_name(*variant_index)),
1682 }
1683 }
1684
1685 fn variant_name(&self) -> String {
1686 match self {
1687 VariantInfo::Adt(variant) => variant.ident.to_string(),
1688 VariantInfo::Generator { variant_index, .. } => {
1689 // Since GDB currently prints out the raw discriminant along
1690 // with every variant, make each variant name be just the value
1691 // of the discriminant. The struct name for the variant includes
1692 // the actual variant description.
1693 format!("{}", variant_index.as_usize())
1694 }
1695 }
1696 }
1697
1698 fn field_name(&self, i: usize) -> String {
1699 let field_name = match *self {
1700 VariantInfo::Adt(variant) if variant.ctor_kind != CtorKind::Fn =>
1701 Some(variant.fields[i].ident.name),
1702 VariantInfo::Generator {
1703 generator_layout,
1704 generator_saved_local_names,
1705 variant_index,
1706 ..
1707 } => generator_saved_local_names[
1708 generator_layout.variant_fields[variant_index][i.into()]
1709 ],
1710 _ => None,
1711 };
1712 field_name.map(|name| name.to_string()).unwrap_or_else(|| format!("__{}", i))
1713 }
1714 }
1715
1716 /// Returns a tuple of (1) `type_metadata_stub` of the variant, (2) a
1717 /// `MemberDescriptionFactory` for producing the descriptions of the
1718 /// fields of the variant. This is a rudimentary version of a full
1719 /// `RecursiveTypeDescription`.
1720 fn describe_enum_variant(
1721 cx: &CodegenCx<'ll, 'tcx>,
1722 layout: layout::TyLayout<'tcx>,
1723 variant: VariantInfo<'_, 'tcx>,
1724 discriminant_info: EnumDiscriminantInfo<'ll>,
1725 containing_scope: &'ll DIScope,
1726 span: Span,
1727 ) -> (&'ll DICompositeType, MemberDescriptionFactory<'ll, 'tcx>) {
1728 let metadata_stub = variant.map_struct_name(|variant_name| {
1729 let unique_type_id = debug_context(cx).type_map
1730 .borrow_mut()
1731 .get_unique_type_id_of_enum_variant(
1732 cx,
1733 layout.ty,
1734 &variant_name);
1735 create_struct_stub(cx,
1736 layout.ty,
1737 &variant_name,
1738 unique_type_id,
1739 Some(containing_scope))
1740 });
1741
1742 // Build an array of (field name, field type) pairs to be captured in the factory closure.
1743 let (offsets, args) = if use_enum_fallback(cx) {
1744 // If this is not a univariant enum, there is also the discriminant field.
1745 let (discr_offset, discr_arg) = match discriminant_info {
1746 RegularDiscriminant { discr_field, .. } => {
1747 // We have the layout of an enum variant, we need the layout of the outer enum
1748 let enum_layout = cx.layout_of(layout.ty);
1749 let offset = enum_layout.fields.offset(discr_field.as_usize());
1750 let args = (
1751 "RUST$ENUM$DISR".to_owned(),
1752 enum_layout.field(cx, discr_field.as_usize()).ty);
1753 (Some(offset), Some(args))
1754 }
1755 _ => (None, None),
1756 };
1757 (
1758 discr_offset.into_iter().chain((0..layout.fields.count()).map(|i| {
1759 layout.fields.offset(i)
1760 })).collect(),
1761 discr_arg.into_iter().chain((0..layout.fields.count()).map(|i| {
1762 (variant.field_name(i), layout.field(cx, i).ty)
1763 })).collect()
1764 )
1765 } else {
1766 (
1767 (0..layout.fields.count()).map(|i| {
1768 layout.fields.offset(i)
1769 }).collect(),
1770 (0..layout.fields.count()).map(|i| {
1771 (variant.field_name(i), layout.field(cx, i).ty)
1772 }).collect()
1773 )
1774 };
1775
1776 let member_description_factory =
1777 VariantMDF(VariantMemberDescriptionFactory {
1778 offsets,
1779 args,
1780 discriminant_type_metadata: match discriminant_info {
1781 RegularDiscriminant { discr_type_metadata, .. } => {
1782 Some(discr_type_metadata)
1783 }
1784 _ => None
1785 },
1786 span,
1787 });
1788
1789 (metadata_stub, member_description_factory)
1790 }
1791
1792 fn prepare_enum_metadata(
1793 cx: &CodegenCx<'ll, 'tcx>,
1794 enum_type: Ty<'tcx>,
1795 enum_def_id: DefId,
1796 unique_type_id: UniqueTypeId,
1797 span: Span,
1798 outer_field_tys: Vec<Ty<'tcx>>,
1799 ) -> RecursiveTypeDescription<'ll, 'tcx> {
1800 let enum_name = compute_debuginfo_type_name(cx.tcx, enum_type, false);
1801
1802 let containing_scope = get_namespace_for_item(cx, enum_def_id);
1803 // FIXME: This should emit actual file metadata for the enum, but we
1804 // currently can't get the necessary information when it comes to types
1805 // imported from other crates. Formerly we violated the ODR when performing
1806 // LTO because we emitted debuginfo for the same type with varying file
1807 // metadata, so as a workaround we pretend that the type comes from
1808 // <unknown>
1809 let file_metadata = unknown_file_metadata(cx);
1810
1811 let discriminant_type_metadata = |discr: layout::Primitive| {
1812 let enumerators_metadata: Vec<_> = match enum_type.kind {
1813 ty::Adt(def, _) => def
1814 .discriminants(cx.tcx)
1815 .zip(&def.variants)
1816 .map(|((_, discr), v)| {
1817 let name = SmallCStr::new(&v.ident.as_str());
1818 unsafe {
1819 Some(llvm::LLVMRustDIBuilderCreateEnumerator(
1820 DIB(cx),
1821 name.as_ptr(),
1822 // FIXME: what if enumeration has i128 discriminant?
1823 discr.val as u64))
1824 }
1825 })
1826 .collect(),
1827 ty::Generator(_, substs, _) => substs
1828 .as_generator()
1829 .variant_range(enum_def_id, cx.tcx)
1830 .map(|variant_index| {
1831 let name = SmallCStr::new(&substs.as_generator().variant_name(variant_index));
1832 unsafe {
1833 Some(llvm::LLVMRustDIBuilderCreateEnumerator(
1834 DIB(cx),
1835 name.as_ptr(),
1836 // FIXME: what if enumeration has i128 discriminant?
1837 variant_index.as_usize() as u64))
1838 }
1839 })
1840 .collect(),
1841 _ => bug!(),
1842 };
1843
1844 let disr_type_key = (enum_def_id, discr);
1845 let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
1846 .borrow()
1847 .get(&disr_type_key).cloned();
1848 match cached_discriminant_type_metadata {
1849 Some(discriminant_type_metadata) => discriminant_type_metadata,
1850 None => {
1851 let (discriminant_size, discriminant_align) =
1852 (discr.size(cx), discr.align(cx));
1853 let discriminant_base_type_metadata =
1854 type_metadata(cx, discr.to_ty(cx.tcx), syntax_pos::DUMMY_SP);
1855
1856 let discriminant_name = match enum_type.kind {
1857 ty::Adt(..) => SmallCStr::new(&cx.tcx.item_name(enum_def_id).as_str()),
1858 ty::Generator(..) => SmallCStr::new(&enum_name),
1859 _ => bug!(),
1860 };
1861
1862 let discriminant_type_metadata = unsafe {
1863 llvm::LLVMRustDIBuilderCreateEnumerationType(
1864 DIB(cx),
1865 containing_scope,
1866 discriminant_name.as_ptr(),
1867 file_metadata,
1868 UNKNOWN_LINE_NUMBER,
1869 discriminant_size.bits(),
1870 discriminant_align.abi.bits() as u32,
1871 create_DIArray(DIB(cx), &enumerators_metadata),
1872 discriminant_base_type_metadata, true)
1873 };
1874
1875 debug_context(cx).created_enum_disr_types
1876 .borrow_mut()
1877 .insert(disr_type_key, discriminant_type_metadata);
1878
1879 discriminant_type_metadata
1880 }
1881 }
1882 };
1883
1884 let layout = cx.layout_of(enum_type);
1885
1886 match (&layout.abi, &layout.variants) {
1887 (&layout::Abi::Scalar(_), &layout::Variants::Multiple {
1888 discr_kind: layout::DiscriminantKind::Tag,
1889 ref discr,
1890 ..
1891 }) => return FinalMetadata(discriminant_type_metadata(discr.value)),
1892 _ => {}
1893 }
1894
1895 let enum_name = SmallCStr::new(&enum_name);
1896 let unique_type_id_str = SmallCStr::new(
1897 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
1898 );
1899
1900 if use_enum_fallback(cx) {
1901 let discriminant_type_metadata = match layout.variants {
1902 layout::Variants::Single { .. } |
1903 layout::Variants::Multiple {
1904 discr_kind: layout::DiscriminantKind::Niche { .. },
1905 ..
1906 } => None,
1907 layout::Variants::Multiple {
1908 discr_kind: layout::DiscriminantKind::Tag,
1909 ref discr,
1910 ..
1911 } => {
1912 Some(discriminant_type_metadata(discr.value))
1913 }
1914 };
1915
1916 let enum_metadata = unsafe {
1917 llvm::LLVMRustDIBuilderCreateUnionType(
1918 DIB(cx),
1919 containing_scope,
1920 enum_name.as_ptr(),
1921 file_metadata,
1922 UNKNOWN_LINE_NUMBER,
1923 layout.size.bits(),
1924 layout.align.abi.bits() as u32,
1925 DIFlags::FlagZero,
1926 None,
1927 0, // RuntimeLang
1928 unique_type_id_str.as_ptr())
1929 };
1930
1931 return create_and_register_recursive_type_forward_declaration(
1932 cx,
1933 enum_type,
1934 unique_type_id,
1935 enum_metadata,
1936 enum_metadata,
1937 EnumMDF(EnumMemberDescriptionFactory {
1938 enum_type,
1939 layout,
1940 discriminant_type_metadata,
1941 containing_scope,
1942 span,
1943 }),
1944 );
1945 }
1946
1947 let discriminator_name = match &enum_type.kind {
1948 ty::Generator(..) => Some(SmallCStr::new(&"__state")),
1949 _ => None,
1950 };
1951 let discriminator_name = discriminator_name.map(|n| n.as_ptr()).unwrap_or(ptr::null_mut());
1952 let discriminator_metadata = match layout.variants {
1953 // A single-variant enum has no discriminant.
1954 layout::Variants::Single { .. } => None,
1955
1956 layout::Variants::Multiple {
1957 discr_kind: layout::DiscriminantKind::Niche { .. },
1958 ref discr,
1959 discr_index,
1960 ..
1961 } => {
1962 // Find the integer type of the correct size.
1963 let size = discr.value.size(cx);
1964 let align = discr.value.align(cx);
1965
1966 let discr_type = match discr.value {
1967 layout::Int(t, _) => t,
1968 layout::F32 => Integer::I32,
1969 layout::F64 => Integer::I64,
1970 layout::Pointer => cx.data_layout().ptr_sized_integer(),
1971 }.to_ty(cx.tcx, false);
1972
1973 let discr_metadata = basic_type_metadata(cx, discr_type);
1974 unsafe {
1975 Some(llvm::LLVMRustDIBuilderCreateMemberType(
1976 DIB(cx),
1977 containing_scope,
1978 discriminator_name,
1979 file_metadata,
1980 UNKNOWN_LINE_NUMBER,
1981 size.bits(),
1982 align.abi.bits() as u32,
1983 layout.fields.offset(discr_index).bits(),
1984 DIFlags::FlagArtificial,
1985 discr_metadata))
1986 }
1987 },
1988
1989 layout::Variants::Multiple {
1990 discr_kind: layout::DiscriminantKind::Tag,
1991 ref discr,
1992 discr_index,
1993 ..
1994 } => {
1995 let discr_type = discr.value.to_ty(cx.tcx);
1996 let (size, align) = cx.size_and_align_of(discr_type);
1997
1998 let discr_metadata = basic_type_metadata(cx, discr_type);
1999 unsafe {
2000 Some(llvm::LLVMRustDIBuilderCreateMemberType(
2001 DIB(cx),
2002 containing_scope,
2003 discriminator_name,
2004 file_metadata,
2005 UNKNOWN_LINE_NUMBER,
2006 size.bits(),
2007 align.bits() as u32,
2008 layout.fields.offset(discr_index).bits(),
2009 DIFlags::FlagArtificial,
2010 discr_metadata))
2011 }
2012 },
2013 };
2014
2015 let mut outer_fields = match layout.variants {
2016 layout::Variants::Single { .. } => vec![],
2017 layout::Variants::Multiple { .. } => {
2018 let tuple_mdf = TupleMemberDescriptionFactory {
2019 ty: enum_type,
2020 component_types: outer_field_tys,
2021 span
2022 };
2023 tuple_mdf
2024 .create_member_descriptions(cx)
2025 .into_iter()
2026 .map(|desc| Some(desc.into_metadata(cx, containing_scope)))
2027 .collect()
2028 }
2029 };
2030
2031 let variant_part_unique_type_id_str = SmallCStr::new(
2032 debug_context(cx).type_map
2033 .borrow_mut()
2034 .get_unique_type_id_str_of_enum_variant_part(unique_type_id)
2035 );
2036 let empty_array = create_DIArray(DIB(cx), &[]);
2037 let variant_part = unsafe {
2038 llvm::LLVMRustDIBuilderCreateVariantPart(
2039 DIB(cx),
2040 containing_scope,
2041 ptr::null_mut(),
2042 file_metadata,
2043 UNKNOWN_LINE_NUMBER,
2044 layout.size.bits(),
2045 layout.align.abi.bits() as u32,
2046 DIFlags::FlagZero,
2047 discriminator_metadata,
2048 empty_array,
2049 variant_part_unique_type_id_str.as_ptr())
2050 };
2051 outer_fields.push(Some(variant_part));
2052
2053 // The variant part must be wrapped in a struct according to DWARF.
2054 let type_array = create_DIArray(DIB(cx), &outer_fields);
2055 let struct_wrapper = unsafe {
2056 llvm::LLVMRustDIBuilderCreateStructType(
2057 DIB(cx),
2058 Some(containing_scope),
2059 enum_name.as_ptr(),
2060 file_metadata,
2061 UNKNOWN_LINE_NUMBER,
2062 layout.size.bits(),
2063 layout.align.abi.bits() as u32,
2064 DIFlags::FlagZero,
2065 None,
2066 type_array,
2067 0,
2068 None,
2069 unique_type_id_str.as_ptr())
2070 };
2071
2072 return create_and_register_recursive_type_forward_declaration(
2073 cx,
2074 enum_type,
2075 unique_type_id,
2076 struct_wrapper,
2077 variant_part,
2078 EnumMDF(EnumMemberDescriptionFactory {
2079 enum_type,
2080 layout,
2081 discriminant_type_metadata: None,
2082 containing_scope,
2083 span,
2084 }),
2085 );
2086 }
2087
2088 /// Creates debug information for a composite type, that is, anything that
2089 /// results in a LLVM struct.
2090 ///
2091 /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
2092 fn composite_type_metadata(
2093 cx: &CodegenCx<'ll, 'tcx>,
2094 composite_type: Ty<'tcx>,
2095 composite_type_name: &str,
2096 composite_type_unique_id: UniqueTypeId,
2097 member_descriptions: Vec<MemberDescription<'ll>>,
2098 containing_scope: Option<&'ll DIScope>,
2099
2100 // Ignore source location information as long as it
2101 // can't be reconstructed for non-local crates.
2102 _file_metadata: &'ll DIFile,
2103 _definition_span: Span,
2104 ) -> &'ll DICompositeType {
2105 // Create the (empty) struct metadata node ...
2106 let composite_type_metadata = create_struct_stub(cx,
2107 composite_type,
2108 composite_type_name,
2109 composite_type_unique_id,
2110 containing_scope);
2111 // ... and immediately create and add the member descriptions.
2112 set_members_of_composite_type(cx,
2113 composite_type,
2114 composite_type_metadata,
2115 member_descriptions);
2116
2117 composite_type_metadata
2118 }
2119
2120 fn set_members_of_composite_type(cx: &CodegenCx<'ll, 'tcx>,
2121 composite_type: Ty<'tcx>,
2122 composite_type_metadata: &'ll DICompositeType,
2123 member_descriptions: Vec<MemberDescription<'ll>>) {
2124 // In some rare cases LLVM metadata uniquing would lead to an existing type
2125 // description being used instead of a new one created in
2126 // create_struct_stub. This would cause a hard to trace assertion in
2127 // DICompositeType::SetTypeArray(). The following check makes sure that we
2128 // get a better error message if this should happen again due to some
2129 // regression.
2130 {
2131 let mut composite_types_completed =
2132 debug_context(cx).composite_types_completed.borrow_mut();
2133 if !composite_types_completed.insert(&composite_type_metadata) {
2134 bug!("debuginfo::set_members_of_composite_type() - \
2135 Already completed forward declaration re-encountered.");
2136 }
2137 }
2138
2139 let member_metadata: Vec<_> = member_descriptions
2140 .into_iter()
2141 .map(|desc| Some(desc.into_metadata(cx, composite_type_metadata)))
2142 .collect();
2143
2144 let type_params = compute_type_parameters(cx, composite_type);
2145 unsafe {
2146 let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
2147 llvm::LLVMRustDICompositeTypeReplaceArrays(
2148 DIB(cx), composite_type_metadata, Some(type_array), type_params);
2149 }
2150 }
2151
2152 /// Computes the type parameters for a type, if any, for the given metadata.
2153 fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> Option<&'ll DIArray> {
2154 if let ty::Adt(def, substs) = ty.kind {
2155 if !substs.types().next().is_none() {
2156 let generics = cx.tcx.generics_of(def.did);
2157 let names = get_parameter_names(cx, generics);
2158 let template_params: Vec<_> = substs.iter().zip(names).filter_map(|(kind, name)| {
2159 if let GenericArgKind::Type(ty) = kind.unpack() {
2160 let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
2161 let actual_type_metadata =
2162 type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
2163 let name = SmallCStr::new(&name.as_str());
2164 Some(unsafe {
2165
2166 Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
2167 DIB(cx),
2168 None,
2169 name.as_ptr(),
2170 actual_type_metadata,
2171 unknown_file_metadata(cx),
2172 0,
2173 0,
2174 ))
2175 })
2176 } else {
2177 None
2178 }
2179 }).collect();
2180
2181 return Some(create_DIArray(DIB(cx), &template_params[..]));
2182 }
2183 }
2184 return Some(create_DIArray(DIB(cx), &[]));
2185
2186 fn get_parameter_names(cx: &CodegenCx<'_, '_>,
2187 generics: &ty::Generics)
2188 -> Vec<Symbol> {
2189 let mut names = generics.parent.map_or(vec![], |def_id| {
2190 get_parameter_names(cx, cx.tcx.generics_of(def_id))
2191 });
2192 names.extend(generics.params.iter().map(|param| param.name));
2193 names
2194 }
2195 }
2196
2197 /// A convenience wrapper around `LLVMRustDIBuilderCreateStructType()`. Does not do
2198 /// any caching, does not add any fields to the struct. This can be done later
2199 /// with `set_members_of_composite_type()`.
2200 fn create_struct_stub(
2201 cx: &CodegenCx<'ll, 'tcx>,
2202 struct_type: Ty<'tcx>,
2203 struct_type_name: &str,
2204 unique_type_id: UniqueTypeId,
2205 containing_scope: Option<&'ll DIScope>,
2206 ) -> &'ll DICompositeType {
2207 let (struct_size, struct_align) = cx.size_and_align_of(struct_type);
2208
2209 let name = SmallCStr::new(struct_type_name);
2210 let unique_type_id = SmallCStr::new(
2211 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
2212 );
2213 let metadata_stub = unsafe {
2214 // `LLVMRustDIBuilderCreateStructType()` wants an empty array. A null
2215 // pointer will lead to hard to trace and debug LLVM assertions
2216 // later on in `llvm/lib/IR/Value.cpp`.
2217 let empty_array = create_DIArray(DIB(cx), &[]);
2218
2219 llvm::LLVMRustDIBuilderCreateStructType(
2220 DIB(cx),
2221 containing_scope,
2222 name.as_ptr(),
2223 unknown_file_metadata(cx),
2224 UNKNOWN_LINE_NUMBER,
2225 struct_size.bits(),
2226 struct_align.bits() as u32,
2227 DIFlags::FlagZero,
2228 None,
2229 empty_array,
2230 0,
2231 None,
2232 unique_type_id.as_ptr())
2233 };
2234
2235 metadata_stub
2236 }
2237
2238 fn create_union_stub(
2239 cx: &CodegenCx<'ll, 'tcx>,
2240 union_type: Ty<'tcx>,
2241 union_type_name: &str,
2242 unique_type_id: UniqueTypeId,
2243 containing_scope: &'ll DIScope,
2244 ) -> &'ll DICompositeType {
2245 let (union_size, union_align) = cx.size_and_align_of(union_type);
2246
2247 let name = SmallCStr::new(union_type_name);
2248 let unique_type_id = SmallCStr::new(
2249 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id)
2250 );
2251 let metadata_stub = unsafe {
2252 // `LLVMRustDIBuilderCreateUnionType()` wants an empty array. A null
2253 // pointer will lead to hard to trace and debug LLVM assertions
2254 // later on in `llvm/lib/IR/Value.cpp`.
2255 let empty_array = create_DIArray(DIB(cx), &[]);
2256
2257 llvm::LLVMRustDIBuilderCreateUnionType(
2258 DIB(cx),
2259 containing_scope,
2260 name.as_ptr(),
2261 unknown_file_metadata(cx),
2262 UNKNOWN_LINE_NUMBER,
2263 union_size.bits(),
2264 union_align.bits() as u32,
2265 DIFlags::FlagZero,
2266 Some(empty_array),
2267 0, // RuntimeLang
2268 unique_type_id.as_ptr())
2269 };
2270
2271 metadata_stub
2272 }
2273
2274 /// Creates debug information for the given global variable.
2275 ///
2276 /// Adds the created metadata nodes directly to the crate's IR.
2277 pub fn create_global_var_metadata(
2278 cx: &CodegenCx<'ll, '_>,
2279 def_id: DefId,
2280 global: &'ll Value,
2281 ) {
2282 if cx.dbg_cx.is_none() {
2283 return;
2284 }
2285
2286 let tcx = cx.tcx;
2287 let attrs = tcx.codegen_fn_attrs(def_id);
2288
2289 if attrs.flags.contains(CodegenFnAttrFlags::NO_DEBUG) {
2290 return;
2291 }
2292
2293 let no_mangle = attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE);
2294 // We may want to remove the namespace scope if we're in an extern block (see
2295 // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952).
2296 let var_scope = get_namespace_for_item(cx, def_id);
2297 let span = tcx.def_span(def_id);
2298
2299 let (file_metadata, line_number) = if !span.is_dummy() {
2300 let loc = span_start(cx, span);
2301 (file_metadata(cx, &loc.file.name, LOCAL_CRATE), loc.line as c_uint)
2302 } else {
2303 (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
2304 };
2305
2306 let is_local_to_unit = is_node_local_to_unit(cx, def_id);
2307 let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx);
2308 let type_metadata = type_metadata(cx, variable_type, span);
2309 let var_name = SmallCStr::new(&tcx.item_name(def_id).as_str());
2310 let linkage_name = if no_mangle {
2311 None
2312 } else {
2313 let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id));
2314 Some(SmallCStr::new(&linkage_name.name.as_str()))
2315 };
2316
2317 let global_align = cx.align_of(variable_type);
2318
2319 unsafe {
2320 llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
2321 Some(var_scope),
2322 var_name.as_ptr(),
2323 // If null, linkage_name field is omitted,
2324 // which is what we want for no_mangle statics
2325 linkage_name.as_ref()
2326 .map_or(ptr::null(), |name| name.as_ptr()),
2327 file_metadata,
2328 line_number,
2329 type_metadata,
2330 is_local_to_unit,
2331 global,
2332 None,
2333 global_align.bytes() as u32,
2334 );
2335 }
2336 }
2337
2338 /// Creates debug information for the given vtable, which is for the
2339 /// given type.
2340 ///
2341 /// Adds the created metadata nodes directly to the crate's IR.
2342 pub fn create_vtable_metadata(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, vtable: &'ll Value) {
2343 if cx.dbg_cx.is_none() {
2344 return;
2345 }
2346
2347 let type_metadata = type_metadata(cx, ty, syntax_pos::DUMMY_SP);
2348
2349 unsafe {
2350 // `LLVMRustDIBuilderCreateStructType()` wants an empty array. A null
2351 // pointer will lead to hard to trace and debug LLVM assertions
2352 // later on in `llvm/lib/IR/Value.cpp`.
2353 let empty_array = create_DIArray(DIB(cx), &[]);
2354
2355 let name = const_cstr!("vtable");
2356
2357 // Create a new one each time. We don't want metadata caching
2358 // here, because each vtable will refer to a unique containing
2359 // type.
2360 let vtable_type = llvm::LLVMRustDIBuilderCreateStructType(
2361 DIB(cx),
2362 NO_SCOPE_METADATA,
2363 name.as_ptr(),
2364 unknown_file_metadata(cx),
2365 UNKNOWN_LINE_NUMBER,
2366 Size::ZERO.bits(),
2367 cx.tcx.data_layout.pointer_align.abi.bits() as u32,
2368 DIFlags::FlagArtificial,
2369 None,
2370 empty_array,
2371 0,
2372 Some(type_metadata),
2373 name.as_ptr()
2374 );
2375
2376 llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
2377 NO_SCOPE_METADATA,
2378 name.as_ptr(),
2379 ptr::null(),
2380 unknown_file_metadata(cx),
2381 UNKNOWN_LINE_NUMBER,
2382 vtable_type,
2383 true,
2384 vtable,
2385 None,
2386 0);
2387 }
2388 }
2389
2390 /// Creates an "extension" of an existing `DIScope` into another file.
2391 pub fn extend_scope_to_file(
2392 cx: &CodegenCx<'ll, '_>,
2393 scope_metadata: &'ll DIScope,
2394 file: &syntax_pos::SourceFile,
2395 defining_crate: CrateNum,
2396 ) -> &'ll DILexicalBlock {
2397 let file_metadata = file_metadata(cx, &file.name, defining_crate);
2398 unsafe {
2399 llvm::LLVMRustDIBuilderCreateLexicalBlockFile(
2400 DIB(cx),
2401 scope_metadata,
2402 file_metadata)
2403 }
2404 }