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