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.
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.
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:
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.
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.
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)`.
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:
41 let file_metadata = file_metadata(crate_context, path);
43 The function will take care of probing the cache for an existing node for that
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).
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
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
65 For example, the following simple type for a singly-linked list...
70 tail: Option<Box<List>>,
74 will generate the following callstack with a naive DFS algorithm:
79 describe(t = Option<Box<List>>)
80 describe(t = Box<List>)
81 describe(t = List) // at the beginning again...
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.
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
101 ## Source Locations and Line Information
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:
108 + set_source_location()
109 + clear_source_location()
110 + start_emitting_source_locations()
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
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.
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.
146 ## Unique Type Identification
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:
153 (1) Primitive types have their name as ID
154 (2) Structs, enums and traits have a multipart identifier
156 (1) The first part is the SVH (strict version hash) of the crate they were
157 originally defined in
159 (2) The second part is the ast::NodeId of the definition in their original
162 (3) The final part is a concatenation of the type IDs of their concrete type
163 arguments if they are generic types.
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).
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.
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). */
188 use driver::config::{FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
190 use llvm::{ModuleRef, ContextRef, ValueRef};
191 use llvm::debuginfo::*;
192 use metadata::csearch;
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;
202 use middle::pat_util;
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;
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;
219 static DW_LANG_RUST: c_uint = 0x9000;
221 static DW_TAG_auto_variable: c_uint = 0x100;
222 static DW_TAG_arg_variable: c_uint = 0x101;
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;
230 static UNKNOWN_LINE_NUMBER: c_uint = 0;
231 static UNKNOWN_COLUMN_NUMBER: c_uint = 0;
233 // ptr::null() doesn't work :(
234 static UNKNOWN_FILE_METADATA: DIFile = (0 as DIFile);
235 static UNKNOWN_SCOPE_METADATA: DIScope = (0 as DIScope);
237 static FLAGS_NONE: c_uint = 0;
238 static FLAGS_ARTIFICAL: c_uint = llvm::debuginfo::FlagArtificial as c_uint;
240 //=-----------------------------------------------------------------------------
241 // Public Interface of debuginfo module
242 //=-----------------------------------------------------------------------------
244 #[deriving(Copy, Show, Hash, Eq, PartialEq, Clone)]
245 struct UniqueTypeId(ast::Name);
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
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>
264 fn new() -> 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(),
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,
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());
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,
289 unique_type_id: UniqueTypeId,
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());
298 fn find_metadata_for_type(&self, type_: ty::t) -> Option<DIType> {
299 self.type_to_metadata.find_copy(&ty::type_id(type_))
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)
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)
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 {
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:>}
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 */}
344 let mut unique_type_id = String::with_capacity(256);
345 unique_type_id.push_char('{');
347 match ty::get(type_).sty {
356 push_debuginfo_type_name(cx, type_, false, &mut unique_type_id);
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);
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);
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());
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());
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());
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");
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());
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");
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());
408 ty::ty_vec(inner_type, optional_length) => {
409 match optional_length {
411 unique_type_id.push_str(format!("[{}]", len).as_slice());
414 unique_type_id.push_str("[]");
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());
422 ty::ty_trait(ref trait_data) => {
423 unique_type_id.push_str("trait ");
425 from_def_id_and_substs(self,
429 &mut unique_type_id);
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 ");
436 unique_type_id.push_str(abi.name());
438 unique_type_id.push_str(" fn(");
440 for ¶meter_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(',');
450 unique_type_id.push_str("...");
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());
458 ty::ty_closure(box ty::ClosureTy { fn_style,
464 if fn_style == ast::UnsafeFn {
465 unique_type_id.push_str("unsafe ");
468 if onceness == ast::Once {
469 unique_type_id.push_str("once ");
473 ty::UniqTraitStore => unique_type_id.push_str("~|"),
474 ty::RegionTraitStore(_, ast::MutMutable) => {
475 unique_type_id.push_str("&mut|")
477 ty::RegionTraitStore(_, ast::MutImmutable) => {
478 unique_type_id.push_str("&|")
482 for ¶meter_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(',');
492 unique_type_id.push_str("...");
495 unique_type_id.push_str("|->");
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());
501 unique_type_id.push_char(':');
503 for bound in bounds.builtin_bounds.iter() {
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"),
510 unique_type_id.push_char('+');
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())
520 unique_type_id.push_char('}');
522 // Trim to size before storing permanently
523 unique_type_id.shrink_to_fit();
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));
528 return UniqueTypeId(key);
530 fn from_def_id_and_substs(type_map: &mut TypeMap,
533 substs: &subst::Substs,
534 output: &mut String) {
535 use std::num::ToStrRadix;
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.
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()
556 cx.sess().cstore.get_crate_hash(source_def_id.krate)
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());
563 // Maybe check that there is no self type here.
565 let tps = substs.types.get_slice(subst::TypeSpace);
567 output.push_char('<');
569 for &type_parameter in tps.iter() {
571 type_map.get_unique_type_id_of_type(cx, type_parameter);
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(',');
578 output.push_char('>');
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,
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)
596 let interner_key = self.unique_id_interner.intern(Rc::new(enum_variant_type_id));
597 UniqueTypeId(interner_key)
600 fn get_unique_type_id_of_gc_box(&mut self,
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)
608 let interner_key = self.unique_id_interner.intern(Rc::new(gc_box_type_id));
609 UniqueTypeId(interner_key)
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
619 .find_metadata_for_unique_id($unique_type_id) {
620 Some(metadata) => return MetadataCreationResult::new(metadata, true),
621 None => { /* proceed normally */ }
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>>,
635 type_map: RefCell<TypeMap>,
636 namespace_map: RefCell<HashMap<Vec<ast::Name>, Rc<NamespaceTreeNode>>>,
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>>,
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,
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()),
662 pub struct FunctionDebugContext {
663 repr: FunctionDebugContextRepr,
666 enum FunctionDebugContextRepr {
667 FunctionDebugContext(Box<FunctionDebugContextData>),
669 FunctionWithoutDebugInfo,
672 impl FunctionDebugContext {
673 fn get_ref<'a>(&'a self,
676 -> &'a FunctionDebugContextData {
678 FunctionDebugContext(box ref data) => data,
679 DebugInfoDisabled => {
680 cx.sess().span_bug(span,
681 FunctionDebugContext::debuginfo_disabled_message());
683 FunctionWithoutDebugInfo => {
684 cx.sess().span_bug(span,
685 FunctionDebugContext::should_be_ignored_message());
690 fn debuginfo_disabled_message() -> &'static str {
691 "debuginfo: Error trying to access FunctionDebugContext although debug info is disabled!"
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!"
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>,
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] }
716 ArgumentVariable(uint /*index*/),
721 /// Create any deferred debug metadata nodes
722 pub fn finalize(cx: &CrateContext) {
723 if cx.dbg_cx().is_none() {
728 compile_unit_metadata(cx);
730 llvm::LLVMDIBuilderFinalize(DIB(cx));
731 llvm::LLVMDIBuilderDispose(DIB(cx));
732 // Debuginfo generation in LLVM by default uses a higher
733 // version of dwarf than OS X currently understands. We can
734 // instruct LLVM to emit an older version of dwarf, however,
735 // for OS X to understand. For more info see #11352
736 // This can be overridden using --llvm-opts -dwarf-version,N.
737 if cx.sess().targ_cfg.os == abi::OsMacos ||
738 cx.sess().targ_cfg.os == abi::OsiOS {
739 "Dwarf Version".with_c_str(
740 |s| llvm::LLVMRustAddModuleFlag(cx.llmod(), s, 2));
741 } else if cx.sess().targ_cfg.os == abi::OsLinux {
742 // FIXME(#13611) this is a kludge fix because the Linux bots have
743 // gdb 7.4 which doesn't understand dwarf4, we should
744 // do something more graceful here.
745 "Dwarf Version".with_c_str(
746 |s| llvm::LLVMRustAddModuleFlag(cx.llmod(), s, 3));
749 // Prevent bitcode readers from deleting the debug info.
750 "Debug Info Version".with_c_str(
751 |s| llvm::LLVMRustAddModuleFlag(cx.llmod(), s,
752 llvm::LLVMRustDebugMetadataVersion));
756 /// Creates debug information for the given global variable.
758 /// Adds the created metadata nodes directly to the crate's IR.
759 pub fn create_global_var_metadata(cx: &CrateContext,
760 node_id: ast::NodeId,
762 if cx.dbg_cx().is_none() {
766 // Don't create debuginfo for globals inlined from other crates. The other
767 // crate should already contain debuginfo for it. More importantly, the
768 // global might not even exist in un-inlined form anywhere which would lead
769 // to a linker errors.
770 if cx.external_srcs().borrow().contains_key(&node_id) {
774 let var_item = cx.tcx().map.get(node_id);
776 let (ident, span) = match var_item {
777 ast_map::NodeItem(item) => {
779 ast::ItemStatic(..) => (item.ident, item.span),
783 format!("debuginfo::\
784 create_global_var_metadata() -
785 Captured var-id refers to \
786 unexpected ast_item variant: {:?}",
787 var_item).as_slice())
791 _ => cx.sess().bug(format!("debuginfo::create_global_var_metadata() \
792 - Captured var-id refers to unexpected \
793 ast_map variant: {:?}",
794 var_item).as_slice())
797 let (file_metadata, line_number) = if span != codemap::DUMMY_SP {
798 let loc = span_start(cx, span);
799 (file_metadata(cx, loc.file.name.as_slice()), loc.line as c_uint)
801 (UNKNOWN_FILE_METADATA, UNKNOWN_LINE_NUMBER)
804 let is_local_to_unit = is_node_local_to_unit(cx, node_id);
805 let variable_type = ty::node_id_to_type(cx.tcx(), node_id);
806 let type_metadata = type_metadata(cx, variable_type, span);
807 let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
808 let var_name = token::get_ident(ident).get().to_string();
810 namespace_node.mangled_name_of_contained_item(var_name.as_slice());
811 let var_scope = namespace_node.scope;
813 var_name.as_slice().with_c_str(|var_name| {
814 linkage_name.as_slice().with_c_str(|linkage_name| {
816 llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
831 /// Creates debug information for the given local variable.
833 /// Adds the created metadata nodes directly to the crate's IR.
834 pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) {
835 if fn_should_be_ignored(bcx.fcx) {
840 let def_map = &cx.tcx().def_map;
842 pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path1| {
843 let var_ident = path1.node;
845 let datum = match bcx.fcx.lllocals.borrow().find_copy(&node_id) {
846 Some(datum) => datum,
848 bcx.sess().span_bug(span,
849 format!("no entry in lllocals table for {:?}",
850 node_id).as_slice());
854 let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
860 DirectVariable { alloca: datum.val },
866 /// Creates debug information for a variable captured in a closure.
868 /// Adds the created metadata nodes directly to the crate's IR.
869 pub fn create_captured_var_metadata(bcx: Block,
870 node_id: ast::NodeId,
871 env_data_type: ty::t,
872 env_pointer: ValueRef,
874 closure_store: ty::TraitStore,
876 if fn_should_be_ignored(bcx.fcx) {
882 let ast_item = cx.tcx().map.find(node_id);
884 let variable_ident = match ast_item {
886 cx.sess().span_bug(span, "debuginfo::create_captured_var_metadata: node not found");
888 Some(ast_map::NodeLocal(pat)) | Some(ast_map::NodeArg(pat)) => {
890 ast::PatIdent(_, ref path1, _) => {
897 "debuginfo::create_captured_var_metadata() - \
898 Captured var-id refers to unexpected \
899 ast_map variant: {:?}",
900 ast_item).as_slice());
907 format!("debuginfo::create_captured_var_metadata() - \
908 Captured var-id refers to unexpected \
909 ast_map variant: {:?}",
910 ast_item).as_slice());
914 let variable_type = node_id_type(bcx, node_id);
915 let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata;
917 let llvm_env_data_type = type_of::type_of(cx, env_data_type);
918 let byte_offset_of_var_in_env = machine::llelement_offset(cx,
922 let address_operations = unsafe {
923 [llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref()),
924 llvm::LLVMDIBuilderCreateOpPlus(Type::i64(cx).to_ref()),
925 C_i64(cx, byte_offset_of_var_in_env as i64),
926 llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref())]
929 let address_op_count = match closure_store {
930 ty::RegionTraitStore(..) => {
931 address_operations.len()
933 ty::UniqTraitStore => {
934 address_operations.len() - 1
938 let variable_access = IndirectVariable {
940 address_operations: address_operations.slice_to(address_op_count)
952 /// Creates debug information for a local variable introduced in the head of a
953 /// match-statement arm.
955 /// Adds the created metadata nodes directly to the crate's IR.
956 pub fn create_match_binding_metadata(bcx: Block,
957 variable_ident: ast::Ident,
958 binding: BindingInfo) {
959 if fn_should_be_ignored(bcx.fcx) {
963 let scope_metadata = scope_metadata(bcx.fcx, binding.id, binding.span);
965 [llvm::LLVMDIBuilderCreateOpDeref(bcx.ccx().int_type().to_ref())]
967 // Regardless of the actual type (`T`) we're always passed the stack slot (alloca)
968 // for the binding. For ByRef bindings that's a `T*` but for ByMove bindings we
969 // actually have `T**`. So to get the actual variable we need to dereference once
970 // more. For ByCopy we just use the stack slot we created for the binding.
971 let var_type = match binding.trmode {
972 TrByCopy(llbinding) => DirectVariable {
975 TrByMove => IndirectVariable {
976 alloca: binding.llmatch,
977 address_operations: aops
979 TrByRef => DirectVariable {
980 alloca: binding.llmatch
993 /// Creates debug information for the given function argument.
995 /// Adds the created metadata nodes directly to the crate's IR.
996 pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) {
997 if fn_should_be_ignored(bcx.fcx) {
1004 let def_map = &cx.tcx().def_map;
1005 let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata;
1007 pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path1| {
1008 let llarg = match bcx.fcx.llargs.borrow().find_copy(&node_id) {
1011 bcx.sess().span_bug(span,
1012 format!("no entry in llargs table for {:?}",
1013 node_id).as_slice());
1017 if unsafe { llvm::LLVMIsAAllocaInst(llarg.val) } == ptr::mut_null() {
1018 cx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \
1019 Referenced variable location is not an alloca!");
1022 let argument_index = {
1023 let counter = &fcx.debug_context.get_ref(cx, span).argument_counter;
1024 let argument_index = counter.get();
1025 counter.set(argument_index + 1);
1033 DirectVariable { alloca: llarg.val },
1034 ArgumentVariable(argument_index),
1039 /// Sets the current debug location at the beginning of the span.
1041 /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). The node_id
1042 /// parameter is used to reliably find the correct visibility scope for the code
1044 pub fn set_source_location(fcx: &FunctionContext,
1045 node_id: ast::NodeId,
1047 match fcx.debug_context.repr {
1048 DebugInfoDisabled => return,
1049 FunctionWithoutDebugInfo => {
1050 set_debug_location(fcx.ccx, UnknownLocation);
1053 FunctionDebugContext(box ref function_debug_context) => {
1056 debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span));
1058 if function_debug_context.source_locations_enabled.get() {
1059 let loc = span_start(cx, span);
1060 let scope = scope_metadata(fcx, node_id, span);
1062 set_debug_location(cx, DebugLocation::new(scope,
1064 loc.col.to_uint()));
1066 set_debug_location(cx, UnknownLocation);
1072 /// Clears the current debug location.
1074 /// Instructions generated hereafter won't be assigned a source location.
1075 pub fn clear_source_location(fcx: &FunctionContext) {
1076 if fn_should_be_ignored(fcx) {
1080 set_debug_location(fcx.ccx, UnknownLocation);
1083 /// Enables emitting source locations for the given functions.
1085 /// Since we don't want source locations to be emitted for the function prelude,
1086 /// they are disabled when beginning to translate a new function. This functions
1087 /// switches source location emitting on and must therefore be called before the
1088 /// first real statement/expression of the function is translated.
1089 pub fn start_emitting_source_locations(fcx: &FunctionContext) {
1090 match fcx.debug_context.repr {
1091 FunctionDebugContext(box ref data) => {
1092 data.source_locations_enabled.set(true)
1094 _ => { /* safe to ignore */ }
1098 /// Creates the function-specific debug context.
1100 /// Returns the FunctionDebugContext for the function which holds state needed
1101 /// for debug info creation. The function may also return another variant of the
1102 /// FunctionDebugContext enum which indicates why no debuginfo should be created
1103 /// for the function.
1104 pub fn create_function_debug_context(cx: &CrateContext,
1105 fn_ast_id: ast::NodeId,
1106 param_substs: ¶m_substs,
1107 llfn: ValueRef) -> FunctionDebugContext {
1108 if cx.sess().opts.debuginfo == NoDebugInfo {
1109 return FunctionDebugContext { repr: DebugInfoDisabled };
1112 // Clear the debug location so we don't assign them in the function prelude.
1113 // Do this here already, in case we do an early exit from this function.
1114 set_debug_location(cx, UnknownLocation);
1116 if fn_ast_id == -1 {
1117 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1120 let empty_generics = ast_util::empty_generics();
1122 let fnitem = cx.tcx().map.get(fn_ast_id);
1124 let (ident, fn_decl, generics, top_level_block, span, has_path) = match fnitem {
1125 ast_map::NodeItem(ref item) => {
1126 if contains_nodebug_attribute(item.attrs.as_slice()) {
1127 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1131 ast::ItemFn(ref fn_decl, _, _, ref generics, ref top_level_block) => {
1132 (item.ident, &**fn_decl, generics, &**top_level_block, item.span, true)
1135 cx.sess().span_bug(item.span,
1136 "create_function_debug_context: item bound to non-function");
1140 ast_map::NodeImplItem(ref item) => {
1142 ast::MethodImplItem(ref method) => {
1143 if contains_nodebug_attribute(method.attrs.as_slice()) {
1144 return FunctionDebugContext {
1145 repr: FunctionWithoutDebugInfo
1150 method.pe_fn_decl(),
1151 method.pe_generics(),
1158 ast_map::NodeExpr(ref expr) => {
1160 ast::ExprFnBlock(_, ref fn_decl, ref top_level_block) |
1161 ast::ExprProc(ref fn_decl, ref top_level_block) |
1162 ast::ExprUnboxedFn(_, _, ref fn_decl, ref top_level_block) => {
1163 let name = format!("fn{}", token::gensym("fn"));
1164 let name = token::str_to_ident(name.as_slice());
1166 // This is not quite right. It should actually inherit
1167 // the generics of the enclosing function.
1171 // Don't try to lookup the item path:
1174 _ => cx.sess().span_bug(expr.span,
1175 "create_function_debug_context: expected an expr_fn_block here")
1178 ast_map::NodeTraitItem(ref trait_method) => {
1179 match **trait_method {
1180 ast::ProvidedMethod(ref method) => {
1181 if contains_nodebug_attribute(method.attrs.as_slice()) {
1182 return FunctionDebugContext {
1183 repr: FunctionWithoutDebugInfo
1188 method.pe_fn_decl(),
1189 method.pe_generics(),
1196 .bug(format!("create_function_debug_context: \
1197 unexpected sort of node: {:?}",
1202 ast_map::NodeForeignItem(..) |
1203 ast_map::NodeVariant(..) |
1204 ast_map::NodeStructCtor(..) => {
1205 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1207 _ => cx.sess().bug(format!("create_function_debug_context: \
1208 unexpected sort of node: {:?}",
1212 // This can be the case for functions inlined from another crate
1213 if span == codemap::DUMMY_SP {
1214 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1217 let loc = span_start(cx, span);
1218 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
1220 let function_type_metadata = unsafe {
1221 let fn_signature = get_function_signature(cx,
1226 llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
1229 // Get_template_parameters() will append a `<...>` clause to the function
1230 // name if necessary.
1231 let mut function_name = String::from_str(token::get_ident(ident).get());
1232 let template_parameters = get_template_parameters(cx,
1236 &mut function_name);
1238 // There is no ast_map::Path for ast::ExprFnBlock-type functions. For now,
1239 // just don't put them into a namespace. In the future this could be improved
1240 // somehow (storing a path in the ast_map, or construct a path using the
1241 // enclosing function).
1242 let (linkage_name, containing_scope) = if has_path {
1243 let namespace_node = namespace_for_item(cx, ast_util::local_def(fn_ast_id));
1244 let linkage_name = namespace_node.mangled_name_of_contained_item(
1245 function_name.as_slice());
1246 let containing_scope = namespace_node.scope;
1247 (linkage_name, containing_scope)
1249 (function_name.as_slice().to_string(), file_metadata)
1252 // Clang sets this parameter to the opening brace of the function's block,
1253 // so let's do this too.
1254 let scope_line = span_start(cx, top_level_block.span).line;
1256 let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id);
1258 let fn_metadata = function_name.as_slice().with_c_str(|function_name| {
1259 linkage_name.as_slice().with_c_str(|linkage_name| {
1261 llvm::LLVMDIBuilderCreateFunction(
1268 function_type_metadata,
1271 scope_line as c_uint,
1272 FlagPrototyped as c_uint,
1273 cx.sess().opts.optimize != config::No,
1275 template_parameters,
1281 // Initialize fn debug context (including scope map and namespace map)
1282 let fn_debug_context = box FunctionDebugContextData {
1283 scope_map: RefCell::new(HashMap::new()),
1284 fn_metadata: fn_metadata,
1285 argument_counter: Cell::new(1),
1286 source_locations_enabled: Cell::new(false),
1289 populate_scope_map(cx,
1290 fn_decl.inputs.as_slice(),
1293 &mut *fn_debug_context.scope_map.borrow_mut());
1295 return FunctionDebugContext { repr: FunctionDebugContext(fn_debug_context) };
1297 fn get_function_signature(cx: &CrateContext,
1298 fn_ast_id: ast::NodeId,
1299 fn_decl: &ast::FnDecl,
1300 param_substs: ¶m_substs,
1301 error_span: Span) -> DIArray {
1302 if cx.sess().opts.debuginfo == LimitedDebugInfo {
1303 return create_DIArray(DIB(cx), []);
1306 let mut signature = Vec::with_capacity(fn_decl.inputs.len() + 1);
1308 // Return type -- llvm::DIBuilder wants this at index 0
1309 match fn_decl.output.node {
1311 signature.push(ptr::mut_null());
1314 assert_type_for_node_id(cx, fn_ast_id, error_span);
1316 let return_type = ty::node_id_to_type(cx.tcx(), fn_ast_id);
1317 let return_type = return_type.substp(cx.tcx(), param_substs);
1318 signature.push(type_metadata(cx, return_type, codemap::DUMMY_SP));
1323 for arg in fn_decl.inputs.iter() {
1324 assert_type_for_node_id(cx, arg.pat.id, arg.pat.span);
1325 let arg_type = ty::node_id_to_type(cx.tcx(), arg.pat.id);
1326 let arg_type = arg_type.substp(cx.tcx(), param_substs);
1327 signature.push(type_metadata(cx, arg_type, codemap::DUMMY_SP));
1330 return create_DIArray(DIB(cx), signature.as_slice());
1333 fn get_template_parameters(cx: &CrateContext,
1334 generics: &ast::Generics,
1335 param_substs: ¶m_substs,
1336 file_metadata: DIFile,
1337 name_to_append_suffix_to: &mut String)
1339 let self_type = param_substs.substs.self_ty();
1341 // Only true for static default methods:
1342 let has_self_type = self_type.is_some();
1344 if !generics.is_type_parameterized() && !has_self_type {
1345 return create_DIArray(DIB(cx), []);
1348 name_to_append_suffix_to.push_char('<');
1350 // The list to be filled with template parameters:
1351 let mut template_params: Vec<DIDescriptor> =
1352 Vec::with_capacity(generics.ty_params.len() + 1);
1356 let actual_self_type = self_type.unwrap();
1357 // Add self type name to <...> clause of function name
1358 let actual_self_type_name = compute_debuginfo_type_name(
1363 name_to_append_suffix_to.push_str(actual_self_type_name.as_slice());
1365 if generics.is_type_parameterized() {
1366 name_to_append_suffix_to.push_str(",");
1369 // Only create type information if full debuginfo is enabled
1370 if cx.sess().opts.debuginfo == FullDebugInfo {
1371 let actual_self_type_metadata = type_metadata(cx,
1375 let ident = special_idents::type_self;
1377 let param_metadata = token::get_ident(ident).get()
1378 .with_c_str(|name| {
1380 llvm::LLVMDIBuilderCreateTemplateTypeParameter(
1384 actual_self_type_metadata,
1391 template_params.push(param_metadata);
1395 // Handle other generic parameters
1396 let actual_types = param_substs.substs.types.get_slice(subst::FnSpace);
1397 for (index, &ast::TyParam{ ident: ident, .. }) in generics.ty_params.iter().enumerate() {
1398 let actual_type = actual_types[index];
1399 // Add actual type name to <...> clause of function name
1400 let actual_type_name = compute_debuginfo_type_name(cx,
1403 name_to_append_suffix_to.push_str(actual_type_name.as_slice());
1405 if index != generics.ty_params.len() - 1 {
1406 name_to_append_suffix_to.push_str(",");
1409 // Again, only create type information if full debuginfo is enabled
1410 if cx.sess().opts.debuginfo == FullDebugInfo {
1411 let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP);
1412 let param_metadata = token::get_ident(ident).get()
1413 .with_c_str(|name| {
1415 llvm::LLVMDIBuilderCreateTemplateTypeParameter(
1419 actual_type_metadata,
1425 template_params.push(param_metadata);
1429 name_to_append_suffix_to.push_char('>');
1431 return create_DIArray(DIB(cx), template_params.as_slice());
1435 //=-----------------------------------------------------------------------------
1436 // Module-Internal debug info creation functions
1437 //=-----------------------------------------------------------------------------
1439 fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
1441 // The is_local_to_unit flag indicates whether a function is local to the
1442 // current compilation unit (i.e. if it is *static* in the C-sense). The
1443 // *reachable* set should provide a good approximation of this, as it
1444 // contains everything that might leak out of the current crate (by being
1445 // externally visible or by being inlined into something externally visible).
1446 // It might better to use the `exported_items` set from `driver::CrateAnalysis`
1447 // in the future, but (atm) this set is not available in the translation pass.
1448 !cx.reachable().contains(&node_id)
1451 #[allow(non_snake_case)]
1452 fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
1454 llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
1458 fn compile_unit_metadata(cx: &CrateContext) {
1459 let work_dir = &cx.sess().working_dir;
1460 let compile_unit_name = match cx.sess().local_crate_source_file {
1461 None => fallback_path(cx),
1462 Some(ref abs_path) => {
1463 if abs_path.is_relative() {
1464 cx.sess().warn("debuginfo: Invalid path to crate's local root source file!");
1467 match abs_path.path_relative_from(work_dir) {
1468 Some(ref p) if p.is_relative() => {
1469 // prepend "./" if necessary
1471 let prefix = &[dotdot[0], ::std::path::SEP_BYTE];
1472 let mut path_bytes = Vec::from_slice(p.as_vec());
1474 if path_bytes.slice_to(2) != prefix &&
1475 path_bytes.slice_to(2) != dotdot {
1476 path_bytes.insert(0, prefix[0]);
1477 path_bytes.insert(1, prefix[1]);
1480 path_bytes.as_slice().to_c_str()
1482 _ => fallback_path(cx)
1488 debug!("compile_unit_metadata: {:?}", compile_unit_name);
1489 let producer = format!("rustc version {}",
1490 (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
1492 let compile_unit_name = compile_unit_name.as_ptr();
1493 work_dir.as_vec().with_c_str(|work_dir| {
1494 producer.with_c_str(|producer| {
1495 "".with_c_str(|flags| {
1496 "".with_c_str(|split_name| {
1498 llvm::LLVMDIBuilderCreateCompileUnit(
1499 debug_context(cx).builder,
1504 cx.sess().opts.optimize != config::No,
1514 fn fallback_path(cx: &CrateContext) -> CString {
1515 cx.link_meta().crate_name.as_slice().to_c_str()
1519 fn declare_local(bcx: Block,
1520 variable_ident: ast::Ident,
1521 variable_type: ty::t,
1522 scope_metadata: DIScope,
1523 variable_access: VariableAccess,
1524 variable_kind: VariableKind,
1526 let cx: &CrateContext = bcx.ccx();
1528 let filename = span_start(cx, span).file.name.clone();
1529 let file_metadata = file_metadata(cx, filename.as_slice());
1531 let name = token::get_ident(variable_ident);
1532 let loc = span_start(cx, span);
1533 let type_metadata = type_metadata(cx, variable_type, span);
1535 let (argument_index, dwarf_tag) = match variable_kind {
1536 ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
1538 CapturedVariable => (0, DW_TAG_auto_variable)
1541 let (var_alloca, var_metadata) = name.get().with_c_str(|name| {
1542 match variable_access {
1543 DirectVariable { alloca } => (
1546 llvm::LLVMDIBuilderCreateLocalVariable(
1554 cx.sess().opts.optimize != config::No,
1559 IndirectVariable { alloca, address_operations } => (
1562 llvm::LLVMDIBuilderCreateComplexVariable(
1570 address_operations.as_ptr(),
1571 address_operations.len() as c_uint,
1578 set_debug_location(cx, DebugLocation::new(scope_metadata,
1580 loc.col.to_uint()));
1582 let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
1588 llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
1591 match variable_kind {
1592 ArgumentVariable(_) | CapturedVariable => {
1596 .source_locations_enabled
1598 set_debug_location(cx, UnknownLocation);
1600 _ => { /* nothing to do */ }
1604 fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
1605 match debug_context(cx).created_files.borrow().find_equiv(&full_path) {
1606 Some(file_metadata) => return *file_metadata,
1610 debug!("file_metadata: {}", full_path);
1612 // FIXME (#9639): This needs to handle non-utf8 paths
1613 let work_dir = cx.sess().working_dir.as_str().unwrap();
1615 if full_path.starts_with(work_dir) {
1616 full_path.slice(work_dir.len() + 1u, full_path.len())
1622 file_name.with_c_str(|file_name| {
1623 work_dir.with_c_str(|work_dir| {
1625 llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir)
1630 let mut created_files = debug_context(cx).created_files.borrow_mut();
1631 created_files.insert(full_path.to_string(), file_metadata);
1632 return file_metadata;
1635 /// Finds the scope metadata node for the given AST node.
1636 fn scope_metadata(fcx: &FunctionContext,
1637 node_id: ast::NodeId,
1640 let scope_map = &fcx.debug_context.get_ref(fcx.ccx, span).scope_map;
1641 match scope_map.borrow().find_copy(&node_id) {
1642 Some(scope_metadata) => scope_metadata,
1644 let node = fcx.ccx.tcx().map.get(node_id);
1646 fcx.ccx.sess().span_bug(span,
1647 format!("debuginfo: Could not find scope info for node {:?}",
1653 fn basic_type_metadata(cx: &CrateContext, t: ty::t) -> DIType {
1655 debug!("basic_type_metadata: {:?}", ty::get(t));
1657 let (name, encoding) = match ty::get(t).sty {
1658 ty::ty_nil => ("()".to_string(), DW_ATE_unsigned),
1659 ty::ty_bot => ("!".to_string(), DW_ATE_unsigned),
1660 ty::ty_bool => ("bool".to_string(), DW_ATE_boolean),
1661 ty::ty_char => ("char".to_string(), DW_ATE_unsigned_char),
1662 ty::ty_int(int_ty) => match int_ty {
1663 ast::TyI => ("int".to_string(), DW_ATE_signed),
1664 ast::TyI8 => ("i8".to_string(), DW_ATE_signed),
1665 ast::TyI16 => ("i16".to_string(), DW_ATE_signed),
1666 ast::TyI32 => ("i32".to_string(), DW_ATE_signed),
1667 ast::TyI64 => ("i64".to_string(), DW_ATE_signed)
1669 ty::ty_uint(uint_ty) => match uint_ty {
1670 ast::TyU => ("uint".to_string(), DW_ATE_unsigned),
1671 ast::TyU8 => ("u8".to_string(), DW_ATE_unsigned),
1672 ast::TyU16 => ("u16".to_string(), DW_ATE_unsigned),
1673 ast::TyU32 => ("u32".to_string(), DW_ATE_unsigned),
1674 ast::TyU64 => ("u64".to_string(), DW_ATE_unsigned)
1676 ty::ty_float(float_ty) => match float_ty {
1677 ast::TyF32 => ("f32".to_string(), DW_ATE_float),
1678 ast::TyF64 => ("f64".to_string(), DW_ATE_float),
1680 _ => cx.sess().bug("debuginfo::basic_type_metadata - t is invalid type")
1683 let llvm_type = type_of::type_of(cx, t);
1684 let (size, align) = size_and_align_of(cx, llvm_type);
1685 let ty_metadata = name.with_c_str(|name| {
1687 llvm::LLVMDIBuilderCreateBasicType(
1690 bytes_to_bits(size),
1691 bytes_to_bits(align),
1699 fn pointer_type_metadata(cx: &CrateContext,
1700 pointer_type: ty::t,
1701 pointee_type_metadata: DIType)
1703 let pointer_llvm_type = type_of::type_of(cx, pointer_type);
1704 let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
1705 let name = compute_debuginfo_type_name(cx, pointer_type, false);
1706 let ptr_metadata = name.as_slice().with_c_str(|name| {
1708 llvm::LLVMDIBuilderCreatePointerType(
1710 pointee_type_metadata,
1711 bytes_to_bits(pointer_size),
1712 bytes_to_bits(pointer_align),
1716 return ptr_metadata;
1719 //=-----------------------------------------------------------------------------
1720 // Common facilities for record-like types (structs, enums, tuples)
1721 //=-----------------------------------------------------------------------------
1724 FixedMemberOffset { bytes: uint },
1725 // For ComputedMemberOffset, the offset is read from the llvm type definition
1726 ComputedMemberOffset
1729 // Description of a type member, which can either be a regular field (as in
1730 // structs or tuples) or an enum variant
1731 struct MemberDescription {
1734 type_metadata: DIType,
1735 offset: MemberOffset,
1739 // A factory for MemberDescriptions. It produces a list of member descriptions
1740 // for some record-like type. MemberDescriptionFactories are used to defer the
1741 // creation of type member descriptions in order to break cycles arising from
1742 // recursive type definitions.
1743 enum MemberDescriptionFactory {
1744 StructMDF(StructMemberDescriptionFactory),
1745 TupleMDF(TupleMemberDescriptionFactory),
1746 EnumMDF(EnumMemberDescriptionFactory),
1747 VariantMDF(VariantMemberDescriptionFactory)
1750 impl MemberDescriptionFactory {
1751 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
1753 StructMDF(ref this) => {
1754 this.create_member_descriptions(cx)
1756 TupleMDF(ref this) => {
1757 this.create_member_descriptions(cx)
1759 EnumMDF(ref this) => {
1760 this.create_member_descriptions(cx)
1762 VariantMDF(ref this) => {
1763 this.create_member_descriptions(cx)
1769 // A description of some recursive type. It can either be already finished (as
1770 // with FinalMetadata) or it is not yet finished, but contains all information
1771 // needed to generate the missing parts of the description. See the documentation
1772 // section on Recursive Types at the top of this file for more information.
1773 enum RecursiveTypeDescription {
1774 UnfinishedMetadata {
1775 unfinished_type: ty::t,
1776 unique_type_id: UniqueTypeId,
1777 metadata_stub: DICompositeType,
1779 member_description_factory: MemberDescriptionFactory,
1781 FinalMetadata(DICompositeType)
1784 fn create_and_register_recursive_type_forward_declaration(
1786 unfinished_type: ty::t,
1787 unique_type_id: UniqueTypeId,
1788 metadata_stub: DICompositeType,
1790 member_description_factory: MemberDescriptionFactory)
1791 -> RecursiveTypeDescription {
1793 // Insert the stub into the TypeMap in order to allow for recursive references
1794 let mut type_map = debug_context(cx).type_map.borrow_mut();
1795 type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata_stub);
1796 type_map.register_type_with_metadata(cx, unfinished_type, metadata_stub);
1798 UnfinishedMetadata {
1799 unfinished_type: unfinished_type,
1800 unique_type_id: unique_type_id,
1801 metadata_stub: metadata_stub,
1802 llvm_type: llvm_type,
1803 member_description_factory: member_description_factory,
1807 impl RecursiveTypeDescription {
1808 // Finishes up the description of the type in question (mostly by providing
1809 // descriptions of the fields of the given type) and returns the final type metadata.
1810 fn finalize(&self, cx: &CrateContext) -> MetadataCreationResult {
1812 FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
1813 UnfinishedMetadata {
1818 ref member_description_factory,
1821 // Make sure that we have a forward declaration of the type in
1822 // the TypeMap so that recursive references are possible. This
1823 // will always be the case if the RecursiveTypeDescription has
1824 // been properly created through the
1825 // create_and_register_recursive_type_forward_declaration() function.
1827 let type_map = debug_context(cx).type_map.borrow();
1828 if type_map.find_metadata_for_unique_id(unique_type_id).is_none() ||
1829 type_map.find_metadata_for_type(unfinished_type).is_none() {
1830 cx.sess().bug(format!("Forward declaration of potentially recursive type \
1831 '{}' was not found in TypeMap!",
1832 ppaux::ty_to_string(cx.tcx(), unfinished_type))
1837 // ... then create the member descriptions ...
1838 let member_descriptions =
1839 member_description_factory.create_member_descriptions(cx);
1841 // ... and attach them to the stub to complete it.
1842 set_members_of_composite_type(cx,
1845 member_descriptions.as_slice());
1846 return MetadataCreationResult::new(metadata_stub, true);
1853 //=-----------------------------------------------------------------------------
1855 //=-----------------------------------------------------------------------------
1857 // Creates MemberDescriptions for the fields of a struct
1858 struct StructMemberDescriptionFactory {
1859 fields: Vec<ty::field>,
1864 impl StructMemberDescriptionFactory {
1865 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
1866 if self.fields.len() == 0 {
1870 let field_size = if self.is_simd {
1871 machine::llsize_of_alloc(cx, type_of::type_of(cx, self.fields.get(0).mt.ty)) as uint
1876 self.fields.iter().enumerate().map(|(i, field)| {
1877 let name = if field.ident.name == special_idents::unnamed_field.name {
1880 token::get_ident(field.ident).get().to_string()
1883 let offset = if self.is_simd {
1884 assert!(field_size != 0xdeadbeef);
1885 FixedMemberOffset { bytes: i * field_size }
1887 ComputedMemberOffset
1892 llvm_type: type_of::type_of(cx, field.mt.ty),
1893 type_metadata: type_metadata(cx, field.mt.ty, self.span),
1902 fn prepare_struct_metadata(cx: &CrateContext,
1905 substs: &subst::Substs,
1906 unique_type_id: UniqueTypeId,
1908 -> RecursiveTypeDescription {
1909 let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
1910 let struct_llvm_type = type_of::type_of(cx, struct_type);
1912 let (containing_scope, _) = get_namespace_and_span_for_item(cx, def_id);
1914 let struct_metadata_stub = create_struct_stub(cx,
1916 struct_name.as_slice(),
1920 let fields = ty::struct_fields(cx.tcx(), def_id, substs);
1922 create_and_register_recursive_type_forward_declaration(
1926 struct_metadata_stub,
1928 StructMDF(StructMemberDescriptionFactory {
1930 is_simd: ty::type_is_simd(cx.tcx(), struct_type),
1937 //=-----------------------------------------------------------------------------
1939 //=-----------------------------------------------------------------------------
1941 // Creates MemberDescriptions for the fields of a tuple
1942 struct TupleMemberDescriptionFactory {
1943 component_types: Vec<ty::t> ,
1947 impl TupleMemberDescriptionFactory {
1948 fn create_member_descriptions(&self, cx: &CrateContext)
1949 -> Vec<MemberDescription> {
1950 self.component_types.iter().map(|&component_type| {
1952 name: "".to_string(),
1953 llvm_type: type_of::type_of(cx, component_type),
1954 type_metadata: type_metadata(cx, component_type, self.span),
1955 offset: ComputedMemberOffset,
1962 fn prepare_tuple_metadata(cx: &CrateContext,
1964 component_types: &[ty::t],
1965 unique_type_id: UniqueTypeId,
1967 -> RecursiveTypeDescription {
1968 let tuple_name = compute_debuginfo_type_name(cx, tuple_type, false);
1969 let tuple_llvm_type = type_of::type_of(cx, tuple_type);
1971 create_and_register_recursive_type_forward_declaration(
1975 create_struct_stub(cx,
1977 tuple_name.as_slice(),
1979 UNKNOWN_SCOPE_METADATA),
1981 TupleMDF(TupleMemberDescriptionFactory {
1982 component_types: Vec::from_slice(component_types),
1989 //=-----------------------------------------------------------------------------
1991 //=-----------------------------------------------------------------------------
1993 // Describes the members of an enum value: An enum is described as a union of
1994 // structs in DWARF. This MemberDescriptionFactory provides the description for
1995 // the members of this union; so for every variant of the given enum, this factory
1996 // will produce one MemberDescription (all with no name and a fixed offset of
1998 struct EnumMemberDescriptionFactory {
2000 type_rep: Rc<adt::Repr>,
2001 variants: Rc<Vec<Rc<ty::VariantInfo>>>,
2002 discriminant_type_metadata: Option<DIType>,
2003 containing_scope: DIScope,
2004 file_metadata: DIFile,
2008 impl EnumMemberDescriptionFactory {
2009 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
2010 match *self.type_rep {
2011 adt::General(_, ref struct_defs, _) => {
2012 let discriminant_info = RegularDiscriminant(self.discriminant_type_metadata
2018 .map(|(i, struct_def)| {
2019 let (variant_type_metadata,
2021 member_desc_factory) =
2022 describe_enum_variant(cx,
2025 &**self.variants.get(i),
2027 self.containing_scope,
2030 let member_descriptions = member_desc_factory
2031 .create_member_descriptions(cx);
2033 set_members_of_composite_type(cx,
2034 variant_type_metadata,
2036 member_descriptions.as_slice());
2038 name: "".to_string(),
2039 llvm_type: variant_llvm_type,
2040 type_metadata: variant_type_metadata,
2041 offset: FixedMemberOffset { bytes: 0 },
2046 adt::Univariant(ref struct_def, _) => {
2047 assert!(self.variants.len() <= 1);
2049 if self.variants.len() == 0 {
2052 let (variant_type_metadata,
2054 member_description_factory) =
2055 describe_enum_variant(cx,
2058 &**self.variants.get(0),
2060 self.containing_scope,
2063 let member_descriptions =
2064 member_description_factory.create_member_descriptions(cx);
2066 set_members_of_composite_type(cx,
2067 variant_type_metadata,
2069 member_descriptions.as_slice());
2072 name: "".to_string(),
2073 llvm_type: variant_llvm_type,
2074 type_metadata: variant_type_metadata,
2075 offset: FixedMemberOffset { bytes: 0 },
2081 adt::RawNullablePointer { nndiscr: non_null_variant_index, nnty, .. } => {
2082 // As far as debuginfo is concerned, the pointer this enum
2083 // represents is still wrapped in a struct. This is to make the
2084 // DWARF representation of enums uniform.
2086 // First create a description of the artificial wrapper struct:
2087 let non_null_variant = self.variants.get(non_null_variant_index as uint);
2088 let non_null_variant_ident = non_null_variant.name;
2089 let non_null_variant_name = token::get_ident(non_null_variant_ident);
2091 // The llvm type and metadata of the pointer
2092 let non_null_llvm_type = type_of::type_of(cx, nnty);
2093 let non_null_type_metadata = type_metadata(cx, nnty, self.span);
2095 // The type of the artificial struct wrapping the pointer
2096 let artificial_struct_llvm_type = Type::struct_(cx,
2097 &[non_null_llvm_type],
2100 // For the metadata of the wrapper struct, we need to create a
2101 // MemberDescription of the struct's single field.
2102 let sole_struct_member_description = MemberDescription {
2103 name: match non_null_variant.arg_names {
2104 Some(ref names) => token::get_ident(*names.get(0)).get().to_string(),
2105 None => "".to_string()
2107 llvm_type: non_null_llvm_type,
2108 type_metadata: non_null_type_metadata,
2109 offset: FixedMemberOffset { bytes: 0 },
2113 let unique_type_id = debug_context(cx).type_map
2115 .get_unique_type_id_of_enum_variant(
2118 non_null_variant_name.get());
2120 // Now we can create the metadata of the artificial struct
2121 let artificial_struct_metadata =
2122 composite_type_metadata(cx,
2123 artificial_struct_llvm_type,
2124 non_null_variant_name.get(),
2126 &[sole_struct_member_description],
2127 self.containing_scope,
2131 // Encode the information about the null variant in the union
2133 let null_variant_index = (1 - non_null_variant_index) as uint;
2134 let null_variant_ident = self.variants.get(null_variant_index).name;
2135 let null_variant_name = token::get_ident(null_variant_ident);
2136 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
2140 // Finally create the (singleton) list of descriptions of union
2144 name: union_member_name,
2145 llvm_type: artificial_struct_llvm_type,
2146 type_metadata: artificial_struct_metadata,
2147 offset: FixedMemberOffset { bytes: 0 },
2152 adt::StructWrappedNullablePointer { nonnull: ref struct_def,
2155 // Create a description of the non-null variant
2156 let (variant_type_metadata, variant_llvm_type, member_description_factory) =
2157 describe_enum_variant(cx,
2160 &**self.variants.get(nndiscr as uint),
2161 OptimizedDiscriminant(ptrfield),
2162 self.containing_scope,
2165 let variant_member_descriptions =
2166 member_description_factory.create_member_descriptions(cx);
2168 set_members_of_composite_type(cx,
2169 variant_type_metadata,
2171 variant_member_descriptions.as_slice());
2173 // Encode the information about the null variant in the union
2175 let null_variant_index = (1 - nndiscr) as uint;
2176 let null_variant_ident = self.variants.get(null_variant_index).name;
2177 let null_variant_name = token::get_ident(null_variant_ident);
2178 let discrfield = match ptrfield {
2179 adt::ThinPointer(field) => format!("{}", field),
2180 adt::FatPointer(field, pair) => format!("{}${}", field, pair)
2182 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
2186 // Create the (singleton) list of descriptions of union members.
2189 name: union_member_name,
2190 llvm_type: variant_llvm_type,
2191 type_metadata: variant_type_metadata,
2192 offset: FixedMemberOffset { bytes: 0 },
2197 adt::CEnum(..) => cx.sess().span_bug(self.span, "This should be unreachable.")
2202 // Creates MemberDescriptions for the fields of a single enum variant.
2203 struct VariantMemberDescriptionFactory {
2204 args: Vec<(String, ty::t)> ,
2205 discriminant_type_metadata: Option<DIType>,
2209 impl VariantMemberDescriptionFactory {
2210 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
2211 self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
2213 name: name.to_string(),
2214 llvm_type: type_of::type_of(cx, ty),
2215 type_metadata: match self.discriminant_type_metadata {
2216 Some(metadata) if i == 0 => metadata,
2217 _ => type_metadata(cx, ty, self.span)
2219 offset: ComputedMemberOffset,
2220 flags: if self.discriminant_type_metadata.is_some() && i == 0 {
2230 enum EnumDiscriminantInfo {
2231 RegularDiscriminant(DIType),
2232 OptimizedDiscriminant(adt::PointerField),
2236 // Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type
2237 // of the variant, and (3) a MemberDescriptionFactory for producing the
2238 // descriptions of the fields of the variant. This is a rudimentary version of a
2239 // full RecursiveTypeDescription.
2240 fn describe_enum_variant(cx: &CrateContext,
2242 struct_def: &adt::Struct,
2243 variant_info: &ty::VariantInfo,
2244 discriminant_info: EnumDiscriminantInfo,
2245 containing_scope: DIScope,
2247 -> (DICompositeType, Type, MemberDescriptionFactory) {
2248 let variant_llvm_type =
2249 Type::struct_(cx, struct_def.fields
2251 .map(|&t| type_of::type_of(cx, t))
2252 .collect::<Vec<_>>()
2255 // Could do some consistency checks here: size, align, field count, discr type
2257 let variant_name = token::get_ident(variant_info.name);
2258 let variant_name = variant_name.get();
2259 let unique_type_id = debug_context(cx).type_map
2261 .get_unique_type_id_of_enum_variant(
2266 let metadata_stub = create_struct_stub(cx,
2272 // Get the argument names from the enum variant info
2273 let mut arg_names: Vec<_> = match variant_info.arg_names {
2274 Some(ref names) => {
2277 token::get_ident(*ident).get().to_string().into_string()
2280 None => variant_info.args.iter().map(|_| "".to_string()).collect()
2283 // If this is not a univariant enum, there is also the (unnamed) discriminant field.
2284 match discriminant_info {
2285 RegularDiscriminant(_) => arg_names.insert(0, "".to_string()),
2286 _ => { /* do nothing */ }
2289 // Build an array of (field name, field type) pairs to be captured in the factory closure.
2290 let args: Vec<(String, ty::t)> = arg_names.iter()
2291 .zip(struct_def.fields.iter())
2292 .map(|(s, &t)| (s.to_string(), t))
2295 let member_description_factory =
2296 VariantMDF(VariantMemberDescriptionFactory {
2298 discriminant_type_metadata: match discriminant_info {
2299 RegularDiscriminant(discriminant_type_metadata) => {
2300 Some(discriminant_type_metadata)
2307 (metadata_stub, variant_llvm_type, member_description_factory)
2310 fn prepare_enum_metadata(cx: &CrateContext,
2312 enum_def_id: ast::DefId,
2313 unique_type_id: UniqueTypeId,
2315 -> RecursiveTypeDescription {
2316 let enum_name = compute_debuginfo_type_name(cx, enum_type, false);
2318 let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, enum_def_id);
2319 let loc = span_start(cx, definition_span);
2320 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2322 let variants = ty::enum_variants(cx.tcx(), enum_def_id);
2324 let enumerators_metadata: Vec<DIDescriptor> = variants
2327 token::get_ident(v.name).get().with_c_str(|name| {
2329 llvm::LLVMDIBuilderCreateEnumerator(
2332 v.disr_val as c_ulonglong)
2338 let discriminant_type_metadata = |inttype| {
2339 // We can reuse the type of the discriminant for all monomorphized
2340 // instances of an enum because it doesn't depend on any type parameters.
2341 // The def_id, uniquely identifying the enum's polytype acts as key in
2343 let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
2345 .find_copy(&enum_def_id);
2346 match cached_discriminant_type_metadata {
2347 Some(discriminant_type_metadata) => discriminant_type_metadata,
2349 let discriminant_llvm_type = adt::ll_inttype(cx, inttype);
2350 let (discriminant_size, discriminant_align) =
2351 size_and_align_of(cx, discriminant_llvm_type);
2352 let discriminant_base_type_metadata = type_metadata(cx,
2353 adt::ty_of_inttype(inttype),
2355 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
2357 let discriminant_type_metadata = discriminant_name.get().with_c_str(|name| {
2359 llvm::LLVMDIBuilderCreateEnumerationType(
2363 UNKNOWN_FILE_METADATA,
2364 UNKNOWN_LINE_NUMBER,
2365 bytes_to_bits(discriminant_size),
2366 bytes_to_bits(discriminant_align),
2367 create_DIArray(DIB(cx), enumerators_metadata.as_slice()),
2368 discriminant_base_type_metadata)
2372 debug_context(cx).created_enum_disr_types
2374 .insert(enum_def_id, discriminant_type_metadata);
2376 discriminant_type_metadata
2381 let type_rep = adt::represent_type(cx, enum_type);
2383 let discriminant_type_metadata = match *type_rep {
2384 adt::CEnum(inttype, _, _) => {
2385 return FinalMetadata(discriminant_type_metadata(inttype))
2387 adt::RawNullablePointer { .. } |
2388 adt::StructWrappedNullablePointer { .. } |
2389 adt::Univariant(..) => None,
2390 adt::General(inttype, _, _) => Some(discriminant_type_metadata(inttype)),
2393 let enum_llvm_type = type_of::type_of(cx, enum_type);
2394 let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
2396 let unique_type_id_str = debug_context(cx)
2399 .get_unique_type_id_as_string(unique_type_id);
2401 let enum_metadata = enum_name.as_slice().with_c_str(|enum_name| {
2402 unique_type_id_str.as_slice().with_c_str(|unique_type_id_str| {
2404 llvm::LLVMDIBuilderCreateUnionType(
2408 UNKNOWN_FILE_METADATA,
2409 UNKNOWN_LINE_NUMBER,
2410 bytes_to_bits(enum_type_size),
2411 bytes_to_bits(enum_type_align),
2420 return create_and_register_recursive_type_forward_declaration(
2426 EnumMDF(EnumMemberDescriptionFactory {
2427 enum_type: enum_type,
2428 type_rep: type_rep.clone(),
2430 discriminant_type_metadata: discriminant_type_metadata,
2431 containing_scope: containing_scope,
2432 file_metadata: file_metadata,
2437 fn get_enum_discriminant_name(cx: &CrateContext,
2439 -> token::InternedString {
2440 let name = if def_id.krate == ast::LOCAL_CRATE {
2441 cx.tcx().map.get_path_elem(def_id.node).name()
2443 csearch::get_item_path(cx.tcx(), def_id).last().unwrap().name()
2446 token::get_name(name)
2450 /// Creates debug information for a composite type, that is, anything that
2451 /// results in a LLVM struct.
2453 /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
2454 fn composite_type_metadata(cx: &CrateContext,
2455 composite_llvm_type: Type,
2456 composite_type_name: &str,
2457 composite_type_unique_id: UniqueTypeId,
2458 member_descriptions: &[MemberDescription],
2459 containing_scope: DIScope,
2461 // Ignore source location information as long as it
2462 // can't be reconstructed for non-local crates.
2463 _file_metadata: DIFile,
2464 _definition_span: Span)
2465 -> DICompositeType {
2466 // Create the (empty) struct metadata node ...
2467 let composite_type_metadata = create_struct_stub(cx,
2468 composite_llvm_type,
2469 composite_type_name,
2470 composite_type_unique_id,
2472 // ... and immediately create and add the member descriptions.
2473 set_members_of_composite_type(cx,
2474 composite_type_metadata,
2475 composite_llvm_type,
2476 member_descriptions);
2478 return composite_type_metadata;
2481 fn set_members_of_composite_type(cx: &CrateContext,
2482 composite_type_metadata: DICompositeType,
2483 composite_llvm_type: Type,
2484 member_descriptions: &[MemberDescription]) {
2485 // In some rare cases LLVM metadata uniquing would lead to an existing type
2486 // description being used instead of a new one created in create_struct_stub.
2487 // This would cause a hard to trace assertion in DICompositeType::SetTypeArray().
2488 // The following check makes sure that we get a better error message if this
2489 // should happen again due to some regression.
2491 let mut composite_types_completed =
2492 debug_context(cx).composite_types_completed.borrow_mut();
2493 if composite_types_completed.contains(&composite_type_metadata) {
2494 let (llvm_version_major, llvm_version_minor) = unsafe {
2495 (llvm::LLVMVersionMajor(), llvm::LLVMVersionMinor())
2498 let actual_llvm_version = llvm_version_major * 1000000 + llvm_version_minor * 1000;
2499 let min_supported_llvm_version = 3 * 1000000 + 4 * 1000;
2501 if actual_llvm_version < min_supported_llvm_version {
2502 cx.sess().warn(format!("This version of rustc was built with LLVM \
2503 {}.{}. Rustc just ran into a known \
2504 debuginfo corruption problem thatoften \
2505 occurs with LLVM versions below 3.4. \
2506 Please use a rustc built with anewer \
2509 llvm_version_minor).as_slice());
2511 cx.sess().bug("debuginfo::set_members_of_composite_type() - \
2512 Already completed forward declaration re-encountered.");
2515 composite_types_completed.insert(composite_type_metadata);
2519 let member_metadata: Vec<DIDescriptor> = member_descriptions
2522 .map(|(i, member_description)| {
2523 let (member_size, member_align) = size_and_align_of(cx, member_description.llvm_type);
2524 let member_offset = match member_description.offset {
2525 FixedMemberOffset { bytes } => bytes as u64,
2526 ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
2529 member_description.name.as_slice().with_c_str(|member_name| {
2531 llvm::LLVMDIBuilderCreateMemberType(
2533 composite_type_metadata,
2535 UNKNOWN_FILE_METADATA,
2536 UNKNOWN_LINE_NUMBER,
2537 bytes_to_bits(member_size),
2538 bytes_to_bits(member_align),
2539 bytes_to_bits(member_offset),
2540 member_description.flags,
2541 member_description.type_metadata)
2548 let type_array = create_DIArray(DIB(cx), member_metadata.as_slice());
2549 llvm::LLVMDICompositeTypeSetTypeArray(composite_type_metadata, type_array);
2553 // A convenience wrapper around LLVMDIBuilderCreateStructType(). Does not do any
2554 // caching, does not add any fields to the struct. This can be done later with
2555 // set_members_of_composite_type().
2556 fn create_struct_stub(cx: &CrateContext,
2557 struct_llvm_type: Type,
2558 struct_type_name: &str,
2559 unique_type_id: UniqueTypeId,
2560 containing_scope: DIScope)
2561 -> DICompositeType {
2562 let (struct_size, struct_align) = size_and_align_of(cx, struct_llvm_type);
2564 let unique_type_id_str = debug_context(cx).type_map
2566 .get_unique_type_id_as_string(unique_type_id);
2567 let metadata_stub = unsafe {
2568 struct_type_name.with_c_str(|name| {
2569 unique_type_id_str.as_slice().with_c_str(|unique_type_id| {
2570 // LLVMDIBuilderCreateStructType() wants an empty array. A null
2571 // pointer will lead to hard to trace and debug LLVM assertions
2572 // later on in llvm/lib/IR/Value.cpp.
2573 let empty_array = create_DIArray(DIB(cx), []);
2575 llvm::LLVMDIBuilderCreateStructType(
2579 UNKNOWN_FILE_METADATA,
2580 UNKNOWN_LINE_NUMBER,
2581 bytes_to_bits(struct_size),
2582 bytes_to_bits(struct_align),
2593 return metadata_stub;
2596 fn at_box_metadata(cx: &CrateContext,
2597 at_pointer_type: ty::t,
2598 content_type: ty::t,
2599 unique_type_id: UniqueTypeId)
2600 -> MetadataCreationResult {
2601 let content_type_metadata = type_metadata(cx, content_type, codemap::DUMMY_SP);
2603 return_if_metadata_created_in_meantime!(cx, unique_type_id);
2605 let content_type_name = compute_debuginfo_type_name(cx, content_type, true);
2606 let content_type_name = content_type_name.as_slice();
2607 let content_llvm_type = type_of::type_of(cx, content_type);
2609 let box_type_name = format!("GcBox<{}>", content_type_name);
2610 let box_llvm_type = Type::at_box(cx, content_llvm_type);
2611 let member_llvm_types = box_llvm_type.field_types();
2612 assert!(box_layout_is_correct(cx,
2613 member_llvm_types.as_slice(),
2614 content_llvm_type));
2616 let int_type = ty::mk_int();
2617 let nil_pointer_type = ty::mk_nil_ptr(cx.tcx());
2618 let nil_pointer_type_metadata = type_metadata(cx,
2621 let member_descriptions = [
2623 name: "refcnt".to_string(),
2624 llvm_type: *member_llvm_types.get(0),
2625 type_metadata: type_metadata(cx, int_type, codemap::DUMMY_SP),
2626 offset: ComputedMemberOffset,
2627 flags: FLAGS_ARTIFICAL,
2630 name: "drop_glue".to_string(),
2631 llvm_type: *member_llvm_types.get(1),
2632 type_metadata: nil_pointer_type_metadata,
2633 offset: ComputedMemberOffset,
2634 flags: FLAGS_ARTIFICAL,
2637 name: "prev".to_string(),
2638 llvm_type: *member_llvm_types.get(2),
2639 type_metadata: nil_pointer_type_metadata,
2640 offset: ComputedMemberOffset,
2641 flags: FLAGS_ARTIFICAL,
2644 name: "next".to_string(),
2645 llvm_type: *member_llvm_types.get(3),
2646 type_metadata: nil_pointer_type_metadata,
2647 offset: ComputedMemberOffset,
2648 flags: FLAGS_ARTIFICAL,
2651 name: "val".to_string(),
2652 llvm_type: *member_llvm_types.get(4),
2653 type_metadata: content_type_metadata,
2654 offset: ComputedMemberOffset,
2655 flags: FLAGS_ARTIFICAL,
2659 let gc_box_unique_id = debug_context(cx).type_map
2661 .get_unique_type_id_of_gc_box(cx, content_type);
2663 let gc_box_metadata = composite_type_metadata(
2666 box_type_name.as_slice(),
2668 member_descriptions,
2669 UNKNOWN_SCOPE_METADATA,
2670 UNKNOWN_FILE_METADATA,
2673 let gc_pointer_metadata = pointer_type_metadata(cx,
2677 return MetadataCreationResult::new(gc_pointer_metadata, false);
2679 // Unfortunately, we cannot assert anything but the correct types here---and
2680 // not whether the 'next' and 'prev' pointers are in the correct order.
2681 fn box_layout_is_correct(cx: &CrateContext,
2682 member_llvm_types: &[Type],
2683 content_llvm_type: Type)
2685 member_llvm_types.len() == 5 &&
2686 member_llvm_types[0] == cx.int_type() &&
2687 member_llvm_types[1] == Type::generic_glue_fn(cx).ptr_to() &&
2688 member_llvm_types[2] == Type::i8(cx).ptr_to() &&
2689 member_llvm_types[3] == Type::i8(cx).ptr_to() &&
2690 member_llvm_types[4] == content_llvm_type
2695 fn fixed_vec_metadata(cx: &CrateContext,
2696 unique_type_id: UniqueTypeId,
2697 element_type: ty::t,
2700 -> MetadataCreationResult {
2701 let element_type_metadata = type_metadata(cx, element_type, span);
2703 return_if_metadata_created_in_meantime!(cx, unique_type_id);
2705 let element_llvm_type = type_of::type_of(cx, element_type);
2706 let (element_type_size, element_type_align) = size_and_align_of(cx, element_llvm_type);
2708 let subrange = unsafe {
2709 llvm::LLVMDIBuilderGetOrCreateSubrange(
2715 let subscripts = create_DIArray(DIB(cx), [subrange]);
2716 let metadata = unsafe {
2717 llvm::LLVMDIBuilderCreateArrayType(
2719 bytes_to_bits(element_type_size * (len as u64)),
2720 bytes_to_bits(element_type_align),
2721 element_type_metadata,
2725 return MetadataCreationResult::new(metadata, false);
2728 fn vec_slice_metadata(cx: &CrateContext,
2730 element_type: ty::t,
2731 unique_type_id: UniqueTypeId,
2733 -> MetadataCreationResult {
2734 let data_ptr_type = ty::mk_ptr(cx.tcx(), ty::mt {
2736 mutbl: ast::MutImmutable
2739 let element_type_metadata = type_metadata(cx, data_ptr_type, span);
2741 return_if_metadata_created_in_meantime!(cx, unique_type_id);
2743 let slice_llvm_type = type_of::type_of(cx, vec_type);
2744 let slice_type_name = compute_debuginfo_type_name(cx, vec_type, true);
2746 let member_llvm_types = slice_llvm_type.field_types();
2747 assert!(slice_layout_is_correct(cx,
2748 member_llvm_types.as_slice(),
2750 let member_descriptions = [
2752 name: "data_ptr".to_string(),
2753 llvm_type: *member_llvm_types.get(0),
2754 type_metadata: element_type_metadata,
2755 offset: ComputedMemberOffset,
2756 flags: FLAGS_ARTIFICAL
2759 name: "length".to_string(),
2760 llvm_type: *member_llvm_types.get(1),
2761 type_metadata: type_metadata(cx, ty::mk_uint(), span),
2762 offset: ComputedMemberOffset,
2763 flags: FLAGS_ARTIFICAL
2767 assert!(member_descriptions.len() == member_llvm_types.len());
2769 let loc = span_start(cx, span);
2770 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2772 let metadata = composite_type_metadata(cx,
2774 slice_type_name.as_slice(),
2776 member_descriptions,
2777 UNKNOWN_SCOPE_METADATA,
2780 return MetadataCreationResult::new(metadata, false);
2782 fn slice_layout_is_correct(cx: &CrateContext,
2783 member_llvm_types: &[Type],
2784 element_type: ty::t)
2786 member_llvm_types.len() == 2 &&
2787 member_llvm_types[0] == type_of::type_of(cx, element_type).ptr_to() &&
2788 member_llvm_types[1] == cx.int_type()
2792 fn subroutine_type_metadata(cx: &CrateContext,
2793 unique_type_id: UniqueTypeId,
2794 signature: &ty::FnSig,
2796 -> MetadataCreationResult {
2797 let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs.len() + 1);
2800 signature_metadata.push(match ty::get(signature.output).sty {
2801 ty::ty_nil => ptr::mut_null(),
2802 _ => type_metadata(cx, signature.output, span)
2805 // regular arguments
2806 for &argument_type in signature.inputs.iter() {
2807 signature_metadata.push(type_metadata(cx, argument_type, span));
2810 return_if_metadata_created_in_meantime!(cx, unique_type_id);
2812 return MetadataCreationResult::new(
2814 llvm::LLVMDIBuilderCreateSubroutineType(
2816 UNKNOWN_FILE_METADATA,
2817 create_DIArray(DIB(cx), signature_metadata.as_slice()))
2822 // FIXME(1563) This is all a bit of a hack because 'trait pointer' is an ill-
2823 // defined concept. For the case of an actual trait pointer (i.e., Box<Trait>,
2824 // &Trait), trait_object_type should be the whole thing (e.g, Box<Trait>) and
2825 // trait_type should be the actual trait (e.g., Trait). Where the trait is part
2826 // of a DST struct, there is no trait_object_type and the results of this
2827 // function will be a little bit weird.
2828 fn trait_pointer_metadata(cx: &CrateContext,
2830 trait_object_type: Option<ty::t>,
2831 unique_type_id: UniqueTypeId)
2833 // The implementation provided here is a stub. It makes sure that the trait
2834 // type is assigned the correct name, size, namespace, and source location.
2835 // But it does not describe the trait's methods.
2837 let def_id = match ty::get(trait_type).sty {
2838 ty::ty_trait(box ty::TyTrait { def_id, .. }) => def_id,
2840 let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_type);
2841 cx.sess().bug(format!("debuginfo: Unexpected trait-object type in \
2842 trait_pointer_metadata(): {}",
2843 pp_type_name.as_slice()).as_slice());
2847 let trait_object_type = trait_object_type.unwrap_or(trait_type);
2848 let trait_type_name =
2849 compute_debuginfo_type_name(cx, trait_object_type, false);
2851 let (containing_scope, _) = get_namespace_and_span_for_item(cx, def_id);
2853 let trait_llvm_type = type_of::type_of(cx, trait_object_type);
2855 composite_type_metadata(cx,
2857 trait_type_name.as_slice(),
2861 UNKNOWN_FILE_METADATA,
2865 fn type_metadata(cx: &CrateContext,
2867 usage_site_span: Span)
2869 // Get the unique type id of this type.
2870 let unique_type_id = {
2871 let mut type_map = debug_context(cx).type_map.borrow_mut();
2872 // First, try to find the type in TypeMap. If we have seen it before, we
2873 // can exit early here.
2874 match type_map.find_metadata_for_type(t) {
2879 // The ty::t is not in the TypeMap but maybe we have already seen
2880 // an equivalent type (e.g. only differing in region arguments).
2881 // In order to find out, generate the unique type id and look
2883 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
2884 match type_map.find_metadata_for_unique_id(unique_type_id) {
2886 // There is already an equivalent type in the TypeMap.
2887 // Register this ty::t as an alias in the cache and
2888 // return the cached metadata.
2889 type_map.register_type_with_metadata(cx, t, metadata);
2893 // There really is no type metadata for this type, so
2894 // proceed by creating it.
2902 debug!("type_metadata: {:?}", ty::get(t));
2904 let sty = &ty::get(t).sty;
2905 let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty {
2912 ty::ty_float(_) => {
2913 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
2915 ty::ty_enum(def_id, _) => {
2916 prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span).finalize(cx)
2918 ty::ty_box(pointee_type) => {
2919 at_box_metadata(cx, t, pointee_type, unique_type_id)
2921 ty::ty_vec(typ, Some(len)) => {
2922 fixed_vec_metadata(cx, unique_type_id, typ, len, usage_site_span)
2924 // FIXME Can we do better than this for unsized vec/str fields?
2925 ty::ty_vec(typ, None) => fixed_vec_metadata(cx, unique_type_id, typ, 0, usage_site_span),
2926 ty::ty_str => fixed_vec_metadata(cx, unique_type_id, ty::mk_i8(), 0, usage_site_span),
2927 ty::ty_trait(..) => {
2928 MetadataCreationResult::new(
2929 trait_pointer_metadata(cx, t, None, unique_type_id),
2932 ty::ty_uniq(ty) | ty::ty_ptr(ty::mt{ty, ..}) | ty::ty_rptr(_, ty::mt{ty, ..}) => {
2933 match ty::get(ty).sty {
2934 ty::ty_vec(typ, None) => {
2935 vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span)
2938 vec_slice_metadata(cx, t, ty::mk_u8(), unique_type_id, usage_site_span)
2940 ty::ty_trait(..) => {
2941 MetadataCreationResult::new(
2942 trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
2946 let pointee_metadata = type_metadata(cx, ty, usage_site_span);
2948 match debug_context(cx).type_map
2950 .find_metadata_for_unique_id(unique_type_id) {
2951 Some(metadata) => return metadata,
2952 None => { /* proceed normally */ }
2955 MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
2960 ty::ty_bare_fn(ref barefnty) => {
2961 subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
2963 ty::ty_closure(ref closurety) => {
2964 subroutine_type_metadata(cx, unique_type_id, &closurety.sig, usage_site_span)
2966 ty::ty_struct(def_id, ref substs) => {
2967 prepare_struct_metadata(cx,
2972 usage_site_span).finalize(cx)
2974 ty::ty_tup(ref elements) => {
2975 prepare_tuple_metadata(cx,
2977 elements.as_slice(),
2979 usage_site_span).finalize(cx)
2982 cx.sess().bug(format!("debuginfo: unexpected type in type_metadata: {:?}",
2988 let mut type_map = debug_context(cx).type_map.borrow_mut();
2990 if already_stored_in_typemap {
2991 // Also make sure that we already have a TypeMap entry entry for the unique type id.
2992 let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
2993 Some(metadata) => metadata,
2995 let unique_type_id_str =
2996 type_map.get_unique_type_id_as_string(unique_type_id);
2997 let error_message = format!("Expected type metadata for unique \
2998 type id '{}' to already be in \
2999 the debuginfo::TypeMap but it \
3000 was not. (ty::t = {})",
3001 unique_type_id_str.as_slice(),
3002 ppaux::ty_to_string(cx.tcx(), t));
3003 cx.sess().span_bug(usage_site_span, error_message.as_slice());
3007 match type_map.find_metadata_for_type(t) {
3009 if metadata != metadata_for_uid {
3010 let unique_type_id_str =
3011 type_map.get_unique_type_id_as_string(unique_type_id);
3012 let error_message = format!("Mismatch between ty::t and \
3013 UniqueTypeId maps in \
3014 debuginfo::TypeMap. \
3015 UniqueTypeId={}, ty::t={}",
3016 unique_type_id_str.as_slice(),
3017 ppaux::ty_to_string(cx.tcx(), t));
3018 cx.sess().span_bug(usage_site_span, error_message.as_slice());
3022 type_map.register_type_with_metadata(cx, t, metadata);
3026 type_map.register_type_with_metadata(cx, t, metadata);
3027 type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata);
3034 struct MetadataCreationResult {
3036 already_stored_in_typemap: bool
3039 impl MetadataCreationResult {
3040 fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationResult {
3041 MetadataCreationResult {
3043 already_stored_in_typemap: already_stored_in_typemap
3048 #[deriving(PartialEq)]
3049 enum DebugLocation {
3050 KnownLocation { scope: DIScope, line: uint, col: uint },
3054 impl DebugLocation {
3055 fn new(scope: DIScope, line: uint, col: uint) -> DebugLocation {
3064 fn set_debug_location(cx: &CrateContext, debug_location: DebugLocation) {
3065 if debug_location == debug_context(cx).current_debug_location.get() {
3071 match debug_location {
3072 KnownLocation { scope, line, .. } => {
3073 // Always set the column to zero like Clang and GCC
3074 let col = UNKNOWN_COLUMN_NUMBER;
3075 debug!("setting debug location to {} {}", line, col);
3076 let elements = [C_i32(cx, line as i32), C_i32(cx, col as i32),
3077 scope, ptr::mut_null()];
3079 metadata_node = llvm::LLVMMDNodeInContext(debug_context(cx).llcontext,
3081 elements.len() as c_uint);
3084 UnknownLocation => {
3085 debug!("clearing debug location ");
3086 metadata_node = ptr::mut_null();
3091 llvm::LLVMSetCurrentDebugLocation(cx.raw_builder(), metadata_node);
3094 debug_context(cx).current_debug_location.set(debug_location);
3097 //=-----------------------------------------------------------------------------
3098 // Utility Functions
3099 //=-----------------------------------------------------------------------------
3101 fn contains_nodebug_attribute(attributes: &[ast::Attribute]) -> bool {
3102 attributes.iter().any(|attr| {
3103 let meta_item: &ast::MetaItem = &*attr.node.value;
3104 match meta_item.node {
3105 ast::MetaWord(ref value) => value.get() == "no_debug",
3111 /// Return codemap::Loc corresponding to the beginning of the span
3112 fn span_start(cx: &CrateContext, span: Span) -> codemap::Loc {
3113 cx.sess().codemap().lookup_char_pos(span.lo)
3116 fn size_and_align_of(cx: &CrateContext, llvm_type: Type) -> (u64, u64) {
3117 (machine::llsize_of_alloc(cx, llvm_type), machine::llalign_of_min(cx, llvm_type))
3120 fn bytes_to_bits(bytes: u64) -> c_ulonglong {
3121 (bytes * 8) as c_ulonglong
3125 fn debug_context<'a>(cx: &'a CrateContext) -> &'a CrateDebugContext {
3126 let debug_context: &'a CrateDebugContext = cx.dbg_cx().get_ref();
3131 #[allow(non_snake_case)]
3132 fn DIB(cx: &CrateContext) -> DIBuilderRef {
3133 cx.dbg_cx().get_ref().builder
3136 fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
3137 match fcx.debug_context.repr {
3138 FunctionDebugContext(_) => false,
3143 fn assert_type_for_node_id(cx: &CrateContext, node_id: ast::NodeId, error_span: Span) {
3144 if !cx.tcx().node_types.borrow().contains_key(&(node_id as uint)) {
3145 cx.sess().span_bug(error_span, "debuginfo: Could not find type for node id!");
3149 fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: ast::DefId)
3150 -> (DIScope, Span) {
3151 let containing_scope = namespace_for_item(cx, def_id).scope;
3152 let definition_span = if def_id.krate == ast::LOCAL_CRATE {
3153 cx.tcx().map.span(def_id.node)
3155 // For external items there is no span information
3159 (containing_scope, definition_span)
3162 // This procedure builds the *scope map* for a given function, which maps any
3163 // given ast::NodeId in the function's AST to the correct DIScope metadata instance.
3165 // This builder procedure walks the AST in execution order and keeps track of
3166 // what belongs to which scope, creating DIScope DIEs along the way, and
3167 // introducing *artificial* lexical scope descriptors where necessary. These
3168 // artificial scopes allow GDB to correctly handle name shadowing.
3169 fn populate_scope_map(cx: &CrateContext,
3171 fn_entry_block: &ast::Block,
3172 fn_metadata: DISubprogram,
3173 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3174 let def_map = &cx.tcx().def_map;
3176 struct ScopeStackEntry {
3177 scope_metadata: DIScope,
3178 ident: Option<ast::Ident>
3181 let mut scope_stack = vec!(ScopeStackEntry { scope_metadata: fn_metadata,
3184 // Push argument identifiers onto the stack so arguments integrate nicely
3185 // with variable shadowing.
3186 for arg in args.iter() {
3187 pat_util::pat_bindings(def_map, &*arg.pat, |_, _, _, path1| {
3188 scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata,
3189 ident: Some(path1.node) });
3193 // Clang creates a separate scope for function bodies, so let's do this too.
3195 fn_entry_block.span,
3198 |cx, scope_stack, scope_map| {
3199 walk_block(cx, fn_entry_block, scope_stack, scope_map);
3202 // local helper functions for walking the AST.
3203 fn with_new_scope(cx: &CrateContext,
3205 scope_stack: &mut Vec<ScopeStackEntry> ,
3206 scope_map: &mut HashMap<ast::NodeId, DIScope>,
3207 inner_walk: |&CrateContext,
3208 &mut Vec<ScopeStackEntry> ,
3209 &mut HashMap<ast::NodeId, DIScope>|) {
3210 // Create a new lexical scope and push it onto the stack
3211 let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
3212 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
3213 let parent_scope = scope_stack.last().unwrap().scope_metadata;
3215 let scope_metadata = unsafe {
3216 llvm::LLVMDIBuilderCreateLexicalBlock(
3221 loc.col.to_uint() as c_uint,
3225 scope_stack.push(ScopeStackEntry { scope_metadata: scope_metadata,
3228 inner_walk(cx, scope_stack, scope_map);
3230 // pop artificial scopes
3231 while scope_stack.last().unwrap().ident.is_some() {
3235 if scope_stack.last().unwrap().scope_metadata != scope_metadata {
3236 cx.sess().span_bug(scope_span, "debuginfo: Inconsistency in scope management.");
3242 fn walk_block(cx: &CrateContext,
3244 scope_stack: &mut Vec<ScopeStackEntry> ,
3245 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3246 scope_map.insert(block.id, scope_stack.last().unwrap().scope_metadata);
3248 // The interesting things here are statements and the concluding expression.
3249 for statement in block.stmts.iter() {
3250 scope_map.insert(ast_util::stmt_id(&**statement),
3251 scope_stack.last().unwrap().scope_metadata);
3253 match statement.node {
3254 ast::StmtDecl(ref decl, _) =>
3255 walk_decl(cx, &**decl, scope_stack, scope_map),
3256 ast::StmtExpr(ref exp, _) |
3257 ast::StmtSemi(ref exp, _) =>
3258 walk_expr(cx, &**exp, scope_stack, scope_map),
3259 ast::StmtMac(..) => () // Ignore macros (which should be expanded anyway).
3263 for exp in block.expr.iter() {
3264 walk_expr(cx, &**exp, scope_stack, scope_map);
3268 fn walk_decl(cx: &CrateContext,
3270 scope_stack: &mut Vec<ScopeStackEntry> ,
3271 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3273 codemap::Spanned { node: ast::DeclLocal(ref local), .. } => {
3274 scope_map.insert(local.id, scope_stack.last().unwrap().scope_metadata);
3276 walk_pattern(cx, &*local.pat, scope_stack, scope_map);
3278 for exp in local.init.iter() {
3279 walk_expr(cx, &**exp, scope_stack, scope_map);
3286 fn walk_pattern(cx: &CrateContext,
3288 scope_stack: &mut Vec<ScopeStackEntry> ,
3289 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3291 let def_map = &cx.tcx().def_map;
3293 // Unfortunately, we cannot just use pat_util::pat_bindings() or
3294 // ast_util::walk_pat() here because we have to visit *all* nodes in
3295 // order to put them into the scope map. The above functions don't do that.
3297 ast::PatIdent(_, ref path1, ref sub_pat_opt) => {
3299 // Check if this is a binding. If so we need to put it on the
3300 // scope stack and maybe introduce an artificial scope
3301 if pat_util::pat_is_binding(def_map, &*pat) {
3303 let ident = path1.node;
3305 // LLVM does not properly generate 'DW_AT_start_scope' fields
3306 // for variable DIEs. For this reason we have to introduce
3307 // an artificial scope at bindings whenever a variable with
3308 // the same name is declared in *any* parent scope.
3310 // Otherwise the following error occurs:
3314 // do_something(); // 'gdb print x' correctly prints 10
3317 // do_something(); // 'gdb print x' prints 0, because it
3318 // // already reads the uninitialized 'x'
3319 // // from the next line...
3321 // do_something(); // 'gdb print x' correctly prints 100
3324 // Is there already a binding with that name?
3325 // N.B.: this comparison must be UNhygienic... because
3326 // gdb knows nothing about the context, so any two
3327 // variables with the same name will cause the problem.
3328 let need_new_scope = scope_stack
3330 .any(|entry| entry.ident.iter().any(|i| i.name == ident.name));
3333 // Create a new lexical scope and push it onto the stack
3334 let loc = cx.sess().codemap().lookup_char_pos(pat.span.lo);
3335 let file_metadata = file_metadata(cx,
3339 let parent_scope = scope_stack.last().unwrap().scope_metadata;
3341 let scope_metadata = unsafe {
3342 llvm::LLVMDIBuilderCreateLexicalBlock(
3347 loc.col.to_uint() as c_uint,
3351 scope_stack.push(ScopeStackEntry {
3352 scope_metadata: scope_metadata,
3357 // Push a new entry anyway so the name can be found
3358 let prev_metadata = scope_stack.last().unwrap().scope_metadata;
3359 scope_stack.push(ScopeStackEntry {
3360 scope_metadata: prev_metadata,
3366 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3368 for sub_pat in sub_pat_opt.iter() {
3369 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3373 ast::PatWild(_) => {
3374 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3377 ast::PatEnum(_, ref sub_pats_opt) => {
3378 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3380 for sub_pats in sub_pats_opt.iter() {
3381 for p in sub_pats.iter() {
3382 walk_pattern(cx, &**p, scope_stack, scope_map);
3387 ast::PatStruct(_, ref field_pats, _) => {
3388 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3390 for &ast::FieldPat { pat: ref sub_pat, .. } in field_pats.iter() {
3391 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3395 ast::PatTup(ref sub_pats) => {
3396 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3398 for sub_pat in sub_pats.iter() {
3399 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3403 ast::PatBox(ref sub_pat) | ast::PatRegion(ref sub_pat) => {
3404 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3405 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3408 ast::PatLit(ref exp) => {
3409 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3410 walk_expr(cx, &**exp, scope_stack, scope_map);
3413 ast::PatRange(ref exp1, ref exp2) => {
3414 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3415 walk_expr(cx, &**exp1, scope_stack, scope_map);
3416 walk_expr(cx, &**exp2, scope_stack, scope_map);
3419 ast::PatVec(ref front_sub_pats, ref middle_sub_pats, ref back_sub_pats) => {
3420 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3422 for sub_pat in front_sub_pats.iter() {
3423 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3426 for sub_pat in middle_sub_pats.iter() {
3427 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3430 for sub_pat in back_sub_pats.iter() {
3431 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3436 cx.sess().span_bug(pat.span, "debuginfo::populate_scope_map() - \
3437 Found unexpanded macro.");
3442 fn walk_expr(cx: &CrateContext,
3444 scope_stack: &mut Vec<ScopeStackEntry> ,
3445 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3447 scope_map.insert(exp.id, scope_stack.last().unwrap().scope_metadata);
3453 ast::ExprPath(_) => {}
3455 ast::ExprCast(ref sub_exp, _) |
3456 ast::ExprAddrOf(_, ref sub_exp) |
3457 ast::ExprField(ref sub_exp, _, _) |
3458 ast::ExprTupField(ref sub_exp, _, _) |
3459 ast::ExprParen(ref sub_exp) =>
3460 walk_expr(cx, &**sub_exp, scope_stack, scope_map),
3462 ast::ExprBox(ref place, ref sub_expr) => {
3463 walk_expr(cx, &**place, scope_stack, scope_map);
3464 walk_expr(cx, &**sub_expr, scope_stack, scope_map);
3467 ast::ExprRet(ref exp_opt) => match *exp_opt {
3468 Some(ref sub_exp) => walk_expr(cx, &**sub_exp, scope_stack, scope_map),
3472 ast::ExprUnary(_, ref sub_exp) => {
3473 walk_expr(cx, &**sub_exp, scope_stack, scope_map);
3476 ast::ExprAssignOp(_, ref lhs, ref rhs) |
3477 ast::ExprIndex(ref lhs, ref rhs) |
3478 ast::ExprBinary(_, ref lhs, ref rhs) => {
3479 walk_expr(cx, &**lhs, scope_stack, scope_map);
3480 walk_expr(cx, &**rhs, scope_stack, scope_map);
3483 ast::ExprVec(ref init_expressions) |
3484 ast::ExprTup(ref init_expressions) => {
3485 for ie in init_expressions.iter() {
3486 walk_expr(cx, &**ie, scope_stack, scope_map);
3490 ast::ExprAssign(ref sub_exp1, ref sub_exp2) |
3491 ast::ExprRepeat(ref sub_exp1, ref sub_exp2) => {
3492 walk_expr(cx, &**sub_exp1, scope_stack, scope_map);
3493 walk_expr(cx, &**sub_exp2, scope_stack, scope_map);
3496 ast::ExprIf(ref cond_exp, ref then_block, ref opt_else_exp) => {
3497 walk_expr(cx, &**cond_exp, scope_stack, scope_map);
3503 |cx, scope_stack, scope_map| {
3504 walk_block(cx, &**then_block, scope_stack, scope_map);
3507 match *opt_else_exp {
3508 Some(ref else_exp) =>
3509 walk_expr(cx, &**else_exp, scope_stack, scope_map),
3514 ast::ExprWhile(ref cond_exp, ref loop_body, _) => {
3515 walk_expr(cx, &**cond_exp, scope_stack, scope_map);
3521 |cx, scope_stack, scope_map| {
3522 walk_block(cx, &**loop_body, scope_stack, scope_map);
3526 ast::ExprForLoop(ref pattern, ref head, ref body, _) => {
3527 walk_expr(cx, &**head, scope_stack, scope_map);
3533 |cx, scope_stack, scope_map| {
3534 scope_map.insert(exp.id,
3542 walk_block(cx, &**body, scope_stack, scope_map);
3546 ast::ExprMac(_) => {
3547 cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
3548 Found unexpanded macro.");
3551 ast::ExprLoop(ref block, _) |
3552 ast::ExprBlock(ref block) => {
3557 |cx, scope_stack, scope_map| {
3558 walk_block(cx, &**block, scope_stack, scope_map);
3562 ast::ExprFnBlock(_, ref decl, ref block) |
3563 ast::ExprProc(ref decl, ref block) |
3564 ast::ExprUnboxedFn(_, _, ref decl, ref block) => {
3569 |cx, scope_stack, scope_map| {
3570 for &ast::Arg { pat: ref pattern, .. } in decl.inputs.iter() {
3571 walk_pattern(cx, &**pattern, scope_stack, scope_map);
3574 walk_block(cx, &**block, scope_stack, scope_map);
3578 ast::ExprCall(ref fn_exp, ref args) => {
3579 walk_expr(cx, &**fn_exp, scope_stack, scope_map);
3581 for arg_exp in args.iter() {
3582 walk_expr(cx, &**arg_exp, scope_stack, scope_map);
3586 ast::ExprMethodCall(_, _, ref args) => {
3587 for arg_exp in args.iter() {
3588 walk_expr(cx, &**arg_exp, scope_stack, scope_map);
3592 ast::ExprMatch(ref discriminant_exp, ref arms) => {
3593 walk_expr(cx, &**discriminant_exp, scope_stack, scope_map);
3595 // For each arm we have to first walk the pattern as these might
3596 // introduce new artificial scopes. It should be sufficient to
3597 // walk only one pattern per arm, as they all must contain the
3598 // same binding names.
3600 for arm_ref in arms.iter() {
3601 let arm_span = arm_ref.pats.get(0).span;
3607 |cx, scope_stack, scope_map| {
3608 for pat in arm_ref.pats.iter() {
3609 walk_pattern(cx, &**pat, scope_stack, scope_map);
3612 for guard_exp in arm_ref.guard.iter() {
3613 walk_expr(cx, &**guard_exp, scope_stack, scope_map)
3616 walk_expr(cx, &*arm_ref.body, scope_stack, scope_map);
3621 ast::ExprStruct(_, ref fields, ref base_exp) => {
3622 for &ast::Field { expr: ref exp, .. } in fields.iter() {
3623 walk_expr(cx, &**exp, scope_stack, scope_map);
3627 Some(ref exp) => walk_expr(cx, &**exp, scope_stack, scope_map),
3632 ast::ExprInlineAsm(ast::InlineAsm { inputs: ref inputs,
3633 outputs: ref outputs,
3635 // inputs, outputs: ~[(String, Gc<expr>)]
3636 for &(_, ref exp) in inputs.iter() {
3637 walk_expr(cx, &**exp, scope_stack, scope_map);
3640 for &(_, ref exp, _) in outputs.iter() {
3641 walk_expr(cx, &**exp, scope_stack, scope_map);
3649 //=-----------------------------------------------------------------------------
3650 // Type Names for Debug Info
3651 //=-----------------------------------------------------------------------------
3653 // Compute the name of the type as it should be stored in debuginfo. Does not do
3654 // any caching, i.e. calling the function twice with the same type will also do
3655 // the work twice. The `qualified` parameter only affects the first level of the
3656 // type name, further levels (i.e. type parameters) are always fully qualified.
3657 fn compute_debuginfo_type_name(cx: &CrateContext,
3661 let mut result = String::with_capacity(64);
3662 push_debuginfo_type_name(cx, t, qualified, &mut result);
3666 // Pushes the name of the type as it should be stored in debuginfo on the
3667 // `output` String. See also compute_debuginfo_type_name().
3668 fn push_debuginfo_type_name(cx: &CrateContext,
3671 output:&mut String) {
3672 match ty::get(t).sty {
3673 ty::ty_nil => output.push_str("()"),
3674 ty::ty_bot => output.push_str("!"),
3675 ty::ty_bool => output.push_str("bool"),
3676 ty::ty_char => output.push_str("char"),
3677 ty::ty_str => output.push_str("str"),
3678 ty::ty_int(ast::TyI) => output.push_str("int"),
3679 ty::ty_int(ast::TyI8) => output.push_str("i8"),
3680 ty::ty_int(ast::TyI16) => output.push_str("i16"),
3681 ty::ty_int(ast::TyI32) => output.push_str("i32"),
3682 ty::ty_int(ast::TyI64) => output.push_str("i64"),
3683 ty::ty_uint(ast::TyU) => output.push_str("uint"),
3684 ty::ty_uint(ast::TyU8) => output.push_str("u8"),
3685 ty::ty_uint(ast::TyU16) => output.push_str("u16"),
3686 ty::ty_uint(ast::TyU32) => output.push_str("u32"),
3687 ty::ty_uint(ast::TyU64) => output.push_str("u64"),
3688 ty::ty_float(ast::TyF32) => output.push_str("f32"),
3689 ty::ty_float(ast::TyF64) => output.push_str("f64"),
3690 ty::ty_struct(def_id, ref substs) |
3691 ty::ty_enum(def_id, ref substs) => {
3692 push_item_name(cx, def_id, qualified, output);
3693 push_type_params(cx, substs, output);
3695 ty::ty_tup(ref component_types) => {
3696 output.push_char('(');
3697 for &component_type in component_types.iter() {
3698 push_debuginfo_type_name(cx, component_type, true, output);
3699 output.push_str(", ");
3703 output.push_char(')');
3705 ty::ty_uniq(inner_type) => {
3706 output.push_str("Box<");
3707 push_debuginfo_type_name(cx, inner_type, true, output);
3708 output.push_char('>');
3710 ty::ty_box(inner_type) => {
3711 output.push_char('@');
3712 push_debuginfo_type_name(cx, inner_type, true, output);
3714 ty::ty_ptr(ty::mt { ty: inner_type, mutbl } ) => {
3715 output.push_char('*');
3717 ast::MutImmutable => output.push_str("const "),
3718 ast::MutMutable => output.push_str("mut "),
3721 push_debuginfo_type_name(cx, inner_type, true, output);
3723 ty::ty_rptr(_, ty::mt { ty: inner_type, mutbl }) => {
3724 output.push_char('&');
3725 if mutbl == ast::MutMutable {
3726 output.push_str("mut ");
3729 push_debuginfo_type_name(cx, inner_type, true, output);
3731 ty::ty_vec(inner_type, optional_length) => {
3732 output.push_char('[');
3733 push_debuginfo_type_name(cx, inner_type, true, output);
3735 match optional_length {
3737 output.push_str(format!(", ..{}", len).as_slice());
3739 None => { /* nothing to do */ }
3742 output.push_char(']');
3744 ty::ty_trait(ref trait_data) => {
3745 push_item_name(cx, trait_data.def_id, false, output);
3746 push_type_params(cx, &trait_data.substs, output);
3748 ty::ty_bare_fn(ty::BareFnTy{ fn_style, abi, ref sig } ) => {
3749 if fn_style == ast::UnsafeFn {
3750 output.push_str("unsafe ");
3753 if abi != ::syntax::abi::Rust {
3754 output.push_str("extern \"");
3755 output.push_str(abi.name());
3756 output.push_str("\" ");
3759 output.push_str("fn(");
3761 if sig.inputs.len() > 0 {
3762 for ¶meter_type in sig.inputs.iter() {
3763 push_debuginfo_type_name(cx, parameter_type, true, output);
3764 output.push_str(", ");
3771 if sig.inputs.len() > 0 {
3772 output.push_str(", ...");
3774 output.push_str("...");
3778 output.push_char(')');
3780 if !ty::type_is_nil(sig.output) {
3781 output.push_str(" -> ");
3782 push_debuginfo_type_name(cx, sig.output, true, output);
3785 ty::ty_closure(box ty::ClosureTy { fn_style,
3789 .. // omitting bounds ...
3791 if fn_style == ast::UnsafeFn {
3792 output.push_str("unsafe ");
3795 if onceness == ast::Once {
3796 output.push_str("once ");
3799 let param_list_closing_char;
3801 ty::UniqTraitStore => {
3802 output.push_str("proc(");
3803 param_list_closing_char = ')';
3805 ty::RegionTraitStore(_, ast::MutMutable) => {
3806 output.push_str("&mut|");
3807 param_list_closing_char = '|';
3809 ty::RegionTraitStore(_, ast::MutImmutable) => {
3810 output.push_str("&|");
3811 param_list_closing_char = '|';
3815 if sig.inputs.len() > 0 {
3816 for ¶meter_type in sig.inputs.iter() {
3817 push_debuginfo_type_name(cx, parameter_type, true, output);
3818 output.push_str(", ");
3825 if sig.inputs.len() > 0 {
3826 output.push_str(", ...");
3828 output.push_str("...");
3832 output.push_char(param_list_closing_char);
3834 if !ty::type_is_nil(sig.output) {
3835 output.push_str(" -> ");
3836 push_debuginfo_type_name(cx, sig.output, true, output);
3839 ty::ty_unboxed_closure(..) => {
3840 output.push_str("closure");
3845 ty::ty_param(_) => {
3846 cx.sess().bug(format!("debuginfo: Trying to create type name for \
3847 unexpected type: {}", ppaux::ty_to_string(cx.tcx(), t)).as_slice());
3851 fn push_item_name(cx: &CrateContext,
3854 output: &mut String) {
3855 ty::with_path(cx.tcx(), def_id, |mut path| {
3857 if def_id.krate == ast::LOCAL_CRATE {
3858 output.push_str(crate_root_namespace(cx));
3859 output.push_str("::");
3862 let mut path_element_count = 0u;
3863 for path_element in path {
3864 let name = token::get_name(path_element.name());
3865 output.push_str(name.get());
3866 output.push_str("::");
3867 path_element_count += 1;
3870 if path_element_count == 0 {
3871 cx.sess().bug("debuginfo: Encountered empty item path!");
3877 let name = token::get_name(path.last()
3878 .expect("debuginfo: Empty item path?")
3880 output.push_str(name.get());
3885 // Pushes the type parameters in the given `Substs` to the output string.
3886 // This ignores region parameters, since they can't reliably be
3887 // reconstructed for items from non-local crates. For local crates, this
3888 // would be possible but with inlining and LTO we have to use the least
3889 // common denominator - otherwise we would run into conflicts.
3890 fn push_type_params(cx: &CrateContext,
3891 substs: &subst::Substs,
3892 output: &mut String) {
3893 if substs.types.is_empty() {
3897 output.push_char('<');
3899 for &type_parameter in substs.types.iter() {
3900 push_debuginfo_type_name(cx, type_parameter, true, output);
3901 output.push_str(", ");
3907 output.push_char('>');
3912 //=-----------------------------------------------------------------------------
3913 // Namespace Handling
3914 //=-----------------------------------------------------------------------------
3916 struct NamespaceTreeNode {
3919 parent: Option<Weak<NamespaceTreeNode>>,
3922 impl NamespaceTreeNode {
3923 fn mangled_name_of_contained_item(&self, item_name: &str) -> String {
3924 fn fill_nested(node: &NamespaceTreeNode, output: &mut String) {
3926 Some(ref parent) => fill_nested(&*parent.upgrade().unwrap(), output),
3929 let string = token::get_name(node.name);
3930 output.push_str(format!("{}", string.get().len()).as_slice());
3931 output.push_str(string.get());
3934 let mut name = String::from_str("_ZN");
3935 fill_nested(self, &mut name);
3936 name.push_str(format!("{}", item_name.len()).as_slice());
3937 name.push_str(item_name);
3938 name.push_char('E');
3943 fn crate_root_namespace<'a>(cx: &'a CrateContext) -> &'a str {
3944 cx.link_meta().crate_name.as_slice()
3947 fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTreeNode> {
3948 ty::with_path(cx.tcx(), def_id, |path| {
3949 // prepend crate name if not already present
3950 let krate = if def_id.krate == ast::LOCAL_CRATE {
3951 let crate_namespace_ident = token::str_to_ident(crate_root_namespace(cx));
3952 Some(ast_map::PathMod(crate_namespace_ident.name))
3956 let mut path = krate.move_iter().chain(path).peekable();
3958 let mut current_key = Vec::new();
3959 let mut parent_node: Option<Rc<NamespaceTreeNode>> = None;
3961 // Create/Lookup namespace for each element of the path.
3963 // Emulate a for loop so we can use peek below.
3964 let path_element = match path.next() {
3968 // Ignore the name of the item (the last path element).
3969 if path.peek().is_none() {
3973 let name = path_element.name();
3974 current_key.push(name);
3976 let existing_node = debug_context(cx).namespace_map.borrow()
3977 .find_copy(¤t_key);
3978 let current_node = match existing_node {
3979 Some(existing_node) => existing_node,
3981 // create and insert
3982 let parent_scope = match parent_node {
3983 Some(ref node) => node.scope,
3984 None => ptr::mut_null()
3986 let namespace_name = token::get_name(name);
3987 let scope = namespace_name.get().with_c_str(|namespace_name| {
3989 llvm::LLVMDIBuilderCreateNameSpace(
3993 // cannot reconstruct file ...
3995 // ... or line information, but that's not so important.
4000 let node = Rc::new(NamespaceTreeNode {
4003 parent: parent_node.map(|parent| parent.downgrade()),
4006 debug_context(cx).namespace_map.borrow_mut()
4007 .insert(current_key.clone(), node.clone());
4013 parent_node = Some(current_node);
4019 cx.sess().bug(format!("debuginfo::namespace_for_item(): \
4020 path too short for {:?}",
4021 def_id).as_slice());