]> git.lizzy.rs Git - rust.git/blob - src/librustc/middle/trans/debuginfo.rs
Rename all raw pointers as necessary
[rust.git] / src / librustc / middle / trans / debuginfo.rs
1 // Copyright 2012-2014 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 /*!
12 # Debug Info Module
13
14 This module serves the purpose of generating debug symbols. We use LLVM's
15 [source level debugging](http://llvm.org/docs/SourceLevelDebugging.html)
16 features for generating the debug information. The general principle is this:
17
18 Given the right metadata in the LLVM IR, the LLVM code generator is able to
19 create DWARF debug symbols for the given code. The
20 [metadata](http://llvm.org/docs/LangRef.html#metadata-type) is structured much
21 like DWARF *debugging information entries* (DIE), representing type information
22 such as datatype layout, function signatures, block layout, variable location
23 and scope information, etc. It is the purpose of this module to generate correct
24 metadata and insert it into the LLVM IR.
25
26 As the exact format of metadata trees may change between different LLVM
27 versions, we now use LLVM
28 [DIBuilder](http://llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html) to
29 create metadata where possible. This will hopefully ease the adaption of this
30 module to future LLVM versions.
31
32 The public API of the module is a set of functions that will insert the correct
33 metadata into the LLVM IR when called with the right parameters. The module is
34 thus driven from an outside client with functions like
35 `debuginfo::create_local_var_metadata(bcx: block, local: &ast::local)`.
36
37 Internally the module will try to reuse already created metadata by utilizing a
38 cache. The way to get a shared metadata node when needed is thus to just call
39 the corresponding function in this module:
40
41     let file_metadata = file_metadata(crate_context, path);
42
43 The function will take care of probing the cache for an existing node for that
44 exact file path.
45
46 All private state used by the module is stored within either the
47 CrateDebugContext struct (owned by the CrateContext) or the FunctionDebugContext
48 (owned by the FunctionContext).
49
50 This file consists of three conceptual sections:
51 1. The public interface of the module
52 2. Module-internal metadata creation functions
53 3. Minor utility functions
54
55
56 ## Recursive Types Some kinds of types, such as structs and enums can be
57 recursive. That means that the type definition of some type X refers to some
58 other type which in turn (transitively) refers to X. This introduces cycles into
59 the type referral graph. A naive algorithm doing an on-demand, depth-first
60 traversal of this graph when describing types, can get trapped in an endless
61 loop when it reaches such a cycle.
62
63 For example, the following simple type for a singly-linked list...
64
65 ```
66 struct List {
67     value: int,
68     tail: Option<Box<List>>,
69 }
70 ```
71
72 will generate the following callstack with a naive DFS algorithm:
73
74 ```
75 describe(t = List)
76   describe(t = int)
77   describe(t = Option<Box<List>>)
78     describe(t = Box<List>)
79       describe(t = List) // at the beginning again...
80       ...
81 ```
82
83 To break cycles like these, we use "forward declarations". That is, when the
84 algorithm encounters a possibly recursive type (any struct or enum), it
85 immediately creates a type description node and inserts it into the cache
86 *before* describing the members of the type. This type description is just a
87 stub (as type members are not described and added to it yet) but it allows the
88 algorithm to already refer to the type. After the stub is inserted into the
89 cache, the algorithm continues as before. If it now encounters a recursive
90 reference, it will hit the cache and does not try to describe the type anew.
91
92 This behaviour is encapsulated in the 'RecursiveTypeDescription' enum, which
93 represents a kind of continuation, storing all state needed to continue
94 traversal at the type members after the type has been registered with the cache.
95 (This implementation approach might be a tad over-engineered and may change in
96 the future)
97
98
99 ## Source Locations and Line Information In addition to data type descriptions
100 the debugging information must also allow to map machine code locations back to
101 source code locations in order to be useful. This functionality is also handled
102 in this module. The following functions allow to control source mappings:
103
104 + set_source_location()
105 + clear_source_location()
106 + start_emitting_source_locations()
107
108 `set_source_location()` allows to set the current source location. All IR
109 instructions created after a call to this function will be linked to the given
110 source location, until another location is specified with
111 `set_source_location()` or the source location is cleared with
112 `clear_source_location()`. In the later case, subsequent IR instruction will not
113 be linked to any source location. As you can see, this is a stateful API
114 (mimicking the one in LLVM), so be careful with source locations set by previous
115 calls. It's probably best to not rely on any specific state being present at a
116 given point in code.
117
118 One topic that deserves some extra attention is *function prologues*. At the
119 beginning of a function's machine code there are typically a few instructions
120 for loading argument values into allocas and checking if there's enough stack
121 space for the function to execute. This *prologue* is not visible in the source
122 code and LLVM puts a special PROLOGUE END marker into the line table at the
123 first non-prologue instruction of the function. In order to find out where the
124 prologue ends, LLVM looks for the first instruction in the function body that is
125 linked to a source location. So, when generating prologue instructions we have
126 to make sure that we don't emit source location information until the 'real'
127 function body begins. For this reason, source location emission is disabled by
128 default for any new function being translated and is only activated after a call
129 to the third function from the list above, `start_emitting_source_locations()`.
130 This function should be called right before regularly starting to translate the
131 top-level block of the given function.
132
133 There is one exception to the above rule: `llvm.dbg.declare` instruction must be
134 linked to the source location of the variable being declared. For function
135 parameters these `llvm.dbg.declare` instructions typically occur in the middle
136 of the prologue, however, they are ignored by LLVM's prologue detection. The
137 `create_argument_metadata()` and related functions take care of linking the
138 `llvm.dbg.declare` instructions to the correct source locations even while
139 source location emission is still disabled, so there is no need to do anything
140 special with source location handling here.
141
142 ## Unique Type Identification In order for link-time optimization to work
143 properly, LLVM needs a unique type identifier that tells it across compilation
144 units which types are the same as others. This type identifier is created by
145 TypeMap::get_unique_type_id_of_type() using the following algorithm:
146
147 (1) Primitive types have their name as ID
148 (2) Structs, enums and traits have a multipart identifier
149
150     (1) The first part is the SVH (strict version hash) of the crate they were
151         originally defined in
152
153     (2) The second part is the ast::NodeId of the definition in their original
154         crate
155
156     (3) The final part is a concatenation of the type IDs of their concrete type
157         arguments if they are generic types.
158
159 (3) Tuple-, pointer and function types are structurally identified, which means
160     that they are equivalent if their component types are equivalent (i.e. (int,
161     int) is the same regardless in which crate it is used).
162
163 This algorithm also provides a stable ID for types that are defined in one crate
164 but instantiated from metadata within another crate. We just have to take care
165 to always map crate and node IDs back to the original crate context.
166
167 As a side-effect these unique type IDs also help to solve a problem arising from
168 lifetime parameters. Since lifetime parameters are completely omitted in
169 debuginfo, more than one `ty::t` instance may map to the same debuginfo type
170 metadata, that is, some struct `Struct<'a>` may have N instantiations with
171 different concrete substitutions for `'a`, and thus there will be N `ty::t`
172 instances for the type `Struct<'a>` even though it is not generic otherwise.
173 Unfortunately this means that we cannot use `ty::type_id()` as cheap identifier
174 for type metadata---we have done this in the past, but it led to unnecessary
175 metadata duplication in the best case and LLVM assertions in the worst. However,
176 the unique type ID as described above *can* be used as identifier. Since it is
177 comparatively expensive to construct, though, `ty::type_id()` is still used
178 additionally as an optimization for cases where the exact same type has been
179 seen before (which is most of the time). */
180
181 use driver::config;
182 use driver::config::{FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
183 use lib::llvm::llvm;
184 use lib::llvm::{ModuleRef, ContextRef, ValueRef};
185 use lib::llvm::debuginfo::*;
186 use metadata::csearch;
187 use middle::subst;
188 use middle::trans::adt;
189 use middle::trans::common::*;
190 use middle::trans::datum::{Datum, Lvalue};
191 use middle::trans::machine;
192 use middle::trans::type_of;
193 use middle::trans::type_::Type;
194 use middle::trans;
195 use middle::ty;
196 use middle::pat_util;
197 use util::ppaux;
198
199 use libc::{c_uint, c_ulonglong, c_longlong};
200 use std::c_str::{CString, ToCStr};
201 use std::cell::{Cell, RefCell};
202 use std::collections::HashMap;
203 use std::collections::HashSet;
204 use std::gc::Gc;
205 use std::ptr;
206 use std::rc::{Rc, Weak};
207 use syntax::util::interner::Interner;
208 use syntax::codemap::{Span, Pos};
209 use syntax::{abi, ast, codemap, ast_util, ast_map};
210 use syntax::owned_slice::OwnedSlice;
211 use syntax::parse::token;
212 use syntax::parse::token::special_idents;
213
214 static DW_LANG_RUST: c_uint = 0x9000;
215
216 static DW_TAG_auto_variable: c_uint = 0x100;
217 static DW_TAG_arg_variable: c_uint = 0x101;
218
219 static DW_ATE_boolean: c_uint = 0x02;
220 static DW_ATE_float: c_uint = 0x04;
221 static DW_ATE_signed: c_uint = 0x05;
222 static DW_ATE_unsigned: c_uint = 0x07;
223 static DW_ATE_unsigned_char: c_uint = 0x08;
224
225 //=-----------------------------------------------------------------------------
226 //  Public Interface of debuginfo module
227 //=-----------------------------------------------------------------------------
228
229 #[deriving(Copy, Show, Hash, Eq, PartialEq, Clone)]
230 struct UniqueTypeId(ast::Name);
231
232 // The TypeMap is where the CrateDebugContext holds the type metadata nodes
233 // created so far. The metadata nodes are indexed by UniqueTypeId, and, for
234 // faster lookup, also by ty::t. The TypeMap is responsible for creating
235 // UniqueTypeIds.
236 struct TypeMap {
237     // The UniqueTypeIds created so far
238     unique_id_interner: Interner<Rc<String>>,
239     // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
240     unique_id_to_metadata: HashMap<UniqueTypeId, DIType>,
241     // A map from ty::type_id() to debuginfo metadata. This is a N:1 mapping.
242     type_to_metadata: HashMap<uint, DIType>,
243     // A map from ty::type_id() to UniqueTypeId. This is a N:1 mapping.
244     type_to_unique_id: HashMap<uint, UniqueTypeId>
245 }
246
247 impl TypeMap {
248
249     fn new() -> TypeMap {
250         TypeMap {
251             unique_id_interner: Interner::new(),
252             type_to_metadata: HashMap::new(),
253             unique_id_to_metadata: HashMap::new(),
254             type_to_unique_id: HashMap::new(),
255         }
256     }
257
258     // Adds a ty::t to metadata mapping to the TypeMap. The method will fail if
259     // the mapping already exists.
260     fn register_type_with_metadata(&mut self,
261                                    cx: &CrateContext,
262                                    type_: ty::t,
263                                    metadata: DIType) {
264         if !self.type_to_metadata.insert(ty::type_id(type_), metadata) {
265             cx.sess().bug(format!("Type metadata for ty::t '{}' is already in the TypeMap!",
266                                    ppaux::ty_to_str(cx.tcx(), type_)).as_slice());
267         }
268     }
269
270     // Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
271     // fail if the mapping already exists.
272     fn register_unique_id_with_metadata(&mut self,
273                                         cx: &CrateContext,
274                                         unique_type_id: UniqueTypeId,
275                                         metadata: DIType) {
276         if !self.unique_id_to_metadata.insert(unique_type_id, metadata) {
277             let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id);
278             cx.sess().bug(format!("Type metadata for unique id '{}' is already in the TypeMap!",
279                                   unique_type_id_str.as_slice()).as_slice());
280         }
281     }
282
283     fn find_metadata_for_type(&self, type_: ty::t) -> Option<DIType> {
284         self.type_to_metadata.find_copy(&ty::type_id(type_))
285     }
286
287     fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<DIType> {
288         self.unique_id_to_metadata.find_copy(&unique_type_id)
289     }
290
291     // Get the string representation of a UniqueTypeId. This method will fail if
292     // the id is unknown.
293     fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> Rc<String> {
294         let UniqueTypeId(interner_key) = unique_type_id;
295         self.unique_id_interner.get(interner_key)
296     }
297
298     // Get the UniqueTypeId for the given type. If the UniqueTypeId for the given
299     // type has been requested before, this is just a table lookup. Otherwise an
300     // ID will be generated and stored for later lookup.
301     fn get_unique_type_id_of_type(&mut self, cx: &CrateContext, type_: ty::t) -> UniqueTypeId {
302
303         // basic type           -> {:name of the type:}
304         // tuple                -> {tuple_(:param-uid:)*}
305         // struct               -> {struct_:svh: / :node-id:_<(:param-uid:),*> }
306         // enum                 -> {enum_:svh: / :node-id:_<(:param-uid:),*> }
307         // enum variant         -> {variant_:variant-name:_:enum-uid:}
308         // reference (&)        -> {& :pointee-uid:}
309         // mut reference (&mut) -> {&mut :pointee-uid:}
310         // ptr (*)              -> {* :pointee-uid:}
311         // mut ptr (*mut)       -> {*mut :pointee-uid:}
312         // unique ptr (~)       -> {~ :pointee-uid:}
313         // @-ptr (@)            -> {@ :pointee-uid:}
314         // sized vec ([T, ..x]) -> {[:size:] :element-uid:}
315         // unsized vec ([T])    -> {[] :element-uid:}
316         // trait (T)            -> {trait_:svh: / :node-id:_<(:param-uid:),*> }
317         // closure              -> {<unsafe_> <once_> :store-sigil: |(:param-uid:),* <,_...>| -> \
318         //                             :return-type-uid: : (:bounds:)*}
319         // function             -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \
320         //                             :return-type-uid:}
321         // unique vec box (~[]) -> {HEAP_VEC_BOX<:pointee-uid:>}
322         // gc box               -> {GC_BOX<:pointee-uid:>}
323
324         match self.type_to_unique_id.find_copy(&ty::type_id(type_)) {
325             Some(unique_type_id) => return unique_type_id,
326             None => { /* generate one */}
327         };
328
329         let mut unique_type_id = String::with_capacity(256);
330         unique_type_id.push_char('{');
331
332         match ty::get(type_).sty {
333             ty::ty_nil                |
334             ty::ty_bot                |
335             ty::ty_bool               |
336             ty::ty_char               |
337             ty::ty_str                |
338             ty::ty_int(_)             |
339             ty::ty_uint(_)            |
340             ty::ty_float(_) => {
341                 unique_type_id.push_str(ppaux::ty_to_str(cx.tcx(), type_).as_slice());
342             },
343             ty::ty_enum(def_id, ref substs) => {
344                 unique_type_id.push_str("enum ");
345                 from_def_id_and_substs(self, cx, def_id, substs, &mut unique_type_id);
346             },
347             ty::ty_struct(def_id, ref substs) => {
348                 unique_type_id.push_str("struct ");
349                 from_def_id_and_substs(self, cx, def_id, substs, &mut unique_type_id);
350             },
351             ty::ty_tup(ref component_types) => {
352                 unique_type_id.push_str("tuple ");
353                 for &component_type in component_types.iter() {
354                     let component_type_id =
355                         self.get_unique_type_id_of_type(cx, component_type);
356                     let component_type_id =
357                         self.get_unique_type_id_as_string(component_type_id);
358                     unique_type_id.push_str(component_type_id.as_slice());
359                 }
360             },
361             ty::ty_box(inner_type) => {
362                 unique_type_id.push_char('@');
363                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
364                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
365                 unique_type_id.push_str(inner_type_id.as_slice());
366             },
367             ty::ty_uniq(inner_type) => {
368                 unique_type_id.push_char('~');
369                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
370                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
371                 unique_type_id.push_str(inner_type_id.as_slice());
372             },
373             ty::ty_ptr(ty::mt { ty: inner_type, mutbl } ) => {
374                 unique_type_id.push_char('*');
375                 if mutbl == ast::MutMutable {
376                     unique_type_id.push_str("mut");
377                 }
378
379                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
380                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
381                 unique_type_id.push_str(inner_type_id.as_slice());
382             },
383             ty::ty_rptr(_, ty::mt { ty: inner_type, mutbl }) => {
384                 unique_type_id.push_char('&');
385                 if mutbl == ast::MutMutable {
386                     unique_type_id.push_str("mut");
387                 }
388
389                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
390                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
391                 unique_type_id.push_str(inner_type_id.as_slice());
392             },
393             ty::ty_vec(ty::mt { ty: inner_type, .. }, optional_length) => {
394                 match optional_length {
395                     Some(len) => {
396                         unique_type_id.push_str(format!("[{}]", len).as_slice());
397                     }
398                     None => {
399                         unique_type_id.push_str("[]");
400                     }
401                 };
402
403                 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
404                 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
405                 unique_type_id.push_str(inner_type_id.as_slice());
406             },
407             ty::ty_trait(ref trait_data) => {
408                 unique_type_id.push_str("trait ");
409
410                 from_def_id_and_substs(self,
411                                        cx,
412                                        trait_data.def_id,
413                                        &trait_data.substs,
414                                        &mut unique_type_id);
415             },
416             ty::ty_bare_fn(ty::BareFnTy{ fn_style, abi, ref sig } ) => {
417                 if fn_style == ast::UnsafeFn {
418                     unique_type_id.push_str("unsafe ");
419                 }
420
421                 unique_type_id.push_str(abi.name());
422
423                 unique_type_id.push_str(" fn(");
424
425                 for &parameter_type in sig.inputs.iter() {
426                     let parameter_type_id =
427                         self.get_unique_type_id_of_type(cx, parameter_type);
428                     let parameter_type_id =
429                         self.get_unique_type_id_as_string(parameter_type_id);
430                     unique_type_id.push_str(parameter_type_id.as_slice());
431                     unique_type_id.push_char(',');
432                 }
433
434                 if sig.variadic {
435                     unique_type_id.push_str("...");
436                 }
437
438                 unique_type_id.push_str(")->");
439                 let return_type_id = self.get_unique_type_id_of_type(cx, sig.output);
440                 let return_type_id = self.get_unique_type_id_as_string(return_type_id);
441                 unique_type_id.push_str(return_type_id.as_slice());
442             },
443             ty::ty_closure(box ty::ClosureTy { fn_style,
444                                                onceness,
445                                                store,
446                                                ref bounds,
447                                                ref sig }) => {
448                 if fn_style == ast::UnsafeFn {
449                     unique_type_id.push_str("unsafe ");
450                 }
451
452                 if onceness == ast::Once {
453                     unique_type_id.push_str("once ");
454                 }
455
456                 match store {
457                     ty::UniqTraitStore => unique_type_id.push_str("~|"),
458                     ty::RegionTraitStore(_, ast::MutMutable) => {
459                         unique_type_id.push_str("&mut|")
460                     }
461                     ty::RegionTraitStore(_, ast::MutImmutable) => {
462                         unique_type_id.push_str("&|")
463                     }
464                 };
465
466                 for &parameter_type in sig.inputs.iter() {
467                     let parameter_type_id =
468                         self.get_unique_type_id_of_type(cx, parameter_type);
469                     let parameter_type_id =
470                         self.get_unique_type_id_as_string(parameter_type_id);
471                     unique_type_id.push_str(parameter_type_id.as_slice());
472                     unique_type_id.push_char(',');
473                 }
474
475                 if sig.variadic {
476                     unique_type_id.push_str("...");
477                 }
478
479                 unique_type_id.push_str("|->");
480
481                 let return_type_id = self.get_unique_type_id_of_type(cx, sig.output);
482                 let return_type_id = self.get_unique_type_id_as_string(return_type_id);
483                 unique_type_id.push_str(return_type_id.as_slice());
484
485                 unique_type_id.push_char(':');
486
487                 for bound in bounds.iter() {
488                     match bound {
489                         ty::BoundStatic => unique_type_id.push_str("'static"),
490                         ty::BoundSend => unique_type_id.push_str("Send"),
491                         ty::BoundSized => unique_type_id.push_str("Sized"),
492                         ty::BoundCopy => unique_type_id.push_str("Copy"),
493                         ty::BoundShare => unique_type_id.push_str("Share"),
494                     };
495                     unique_type_id.push_char('+');
496                 }
497             },
498             _ => {
499                 cx.sess().bug(format!("get_unique_type_id_of_type() - unexpected type: {}, {:?}",
500                                       ppaux::ty_to_str(cx.tcx(), type_).as_slice(),
501                                       ty::get(type_).sty).as_slice())
502             }
503         };
504
505         unique_type_id.push_char('}');
506
507         // Trim to size before storing permanently
508         unique_type_id.shrink_to_fit();
509
510         let key = self.unique_id_interner.intern(Rc::new(unique_type_id));
511         self.type_to_unique_id.insert(ty::type_id(type_), UniqueTypeId(key));
512
513         return UniqueTypeId(key);
514
515         fn from_def_id_and_substs(type_map: &mut TypeMap,
516                                   cx: &CrateContext,
517                                   def_id: ast::DefId,
518                                   substs: &subst::Substs,
519                                   output: &mut String) {
520             use std::num::ToStrRadix;
521
522             // First, find out the 'real' def_id of the type. Items inlined from
523             // other crates have to be mapped back to their source.
524             let source_def_id = if def_id.krate == ast::LOCAL_CRATE {
525                 match cx.external_srcs.borrow().find_copy(&def_id.node) {
526                     Some(source_def_id) => {
527                         // The given def_id identifies the inlined copy of a
528                         // type definition, let's take the source of the copy.
529                         source_def_id
530                     }
531                     None => def_id
532                 }
533             } else {
534                 def_id
535             };
536
537             // Get the crate hash as first part of the identifier.
538             let crate_hash = if source_def_id.krate == ast::LOCAL_CRATE {
539                 cx.link_meta.crate_hash.clone()
540             } else {
541                 cx.sess().cstore.get_crate_hash(source_def_id.krate)
542             };
543
544             output.push_str(crate_hash.as_str());
545             output.push_str("/");
546             output.push_str(def_id.node.to_str_radix(16).as_slice());
547
548             // Maybe check that there is no self type here.
549
550             let tps = substs.types.get_vec(subst::TypeSpace);
551             if tps.len() > 0 {
552                 output.push_char('<');
553
554                 for &type_parameter in tps.iter() {
555                     let param_type_id =
556                         type_map.get_unique_type_id_of_type(cx, type_parameter);
557                     let param_type_id =
558                         type_map.get_unique_type_id_as_string(param_type_id);
559                     output.push_str(param_type_id.as_slice());
560                     output.push_char(',');
561                 }
562
563                 output.push_char('>');
564             }
565         }
566     }
567
568     // Get the UniqueTypeId for an enum variant. Enum variants are not really
569     // types of their own, so they need special handling. We still need a
570     // UniqueTypeId for them, since to debuginfo they *are* real types.
571     fn get_unique_type_id_of_enum_variant(&mut self,
572                                           cx: &CrateContext,
573                                           enum_type: ty::t,
574                                           variant_name: &str)
575                                        -> UniqueTypeId {
576         let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
577         let enum_variant_type_id = format!("{}::{}",
578                                            self.get_unique_type_id_as_string(enum_type_id)
579                                                .as_slice(),
580                                            variant_name);
581         let interner_key = self.unique_id_interner.intern(Rc::new(enum_variant_type_id));
582         UniqueTypeId(interner_key)
583     }
584
585     fn get_unique_type_id_of_heap_vec_box(&mut self,
586                                           cx: &CrateContext,
587                                           element_type: ty::t)
588                                        -> UniqueTypeId {
589         let element_type_id = self.get_unique_type_id_of_type(cx, element_type);
590         let heap_vec_box_type_id = format!("$$HEAP_VEC_BOX<{}>$$",
591                                            self.get_unique_type_id_as_string(element_type_id)
592                                                .as_slice());
593         let interner_key = self.unique_id_interner.intern(Rc::new(heap_vec_box_type_id));
594         UniqueTypeId(interner_key)
595     }
596
597     fn get_unique_type_id_of_gc_box(&mut self,
598                                     cx: &CrateContext,
599                                     element_type: ty::t)
600                                  -> UniqueTypeId {
601         let element_type_id = self.get_unique_type_id_of_type(cx, element_type);
602         let gc_box_type_id = format!("$$GC_BOX<{}>$$",
603                                      self.get_unique_type_id_as_string(element_type_id)
604                                          .as_slice());
605         let interner_key = self.unique_id_interner.intern(Rc::new(gc_box_type_id));
606         UniqueTypeId(interner_key)
607     }
608 }
609
610
611 /// A context object for maintaining all state needed by the debuginfo module.
612 pub struct CrateDebugContext {
613     llcontext: ContextRef,
614     builder: DIBuilderRef,
615     current_debug_location: Cell<DebugLocation>,
616     created_files: RefCell<HashMap<String, DIFile>>,
617     created_enum_disr_types: RefCell<HashMap<ast::DefId, DIType>>,
618
619     type_map: RefCell<TypeMap>,
620     namespace_map: RefCell<HashMap<Vec<ast::Name>, Rc<NamespaceTreeNode>>>,
621
622     // This collection is used to assert that composite types (structs, enums,
623     // ...) have their members only set once:
624     composite_types_completed: RefCell<HashSet<DIType>>,
625 }
626
627 impl CrateDebugContext {
628     pub fn new(llmod: ModuleRef) -> CrateDebugContext {
629         debug!("CrateDebugContext::new");
630         let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) };
631         // DIBuilder inherits context from the module, so we'd better use the same one
632         let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
633         return CrateDebugContext {
634             llcontext: llcontext,
635             builder: builder,
636             current_debug_location: Cell::new(UnknownLocation),
637             created_files: RefCell::new(HashMap::new()),
638             created_enum_disr_types: RefCell::new(HashMap::new()),
639             type_map: RefCell::new(TypeMap::new()),
640             namespace_map: RefCell::new(HashMap::new()),
641             composite_types_completed: RefCell::new(HashSet::new()),
642         };
643     }
644 }
645
646 pub struct FunctionDebugContext {
647     repr: FunctionDebugContextRepr,
648 }
649
650 enum FunctionDebugContextRepr {
651     FunctionDebugContext(Box<FunctionDebugContextData>),
652     DebugInfoDisabled,
653     FunctionWithoutDebugInfo,
654 }
655
656 impl FunctionDebugContext {
657     fn get_ref<'a>(&'a self,
658                    cx: &CrateContext,
659                    span: Span)
660                    -> &'a FunctionDebugContextData {
661         match self.repr {
662             FunctionDebugContext(box ref data) => data,
663             DebugInfoDisabled => {
664                 cx.sess().span_bug(span,
665                                    FunctionDebugContext::debuginfo_disabled_message());
666             }
667             FunctionWithoutDebugInfo => {
668                 cx.sess().span_bug(span,
669                                    FunctionDebugContext::should_be_ignored_message());
670             }
671         }
672     }
673
674     fn debuginfo_disabled_message() -> &'static str {
675         "debuginfo: Error trying to access FunctionDebugContext although debug info is disabled!"
676     }
677
678     fn should_be_ignored_message() -> &'static str {
679         "debuginfo: Error trying to access FunctionDebugContext for function that should be \
680          ignored by debug info!"
681     }
682 }
683
684 struct FunctionDebugContextData {
685     scope_map: RefCell<HashMap<ast::NodeId, DIScope>>,
686     fn_metadata: DISubprogram,
687     argument_counter: Cell<uint>,
688     source_locations_enabled: Cell<bool>,
689 }
690
691 enum VariableAccess<'a> {
692     // The llptr given is an alloca containing the variable's value
693     DirectVariable { alloca: ValueRef },
694     // The llptr given is an alloca containing the start of some pointer chain
695     // leading to the variable's content.
696     IndirectVariable { alloca: ValueRef, address_operations: &'a [ValueRef] }
697 }
698
699 enum VariableKind {
700     ArgumentVariable(uint /*index*/),
701     LocalVariable,
702     CapturedVariable,
703 }
704
705 /// Create any deferred debug metadata nodes
706 pub fn finalize(cx: &CrateContext) {
707     if cx.dbg_cx.is_none() {
708         return;
709     }
710
711     debug!("finalize");
712     compile_unit_metadata(cx);
713     unsafe {
714         llvm::LLVMDIBuilderFinalize(DIB(cx));
715         llvm::LLVMDIBuilderDispose(DIB(cx));
716         // Debuginfo generation in LLVM by default uses a higher
717         // version of dwarf than OS X currently understands. We can
718         // instruct LLVM to emit an older version of dwarf, however,
719         // for OS X to understand. For more info see #11352
720         // This can be overridden using --llvm-opts -dwarf-version,N.
721         if cx.sess().targ_cfg.os == abi::OsMacos ||
722             cx.sess().targ_cfg.os == abi::OsiOS {
723             "Dwarf Version".with_c_str(
724                 |s| llvm::LLVMRustAddModuleFlag(cx.llmod, s, 2));
725         } else {
726             // FIXME(#13611) this is a kludge fix because the linux bots have
727             //               gdb 7.4 which doesn't understand dwarf4, we should
728             //               do something more graceful here.
729             "Dwarf Version".with_c_str(
730                 |s| llvm::LLVMRustAddModuleFlag(cx.llmod, s, 3));
731         }
732
733         // Prevent bitcode readers from deleting the debug info.
734         "Debug Info Version".with_c_str(
735             |s| llvm::LLVMRustAddModuleFlag(cx.llmod, s,
736                                             llvm::LLVMRustDebugMetadataVersion));
737     };
738 }
739
740 /// Creates debug information for the given global variable.
741 ///
742 /// Adds the created metadata nodes directly to the crate's IR.
743 pub fn create_global_var_metadata(cx: &CrateContext,
744                                   node_id: ast::NodeId,
745                                   global: ValueRef) {
746     if cx.dbg_cx.is_none() {
747         return;
748     }
749
750     // Don't create debuginfo for globals inlined from other crates. The other
751     // crate should already contain debuginfo for it. More importantly, the
752     // global might not even exist in un-inlined form anywhere which would lead
753     // to a linker errors.
754     if cx.external_srcs.borrow().contains_key(&node_id) {
755         return;
756     }
757
758     let var_item = cx.tcx.map.get(node_id);
759
760     let (ident, span) = match var_item {
761         ast_map::NodeItem(item) => {
762             match item.node {
763                 ast::ItemStatic(..) => (item.ident, item.span),
764                 _ => {
765                     cx.sess()
766                       .span_bug(item.span,
767                                 format!("debuginfo::\
768                                          create_global_var_metadata() -
769                                          Captured var-id refers to \
770                                          unexpected ast_item variant: {:?}",
771                                         var_item).as_slice())
772                 }
773             }
774         },
775         _ => cx.sess().bug(format!("debuginfo::create_global_var_metadata() \
776                                     - Captured var-id refers to unexpected \
777                                     ast_map variant: {:?}",
778                                    var_item).as_slice())
779     };
780
781     let filename = span_start(cx, span).file.name.clone();
782     let file_metadata = file_metadata(cx, filename.as_slice());
783
784     let is_local_to_unit = is_node_local_to_unit(cx, node_id);
785     let loc = span_start(cx, span);
786
787     let variable_type = ty::node_id_to_type(cx.tcx(), node_id);
788     let type_metadata = type_metadata(cx, variable_type, span);
789
790     let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
791     let var_name = token::get_ident(ident).get().to_str();
792     let linkage_name =
793         namespace_node.mangled_name_of_contained_item(var_name.as_slice());
794     let var_scope = namespace_node.scope;
795
796     var_name.as_slice().with_c_str(|var_name| {
797         linkage_name.as_slice().with_c_str(|linkage_name| {
798             unsafe {
799                 llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
800                                                         var_scope,
801                                                         var_name,
802                                                         linkage_name,
803                                                         file_metadata,
804                                                         loc.line as c_uint,
805                                                         type_metadata,
806                                                         is_local_to_unit,
807                                                         global,
808                                                         ptr::mut_null());
809             }
810         })
811     });
812 }
813
814 /// Creates debug information for the given local variable.
815 ///
816 /// Adds the created metadata nodes directly to the crate's IR.
817 pub fn create_local_var_metadata(bcx: &Block, local: &ast::Local) {
818     if fn_should_be_ignored(bcx.fcx) {
819         return;
820     }
821
822     let cx = bcx.ccx();
823     let def_map = &cx.tcx.def_map;
824
825     pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path_ref| {
826         let var_ident = ast_util::path_to_ident(path_ref);
827
828         let datum = match bcx.fcx.lllocals.borrow().find_copy(&node_id) {
829             Some(datum) => datum,
830             None => {
831                 bcx.sess().span_bug(span,
832                     format!("no entry in lllocals table for {:?}",
833                             node_id).as_slice());
834             }
835         };
836
837         let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
838
839         declare_local(bcx,
840                       var_ident,
841                       datum.ty,
842                       scope_metadata,
843                       DirectVariable { alloca: datum.val },
844                       LocalVariable,
845                       span);
846     })
847 }
848
849 /// Creates debug information for a variable captured in a closure.
850 ///
851 /// Adds the created metadata nodes directly to the crate's IR.
852 pub fn create_captured_var_metadata(bcx: &Block,
853                                     node_id: ast::NodeId,
854                                     env_data_type: ty::t,
855                                     env_pointer: ValueRef,
856                                     env_index: uint,
857                                     closure_store: ty::TraitStore,
858                                     span: Span) {
859     if fn_should_be_ignored(bcx.fcx) {
860         return;
861     }
862
863     let cx = bcx.ccx();
864
865     let ast_item = cx.tcx.map.find(node_id);
866
867     let variable_ident = match ast_item {
868         None => {
869             cx.sess().span_bug(span, "debuginfo::create_captured_var_metadata: node not found");
870         }
871         Some(ast_map::NodeLocal(pat)) | Some(ast_map::NodeArg(pat)) => {
872             match pat.node {
873                 ast::PatIdent(_, ref path, _) => {
874                     ast_util::path_to_ident(path)
875                 }
876                 _ => {
877                     cx.sess()
878                       .span_bug(span,
879                                 format!(
880                                 "debuginfo::create_captured_var_metadata() - \
881                                  Captured var-id refers to unexpected \
882                                  ast_map variant: {:?}",
883                                  ast_item).as_slice());
884                 }
885             }
886         }
887         _ => {
888             cx.sess()
889               .span_bug(span,
890                         format!("debuginfo::create_captured_var_metadata() - \
891                                  Captured var-id refers to unexpected \
892                                  ast_map variant: {:?}",
893                                 ast_item).as_slice());
894         }
895     };
896
897     let variable_type = node_id_type(bcx, node_id);
898     let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata;
899
900     let llvm_env_data_type = type_of::type_of(cx, env_data_type);
901     let byte_offset_of_var_in_env = machine::llelement_offset(cx,
902                                                               llvm_env_data_type,
903                                                               env_index);
904
905     let address_operations = unsafe {
906         [llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref()),
907          llvm::LLVMDIBuilderCreateOpPlus(Type::i64(cx).to_ref()),
908          C_i64(cx, byte_offset_of_var_in_env as i64),
909          llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref())]
910     };
911
912     let address_op_count = match closure_store {
913         ty::RegionTraitStore(..) => {
914             address_operations.len()
915         }
916         ty::UniqTraitStore => {
917             address_operations.len() - 1
918         }
919     };
920
921     let variable_access = IndirectVariable {
922         alloca: env_pointer,
923         address_operations: address_operations.slice_to(address_op_count)
924     };
925
926     declare_local(bcx,
927                   variable_ident,
928                   variable_type,
929                   scope_metadata,
930                   variable_access,
931                   CapturedVariable,
932                   span);
933 }
934
935 /// Creates debug information for a local variable introduced in the head of a
936 /// match-statement arm.
937 ///
938 /// Adds the created metadata nodes directly to the crate's IR.
939 pub fn create_match_binding_metadata(bcx: &Block,
940                                      variable_ident: ast::Ident,
941                                      node_id: ast::NodeId,
942                                      span: Span,
943                                      datum: Datum<Lvalue>) {
944     if fn_should_be_ignored(bcx.fcx) {
945         return;
946     }
947
948     let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
949
950     declare_local(bcx,
951                   variable_ident,
952                   datum.ty,
953                   scope_metadata,
954                   DirectVariable { alloca: datum.val },
955                   LocalVariable,
956                   span);
957 }
958
959 /// Creates debug information for the given function argument.
960 ///
961 /// Adds the created metadata nodes directly to the crate's IR.
962 pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) {
963     if fn_should_be_ignored(bcx.fcx) {
964         return;
965     }
966
967     let fcx = bcx.fcx;
968     let cx = fcx.ccx;
969
970     let def_map = &cx.tcx.def_map;
971     let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata;
972
973     pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path_ref| {
974         let llarg = match bcx.fcx.llargs.borrow().find_copy(&node_id) {
975             Some(v) => v,
976             None => {
977                 bcx.sess().span_bug(span,
978                     format!("no entry in llargs table for {:?}",
979                             node_id).as_slice());
980             }
981         };
982
983         if unsafe { llvm::LLVMIsAAllocaInst(llarg.val) } == ptr::mut_null() {
984             cx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \
985                                     Referenced variable location is not an alloca!");
986         }
987
988         let argument_ident = ast_util::path_to_ident(path_ref);
989
990         let argument_index = {
991             let counter = &fcx.debug_context.get_ref(cx, span).argument_counter;
992             let argument_index = counter.get();
993             counter.set(argument_index + 1);
994             argument_index
995         };
996
997         declare_local(bcx,
998                       argument_ident,
999                       llarg.ty,
1000                       scope_metadata,
1001                       DirectVariable { alloca: llarg.val },
1002                       ArgumentVariable(argument_index),
1003                       span);
1004     })
1005 }
1006
1007 /// Sets the current debug location at the beginning of the span.
1008 ///
1009 /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). The node_id
1010 /// parameter is used to reliably find the correct visibility scope for the code
1011 /// position.
1012 pub fn set_source_location(fcx: &FunctionContext,
1013                            node_id: ast::NodeId,
1014                            span: Span) {
1015     match fcx.debug_context.repr {
1016         DebugInfoDisabled => return,
1017         FunctionWithoutDebugInfo => {
1018             set_debug_location(fcx.ccx, UnknownLocation);
1019             return;
1020         }
1021         FunctionDebugContext(box ref function_debug_context) => {
1022             let cx = fcx.ccx;
1023
1024             debug!("set_source_location: {}", cx.sess().codemap().span_to_str(span));
1025
1026             if function_debug_context.source_locations_enabled.get() {
1027                 let loc = span_start(cx, span);
1028                 let scope = scope_metadata(fcx, node_id, span);
1029
1030                 set_debug_location(cx, DebugLocation::new(scope,
1031                                                           loc.line,
1032                                                           loc.col.to_uint()));
1033             } else {
1034                 set_debug_location(cx, UnknownLocation);
1035             }
1036         }
1037     }
1038 }
1039
1040 /// Clears the current debug location.
1041 ///
1042 /// Instructions generated hereafter won't be assigned a source location.
1043 pub fn clear_source_location(fcx: &FunctionContext) {
1044     if fn_should_be_ignored(fcx) {
1045         return;
1046     }
1047
1048     set_debug_location(fcx.ccx, UnknownLocation);
1049 }
1050
1051 /// Enables emitting source locations for the given functions.
1052 ///
1053 /// Since we don't want source locations to be emitted for the function prelude,
1054 /// they are disabled when beginning to translate a new function. This functions
1055 /// switches source location emitting on and must therefore be called before the
1056 /// first real statement/expression of the function is translated.
1057 pub fn start_emitting_source_locations(fcx: &FunctionContext) {
1058     match fcx.debug_context.repr {
1059         FunctionDebugContext(box ref data) => {
1060             data.source_locations_enabled.set(true)
1061         },
1062         _ => { /* safe to ignore */ }
1063     }
1064 }
1065
1066 /// Creates the function-specific debug context.
1067 ///
1068 /// Returns the FunctionDebugContext for the function which holds state needed
1069 /// for debug info creation. The function may also return another variant of the
1070 /// FunctionDebugContext enum which indicates why no debuginfo should be created
1071 /// for the function.
1072 pub fn create_function_debug_context(cx: &CrateContext,
1073                                      fn_ast_id: ast::NodeId,
1074                                      param_substs: &param_substs,
1075                                      llfn: ValueRef) -> FunctionDebugContext {
1076     if cx.sess().opts.debuginfo == NoDebugInfo {
1077         return FunctionDebugContext { repr: DebugInfoDisabled };
1078     }
1079
1080     // Clear the debug location so we don't assign them in the function prelude.
1081     // Do this here already, in case we do an early exit from this function.
1082     set_debug_location(cx, UnknownLocation);
1083
1084     if fn_ast_id == -1 {
1085         return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1086     }
1087
1088     let empty_generics = ast::Generics { lifetimes: Vec::new(),
1089                                          ty_params: OwnedSlice::empty() };
1090
1091     let fnitem = cx.tcx.map.get(fn_ast_id);
1092
1093     let (ident, fn_decl, generics, top_level_block, span, has_path) = match fnitem {
1094         ast_map::NodeItem(ref item) => {
1095             match item.node {
1096                 ast::ItemFn(fn_decl, _, _, ref generics, top_level_block) => {
1097                     (item.ident, fn_decl, generics, top_level_block, item.span, true)
1098                 }
1099                 _ => {
1100                     cx.sess().span_bug(item.span,
1101                         "create_function_debug_context: item bound to non-function");
1102                 }
1103             }
1104         }
1105         ast_map::NodeMethod(ref method) => {
1106             (method.ident,
1107              method.decl,
1108              &method.generics,
1109              method.body,
1110              method.span,
1111              true)
1112         }
1113         ast_map::NodeExpr(ref expr) => {
1114             match expr.node {
1115                 ast::ExprFnBlock(fn_decl, top_level_block) |
1116                 ast::ExprProc(fn_decl, top_level_block) => {
1117                     let name = format!("fn{}", token::gensym("fn"));
1118                     let name = token::str_to_ident(name.as_slice());
1119                     (name, fn_decl,
1120                         // This is not quite right. It should actually inherit
1121                         // the generics of the enclosing function.
1122                         &empty_generics,
1123                         top_level_block,
1124                         expr.span,
1125                         // Don't try to lookup the item path:
1126                         false)
1127                 }
1128                 _ => cx.sess().span_bug(expr.span,
1129                         "create_function_debug_context: expected an expr_fn_block here")
1130             }
1131         }
1132         ast_map::NodeTraitMethod(ref trait_method) => {
1133             match **trait_method {
1134                 ast::Provided(ref method) => {
1135                     (method.ident,
1136                      method.decl,
1137                      &method.generics,
1138                      method.body,
1139                      method.span,
1140                      true)
1141                 }
1142                 _ => {
1143                     cx.sess()
1144                       .bug(format!("create_function_debug_context: \
1145                                     unexpected sort of node: {:?}",
1146                                     fnitem).as_slice())
1147                 }
1148             }
1149         }
1150         ast_map::NodeForeignItem(..) |
1151         ast_map::NodeVariant(..) |
1152         ast_map::NodeStructCtor(..) => {
1153             return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1154         }
1155         _ => cx.sess().bug(format!("create_function_debug_context: \
1156                                     unexpected sort of node: {:?}",
1157                                    fnitem).as_slice())
1158     };
1159
1160     // This can be the case for functions inlined from another crate
1161     if span == codemap::DUMMY_SP {
1162         return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1163     }
1164
1165     let loc = span_start(cx, span);
1166     let file_metadata = file_metadata(cx, loc.file.name.as_slice());
1167
1168     let function_type_metadata = unsafe {
1169         let fn_signature = get_function_signature(cx,
1170                                                   fn_ast_id,
1171                                                   &*fn_decl,
1172                                                   param_substs,
1173                                                   span);
1174         llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
1175     };
1176
1177     // Get_template_parameters() will append a `<...>` clause to the function
1178     // name if necessary.
1179     let mut function_name = String::from_str(token::get_ident(ident).get());
1180     let template_parameters = get_template_parameters(cx,
1181                                                       generics,
1182                                                       param_substs,
1183                                                       file_metadata,
1184                                                       &mut function_name);
1185
1186     // There is no ast_map::Path for ast::ExprFnBlock-type functions. For now,
1187     // just don't put them into a namespace. In the future this could be improved
1188     // somehow (storing a path in the ast_map, or construct a path using the
1189     // enclosing function).
1190     let (linkage_name, containing_scope) = if has_path {
1191         let namespace_node = namespace_for_item(cx, ast_util::local_def(fn_ast_id));
1192         let linkage_name = namespace_node.mangled_name_of_contained_item(
1193             function_name.as_slice());
1194         let containing_scope = namespace_node.scope;
1195         (linkage_name, containing_scope)
1196     } else {
1197         (function_name.as_slice().to_string(), file_metadata)
1198     };
1199
1200     // Clang sets this parameter to the opening brace of the function's block,
1201     // so let's do this too.
1202     let scope_line = span_start(cx, top_level_block.span).line;
1203
1204     let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id);
1205
1206     let fn_metadata = function_name.as_slice().with_c_str(|function_name| {
1207                           linkage_name.as_slice().with_c_str(|linkage_name| {
1208             unsafe {
1209                 llvm::LLVMDIBuilderCreateFunction(
1210                     DIB(cx),
1211                     containing_scope,
1212                     function_name,
1213                     linkage_name,
1214                     file_metadata,
1215                     loc.line as c_uint,
1216                     function_type_metadata,
1217                     is_local_to_unit,
1218                     true,
1219                     scope_line as c_uint,
1220                     FlagPrototyped as c_uint,
1221                     cx.sess().opts.optimize != config::No,
1222                     llfn,
1223                     template_parameters,
1224                     ptr::mut_null())
1225             }
1226         })
1227     });
1228
1229     // Initialize fn debug context (including scope map and namespace map)
1230     let fn_debug_context = box FunctionDebugContextData {
1231         scope_map: RefCell::new(HashMap::new()),
1232         fn_metadata: fn_metadata,
1233         argument_counter: Cell::new(1),
1234         source_locations_enabled: Cell::new(false),
1235     };
1236
1237     let arg_pats = fn_decl.inputs.iter().map(|arg_ref| arg_ref.pat).collect::<Vec<_>>();
1238     populate_scope_map(cx,
1239                        arg_pats.as_slice(),
1240                        &*top_level_block,
1241                        fn_metadata,
1242                        &mut *fn_debug_context.scope_map.borrow_mut());
1243
1244     return FunctionDebugContext { repr: FunctionDebugContext(fn_debug_context) };
1245
1246     fn get_function_signature(cx: &CrateContext,
1247                               fn_ast_id: ast::NodeId,
1248                               fn_decl: &ast::FnDecl,
1249                               param_substs: &param_substs,
1250                               error_span: Span) -> DIArray {
1251         if cx.sess().opts.debuginfo == LimitedDebugInfo {
1252             return create_DIArray(DIB(cx), []);
1253         }
1254
1255         let mut signature = Vec::with_capacity(fn_decl.inputs.len() + 1);
1256
1257         // Return type -- llvm::DIBuilder wants this at index 0
1258         match fn_decl.output.node {
1259             ast::TyNil => {
1260                 signature.push(ptr::mut_null());
1261             }
1262             _ => {
1263                 assert_type_for_node_id(cx, fn_ast_id, error_span);
1264
1265                 let return_type = ty::node_id_to_type(cx.tcx(), fn_ast_id);
1266                 let return_type = return_type.substp(cx.tcx(), param_substs);
1267                 signature.push(type_metadata(cx, return_type, codemap::DUMMY_SP));
1268             }
1269         }
1270
1271         // Arguments types
1272         for arg in fn_decl.inputs.iter() {
1273             assert_type_for_node_id(cx, arg.pat.id, arg.pat.span);
1274             let arg_type = ty::node_id_to_type(cx.tcx(), arg.pat.id);
1275             let arg_type = arg_type.substp(cx.tcx(), param_substs);
1276             signature.push(type_metadata(cx, arg_type, codemap::DUMMY_SP));
1277         }
1278
1279         return create_DIArray(DIB(cx), signature.as_slice());
1280     }
1281
1282     fn get_template_parameters(cx: &CrateContext,
1283                                generics: &ast::Generics,
1284                                param_substs: &param_substs,
1285                                file_metadata: DIFile,
1286                                name_to_append_suffix_to: &mut String)
1287                                -> DIArray {
1288         let self_type = param_substs.substs.self_ty();
1289
1290         // Only true for static default methods:
1291         let has_self_type = self_type.is_some();
1292
1293         if !generics.is_type_parameterized() && !has_self_type {
1294             return create_DIArray(DIB(cx), []);
1295         }
1296
1297         name_to_append_suffix_to.push_char('<');
1298
1299         // The list to be filled with template parameters:
1300         let mut template_params: Vec<DIDescriptor> =
1301             Vec::with_capacity(generics.ty_params.len() + 1);
1302
1303         // Handle self type
1304         if has_self_type {
1305             let actual_self_type = self_type.unwrap();
1306             // Add self type name to <...> clause of function name
1307             let actual_self_type_name = ppaux::ty_to_str(cx.tcx(), actual_self_type);
1308             name_to_append_suffix_to.push_str(
1309                 actual_self_type_name.as_slice());
1310
1311             if generics.is_type_parameterized() {
1312                 name_to_append_suffix_to.push_str(",");
1313             }
1314
1315             // Only create type information if full debuginfo is enabled
1316             if cx.sess().opts.debuginfo == FullDebugInfo {
1317                 let actual_self_type_metadata = type_metadata(cx,
1318                                                               actual_self_type,
1319                                                               codemap::DUMMY_SP);
1320
1321                 let ident = special_idents::type_self;
1322
1323                 let param_metadata = token::get_ident(ident).get()
1324                                                             .with_c_str(|name| {
1325                     unsafe {
1326                         llvm::LLVMDIBuilderCreateTemplateTypeParameter(
1327                             DIB(cx),
1328                             file_metadata,
1329                             name,
1330                             actual_self_type_metadata,
1331                             ptr::mut_null(),
1332                             0,
1333                             0)
1334                     }
1335                 });
1336
1337                 template_params.push(param_metadata);
1338             }
1339         }
1340
1341         // Handle other generic parameters
1342         let actual_types = param_substs.substs.types.get_vec(subst::FnSpace);
1343         for (index, &ast::TyParam{ ident: ident, .. }) in generics.ty_params.iter().enumerate() {
1344             let actual_type = *actual_types.get(index);
1345             // Add actual type name to <...> clause of function name
1346             let actual_type_name = ppaux::ty_to_str(cx.tcx(), actual_type);
1347             name_to_append_suffix_to.push_str(actual_type_name.as_slice());
1348
1349             if index != generics.ty_params.len() - 1 {
1350                 name_to_append_suffix_to.push_str(",");
1351             }
1352
1353             // Again, only create type information if full debuginfo is enabled
1354             if cx.sess().opts.debuginfo == FullDebugInfo {
1355                 let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP);
1356                 let param_metadata = token::get_ident(ident).get()
1357                                                             .with_c_str(|name| {
1358                     unsafe {
1359                         llvm::LLVMDIBuilderCreateTemplateTypeParameter(
1360                             DIB(cx),
1361                             file_metadata,
1362                             name,
1363                             actual_type_metadata,
1364                             ptr::mut_null(),
1365                             0,
1366                             0)
1367                     }
1368                 });
1369                 template_params.push(param_metadata);
1370             }
1371         }
1372
1373         name_to_append_suffix_to.push_char('>');
1374
1375         return create_DIArray(DIB(cx), template_params.as_slice());
1376     }
1377 }
1378
1379 //=-----------------------------------------------------------------------------
1380 // Module-Internal debug info creation functions
1381 //=-----------------------------------------------------------------------------
1382
1383 fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
1384 {
1385     // The is_local_to_unit flag indicates whether a function is local to the
1386     // current compilation unit (i.e. if it is *static* in the C-sense). The
1387     // *reachable* set should provide a good approximation of this, as it
1388     // contains everything that might leak out of the current crate (by being
1389     // externally visible or by being inlined into something externally visible).
1390     // It might better to use the `exported_items` set from `driver::CrateAnalysis`
1391     // in the future, but (atm) this set is not available in the translation pass.
1392     !cx.reachable.contains(&node_id)
1393 }
1394
1395 #[allow(non_snake_case_functions)]
1396 fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
1397     return unsafe {
1398         llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
1399     };
1400 }
1401
1402 fn compile_unit_metadata(cx: &CrateContext) {
1403     let work_dir = &cx.sess().working_dir;
1404     let compile_unit_name = match cx.sess().local_crate_source_file {
1405         None => fallback_path(cx),
1406         Some(ref abs_path) => {
1407             if abs_path.is_relative() {
1408                 cx.sess().warn("debuginfo: Invalid path to crate's local root source file!");
1409                 fallback_path(cx)
1410             } else {
1411                 match abs_path.path_relative_from(work_dir) {
1412                     Some(ref p) if p.is_relative() => {
1413                             // prepend "./" if necessary
1414                             let dotdot = b"..";
1415                             let prefix = &[dotdot[0], ::std::path::SEP_BYTE];
1416                             let mut path_bytes = Vec::from_slice(p.as_vec());
1417
1418                             if path_bytes.slice_to(2) != prefix &&
1419                                path_bytes.slice_to(2) != dotdot {
1420                                 path_bytes.insert(0, prefix[0]);
1421                                 path_bytes.insert(1, prefix[1]);
1422                             }
1423
1424                             path_bytes.as_slice().to_c_str()
1425                         }
1426                     _ => fallback_path(cx)
1427                 }
1428             }
1429         }
1430     };
1431
1432     debug!("compile_unit_metadata: {:?}", compile_unit_name);
1433     let producer = format!("rustc version {}",
1434                            (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
1435
1436     compile_unit_name.with_ref(|compile_unit_name| {
1437         work_dir.as_vec().with_c_str(|work_dir| {
1438             producer.with_c_str(|producer| {
1439                 "".with_c_str(|flags| {
1440                     "".with_c_str(|split_name| {
1441                         unsafe {
1442                             llvm::LLVMDIBuilderCreateCompileUnit(
1443                                 debug_context(cx).builder,
1444                                 DW_LANG_RUST,
1445                                 compile_unit_name,
1446                                 work_dir,
1447                                 producer,
1448                                 cx.sess().opts.optimize != config::No,
1449                                 flags,
1450                                 0,
1451                                 split_name);
1452                         }
1453                     })
1454                 })
1455             })
1456         })
1457     });
1458
1459     fn fallback_path(cx: &CrateContext) -> CString {
1460         cx.link_meta.crateid.name.as_slice().to_c_str()
1461     }
1462 }
1463
1464 fn declare_local(bcx: &Block,
1465                  variable_ident: ast::Ident,
1466                  variable_type: ty::t,
1467                  scope_metadata: DIScope,
1468                  variable_access: VariableAccess,
1469                  variable_kind: VariableKind,
1470                  span: Span) {
1471     let cx: &CrateContext = bcx.ccx();
1472
1473     let filename = span_start(cx, span).file.name.clone();
1474     let file_metadata = file_metadata(cx, filename.as_slice());
1475
1476     let name = token::get_ident(variable_ident);
1477     let loc = span_start(cx, span);
1478     let type_metadata = type_metadata(cx, variable_type, span);
1479
1480     let (argument_index, dwarf_tag) = match variable_kind {
1481         ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
1482         LocalVariable    |
1483         CapturedVariable => (0, DW_TAG_auto_variable)
1484     };
1485
1486     let (var_alloca, var_metadata) = name.get().with_c_str(|name| {
1487         match variable_access {
1488             DirectVariable { alloca } => (
1489                 alloca,
1490                 unsafe {
1491                     llvm::LLVMDIBuilderCreateLocalVariable(
1492                         DIB(cx),
1493                         dwarf_tag,
1494                         scope_metadata,
1495                         name,
1496                         file_metadata,
1497                         loc.line as c_uint,
1498                         type_metadata,
1499                         cx.sess().opts.optimize != config::No,
1500                         0,
1501                         argument_index)
1502                 }
1503             ),
1504             IndirectVariable { alloca, address_operations } => (
1505                 alloca,
1506                 unsafe {
1507                     llvm::LLVMDIBuilderCreateComplexVariable(
1508                         DIB(cx),
1509                         dwarf_tag,
1510                         scope_metadata,
1511                         name,
1512                         file_metadata,
1513                         loc.line as c_uint,
1514                         type_metadata,
1515                         address_operations.as_ptr(),
1516                         address_operations.len() as c_uint,
1517                         argument_index)
1518                 }
1519             )
1520         }
1521     });
1522
1523     set_debug_location(cx, DebugLocation::new(scope_metadata,
1524                                               loc.line,
1525                                               loc.col.to_uint()));
1526     unsafe {
1527         let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
1528             DIB(cx),
1529             var_alloca,
1530             var_metadata,
1531             bcx.llbb);
1532
1533         llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
1534     }
1535
1536     match variable_kind {
1537         ArgumentVariable(_) | CapturedVariable => {
1538             assert!(!bcx.fcx
1539                         .debug_context
1540                         .get_ref(cx, span)
1541                         .source_locations_enabled
1542                         .get());
1543             set_debug_location(cx, UnknownLocation);
1544         }
1545         _ => { /* nothing to do */ }
1546     }
1547 }
1548
1549 fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
1550     match debug_context(cx).created_files.borrow().find_equiv(&full_path) {
1551         Some(file_metadata) => return *file_metadata,
1552         None => ()
1553     }
1554
1555     debug!("file_metadata: {}", full_path);
1556
1557     // FIXME (#9639): This needs to handle non-utf8 paths
1558     let work_dir = cx.sess().working_dir.as_str().unwrap();
1559     let file_name =
1560         if full_path.starts_with(work_dir) {
1561             full_path.slice(work_dir.len() + 1u, full_path.len())
1562         } else {
1563             full_path
1564         };
1565
1566     let file_metadata =
1567         file_name.with_c_str(|file_name| {
1568             work_dir.with_c_str(|work_dir| {
1569                 unsafe {
1570                     llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir)
1571                 }
1572             })
1573         });
1574
1575     let mut created_files = debug_context(cx).created_files.borrow_mut();
1576     created_files.insert(full_path.to_string(), file_metadata);
1577     return file_metadata;
1578 }
1579
1580 /// Finds the scope metadata node for the given AST node.
1581 fn scope_metadata(fcx: &FunctionContext,
1582                   node_id: ast::NodeId,
1583                   span: Span)
1584                -> DIScope {
1585     let scope_map = &fcx.debug_context.get_ref(fcx.ccx, span).scope_map;
1586     match scope_map.borrow().find_copy(&node_id) {
1587         Some(scope_metadata) => scope_metadata,
1588         None => {
1589             let node = fcx.ccx.tcx.map.get(node_id);
1590
1591             fcx.ccx.sess().span_bug(span,
1592                 format!("debuginfo: Could not find scope info for node {:?}",
1593                         node).as_slice());
1594         }
1595     }
1596 }
1597
1598 fn basic_type_metadata(cx: &CrateContext, t: ty::t) -> DIType {
1599
1600     debug!("basic_type_metadata: {:?}", ty::get(t));
1601
1602     let (name, encoding) = match ty::get(t).sty {
1603         ty::ty_nil => ("()".to_string(), DW_ATE_unsigned),
1604         ty::ty_bot => ("!".to_string(), DW_ATE_unsigned),
1605         ty::ty_bool => ("bool".to_string(), DW_ATE_boolean),
1606         ty::ty_char => ("char".to_string(), DW_ATE_unsigned_char),
1607         ty::ty_int(int_ty) => match int_ty {
1608             ast::TyI => ("int".to_string(), DW_ATE_signed),
1609             ast::TyI8 => ("i8".to_string(), DW_ATE_signed),
1610             ast::TyI16 => ("i16".to_string(), DW_ATE_signed),
1611             ast::TyI32 => ("i32".to_string(), DW_ATE_signed),
1612             ast::TyI64 => ("i64".to_string(), DW_ATE_signed)
1613         },
1614         ty::ty_uint(uint_ty) => match uint_ty {
1615             ast::TyU => ("uint".to_string(), DW_ATE_unsigned),
1616             ast::TyU8 => ("u8".to_string(), DW_ATE_unsigned),
1617             ast::TyU16 => ("u16".to_string(), DW_ATE_unsigned),
1618             ast::TyU32 => ("u32".to_string(), DW_ATE_unsigned),
1619             ast::TyU64 => ("u64".to_string(), DW_ATE_unsigned)
1620         },
1621         ty::ty_float(float_ty) => match float_ty {
1622             ast::TyF32 => ("f32".to_string(), DW_ATE_float),
1623             ast::TyF64 => ("f64".to_string(), DW_ATE_float),
1624         },
1625         _ => cx.sess().bug("debuginfo::basic_type_metadata - t is invalid type")
1626     };
1627
1628     let llvm_type = type_of::type_of(cx, t);
1629     let (size, align) = size_and_align_of(cx, llvm_type);
1630     let ty_metadata = name.with_c_str(|name| {
1631         unsafe {
1632             llvm::LLVMDIBuilderCreateBasicType(
1633                 DIB(cx),
1634                 name,
1635                 bytes_to_bits(size),
1636                 bytes_to_bits(align),
1637                 encoding)
1638         }
1639     });
1640
1641     return ty_metadata;
1642 }
1643
1644 fn pointer_type_metadata(cx: &CrateContext,
1645                          pointer_type: ty::t,
1646                          pointee_type_metadata: DIType)
1647                       -> DIType {
1648     let pointer_llvm_type = type_of::type_of(cx, pointer_type);
1649     let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
1650     let name = ppaux::ty_to_str(cx.tcx(), pointer_type);
1651     let ptr_metadata = name.as_slice().with_c_str(|name| {
1652         unsafe {
1653             llvm::LLVMDIBuilderCreatePointerType(
1654                 DIB(cx),
1655                 pointee_type_metadata,
1656                 bytes_to_bits(pointer_size),
1657                 bytes_to_bits(pointer_align),
1658                 name)
1659         }
1660     });
1661     return ptr_metadata;
1662 }
1663
1664 //=-----------------------------------------------------------------------------
1665 // Common facilities for record-like types (structs, enums, tuples)
1666 //=-----------------------------------------------------------------------------
1667
1668 enum MemberOffset {
1669     FixedMemberOffset { bytes: uint },
1670     // For ComputedMemberOffset, the offset is read from the llvm type definition
1671     ComputedMemberOffset
1672 }
1673
1674 // Description of a type member, which can either be a regular field (as in
1675 // structs or tuples) or an enum variant
1676 struct MemberDescription {
1677     name: String,
1678     llvm_type: Type,
1679     type_metadata: DIType,
1680     offset: MemberOffset,
1681 }
1682
1683 // A factory for MemberDescriptions. It produces a list of member descriptions
1684 // for some record-like type. MemberDescriptionFactories are used to defer the
1685 // creation of type member descriptions in order to break cycles arising from
1686 // recursive type definitions.
1687 enum MemberDescriptionFactory {
1688     StructMDF(StructMemberDescriptionFactory),
1689     TupleMDF(TupleMemberDescriptionFactory),
1690     EnumMDF(EnumMemberDescriptionFactory),
1691     VariantMDF(VariantMemberDescriptionFactory)
1692 }
1693
1694 impl MemberDescriptionFactory {
1695     fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
1696         match *self {
1697             StructMDF(ref this) => {
1698                 this.create_member_descriptions(cx)
1699             }
1700             TupleMDF(ref this) => {
1701                 this.create_member_descriptions(cx)
1702             }
1703             EnumMDF(ref this) => {
1704                 this.create_member_descriptions(cx)
1705             }
1706             VariantMDF(ref this) => {
1707                 this.create_member_descriptions(cx)
1708             }
1709         }
1710     }
1711 }
1712
1713 // A description of some recursive type. It can either be already finished (as
1714 // with FinalMetadata) or it is not yet finished, but contains all information
1715 // needed to generate the missing parts of the description. See the documentation
1716 // section on Recursive Types at the top of this file for more information.
1717 enum RecursiveTypeDescription {
1718     UnfinishedMetadata {
1719         unfinished_type: ty::t,
1720         unique_type_id: UniqueTypeId,
1721         metadata_stub: DICompositeType,
1722         llvm_type: Type,
1723         file_metadata: DIFile,
1724         member_description_factory: MemberDescriptionFactory,
1725     },
1726     FinalMetadata(DICompositeType)
1727 }
1728
1729 fn create_and_register_recursive_type_forward_declaration(
1730     cx: &CrateContext,
1731     unfinished_type: ty::t,
1732     unique_type_id: UniqueTypeId,
1733     metadata_stub: DICompositeType,
1734     llvm_type: Type,
1735     file_metadata: DIFile,
1736     member_description_factory: MemberDescriptionFactory)
1737  -> RecursiveTypeDescription {
1738
1739     // Insert the stub into the TypeMap in order to allow for recursive references
1740     let mut type_map = debug_context(cx).type_map.borrow_mut();
1741     type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata_stub);
1742     type_map.register_type_with_metadata(cx, unfinished_type, metadata_stub);
1743
1744     UnfinishedMetadata {
1745         unfinished_type: unfinished_type,
1746         unique_type_id: unique_type_id,
1747         metadata_stub: metadata_stub,
1748         llvm_type: llvm_type,
1749         file_metadata: file_metadata,
1750         member_description_factory: member_description_factory,
1751     }
1752 }
1753
1754 impl RecursiveTypeDescription {
1755     // Finishes up the description of the type in question (mostly by providing
1756     // descriptions of the fields of the given type) and returns the final type metadata.
1757     fn finalize(&self, cx: &CrateContext) -> MetadataCreationResult {
1758         match *self {
1759             FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
1760             UnfinishedMetadata {
1761                 unfinished_type,
1762                 unique_type_id,
1763                 metadata_stub,
1764                 llvm_type,
1765                 file_metadata,
1766                 ref member_description_factory
1767             } => {
1768                 // Make sure that we have a forward declaration of the type in
1769                 // the TypeMap so that recursive references are possible. This
1770                 // will always be the case if the RecursiveTypeDescription has
1771                 // been properly created through the
1772                 // create_and_register_recursive_type_forward_declaration() function.
1773                 {
1774                     let type_map = debug_context(cx).type_map.borrow();
1775                     if type_map.find_metadata_for_unique_id(unique_type_id).is_none() ||
1776                        type_map.find_metadata_for_type(unfinished_type).is_none() {
1777                         cx.sess().bug(format!("Forward declaration of potentially recursive type \
1778                                               '{}' was not found in TypeMap!",
1779                                               ppaux::ty_to_str(cx.tcx(), unfinished_type))
1780                                       .as_slice());
1781                     }
1782                 }
1783
1784                 // ... then create the member descriptions ...
1785                 let member_descriptions =
1786                     member_description_factory.create_member_descriptions(cx);
1787
1788                 // ... and attach them to the stub to complete it.
1789                 set_members_of_composite_type(cx,
1790                                               metadata_stub,
1791                                               llvm_type,
1792                                               member_descriptions.as_slice(),
1793                                               file_metadata,
1794                                               codemap::DUMMY_SP);
1795                 return MetadataCreationResult::new(metadata_stub, true);
1796             }
1797         }
1798     }
1799 }
1800
1801
1802 //=-----------------------------------------------------------------------------
1803 // Structs
1804 //=-----------------------------------------------------------------------------
1805
1806 // Creates MemberDescriptions for the fields of a struct
1807 struct StructMemberDescriptionFactory {
1808     fields: Vec<ty::field>,
1809     is_simd: bool,
1810     span: Span,
1811 }
1812
1813 impl StructMemberDescriptionFactory {
1814     fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
1815         if self.fields.len() == 0 {
1816             return Vec::new();
1817         }
1818
1819         let field_size = if self.is_simd {
1820             machine::llsize_of_alloc(cx, type_of::type_of(cx, self.fields.get(0).mt.ty)) as uint
1821         } else {
1822             0xdeadbeef
1823         };
1824
1825         self.fields.iter().enumerate().map(|(i, field)| {
1826             let name = if field.ident.name == special_idents::unnamed_field.name {
1827                 "".to_string()
1828             } else {
1829                 token::get_ident(field.ident).get().to_string()
1830             };
1831
1832             let offset = if self.is_simd {
1833                 assert!(field_size != 0xdeadbeef);
1834                 FixedMemberOffset { bytes: i * field_size }
1835             } else {
1836                 ComputedMemberOffset
1837             };
1838
1839             MemberDescription {
1840                 name: name,
1841                 llvm_type: type_of::type_of(cx, field.mt.ty),
1842                 type_metadata: type_metadata(cx, field.mt.ty, self.span),
1843                 offset: offset,
1844             }
1845         }).collect()
1846     }
1847 }
1848
1849 fn prepare_struct_metadata(cx: &CrateContext,
1850                            struct_type: ty::t,
1851                            def_id: ast::DefId,
1852                            substs: &subst::Substs,
1853                            unique_type_id: UniqueTypeId,
1854                            span: Span)
1855                         -> RecursiveTypeDescription {
1856     let struct_name = ppaux::ty_to_str(cx.tcx(), struct_type);
1857     let struct_llvm_type = type_of::type_of(cx, struct_type);
1858
1859     let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, def_id);
1860
1861     let file_name = span_start(cx, definition_span).file.name.clone();
1862     let file_metadata = file_metadata(cx, file_name.as_slice());
1863
1864     let struct_metadata_stub = create_struct_stub(cx,
1865                                                   struct_llvm_type,
1866                                                   struct_name.as_slice(),
1867                                                   unique_type_id,
1868                                                   containing_scope,
1869                                                   file_metadata,
1870                                                   definition_span);
1871
1872     let fields = ty::struct_fields(cx.tcx(), def_id, substs);
1873
1874     create_and_register_recursive_type_forward_declaration(
1875         cx,
1876         struct_type,
1877         unique_type_id,
1878         struct_metadata_stub,
1879         struct_llvm_type,
1880         file_metadata,
1881         StructMDF(StructMemberDescriptionFactory {
1882             fields: fields,
1883             is_simd: ty::type_is_simd(cx.tcx(), struct_type),
1884             span: span,
1885         })
1886     )
1887 }
1888
1889
1890 //=-----------------------------------------------------------------------------
1891 // Tuples
1892 //=-----------------------------------------------------------------------------
1893
1894 // Creates MemberDescriptions for the fields of a tuple
1895 struct TupleMemberDescriptionFactory {
1896     component_types: Vec<ty::t> ,
1897     span: Span,
1898 }
1899
1900 impl TupleMemberDescriptionFactory {
1901     fn create_member_descriptions(&self, cx: &CrateContext)
1902                                   -> Vec<MemberDescription> {
1903         self.component_types.iter().map(|&component_type| {
1904             MemberDescription {
1905                 name: "".to_string(),
1906                 llvm_type: type_of::type_of(cx, component_type),
1907                 type_metadata: type_metadata(cx, component_type, self.span),
1908                 offset: ComputedMemberOffset,
1909             }
1910         }).collect()
1911     }
1912 }
1913
1914 fn prepare_tuple_metadata(cx: &CrateContext,
1915                           tuple_type: ty::t,
1916                           component_types: &[ty::t],
1917                           unique_type_id: UniqueTypeId,
1918                           span: Span)
1919                        -> RecursiveTypeDescription {
1920     let tuple_name = ppaux::ty_to_str(cx.tcx(), tuple_type);
1921     let tuple_llvm_type = type_of::type_of(cx, tuple_type);
1922
1923     let loc = span_start(cx, span);
1924     let file_metadata = file_metadata(cx, loc.file.name.as_slice());
1925
1926     create_and_register_recursive_type_forward_declaration(
1927         cx,
1928         tuple_type,
1929         unique_type_id,
1930         create_struct_stub(cx,
1931                            tuple_llvm_type,
1932                            tuple_name.as_slice(),
1933                            unique_type_id,
1934                            file_metadata,
1935                            file_metadata,
1936                            span),
1937         tuple_llvm_type,
1938         file_metadata,
1939         TupleMDF(TupleMemberDescriptionFactory {
1940             component_types: Vec::from_slice(component_types),
1941             span: span,
1942         })
1943     )
1944 }
1945
1946
1947 //=-----------------------------------------------------------------------------
1948 // Enums
1949 //=-----------------------------------------------------------------------------
1950
1951 // Describes the members of an enum value: An enum is described as a union of
1952 // structs in DWARF. This MemberDescriptionFactory provides the description for
1953 // the members of this union; so for every variant of the given enum, this factory
1954 // will produce one MemberDescription (all with no name and a fixed offset of
1955 // zero bytes).
1956 struct EnumMemberDescriptionFactory {
1957     enum_type: ty::t,
1958     type_rep: Rc<adt::Repr>,
1959     variants: Rc<Vec<Rc<ty::VariantInfo>>>,
1960     discriminant_type_metadata: Option<DIType>,
1961     containing_scope: DIScope,
1962     file_metadata: DIFile,
1963     span: Span,
1964 }
1965
1966 impl EnumMemberDescriptionFactory {
1967     fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
1968         match *self.type_rep {
1969             adt::General(_, ref struct_defs) => {
1970                 let discriminant_info = RegularDiscriminant(self.discriminant_type_metadata
1971                     .expect(""));
1972
1973                 struct_defs
1974                     .iter()
1975                     .enumerate()
1976                     .map(|(i, struct_def)| {
1977                         let (variant_type_metadata,
1978                              variant_llvm_type,
1979                              member_desc_factory) =
1980                             describe_enum_variant(cx,
1981                                                   self.enum_type,
1982                                                   struct_def,
1983                                                   &**self.variants.get(i),
1984                                                   discriminant_info,
1985                                                   self.containing_scope,
1986                                                   self.file_metadata,
1987                                                   self.span);
1988
1989                         let member_descriptions = member_desc_factory
1990                             .create_member_descriptions(cx);
1991
1992                         set_members_of_composite_type(cx,
1993                                                       variant_type_metadata,
1994                                                       variant_llvm_type,
1995                                                       member_descriptions.as_slice(),
1996                                                       self.file_metadata,
1997                                                       codemap::DUMMY_SP);
1998                         MemberDescription {
1999                             name: "".to_string(),
2000                             llvm_type: variant_llvm_type,
2001                             type_metadata: variant_type_metadata,
2002                             offset: FixedMemberOffset { bytes: 0 },
2003                         }
2004                     }).collect()
2005             },
2006             adt::Univariant(ref struct_def, _) => {
2007                 assert!(self.variants.len() <= 1);
2008
2009                 if self.variants.len() == 0 {
2010                     vec![]
2011                 } else {
2012                     let (variant_type_metadata,
2013                          variant_llvm_type,
2014                          member_description_factory) =
2015                         describe_enum_variant(cx,
2016                                               self.enum_type,
2017                                               struct_def,
2018                                               &**self.variants.get(0),
2019                                               NoDiscriminant,
2020                                               self.containing_scope,
2021                                               self.file_metadata,
2022                                               self.span);
2023
2024                     let member_descriptions =
2025                         member_description_factory.create_member_descriptions(cx);
2026
2027                     set_members_of_composite_type(cx,
2028                                                   variant_type_metadata,
2029                                                   variant_llvm_type,
2030                                                   member_descriptions.as_slice(),
2031                                                   self.file_metadata,
2032                                                   codemap::DUMMY_SP);
2033                     vec![
2034                         MemberDescription {
2035                             name: "".to_string(),
2036                             llvm_type: variant_llvm_type,
2037                             type_metadata: variant_type_metadata,
2038                             offset: FixedMemberOffset { bytes: 0 },
2039                         }
2040                     ]
2041                 }
2042             }
2043             adt::RawNullablePointer { nndiscr: non_null_variant_index, nnty, .. } => {
2044                 // As far as debuginfo is concerned, the pointer this enum
2045                 // represents is still wrapped in a struct. This is to make the
2046                 // DWARF representation of enums uniform.
2047
2048                 // First create a description of the artificial wrapper struct:
2049                 let non_null_variant = self.variants.get(non_null_variant_index as uint);
2050                 let non_null_variant_ident = non_null_variant.name;
2051                 let non_null_variant_name = token::get_ident(non_null_variant_ident);
2052
2053                 // The llvm type and metadata of the pointer
2054                 let non_null_llvm_type = type_of::type_of(cx, nnty);
2055                 let non_null_type_metadata = type_metadata(cx, nnty, self.span);
2056
2057                 // The type of the artificial struct wrapping the pointer
2058                 let artificial_struct_llvm_type = Type::struct_(cx,
2059                                                                 &[non_null_llvm_type],
2060                                                                 false);
2061
2062                 // For the metadata of the wrapper struct, we need to create a
2063                 // MemberDescription of the struct's single field.
2064                 let sole_struct_member_description = MemberDescription {
2065                     name: match non_null_variant.arg_names {
2066                         Some(ref names) => token::get_ident(*names.get(0)).get().to_string(),
2067                         None => "".to_string()
2068                     },
2069                     llvm_type: non_null_llvm_type,
2070                     type_metadata: non_null_type_metadata,
2071                     offset: FixedMemberOffset { bytes: 0 },
2072                 };
2073
2074                 let unique_type_id = debug_context(cx).type_map
2075                                                       .borrow_mut()
2076                                                       .get_unique_type_id_of_enum_variant(
2077                                                           cx,
2078                                                           self.enum_type,
2079                                                           non_null_variant_name.get());
2080
2081                 // Now we can create the metadata of the artificial struct
2082                 let artificial_struct_metadata =
2083                     composite_type_metadata(cx,
2084                                             artificial_struct_llvm_type,
2085                                             non_null_variant_name.get(),
2086                                             unique_type_id,
2087                                             &[sole_struct_member_description],
2088                                             self.containing_scope,
2089                                             self.file_metadata,
2090                                             codemap::DUMMY_SP);
2091
2092                 // Encode the information about the null variant in the union
2093                 // member's name.
2094                 let null_variant_index = (1 - non_null_variant_index) as uint;
2095                 let null_variant_ident = self.variants.get(null_variant_index).name;
2096                 let null_variant_name = token::get_ident(null_variant_ident);
2097                 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
2098                                                 0u,
2099                                                 null_variant_name);
2100
2101                 // Finally create the (singleton) list of descriptions of union
2102                 // members.
2103                 vec![
2104                     MemberDescription {
2105                         name: union_member_name,
2106                         llvm_type: artificial_struct_llvm_type,
2107                         type_metadata: artificial_struct_metadata,
2108                         offset: FixedMemberOffset { bytes: 0 },
2109                     }
2110                 ]
2111             },
2112             adt::StructWrappedNullablePointer { nonnull: ref struct_def,
2113                                                 nndiscr,
2114                                                 ptrfield, ..} => {
2115                 // Create a description of the non-null variant
2116                 let (variant_type_metadata, variant_llvm_type, member_description_factory) =
2117                     describe_enum_variant(cx,
2118                                           self.enum_type,
2119                                           struct_def,
2120                                           &**self.variants.get(nndiscr as uint),
2121                                           OptimizedDiscriminant(ptrfield),
2122                                           self.containing_scope,
2123                                           self.file_metadata,
2124                                           self.span);
2125
2126                 let variant_member_descriptions =
2127                     member_description_factory.create_member_descriptions(cx);
2128
2129                 set_members_of_composite_type(cx,
2130                                               variant_type_metadata,
2131                                               variant_llvm_type,
2132                                               variant_member_descriptions.as_slice(),
2133                                               self.file_metadata,
2134                                               codemap::DUMMY_SP);
2135
2136                 // Encode the information about the null variant in the union
2137                 // member's name.
2138                 let null_variant_index = (1 - nndiscr) as uint;
2139                 let null_variant_ident = self.variants.get(null_variant_index).name;
2140                 let null_variant_name = token::get_ident(null_variant_ident);
2141                 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
2142                                                 ptrfield,
2143                                                 null_variant_name);
2144
2145                 // Create the (singleton) list of descriptions of union members.
2146                 vec![
2147                     MemberDescription {
2148                         name: union_member_name,
2149                         llvm_type: variant_llvm_type,
2150                         type_metadata: variant_type_metadata,
2151                         offset: FixedMemberOffset { bytes: 0 },
2152                     }
2153                 ]
2154             },
2155             adt::CEnum(..) => cx.sess().span_bug(self.span, "This should be unreachable.")
2156         }
2157     }
2158 }
2159
2160 // Creates MemberDescriptions for the fields of a single enum variant.
2161 struct VariantMemberDescriptionFactory {
2162     args: Vec<(String, ty::t)> ,
2163     discriminant_type_metadata: Option<DIType>,
2164     span: Span,
2165 }
2166
2167 impl VariantMemberDescriptionFactory {
2168     fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
2169         self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
2170             MemberDescription {
2171                 name: name.to_string(),
2172                 llvm_type: type_of::type_of(cx, ty),
2173                 type_metadata: match self.discriminant_type_metadata {
2174                     Some(metadata) if i == 0 => metadata,
2175                     _ => type_metadata(cx, ty, self.span)
2176                 },
2177                 offset: ComputedMemberOffset,
2178             }
2179         }).collect()
2180     }
2181 }
2182
2183 enum EnumDiscriminantInfo {
2184     RegularDiscriminant(DIType),
2185     OptimizedDiscriminant(uint),
2186     NoDiscriminant
2187 }
2188
2189 // Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type
2190 // of the variant, and (3) a MemberDescriptionFactory for producing the
2191 // descriptions of the fields of the variant. This is a rudimentary version of a
2192 // full RecursiveTypeDescription.
2193 fn describe_enum_variant(cx: &CrateContext,
2194                          enum_type: ty::t,
2195                          struct_def: &adt::Struct,
2196                          variant_info: &ty::VariantInfo,
2197                          discriminant_info: EnumDiscriminantInfo,
2198                          containing_scope: DIScope,
2199                          file_metadata: DIFile,
2200                          span: Span)
2201                       -> (DICompositeType, Type, MemberDescriptionFactory) {
2202     let variant_llvm_type =
2203         Type::struct_(cx, struct_def.fields
2204                                     .iter()
2205                                     .map(|&t| type_of::type_of(cx, t))
2206                                     .collect::<Vec<_>>()
2207                                     .as_slice(),
2208                       struct_def.packed);
2209     // Could do some consistency checks here: size, align, field count, discr type
2210
2211     // Find the source code location of the variant's definition
2212     let variant_definition_span = if variant_info.id.krate == ast::LOCAL_CRATE {
2213         cx.tcx.map.span(variant_info.id.node)
2214     } else {
2215         // For definitions from other crates we have no location information available.
2216         codemap::DUMMY_SP
2217     };
2218
2219     let variant_name = token::get_ident(variant_info.name);
2220     let variant_name = variant_name.get();
2221     let unique_type_id = debug_context(cx).type_map
2222                                           .borrow_mut()
2223                                           .get_unique_type_id_of_enum_variant(
2224                                               cx,
2225                                               enum_type,
2226                                               variant_name);
2227
2228     let metadata_stub = create_struct_stub(cx,
2229                                            variant_llvm_type,
2230                                            variant_name,
2231                                            unique_type_id,
2232                                            containing_scope,
2233                                            file_metadata,
2234                                            variant_definition_span);
2235
2236     // Get the argument names from the enum variant info
2237     let mut arg_names: Vec<_> = match variant_info.arg_names {
2238         Some(ref names) => {
2239             names.iter()
2240                  .map(|ident| {
2241                      token::get_ident(*ident).get().to_str().into_string()
2242                  }).collect()
2243         }
2244         None => variant_info.args.iter().map(|_| "".to_string()).collect()
2245     };
2246
2247     // If this is not a univariant enum, there is also the (unnamed) discriminant field.
2248     match discriminant_info {
2249         RegularDiscriminant(_) => arg_names.insert(0, "".to_string()),
2250         _ => { /* do nothing */ }
2251     };
2252
2253     // Build an array of (field name, field type) pairs to be captured in the factory closure.
2254     let args: Vec<(String, ty::t)> = arg_names.iter()
2255         .zip(struct_def.fields.iter())
2256         .map(|(s, &t)| (s.to_string(), t))
2257         .collect();
2258
2259     let member_description_factory =
2260         VariantMDF(VariantMemberDescriptionFactory {
2261             args: args,
2262             discriminant_type_metadata: match discriminant_info {
2263                 RegularDiscriminant(discriminant_type_metadata) => {
2264                     Some(discriminant_type_metadata)
2265                 }
2266                 _ => None
2267             },
2268             span: span,
2269         });
2270
2271     (metadata_stub, variant_llvm_type, member_description_factory)
2272 }
2273
2274 fn prepare_enum_metadata(cx: &CrateContext,
2275                          enum_type: ty::t,
2276                          enum_def_id: ast::DefId,
2277                          unique_type_id: UniqueTypeId,
2278                          span: Span)
2279                       -> RecursiveTypeDescription {
2280     let enum_name = ppaux::ty_to_str(cx.tcx(), enum_type);
2281
2282     let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, enum_def_id);
2283     let loc = span_start(cx, definition_span);
2284     let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2285
2286     let variants = ty::enum_variants(cx.tcx(), enum_def_id);
2287
2288     let enumerators_metadata: Vec<DIDescriptor> = variants
2289         .iter()
2290         .map(|v| {
2291             token::get_ident(v.name).get().with_c_str(|name| {
2292                 unsafe {
2293                     llvm::LLVMDIBuilderCreateEnumerator(
2294                         DIB(cx),
2295                         name,
2296                         v.disr_val as c_ulonglong)
2297                 }
2298             })
2299         })
2300         .collect();
2301
2302     let discriminant_type_metadata = |inttype| {
2303         // We can reuse the type of the discriminant for all monomorphized
2304         // instances of an enum because it doesn't depend on any type parameters.
2305         // The def_id, uniquely identifying the enum's polytype acts as key in
2306         // this cache.
2307         let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
2308                                                                  .borrow()
2309                                                                  .find_copy(&enum_def_id);
2310         match cached_discriminant_type_metadata {
2311             Some(discriminant_type_metadata) => discriminant_type_metadata,
2312             None => {
2313                 let discriminant_llvm_type = adt::ll_inttype(cx, inttype);
2314                 let (discriminant_size, discriminant_align) =
2315                     size_and_align_of(cx, discriminant_llvm_type);
2316                 let discriminant_base_type_metadata = type_metadata(cx,
2317                                                                     adt::ty_of_inttype(inttype),
2318                                                                     codemap::DUMMY_SP);
2319                 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
2320
2321                 let discriminant_type_metadata = discriminant_name.get().with_c_str(|name| {
2322                     unsafe {
2323                         llvm::LLVMDIBuilderCreateEnumerationType(
2324                             DIB(cx),
2325                             containing_scope,
2326                             name,
2327                             file_metadata,
2328                             loc.line as c_uint,
2329                             bytes_to_bits(discriminant_size),
2330                             bytes_to_bits(discriminant_align),
2331                             create_DIArray(DIB(cx), enumerators_metadata.as_slice()),
2332                             discriminant_base_type_metadata)
2333                     }
2334                 });
2335
2336                 debug_context(cx).created_enum_disr_types
2337                                  .borrow_mut()
2338                                  .insert(enum_def_id, discriminant_type_metadata);
2339
2340                 discriminant_type_metadata
2341             }
2342         }
2343     };
2344
2345     let type_rep = adt::represent_type(cx, enum_type);
2346
2347     let discriminant_type_metadata = match *type_rep {
2348         adt::CEnum(inttype, _, _) => {
2349             return FinalMetadata(discriminant_type_metadata(inttype))
2350         },
2351         adt::RawNullablePointer { .. }           |
2352         adt::StructWrappedNullablePointer { .. } |
2353         adt::Univariant(..)                      => None,
2354         adt::General(inttype, _) => Some(discriminant_type_metadata(inttype)),
2355     };
2356
2357     let enum_llvm_type = type_of::type_of(cx, enum_type);
2358     let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
2359
2360     let unique_type_id_str = debug_context(cx)
2361                              .type_map
2362                              .borrow()
2363                              .get_unique_type_id_as_string(unique_type_id);
2364
2365     let enum_metadata = enum_name.as_slice().with_c_str(|enum_name| {
2366         unique_type_id_str.as_slice().with_c_str(|unique_type_id_str| {
2367             unsafe {
2368                 llvm::LLVMDIBuilderCreateUnionType(
2369                 DIB(cx),
2370                 containing_scope,
2371                 enum_name,
2372                 file_metadata,
2373                 loc.line as c_uint,
2374                 bytes_to_bits(enum_type_size),
2375                 bytes_to_bits(enum_type_align),
2376                 0, // Flags
2377                 ptr::mut_null(),
2378                 0, // RuntimeLang
2379                 unique_type_id_str)
2380             }
2381         })
2382     });
2383
2384     return create_and_register_recursive_type_forward_declaration(
2385         cx,
2386         enum_type,
2387         unique_type_id,
2388         enum_metadata,
2389         enum_llvm_type,
2390         file_metadata,
2391         EnumMDF(EnumMemberDescriptionFactory {
2392             enum_type: enum_type,
2393             type_rep: type_rep.clone(),
2394             variants: variants,
2395             discriminant_type_metadata: discriminant_type_metadata,
2396             containing_scope: containing_scope,
2397             file_metadata: file_metadata,
2398             span: span,
2399         }),
2400     );
2401
2402     fn get_enum_discriminant_name(cx: &CrateContext,
2403                                   def_id: ast::DefId)
2404                                   -> token::InternedString {
2405         let name = if def_id.krate == ast::LOCAL_CRATE {
2406             cx.tcx.map.get_path_elem(def_id.node).name()
2407         } else {
2408             csearch::get_item_path(&cx.tcx, def_id).last().unwrap().name()
2409         };
2410
2411         token::get_name(name)
2412     }
2413 }
2414
2415 /// Creates debug information for a composite type, that is, anything that
2416 /// results in a LLVM struct.
2417 ///
2418 /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
2419 fn composite_type_metadata(cx: &CrateContext,
2420                            composite_llvm_type: Type,
2421                            composite_type_name: &str,
2422                            composite_type_unique_id: UniqueTypeId,
2423                            member_descriptions: &[MemberDescription],
2424                            containing_scope: DIScope,
2425                            file_metadata: DIFile,
2426                            definition_span: Span)
2427                         -> DICompositeType {
2428     // Create the (empty) struct metadata node ...
2429     let composite_type_metadata = create_struct_stub(cx,
2430                                                      composite_llvm_type,
2431                                                      composite_type_name,
2432                                                      composite_type_unique_id,
2433                                                      containing_scope,
2434                                                      file_metadata,
2435                                                      definition_span);
2436     // ... and immediately create and add the member descriptions.
2437     set_members_of_composite_type(cx,
2438                                   composite_type_metadata,
2439                                   composite_llvm_type,
2440                                   member_descriptions,
2441                                   file_metadata,
2442                                   definition_span);
2443
2444     return composite_type_metadata;
2445 }
2446
2447 fn set_members_of_composite_type(cx: &CrateContext,
2448                                  composite_type_metadata: DICompositeType,
2449                                  composite_llvm_type: Type,
2450                                  member_descriptions: &[MemberDescription],
2451                                  file_metadata: DIFile,
2452                                  definition_span: Span) {
2453     // In some rare cases LLVM metadata uniquing would lead to an existing type
2454     // description being used instead of a new one created in create_struct_stub.
2455     // This would cause a hard to trace assertion in DICompositeType::SetTypeArray().
2456     // The following check makes sure that we get a better error message if this
2457     // should happen again due to some regression.
2458     {
2459         let mut composite_types_completed =
2460             debug_context(cx).composite_types_completed.borrow_mut();
2461         if composite_types_completed.contains(&composite_type_metadata) {
2462             let (llvm_version_major, llvm_version_minor) = unsafe {
2463                 (llvm::LLVMVersionMajor(), llvm::LLVMVersionMinor())
2464             };
2465
2466             let actual_llvm_version = llvm_version_major * 1000000 + llvm_version_minor * 1000;
2467             let min_supported_llvm_version = 3 * 1000000 + 4 * 1000;
2468
2469             if actual_llvm_version < min_supported_llvm_version {
2470                 cx.sess().warn(format!("This version of rustc was built with LLVM \
2471                                         {}.{}. Rustc just ran into a known \
2472                                         debuginfo corruption problem thatoften \
2473                                         occurs with LLVM versions below 3.4. \
2474                                         Please use a rustc built with anewer \
2475                                         version of LLVM.",
2476                                        llvm_version_major,
2477                                        llvm_version_minor).as_slice());
2478             } else {
2479                 cx.sess().bug("debuginfo::set_members_of_composite_type() - \
2480                                Already completed forward declaration re-encountered.");
2481             }
2482         } else {
2483             composite_types_completed.insert(composite_type_metadata);
2484         }
2485     }
2486
2487     let loc = span_start(cx, definition_span);
2488
2489     let member_metadata: Vec<DIDescriptor> = member_descriptions
2490         .iter()
2491         .enumerate()
2492         .map(|(i, member_description)| {
2493             let (member_size, member_align) = size_and_align_of(cx, member_description.llvm_type);
2494             let member_offset = match member_description.offset {
2495                 FixedMemberOffset { bytes } => bytes as u64,
2496                 ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
2497             };
2498
2499             member_description.name.as_slice().with_c_str(|member_name| {
2500                 unsafe {
2501                     llvm::LLVMDIBuilderCreateMemberType(
2502                         DIB(cx),
2503                         composite_type_metadata,
2504                         member_name,
2505                         file_metadata,
2506                         loc.line as c_uint,
2507                         bytes_to_bits(member_size),
2508                         bytes_to_bits(member_align),
2509                         bytes_to_bits(member_offset),
2510                         0,
2511                         member_description.type_metadata)
2512                 }
2513             })
2514         })
2515         .collect();
2516
2517     unsafe {
2518         let type_array = create_DIArray(DIB(cx), member_metadata.as_slice());
2519         llvm::LLVMDICompositeTypeSetTypeArray(composite_type_metadata, type_array);
2520     }
2521 }
2522
2523 // A convenience wrapper around LLVMDIBuilderCreateStructType(). Does not do any
2524 // caching, does not add any fields to the struct. This can be done later with
2525 // set_members_of_composite_type().
2526 fn create_struct_stub(cx: &CrateContext,
2527                       struct_llvm_type: Type,
2528                       struct_type_name: &str,
2529                       unique_type_id: UniqueTypeId,
2530                       containing_scope: DIScope,
2531                       file_metadata: DIFile,
2532                       definition_span: Span)
2533                    -> DICompositeType {
2534     let loc = span_start(cx, definition_span);
2535     let (struct_size, struct_align) = size_and_align_of(cx, struct_llvm_type);
2536
2537     let unique_type_id_str = debug_context(cx).type_map
2538                                               .borrow()
2539                                               .get_unique_type_id_as_string(unique_type_id);
2540     let metadata_stub = unsafe {
2541         struct_type_name.with_c_str(|name| {
2542             unique_type_id_str.as_slice().with_c_str(|unique_type_id| {
2543                 // LLVMDIBuilderCreateStructType() wants an empty array. A null
2544                 // pointer will lead to hard to trace and debug LLVM assertions
2545                 // later on in llvm/lib/IR/Value.cpp.
2546                 let empty_array = create_DIArray(DIB(cx), []);
2547
2548                 llvm::LLVMDIBuilderCreateStructType(
2549                     DIB(cx),
2550                     containing_scope,
2551                     name,
2552                     file_metadata,
2553                     loc.line as c_uint,
2554                     bytes_to_bits(struct_size),
2555                     bytes_to_bits(struct_align),
2556                     0,
2557                     ptr::mut_null(),
2558                     empty_array,
2559                     0,
2560                     ptr::mut_null(),
2561                     unique_type_id)
2562             })
2563         })
2564     };
2565
2566     return metadata_stub;
2567 }
2568
2569 fn at_box_metadata(cx: &CrateContext,
2570                    at_pointer_type: ty::t,
2571                    content_type: ty::t,
2572                    unique_type_id: UniqueTypeId)
2573                 -> MetadataCreationResult {
2574     let content_type_metadata = type_metadata(cx, content_type, codemap::DUMMY_SP);
2575
2576     match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
2577         Some(metadata) => return MetadataCreationResult::new(metadata, true),
2578         None => { /* proceed */ }
2579     };
2580
2581     let content_type_name = ppaux::ty_to_str(cx.tcx(), content_type);
2582     let content_type_name = content_type_name.as_slice();
2583     let content_llvm_type = type_of::type_of(cx, content_type);
2584
2585     let box_type_name = format!("GcBox<{}>", content_type_name);
2586     let box_llvm_type = Type::at_box(cx, content_llvm_type);
2587     let member_llvm_types = box_llvm_type.field_types();
2588     assert!(box_layout_is_correct(cx,
2589                                   member_llvm_types.as_slice(),
2590                                   content_llvm_type));
2591
2592     let int_type = ty::mk_int();
2593     let nil_pointer_type = ty::mk_nil_ptr(cx.tcx());
2594     let nil_pointer_type_metadata = type_metadata(cx,
2595                                                   nil_pointer_type,
2596                                                   codemap::DUMMY_SP);
2597
2598     let member_descriptions = [
2599         MemberDescription {
2600             name: "refcnt".to_string(),
2601             llvm_type: *member_llvm_types.get(0),
2602             type_metadata: type_metadata(cx, int_type, codemap::DUMMY_SP),
2603             offset: ComputedMemberOffset,
2604         },
2605         MemberDescription {
2606             name: "drop_glue".to_string(),
2607             llvm_type: *member_llvm_types.get(1),
2608             type_metadata: nil_pointer_type_metadata,
2609             offset: ComputedMemberOffset,
2610         },
2611         MemberDescription {
2612             name: "prev".to_string(),
2613             llvm_type: *member_llvm_types.get(2),
2614             type_metadata: nil_pointer_type_metadata,
2615             offset: ComputedMemberOffset,
2616         },
2617         MemberDescription {
2618             name: "next".to_string(),
2619             llvm_type: *member_llvm_types.get(3),
2620             type_metadata: nil_pointer_type_metadata,
2621             offset: ComputedMemberOffset,
2622         },
2623         MemberDescription {
2624             name: "val".to_string(),
2625             llvm_type: *member_llvm_types.get(4),
2626             type_metadata: content_type_metadata,
2627             offset: ComputedMemberOffset,
2628         }
2629     ];
2630
2631     let loc = span_start(cx, codemap::DUMMY_SP);
2632     let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2633
2634     let gc_box_unique_id = debug_context(cx).type_map
2635                                             .borrow_mut()
2636                                             .get_unique_type_id_of_gc_box(cx, content_type);
2637
2638     let gc_box_metadata = composite_type_metadata(
2639         cx,
2640         box_llvm_type,
2641         box_type_name.as_slice(),
2642         gc_box_unique_id,
2643         member_descriptions,
2644         file_metadata,
2645         file_metadata,
2646         codemap::DUMMY_SP);
2647
2648     let gc_pointer_metadata = pointer_type_metadata(cx,
2649                                                     at_pointer_type,
2650                                                     gc_box_metadata);
2651
2652     return MetadataCreationResult::new(gc_pointer_metadata, false);
2653
2654     // Unfortunately, we cannot assert anything but the correct types here---and
2655     // not whether the 'next' and 'prev' pointers are in the correct order.
2656     fn box_layout_is_correct(cx: &CrateContext,
2657                              member_llvm_types: &[Type],
2658                              content_llvm_type: Type)
2659                           -> bool {
2660         member_llvm_types.len() == 5 &&
2661         member_llvm_types[0] == cx.int_type &&
2662         member_llvm_types[1] == Type::generic_glue_fn(cx).ptr_to() &&
2663         member_llvm_types[2] == Type::i8(cx).ptr_to() &&
2664         member_llvm_types[3] == Type::i8(cx).ptr_to() &&
2665         member_llvm_types[4] == content_llvm_type
2666     }
2667 }
2668
2669
2670 fn fixed_vec_metadata(cx: &CrateContext,
2671                       unique_type_id: UniqueTypeId,
2672                       element_type: ty::t,
2673                       len: uint,
2674                       span: Span)
2675                    -> MetadataCreationResult {
2676     let element_type_metadata = type_metadata(cx, element_type, span);
2677
2678     match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
2679         Some(metadata) => return MetadataCreationResult::new(metadata, true),
2680         None => { /* proceed */ }
2681     };
2682
2683     let element_llvm_type = type_of::type_of(cx, element_type);
2684     let (element_type_size, element_type_align) = size_and_align_of(cx, element_llvm_type);
2685
2686     let subrange = unsafe {
2687         llvm::LLVMDIBuilderGetOrCreateSubrange(
2688         DIB(cx),
2689         0,
2690         len as c_longlong)
2691     };
2692
2693     let subscripts = create_DIArray(DIB(cx), [subrange]);
2694     let metadata = unsafe {
2695         llvm::LLVMDIBuilderCreateArrayType(
2696             DIB(cx),
2697             bytes_to_bits(element_type_size * (len as u64)),
2698             bytes_to_bits(element_type_align),
2699             element_type_metadata,
2700             subscripts)
2701     };
2702
2703     return MetadataCreationResult::new(metadata, false);
2704 }
2705
2706 fn heap_vec_metadata(cx: &CrateContext,
2707                      vec_pointer_type: ty::t,
2708                      element_type: ty::t,
2709                      unique_type_id: UniqueTypeId,
2710                      span: Span)
2711                   -> MetadataCreationResult {
2712     let element_type_metadata = type_metadata(cx, element_type, span);
2713     let element_llvm_type = type_of::type_of(cx, element_type);
2714     let (element_size, element_align) = size_and_align_of(cx, element_llvm_type);
2715
2716     match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
2717         Some(metadata) => return MetadataCreationResult::new(metadata, true),
2718         None => { /* proceed */ }
2719     };
2720
2721     let vecbox_llvm_type = Type::vec(cx, &element_llvm_type);
2722     let vec_pointer_type_name = ppaux::ty_to_str(cx.tcx(), vec_pointer_type);
2723     let vec_pointer_type_name = vec_pointer_type_name.as_slice();
2724
2725     let member_llvm_types = vecbox_llvm_type.field_types();
2726
2727     let int_type_metadata = type_metadata(cx, ty::mk_int(), span);
2728     let array_type_metadata = unsafe {
2729         llvm::LLVMDIBuilderCreateArrayType(
2730             DIB(cx),
2731             bytes_to_bits(element_size),
2732             bytes_to_bits(element_align),
2733             element_type_metadata,
2734             create_DIArray(DIB(cx), [llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0, 0)]))
2735     };
2736
2737     let member_descriptions = [
2738         MemberDescription {
2739             name: "fill".to_string(),
2740             llvm_type: *member_llvm_types.get(0),
2741             type_metadata: int_type_metadata,
2742             offset: ComputedMemberOffset,
2743         },
2744         MemberDescription {
2745             name: "alloc".to_string(),
2746             llvm_type: *member_llvm_types.get(1),
2747             type_metadata: int_type_metadata,
2748             offset: ComputedMemberOffset,
2749         },
2750         MemberDescription {
2751             name: "elements".to_string(),
2752             llvm_type: *member_llvm_types.get(2),
2753             type_metadata: array_type_metadata,
2754             offset: ComputedMemberOffset,
2755         }
2756     ];
2757
2758     assert!(member_descriptions.len() == member_llvm_types.len());
2759
2760     let loc = span_start(cx, span);
2761     let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2762
2763     let vec_box_unique_id = debug_context(cx).type_map
2764                                              .borrow_mut()
2765                                              .get_unique_type_id_of_heap_vec_box(cx,
2766                                                                                  element_type);
2767
2768     let vecbox_metadata = composite_type_metadata(cx,
2769                                                   vecbox_llvm_type,
2770                                                   vec_pointer_type_name,
2771                                                   vec_box_unique_id,
2772                                                   member_descriptions,
2773                                                   file_metadata,
2774                                                   file_metadata,
2775                                                   span);
2776
2777     MetadataCreationResult::new(pointer_type_metadata(cx,
2778                                                       vec_pointer_type,
2779                                                       vecbox_metadata), false)
2780 }
2781
2782 fn vec_slice_metadata(cx: &CrateContext,
2783                       vec_type: ty::t,
2784                       element_type: ty::t,
2785                       unique_type_id: UniqueTypeId,
2786                       span: Span)
2787                    -> MetadataCreationResult {
2788     let data_ptr_type = ty::mk_ptr(cx.tcx(), ty::mt {
2789         ty: element_type,
2790         mutbl: ast::MutImmutable
2791     });
2792
2793     let element_type_metadata = type_metadata(cx, data_ptr_type, span);
2794
2795     match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
2796         Some(metadata) => return MetadataCreationResult::new(metadata, true),
2797         None => { /* proceed */ }
2798     };
2799
2800     let slice_llvm_type = type_of::type_of(cx, vec_type);
2801     let slice_type_name = ppaux::ty_to_str(cx.tcx(), vec_type);
2802
2803     let member_llvm_types = slice_llvm_type.field_types();
2804     assert!(slice_layout_is_correct(cx,
2805                                     member_llvm_types.as_slice(),
2806                                     element_type));
2807     let member_descriptions = [
2808         MemberDescription {
2809             name: "data_ptr".to_string(),
2810             llvm_type: *member_llvm_types.get(0),
2811             type_metadata: element_type_metadata,
2812             offset: ComputedMemberOffset,
2813         },
2814         MemberDescription {
2815             name: "length".to_string(),
2816             llvm_type: *member_llvm_types.get(1),
2817             type_metadata: type_metadata(cx, ty::mk_uint(), span),
2818             offset: ComputedMemberOffset,
2819         },
2820     ];
2821
2822     assert!(member_descriptions.len() == member_llvm_types.len());
2823
2824     let loc = span_start(cx, span);
2825     let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2826
2827     let metadata = composite_type_metadata(cx,
2828                                            slice_llvm_type,
2829                                            slice_type_name.as_slice(),
2830                                            unique_type_id,
2831                                            member_descriptions,
2832                                            file_metadata,
2833                                            file_metadata,
2834                                            span);
2835     return MetadataCreationResult::new(metadata, false);
2836
2837     fn slice_layout_is_correct(cx: &CrateContext,
2838                                member_llvm_types: &[Type],
2839                                element_type: ty::t)
2840                             -> bool {
2841         member_llvm_types.len() == 2 &&
2842         member_llvm_types[0] == type_of::type_of(cx, element_type).ptr_to() &&
2843         member_llvm_types[1] == cx.int_type
2844     }
2845 }
2846
2847 fn subroutine_type_metadata(cx: &CrateContext,
2848                             unique_type_id: UniqueTypeId,
2849                             signature: &ty::FnSig,
2850                             span: Span)
2851                          -> MetadataCreationResult {
2852     let loc = span_start(cx, span);
2853     let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2854     let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs.len() + 1);
2855
2856     // return type
2857     signature_metadata.push(match ty::get(signature.output).sty {
2858         ty::ty_nil => ptr::mut_null(),
2859         _ => type_metadata(cx, signature.output, span)
2860     });
2861
2862     // regular arguments
2863     for &argument_type in signature.inputs.iter() {
2864         signature_metadata.push(type_metadata(cx, argument_type, span));
2865     }
2866
2867     match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
2868         Some(metadata) => return MetadataCreationResult::new(metadata, true),
2869         None => { /* proceed */ }
2870     };
2871
2872     return MetadataCreationResult::new(
2873         unsafe {
2874             llvm::LLVMDIBuilderCreateSubroutineType(
2875                 DIB(cx),
2876                 file_metadata,
2877                 create_DIArray(DIB(cx), signature_metadata.as_slice()))
2878         },
2879         false);
2880 }
2881
2882 fn trait_metadata(cx: &CrateContext,
2883                   def_id: ast::DefId,
2884                   trait_type: ty::t,
2885                   substs: &subst::Substs,
2886                   trait_store: ty::TraitStore,
2887                   _: &ty::BuiltinBounds,
2888                   unique_type_id: UniqueTypeId)
2889                -> DIType {
2890     // The implementation provided here is a stub. It makes sure that the trait
2891     // type is assigned the correct name, size, namespace, and source location.
2892     // But it does not describe the trait's methods.
2893     let last = ty::with_path(cx.tcx(), def_id, |mut path| path.last().unwrap());
2894     let ident_string = token::get_name(last.name());
2895     let mut name = ppaux::trait_store_to_str(cx.tcx(), trait_store);
2896     name.push_str(ident_string.get());
2897
2898     // Add type and region parameters
2899     let trait_def = ty::lookup_trait_def(cx.tcx(), def_id);
2900     let name = ppaux::parameterized(cx.tcx(), name.as_slice(),
2901                                     substs, &trait_def.generics);
2902
2903     let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, def_id);
2904
2905     let file_name = span_start(cx, definition_span).file.name.clone();
2906     let file_metadata = file_metadata(cx, file_name.as_slice());
2907
2908     let trait_llvm_type = type_of::type_of(cx, trait_type);
2909
2910     composite_type_metadata(cx,
2911                             trait_llvm_type,
2912                             name.as_slice(),
2913                             unique_type_id,
2914                             [],
2915                             containing_scope,
2916                             file_metadata,
2917                             definition_span)
2918 }
2919
2920 fn type_metadata(cx: &CrateContext,
2921                  t: ty::t,
2922                  usage_site_span: Span)
2923               -> DIType {
2924     // Get the unique type id of this type.
2925     let unique_type_id = {
2926         let mut type_map = debug_context(cx).type_map.borrow_mut();
2927         // First, try to find the type in TypeMap. If we have seen it before, we
2928         // can exit early here.
2929         match type_map.find_metadata_for_type(t) {
2930             Some(metadata) => {
2931                 return metadata;
2932             },
2933             None => {
2934                 // The ty::t is not in the TypeMap but maybe we have already seen
2935                 // an equivalent type (e.g. only differing in region arguments).
2936                 // In order to find out, generate the unique type id and look
2937                 // that up.
2938                 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
2939                 match type_map.find_metadata_for_unique_id(unique_type_id) {
2940                     Some(metadata) => {
2941                         // There is already an equivalent type in the TypeMap.
2942                         // Register this ty::t as an alias in the cache and
2943                         // return the cached metadata.
2944                         type_map.register_type_with_metadata(cx, t, metadata);
2945                         return metadata;
2946                     },
2947                     None => {
2948                         // There really is no type metadata for this type, so
2949                         // proceed by creating it.
2950                         unique_type_id
2951                     }
2952                 }
2953             }
2954         }
2955     };
2956
2957     debug!("type_metadata: {:?}", ty::get(t));
2958
2959     macro_rules! return_if_created_in_meantime(
2960         () => (
2961             match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
2962                 Some(metadata) => return metadata,
2963                 None => { /* proceed normally */ }
2964             };
2965         )
2966     )
2967
2968     let sty = &ty::get(t).sty;
2969     let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty {
2970         ty::ty_nil      |
2971         ty::ty_bot      |
2972         ty::ty_bool     |
2973         ty::ty_char     |
2974         ty::ty_int(_)   |
2975         ty::ty_uint(_)  |
2976         ty::ty_float(_) => {
2977             MetadataCreationResult::new(basic_type_metadata(cx, t), false)
2978         }
2979         ty::ty_enum(def_id, _) => {
2980             prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span).finalize(cx)
2981         }
2982         ty::ty_box(pointee_type) => {
2983             at_box_metadata(cx, t, pointee_type, unique_type_id)
2984         }
2985         ty::ty_vec(ref mt, Some(len)) => {
2986             fixed_vec_metadata(cx, unique_type_id, mt.ty, len, usage_site_span)
2987         }
2988         ty::ty_uniq(pointee_type) => {
2989             match ty::get(pointee_type).sty {
2990                 ty::ty_vec(ref mt, None) => {
2991                     heap_vec_metadata(cx, pointee_type, mt.ty, unique_type_id, usage_site_span)
2992                 }
2993                 ty::ty_str => {
2994                     let i8_t = ty::mk_i8();
2995                     heap_vec_metadata(cx, pointee_type, i8_t, unique_type_id, usage_site_span)
2996                 }
2997                 ty::ty_trait(box ty::TyTrait {
2998                         def_id,
2999                         ref substs,
3000                         ref bounds
3001                     }) => {
3002                     MetadataCreationResult::new(
3003                         trait_metadata(cx, def_id, t, substs, ty::UniqTraitStore,
3004                                        bounds, unique_type_id),
3005                     false)
3006                 }
3007                 _ => {
3008                     let pointee_metadata = type_metadata(cx, pointee_type, usage_site_span);
3009                     return_if_created_in_meantime!();
3010                     MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
3011                                                 false)
3012                 }
3013             }
3014         }
3015         ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => {
3016             match ty::get(mt.ty).sty {
3017                 ty::ty_vec(ref mt, None) => {
3018                     vec_slice_metadata(cx, t, mt.ty, unique_type_id, usage_site_span)
3019                 }
3020                 ty::ty_str => {
3021                     vec_slice_metadata(cx, t, ty::mk_i8(), unique_type_id, usage_site_span)
3022                 }
3023                 ty::ty_trait(box ty::TyTrait {
3024                         def_id,
3025                         ref substs,
3026                         ref bounds
3027                     }) => {
3028                     MetadataCreationResult::new(
3029                         trait_metadata(cx, def_id, t, substs,
3030                                        ty::RegionTraitStore(ty::ReStatic, mt.mutbl),
3031                                        bounds, unique_type_id),
3032                     false)
3033                 }
3034                 _ => {
3035                     let pointee = type_metadata(cx, mt.ty, usage_site_span);
3036                     return_if_created_in_meantime!();
3037                     MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee), false)
3038                 }
3039             }
3040         }
3041         ty::ty_bare_fn(ref barefnty) => {
3042             subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
3043         }
3044         ty::ty_closure(ref closurety) => {
3045             subroutine_type_metadata(cx, unique_type_id, &closurety.sig, usage_site_span)
3046         }
3047         ty::ty_struct(def_id, ref substs) => {
3048             prepare_struct_metadata(cx,
3049                                     t,
3050                                     def_id,
3051                                     substs,
3052                                     unique_type_id,
3053                                     usage_site_span).finalize(cx)
3054         }
3055         ty::ty_tup(ref elements) => {
3056             prepare_tuple_metadata(cx,
3057                                    t,
3058                                    elements.as_slice(),
3059                                    unique_type_id,
3060                                    usage_site_span).finalize(cx)
3061         }
3062         _ => {
3063             cx.sess().bug(format!("debuginfo: unexpected type in type_metadata: {:?}",
3064                                   sty).as_slice())
3065         }
3066     };
3067
3068     {
3069         let mut type_map = debug_context(cx).type_map.borrow_mut();
3070
3071         if already_stored_in_typemap {
3072             // Also make sure that we already have a TypeMap entry entry for the unique type id.
3073             let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
3074                 Some(metadata) => metadata,
3075                 None => {
3076                     let unique_type_id_str =
3077                         type_map.get_unique_type_id_as_string(unique_type_id);
3078                     let error_message = format!("Expected type metadata for unique \
3079                                                  type id '{}' to already be in \
3080                                                  the debuginfo::TypeMap but it \
3081                                                  was not. (ty::t = {})",
3082                                                 unique_type_id_str.as_slice(),
3083                                                 ppaux::ty_to_str(cx.tcx(), t));
3084                     cx.sess().span_bug(usage_site_span, error_message.as_slice());
3085                 }
3086             };
3087
3088             match type_map.find_metadata_for_type(t) {
3089                 Some(metadata) => {
3090                     if metadata != metadata_for_uid {
3091                         let unique_type_id_str =
3092                             type_map.get_unique_type_id_as_string(unique_type_id);
3093                         let error_message = format!("Mismatch between ty::t and \
3094                                                      UniqueTypeId maps in \
3095                                                      debuginfo::TypeMap. \
3096                                                      UniqueTypeId={}, ty::t={}",
3097                             unique_type_id_str.as_slice(),
3098                             ppaux::ty_to_str(cx.tcx(), t));
3099                         cx.sess().span_bug(usage_site_span, error_message.as_slice());
3100                     }
3101                 }
3102                 None => {
3103                     type_map.register_type_with_metadata(cx, t, metadata);
3104                 }
3105             }
3106         } else {
3107             type_map.register_type_with_metadata(cx, t, metadata);
3108             type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata);
3109         }
3110     }
3111
3112     metadata
3113 }
3114
3115 struct MetadataCreationResult {
3116     metadata: DIType,
3117     already_stored_in_typemap: bool
3118 }
3119
3120 impl MetadataCreationResult {
3121     fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationResult {
3122         MetadataCreationResult {
3123             metadata: metadata,
3124             already_stored_in_typemap: already_stored_in_typemap
3125         }
3126     }
3127 }
3128
3129 #[deriving(PartialEq)]
3130 enum DebugLocation {
3131     KnownLocation { scope: DIScope, line: uint, col: uint },
3132     UnknownLocation
3133 }
3134
3135 impl DebugLocation {
3136     fn new(scope: DIScope, line: uint, col: uint) -> DebugLocation {
3137         KnownLocation {
3138             scope: scope,
3139             line: line,
3140             col: col,
3141         }
3142     }
3143 }
3144
3145 fn set_debug_location(cx: &CrateContext, debug_location: DebugLocation) {
3146     if debug_location == debug_context(cx).current_debug_location.get() {
3147         return;
3148     }
3149
3150     let metadata_node;
3151
3152     match debug_location {
3153         KnownLocation { scope, line, .. } => {
3154             let col = 0u; // Always set the column to zero like Clang and GCC
3155             debug!("setting debug location to {} {}", line, col);
3156             let elements = [C_i32(cx, line as i32), C_i32(cx, col as i32),
3157                             scope, ptr::mut_null()];
3158             unsafe {
3159                 metadata_node = llvm::LLVMMDNodeInContext(debug_context(cx).llcontext,
3160                                                           elements.as_ptr(),
3161                                                           elements.len() as c_uint);
3162             }
3163         }
3164         UnknownLocation => {
3165             debug!("clearing debug location ");
3166             metadata_node = ptr::mut_null();
3167         }
3168     };
3169
3170     unsafe {
3171         llvm::LLVMSetCurrentDebugLocation(cx.builder.b, metadata_node);
3172     }
3173
3174     debug_context(cx).current_debug_location.set(debug_location);
3175 }
3176
3177 //=-----------------------------------------------------------------------------
3178 //  Utility Functions
3179 //=-----------------------------------------------------------------------------
3180
3181 /// Return codemap::Loc corresponding to the beginning of the span
3182 fn span_start(cx: &CrateContext, span: Span) -> codemap::Loc {
3183     cx.sess().codemap().lookup_char_pos(span.lo)
3184 }
3185
3186 fn size_and_align_of(cx: &CrateContext, llvm_type: Type) -> (u64, u64) {
3187     (machine::llsize_of_alloc(cx, llvm_type), machine::llalign_of_min(cx, llvm_type))
3188 }
3189
3190 fn bytes_to_bits(bytes: u64) -> c_ulonglong {
3191     (bytes * 8) as c_ulonglong
3192 }
3193
3194 #[inline]
3195 fn debug_context<'a>(cx: &'a CrateContext) -> &'a CrateDebugContext {
3196     let debug_context: &'a CrateDebugContext = cx.dbg_cx.get_ref();
3197     debug_context
3198 }
3199
3200 #[inline]
3201 #[allow(non_snake_case_functions)]
3202 fn DIB(cx: &CrateContext) -> DIBuilderRef {
3203     cx.dbg_cx.get_ref().builder
3204 }
3205
3206 fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
3207     match fcx.debug_context.repr {
3208         FunctionDebugContext(_) => false,
3209         _ => true
3210     }
3211 }
3212
3213 fn assert_type_for_node_id(cx: &CrateContext, node_id: ast::NodeId, error_span: Span) {
3214     if !cx.tcx.node_types.borrow().contains_key(&(node_id as uint)) {
3215         cx.sess().span_bug(error_span, "debuginfo: Could not find type for node id!");
3216     }
3217 }
3218
3219 fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: ast::DefId)
3220                                    -> (DIScope, Span) {
3221     let containing_scope = namespace_for_item(cx, def_id).scope;
3222     let definition_span = if def_id.krate == ast::LOCAL_CRATE {
3223         cx.tcx.map.span(def_id.node)
3224     } else {
3225         // For external items there is no span information
3226         codemap::DUMMY_SP
3227     };
3228
3229     (containing_scope, definition_span)
3230 }
3231
3232 // This procedure builds the *scope map* for a given function, which maps any
3233 // given ast::NodeId in the function's AST to the correct DIScope metadata instance.
3234 //
3235 // This builder procedure walks the AST in execution order and keeps track of
3236 // what belongs to which scope, creating DIScope DIEs along the way, and
3237 // introducing *artificial* lexical scope descriptors where necessary. These
3238 // artificial scopes allow GDB to correctly handle name shadowing.
3239 fn populate_scope_map(cx: &CrateContext,
3240                       arg_pats: &[Gc<ast::Pat>],
3241                       fn_entry_block: &ast::Block,
3242                       fn_metadata: DISubprogram,
3243                       scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3244     let def_map = &cx.tcx.def_map;
3245
3246     struct ScopeStackEntry {
3247         scope_metadata: DIScope,
3248         ident: Option<ast::Ident>
3249     }
3250
3251     let mut scope_stack = vec!(ScopeStackEntry { scope_metadata: fn_metadata,
3252                                                  ident: None });
3253
3254     // Push argument identifiers onto the stack so arguments integrate nicely
3255     // with variable shadowing.
3256     for &arg_pat in arg_pats.iter() {
3257         pat_util::pat_bindings(def_map, &*arg_pat, |_, _, _, path_ref| {
3258             let ident = ast_util::path_to_ident(path_ref);
3259             scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata,
3260                                                ident: Some(ident) });
3261         })
3262     }
3263
3264     // Clang creates a separate scope for function bodies, so let's do this too.
3265     with_new_scope(cx,
3266                    fn_entry_block.span,
3267                    &mut scope_stack,
3268                    scope_map,
3269                    |cx, scope_stack, scope_map| {
3270         walk_block(cx, fn_entry_block, scope_stack, scope_map);
3271     });
3272
3273     // local helper functions for walking the AST.
3274     fn with_new_scope(cx: &CrateContext,
3275                       scope_span: Span,
3276                       scope_stack: &mut Vec<ScopeStackEntry> ,
3277                       scope_map: &mut HashMap<ast::NodeId, DIScope>,
3278                       inner_walk: |&CrateContext,
3279                                    &mut Vec<ScopeStackEntry> ,
3280                                    &mut HashMap<ast::NodeId, DIScope>|) {
3281         // Create a new lexical scope and push it onto the stack
3282         let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
3283         let file_metadata = file_metadata(cx, loc.file.name.as_slice());
3284         let parent_scope = scope_stack.last().unwrap().scope_metadata;
3285
3286         let scope_metadata = unsafe {
3287             llvm::LLVMDIBuilderCreateLexicalBlock(
3288                 DIB(cx),
3289                 parent_scope,
3290                 file_metadata,
3291                 loc.line as c_uint,
3292                 loc.col.to_uint() as c_uint,
3293                 0)
3294         };
3295
3296         scope_stack.push(ScopeStackEntry { scope_metadata: scope_metadata,
3297                                            ident: None });
3298
3299         inner_walk(cx, scope_stack, scope_map);
3300
3301         // pop artificial scopes
3302         while scope_stack.last().unwrap().ident.is_some() {
3303             scope_stack.pop();
3304         }
3305
3306         if scope_stack.last().unwrap().scope_metadata != scope_metadata {
3307             cx.sess().span_bug(scope_span, "debuginfo: Inconsistency in scope management.");
3308         }
3309
3310         scope_stack.pop();
3311     }
3312
3313     fn walk_block(cx: &CrateContext,
3314                   block: &ast::Block,
3315                   scope_stack: &mut Vec<ScopeStackEntry> ,
3316                   scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3317         scope_map.insert(block.id, scope_stack.last().unwrap().scope_metadata);
3318
3319         // The interesting things here are statements and the concluding expression.
3320         for statement in block.stmts.iter() {
3321             scope_map.insert(ast_util::stmt_id(&**statement),
3322                              scope_stack.last().unwrap().scope_metadata);
3323
3324             match statement.node {
3325                 ast::StmtDecl(ref decl, _) =>
3326                     walk_decl(cx, &**decl, scope_stack, scope_map),
3327                 ast::StmtExpr(ref exp, _) |
3328                 ast::StmtSemi(ref exp, _) =>
3329                     walk_expr(cx, &**exp, scope_stack, scope_map),
3330                 ast::StmtMac(..) => () // Ignore macros (which should be expanded anyway).
3331             }
3332         }
3333
3334         for exp in block.expr.iter() {
3335             walk_expr(cx, &**exp, scope_stack, scope_map);
3336         }
3337     }
3338
3339     fn walk_decl(cx: &CrateContext,
3340                  decl: &ast::Decl,
3341                  scope_stack: &mut Vec<ScopeStackEntry> ,
3342                  scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3343         match *decl {
3344             codemap::Spanned { node: ast::DeclLocal(local), .. } => {
3345                 scope_map.insert(local.id, scope_stack.last().unwrap().scope_metadata);
3346
3347                 walk_pattern(cx, local.pat, scope_stack, scope_map);
3348
3349                 for exp in local.init.iter() {
3350                     walk_expr(cx, &**exp, scope_stack, scope_map);
3351                 }
3352             }
3353             _ => ()
3354         }
3355     }
3356
3357     fn walk_pattern(cx: &CrateContext,
3358                     pat: Gc<ast::Pat>,
3359                     scope_stack: &mut Vec<ScopeStackEntry> ,
3360                     scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3361
3362         let def_map = &cx.tcx.def_map;
3363
3364         // Unfortunately, we cannot just use pat_util::pat_bindings() or
3365         // ast_util::walk_pat() here because we have to visit *all* nodes in
3366         // order to put them into the scope map. The above functions don't do that.
3367         match pat.node {
3368             ast::PatIdent(_, ref path_ref, ref sub_pat_opt) => {
3369
3370                 // Check if this is a binding. If so we need to put it on the
3371                 // scope stack and maybe introduce an artificial scope
3372                 if pat_util::pat_is_binding(def_map, &*pat) {
3373
3374                     let ident = ast_util::path_to_ident(path_ref);
3375
3376                     // LLVM does not properly generate 'DW_AT_start_scope' fields
3377                     // for variable DIEs. For this reason we have to introduce
3378                     // an artificial scope at bindings whenever a variable with
3379                     // the same name is declared in *any* parent scope.
3380                     //
3381                     // Otherwise the following error occurs:
3382                     //
3383                     // let x = 10;
3384                     //
3385                     // do_something(); // 'gdb print x' correctly prints 10
3386                     //
3387                     // {
3388                     //     do_something(); // 'gdb print x' prints 0, because it
3389                     //                     // already reads the uninitialized 'x'
3390                     //                     // from the next line...
3391                     //     let x = 100;
3392                     //     do_something(); // 'gdb print x' correctly prints 100
3393                     // }
3394
3395                     // Is there already a binding with that name?
3396                     // N.B.: this comparison must be UNhygienic... because
3397                     // gdb knows nothing about the context, so any two
3398                     // variables with the same name will cause the problem.
3399                     let need_new_scope = scope_stack
3400                         .iter()
3401                         .any(|entry| entry.ident.iter().any(|i| i.name == ident.name));
3402
3403                     if need_new_scope {
3404                         // Create a new lexical scope and push it onto the stack
3405                         let loc = cx.sess().codemap().lookup_char_pos(pat.span.lo);
3406                         let file_metadata = file_metadata(cx,
3407                                                           loc.file
3408                                                              .name
3409                                                              .as_slice());
3410                         let parent_scope = scope_stack.last().unwrap().scope_metadata;
3411
3412                         let scope_metadata = unsafe {
3413                             llvm::LLVMDIBuilderCreateLexicalBlock(
3414                                 DIB(cx),
3415                                 parent_scope,
3416                                 file_metadata,
3417                                 loc.line as c_uint,
3418                                 loc.col.to_uint() as c_uint,
3419                                 0)
3420                         };
3421
3422                         scope_stack.push(ScopeStackEntry {
3423                             scope_metadata: scope_metadata,
3424                             ident: Some(ident)
3425                         });
3426
3427                     } else {
3428                         // Push a new entry anyway so the name can be found
3429                         let prev_metadata = scope_stack.last().unwrap().scope_metadata;
3430                         scope_stack.push(ScopeStackEntry {
3431                             scope_metadata: prev_metadata,
3432                             ident: Some(ident)
3433                         });
3434                     }
3435                 }
3436
3437                 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3438
3439                 for &sub_pat in sub_pat_opt.iter() {
3440                     walk_pattern(cx, sub_pat, scope_stack, scope_map);
3441                 }
3442             }
3443
3444             ast::PatWild | ast::PatWildMulti => {
3445                 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3446             }
3447
3448             ast::PatEnum(_, ref sub_pats_opt) => {
3449                 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3450
3451                 for ref sub_pats in sub_pats_opt.iter() {
3452                     for &p in sub_pats.iter() {
3453                         walk_pattern(cx, p, scope_stack, scope_map);
3454                     }
3455                 }
3456             }
3457
3458             ast::PatStruct(_, ref field_pats, _) => {
3459                 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3460
3461                 for &ast::FieldPat { pat: sub_pat, .. } in field_pats.iter() {
3462                     walk_pattern(cx, sub_pat, scope_stack, scope_map);
3463                 }
3464             }
3465
3466             ast::PatTup(ref sub_pats) => {
3467                 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3468
3469                 for sub_pat in sub_pats.iter() {
3470                     walk_pattern(cx, sub_pat.clone(), scope_stack, scope_map);
3471                 }
3472             }
3473
3474             ast::PatBox(ref sub_pat) | ast::PatRegion(ref sub_pat) => {
3475                 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3476                 walk_pattern(cx, sub_pat.clone(), scope_stack, scope_map);
3477             }
3478
3479             ast::PatLit(ref exp) => {
3480                 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3481                 walk_expr(cx, &**exp, scope_stack, scope_map);
3482             }
3483
3484             ast::PatRange(ref exp1, ref exp2) => {
3485                 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3486                 walk_expr(cx, &**exp1, scope_stack, scope_map);
3487                 walk_expr(cx, &**exp2, scope_stack, scope_map);
3488             }
3489
3490             ast::PatVec(ref front_sub_pats, ref middle_sub_pats, ref back_sub_pats) => {
3491                 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3492
3493                 for &sub_pat in front_sub_pats.iter() {
3494                     walk_pattern(cx, sub_pat, scope_stack, scope_map);
3495                 }
3496
3497                 for &sub_pat in middle_sub_pats.iter() {
3498                     walk_pattern(cx, sub_pat, scope_stack, scope_map);
3499                 }
3500
3501                 for &sub_pat in back_sub_pats.iter() {
3502                     walk_pattern(cx, sub_pat, scope_stack, scope_map);
3503                 }
3504             }
3505
3506             ast::PatMac(_) => {
3507                 cx.sess().span_bug(pat.span, "debuginfo::populate_scope_map() - \
3508                                               Found unexpanded macro.");
3509             }
3510         }
3511     }
3512
3513     fn walk_expr(cx: &CrateContext,
3514                  exp: &ast::Expr,
3515                  scope_stack: &mut Vec<ScopeStackEntry> ,
3516                  scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3517
3518         scope_map.insert(exp.id, scope_stack.last().unwrap().scope_metadata);
3519
3520         match exp.node {
3521             ast::ExprLit(_)   |
3522             ast::ExprBreak(_) |
3523             ast::ExprAgain(_) |
3524             ast::ExprPath(_)  => {}
3525
3526             ast::ExprVstore(ref sub_exp, _)   |
3527             ast::ExprCast(ref sub_exp, _)     |
3528             ast::ExprAddrOf(_, ref sub_exp)  |
3529             ast::ExprField(ref sub_exp, _, _) |
3530             ast::ExprParen(ref sub_exp) =>
3531                 walk_expr(cx, &**sub_exp, scope_stack, scope_map),
3532
3533             ast::ExprBox(ref place, ref sub_expr) => {
3534                 walk_expr(cx, &**place, scope_stack, scope_map);
3535                 walk_expr(cx, &**sub_expr, scope_stack, scope_map);
3536             }
3537
3538             ast::ExprRet(exp_opt) => match exp_opt {
3539                 Some(sub_exp) => walk_expr(cx, &*sub_exp, scope_stack, scope_map),
3540                 None => ()
3541             },
3542
3543             ast::ExprUnary(_, ref sub_exp) => {
3544                 walk_expr(cx, &**sub_exp, scope_stack, scope_map);
3545             }
3546
3547             ast::ExprAssignOp(_, ref lhs, ref rhs) |
3548             ast::ExprIndex(ref lhs, ref rhs)        |
3549             ast::ExprBinary(_, ref lhs, ref rhs)    => {
3550                 walk_expr(cx, &**lhs, scope_stack, scope_map);
3551                 walk_expr(cx, &**rhs, scope_stack, scope_map);
3552             }
3553
3554             ast::ExprVec(ref init_expressions) |
3555             ast::ExprTup(ref init_expressions) => {
3556                 for ie in init_expressions.iter() {
3557                     walk_expr(cx, &**ie, scope_stack, scope_map);
3558                 }
3559             }
3560
3561             ast::ExprAssign(ref sub_exp1, ref sub_exp2) |
3562             ast::ExprRepeat(ref sub_exp1, ref sub_exp2) => {
3563                 walk_expr(cx, &**sub_exp1, scope_stack, scope_map);
3564                 walk_expr(cx, &**sub_exp2, scope_stack, scope_map);
3565             }
3566
3567             ast::ExprIf(ref cond_exp, ref then_block, ref opt_else_exp) => {
3568                 walk_expr(cx, &**cond_exp, scope_stack, scope_map);
3569
3570                 with_new_scope(cx,
3571                                then_block.span,
3572                                scope_stack,
3573                                scope_map,
3574                                |cx, scope_stack, scope_map| {
3575                     walk_block(cx, &**then_block, scope_stack, scope_map);
3576                 });
3577
3578                 match *opt_else_exp {
3579                     Some(ref else_exp) =>
3580                         walk_expr(cx, &**else_exp, scope_stack, scope_map),
3581                     _ => ()
3582                 }
3583             }
3584
3585             ast::ExprWhile(ref cond_exp, ref loop_body) => {
3586                 walk_expr(cx, &**cond_exp, scope_stack, scope_map);
3587
3588                 with_new_scope(cx,
3589                                loop_body.span,
3590                                scope_stack,
3591                                scope_map,
3592                                |cx, scope_stack, scope_map| {
3593                     walk_block(cx, &**loop_body, scope_stack, scope_map);
3594                 })
3595             }
3596
3597             ast::ExprForLoop(_, _, _, _) => {
3598                 cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
3599                                               Found unexpanded for-loop.");
3600             }
3601
3602             ast::ExprMac(_) => {
3603                 cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
3604                                               Found unexpanded macro.");
3605             }
3606
3607             ast::ExprLoop(ref block, _) |
3608             ast::ExprBlock(ref block)   => {
3609                 with_new_scope(cx,
3610                                block.span,
3611                                scope_stack,
3612                                scope_map,
3613                                |cx, scope_stack, scope_map| {
3614                     walk_block(cx, &**block, scope_stack, scope_map);
3615                 })
3616             }
3617
3618             ast::ExprFnBlock(ref decl, ref block) |
3619             ast::ExprProc(ref decl, ref block) => {
3620                 with_new_scope(cx,
3621                                block.span,
3622                                scope_stack,
3623                                scope_map,
3624                                |cx, scope_stack, scope_map| {
3625                     for &ast::Arg { pat: ref pattern, .. } in decl.inputs.iter() {
3626                         walk_pattern(cx, pattern.clone(), scope_stack, scope_map);
3627                     }
3628
3629                     walk_block(cx, &**block, scope_stack, scope_map);
3630                 })
3631             }
3632
3633             ast::ExprCall(ref fn_exp, ref args) => {
3634                 walk_expr(cx, &**fn_exp, scope_stack, scope_map);
3635
3636                 for arg_exp in args.iter() {
3637                     walk_expr(cx, &**arg_exp, scope_stack, scope_map);
3638                 }
3639             }
3640
3641             ast::ExprMethodCall(_, _, ref args) => {
3642                 for arg_exp in args.iter() {
3643                     walk_expr(cx, &**arg_exp, scope_stack, scope_map);
3644                 }
3645             }
3646
3647             ast::ExprMatch(ref discriminant_exp, ref arms) => {
3648                 walk_expr(cx, &**discriminant_exp, scope_stack, scope_map);
3649
3650                 // For each arm we have to first walk the pattern as these might
3651                 // introduce new artificial scopes. It should be sufficient to
3652                 // walk only one pattern per arm, as they all must contain the
3653                 // same binding names.
3654
3655                 for arm_ref in arms.iter() {
3656                     let arm_span = arm_ref.pats.get(0).span;
3657
3658                     with_new_scope(cx,
3659                                    arm_span,
3660                                    scope_stack,
3661                                    scope_map,
3662                                    |cx, scope_stack, scope_map| {
3663                         for &pat in arm_ref.pats.iter() {
3664                             walk_pattern(cx, pat, scope_stack, scope_map);
3665                         }
3666
3667                         for guard_exp in arm_ref.guard.iter() {
3668                             walk_expr(cx, &**guard_exp, scope_stack, scope_map)
3669                         }
3670
3671                         walk_expr(cx, &*arm_ref.body, scope_stack, scope_map);
3672                     })
3673                 }
3674             }
3675
3676             ast::ExprStruct(_, ref fields, ref base_exp) => {
3677                 for &ast::Field { expr: ref exp, .. } in fields.iter() {
3678                     walk_expr(cx, &**exp, scope_stack, scope_map);
3679                 }
3680
3681                 match *base_exp {
3682                     Some(ref exp) => walk_expr(cx, &**exp, scope_stack, scope_map),
3683                     None => ()
3684                 }
3685             }
3686
3687             ast::ExprInlineAsm(ast::InlineAsm { inputs: ref inputs,
3688                                                 outputs: ref outputs,
3689                                                 .. }) => {
3690                 // inputs, outputs: ~[(String, Gc<expr>)]
3691                 for &(_, ref exp) in inputs.iter() {
3692                     walk_expr(cx, &**exp, scope_stack, scope_map);
3693                 }
3694
3695                 for &(_, ref exp) in outputs.iter() {
3696                     walk_expr(cx, &**exp, scope_stack, scope_map);
3697                 }
3698             }
3699         }
3700     }
3701 }
3702
3703
3704 //=-----------------------------------------------------------------------------
3705 // Namespace Handling
3706 //=-----------------------------------------------------------------------------
3707
3708 struct NamespaceTreeNode {
3709     name: ast::Name,
3710     scope: DIScope,
3711     parent: Option<Weak<NamespaceTreeNode>>,
3712 }
3713
3714 impl NamespaceTreeNode {
3715     fn mangled_name_of_contained_item(&self, item_name: &str) -> String {
3716         fn fill_nested(node: &NamespaceTreeNode, output: &mut String) {
3717             match node.parent {
3718                 Some(ref parent) => fill_nested(&*parent.upgrade().unwrap(), output),
3719                 None => {}
3720             }
3721             let string = token::get_name(node.name);
3722             output.push_str(format!("{}", string.get().len()).as_slice());
3723             output.push_str(string.get());
3724         }
3725
3726         let mut name = String::from_str("_ZN");
3727         fill_nested(self, &mut name);
3728         name.push_str(format!("{}", item_name.len()).as_slice());
3729         name.push_str(item_name);
3730         name.push_char('E');
3731         name
3732     }
3733 }
3734
3735 fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTreeNode> {
3736     ty::with_path(cx.tcx(), def_id, |path| {
3737         // prepend crate name if not already present
3738         let krate = if def_id.krate == ast::LOCAL_CRATE {
3739             let crate_namespace_ident = token::str_to_ident(cx.link_meta
3740                                                               .crateid
3741                                                               .name
3742                                                               .as_slice());
3743             Some(ast_map::PathMod(crate_namespace_ident.name))
3744         } else {
3745             None
3746         };
3747         let mut path = krate.move_iter().chain(path).peekable();
3748
3749         let mut current_key = Vec::new();
3750         let mut parent_node: Option<Rc<NamespaceTreeNode>> = None;
3751
3752         // Create/Lookup namespace for each element of the path.
3753         loop {
3754             // Emulate a for loop so we can use peek below.
3755             let path_element = match path.next() {
3756                 Some(e) => e,
3757                 None => break
3758             };
3759             // Ignore the name of the item (the last path element).
3760             if path.peek().is_none() {
3761                 break;
3762             }
3763
3764             let name = path_element.name();
3765             current_key.push(name);
3766
3767             let existing_node = debug_context(cx).namespace_map.borrow()
3768                                                  .find_copy(&current_key);
3769             let current_node = match existing_node {
3770                 Some(existing_node) => existing_node,
3771                 None => {
3772                     // create and insert
3773                     let parent_scope = match parent_node {
3774                         Some(ref node) => node.scope,
3775                         None => ptr::mut_null()
3776                     };
3777                     let namespace_name = token::get_name(name);
3778                     let scope = namespace_name.get().with_c_str(|namespace_name| {
3779                         unsafe {
3780                             llvm::LLVMDIBuilderCreateNameSpace(
3781                                 DIB(cx),
3782                                 parent_scope,
3783                                 namespace_name,
3784                                 // cannot reconstruct file ...
3785                                 ptr::mut_null(),
3786                                 // ... or line information, but that's not so important.
3787                                 0)
3788                         }
3789                     });
3790
3791                     let node = Rc::new(NamespaceTreeNode {
3792                         name: name,
3793                         scope: scope,
3794                         parent: parent_node.map(|parent| parent.downgrade()),
3795                     });
3796
3797                     debug_context(cx).namespace_map.borrow_mut()
3798                                      .insert(current_key.clone(), node.clone());
3799
3800                     node
3801                 }
3802             };
3803
3804             parent_node = Some(current_node);
3805         }
3806
3807         match parent_node {
3808             Some(node) => node,
3809             None => {
3810                 cx.sess().bug(format!("debuginfo::namespace_for_item(): \
3811                                        path too short for {:?}",
3812                                       def_id).as_slice());
3813             }
3814         }
3815     })
3816 }