]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/debuginfo/metadata.rs
Add transpose conversions for Option and Result
[rust.git] / src / librustc_trans / debuginfo / metadata.rs
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.
4 //
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.
10
11 use self::RecursiveTypeDescription::*;
12 use self::MemberDescriptionFactory::*;
13 use self::EnumDiscriminantInfo::*;
14
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_item;
18 use super::type_names::compute_debuginfo_type_name;
19 use super::{CrateDebugContext};
20 use abi;
21 use context::SharedCrateContext;
22
23 use llvm::{self, ValueRef};
24 use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
25                       DICompositeType, DILexicalBlock, DIFlags};
26
27 use rustc::hir::def::CtorKind;
28 use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
29 use rustc::ty::fold::TypeVisitor;
30 use rustc::ty::util::TypeIdHasher;
31 use rustc::ich::Fingerprint;
32 use rustc::ty::Instance;
33 use common::CrateContext;
34 use rustc::ty::{self, AdtKind, Ty};
35 use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout};
36 use rustc::session::{Session, config};
37 use rustc::util::nodemap::FxHashMap;
38 use rustc::util::common::path2cstr;
39
40 use libc::{c_uint, c_longlong};
41 use std::ffi::CString;
42 use std::fmt::Write;
43 use std::ptr;
44 use std::path::{Path, PathBuf};
45 use syntax::{ast, attr};
46 use syntax::symbol::{Interner, InternedString, Symbol};
47 use syntax_pos::{self, Span, FileName};
48
49
50 // From DWARF 5.
51 // See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1
52 const DW_LANG_RUST: c_uint = 0x1c;
53 #[allow(non_upper_case_globals)]
54 const DW_ATE_boolean: c_uint = 0x02;
55 #[allow(non_upper_case_globals)]
56 const DW_ATE_float: c_uint = 0x04;
57 #[allow(non_upper_case_globals)]
58 const DW_ATE_signed: c_uint = 0x05;
59 #[allow(non_upper_case_globals)]
60 const DW_ATE_unsigned: c_uint = 0x07;
61 #[allow(non_upper_case_globals)]
62 const DW_ATE_unsigned_char: c_uint = 0x08;
63
64 pub const UNKNOWN_LINE_NUMBER: c_uint = 0;
65 pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
66
67 // ptr::null() doesn't work :(
68 pub const NO_SCOPE_METADATA: DIScope = (0 as DIScope);
69
70 #[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
71 pub struct UniqueTypeId(ast::Name);
72
73 // The TypeMap is where the CrateDebugContext holds the type metadata nodes
74 // created so far. The metadata nodes are indexed by UniqueTypeId, and, for
75 // faster lookup, also by Ty. The TypeMap is responsible for creating
76 // UniqueTypeIds.
77 pub struct TypeMap<'tcx> {
78     // The UniqueTypeIds created so far
79     unique_id_interner: Interner,
80     // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
81     unique_id_to_metadata: FxHashMap<UniqueTypeId, DIType>,
82     // A map from types to debuginfo metadata. This is a N:1 mapping.
83     type_to_metadata: FxHashMap<Ty<'tcx>, DIType>,
84     // A map from types to UniqueTypeId. This is a N:1 mapping.
85     type_to_unique_id: FxHashMap<Ty<'tcx>, UniqueTypeId>
86 }
87
88 impl<'tcx> TypeMap<'tcx> {
89     pub fn new() -> TypeMap<'tcx> {
90         TypeMap {
91             unique_id_interner: Interner::new(),
92             type_to_metadata: FxHashMap(),
93             unique_id_to_metadata: FxHashMap(),
94             type_to_unique_id: FxHashMap(),
95         }
96     }
97
98     // Adds a Ty to metadata mapping to the TypeMap. The method will fail if
99     // the mapping already exists.
100     fn register_type_with_metadata<'a>(&mut self,
101                                        type_: Ty<'tcx>,
102                                        metadata: DIType) {
103         if self.type_to_metadata.insert(type_, metadata).is_some() {
104             bug!("Type metadata for Ty '{}' is already in the TypeMap!", type_);
105         }
106     }
107
108     // Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
109     // fail if the mapping already exists.
110     fn register_unique_id_with_metadata(&mut self,
111                                         unique_type_id: UniqueTypeId,
112                                         metadata: DIType) {
113         if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
114             bug!("Type metadata for unique id '{}' is already in the TypeMap!",
115                  self.get_unique_type_id_as_string(unique_type_id));
116         }
117     }
118
119     fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<DIType> {
120         self.type_to_metadata.get(&type_).cloned()
121     }
122
123     fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<DIType> {
124         self.unique_id_to_metadata.get(&unique_type_id).cloned()
125     }
126
127     // Get the string representation of a UniqueTypeId. This method will fail if
128     // the id is unknown.
129     fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> &str {
130         let UniqueTypeId(interner_key) = unique_type_id;
131         self.unique_id_interner.get(interner_key)
132     }
133
134     // Get the UniqueTypeId for the given type. If the UniqueTypeId for the given
135     // type has been requested before, this is just a table lookup. Otherwise an
136     // ID will be generated and stored for later lookup.
137     fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
138                                       type_: Ty<'tcx>) -> UniqueTypeId {
139         // Let's see if we already have something in the cache
140         match self.type_to_unique_id.get(&type_).cloned() {
141             Some(unique_type_id) => return unique_type_id,
142             None => { /* generate one */}
143         };
144
145         // The hasher we are using to generate the UniqueTypeId. We want
146         // something that provides more than the 64 bits of the DefaultHasher.
147         let mut type_id_hasher = TypeIdHasher::<Fingerprint>::new(cx.tcx());
148         type_id_hasher.visit_ty(type_);
149         let unique_type_id = type_id_hasher.finish().to_hex();
150
151         let key = self.unique_id_interner.intern(&unique_type_id);
152         self.type_to_unique_id.insert(type_, UniqueTypeId(key));
153
154         return UniqueTypeId(key);
155     }
156
157     // Get the UniqueTypeId for an enum variant. Enum variants are not really
158     // types of their own, so they need special handling. We still need a
159     // UniqueTypeId for them, since to debuginfo they *are* real types.
160     fn get_unique_type_id_of_enum_variant<'a>(&mut self,
161                                               cx: &CrateContext<'a, 'tcx>,
162                                               enum_type: Ty<'tcx>,
163                                               variant_name: &str)
164                                               -> UniqueTypeId {
165         let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
166         let enum_variant_type_id = format!("{}::{}",
167                                            self.get_unique_type_id_as_string(enum_type_id),
168                                            variant_name);
169         let interner_key = self.unique_id_interner.intern(&enum_variant_type_id);
170         UniqueTypeId(interner_key)
171     }
172 }
173
174 // A description of some recursive type. It can either be already finished (as
175 // with FinalMetadata) or it is not yet finished, but contains all information
176 // needed to generate the missing parts of the description. See the
177 // documentation section on Recursive Types at the top of this file for more
178 // information.
179 enum RecursiveTypeDescription<'tcx> {
180     UnfinishedMetadata {
181         unfinished_type: Ty<'tcx>,
182         unique_type_id: UniqueTypeId,
183         metadata_stub: DICompositeType,
184         member_description_factory: MemberDescriptionFactory<'tcx>,
185     },
186     FinalMetadata(DICompositeType)
187 }
188
189 fn create_and_register_recursive_type_forward_declaration<'a, 'tcx>(
190     cx: &CrateContext<'a, 'tcx>,
191     unfinished_type: Ty<'tcx>,
192     unique_type_id: UniqueTypeId,
193     metadata_stub: DICompositeType,
194     member_description_factory: MemberDescriptionFactory<'tcx>)
195  -> RecursiveTypeDescription<'tcx> {
196
197     // Insert the stub into the TypeMap in order to allow for recursive references
198     let mut type_map = debug_context(cx).type_map.borrow_mut();
199     type_map.register_unique_id_with_metadata(unique_type_id, metadata_stub);
200     type_map.register_type_with_metadata(unfinished_type, metadata_stub);
201
202     UnfinishedMetadata {
203         unfinished_type,
204         unique_type_id,
205         metadata_stub,
206         member_description_factory,
207     }
208 }
209
210 impl<'tcx> RecursiveTypeDescription<'tcx> {
211     // Finishes up the description of the type in question (mostly by providing
212     // descriptions of the fields of the given type) and returns the final type
213     // metadata.
214     fn finalize<'a>(&self, cx: &CrateContext<'a, 'tcx>) -> MetadataCreationResult {
215         match *self {
216             FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
217             UnfinishedMetadata {
218                 unfinished_type,
219                 unique_type_id,
220                 metadata_stub,
221                 ref member_description_factory,
222             } => {
223                 // Make sure that we have a forward declaration of the type in
224                 // the TypeMap so that recursive references are possible. This
225                 // will always be the case if the RecursiveTypeDescription has
226                 // been properly created through the
227                 // create_and_register_recursive_type_forward_declaration()
228                 // function.
229                 {
230                     let type_map = debug_context(cx).type_map.borrow();
231                     if type_map.find_metadata_for_unique_id(unique_type_id).is_none() ||
232                        type_map.find_metadata_for_type(unfinished_type).is_none() {
233                         bug!("Forward declaration of potentially recursive type \
234                               '{:?}' was not found in TypeMap!",
235                              unfinished_type);
236                     }
237                 }
238
239                 // ... then create the member descriptions ...
240                 let member_descriptions =
241                     member_description_factory.create_member_descriptions(cx);
242
243                 // ... and attach them to the stub to complete it.
244                 set_members_of_composite_type(cx,
245                                               metadata_stub,
246                                               &member_descriptions[..]);
247                 return MetadataCreationResult::new(metadata_stub, true);
248             }
249         }
250     }
251 }
252
253 // Returns from the enclosing function if the type metadata with the given
254 // unique id can be found in the type map
255 macro_rules! return_if_metadata_created_in_meantime {
256     ($cx: expr, $unique_type_id: expr) => (
257         match debug_context($cx).type_map
258                                 .borrow()
259                                 .find_metadata_for_unique_id($unique_type_id) {
260             Some(metadata) => return MetadataCreationResult::new(metadata, true),
261             None => { /* proceed normally */ }
262         }
263     )
264 }
265
266 fn fixed_vec_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
267                                 unique_type_id: UniqueTypeId,
268                                 array_or_slice_type: Ty<'tcx>,
269                                 element_type: Ty<'tcx>,
270                                 span: Span)
271                                 -> MetadataCreationResult {
272     let element_type_metadata = type_metadata(cx, element_type, span);
273
274     return_if_metadata_created_in_meantime!(cx, unique_type_id);
275
276     let (size, align) = cx.size_and_align_of(array_or_slice_type);
277
278     let upper_bound = match array_or_slice_type.sty {
279         ty::TyArray(_, len) => {
280             len.val.to_const_int().unwrap().to_u64().unwrap() as c_longlong
281         }
282         _ => -1
283     };
284
285     let subrange = unsafe {
286         llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)
287     };
288
289     let subscripts = create_DIArray(DIB(cx), &[subrange]);
290     let metadata = unsafe {
291         llvm::LLVMRustDIBuilderCreateArrayType(
292             DIB(cx),
293             size.bits(),
294             align.abi_bits() as u32,
295             element_type_metadata,
296             subscripts)
297     };
298
299     return MetadataCreationResult::new(metadata, false);
300 }
301
302 fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
303                                 slice_ptr_type: Ty<'tcx>,
304                                 element_type: Ty<'tcx>,
305                                 unique_type_id: UniqueTypeId,
306                                 span: Span)
307                                 -> MetadataCreationResult {
308     let data_ptr_type = cx.tcx().mk_imm_ptr(element_type);
309
310     let data_ptr_metadata = type_metadata(cx, data_ptr_type, span);
311
312     return_if_metadata_created_in_meantime!(cx, unique_type_id);
313
314     let slice_type_name = compute_debuginfo_type_name(cx, slice_ptr_type, true);
315
316     let (pointer_size, pointer_align) = cx.size_and_align_of(data_ptr_type);
317     let (usize_size, usize_align) = cx.size_and_align_of(cx.tcx().types.usize);
318
319     let member_descriptions = [
320         MemberDescription {
321             name: "data_ptr".to_string(),
322             type_metadata: data_ptr_metadata,
323             offset: Size::from_bytes(0),
324             size: pointer_size,
325             align: pointer_align,
326             flags: DIFlags::FlagZero,
327         },
328         MemberDescription {
329             name: "length".to_string(),
330             type_metadata: type_metadata(cx, cx.tcx().types.usize, span),
331             offset: pointer_size,
332             size: usize_size,
333             align: usize_align,
334             flags: DIFlags::FlagZero,
335         },
336     ];
337
338     let file_metadata = unknown_file_metadata(cx);
339
340     let metadata = composite_type_metadata(cx,
341                                            slice_ptr_type,
342                                            &slice_type_name[..],
343                                            unique_type_id,
344                                            &member_descriptions,
345                                            NO_SCOPE_METADATA,
346                                            file_metadata,
347                                            span);
348     MetadataCreationResult::new(metadata, false)
349 }
350
351 fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
352                                       unique_type_id: UniqueTypeId,
353                                       signature: ty::PolyFnSig<'tcx>,
354                                       span: Span)
355                                       -> MetadataCreationResult
356 {
357     let signature = cx.tcx().erase_late_bound_regions_and_normalize(&signature);
358
359     let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs().len() + 1);
360
361     // return type
362     signature_metadata.push(match signature.output().sty {
363         ty::TyTuple(ref tys, _) if tys.is_empty() => ptr::null_mut(),
364         _ => type_metadata(cx, signature.output(), span)
365     });
366
367     // regular arguments
368     for &argument_type in signature.inputs() {
369         signature_metadata.push(type_metadata(cx, argument_type, span));
370     }
371
372     return_if_metadata_created_in_meantime!(cx, unique_type_id);
373
374     return MetadataCreationResult::new(
375         unsafe {
376             llvm::LLVMRustDIBuilderCreateSubroutineType(
377                 DIB(cx),
378                 unknown_file_metadata(cx),
379                 create_DIArray(DIB(cx), &signature_metadata[..]))
380         },
381         false);
382 }
383
384 // FIXME(1563) This is all a bit of a hack because 'trait pointer' is an ill-
385 // defined concept. For the case of an actual trait pointer (i.e., Box<Trait>,
386 // &Trait), trait_object_type should be the whole thing (e.g, Box<Trait>) and
387 // trait_type should be the actual trait (e.g., Trait). Where the trait is part
388 // of a DST struct, there is no trait_object_type and the results of this
389 // function will be a little bit weird.
390 fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
391                                     trait_type: Ty<'tcx>,
392                                     trait_object_type: Option<Ty<'tcx>>,
393                                     unique_type_id: UniqueTypeId)
394                                     -> DIType {
395     // The implementation provided here is a stub. It makes sure that the trait
396     // type is assigned the correct name, size, namespace, and source location.
397     // But it does not describe the trait's methods.
398
399     let containing_scope = match trait_type.sty {
400         ty::TyDynamic(ref data, ..) => if let Some(principal) = data.principal() {
401             let def_id = principal.def_id();
402             get_namespace_for_item(cx, def_id)
403         } else {
404             NO_SCOPE_METADATA
405         },
406         _ => {
407             bug!("debuginfo: Unexpected trait-object type in \
408                   trait_pointer_metadata(): {:?}",
409                  trait_type);
410         }
411     };
412
413     let trait_object_type = trait_object_type.unwrap_or(trait_type);
414     let trait_type_name =
415         compute_debuginfo_type_name(cx, trait_object_type, false);
416
417     let file_metadata = unknown_file_metadata(cx);
418
419     let layout = cx.layout_of(cx.tcx().mk_mut_ptr(trait_type));
420
421     assert_eq!(abi::FAT_PTR_ADDR, 0);
422     assert_eq!(abi::FAT_PTR_EXTRA, 1);
423
424     let data_ptr_field = layout.field(cx, 0);
425     let vtable_field = layout.field(cx, 1);
426     let member_descriptions = [
427         MemberDescription {
428             name: "pointer".to_string(),
429             type_metadata: type_metadata(cx,
430                 cx.tcx().mk_mut_ptr(cx.tcx().types.u8),
431                 syntax_pos::DUMMY_SP),
432             offset: layout.fields.offset(0),
433             size: data_ptr_field.size,
434             align: data_ptr_field.align,
435             flags: DIFlags::FlagArtificial,
436         },
437         MemberDescription {
438             name: "vtable".to_string(),
439             type_metadata: type_metadata(cx, vtable_field.ty, syntax_pos::DUMMY_SP),
440             offset: layout.fields.offset(1),
441             size: vtable_field.size,
442             align: vtable_field.align,
443             flags: DIFlags::FlagArtificial,
444         },
445     ];
446
447     composite_type_metadata(cx,
448                             trait_object_type,
449                             &trait_type_name[..],
450                             unique_type_id,
451                             &member_descriptions,
452                             containing_scope,
453                             file_metadata,
454                             syntax_pos::DUMMY_SP)
455 }
456
457 pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
458                                t: Ty<'tcx>,
459                                usage_site_span: Span)
460                                -> DIType {
461     // Get the unique type id of this type.
462     let unique_type_id = {
463         let mut type_map = debug_context(cx).type_map.borrow_mut();
464         // First, try to find the type in TypeMap. If we have seen it before, we
465         // can exit early here.
466         match type_map.find_metadata_for_type(t) {
467             Some(metadata) => {
468                 return metadata;
469             },
470             None => {
471                 // The Ty is not in the TypeMap but maybe we have already seen
472                 // an equivalent type (e.g. only differing in region arguments).
473                 // In order to find out, generate the unique type id and look
474                 // that up.
475                 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
476                 match type_map.find_metadata_for_unique_id(unique_type_id) {
477                     Some(metadata) => {
478                         // There is already an equivalent type in the TypeMap.
479                         // Register this Ty as an alias in the cache and
480                         // return the cached metadata.
481                         type_map.register_type_with_metadata(t, metadata);
482                         return metadata;
483                     },
484                     None => {
485                         // There really is no type metadata for this type, so
486                         // proceed by creating it.
487                         unique_type_id
488                     }
489                 }
490             }
491         }
492     };
493
494     debug!("type_metadata: {:?}", t);
495
496     let ptr_metadata = |ty: Ty<'tcx>| {
497         match ty.sty {
498             ty::TySlice(typ) => {
499                 Ok(vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span))
500             }
501             ty::TyStr => {
502                 Ok(vec_slice_metadata(cx, t, cx.tcx().types.u8, unique_type_id, usage_site_span))
503             }
504             ty::TyDynamic(..) => {
505                 Ok(MetadataCreationResult::new(
506                     trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
507                     false))
508             }
509             _ => {
510                 let pointee_metadata = type_metadata(cx, ty, usage_site_span);
511
512                 match debug_context(cx).type_map
513                                         .borrow()
514                                         .find_metadata_for_unique_id(unique_type_id) {
515                     Some(metadata) => return Err(metadata),
516                     None => { /* proceed normally */ }
517                 };
518
519                 Ok(MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
520                    false))
521             }
522         }
523     };
524
525     let MetadataCreationResult { metadata, already_stored_in_typemap } = match t.sty {
526         ty::TyNever    |
527         ty::TyBool     |
528         ty::TyChar     |
529         ty::TyInt(_)   |
530         ty::TyUint(_)  |
531         ty::TyFloat(_) => {
532             MetadataCreationResult::new(basic_type_metadata(cx, t), false)
533         }
534         ty::TyTuple(ref elements, _) if elements.is_empty() => {
535             MetadataCreationResult::new(basic_type_metadata(cx, t), false)
536         }
537         ty::TyArray(typ, _) |
538         ty::TySlice(typ) => {
539             fixed_vec_metadata(cx, unique_type_id, t, typ, usage_site_span)
540         }
541         ty::TyStr => {
542             fixed_vec_metadata(cx, unique_type_id, t, cx.tcx().types.i8, usage_site_span)
543         }
544         ty::TyDynamic(..) => {
545             MetadataCreationResult::new(
546                         trait_pointer_metadata(cx, t, None, unique_type_id),
547             false)
548         }
549         ty::TyForeign(..) => {
550             MetadataCreationResult::new(
551                         foreign_type_metadata(cx, t, unique_type_id),
552             false)
553         }
554         ty::TyRawPtr(ty::TypeAndMut{ty, ..}) |
555         ty::TyRef(_, ty::TypeAndMut{ty, ..}) => {
556             match ptr_metadata(ty) {
557                 Ok(res) => res,
558                 Err(metadata) => return metadata,
559             }
560         }
561         ty::TyAdt(def, _) if def.is_box() => {
562             match ptr_metadata(t.boxed_ty()) {
563                 Ok(res) => res,
564                 Err(metadata) => return metadata,
565             }
566         }
567         ty::TyFnDef(..) | ty::TyFnPtr(_) => {
568             let fn_metadata = subroutine_type_metadata(cx,
569                                                        unique_type_id,
570                                                        t.fn_sig(cx.tcx()),
571                                                        usage_site_span).metadata;
572             match debug_context(cx).type_map
573                                    .borrow()
574                                    .find_metadata_for_unique_id(unique_type_id) {
575                 Some(metadata) => return metadata,
576                 None => { /* proceed normally */ }
577             };
578
579             // This is actually a function pointer, so wrap it in pointer DI
580             MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false)
581
582         }
583         ty::TyClosure(def_id, substs) => {
584             let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx()).collect();
585             prepare_tuple_metadata(cx,
586                                    t,
587                                    &upvar_tys,
588                                    unique_type_id,
589                                    usage_site_span).finalize(cx)
590         }
591         ty::TyGenerator(def_id, substs, _) => {
592             let upvar_tys : Vec<_> = substs.field_tys(def_id, cx.tcx()).map(|t| {
593                 cx.tcx().fully_normalize_associated_types_in(&t)
594             }).collect();
595             prepare_tuple_metadata(cx,
596                                    t,
597                                    &upvar_tys,
598                                    unique_type_id,
599                                    usage_site_span).finalize(cx)
600         }
601         ty::TyAdt(def, ..) => match def.adt_kind() {
602             AdtKind::Struct => {
603                 prepare_struct_metadata(cx,
604                                         t,
605                                         unique_type_id,
606                                         usage_site_span).finalize(cx)
607             }
608             AdtKind::Union => {
609                 prepare_union_metadata(cx,
610                                     t,
611                                     unique_type_id,
612                                     usage_site_span).finalize(cx)
613             }
614             AdtKind::Enum => {
615                 prepare_enum_metadata(cx,
616                                     t,
617                                     def.did,
618                                     unique_type_id,
619                                     usage_site_span).finalize(cx)
620             }
621         },
622         ty::TyTuple(ref elements, _) => {
623             prepare_tuple_metadata(cx,
624                                    t,
625                                    &elements[..],
626                                    unique_type_id,
627                                    usage_site_span).finalize(cx)
628         }
629         _ => {
630             bug!("debuginfo: unexpected type in type_metadata: {:?}", t)
631         }
632     };
633
634     {
635         let mut type_map = debug_context(cx).type_map.borrow_mut();
636
637         if already_stored_in_typemap {
638             // Also make sure that we already have a TypeMap entry for the unique type id.
639             let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
640                 Some(metadata) => metadata,
641                 None => {
642                     span_bug!(usage_site_span,
643                               "Expected type metadata for unique \
644                                type id '{}' to already be in \
645                                the debuginfo::TypeMap but it \
646                                was not. (Ty = {})",
647                               type_map.get_unique_type_id_as_string(unique_type_id),
648                               t);
649                 }
650             };
651
652             match type_map.find_metadata_for_type(t) {
653                 Some(metadata) => {
654                     if metadata != metadata_for_uid {
655                         span_bug!(usage_site_span,
656                                   "Mismatch between Ty and \
657                                    UniqueTypeId maps in \
658                                    debuginfo::TypeMap. \
659                                    UniqueTypeId={}, Ty={}",
660                                   type_map.get_unique_type_id_as_string(unique_type_id),
661                                   t);
662                     }
663                 }
664                 None => {
665                     type_map.register_type_with_metadata(t, metadata);
666                 }
667             }
668         } else {
669             type_map.register_type_with_metadata(t, metadata);
670             type_map.register_unique_id_with_metadata(unique_type_id, metadata);
671         }
672     }
673
674     metadata
675 }
676
677 pub fn file_metadata(cx: &CrateContext,
678                      file_name: &FileName,
679                      defining_crate: CrateNum) -> DIFile {
680     debug!("file_metadata: file_name: {}, defining_crate: {}",
681            file_name,
682            defining_crate);
683
684     let directory = if defining_crate == LOCAL_CRATE {
685         &cx.sess().working_dir.0
686     } else {
687         // If the path comes from an upstream crate we assume it has been made
688         // independent of the compiler's working directory one way or another.
689         Path::new("")
690     };
691
692     file_metadata_raw(cx, &file_name.to_string(), &directory.to_string_lossy())
693 }
694
695 pub fn unknown_file_metadata(cx: &CrateContext) -> DIFile {
696     file_metadata_raw(cx, "<unknown>", "")
697 }
698
699 fn file_metadata_raw(cx: &CrateContext,
700                      file_name: &str,
701                      directory: &str)
702                      -> DIFile {
703     let key = (Symbol::intern(file_name), Symbol::intern(directory));
704
705     if let Some(file_metadata) = debug_context(cx).created_files.borrow().get(&key) {
706         return *file_metadata;
707     }
708
709     debug!("file_metadata: file_name: {}, directory: {}", file_name, directory);
710
711     let file_name = CString::new(file_name).unwrap();
712     let directory = CString::new(directory).unwrap();
713
714     let file_metadata = unsafe {
715         llvm::LLVMRustDIBuilderCreateFile(DIB(cx),
716                                           file_name.as_ptr(),
717                                           directory.as_ptr())
718     };
719
720     let mut created_files = debug_context(cx).created_files.borrow_mut();
721     created_files.insert(key, file_metadata);
722     file_metadata
723 }
724
725 fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
726                                  t: Ty<'tcx>) -> DIType {
727
728     debug!("basic_type_metadata: {:?}", t);
729
730     let (name, encoding) = match t.sty {
731         ty::TyNever => ("!", DW_ATE_unsigned),
732         ty::TyTuple(ref elements, _) if elements.is_empty() =>
733             ("()", DW_ATE_unsigned),
734         ty::TyBool => ("bool", DW_ATE_boolean),
735         ty::TyChar => ("char", DW_ATE_unsigned_char),
736         ty::TyInt(int_ty) => {
737             (int_ty.ty_to_string(), DW_ATE_signed)
738         },
739         ty::TyUint(uint_ty) => {
740             (uint_ty.ty_to_string(), DW_ATE_unsigned)
741         },
742         ty::TyFloat(float_ty) => {
743             (float_ty.ty_to_string(), DW_ATE_float)
744         },
745         _ => bug!("debuginfo::basic_type_metadata - t is invalid type")
746     };
747
748     let (size, align) = cx.size_and_align_of(t);
749     let name = CString::new(name).unwrap();
750     let ty_metadata = unsafe {
751         llvm::LLVMRustDIBuilderCreateBasicType(
752             DIB(cx),
753             name.as_ptr(),
754             size.bits(),
755             align.abi_bits() as u32,
756             encoding)
757     };
758
759     return ty_metadata;
760 }
761
762 fn foreign_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
763                                    t: Ty<'tcx>,
764                                    unique_type_id: UniqueTypeId) -> DIType {
765     debug!("foreign_type_metadata: {:?}", t);
766
767     let name = compute_debuginfo_type_name(cx, t, false);
768     create_struct_stub(cx, t, &name, unique_type_id, NO_SCOPE_METADATA)
769 }
770
771 fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
772                                    pointer_type: Ty<'tcx>,
773                                    pointee_type_metadata: DIType)
774                                    -> DIType {
775     let (pointer_size, pointer_align) = cx.size_and_align_of(pointer_type);
776     let name = compute_debuginfo_type_name(cx, pointer_type, false);
777     let name = CString::new(name).unwrap();
778     unsafe {
779         llvm::LLVMRustDIBuilderCreatePointerType(
780             DIB(cx),
781             pointee_type_metadata,
782             pointer_size.bits(),
783             pointer_align.abi_bits() as u32,
784             name.as_ptr())
785     }
786 }
787
788 pub fn compile_unit_metadata(scc: &SharedCrateContext,
789                              codegen_unit_name: &str,
790                              debug_context: &CrateDebugContext,
791                              sess: &Session)
792                              -> DIDescriptor {
793     let mut name_in_debuginfo = match sess.local_crate_source_file {
794         Some(ref path) => path.clone(),
795         None => PathBuf::from(&*scc.tcx().crate_name(LOCAL_CRATE).as_str()),
796     };
797
798     // The OSX linker has an idiosyncrasy where it will ignore some debuginfo
799     // if multiple object files with the same DW_AT_name are linked together.
800     // As a workaround we generate unique names for each object file. Those do
801     // not correspond to an actual source file but that should be harmless.
802     if scc.sess().target.target.options.is_like_osx {
803         name_in_debuginfo.push("@");
804         name_in_debuginfo.push(codegen_unit_name);
805     }
806
807     debug!("compile_unit_metadata: {:?}", name_in_debuginfo);
808     // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
809     let producer = format!("clang LLVM (rustc version {})",
810                            (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
811
812     let name_in_debuginfo = name_in_debuginfo.to_string_lossy().into_owned();
813     let name_in_debuginfo = CString::new(name_in_debuginfo).unwrap();
814     let work_dir = CString::new(&sess.working_dir.0.to_string_lossy()[..]).unwrap();
815     let producer = CString::new(producer).unwrap();
816     let flags = "\0";
817     let split_name = "\0";
818
819     unsafe {
820         let file_metadata = llvm::LLVMRustDIBuilderCreateFile(
821             debug_context.builder, name_in_debuginfo.as_ptr(), work_dir.as_ptr());
822
823         let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
824             debug_context.builder,
825             DW_LANG_RUST,
826             file_metadata,
827             producer.as_ptr(),
828             sess.opts.optimize != config::OptLevel::No,
829             flags.as_ptr() as *const _,
830             0,
831             split_name.as_ptr() as *const _);
832
833         if sess.opts.debugging_opts.profile {
834             let cu_desc_metadata = llvm::LLVMRustMetadataAsValue(debug_context.llcontext,
835                                                                  unit_metadata);
836
837             let gcov_cu_info = [
838                 path_to_mdstring(debug_context.llcontext,
839                                  &scc.tcx().output_filenames(LOCAL_CRATE).with_extension("gcno")),
840                 path_to_mdstring(debug_context.llcontext,
841                                  &scc.tcx().output_filenames(LOCAL_CRATE).with_extension("gcda")),
842                 cu_desc_metadata,
843             ];
844             let gcov_metadata = llvm::LLVMMDNodeInContext(debug_context.llcontext,
845                                                           gcov_cu_info.as_ptr(),
846                                                           gcov_cu_info.len() as c_uint);
847
848             let llvm_gcov_ident = CString::new("llvm.gcov").unwrap();
849             llvm::LLVMAddNamedMetadataOperand(debug_context.llmod,
850                                               llvm_gcov_ident.as_ptr(),
851                                               gcov_metadata);
852         }
853
854         return unit_metadata;
855     };
856
857     fn path_to_mdstring(llcx: llvm::ContextRef, path: &Path) -> llvm::ValueRef {
858         let path_str = path2cstr(path);
859         unsafe {
860             llvm::LLVMMDStringInContext(llcx,
861                                         path_str.as_ptr(),
862                                         path_str.as_bytes().len() as c_uint)
863         }
864     }
865 }
866
867 struct MetadataCreationResult {
868     metadata: DIType,
869     already_stored_in_typemap: bool
870 }
871
872 impl MetadataCreationResult {
873     fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationResult {
874         MetadataCreationResult {
875             metadata,
876             already_stored_in_typemap,
877         }
878     }
879 }
880
881 // Description of a type member, which can either be a regular field (as in
882 // structs or tuples) or an enum variant.
883 #[derive(Debug)]
884 struct MemberDescription {
885     name: String,
886     type_metadata: DIType,
887     offset: Size,
888     size: Size,
889     align: Align,
890     flags: DIFlags,
891 }
892
893 // A factory for MemberDescriptions. It produces a list of member descriptions
894 // for some record-like type. MemberDescriptionFactories are used to defer the
895 // creation of type member descriptions in order to break cycles arising from
896 // recursive type definitions.
897 enum MemberDescriptionFactory<'tcx> {
898     StructMDF(StructMemberDescriptionFactory<'tcx>),
899     TupleMDF(TupleMemberDescriptionFactory<'tcx>),
900     EnumMDF(EnumMemberDescriptionFactory<'tcx>),
901     UnionMDF(UnionMemberDescriptionFactory<'tcx>),
902     VariantMDF(VariantMemberDescriptionFactory<'tcx>)
903 }
904
905 impl<'tcx> MemberDescriptionFactory<'tcx> {
906     fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
907                                       -> Vec<MemberDescription> {
908         match *self {
909             StructMDF(ref this) => {
910                 this.create_member_descriptions(cx)
911             }
912             TupleMDF(ref this) => {
913                 this.create_member_descriptions(cx)
914             }
915             EnumMDF(ref this) => {
916                 this.create_member_descriptions(cx)
917             }
918             UnionMDF(ref this) => {
919                 this.create_member_descriptions(cx)
920             }
921             VariantMDF(ref this) => {
922                 this.create_member_descriptions(cx)
923             }
924         }
925     }
926 }
927
928 //=-----------------------------------------------------------------------------
929 // Structs
930 //=-----------------------------------------------------------------------------
931
932 // Creates MemberDescriptions for the fields of a struct
933 struct StructMemberDescriptionFactory<'tcx> {
934     ty: Ty<'tcx>,
935     variant: &'tcx ty::VariantDef,
936     span: Span,
937 }
938
939 impl<'tcx> StructMemberDescriptionFactory<'tcx> {
940     fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
941                                       -> Vec<MemberDescription> {
942         let layout = cx.layout_of(self.ty);
943         self.variant.fields.iter().enumerate().map(|(i, f)| {
944             let name = if self.variant.ctor_kind == CtorKind::Fn {
945                 format!("__{}", i)
946             } else {
947                 f.name.to_string()
948             };
949             let field = layout.field(cx, i);
950             let (size, align) = field.size_and_align();
951             MemberDescription {
952                 name,
953                 type_metadata: type_metadata(cx, field.ty, self.span),
954                 offset: layout.fields.offset(i),
955                 size,
956                 align,
957                 flags: DIFlags::FlagZero,
958             }
959         }).collect()
960     }
961 }
962
963
964 fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
965                                      struct_type: Ty<'tcx>,
966                                      unique_type_id: UniqueTypeId,
967                                      span: Span)
968                                      -> RecursiveTypeDescription<'tcx> {
969     let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
970
971     let (struct_def_id, variant) = match struct_type.sty {
972         ty::TyAdt(def, _) => (def.did, def.struct_variant()),
973         _ => bug!("prepare_struct_metadata on a non-ADT")
974     };
975
976     let containing_scope = get_namespace_for_item(cx, struct_def_id);
977
978     let struct_metadata_stub = create_struct_stub(cx,
979                                                   struct_type,
980                                                   &struct_name,
981                                                   unique_type_id,
982                                                   containing_scope);
983
984     create_and_register_recursive_type_forward_declaration(
985         cx,
986         struct_type,
987         unique_type_id,
988         struct_metadata_stub,
989         StructMDF(StructMemberDescriptionFactory {
990             ty: struct_type,
991             variant,
992             span,
993         })
994     )
995 }
996
997 //=-----------------------------------------------------------------------------
998 // Tuples
999 //=-----------------------------------------------------------------------------
1000
1001 // Creates MemberDescriptions for the fields of a tuple
1002 struct TupleMemberDescriptionFactory<'tcx> {
1003     ty: Ty<'tcx>,
1004     component_types: Vec<Ty<'tcx>>,
1005     span: Span,
1006 }
1007
1008 impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
1009     fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1010                                       -> Vec<MemberDescription> {
1011         let layout = cx.layout_of(self.ty);
1012         self.component_types.iter().enumerate().map(|(i, &component_type)| {
1013             let (size, align) = cx.size_and_align_of(component_type);
1014             MemberDescription {
1015                 name: format!("__{}", i),
1016                 type_metadata: type_metadata(cx, component_type, self.span),
1017                 offset: layout.fields.offset(i),
1018                 size,
1019                 align,
1020                 flags: DIFlags::FlagZero,
1021             }
1022         }).collect()
1023     }
1024 }
1025
1026 fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1027                                     tuple_type: Ty<'tcx>,
1028                                     component_types: &[Ty<'tcx>],
1029                                     unique_type_id: UniqueTypeId,
1030                                     span: Span)
1031                                     -> RecursiveTypeDescription<'tcx> {
1032     let tuple_name = compute_debuginfo_type_name(cx, tuple_type, false);
1033
1034     create_and_register_recursive_type_forward_declaration(
1035         cx,
1036         tuple_type,
1037         unique_type_id,
1038         create_struct_stub(cx,
1039                            tuple_type,
1040                            &tuple_name[..],
1041                            unique_type_id,
1042                            NO_SCOPE_METADATA),
1043         TupleMDF(TupleMemberDescriptionFactory {
1044             ty: tuple_type,
1045             component_types: component_types.to_vec(),
1046             span,
1047         })
1048     )
1049 }
1050
1051 //=-----------------------------------------------------------------------------
1052 // Unions
1053 //=-----------------------------------------------------------------------------
1054
1055 struct UnionMemberDescriptionFactory<'tcx> {
1056     layout: TyLayout<'tcx>,
1057     variant: &'tcx ty::VariantDef,
1058     span: Span,
1059 }
1060
1061 impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
1062     fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1063                                       -> Vec<MemberDescription> {
1064         self.variant.fields.iter().enumerate().map(|(i, f)| {
1065             let field = self.layout.field(cx, i);
1066             let (size, align) = field.size_and_align();
1067             MemberDescription {
1068                 name: f.name.to_string(),
1069                 type_metadata: type_metadata(cx, field.ty, self.span),
1070                 offset: Size::from_bytes(0),
1071                 size,
1072                 align,
1073                 flags: DIFlags::FlagZero,
1074             }
1075         }).collect()
1076     }
1077 }
1078
1079 fn prepare_union_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1080                                     union_type: Ty<'tcx>,
1081                                     unique_type_id: UniqueTypeId,
1082                                     span: Span)
1083                                     -> RecursiveTypeDescription<'tcx> {
1084     let union_name = compute_debuginfo_type_name(cx, union_type, false);
1085
1086     let (union_def_id, variant) = match union_type.sty {
1087         ty::TyAdt(def, _) => (def.did, def.struct_variant()),
1088         _ => bug!("prepare_union_metadata on a non-ADT")
1089     };
1090
1091     let containing_scope = get_namespace_for_item(cx, union_def_id);
1092
1093     let union_metadata_stub = create_union_stub(cx,
1094                                                 union_type,
1095                                                 &union_name,
1096                                                 unique_type_id,
1097                                                 containing_scope);
1098
1099     create_and_register_recursive_type_forward_declaration(
1100         cx,
1101         union_type,
1102         unique_type_id,
1103         union_metadata_stub,
1104         UnionMDF(UnionMemberDescriptionFactory {
1105             layout: cx.layout_of(union_type),
1106             variant,
1107             span,
1108         })
1109     )
1110 }
1111
1112 //=-----------------------------------------------------------------------------
1113 // Enums
1114 //=-----------------------------------------------------------------------------
1115
1116 // Describes the members of an enum value: An enum is described as a union of
1117 // structs in DWARF. This MemberDescriptionFactory provides the description for
1118 // the members of this union; so for every variant of the given enum, this
1119 // factory will produce one MemberDescription (all with no name and a fixed
1120 // offset of zero bytes).
1121 struct EnumMemberDescriptionFactory<'tcx> {
1122     enum_type: Ty<'tcx>,
1123     layout: TyLayout<'tcx>,
1124     discriminant_type_metadata: Option<DIType>,
1125     containing_scope: DIScope,
1126     span: Span,
1127 }
1128
1129 impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
1130     fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1131                                       -> Vec<MemberDescription> {
1132         let adt = &self.enum_type.ty_adt_def().unwrap();
1133         match self.layout.variants {
1134             layout::Variants::Single { .. } if adt.variants.is_empty() => vec![],
1135             layout::Variants::Single { index } => {
1136                 let (variant_type_metadata, member_description_factory) =
1137                     describe_enum_variant(cx,
1138                                           self.layout,
1139                                           &adt.variants[index],
1140                                           NoDiscriminant,
1141                                           self.containing_scope,
1142                                           self.span);
1143
1144                 let member_descriptions =
1145                     member_description_factory.create_member_descriptions(cx);
1146
1147                 set_members_of_composite_type(cx,
1148                                               variant_type_metadata,
1149                                               &member_descriptions[..]);
1150                 vec![
1151                     MemberDescription {
1152                         name: "".to_string(),
1153                         type_metadata: variant_type_metadata,
1154                         offset: Size::from_bytes(0),
1155                         size: self.layout.size,
1156                         align: self.layout.align,
1157                         flags: DIFlags::FlagZero
1158                     }
1159                 ]
1160             }
1161             layout::Variants::Tagged { ref variants, .. } => {
1162                 let discriminant_info = RegularDiscriminant(self.discriminant_type_metadata
1163                     .expect(""));
1164                 (0..variants.len()).map(|i| {
1165                     let variant = self.layout.for_variant(cx, i);
1166                     let (variant_type_metadata, member_desc_factory) =
1167                         describe_enum_variant(cx,
1168                                               variant,
1169                                               &adt.variants[i],
1170                                               discriminant_info,
1171                                               self.containing_scope,
1172                                               self.span);
1173
1174                     let member_descriptions = member_desc_factory
1175                         .create_member_descriptions(cx);
1176
1177                     set_members_of_composite_type(cx,
1178                                                   variant_type_metadata,
1179                                                   &member_descriptions);
1180                     MemberDescription {
1181                         name: "".to_string(),
1182                         type_metadata: variant_type_metadata,
1183                         offset: Size::from_bytes(0),
1184                         size: variant.size,
1185                         align: variant.align,
1186                         flags: DIFlags::FlagZero
1187                     }
1188                 }).collect()
1189             }
1190             layout::Variants::NicheFilling { dataful_variant, ref niche_variants, .. } => {
1191                 let variant = self.layout.for_variant(cx, dataful_variant);
1192                 // Create a description of the non-null variant
1193                 let (variant_type_metadata, member_description_factory) =
1194                     describe_enum_variant(cx,
1195                                           variant,
1196                                           &adt.variants[dataful_variant],
1197                                           OptimizedDiscriminant,
1198                                           self.containing_scope,
1199                                           self.span);
1200
1201                 let variant_member_descriptions =
1202                     member_description_factory.create_member_descriptions(cx);
1203
1204                 set_members_of_composite_type(cx,
1205                                               variant_type_metadata,
1206                                               &variant_member_descriptions[..]);
1207
1208                 // Encode the information about the null variant in the union
1209                 // member's name.
1210                 let mut name = String::from("RUST$ENCODED$ENUM$");
1211                 // HACK(eddyb) the debuggers should just handle offset+size
1212                 // of discriminant instead of us having to recover its path.
1213                 // Right now it's not even going to work for `niche_start > 0`,
1214                 // and for multiple niche variants it only supports the first.
1215                 fn compute_field_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1216                                                 name: &mut String,
1217                                                 layout: TyLayout<'tcx>,
1218                                                 offset: Size,
1219                                                 size: Size) {
1220                     for i in 0..layout.fields.count() {
1221                         let field_offset = layout.fields.offset(i);
1222                         if field_offset > offset {
1223                             continue;
1224                         }
1225                         let inner_offset = offset - field_offset;
1226                         let field = layout.field(ccx, i);
1227                         if inner_offset + size <= field.size {
1228                             write!(name, "{}$", i).unwrap();
1229                             compute_field_path(ccx, name, field, inner_offset, size);
1230                         }
1231                     }
1232                 }
1233                 compute_field_path(cx, &mut name,
1234                                    self.layout,
1235                                    self.layout.fields.offset(0),
1236                                    self.layout.field(cx, 0).size);
1237                 name.push_str(&adt.variants[niche_variants.start].name.as_str());
1238
1239                 // Create the (singleton) list of descriptions of union members.
1240                 vec![
1241                     MemberDescription {
1242                         name,
1243                         type_metadata: variant_type_metadata,
1244                         offset: Size::from_bytes(0),
1245                         size: variant.size,
1246                         align: variant.align,
1247                         flags: DIFlags::FlagZero
1248                     }
1249                 ]
1250             }
1251         }
1252     }
1253 }
1254
1255 // Creates MemberDescriptions for the fields of a single enum variant.
1256 struct VariantMemberDescriptionFactory<'tcx> {
1257     // Cloned from the layout::Struct describing the variant.
1258     offsets: Vec<layout::Size>,
1259     args: Vec<(String, Ty<'tcx>)>,
1260     discriminant_type_metadata: Option<DIType>,
1261     span: Span,
1262 }
1263
1264 impl<'tcx> VariantMemberDescriptionFactory<'tcx> {
1265     fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1266                                       -> Vec<MemberDescription> {
1267         self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
1268             let (size, align) = cx.size_and_align_of(ty);
1269             MemberDescription {
1270                 name: name.to_string(),
1271                 type_metadata: match self.discriminant_type_metadata {
1272                     Some(metadata) if i == 0 => metadata,
1273                     _ => type_metadata(cx, ty, self.span)
1274                 },
1275                 offset: self.offsets[i],
1276                 size,
1277                 align,
1278                 flags: DIFlags::FlagZero
1279             }
1280         }).collect()
1281     }
1282 }
1283
1284 #[derive(Copy, Clone)]
1285 enum EnumDiscriminantInfo {
1286     RegularDiscriminant(DIType),
1287     OptimizedDiscriminant,
1288     NoDiscriminant
1289 }
1290
1291 // Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type
1292 // of the variant, and (3) a MemberDescriptionFactory for producing the
1293 // descriptions of the fields of the variant. This is a rudimentary version of a
1294 // full RecursiveTypeDescription.
1295 fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1296                                    layout: layout::TyLayout<'tcx>,
1297                                    variant: &'tcx ty::VariantDef,
1298                                    discriminant_info: EnumDiscriminantInfo,
1299                                    containing_scope: DIScope,
1300                                    span: Span)
1301                                    -> (DICompositeType, MemberDescriptionFactory<'tcx>) {
1302     let variant_name = variant.name.as_str();
1303     let unique_type_id = debug_context(cx).type_map
1304                                           .borrow_mut()
1305                                           .get_unique_type_id_of_enum_variant(
1306                                               cx,
1307                                               layout.ty,
1308                                               &variant_name);
1309
1310     let metadata_stub = create_struct_stub(cx,
1311                                            layout.ty,
1312                                            &variant_name,
1313                                            unique_type_id,
1314                                            containing_scope);
1315
1316     // If this is not a univariant enum, there is also the discriminant field.
1317     let (discr_offset, discr_arg) = match discriminant_info {
1318         RegularDiscriminant(_) => {
1319             let enum_layout = cx.layout_of(layout.ty);
1320             (Some(enum_layout.fields.offset(0)),
1321              Some(("RUST$ENUM$DISR".to_string(), enum_layout.field(cx, 0).ty)))
1322         }
1323         _ => (None, None),
1324     };
1325     let offsets = discr_offset.into_iter().chain((0..layout.fields.count()).map(|i| {
1326         layout.fields.offset(i)
1327     })).collect();
1328
1329     // Build an array of (field name, field type) pairs to be captured in the factory closure.
1330     let args = discr_arg.into_iter().chain((0..layout.fields.count()).map(|i| {
1331         let name = if variant.ctor_kind == CtorKind::Fn {
1332             format!("__{}", i)
1333         } else {
1334             variant.fields[i].name.to_string()
1335         };
1336         (name, layout.field(cx, i).ty)
1337     })).collect();
1338
1339     let member_description_factory =
1340         VariantMDF(VariantMemberDescriptionFactory {
1341             offsets,
1342             args,
1343             discriminant_type_metadata: match discriminant_info {
1344                 RegularDiscriminant(discriminant_type_metadata) => {
1345                     Some(discriminant_type_metadata)
1346                 }
1347                 _ => None
1348             },
1349             span,
1350         });
1351
1352     (metadata_stub, member_description_factory)
1353 }
1354
1355 fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1356                                    enum_type: Ty<'tcx>,
1357                                    enum_def_id: DefId,
1358                                    unique_type_id: UniqueTypeId,
1359                                    span: Span)
1360                                    -> RecursiveTypeDescription<'tcx> {
1361     let enum_name = compute_debuginfo_type_name(cx, enum_type, false);
1362
1363     let containing_scope = get_namespace_for_item(cx, enum_def_id);
1364     // FIXME: This should emit actual file metadata for the enum, but we
1365     // currently can't get the necessary information when it comes to types
1366     // imported from other crates. Formerly we violated the ODR when performing
1367     // LTO because we emitted debuginfo for the same type with varying file
1368     // metadata, so as a workaround we pretend that the type comes from
1369     // <unknown>
1370     let file_metadata = unknown_file_metadata(cx);
1371
1372     let def = enum_type.ty_adt_def().unwrap();
1373     let enumerators_metadata: Vec<DIDescriptor> = def.discriminants(cx.tcx())
1374         .zip(&def.variants)
1375         .map(|(discr, v)| {
1376             let token = v.name.as_str();
1377             let name = CString::new(token.as_bytes()).unwrap();
1378             unsafe {
1379                 llvm::LLVMRustDIBuilderCreateEnumerator(
1380                     DIB(cx),
1381                     name.as_ptr(),
1382                     // FIXME: what if enumeration has i128 discriminant?
1383                     discr.to_u128_unchecked() as u64)
1384             }
1385         })
1386         .collect();
1387
1388     let discriminant_type_metadata = |discr: layout::Primitive| {
1389         let disr_type_key = (enum_def_id, discr);
1390         let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
1391                                                                  .borrow()
1392                                                                  .get(&disr_type_key).cloned();
1393         match cached_discriminant_type_metadata {
1394             Some(discriminant_type_metadata) => discriminant_type_metadata,
1395             None => {
1396                 let (discriminant_size, discriminant_align) =
1397                     (discr.size(cx), discr.align(cx));
1398                 let discriminant_base_type_metadata =
1399                     type_metadata(cx, discr.to_ty(cx.tcx()), syntax_pos::DUMMY_SP);
1400                 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
1401
1402                 let name = CString::new(discriminant_name.as_bytes()).unwrap();
1403                 let discriminant_type_metadata = unsafe {
1404                     llvm::LLVMRustDIBuilderCreateEnumerationType(
1405                         DIB(cx),
1406                         containing_scope,
1407                         name.as_ptr(),
1408                         file_metadata,
1409                         UNKNOWN_LINE_NUMBER,
1410                         discriminant_size.bits(),
1411                         discriminant_align.abi_bits() as u32,
1412                         create_DIArray(DIB(cx), &enumerators_metadata),
1413                         discriminant_base_type_metadata)
1414                 };
1415
1416                 debug_context(cx).created_enum_disr_types
1417                                  .borrow_mut()
1418                                  .insert(disr_type_key, discriminant_type_metadata);
1419
1420                 discriminant_type_metadata
1421             }
1422         }
1423     };
1424
1425     let layout = cx.layout_of(enum_type);
1426
1427     let discriminant_type_metadata = match layout.variants {
1428         layout::Variants::Single { .. } |
1429         layout::Variants::NicheFilling { .. } => None,
1430         layout::Variants::Tagged { ref discr, .. } => {
1431             Some(discriminant_type_metadata(discr.value))
1432         }
1433     };
1434
1435     match (&layout.abi, discriminant_type_metadata) {
1436         (&layout::Abi::Scalar(_), Some(discr)) => return FinalMetadata(discr),
1437         _ => {}
1438     }
1439
1440     let (enum_type_size, enum_type_align) = layout.size_and_align();
1441
1442     let enum_name = CString::new(enum_name).unwrap();
1443     let unique_type_id_str = CString::new(
1444         debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
1445     ).unwrap();
1446     let enum_metadata = unsafe {
1447         llvm::LLVMRustDIBuilderCreateUnionType(
1448         DIB(cx),
1449         containing_scope,
1450         enum_name.as_ptr(),
1451         file_metadata,
1452         UNKNOWN_LINE_NUMBER,
1453         enum_type_size.bits(),
1454         enum_type_align.abi_bits() as u32,
1455         DIFlags::FlagZero,
1456         ptr::null_mut(),
1457         0, // RuntimeLang
1458         unique_type_id_str.as_ptr())
1459     };
1460
1461     return create_and_register_recursive_type_forward_declaration(
1462         cx,
1463         enum_type,
1464         unique_type_id,
1465         enum_metadata,
1466         EnumMDF(EnumMemberDescriptionFactory {
1467             enum_type,
1468             layout,
1469             discriminant_type_metadata,
1470             containing_scope,
1471             span,
1472         }),
1473     );
1474
1475     fn get_enum_discriminant_name(cx: &CrateContext,
1476                                   def_id: DefId)
1477                                   -> InternedString {
1478         cx.tcx().item_name(def_id)
1479     }
1480 }
1481
1482 /// Creates debug information for a composite type, that is, anything that
1483 /// results in a LLVM struct.
1484 ///
1485 /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
1486 fn composite_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1487                                      composite_type: Ty<'tcx>,
1488                                      composite_type_name: &str,
1489                                      composite_type_unique_id: UniqueTypeId,
1490                                      member_descriptions: &[MemberDescription],
1491                                      containing_scope: DIScope,
1492
1493                                      // Ignore source location information as long as it
1494                                      // can't be reconstructed for non-local crates.
1495                                      _file_metadata: DIFile,
1496                                      _definition_span: Span)
1497                                      -> DICompositeType {
1498     // Create the (empty) struct metadata node ...
1499     let composite_type_metadata = create_struct_stub(cx,
1500                                                      composite_type,
1501                                                      composite_type_name,
1502                                                      composite_type_unique_id,
1503                                                      containing_scope);
1504     // ... and immediately create and add the member descriptions.
1505     set_members_of_composite_type(cx,
1506                                   composite_type_metadata,
1507                                   member_descriptions);
1508
1509     return composite_type_metadata;
1510 }
1511
1512 fn set_members_of_composite_type(cx: &CrateContext,
1513                                  composite_type_metadata: DICompositeType,
1514                                  member_descriptions: &[MemberDescription]) {
1515     // In some rare cases LLVM metadata uniquing would lead to an existing type
1516     // description being used instead of a new one created in
1517     // create_struct_stub. This would cause a hard to trace assertion in
1518     // DICompositeType::SetTypeArray(). The following check makes sure that we
1519     // get a better error message if this should happen again due to some
1520     // regression.
1521     {
1522         let mut composite_types_completed =
1523             debug_context(cx).composite_types_completed.borrow_mut();
1524         if composite_types_completed.contains(&composite_type_metadata) {
1525             bug!("debuginfo::set_members_of_composite_type() - \
1526                   Already completed forward declaration re-encountered.");
1527         } else {
1528             composite_types_completed.insert(composite_type_metadata);
1529         }
1530     }
1531
1532     let member_metadata: Vec<DIDescriptor> = member_descriptions
1533         .iter()
1534         .map(|member_description| {
1535             let member_name = member_description.name.as_bytes();
1536             let member_name = CString::new(member_name).unwrap();
1537             unsafe {
1538                 llvm::LLVMRustDIBuilderCreateMemberType(
1539                     DIB(cx),
1540                     composite_type_metadata,
1541                     member_name.as_ptr(),
1542                     unknown_file_metadata(cx),
1543                     UNKNOWN_LINE_NUMBER,
1544                     member_description.size.bits(),
1545                     member_description.align.abi_bits() as u32,
1546                     member_description.offset.bits(),
1547                     member_description.flags,
1548                     member_description.type_metadata)
1549             }
1550         })
1551         .collect();
1552
1553     unsafe {
1554         let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
1555         llvm::LLVMRustDICompositeTypeSetTypeArray(
1556             DIB(cx), composite_type_metadata, type_array);
1557     }
1558 }
1559
1560 // A convenience wrapper around LLVMRustDIBuilderCreateStructType(). Does not do
1561 // any caching, does not add any fields to the struct. This can be done later
1562 // with set_members_of_composite_type().
1563 fn create_struct_stub<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1564                                 struct_type: Ty<'tcx>,
1565                                 struct_type_name: &str,
1566                                 unique_type_id: UniqueTypeId,
1567                                 containing_scope: DIScope)
1568                                 -> DICompositeType {
1569     let (struct_size, struct_align) = cx.size_and_align_of(struct_type);
1570
1571     let name = CString::new(struct_type_name).unwrap();
1572     let unique_type_id = CString::new(
1573         debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
1574     ).unwrap();
1575     let metadata_stub = unsafe {
1576         // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
1577         // pointer will lead to hard to trace and debug LLVM assertions
1578         // later on in llvm/lib/IR/Value.cpp.
1579         let empty_array = create_DIArray(DIB(cx), &[]);
1580
1581         llvm::LLVMRustDIBuilderCreateStructType(
1582             DIB(cx),
1583             containing_scope,
1584             name.as_ptr(),
1585             unknown_file_metadata(cx),
1586             UNKNOWN_LINE_NUMBER,
1587             struct_size.bits(),
1588             struct_align.abi_bits() as u32,
1589             DIFlags::FlagZero,
1590             ptr::null_mut(),
1591             empty_array,
1592             0,
1593             ptr::null_mut(),
1594             unique_type_id.as_ptr())
1595     };
1596
1597     return metadata_stub;
1598 }
1599
1600 fn create_union_stub<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1601                                union_type: Ty<'tcx>,
1602                                union_type_name: &str,
1603                                unique_type_id: UniqueTypeId,
1604                                containing_scope: DIScope)
1605                                -> DICompositeType {
1606     let (union_size, union_align) = cx.size_and_align_of(union_type);
1607
1608     let name = CString::new(union_type_name).unwrap();
1609     let unique_type_id = CString::new(
1610         debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
1611     ).unwrap();
1612     let metadata_stub = unsafe {
1613         // LLVMRustDIBuilderCreateUnionType() wants an empty array. A null
1614         // pointer will lead to hard to trace and debug LLVM assertions
1615         // later on in llvm/lib/IR/Value.cpp.
1616         let empty_array = create_DIArray(DIB(cx), &[]);
1617
1618         llvm::LLVMRustDIBuilderCreateUnionType(
1619             DIB(cx),
1620             containing_scope,
1621             name.as_ptr(),
1622             unknown_file_metadata(cx),
1623             UNKNOWN_LINE_NUMBER,
1624             union_size.bits(),
1625             union_align.abi_bits() as u32,
1626             DIFlags::FlagZero,
1627             empty_array,
1628             0, // RuntimeLang
1629             unique_type_id.as_ptr())
1630     };
1631
1632     return metadata_stub;
1633 }
1634
1635 /// Creates debug information for the given global variable.
1636 ///
1637 /// Adds the created metadata nodes directly to the crate's IR.
1638 pub fn create_global_var_metadata(cx: &CrateContext,
1639                                   node_id: ast::NodeId,
1640                                   global: ValueRef) {
1641     if cx.dbg_cx().is_none() {
1642         return;
1643     }
1644
1645     let tcx = cx.tcx();
1646     let node_def_id = tcx.hir.local_def_id(node_id);
1647     let no_mangle = attr::contains_name(&tcx.get_attrs(node_def_id), "no_mangle");
1648     // We may want to remove the namespace scope if we're in an extern block, see:
1649     // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952
1650     let var_scope = get_namespace_for_item(cx, node_def_id);
1651     let span = cx.tcx().def_span(node_def_id);
1652
1653     let (file_metadata, line_number) = if span != syntax_pos::DUMMY_SP {
1654         let loc = span_start(cx, span);
1655         (file_metadata(cx, &loc.file.name, LOCAL_CRATE), loc.line as c_uint)
1656     } else {
1657         (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
1658     };
1659
1660     let is_local_to_unit = is_node_local_to_unit(cx, node_id);
1661     let variable_type = Instance::mono(cx.tcx(), node_def_id).ty(cx.tcx());
1662     let type_metadata = type_metadata(cx, variable_type, span);
1663     let var_name = tcx.item_name(node_def_id).to_string();
1664     let var_name = CString::new(var_name).unwrap();
1665     let linkage_name = if no_mangle {
1666         None
1667     } else {
1668         let linkage_name = mangled_name_of_item(cx, node_id);
1669         Some(CString::new(linkage_name.to_string()).unwrap())
1670     };
1671
1672     let global_align = cx.align_of(variable_type);
1673
1674     unsafe {
1675         llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
1676                                                     var_scope,
1677                                                     var_name.as_ptr(),
1678                                                     // If null, linkage_name field is omitted,
1679                                                     // which is what we want for no_mangle statics
1680                                                     linkage_name.as_ref()
1681                                                      .map_or(ptr::null(), |name| name.as_ptr()),
1682                                                     file_metadata,
1683                                                     line_number,
1684                                                     type_metadata,
1685                                                     is_local_to_unit,
1686                                                     global,
1687                                                     ptr::null_mut(),
1688                                                     global_align.abi() as u32,
1689         );
1690     }
1691 }
1692
1693 // Creates an "extension" of an existing DIScope into another file.
1694 pub fn extend_scope_to_file(ccx: &CrateContext,
1695                             scope_metadata: DIScope,
1696                             file: &syntax_pos::FileMap,
1697                             defining_crate: CrateNum)
1698                             -> DILexicalBlock {
1699     let file_metadata = file_metadata(ccx, &file.name, defining_crate);
1700     unsafe {
1701         llvm::LLVMRustDIBuilderCreateLexicalBlockFile(
1702             DIB(ccx),
1703             scope_metadata,
1704             file_metadata)
1705     }
1706 }
1707
1708 /// Creates debug information for the given vtable, which is for the
1709 /// given type.
1710 ///
1711 /// Adds the created metadata nodes directly to the crate's IR.
1712 pub fn create_vtable_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1713                                         ty: ty::Ty<'tcx>,
1714                                         vtable: ValueRef) {
1715     if cx.dbg_cx().is_none() {
1716         return;
1717     }
1718
1719     let type_metadata = type_metadata(cx, ty, syntax_pos::DUMMY_SP);
1720
1721     unsafe {
1722         // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
1723         // pointer will lead to hard to trace and debug LLVM assertions
1724         // later on in llvm/lib/IR/Value.cpp.
1725         let empty_array = create_DIArray(DIB(cx), &[]);
1726
1727         let name = CString::new("vtable").unwrap();
1728
1729         // Create a new one each time.  We don't want metadata caching
1730         // here, because each vtable will refer to a unique containing
1731         // type.
1732         let vtable_type = llvm::LLVMRustDIBuilderCreateStructType(
1733             DIB(cx),
1734             NO_SCOPE_METADATA,
1735             name.as_ptr(),
1736             unknown_file_metadata(cx),
1737             UNKNOWN_LINE_NUMBER,
1738             Size::from_bytes(0).bits(),
1739             cx.tcx().data_layout.pointer_align.abi_bits() as u32,
1740             DIFlags::FlagArtificial,
1741             ptr::null_mut(),
1742             empty_array,
1743             0,
1744             type_metadata,
1745             name.as_ptr()
1746         );
1747
1748         llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
1749                                                     NO_SCOPE_METADATA,
1750                                                     name.as_ptr(),
1751                                                     // LLVM 3.9
1752                                                     // doesn't accept
1753                                                     // null here, so
1754                                                     // pass the name
1755                                                     // as the linkage
1756                                                     // name.
1757                                                     name.as_ptr(),
1758                                                     unknown_file_metadata(cx),
1759                                                     UNKNOWN_LINE_NUMBER,
1760                                                     vtable_type,
1761                                                     true,
1762                                                     vtable,
1763                                                     ptr::null_mut(),
1764                                                     0);
1765     }
1766 }