]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/trans/debuginfo/metadata.rs
fa2c476f6133b120f94c9c96b94bd01eca8533c2
[rust.git] / src / librustc_trans / 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::MemberOffset::*;
13 use self::MemberDescriptionFactory::*;
14 use self::EnumDiscriminantInfo::*;
15
16 use super::utils::{debug_context, DIB, span_start, bytes_to_bits, size_and_align_of,
17                    get_namespace_and_span_for_item, create_DIArray,
18                    fn_should_be_ignored, is_node_local_to_unit};
19 use super::namespace::namespace_for_item;
20 use super::type_names::{compute_debuginfo_type_name, push_debuginfo_type_name};
21 use super::{declare_local, VariableKind, VariableAccess};
22
23 use llvm::{self, ValueRef};
24 use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};
25
26 use middle::def_id::DefId;
27 use middle::pat_util;
28 use middle::subst::{self, Substs};
29 use rustc::front::map as hir_map;
30 use rustc_front::hir;
31 use trans::{type_of, adt, machine, monomorphize};
32 use trans::common::{self, CrateContext, FunctionContext, Block};
33 use trans::_match::{BindingInfo, TransBindingMode};
34 use trans::type_::Type;
35 use middle::ty::{self, Ty};
36 use session::config::{self, FullDebugInfo};
37 use util::nodemap::FnvHashMap;
38 use util::common::path2cstr;
39
40 use libc::{c_uint, c_longlong};
41 use std::ffi::CString;
42 use std::path::Path;
43 use std::ptr;
44 use std::rc::Rc;
45 use syntax;
46 use syntax::util::interner::Interner;
47 use syntax::codemap::Span;
48 use syntax::{ast, codemap};
49 use syntax::parse::token;
50
51
52 const DW_LANG_RUST: c_uint = 0x9000;
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 const NO_FILE_METADATA: DIFile = (0 as DIFile);
69 const NO_SCOPE_METADATA: DIScope = (0 as DIScope);
70
71 const FLAGS_NONE: c_uint = 0;
72
73 #[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
74 pub struct UniqueTypeId(ast::Name);
75
76 // The TypeMap is where the CrateDebugContext holds the type metadata nodes
77 // created so far. The metadata nodes are indexed by UniqueTypeId, and, for
78 // faster lookup, also by Ty. The TypeMap is responsible for creating
79 // UniqueTypeIds.
80 pub struct TypeMap<'tcx> {
81     // The UniqueTypeIds created so far
82     unique_id_interner: Interner<Rc<String>>,
83     // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
84     unique_id_to_metadata: FnvHashMap<UniqueTypeId, DIType>,
85     // A map from types to debuginfo metadata. This is a N:1 mapping.
86     type_to_metadata: FnvHashMap<Ty<'tcx>, DIType>,
87     // A map from types to UniqueTypeId. This is a N:1 mapping.
88     type_to_unique_id: FnvHashMap<Ty<'tcx>, UniqueTypeId>
89 }
90
91 impl<'tcx> TypeMap<'tcx> {
92     pub fn new() -> TypeMap<'tcx> {
93         TypeMap {
94             unique_id_interner: Interner::new(),
95             type_to_metadata: FnvHashMap(),
96             unique_id_to_metadata: FnvHashMap(),
97             type_to_unique_id: FnvHashMap(),
98         }
99     }
100
101     // Adds a Ty to metadata mapping to the TypeMap. The method will fail if
102     // the mapping already exists.
103     fn register_type_with_metadata<'a>(&mut self,
104                                        cx: &CrateContext<'a, 'tcx>,
105                                        type_: Ty<'tcx>,
106                                        metadata: DIType) {
107         if self.type_to_metadata.insert(type_, metadata).is_some() {
108             cx.sess().bug(&format!("Type metadata for Ty '{}' is already in the TypeMap!",
109                                    type_));
110         }
111     }
112
113     // Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
114     // fail if the mapping already exists.
115     fn register_unique_id_with_metadata(&mut self,
116                                         cx: &CrateContext,
117                                         unique_type_id: UniqueTypeId,
118                                         metadata: DIType) {
119         if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
120             let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id);
121             cx.sess().bug(&format!("Type metadata for unique id '{}' is already in the TypeMap!",
122                                   &unique_type_id_str[..]));
123         }
124     }
125
126     fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<DIType> {
127         self.type_to_metadata.get(&type_).cloned()
128     }
129
130     fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<DIType> {
131         self.unique_id_to_metadata.get(&unique_type_id).cloned()
132     }
133
134     // Get the string representation of a UniqueTypeId. This method will fail if
135     // the id is unknown.
136     fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> Rc<String> {
137         let UniqueTypeId(interner_key) = unique_type_id;
138         self.unique_id_interner.get(interner_key)
139     }
140
141     // Get the UniqueTypeId for the given type. If the UniqueTypeId for the given
142     // type has been requested before, this is just a table lookup. Otherwise an
143     // ID will be generated and stored for later lookup.
144     fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
145                                       type_: Ty<'tcx>) -> UniqueTypeId {
146
147         // basic type             -> {:name of the type:}
148         // tuple                  -> {tuple_(:param-uid:)*}
149         // struct                 -> {struct_:svh: / :node-id:_<(:param-uid:),*> }
150         // enum                   -> {enum_:svh: / :node-id:_<(:param-uid:),*> }
151         // enum variant           -> {variant_:variant-name:_:enum-uid:}
152         // reference (&)          -> {& :pointee-uid:}
153         // mut reference (&mut)   -> {&mut :pointee-uid:}
154         // ptr (*)                -> {* :pointee-uid:}
155         // mut ptr (*mut)         -> {*mut :pointee-uid:}
156         // unique ptr (box)       -> {box :pointee-uid:}
157         // @-ptr (@)              -> {@ :pointee-uid:}
158         // sized vec ([T; x])     -> {[:size:] :element-uid:}
159         // unsized vec ([T])      -> {[] :element-uid:}
160         // trait (T)              -> {trait_:svh: / :node-id:_<(:param-uid:),*> }
161         // closure                -> {<unsafe_> <once_> :store-sigil: |(:param-uid:),* <,_...>| -> \
162         //                             :return-type-uid: : (:bounds:)*}
163         // function               -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \
164         //                             :return-type-uid:}
165
166         match self.type_to_unique_id.get(&type_).cloned() {
167             Some(unique_type_id) => return unique_type_id,
168             None => { /* generate one */}
169         };
170
171         let mut unique_type_id = String::with_capacity(256);
172         unique_type_id.push('{');
173
174         match type_.sty {
175             ty::TyBool     |
176             ty::TyChar     |
177             ty::TyStr      |
178             ty::TyInt(_)   |
179             ty::TyUint(_)  |
180             ty::TyFloat(_) => {
181                 push_debuginfo_type_name(cx, type_, false, &mut unique_type_id);
182             },
183             ty::TyEnum(def, substs) => {
184                 unique_type_id.push_str("enum ");
185                 from_def_id_and_substs(self, cx, def.did, substs, &mut unique_type_id);
186             },
187             ty::TyStruct(def, substs) => {
188                 unique_type_id.push_str("struct ");
189                 from_def_id_and_substs(self, cx, def.did, substs, &mut unique_type_id);
190             },
191             ty::TyTuple(ref component_types) if component_types.is_empty() => {
192                 push_debuginfo_type_name(cx, type_, false, &mut unique_type_id);
193             },
194             ty::TyTuple(ref component_types) => {
195                 unique_type_id.push_str("tuple ");
196                 for &component_type in component_types {
197                     let component_type_id =
198                         self.get_unique_type_id_of_type(cx, component_type);
199                     let component_type_id =
200                         self.get_unique_type_id_as_string(component_type_id);
201                     unique_type_id.push_str(&component_type_id[..]);
202                 }
203             },
204             ty::TyBox(inner_type) => {
205                 unique_type_id.push_str("box ");
206                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
207                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
208                 unique_type_id.push_str(&inner_type_id[..]);
209             },
210             ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => {
211                 unique_type_id.push('*');
212                 if mutbl == hir::MutMutable {
213                     unique_type_id.push_str("mut");
214                 }
215
216                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
217                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
218                 unique_type_id.push_str(&inner_type_id[..]);
219             },
220             ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => {
221                 unique_type_id.push('&');
222                 if mutbl == hir::MutMutable {
223                     unique_type_id.push_str("mut");
224                 }
225
226                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
227                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
228                 unique_type_id.push_str(&inner_type_id[..]);
229             },
230             ty::TyArray(inner_type, len) => {
231                 unique_type_id.push_str(&format!("[{}]", len));
232
233                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
234                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
235                 unique_type_id.push_str(&inner_type_id[..]);
236             },
237             ty::TySlice(inner_type) => {
238                 unique_type_id.push_str("[]");
239
240                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
241                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
242                 unique_type_id.push_str(&inner_type_id[..]);
243             },
244             ty::TyTrait(ref trait_data) => {
245                 unique_type_id.push_str("trait ");
246
247                 let principal = cx.tcx().erase_late_bound_regions(&trait_data.principal);
248
249                 from_def_id_and_substs(self,
250                                        cx,
251                                        principal.def_id,
252                                        principal.substs,
253                                        &mut unique_type_id);
254             },
255             ty::TyBareFn(_, &ty::BareFnTy{ unsafety, abi, ref sig } ) => {
256                 if unsafety == hir::Unsafety::Unsafe {
257                     unique_type_id.push_str("unsafe ");
258                 }
259
260                 unique_type_id.push_str(abi.name());
261
262                 unique_type_id.push_str(" fn(");
263
264                 let sig = cx.tcx().erase_late_bound_regions(sig);
265
266                 for &parameter_type in &sig.inputs {
267                     let parameter_type_id =
268                         self.get_unique_type_id_of_type(cx, parameter_type);
269                     let parameter_type_id =
270                         self.get_unique_type_id_as_string(parameter_type_id);
271                     unique_type_id.push_str(&parameter_type_id[..]);
272                     unique_type_id.push(',');
273                 }
274
275                 if sig.variadic {
276                     unique_type_id.push_str("...");
277                 }
278
279                 unique_type_id.push_str(")->");
280                 match sig.output {
281                     ty::FnConverging(ret_ty) => {
282                         let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
283                         let return_type_id = self.get_unique_type_id_as_string(return_type_id);
284                         unique_type_id.push_str(&return_type_id[..]);
285                     }
286                     ty::FnDiverging => {
287                         unique_type_id.push_str("!");
288                     }
289                 }
290             },
291             ty::TyClosure(_, ref substs) if substs.upvar_tys.is_empty() => {
292                 push_debuginfo_type_name(cx, type_, false, &mut unique_type_id);
293             },
294             ty::TyClosure(_, ref substs) => {
295                 unique_type_id.push_str("closure ");
296                 for upvar_type in &substs.upvar_tys {
297                     let upvar_type_id =
298                         self.get_unique_type_id_of_type(cx, upvar_type);
299                     let upvar_type_id =
300                         self.get_unique_type_id_as_string(upvar_type_id);
301                     unique_type_id.push_str(&upvar_type_id[..]);
302                 }
303             },
304             _ => {
305                 cx.sess().bug(&format!("get_unique_type_id_of_type() - unexpected type: {:?}",
306                                        type_))
307             }
308         };
309
310         unique_type_id.push('}');
311
312         // Trim to size before storing permanently
313         unique_type_id.shrink_to_fit();
314
315         let key = self.unique_id_interner.intern(Rc::new(unique_type_id));
316         self.type_to_unique_id.insert(type_, UniqueTypeId(key));
317
318         return UniqueTypeId(key);
319
320         fn from_def_id_and_substs<'a, 'tcx>(type_map: &mut TypeMap<'tcx>,
321                                             cx: &CrateContext<'a, 'tcx>,
322                                             def_id: DefId,
323                                             substs: &subst::Substs<'tcx>,
324                                             output: &mut String) {
325             // First, find out the 'real' def_id of the type. Items inlined from
326             // other crates have to be mapped back to their source.
327             let source_def_id = if def_id.is_local() {
328                 match cx.external_srcs().borrow().get(&def_id.node).cloned() {
329                     Some(source_def_id) => {
330                         // The given def_id identifies the inlined copy of a
331                         // type definition, let's take the source of the copy.
332                         source_def_id
333                     }
334                     None => def_id
335                 }
336             } else {
337                 def_id
338             };
339
340             // Get the crate hash as first part of the identifier.
341             let crate_hash = if source_def_id.is_local() {
342                 cx.link_meta().crate_hash.clone()
343             } else {
344                 cx.sess().cstore.get_crate_hash(source_def_id.krate)
345             };
346
347             output.push_str(crate_hash.as_str());
348             output.push_str("/");
349             output.push_str(&format!("{:x}", def_id.node));
350
351             // Maybe check that there is no self type here.
352
353             let tps = substs.types.get_slice(subst::TypeSpace);
354             if !tps.is_empty() {
355                 output.push('<');
356
357                 for &type_parameter in tps {
358                     let param_type_id =
359                         type_map.get_unique_type_id_of_type(cx, type_parameter);
360                     let param_type_id =
361                         type_map.get_unique_type_id_as_string(param_type_id);
362                     output.push_str(&param_type_id[..]);
363                     output.push(',');
364                 }
365
366                 output.push('>');
367             }
368         }
369     }
370
371     // Get the UniqueTypeId for an enum variant. Enum variants are not really
372     // types of their own, so they need special handling. We still need a
373     // UniqueTypeId for them, since to debuginfo they *are* real types.
374     fn get_unique_type_id_of_enum_variant<'a>(&mut self,
375                                               cx: &CrateContext<'a, 'tcx>,
376                                               enum_type: Ty<'tcx>,
377                                               variant_name: &str)
378                                               -> UniqueTypeId {
379         let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
380         let enum_variant_type_id = format!("{}::{}",
381                                            &self.get_unique_type_id_as_string(enum_type_id),
382                                            variant_name);
383         let interner_key = self.unique_id_interner.intern(Rc::new(enum_variant_type_id));
384         UniqueTypeId(interner_key)
385     }
386 }
387
388 // A description of some recursive type. It can either be already finished (as
389 // with FinalMetadata) or it is not yet finished, but contains all information
390 // needed to generate the missing parts of the description. See the
391 // documentation section on Recursive Types at the top of this file for more
392 // information.
393 enum RecursiveTypeDescription<'tcx> {
394     UnfinishedMetadata {
395         unfinished_type: Ty<'tcx>,
396         unique_type_id: UniqueTypeId,
397         metadata_stub: DICompositeType,
398         llvm_type: Type,
399         member_description_factory: MemberDescriptionFactory<'tcx>,
400     },
401     FinalMetadata(DICompositeType)
402 }
403
404 fn create_and_register_recursive_type_forward_declaration<'a, 'tcx>(
405     cx: &CrateContext<'a, 'tcx>,
406     unfinished_type: Ty<'tcx>,
407     unique_type_id: UniqueTypeId,
408     metadata_stub: DICompositeType,
409     llvm_type: Type,
410     member_description_factory: MemberDescriptionFactory<'tcx>)
411  -> RecursiveTypeDescription<'tcx> {
412
413     // Insert the stub into the TypeMap in order to allow for recursive references
414     let mut type_map = debug_context(cx).type_map.borrow_mut();
415     type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata_stub);
416     type_map.register_type_with_metadata(cx, unfinished_type, metadata_stub);
417
418     UnfinishedMetadata {
419         unfinished_type: unfinished_type,
420         unique_type_id: unique_type_id,
421         metadata_stub: metadata_stub,
422         llvm_type: llvm_type,
423         member_description_factory: member_description_factory,
424     }
425 }
426
427 impl<'tcx> RecursiveTypeDescription<'tcx> {
428     // Finishes up the description of the type in question (mostly by providing
429     // descriptions of the fields of the given type) and returns the final type
430     // metadata.
431     fn finalize<'a>(&self, cx: &CrateContext<'a, 'tcx>) -> MetadataCreationResult {
432         match *self {
433             FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
434             UnfinishedMetadata {
435                 unfinished_type,
436                 unique_type_id,
437                 metadata_stub,
438                 llvm_type,
439                 ref member_description_factory,
440                 ..
441             } => {
442                 // Make sure that we have a forward declaration of the type in
443                 // the TypeMap so that recursive references are possible. This
444                 // will always be the case if the RecursiveTypeDescription has
445                 // been properly created through the
446                 // create_and_register_recursive_type_forward_declaration()
447                 // function.
448                 {
449                     let type_map = debug_context(cx).type_map.borrow();
450                     if type_map.find_metadata_for_unique_id(unique_type_id).is_none() ||
451                        type_map.find_metadata_for_type(unfinished_type).is_none() {
452                         cx.sess().bug(&format!("Forward declaration of potentially recursive type \
453                                               '{:?}' was not found in TypeMap!",
454                                               unfinished_type)
455                                       );
456                     }
457                 }
458
459                 // ... then create the member descriptions ...
460                 let member_descriptions =
461                     member_description_factory.create_member_descriptions(cx);
462
463                 // ... and attach them to the stub to complete it.
464                 set_members_of_composite_type(cx,
465                                               metadata_stub,
466                                               llvm_type,
467                                               &member_descriptions[..]);
468                 return MetadataCreationResult::new(metadata_stub, true);
469             }
470         }
471     }
472 }
473
474 // Returns from the enclosing function if the type metadata with the given
475 // unique id can be found in the type map
476 macro_rules! return_if_metadata_created_in_meantime {
477     ($cx: expr, $unique_type_id: expr) => (
478         match debug_context($cx).type_map
479                                 .borrow()
480                                 .find_metadata_for_unique_id($unique_type_id) {
481             Some(metadata) => return MetadataCreationResult::new(metadata, true),
482             None => { /* proceed normally */ }
483         };
484     )
485 }
486
487 fn fixed_vec_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
488                                 unique_type_id: UniqueTypeId,
489                                 element_type: Ty<'tcx>,
490                                 len: Option<u64>,
491                                 span: Span)
492                                 -> MetadataCreationResult {
493     let element_type_metadata = type_metadata(cx, element_type, span);
494
495     return_if_metadata_created_in_meantime!(cx, unique_type_id);
496
497     let element_llvm_type = type_of::type_of(cx, element_type);
498     let (element_type_size, element_type_align) = size_and_align_of(cx, element_llvm_type);
499
500     let (array_size_in_bytes, upper_bound) = match len {
501         Some(len) => (element_type_size * len, len as c_longlong),
502         None => (0, -1)
503     };
504
505     let subrange = unsafe {
506         llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)
507     };
508
509     let subscripts = create_DIArray(DIB(cx), &[subrange]);
510     let metadata = unsafe {
511         llvm::LLVMDIBuilderCreateArrayType(
512             DIB(cx),
513             bytes_to_bits(array_size_in_bytes),
514             bytes_to_bits(element_type_align),
515             element_type_metadata,
516             subscripts)
517     };
518
519     return MetadataCreationResult::new(metadata, false);
520 }
521
522 fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
523                                 vec_type: Ty<'tcx>,
524                                 element_type: Ty<'tcx>,
525                                 unique_type_id: UniqueTypeId,
526                                 span: Span)
527                                 -> MetadataCreationResult {
528     let data_ptr_type = cx.tcx().mk_ptr(ty::TypeAndMut {
529         ty: element_type,
530         mutbl: hir::MutImmutable
531     });
532
533     let element_type_metadata = type_metadata(cx, data_ptr_type, span);
534
535     return_if_metadata_created_in_meantime!(cx, unique_type_id);
536
537     let slice_llvm_type = type_of::type_of(cx, vec_type);
538     let slice_type_name = compute_debuginfo_type_name(cx, vec_type, true);
539
540     let member_llvm_types = slice_llvm_type.field_types();
541     assert!(slice_layout_is_correct(cx,
542                                     &member_llvm_types[..],
543                                     element_type));
544     let member_descriptions = [
545         MemberDescription {
546             name: "data_ptr".to_string(),
547             llvm_type: member_llvm_types[0],
548             type_metadata: element_type_metadata,
549             offset: ComputedMemberOffset,
550             flags: FLAGS_NONE
551         },
552         MemberDescription {
553             name: "length".to_string(),
554             llvm_type: member_llvm_types[1],
555             type_metadata: type_metadata(cx, cx.tcx().types.usize, span),
556             offset: ComputedMemberOffset,
557             flags: FLAGS_NONE
558         },
559     ];
560
561     assert!(member_descriptions.len() == member_llvm_types.len());
562
563     let loc = span_start(cx, span);
564     let file_metadata = file_metadata(cx, &loc.file.name);
565
566     let metadata = composite_type_metadata(cx,
567                                            slice_llvm_type,
568                                            &slice_type_name[..],
569                                            unique_type_id,
570                                            &member_descriptions,
571                                            NO_SCOPE_METADATA,
572                                            file_metadata,
573                                            span);
574     return MetadataCreationResult::new(metadata, false);
575
576     fn slice_layout_is_correct<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
577                                          member_llvm_types: &[Type],
578                                          element_type: Ty<'tcx>)
579                                          -> bool {
580         member_llvm_types.len() == 2 &&
581         member_llvm_types[0] == type_of::type_of(cx, element_type).ptr_to() &&
582         member_llvm_types[1] == cx.int_type()
583     }
584 }
585
586 fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
587                                       unique_type_id: UniqueTypeId,
588                                       signature: &ty::PolyFnSig<'tcx>,
589                                       span: Span)
590                                       -> MetadataCreationResult
591 {
592     let signature = cx.tcx().erase_late_bound_regions(signature);
593
594     let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs.len() + 1);
595
596     // return type
597     signature_metadata.push(match signature.output {
598         ty::FnConverging(ret_ty) => match ret_ty.sty {
599             ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(),
600             _ => type_metadata(cx, ret_ty, span)
601         },
602         ty::FnDiverging => diverging_type_metadata(cx)
603     });
604
605     // regular arguments
606     for &argument_type in &signature.inputs {
607         signature_metadata.push(type_metadata(cx, argument_type, span));
608     }
609
610     return_if_metadata_created_in_meantime!(cx, unique_type_id);
611
612     return MetadataCreationResult::new(
613         unsafe {
614             llvm::LLVMDIBuilderCreateSubroutineType(
615                 DIB(cx),
616                 NO_FILE_METADATA,
617                 create_DIArray(DIB(cx), &signature_metadata[..]))
618         },
619         false);
620 }
621
622 // FIXME(1563) This is all a bit of a hack because 'trait pointer' is an ill-
623 // defined concept. For the case of an actual trait pointer (i.e., Box<Trait>,
624 // &Trait), trait_object_type should be the whole thing (e.g, Box<Trait>) and
625 // trait_type should be the actual trait (e.g., Trait). Where the trait is part
626 // of a DST struct, there is no trait_object_type and the results of this
627 // function will be a little bit weird.
628 fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
629                                     trait_type: Ty<'tcx>,
630                                     trait_object_type: Option<Ty<'tcx>>,
631                                     unique_type_id: UniqueTypeId)
632                                     -> DIType {
633     // The implementation provided here is a stub. It makes sure that the trait
634     // type is assigned the correct name, size, namespace, and source location.
635     // But it does not describe the trait's methods.
636
637     let def_id = match trait_type.sty {
638         ty::TyTrait(ref data) => data.principal_def_id(),
639         _ => {
640             cx.sess().bug(&format!("debuginfo: Unexpected trait-object type in \
641                                    trait_pointer_metadata(): {:?}",
642                                    trait_type));
643         }
644     };
645
646     let trait_object_type = trait_object_type.unwrap_or(trait_type);
647     let trait_type_name =
648         compute_debuginfo_type_name(cx, trait_object_type, false);
649
650     let (containing_scope, _) = get_namespace_and_span_for_item(cx, def_id);
651
652     let trait_llvm_type = type_of::type_of(cx, trait_object_type);
653
654     composite_type_metadata(cx,
655                             trait_llvm_type,
656                             &trait_type_name[..],
657                             unique_type_id,
658                             &[],
659                             containing_scope,
660                             NO_FILE_METADATA,
661                             codemap::DUMMY_SP)
662 }
663
664 pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
665                                t: Ty<'tcx>,
666                                usage_site_span: Span)
667                                -> DIType {
668     // Get the unique type id of this type.
669     let unique_type_id = {
670         let mut type_map = debug_context(cx).type_map.borrow_mut();
671         // First, try to find the type in TypeMap. If we have seen it before, we
672         // can exit early here.
673         match type_map.find_metadata_for_type(t) {
674             Some(metadata) => {
675                 return metadata;
676             },
677             None => {
678                 // The Ty is not in the TypeMap but maybe we have already seen
679                 // an equivalent type (e.g. only differing in region arguments).
680                 // In order to find out, generate the unique type id and look
681                 // that up.
682                 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
683                 match type_map.find_metadata_for_unique_id(unique_type_id) {
684                     Some(metadata) => {
685                         // There is already an equivalent type in the TypeMap.
686                         // Register this Ty as an alias in the cache and
687                         // return the cached metadata.
688                         type_map.register_type_with_metadata(cx, t, metadata);
689                         return metadata;
690                     },
691                     None => {
692                         // There really is no type metadata for this type, so
693                         // proceed by creating it.
694                         unique_type_id
695                     }
696                 }
697             }
698         }
699     };
700
701     debug!("type_metadata: {:?}", t);
702
703     let sty = &t.sty;
704     let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty {
705         ty::TyBool     |
706         ty::TyChar     |
707         ty::TyInt(_)   |
708         ty::TyUint(_)  |
709         ty::TyFloat(_) => {
710             MetadataCreationResult::new(basic_type_metadata(cx, t), false)
711         }
712         ty::TyTuple(ref elements) if elements.is_empty() => {
713             MetadataCreationResult::new(basic_type_metadata(cx, t), false)
714         }
715         ty::TyEnum(def, _) => {
716             prepare_enum_metadata(cx,
717                                   t,
718                                   def.did,
719                                   unique_type_id,
720                                   usage_site_span).finalize(cx)
721         }
722         ty::TyArray(typ, len) => {
723             fixed_vec_metadata(cx, unique_type_id, typ, Some(len as u64), usage_site_span)
724         }
725         ty::TySlice(typ) => {
726             fixed_vec_metadata(cx, unique_type_id, typ, None, usage_site_span)
727         }
728         ty::TyStr => {
729             fixed_vec_metadata(cx, unique_type_id, cx.tcx().types.i8, None, usage_site_span)
730         }
731         ty::TyTrait(..) => {
732             MetadataCreationResult::new(
733                         trait_pointer_metadata(cx, t, None, unique_type_id),
734             false)
735         }
736         ty::TyBox(ty) |
737         ty::TyRawPtr(ty::TypeAndMut{ty, ..}) |
738         ty::TyRef(_, ty::TypeAndMut{ty, ..}) => {
739             match ty.sty {
740                 ty::TySlice(typ) => {
741                     vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span)
742                 }
743                 ty::TyStr => {
744                     vec_slice_metadata(cx, t, cx.tcx().types.u8, unique_type_id, usage_site_span)
745                 }
746                 ty::TyTrait(..) => {
747                     MetadataCreationResult::new(
748                         trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
749                         false)
750                 }
751                 _ => {
752                     let pointee_metadata = type_metadata(cx, ty, usage_site_span);
753
754                     match debug_context(cx).type_map
755                                            .borrow()
756                                            .find_metadata_for_unique_id(unique_type_id) {
757                         Some(metadata) => return metadata,
758                         None => { /* proceed normally */ }
759                     };
760
761                     MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
762                                                 false)
763                 }
764             }
765         }
766         ty::TyBareFn(_, ref barefnty) => {
767             let fn_metadata = subroutine_type_metadata(cx,
768                                                        unique_type_id,
769                                                        &barefnty.sig,
770                                                        usage_site_span).metadata;
771             match debug_context(cx).type_map
772                                    .borrow()
773                                    .find_metadata_for_unique_id(unique_type_id) {
774                 Some(metadata) => return metadata,
775                 None => { /* proceed normally */ }
776             };
777
778             // This is actually a function pointer, so wrap it in pointer DI
779             MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false)
780
781         }
782         ty::TyClosure(_, ref substs) => {
783             prepare_tuple_metadata(cx,
784                                    t,
785                                    &substs.upvar_tys,
786                                    unique_type_id,
787                                    usage_site_span).finalize(cx)
788         }
789         ty::TyStruct(..) => {
790             prepare_struct_metadata(cx,
791                                     t,
792                                     unique_type_id,
793                                     usage_site_span).finalize(cx)
794         }
795         ty::TyTuple(ref elements) => {
796             prepare_tuple_metadata(cx,
797                                    t,
798                                    &elements[..],
799                                    unique_type_id,
800                                    usage_site_span).finalize(cx)
801         }
802         _ => {
803             cx.sess().bug(&format!("debuginfo: unexpected type in type_metadata: {:?}",
804                                   sty))
805         }
806     };
807
808     {
809         let mut type_map = debug_context(cx).type_map.borrow_mut();
810
811         if already_stored_in_typemap {
812             // Also make sure that we already have a TypeMap entry entry for the unique type id.
813             let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
814                 Some(metadata) => metadata,
815                 None => {
816                     let unique_type_id_str =
817                         type_map.get_unique_type_id_as_string(unique_type_id);
818                     let error_message = format!("Expected type metadata for unique \
819                                                  type id '{}' to already be in \
820                                                  the debuginfo::TypeMap but it \
821                                                  was not. (Ty = {})",
822                                                 &unique_type_id_str[..],
823                                                 t);
824                     cx.sess().span_bug(usage_site_span, &error_message[..]);
825                 }
826             };
827
828             match type_map.find_metadata_for_type(t) {
829                 Some(metadata) => {
830                     if metadata != metadata_for_uid {
831                         let unique_type_id_str =
832                             type_map.get_unique_type_id_as_string(unique_type_id);
833                         let error_message = format!("Mismatch between Ty and \
834                                                      UniqueTypeId maps in \
835                                                      debuginfo::TypeMap. \
836                                                      UniqueTypeId={}, Ty={}",
837                             &unique_type_id_str[..],
838                             t);
839                         cx.sess().span_bug(usage_site_span, &error_message[..]);
840                     }
841                 }
842                 None => {
843                     type_map.register_type_with_metadata(cx, t, metadata);
844                 }
845             }
846         } else {
847             type_map.register_type_with_metadata(cx, t, metadata);
848             type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata);
849         }
850     }
851
852     metadata
853 }
854
855 pub fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
856     // FIXME (#9639): This needs to handle non-utf8 paths
857     let work_dir = cx.sess().working_dir.to_str().unwrap();
858     let file_name =
859         if full_path.starts_with(work_dir) {
860             &full_path[work_dir.len() + 1..full_path.len()]
861         } else {
862             full_path
863         };
864
865     file_metadata_(cx, full_path, file_name, &work_dir)
866 }
867
868 pub fn unknown_file_metadata(cx: &CrateContext) -> DIFile {
869     // Regular filenames should not be empty, so we abuse an empty name as the
870     // key for the special unknown file metadata
871     file_metadata_(cx, "", "<unknown>", "")
872
873 }
874
875 fn file_metadata_(cx: &CrateContext, key: &str, file_name: &str, work_dir: &str) -> DIFile {
876     match debug_context(cx).created_files.borrow().get(key) {
877         Some(file_metadata) => return *file_metadata,
878         None => ()
879     }
880
881     debug!("file_metadata: file_name: {}, work_dir: {}", file_name, work_dir);
882
883     let file_name = CString::new(file_name).unwrap();
884     let work_dir = CString::new(work_dir).unwrap();
885     let file_metadata = unsafe {
886         llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name.as_ptr(),
887                                       work_dir.as_ptr())
888     };
889
890     let mut created_files = debug_context(cx).created_files.borrow_mut();
891     created_files.insert(key.to_string(), file_metadata);
892     file_metadata
893 }
894
895 /// Finds the scope metadata node for the given AST node.
896 pub fn scope_metadata(fcx: &FunctionContext,
897                   node_id: ast::NodeId,
898                   error_reporting_span: Span)
899                -> DIScope {
900     let scope_map = &fcx.debug_context
901                         .get_ref(fcx.ccx, error_reporting_span)
902                         .scope_map;
903     match scope_map.borrow().get(&node_id).cloned() {
904         Some(scope_metadata) => scope_metadata,
905         None => {
906             let node = fcx.ccx.tcx().map.get(node_id);
907
908             fcx.ccx.sess().span_bug(error_reporting_span,
909                 &format!("debuginfo: Could not find scope info for node {:?}",
910                         node));
911         }
912     }
913 }
914
915 pub fn diverging_type_metadata(cx: &CrateContext) -> DIType {
916     unsafe {
917         llvm::LLVMDIBuilderCreateBasicType(
918             DIB(cx),
919             "!\0".as_ptr() as *const _,
920             bytes_to_bits(0),
921             bytes_to_bits(0),
922             DW_ATE_unsigned)
923     }
924 }
925
926 fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
927                                  t: Ty<'tcx>) -> DIType {
928
929     debug!("basic_type_metadata: {:?}", t);
930
931     let (name, encoding) = match t.sty {
932         ty::TyTuple(ref elements) if elements.is_empty() =>
933             ("()".to_string(), DW_ATE_unsigned),
934         ty::TyBool => ("bool".to_string(), DW_ATE_boolean),
935         ty::TyChar => ("char".to_string(), DW_ATE_unsigned_char),
936         ty::TyInt(int_ty) => match int_ty {
937             ast::TyIs => ("isize".to_string(), DW_ATE_signed),
938             ast::TyI8 => ("i8".to_string(), DW_ATE_signed),
939             ast::TyI16 => ("i16".to_string(), DW_ATE_signed),
940             ast::TyI32 => ("i32".to_string(), DW_ATE_signed),
941             ast::TyI64 => ("i64".to_string(), DW_ATE_signed)
942         },
943         ty::TyUint(uint_ty) => match uint_ty {
944             ast::TyUs => ("usize".to_string(), DW_ATE_unsigned),
945             ast::TyU8 => ("u8".to_string(), DW_ATE_unsigned),
946             ast::TyU16 => ("u16".to_string(), DW_ATE_unsigned),
947             ast::TyU32 => ("u32".to_string(), DW_ATE_unsigned),
948             ast::TyU64 => ("u64".to_string(), DW_ATE_unsigned)
949         },
950         ty::TyFloat(float_ty) => match float_ty {
951             ast::TyF32 => ("f32".to_string(), DW_ATE_float),
952             ast::TyF64 => ("f64".to_string(), DW_ATE_float),
953         },
954         _ => cx.sess().bug("debuginfo::basic_type_metadata - t is invalid type")
955     };
956
957     let llvm_type = type_of::type_of(cx, t);
958     let (size, align) = size_and_align_of(cx, llvm_type);
959     let name = CString::new(name).unwrap();
960     let ty_metadata = unsafe {
961         llvm::LLVMDIBuilderCreateBasicType(
962             DIB(cx),
963             name.as_ptr(),
964             bytes_to_bits(size),
965             bytes_to_bits(align),
966             encoding)
967     };
968
969     return ty_metadata;
970 }
971
972 fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
973                                    pointer_type: Ty<'tcx>,
974                                    pointee_type_metadata: DIType)
975                                    -> DIType {
976     let pointer_llvm_type = type_of::type_of(cx, pointer_type);
977     let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
978     let name = compute_debuginfo_type_name(cx, pointer_type, false);
979     let name = CString::new(name).unwrap();
980     let ptr_metadata = unsafe {
981         llvm::LLVMDIBuilderCreatePointerType(
982             DIB(cx),
983             pointee_type_metadata,
984             bytes_to_bits(pointer_size),
985             bytes_to_bits(pointer_align),
986             name.as_ptr())
987     };
988     return ptr_metadata;
989 }
990
991 pub fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
992     let work_dir = &cx.sess().working_dir;
993     let compile_unit_name = match cx.sess().local_crate_source_file {
994         None => fallback_path(cx),
995         Some(ref abs_path) => {
996             if abs_path.is_relative() {
997                 cx.sess().warn("debuginfo: Invalid path to crate's local root source file!");
998                 fallback_path(cx)
999             } else {
1000                 match abs_path.relative_from(work_dir) {
1001                     Some(ref p) if p.is_relative() => {
1002                         if p.starts_with(Path::new("./")) {
1003                             path2cstr(p)
1004                         } else {
1005                             path2cstr(&Path::new(".").join(p))
1006                         }
1007                     }
1008                     _ => fallback_path(cx)
1009                 }
1010             }
1011         }
1012     };
1013
1014     debug!("compile_unit_metadata: {:?}", compile_unit_name);
1015     let producer = format!("rustc version {}",
1016                            (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
1017
1018     let compile_unit_name = compile_unit_name.as_ptr();
1019     let work_dir = path2cstr(&work_dir);
1020     let producer = CString::new(producer).unwrap();
1021     let flags = "\0";
1022     let split_name = "\0";
1023     return unsafe {
1024         llvm::LLVMDIBuilderCreateCompileUnit(
1025             debug_context(cx).builder,
1026             DW_LANG_RUST,
1027             compile_unit_name,
1028             work_dir.as_ptr(),
1029             producer.as_ptr(),
1030             cx.sess().opts.optimize != config::No,
1031             flags.as_ptr() as *const _,
1032             0,
1033             split_name.as_ptr() as *const _)
1034     };
1035
1036     fn fallback_path(cx: &CrateContext) -> CString {
1037         CString::new(cx.link_meta().crate_name.clone()).unwrap()
1038     }
1039 }
1040
1041 struct MetadataCreationResult {
1042     metadata: DIType,
1043     already_stored_in_typemap: bool
1044 }
1045
1046 impl MetadataCreationResult {
1047     fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationResult {
1048         MetadataCreationResult {
1049             metadata: metadata,
1050             already_stored_in_typemap: already_stored_in_typemap
1051         }
1052     }
1053 }
1054
1055 #[derive(Debug)]
1056 enum MemberOffset {
1057     FixedMemberOffset { bytes: usize },
1058     // For ComputedMemberOffset, the offset is read from the llvm type definition.
1059     ComputedMemberOffset
1060 }
1061
1062 // Description of a type member, which can either be a regular field (as in
1063 // structs or tuples) or an enum variant.
1064 #[derive(Debug)]
1065 struct MemberDescription {
1066     name: String,
1067     llvm_type: Type,
1068     type_metadata: DIType,
1069     offset: MemberOffset,
1070     flags: c_uint
1071 }
1072
1073 // A factory for MemberDescriptions. It produces a list of member descriptions
1074 // for some record-like type. MemberDescriptionFactories are used to defer the
1075 // creation of type member descriptions in order to break cycles arising from
1076 // recursive type definitions.
1077 enum MemberDescriptionFactory<'tcx> {
1078     StructMDF(StructMemberDescriptionFactory<'tcx>),
1079     TupleMDF(TupleMemberDescriptionFactory<'tcx>),
1080     EnumMDF(EnumMemberDescriptionFactory<'tcx>),
1081     VariantMDF(VariantMemberDescriptionFactory<'tcx>)
1082 }
1083
1084 impl<'tcx> MemberDescriptionFactory<'tcx> {
1085     fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1086                                       -> Vec<MemberDescription> {
1087         match *self {
1088             StructMDF(ref this) => {
1089                 this.create_member_descriptions(cx)
1090             }
1091             TupleMDF(ref this) => {
1092                 this.create_member_descriptions(cx)
1093             }
1094             EnumMDF(ref this) => {
1095                 this.create_member_descriptions(cx)
1096             }
1097             VariantMDF(ref this) => {
1098                 this.create_member_descriptions(cx)
1099             }
1100         }
1101     }
1102 }
1103
1104 //=-----------------------------------------------------------------------------
1105 // Structs
1106 //=-----------------------------------------------------------------------------
1107
1108 // Creates MemberDescriptions for the fields of a struct
1109 struct StructMemberDescriptionFactory<'tcx> {
1110     variant: ty::VariantDef<'tcx>,
1111     substs: &'tcx subst::Substs<'tcx>,
1112     is_simd: bool,
1113     span: Span,
1114 }
1115
1116 impl<'tcx> StructMemberDescriptionFactory<'tcx> {
1117     fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1118                                       -> Vec<MemberDescription> {
1119         if let ty::VariantKind::Unit = self.variant.kind() {
1120             return Vec::new();
1121         }
1122
1123         let field_size = if self.is_simd {
1124             let fty = monomorphize::field_ty(cx.tcx(),
1125                                              self.substs,
1126                                              &self.variant.fields[0]);
1127             Some(machine::llsize_of_alloc(
1128                 cx,
1129                 type_of::type_of(cx, fty)
1130             ) as usize)
1131         } else {
1132             None
1133         };
1134
1135         self.variant.fields.iter().enumerate().map(|(i, f)| {
1136             let name = if let ty::VariantKind::Tuple = self.variant.kind() {
1137                 format!("__{}", i)
1138             } else {
1139                 f.name.to_string()
1140             };
1141             let fty = monomorphize::field_ty(cx.tcx(), self.substs, f);
1142
1143             let offset = if self.is_simd {
1144                 FixedMemberOffset { bytes: i * field_size.unwrap() }
1145             } else {
1146                 ComputedMemberOffset
1147             };
1148
1149             MemberDescription {
1150                 name: name,
1151                 llvm_type: type_of::type_of(cx, fty),
1152                 type_metadata: type_metadata(cx, fty, self.span),
1153                 offset: offset,
1154                 flags: FLAGS_NONE,
1155             }
1156         }).collect()
1157     }
1158 }
1159
1160
1161 fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1162                                      struct_type: Ty<'tcx>,
1163                                      unique_type_id: UniqueTypeId,
1164                                      span: Span)
1165                                      -> RecursiveTypeDescription<'tcx> {
1166     let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
1167     let struct_llvm_type = type_of::in_memory_type_of(cx, struct_type);
1168
1169     let (variant, substs) = match struct_type.sty {
1170         ty::TyStruct(def, substs) => (def.struct_variant(), substs),
1171         _ => cx.tcx().sess.bug("prepare_struct_metadata on a non-struct")
1172     };
1173
1174     let (containing_scope, _) = get_namespace_and_span_for_item(cx, variant.did);
1175
1176     let struct_metadata_stub = create_struct_stub(cx,
1177                                                   struct_llvm_type,
1178                                                   &struct_name,
1179                                                   unique_type_id,
1180                                                   containing_scope);
1181
1182     create_and_register_recursive_type_forward_declaration(
1183         cx,
1184         struct_type,
1185         unique_type_id,
1186         struct_metadata_stub,
1187         struct_llvm_type,
1188         StructMDF(StructMemberDescriptionFactory {
1189             variant: variant,
1190             substs: substs,
1191             is_simd: struct_type.is_simd(),
1192             span: span,
1193         })
1194     )
1195 }
1196
1197
1198 //=-----------------------------------------------------------------------------
1199 // Tuples
1200 //=-----------------------------------------------------------------------------
1201
1202 // Creates MemberDescriptions for the fields of a tuple
1203 struct TupleMemberDescriptionFactory<'tcx> {
1204     component_types: Vec<Ty<'tcx>>,
1205     span: Span,
1206 }
1207
1208 impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
1209     fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1210                                       -> Vec<MemberDescription> {
1211         self.component_types
1212             .iter()
1213             .enumerate()
1214             .map(|(i, &component_type)| {
1215             MemberDescription {
1216                 name: format!("__{}", i),
1217                 llvm_type: type_of::type_of(cx, component_type),
1218                 type_metadata: type_metadata(cx, component_type, self.span),
1219                 offset: ComputedMemberOffset,
1220                 flags: FLAGS_NONE,
1221             }
1222         }).collect()
1223     }
1224 }
1225
1226 fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1227                                     tuple_type: Ty<'tcx>,
1228                                     component_types: &[Ty<'tcx>],
1229                                     unique_type_id: UniqueTypeId,
1230                                     span: Span)
1231                                     -> RecursiveTypeDescription<'tcx> {
1232     let tuple_name = compute_debuginfo_type_name(cx, tuple_type, false);
1233     let tuple_llvm_type = type_of::type_of(cx, tuple_type);
1234
1235     create_and_register_recursive_type_forward_declaration(
1236         cx,
1237         tuple_type,
1238         unique_type_id,
1239         create_struct_stub(cx,
1240                            tuple_llvm_type,
1241                            &tuple_name[..],
1242                            unique_type_id,
1243                            NO_SCOPE_METADATA),
1244         tuple_llvm_type,
1245         TupleMDF(TupleMemberDescriptionFactory {
1246             component_types: component_types.to_vec(),
1247             span: span,
1248         })
1249     )
1250 }
1251
1252
1253 //=-----------------------------------------------------------------------------
1254 // Enums
1255 //=-----------------------------------------------------------------------------
1256
1257 // Describes the members of an enum value: An enum is described as a union of
1258 // structs in DWARF. This MemberDescriptionFactory provides the description for
1259 // the members of this union; so for every variant of the given enum, this
1260 // factory will produce one MemberDescription (all with no name and a fixed
1261 // offset of zero bytes).
1262 struct EnumMemberDescriptionFactory<'tcx> {
1263     enum_type: Ty<'tcx>,
1264     type_rep: Rc<adt::Repr<'tcx>>,
1265     discriminant_type_metadata: Option<DIType>,
1266     containing_scope: DIScope,
1267     file_metadata: DIFile,
1268     span: Span,
1269 }
1270
1271 impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
1272     fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1273                                       -> Vec<MemberDescription> {
1274         let adt = &self.enum_type.ty_adt_def().unwrap();
1275         match *self.type_rep {
1276             adt::General(_, ref struct_defs, _) => {
1277                 let discriminant_info = RegularDiscriminant(self.discriminant_type_metadata
1278                     .expect(""));
1279                 struct_defs
1280                     .iter()
1281                     .enumerate()
1282                     .map(|(i, struct_def)| {
1283                         let (variant_type_metadata,
1284                              variant_llvm_type,
1285                              member_desc_factory) =
1286                             describe_enum_variant(cx,
1287                                                   self.enum_type,
1288                                                   struct_def,
1289                                                   &adt.variants[i],
1290                                                   discriminant_info,
1291                                                   self.containing_scope,
1292                                                   self.span);
1293
1294                         let member_descriptions = member_desc_factory
1295                             .create_member_descriptions(cx);
1296
1297                         set_members_of_composite_type(cx,
1298                                                       variant_type_metadata,
1299                                                       variant_llvm_type,
1300                                                       &member_descriptions);
1301                         MemberDescription {
1302                             name: "".to_string(),
1303                             llvm_type: variant_llvm_type,
1304                             type_metadata: variant_type_metadata,
1305                             offset: FixedMemberOffset { bytes: 0 },
1306                             flags: FLAGS_NONE
1307                         }
1308                     }).collect()
1309             },
1310             adt::Univariant(ref struct_def, _) => {
1311                 assert!(adt.variants.len() <= 1);
1312
1313                 if adt.variants.is_empty() {
1314                     vec![]
1315                 } else {
1316                     let (variant_type_metadata,
1317                          variant_llvm_type,
1318                          member_description_factory) =
1319                         describe_enum_variant(cx,
1320                                               self.enum_type,
1321                                               struct_def,
1322                                               &adt.variants[0],
1323                                               NoDiscriminant,
1324                                               self.containing_scope,
1325                                               self.span);
1326
1327                     let member_descriptions =
1328                         member_description_factory.create_member_descriptions(cx);
1329
1330                     set_members_of_composite_type(cx,
1331                                                   variant_type_metadata,
1332                                                   variant_llvm_type,
1333                                                   &member_descriptions[..]);
1334                     vec![
1335                         MemberDescription {
1336                             name: "".to_string(),
1337                             llvm_type: variant_llvm_type,
1338                             type_metadata: variant_type_metadata,
1339                             offset: FixedMemberOffset { bytes: 0 },
1340                             flags: FLAGS_NONE
1341                         }
1342                     ]
1343                 }
1344             }
1345             adt::RawNullablePointer { nndiscr: non_null_variant_index, nnty, .. } => {
1346                 // As far as debuginfo is concerned, the pointer this enum
1347                 // represents is still wrapped in a struct. This is to make the
1348                 // DWARF representation of enums uniform.
1349
1350                 // First create a description of the artificial wrapper struct:
1351                 let non_null_variant = &adt.variants[non_null_variant_index as usize];
1352                 let non_null_variant_name = non_null_variant.name.as_str();
1353
1354                 // The llvm type and metadata of the pointer
1355                 let non_null_llvm_type = type_of::type_of(cx, nnty);
1356                 let non_null_type_metadata = type_metadata(cx, nnty, self.span);
1357
1358                 // The type of the artificial struct wrapping the pointer
1359                 let artificial_struct_llvm_type = Type::struct_(cx,
1360                                                                 &[non_null_llvm_type],
1361                                                                 false);
1362
1363                 // For the metadata of the wrapper struct, we need to create a
1364                 // MemberDescription of the struct's single field.
1365                 let sole_struct_member_description = MemberDescription {
1366                     name: match non_null_variant.kind() {
1367                         ty::VariantKind::Tuple => "__0".to_string(),
1368                         ty::VariantKind::Dict => {
1369                             non_null_variant.fields[0].name.to_string()
1370                         }
1371                         ty::VariantKind::Unit => unreachable!()
1372                     },
1373                     llvm_type: non_null_llvm_type,
1374                     type_metadata: non_null_type_metadata,
1375                     offset: FixedMemberOffset { bytes: 0 },
1376                     flags: FLAGS_NONE
1377                 };
1378
1379                 let unique_type_id = debug_context(cx).type_map
1380                                                       .borrow_mut()
1381                                                       .get_unique_type_id_of_enum_variant(
1382                                                           cx,
1383                                                           self.enum_type,
1384                                                           &non_null_variant_name);
1385
1386                 // Now we can create the metadata of the artificial struct
1387                 let artificial_struct_metadata =
1388                     composite_type_metadata(cx,
1389                                             artificial_struct_llvm_type,
1390                                             &non_null_variant_name,
1391                                             unique_type_id,
1392                                             &[sole_struct_member_description],
1393                                             self.containing_scope,
1394                                             self.file_metadata,
1395                                             codemap::DUMMY_SP);
1396
1397                 // Encode the information about the null variant in the union
1398                 // member's name.
1399                 let null_variant_index = (1 - non_null_variant_index) as usize;
1400                 let null_variant_name = adt.variants[null_variant_index].name;
1401                 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
1402                                                 0,
1403                                                 null_variant_name);
1404
1405                 // Finally create the (singleton) list of descriptions of union
1406                 // members.
1407                 vec![
1408                     MemberDescription {
1409                         name: union_member_name,
1410                         llvm_type: artificial_struct_llvm_type,
1411                         type_metadata: artificial_struct_metadata,
1412                         offset: FixedMemberOffset { bytes: 0 },
1413                         flags: FLAGS_NONE
1414                     }
1415                 ]
1416             },
1417             adt::StructWrappedNullablePointer { nonnull: ref struct_def,
1418                                                 nndiscr,
1419                                                 ref discrfield, ..} => {
1420                 // Create a description of the non-null variant
1421                 let (variant_type_metadata, variant_llvm_type, member_description_factory) =
1422                     describe_enum_variant(cx,
1423                                           self.enum_type,
1424                                           struct_def,
1425                                           &adt.variants[nndiscr as usize],
1426                                           OptimizedDiscriminant,
1427                                           self.containing_scope,
1428                                           self.span);
1429
1430                 let variant_member_descriptions =
1431                     member_description_factory.create_member_descriptions(cx);
1432
1433                 set_members_of_composite_type(cx,
1434                                               variant_type_metadata,
1435                                               variant_llvm_type,
1436                                               &variant_member_descriptions[..]);
1437
1438                 // Encode the information about the null variant in the union
1439                 // member's name.
1440                 let null_variant_index = (1 - nndiscr) as usize;
1441                 let null_variant_name = adt.variants[null_variant_index].name;
1442                 let discrfield = discrfield.iter()
1443                                            .skip(1)
1444                                            .map(|x| x.to_string())
1445                                            .collect::<Vec<_>>().join("$");
1446                 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
1447                                                 discrfield,
1448                                                 null_variant_name);
1449
1450                 // Create the (singleton) list of descriptions of union members.
1451                 vec![
1452                     MemberDescription {
1453                         name: union_member_name,
1454                         llvm_type: variant_llvm_type,
1455                         type_metadata: variant_type_metadata,
1456                         offset: FixedMemberOffset { bytes: 0 },
1457                         flags: FLAGS_NONE
1458                     }
1459                 ]
1460             },
1461             adt::CEnum(..) => cx.sess().span_bug(self.span, "This should be unreachable.")
1462         }
1463     }
1464 }
1465
1466 // Creates MemberDescriptions for the fields of a single enum variant.
1467 struct VariantMemberDescriptionFactory<'tcx> {
1468     args: Vec<(String, Ty<'tcx>)>,
1469     discriminant_type_metadata: Option<DIType>,
1470     span: Span,
1471 }
1472
1473 impl<'tcx> VariantMemberDescriptionFactory<'tcx> {
1474     fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1475                                       -> Vec<MemberDescription> {
1476         self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
1477             MemberDescription {
1478                 name: name.to_string(),
1479                 llvm_type: type_of::type_of(cx, ty),
1480                 type_metadata: match self.discriminant_type_metadata {
1481                     Some(metadata) if i == 0 => metadata,
1482                     _ => type_metadata(cx, ty, self.span)
1483                 },
1484                 offset: ComputedMemberOffset,
1485                 flags: FLAGS_NONE
1486             }
1487         }).collect()
1488     }
1489 }
1490
1491 #[derive(Copy, Clone)]
1492 enum EnumDiscriminantInfo {
1493     RegularDiscriminant(DIType),
1494     OptimizedDiscriminant,
1495     NoDiscriminant
1496 }
1497
1498 // Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type
1499 // of the variant, and (3) a MemberDescriptionFactory for producing the
1500 // descriptions of the fields of the variant. This is a rudimentary version of a
1501 // full RecursiveTypeDescription.
1502 fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1503                                    enum_type: Ty<'tcx>,
1504                                    struct_def: &adt::Struct<'tcx>,
1505                                    variant: ty::VariantDef<'tcx>,
1506                                    discriminant_info: EnumDiscriminantInfo,
1507                                    containing_scope: DIScope,
1508                                    span: Span)
1509                                    -> (DICompositeType, Type, MemberDescriptionFactory<'tcx>) {
1510     let variant_llvm_type =
1511         Type::struct_(cx, &struct_def.fields
1512                                     .iter()
1513                                     .map(|&t| type_of::type_of(cx, t))
1514                                     .collect::<Vec<_>>()
1515                                     ,
1516                       struct_def.packed);
1517     // Could do some consistency checks here: size, align, field count, discr type
1518
1519     let variant_name = variant.name.as_str();
1520     let unique_type_id = debug_context(cx).type_map
1521                                           .borrow_mut()
1522                                           .get_unique_type_id_of_enum_variant(
1523                                               cx,
1524                                               enum_type,
1525                                               &variant_name);
1526
1527     let metadata_stub = create_struct_stub(cx,
1528                                            variant_llvm_type,
1529                                            &variant_name,
1530                                            unique_type_id,
1531                                            containing_scope);
1532
1533     // Get the argument names from the enum variant info
1534     let mut arg_names: Vec<_> = match variant.kind() {
1535         ty::VariantKind::Unit => vec![],
1536         ty::VariantKind::Tuple => {
1537             variant.fields
1538                    .iter()
1539                    .enumerate()
1540                    .map(|(i, _)| format!("__{}", i))
1541                    .collect()
1542         }
1543         ty::VariantKind::Dict => {
1544             variant.fields
1545                    .iter()
1546                    .map(|f| f.name.to_string())
1547                    .collect()
1548         }
1549     };
1550
1551     // If this is not a univariant enum, there is also the discriminant field.
1552     match discriminant_info {
1553         RegularDiscriminant(_) => arg_names.insert(0, "RUST$ENUM$DISR".to_string()),
1554         _ => { /* do nothing */ }
1555     };
1556
1557     // Build an array of (field name, field type) pairs to be captured in the factory closure.
1558     let args: Vec<(String, Ty)> = arg_names.iter()
1559         .zip(&struct_def.fields)
1560         .map(|(s, &t)| (s.to_string(), t))
1561         .collect();
1562
1563     let member_description_factory =
1564         VariantMDF(VariantMemberDescriptionFactory {
1565             args: args,
1566             discriminant_type_metadata: match discriminant_info {
1567                 RegularDiscriminant(discriminant_type_metadata) => {
1568                     Some(discriminant_type_metadata)
1569                 }
1570                 _ => None
1571             },
1572             span: span,
1573         });
1574
1575     (metadata_stub, variant_llvm_type, member_description_factory)
1576 }
1577
1578 fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1579                                    enum_type: Ty<'tcx>,
1580                                    enum_def_id: DefId,
1581                                    unique_type_id: UniqueTypeId,
1582                                    span: Span)
1583                                    -> RecursiveTypeDescription<'tcx> {
1584     let enum_name = compute_debuginfo_type_name(cx, enum_type, false);
1585
1586     let (containing_scope, _) = get_namespace_and_span_for_item(cx, enum_def_id);
1587     // FIXME: This should emit actual file metadata for the enum, but we
1588     // currently can't get the necessary information when it comes to types
1589     // imported from other crates. Formerly we violated the ODR when performing
1590     // LTO because we emitted debuginfo for the same type with varying file
1591     // metadata, so as a workaround we pretend that the type comes from
1592     // <unknown>
1593     let file_metadata = unknown_file_metadata(cx);
1594
1595     let variants = &enum_type.ty_adt_def().unwrap().variants;
1596
1597     let enumerators_metadata: Vec<DIDescriptor> = variants
1598         .iter()
1599         .map(|v| {
1600             let token = v.name.as_str();
1601             let name = CString::new(token.as_bytes()).unwrap();
1602             unsafe {
1603                 llvm::LLVMDIBuilderCreateEnumerator(
1604                     DIB(cx),
1605                     name.as_ptr(),
1606                     v.disr_val as u64)
1607             }
1608         })
1609         .collect();
1610
1611     let discriminant_type_metadata = |inttype: syntax::attr::IntType| {
1612         let disr_type_key = (enum_def_id, inttype);
1613         let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
1614                                                                  .borrow()
1615                                                                  .get(&disr_type_key).cloned();
1616         match cached_discriminant_type_metadata {
1617             Some(discriminant_type_metadata) => discriminant_type_metadata,
1618             None => {
1619                 let discriminant_llvm_type = adt::ll_inttype(cx, inttype);
1620                 let (discriminant_size, discriminant_align) =
1621                     size_and_align_of(cx, discriminant_llvm_type);
1622                 let discriminant_base_type_metadata =
1623                     type_metadata(cx,
1624                                   adt::ty_of_inttype(cx.tcx(), inttype),
1625                                   codemap::DUMMY_SP);
1626                 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
1627
1628                 let name = CString::new(discriminant_name.as_bytes()).unwrap();
1629                 let discriminant_type_metadata = unsafe {
1630                     llvm::LLVMDIBuilderCreateEnumerationType(
1631                         DIB(cx),
1632                         containing_scope,
1633                         name.as_ptr(),
1634                         NO_FILE_METADATA,
1635                         UNKNOWN_LINE_NUMBER,
1636                         bytes_to_bits(discriminant_size),
1637                         bytes_to_bits(discriminant_align),
1638                         create_DIArray(DIB(cx), &enumerators_metadata),
1639                         discriminant_base_type_metadata)
1640                 };
1641
1642                 debug_context(cx).created_enum_disr_types
1643                                  .borrow_mut()
1644                                  .insert(disr_type_key, discriminant_type_metadata);
1645
1646                 discriminant_type_metadata
1647             }
1648         }
1649     };
1650
1651     let type_rep = adt::represent_type(cx, enum_type);
1652
1653     let discriminant_type_metadata = match *type_rep {
1654         adt::CEnum(inttype, _, _) => {
1655             return FinalMetadata(discriminant_type_metadata(inttype))
1656         },
1657         adt::RawNullablePointer { .. }           |
1658         adt::StructWrappedNullablePointer { .. } |
1659         adt::Univariant(..)                      => None,
1660         adt::General(inttype, _, _) => Some(discriminant_type_metadata(inttype)),
1661     };
1662
1663     let enum_llvm_type = type_of::type_of(cx, enum_type);
1664     let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
1665
1666     let unique_type_id_str = debug_context(cx)
1667                              .type_map
1668                              .borrow()
1669                              .get_unique_type_id_as_string(unique_type_id);
1670
1671     let enum_name = CString::new(enum_name).unwrap();
1672     let unique_type_id_str = CString::new(unique_type_id_str.as_bytes()).unwrap();
1673     let enum_metadata = unsafe {
1674         llvm::LLVMDIBuilderCreateUnionType(
1675         DIB(cx),
1676         containing_scope,
1677         enum_name.as_ptr(),
1678         file_metadata,
1679         UNKNOWN_LINE_NUMBER,
1680         bytes_to_bits(enum_type_size),
1681         bytes_to_bits(enum_type_align),
1682         0, // Flags
1683         ptr::null_mut(),
1684         0, // RuntimeLang
1685         unique_type_id_str.as_ptr())
1686     };
1687
1688     return create_and_register_recursive_type_forward_declaration(
1689         cx,
1690         enum_type,
1691         unique_type_id,
1692         enum_metadata,
1693         enum_llvm_type,
1694         EnumMDF(EnumMemberDescriptionFactory {
1695             enum_type: enum_type,
1696             type_rep: type_rep.clone(),
1697             discriminant_type_metadata: discriminant_type_metadata,
1698             containing_scope: containing_scope,
1699             file_metadata: file_metadata,
1700             span: span,
1701         }),
1702     );
1703
1704     fn get_enum_discriminant_name(cx: &CrateContext,
1705                                   def_id: DefId)
1706                                   -> token::InternedString {
1707         cx.tcx().item_name(def_id).as_str()
1708     }
1709 }
1710
1711 /// Creates debug information for a composite type, that is, anything that
1712 /// results in a LLVM struct.
1713 ///
1714 /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
1715 fn composite_type_metadata(cx: &CrateContext,
1716                            composite_llvm_type: Type,
1717                            composite_type_name: &str,
1718                            composite_type_unique_id: UniqueTypeId,
1719                            member_descriptions: &[MemberDescription],
1720                            containing_scope: DIScope,
1721
1722                            // Ignore source location information as long as it
1723                            // can't be reconstructed for non-local crates.
1724                            _file_metadata: DIFile,
1725                            _definition_span: Span)
1726                            -> DICompositeType {
1727     // Create the (empty) struct metadata node ...
1728     let composite_type_metadata = create_struct_stub(cx,
1729                                                      composite_llvm_type,
1730                                                      composite_type_name,
1731                                                      composite_type_unique_id,
1732                                                      containing_scope);
1733     // ... and immediately create and add the member descriptions.
1734     set_members_of_composite_type(cx,
1735                                   composite_type_metadata,
1736                                   composite_llvm_type,
1737                                   member_descriptions);
1738
1739     return composite_type_metadata;
1740 }
1741
1742 fn set_members_of_composite_type(cx: &CrateContext,
1743                                  composite_type_metadata: DICompositeType,
1744                                  composite_llvm_type: Type,
1745                                  member_descriptions: &[MemberDescription]) {
1746     // In some rare cases LLVM metadata uniquing would lead to an existing type
1747     // description being used instead of a new one created in
1748     // create_struct_stub. This would cause a hard to trace assertion in
1749     // DICompositeType::SetTypeArray(). The following check makes sure that we
1750     // get a better error message if this should happen again due to some
1751     // regression.
1752     {
1753         let mut composite_types_completed =
1754             debug_context(cx).composite_types_completed.borrow_mut();
1755         if composite_types_completed.contains(&composite_type_metadata) {
1756             cx.sess().bug("debuginfo::set_members_of_composite_type() - \
1757                            Already completed forward declaration re-encountered.");
1758         } else {
1759             composite_types_completed.insert(composite_type_metadata);
1760         }
1761     }
1762
1763     let member_metadata: Vec<DIDescriptor> = member_descriptions
1764         .iter()
1765         .enumerate()
1766         .map(|(i, member_description)| {
1767             let (member_size, member_align) = size_and_align_of(cx, member_description.llvm_type);
1768             let member_offset = match member_description.offset {
1769                 FixedMemberOffset { bytes } => bytes as u64,
1770                 ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
1771             };
1772
1773             let member_name = member_description.name.as_bytes();
1774             let member_name = CString::new(member_name).unwrap();
1775             unsafe {
1776                 llvm::LLVMDIBuilderCreateMemberType(
1777                     DIB(cx),
1778                     composite_type_metadata,
1779                     member_name.as_ptr(),
1780                     NO_FILE_METADATA,
1781                     UNKNOWN_LINE_NUMBER,
1782                     bytes_to_bits(member_size),
1783                     bytes_to_bits(member_align),
1784                     bytes_to_bits(member_offset),
1785                     member_description.flags,
1786                     member_description.type_metadata)
1787             }
1788         })
1789         .collect();
1790
1791     unsafe {
1792         let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
1793         llvm::LLVMDICompositeTypeSetTypeArray(DIB(cx), composite_type_metadata, type_array);
1794     }
1795 }
1796
1797 // A convenience wrapper around LLVMDIBuilderCreateStructType(). Does not do any
1798 // caching, does not add any fields to the struct. This can be done later with
1799 // set_members_of_composite_type().
1800 fn create_struct_stub(cx: &CrateContext,
1801                       struct_llvm_type: Type,
1802                       struct_type_name: &str,
1803                       unique_type_id: UniqueTypeId,
1804                       containing_scope: DIScope)
1805                    -> DICompositeType {
1806     let (struct_size, struct_align) = size_and_align_of(cx, struct_llvm_type);
1807
1808     let unique_type_id_str = debug_context(cx).type_map
1809                                               .borrow()
1810                                               .get_unique_type_id_as_string(unique_type_id);
1811     let name = CString::new(struct_type_name).unwrap();
1812     let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
1813     let metadata_stub = unsafe {
1814         // LLVMDIBuilderCreateStructType() wants an empty array. A null
1815         // pointer will lead to hard to trace and debug LLVM assertions
1816         // later on in llvm/lib/IR/Value.cpp.
1817         let empty_array = create_DIArray(DIB(cx), &[]);
1818
1819         llvm::LLVMDIBuilderCreateStructType(
1820             DIB(cx),
1821             containing_scope,
1822             name.as_ptr(),
1823             NO_FILE_METADATA,
1824             UNKNOWN_LINE_NUMBER,
1825             bytes_to_bits(struct_size),
1826             bytes_to_bits(struct_align),
1827             0,
1828             ptr::null_mut(),
1829             empty_array,
1830             0,
1831             ptr::null_mut(),
1832             unique_type_id.as_ptr())
1833     };
1834
1835     return metadata_stub;
1836 }
1837
1838 /// Creates debug information for the given global variable.
1839 ///
1840 /// Adds the created metadata nodes directly to the crate's IR.
1841 pub fn create_global_var_metadata(cx: &CrateContext,
1842                                   node_id: ast::NodeId,
1843                                   global: ValueRef) {
1844     if cx.dbg_cx().is_none() {
1845         return;
1846     }
1847
1848     // Don't create debuginfo for globals inlined from other crates. The other
1849     // crate should already contain debuginfo for it. More importantly, the
1850     // global might not even exist in un-inlined form anywhere which would lead
1851     // to a linker errors.
1852     if cx.external_srcs().borrow().contains_key(&node_id) {
1853         return;
1854     }
1855
1856     let var_item = cx.tcx().map.get(node_id);
1857
1858     let (name, span) = match var_item {
1859         hir_map::NodeItem(item) => {
1860             match item.node {
1861                 hir::ItemStatic(..) => (item.name, item.span),
1862                 hir::ItemConst(..) => (item.name, item.span),
1863                 _ => {
1864                     cx.sess()
1865                       .span_bug(item.span,
1866                                 &format!("debuginfo::\
1867                                          create_global_var_metadata() -
1868                                          Captured var-id refers to \
1869                                          unexpected ast_item variant: {:?}",
1870                                         var_item))
1871                 }
1872             }
1873         },
1874         _ => cx.sess().bug(&format!("debuginfo::create_global_var_metadata() \
1875                                     - Captured var-id refers to unexpected \
1876                                     hir_map variant: {:?}",
1877                                    var_item))
1878     };
1879
1880     let (file_metadata, line_number) = if span != codemap::DUMMY_SP {
1881         let loc = span_start(cx, span);
1882         (file_metadata(cx, &loc.file.name), loc.line as c_uint)
1883     } else {
1884         (NO_FILE_METADATA, UNKNOWN_LINE_NUMBER)
1885     };
1886
1887     let is_local_to_unit = is_node_local_to_unit(cx, node_id);
1888     let variable_type = cx.tcx().node_id_to_type(node_id);
1889     let type_metadata = type_metadata(cx, variable_type, span);
1890     let namespace_node = namespace_for_item(cx, DefId::local(node_id));
1891     let var_name = name.to_string();
1892     let linkage_name =
1893         namespace_node.mangled_name_of_contained_item(&var_name[..]);
1894     let var_scope = namespace_node.scope;
1895
1896     let var_name = CString::new(var_name).unwrap();
1897     let linkage_name = CString::new(linkage_name).unwrap();
1898     unsafe {
1899         llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
1900                                                 var_scope,
1901                                                 var_name.as_ptr(),
1902                                                 linkage_name.as_ptr(),
1903                                                 file_metadata,
1904                                                 line_number,
1905                                                 type_metadata,
1906                                                 is_local_to_unit,
1907                                                 global,
1908                                                 ptr::null_mut());
1909     }
1910 }
1911
1912 /// Creates debug information for the given local variable.
1913 ///
1914 /// This function assumes that there's a datum for each pattern component of the
1915 /// local in `bcx.fcx.lllocals`.
1916 /// Adds the created metadata nodes directly to the crate's IR.
1917 pub fn create_local_var_metadata(bcx: Block, local: &hir::Local) {
1918     if bcx.unreachable.get() ||
1919        fn_should_be_ignored(bcx.fcx) ||
1920        bcx.sess().opts.debuginfo != FullDebugInfo  {
1921         return;
1922     }
1923
1924     let cx = bcx.ccx();
1925     let def_map = &cx.tcx().def_map;
1926     let locals = bcx.fcx.lllocals.borrow();
1927
1928     pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, var_ident| {
1929         let datum = match locals.get(&node_id) {
1930             Some(datum) => datum,
1931             None => {
1932                 bcx.sess().span_bug(span,
1933                     &format!("no entry in lllocals table for {}",
1934                             node_id));
1935             }
1936         };
1937
1938         if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() {
1939             cx.sess().span_bug(span, "debuginfo::create_local_var_metadata() - \
1940                                       Referenced variable location is not an alloca!");
1941         }
1942
1943         let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
1944
1945         declare_local(bcx,
1946                       var_ident.node.name,
1947                       datum.ty,
1948                       scope_metadata,
1949                       VariableAccess::DirectVariable { alloca: datum.val },
1950                       VariableKind::LocalVariable,
1951                       span);
1952     })
1953 }
1954
1955 /// Creates debug information for a variable captured in a closure.
1956 ///
1957 /// Adds the created metadata nodes directly to the crate's IR.
1958 pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1959                                                 node_id: ast::NodeId,
1960                                                 env_pointer: ValueRef,
1961                                                 env_index: usize,
1962                                                 captured_by_ref: bool,
1963                                                 span: Span) {
1964     if bcx.unreachable.get() ||
1965        fn_should_be_ignored(bcx.fcx) ||
1966        bcx.sess().opts.debuginfo != FullDebugInfo {
1967         return;
1968     }
1969
1970     let cx = bcx.ccx();
1971
1972     let ast_item = cx.tcx().map.find(node_id);
1973
1974     let variable_name = match ast_item {
1975         None => {
1976             cx.sess().span_bug(span, "debuginfo::create_captured_var_metadata: node not found");
1977         }
1978         Some(hir_map::NodeLocal(pat)) | Some(hir_map::NodeArg(pat)) => {
1979             match pat.node {
1980                 hir::PatIdent(_, ref path1, _) => {
1981                     path1.node.name
1982                 }
1983                 _ => {
1984                     cx.sess()
1985                       .span_bug(span,
1986                                 &format!(
1987                                 "debuginfo::create_captured_var_metadata() - \
1988                                  Captured var-id refers to unexpected \
1989                                  hir_map variant: {:?}",
1990                                  ast_item));
1991                 }
1992             }
1993         }
1994         _ => {
1995             cx.sess()
1996               .span_bug(span,
1997                         &format!("debuginfo::create_captured_var_metadata() - \
1998                                  Captured var-id refers to unexpected \
1999                                  hir_map variant: {:?}",
2000                                 ast_item));
2001         }
2002     };
2003
2004     let variable_type = common::node_id_type(bcx, node_id);
2005     let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata;
2006
2007     // env_pointer is the alloca containing the pointer to the environment,
2008     // so it's type is **EnvironmentType. In order to find out the type of
2009     // the environment we have to "dereference" two times.
2010     let llvm_env_data_type = common::val_ty(env_pointer).element_type()
2011                                                         .element_type();
2012     let byte_offset_of_var_in_env = machine::llelement_offset(cx,
2013                                                               llvm_env_data_type,
2014                                                               env_index);
2015
2016     let address_operations = unsafe {
2017         [llvm::LLVMDIBuilderCreateOpDeref(),
2018          llvm::LLVMDIBuilderCreateOpPlus(),
2019          byte_offset_of_var_in_env as i64,
2020          llvm::LLVMDIBuilderCreateOpDeref()]
2021     };
2022
2023     let address_op_count = if captured_by_ref {
2024         address_operations.len()
2025     } else {
2026         address_operations.len() - 1
2027     };
2028
2029     let variable_access = VariableAccess::IndirectVariable {
2030         alloca: env_pointer,
2031         address_operations: &address_operations[..address_op_count]
2032     };
2033
2034     declare_local(bcx,
2035                   variable_name,
2036                   variable_type,
2037                   scope_metadata,
2038                   variable_access,
2039                   VariableKind::CapturedVariable,
2040                   span);
2041 }
2042
2043 /// Creates debug information for a local variable introduced in the head of a
2044 /// match-statement arm.
2045 ///
2046 /// Adds the created metadata nodes directly to the crate's IR.
2047 pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
2048                                                  variable_name: ast::Name,
2049                                                  binding: BindingInfo<'tcx>) {
2050     if bcx.unreachable.get() ||
2051        fn_should_be_ignored(bcx.fcx) ||
2052        bcx.sess().opts.debuginfo != FullDebugInfo {
2053         return;
2054     }
2055
2056     let scope_metadata = scope_metadata(bcx.fcx, binding.id, binding.span);
2057     let aops = unsafe {
2058         [llvm::LLVMDIBuilderCreateOpDeref()]
2059     };
2060     // Regardless of the actual type (`T`) we're always passed the stack slot
2061     // (alloca) for the binding. For ByRef bindings that's a `T*` but for ByMove
2062     // bindings we actually have `T**`. So to get the actual variable we need to
2063     // dereference once more. For ByCopy we just use the stack slot we created
2064     // for the binding.
2065     let var_access = match binding.trmode {
2066         TransBindingMode::TrByCopy(llbinding) |
2067         TransBindingMode::TrByMoveIntoCopy(llbinding) => VariableAccess::DirectVariable {
2068             alloca: llbinding
2069         },
2070         TransBindingMode::TrByMoveRef => VariableAccess::IndirectVariable {
2071             alloca: binding.llmatch,
2072             address_operations: &aops
2073         },
2074         TransBindingMode::TrByRef => VariableAccess::DirectVariable {
2075             alloca: binding.llmatch
2076         }
2077     };
2078
2079     declare_local(bcx,
2080                   variable_name,
2081                   binding.ty,
2082                   scope_metadata,
2083                   var_access,
2084                   VariableKind::LocalVariable,
2085                   binding.span);
2086 }
2087
2088 /// Creates debug information for the given function argument.
2089 ///
2090 /// This function assumes that there's a datum for each pattern component of the
2091 /// argument in `bcx.fcx.lllocals`.
2092 /// Adds the created metadata nodes directly to the crate's IR.
2093 pub fn create_argument_metadata(bcx: Block, arg: &hir::Arg) {
2094     if bcx.unreachable.get() ||
2095        fn_should_be_ignored(bcx.fcx) ||
2096        bcx.sess().opts.debuginfo != FullDebugInfo {
2097         return;
2098     }
2099
2100     let def_map = &bcx.tcx().def_map;
2101     let scope_metadata = bcx
2102                          .fcx
2103                          .debug_context
2104                          .get_ref(bcx.ccx(), arg.pat.span)
2105                          .fn_metadata;
2106     let locals = bcx.fcx.lllocals.borrow();
2107
2108     pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, var_ident| {
2109         let datum = match locals.get(&node_id) {
2110             Some(v) => v,
2111             None => {
2112                 bcx.sess().span_bug(span,
2113                     &format!("no entry in lllocals table for {}",
2114                             node_id));
2115             }
2116         };
2117
2118         if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() {
2119             bcx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \
2120                                        Referenced variable location is not an alloca!");
2121         }
2122
2123         let argument_index = {
2124             let counter = &bcx
2125                           .fcx
2126                           .debug_context
2127                           .get_ref(bcx.ccx(), span)
2128                           .argument_counter;
2129             let argument_index = counter.get();
2130             counter.set(argument_index + 1);
2131             argument_index
2132         };
2133
2134         declare_local(bcx,
2135                       var_ident.node.name,
2136                       datum.ty,
2137                       scope_metadata,
2138                       VariableAccess::DirectVariable { alloca: datum.val },
2139                       VariableKind::ArgumentVariable(argument_index),
2140                       span);
2141     })
2142 }