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