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