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;
212 use std::rc::{Rc, Weak};
213 use syntax::util::interner::Interner;
214 use syntax::codemap::{Span, Pos};
215 use syntax::{abi, ast, codemap, ast_util, ast_map};
216 use syntax::ast_util::PostExpansionMethod;
217 use syntax::parse::token;
218 use syntax::parse::token::special_idents;
220 static DW_LANG_RUST: c_uint = 0x9000;
222 static DW_TAG_auto_variable: c_uint = 0x100;
223 static DW_TAG_arg_variable: c_uint = 0x101;
225 static DW_ATE_boolean: c_uint = 0x02;
226 static DW_ATE_float: c_uint = 0x04;
227 static DW_ATE_signed: c_uint = 0x05;
228 static DW_ATE_unsigned: c_uint = 0x07;
229 static DW_ATE_unsigned_char: c_uint = 0x08;
231 static UNKNOWN_LINE_NUMBER: c_uint = 0;
232 static UNKNOWN_COLUMN_NUMBER: c_uint = 0;
234 // ptr::null() doesn't work :(
235 static UNKNOWN_FILE_METADATA: DIFile = (0 as DIFile);
236 static UNKNOWN_SCOPE_METADATA: DIScope = (0 as DIScope);
238 static FLAGS_NONE: c_uint = 0;
239 static FLAGS_ARTIFICAL: c_uint = llvm::debuginfo::FlagArtificial as c_uint;
241 //=-----------------------------------------------------------------------------
242 // Public Interface of debuginfo module
243 //=-----------------------------------------------------------------------------
245 #[deriving(Copy, Show, Hash, Eq, PartialEq, Clone)]
246 struct UniqueTypeId(ast::Name);
248 // The TypeMap is where the CrateDebugContext holds the type metadata nodes
249 // created so far. The metadata nodes are indexed by UniqueTypeId, and, for
250 // faster lookup, also by ty::t. The TypeMap is responsible for creating
253 // The UniqueTypeIds created so far
254 unique_id_interner: Interner<Rc<String>>,
255 // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
256 unique_id_to_metadata: HashMap<UniqueTypeId, DIType>,
257 // A map from ty::type_id() to debuginfo metadata. This is a N:1 mapping.
258 type_to_metadata: HashMap<uint, DIType>,
259 // A map from ty::type_id() to UniqueTypeId. This is a N:1 mapping.
260 type_to_unique_id: HashMap<uint, UniqueTypeId>
265 fn new() -> TypeMap {
267 unique_id_interner: Interner::new(),
268 type_to_metadata: HashMap::new(),
269 unique_id_to_metadata: HashMap::new(),
270 type_to_unique_id: HashMap::new(),
274 // Adds a ty::t to metadata mapping to the TypeMap. The method will fail if
275 // the mapping already exists.
276 fn register_type_with_metadata(&mut self,
280 if !self.type_to_metadata.insert(ty::type_id(type_), metadata) {
281 cx.sess().bug(format!("Type metadata for ty::t '{}' is already in the TypeMap!",
282 ppaux::ty_to_string(cx.tcx(), type_)).as_slice());
286 // Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
287 // fail if the mapping already exists.
288 fn register_unique_id_with_metadata(&mut self,
290 unique_type_id: UniqueTypeId,
292 if !self.unique_id_to_metadata.insert(unique_type_id, metadata) {
293 let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id);
294 cx.sess().bug(format!("Type metadata for unique id '{}' is already in the TypeMap!",
295 unique_type_id_str.as_slice()).as_slice());
299 fn find_metadata_for_type(&self, type_: ty::t) -> Option<DIType> {
300 self.type_to_metadata.find_copy(&ty::type_id(type_))
303 fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<DIType> {
304 self.unique_id_to_metadata.find_copy(&unique_type_id)
307 // Get the string representation of a UniqueTypeId. This method will fail if
308 // the id is unknown.
309 fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> Rc<String> {
310 let UniqueTypeId(interner_key) = unique_type_id;
311 self.unique_id_interner.get(interner_key)
314 // Get the UniqueTypeId for the given type. If the UniqueTypeId for the given
315 // type has been requested before, this is just a table lookup. Otherwise an
316 // ID will be generated and stored for later lookup.
317 fn get_unique_type_id_of_type(&mut self, cx: &CrateContext, type_: ty::t) -> UniqueTypeId {
319 // basic type -> {:name of the type:}
320 // tuple -> {tuple_(:param-uid:)*}
321 // struct -> {struct_:svh: / :node-id:_<(:param-uid:),*> }
322 // enum -> {enum_:svh: / :node-id:_<(:param-uid:),*> }
323 // enum variant -> {variant_:variant-name:_:enum-uid:}
324 // reference (&) -> {& :pointee-uid:}
325 // mut reference (&mut) -> {&mut :pointee-uid:}
326 // ptr (*) -> {* :pointee-uid:}
327 // mut ptr (*mut) -> {*mut :pointee-uid:}
328 // unique ptr (~) -> {~ :pointee-uid:}
329 // @-ptr (@) -> {@ :pointee-uid:}
330 // sized vec ([T, ..x]) -> {[:size:] :element-uid:}
331 // unsized vec ([T]) -> {[] :element-uid:}
332 // trait (T) -> {trait_:svh: / :node-id:_<(:param-uid:),*> }
333 // closure -> {<unsafe_> <once_> :store-sigil: |(:param-uid:),* <,_...>| -> \
334 // :return-type-uid: : (:bounds:)*}
335 // function -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \
336 // :return-type-uid:}
337 // unique vec box (~[]) -> {HEAP_VEC_BOX<:pointee-uid:>}
338 // gc box -> {GC_BOX<:pointee-uid:>}
340 match self.type_to_unique_id.find_copy(&ty::type_id(type_)) {
341 Some(unique_type_id) => return unique_type_id,
342 None => { /* generate one */}
345 let mut unique_type_id = String::with_capacity(256);
346 unique_type_id.push_char('{');
348 match ty::get(type_).sty {
357 push_debuginfo_type_name(cx, type_, false, &mut unique_type_id);
359 ty::ty_enum(def_id, ref substs) => {
360 unique_type_id.push_str("enum ");
361 from_def_id_and_substs(self, cx, def_id, substs, &mut unique_type_id);
363 ty::ty_struct(def_id, ref substs) => {
364 unique_type_id.push_str("struct ");
365 from_def_id_and_substs(self, cx, def_id, substs, &mut unique_type_id);
367 ty::ty_tup(ref component_types) => {
368 unique_type_id.push_str("tuple ");
369 for &component_type in component_types.iter() {
370 let component_type_id =
371 self.get_unique_type_id_of_type(cx, component_type);
372 let component_type_id =
373 self.get_unique_type_id_as_string(component_type_id);
374 unique_type_id.push_str(component_type_id.as_slice());
377 ty::ty_box(inner_type) => {
378 unique_type_id.push_char('@');
379 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
380 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
381 unique_type_id.push_str(inner_type_id.as_slice());
383 ty::ty_uniq(inner_type) => {
384 unique_type_id.push_char('~');
385 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
386 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
387 unique_type_id.push_str(inner_type_id.as_slice());
389 ty::ty_ptr(ty::mt { ty: inner_type, mutbl } ) => {
390 unique_type_id.push_char('*');
391 if mutbl == ast::MutMutable {
392 unique_type_id.push_str("mut");
395 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
396 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
397 unique_type_id.push_str(inner_type_id.as_slice());
399 ty::ty_rptr(_, ty::mt { ty: inner_type, mutbl }) => {
400 unique_type_id.push_char('&');
401 if mutbl == ast::MutMutable {
402 unique_type_id.push_str("mut");
405 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
406 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
407 unique_type_id.push_str(inner_type_id.as_slice());
409 ty::ty_vec(inner_type, optional_length) => {
410 match optional_length {
412 unique_type_id.push_str(format!("[{}]", len).as_slice());
415 unique_type_id.push_str("[]");
419 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
420 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
421 unique_type_id.push_str(inner_type_id.as_slice());
423 ty::ty_trait(ref trait_data) => {
424 unique_type_id.push_str("trait ");
426 from_def_id_and_substs(self,
430 &mut unique_type_id);
432 ty::ty_bare_fn(ty::BareFnTy{ fn_style, abi, ref sig } ) => {
433 if fn_style == ast::UnsafeFn {
434 unique_type_id.push_str("unsafe ");
437 unique_type_id.push_str(abi.name());
439 unique_type_id.push_str(" fn(");
441 for ¶meter_type in sig.inputs.iter() {
442 let parameter_type_id =
443 self.get_unique_type_id_of_type(cx, parameter_type);
444 let parameter_type_id =
445 self.get_unique_type_id_as_string(parameter_type_id);
446 unique_type_id.push_str(parameter_type_id.as_slice());
447 unique_type_id.push_char(',');
451 unique_type_id.push_str("...");
454 unique_type_id.push_str(")->");
455 let return_type_id = self.get_unique_type_id_of_type(cx, sig.output);
456 let return_type_id = self.get_unique_type_id_as_string(return_type_id);
457 unique_type_id.push_str(return_type_id.as_slice());
459 ty::ty_closure(box ty::ClosureTy { fn_style,
465 if fn_style == ast::UnsafeFn {
466 unique_type_id.push_str("unsafe ");
469 if onceness == ast::Once {
470 unique_type_id.push_str("once ");
474 ty::UniqTraitStore => unique_type_id.push_str("~|"),
475 ty::RegionTraitStore(_, ast::MutMutable) => {
476 unique_type_id.push_str("&mut|")
478 ty::RegionTraitStore(_, ast::MutImmutable) => {
479 unique_type_id.push_str("&|")
483 for ¶meter_type in sig.inputs.iter() {
484 let parameter_type_id =
485 self.get_unique_type_id_of_type(cx, parameter_type);
486 let parameter_type_id =
487 self.get_unique_type_id_as_string(parameter_type_id);
488 unique_type_id.push_str(parameter_type_id.as_slice());
489 unique_type_id.push_char(',');
493 unique_type_id.push_str("...");
496 unique_type_id.push_str("|->");
498 let return_type_id = self.get_unique_type_id_of_type(cx, sig.output);
499 let return_type_id = self.get_unique_type_id_as_string(return_type_id);
500 unique_type_id.push_str(return_type_id.as_slice());
502 unique_type_id.push_char(':');
504 for bound in bounds.builtin_bounds.iter() {
506 ty::BoundSend => unique_type_id.push_str("Send"),
507 ty::BoundSized => unique_type_id.push_str("Sized"),
508 ty::BoundCopy => unique_type_id.push_str("Copy"),
509 ty::BoundSync => unique_type_id.push_str("Sync"),
511 unique_type_id.push_char('+');
515 cx.sess().bug(format!("get_unique_type_id_of_type() - unexpected type: {}, {:?}",
516 ppaux::ty_to_string(cx.tcx(), type_).as_slice(),
517 ty::get(type_).sty).as_slice())
521 unique_type_id.push_char('}');
523 // Trim to size before storing permanently
524 unique_type_id.shrink_to_fit();
526 let key = self.unique_id_interner.intern(Rc::new(unique_type_id));
527 self.type_to_unique_id.insert(ty::type_id(type_), UniqueTypeId(key));
529 return UniqueTypeId(key);
531 fn from_def_id_and_substs(type_map: &mut TypeMap,
534 substs: &subst::Substs,
535 output: &mut String) {
536 use std::num::ToStrRadix;
538 // First, find out the 'real' def_id of the type. Items inlined from
539 // other crates have to be mapped back to their source.
540 let source_def_id = if def_id.krate == ast::LOCAL_CRATE {
541 match cx.external_srcs().borrow().find_copy(&def_id.node) {
542 Some(source_def_id) => {
543 // The given def_id identifies the inlined copy of a
544 // type definition, let's take the source of the copy.
553 // Get the crate hash as first part of the identifier.
554 let crate_hash = if source_def_id.krate == ast::LOCAL_CRATE {
555 cx.link_meta().crate_hash.clone()
557 cx.sess().cstore.get_crate_hash(source_def_id.krate)
560 output.push_str(crate_hash.as_str());
561 output.push_str("/");
562 output.push_str(def_id.node.to_str_radix(16).as_slice());
564 // Maybe check that there is no self type here.
566 let tps = substs.types.get_slice(subst::TypeSpace);
568 output.push_char('<');
570 for &type_parameter in tps.iter() {
572 type_map.get_unique_type_id_of_type(cx, type_parameter);
574 type_map.get_unique_type_id_as_string(param_type_id);
575 output.push_str(param_type_id.as_slice());
576 output.push_char(',');
579 output.push_char('>');
584 // Get the UniqueTypeId for an enum variant. Enum variants are not really
585 // types of their own, so they need special handling. We still need a
586 // UniqueTypeId for them, since to debuginfo they *are* real types.
587 fn get_unique_type_id_of_enum_variant(&mut self,
592 let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
593 let enum_variant_type_id = format!("{}::{}",
594 self.get_unique_type_id_as_string(enum_type_id)
597 let interner_key = self.unique_id_interner.intern(Rc::new(enum_variant_type_id));
598 UniqueTypeId(interner_key)
601 fn get_unique_type_id_of_gc_box(&mut self,
605 let element_type_id = self.get_unique_type_id_of_type(cx, element_type);
606 let gc_box_type_id = format!("{{GC_BOX<{}>}}",
607 self.get_unique_type_id_as_string(element_type_id)
609 let interner_key = self.unique_id_interner.intern(Rc::new(gc_box_type_id));
610 UniqueTypeId(interner_key)
614 // Returns from the enclosing function if the type metadata with the given
615 // unique id can be found in the type map
616 macro_rules! return_if_metadata_created_in_meantime(
617 ($cx: expr, $unique_type_id: expr) => (
618 match debug_context($cx).type_map
620 .find_metadata_for_unique_id($unique_type_id) {
621 Some(metadata) => return MetadataCreationResult::new(metadata, true),
622 None => { /* proceed normally */ }
628 /// A context object for maintaining all state needed by the debuginfo module.
629 pub struct CrateDebugContext {
630 llcontext: ContextRef,
631 builder: DIBuilderRef,
632 current_debug_location: Cell<DebugLocation>,
633 created_files: RefCell<HashMap<String, DIFile>>,
634 created_enum_disr_types: RefCell<HashMap<ast::DefId, DIType>>,
636 type_map: RefCell<TypeMap>,
637 namespace_map: RefCell<HashMap<Vec<ast::Name>, Rc<NamespaceTreeNode>>>,
639 // This collection is used to assert that composite types (structs, enums,
640 // ...) have their members only set once:
641 composite_types_completed: RefCell<HashSet<DIType>>,
644 impl CrateDebugContext {
645 pub fn new(llmod: ModuleRef) -> CrateDebugContext {
646 debug!("CrateDebugContext::new");
647 let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) };
648 // DIBuilder inherits context from the module, so we'd better use the same one
649 let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
650 return CrateDebugContext {
651 llcontext: llcontext,
653 current_debug_location: Cell::new(UnknownLocation),
654 created_files: RefCell::new(HashMap::new()),
655 created_enum_disr_types: RefCell::new(HashMap::new()),
656 type_map: RefCell::new(TypeMap::new()),
657 namespace_map: RefCell::new(HashMap::new()),
658 composite_types_completed: RefCell::new(HashSet::new()),
663 pub struct FunctionDebugContext {
664 repr: FunctionDebugContextRepr,
667 enum FunctionDebugContextRepr {
668 FunctionDebugContext(Box<FunctionDebugContextData>),
670 FunctionWithoutDebugInfo,
673 impl FunctionDebugContext {
674 fn get_ref<'a>(&'a self,
677 -> &'a FunctionDebugContextData {
679 FunctionDebugContext(box ref data) => data,
680 DebugInfoDisabled => {
681 cx.sess().span_bug(span,
682 FunctionDebugContext::debuginfo_disabled_message());
684 FunctionWithoutDebugInfo => {
685 cx.sess().span_bug(span,
686 FunctionDebugContext::should_be_ignored_message());
691 fn debuginfo_disabled_message() -> &'static str {
692 "debuginfo: Error trying to access FunctionDebugContext although debug info is disabled!"
695 fn should_be_ignored_message() -> &'static str {
696 "debuginfo: Error trying to access FunctionDebugContext for function that should be \
697 ignored by debug info!"
701 struct FunctionDebugContextData {
702 scope_map: RefCell<HashMap<ast::NodeId, DIScope>>,
703 fn_metadata: DISubprogram,
704 argument_counter: Cell<uint>,
705 source_locations_enabled: Cell<bool>,
708 enum VariableAccess<'a> {
709 // The llptr given is an alloca containing the variable's value
710 DirectVariable { alloca: ValueRef },
711 // The llptr given is an alloca containing the start of some pointer chain
712 // leading to the variable's content.
713 IndirectVariable { alloca: ValueRef, address_operations: &'a [ValueRef] }
717 ArgumentVariable(uint /*index*/),
722 /// Create any deferred debug metadata nodes
723 pub fn finalize(cx: &CrateContext) {
724 if cx.dbg_cx().is_none() {
729 compile_unit_metadata(cx);
731 llvm::LLVMDIBuilderFinalize(DIB(cx));
732 llvm::LLVMDIBuilderDispose(DIB(cx));
733 // Debuginfo generation in LLVM by default uses a higher
734 // version of dwarf than OS X currently understands. We can
735 // instruct LLVM to emit an older version of dwarf, however,
736 // for OS X to understand. For more info see #11352
737 // This can be overridden using --llvm-opts -dwarf-version,N.
738 if cx.sess().targ_cfg.os == abi::OsMacos ||
739 cx.sess().targ_cfg.os == abi::OsiOS {
740 "Dwarf Version".with_c_str(
741 |s| llvm::LLVMRustAddModuleFlag(cx.llmod(), s, 2));
743 // FIXME(#13611) this is a kludge fix because the Linux bots have
744 // gdb 7.4 which doesn't understand dwarf4, we should
745 // do something more graceful here.
746 "Dwarf Version".with_c_str(
747 |s| llvm::LLVMRustAddModuleFlag(cx.llmod(), s, 3));
750 // Prevent bitcode readers from deleting the debug info.
751 "Debug Info Version".with_c_str(
752 |s| llvm::LLVMRustAddModuleFlag(cx.llmod(), s,
753 llvm::LLVMRustDebugMetadataVersion));
757 /// Creates debug information for the given global variable.
759 /// Adds the created metadata nodes directly to the crate's IR.
760 pub fn create_global_var_metadata(cx: &CrateContext,
761 node_id: ast::NodeId,
763 if cx.dbg_cx().is_none() {
767 // Don't create debuginfo for globals inlined from other crates. The other
768 // crate should already contain debuginfo for it. More importantly, the
769 // global might not even exist in un-inlined form anywhere which would lead
770 // to a linker errors.
771 if cx.external_srcs().borrow().contains_key(&node_id) {
775 let var_item = cx.tcx().map.get(node_id);
777 let (ident, span) = match var_item {
778 ast_map::NodeItem(item) => {
780 ast::ItemStatic(..) => (item.ident, item.span),
784 format!("debuginfo::\
785 create_global_var_metadata() -
786 Captured var-id refers to \
787 unexpected ast_item variant: {:?}",
788 var_item).as_slice())
792 _ => cx.sess().bug(format!("debuginfo::create_global_var_metadata() \
793 - Captured var-id refers to unexpected \
794 ast_map variant: {:?}",
795 var_item).as_slice())
798 let (file_metadata, line_number) = if span != codemap::DUMMY_SP {
799 let loc = span_start(cx, span);
800 (file_metadata(cx, loc.file.name.as_slice()), loc.line as c_uint)
802 (UNKNOWN_FILE_METADATA, UNKNOWN_LINE_NUMBER)
805 let is_local_to_unit = is_node_local_to_unit(cx, node_id);
806 let variable_type = ty::node_id_to_type(cx.tcx(), node_id);
807 let type_metadata = type_metadata(cx, variable_type, span);
808 let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
809 let var_name = token::get_ident(ident).get().to_string();
811 namespace_node.mangled_name_of_contained_item(var_name.as_slice());
812 let var_scope = namespace_node.scope;
814 var_name.as_slice().with_c_str(|var_name| {
815 linkage_name.as_slice().with_c_str(|linkage_name| {
817 llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
832 /// Creates debug information for the given local variable.
834 /// Adds the created metadata nodes directly to the crate's IR.
835 pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) {
836 if fn_should_be_ignored(bcx.fcx) {
841 let def_map = &cx.tcx().def_map;
843 pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path1| {
844 let var_ident = path1.node;
846 let datum = match bcx.fcx.lllocals.borrow().find_copy(&node_id) {
847 Some(datum) => datum,
849 bcx.sess().span_bug(span,
850 format!("no entry in lllocals table for {:?}",
851 node_id).as_slice());
855 let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
861 DirectVariable { alloca: datum.val },
867 /// Creates debug information for a variable captured in a closure.
869 /// Adds the created metadata nodes directly to the crate's IR.
870 pub fn create_captured_var_metadata(bcx: Block,
871 node_id: ast::NodeId,
872 env_data_type: ty::t,
873 env_pointer: ValueRef,
875 closure_store: ty::TraitStore,
877 if fn_should_be_ignored(bcx.fcx) {
883 let ast_item = cx.tcx().map.find(node_id);
885 let variable_ident = match ast_item {
887 cx.sess().span_bug(span, "debuginfo::create_captured_var_metadata: node not found");
889 Some(ast_map::NodeLocal(pat)) | Some(ast_map::NodeArg(pat)) => {
891 ast::PatIdent(_, ref path1, _) => {
898 "debuginfo::create_captured_var_metadata() - \
899 Captured var-id refers to unexpected \
900 ast_map variant: {:?}",
901 ast_item).as_slice());
908 format!("debuginfo::create_captured_var_metadata() - \
909 Captured var-id refers to unexpected \
910 ast_map variant: {:?}",
911 ast_item).as_slice());
915 let variable_type = node_id_type(bcx, node_id);
916 let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata;
918 let llvm_env_data_type = type_of::type_of(cx, env_data_type);
919 let byte_offset_of_var_in_env = machine::llelement_offset(cx,
923 let address_operations = unsafe {
924 [llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref()),
925 llvm::LLVMDIBuilderCreateOpPlus(Type::i64(cx).to_ref()),
926 C_i64(cx, byte_offset_of_var_in_env as i64),
927 llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref())]
930 let address_op_count = match closure_store {
931 ty::RegionTraitStore(..) => {
932 address_operations.len()
934 ty::UniqTraitStore => {
935 address_operations.len() - 1
939 let variable_access = IndirectVariable {
941 address_operations: address_operations.slice_to(address_op_count)
953 /// Creates debug information for a local variable introduced in the head of a
954 /// match-statement arm.
956 /// Adds the created metadata nodes directly to the crate's IR.
957 pub fn create_match_binding_metadata(bcx: Block,
958 variable_ident: ast::Ident,
959 binding: BindingInfo) {
960 if fn_should_be_ignored(bcx.fcx) {
964 let scope_metadata = scope_metadata(bcx.fcx, binding.id, binding.span);
966 [llvm::LLVMDIBuilderCreateOpDeref(bcx.ccx().int_type().to_ref())]
968 // Regardless of the actual type (`T`) we're always passed the stack slot (alloca)
969 // for the binding. For ByRef bindings that's a `T*` but for ByMove bindings we
970 // actually have `T**`. So to get the actual variable we need to dereference once
971 // more. For ByCopy we just use the stack slot we created for the binding.
972 let var_type = match binding.trmode {
973 TrByCopy(llbinding) => DirectVariable {
976 TrByMove => IndirectVariable {
977 alloca: binding.llmatch,
978 address_operations: aops
980 TrByRef => DirectVariable {
981 alloca: binding.llmatch
994 /// Creates debug information for the given function argument.
996 /// Adds the created metadata nodes directly to the crate's IR.
997 pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) {
998 if fn_should_be_ignored(bcx.fcx) {
1005 let def_map = &cx.tcx().def_map;
1006 let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata;
1008 pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path1| {
1009 let llarg = match bcx.fcx.llargs.borrow().find_copy(&node_id) {
1012 bcx.sess().span_bug(span,
1013 format!("no entry in llargs table for {:?}",
1014 node_id).as_slice());
1018 if unsafe { llvm::LLVMIsAAllocaInst(llarg.val) } == ptr::mut_null() {
1019 cx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \
1020 Referenced variable location is not an alloca!");
1023 let argument_index = {
1024 let counter = &fcx.debug_context.get_ref(cx, span).argument_counter;
1025 let argument_index = counter.get();
1026 counter.set(argument_index + 1);
1034 DirectVariable { alloca: llarg.val },
1035 ArgumentVariable(argument_index),
1040 /// Sets the current debug location at the beginning of the span.
1042 /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). The node_id
1043 /// parameter is used to reliably find the correct visibility scope for the code
1045 pub fn set_source_location(fcx: &FunctionContext,
1046 node_id: ast::NodeId,
1048 match fcx.debug_context.repr {
1049 DebugInfoDisabled => return,
1050 FunctionWithoutDebugInfo => {
1051 set_debug_location(fcx.ccx, UnknownLocation);
1054 FunctionDebugContext(box ref function_debug_context) => {
1057 debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span));
1059 if function_debug_context.source_locations_enabled.get() {
1060 let loc = span_start(cx, span);
1061 let scope = scope_metadata(fcx, node_id, span);
1063 set_debug_location(cx, DebugLocation::new(scope,
1065 loc.col.to_uint()));
1067 set_debug_location(cx, UnknownLocation);
1073 /// Clears the current debug location.
1075 /// Instructions generated hereafter won't be assigned a source location.
1076 pub fn clear_source_location(fcx: &FunctionContext) {
1077 if fn_should_be_ignored(fcx) {
1081 set_debug_location(fcx.ccx, UnknownLocation);
1084 /// Enables emitting source locations for the given functions.
1086 /// Since we don't want source locations to be emitted for the function prelude,
1087 /// they are disabled when beginning to translate a new function. This functions
1088 /// switches source location emitting on and must therefore be called before the
1089 /// first real statement/expression of the function is translated.
1090 pub fn start_emitting_source_locations(fcx: &FunctionContext) {
1091 match fcx.debug_context.repr {
1092 FunctionDebugContext(box ref data) => {
1093 data.source_locations_enabled.set(true)
1095 _ => { /* safe to ignore */ }
1099 /// Creates the function-specific debug context.
1101 /// Returns the FunctionDebugContext for the function which holds state needed
1102 /// for debug info creation. The function may also return another variant of the
1103 /// FunctionDebugContext enum which indicates why no debuginfo should be created
1104 /// for the function.
1105 pub fn create_function_debug_context(cx: &CrateContext,
1106 fn_ast_id: ast::NodeId,
1107 param_substs: ¶m_substs,
1108 llfn: ValueRef) -> FunctionDebugContext {
1109 if cx.sess().opts.debuginfo == NoDebugInfo {
1110 return FunctionDebugContext { repr: DebugInfoDisabled };
1113 // Clear the debug location so we don't assign them in the function prelude.
1114 // Do this here already, in case we do an early exit from this function.
1115 set_debug_location(cx, UnknownLocation);
1117 if fn_ast_id == -1 {
1118 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1121 let empty_generics = ast_util::empty_generics();
1123 let fnitem = cx.tcx().map.get(fn_ast_id);
1125 let (ident, fn_decl, generics, top_level_block, span, has_path) = match fnitem {
1126 ast_map::NodeItem(ref item) => {
1127 if contains_nodebug_attribute(item.attrs.as_slice()) {
1128 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1132 ast::ItemFn(fn_decl, _, _, ref generics, top_level_block) => {
1133 (item.ident, fn_decl, generics, top_level_block, item.span, true)
1136 cx.sess().span_bug(item.span,
1137 "create_function_debug_context: item bound to non-function");
1141 ast_map::NodeImplItem(ref item) => {
1143 ast::MethodImplItem(ref method) => {
1144 if contains_nodebug_attribute(method.attrs.as_slice()) {
1145 return FunctionDebugContext {
1146 repr: FunctionWithoutDebugInfo
1151 method.pe_fn_decl(),
1152 method.pe_generics(),
1159 ast_map::NodeExpr(ref expr) => {
1161 ast::ExprFnBlock(_, fn_decl, top_level_block) |
1162 ast::ExprProc(fn_decl, top_level_block) |
1163 ast::ExprUnboxedFn(_, _, fn_decl, top_level_block) => {
1164 let name = format!("fn{}", token::gensym("fn"));
1165 let name = token::str_to_ident(name.as_slice());
1167 // This is not quite right. It should actually inherit
1168 // the generics of the enclosing function.
1172 // Don't try to lookup the item path:
1175 _ => cx.sess().span_bug(expr.span,
1176 "create_function_debug_context: expected an expr_fn_block here")
1179 ast_map::NodeTraitItem(ref trait_method) => {
1180 match **trait_method {
1181 ast::ProvidedMethod(ref method) => {
1182 if contains_nodebug_attribute(method.attrs.as_slice()) {
1183 return FunctionDebugContext {
1184 repr: FunctionWithoutDebugInfo
1189 method.pe_fn_decl(),
1190 method.pe_generics(),
1197 .bug(format!("create_function_debug_context: \
1198 unexpected sort of node: {:?}",
1203 ast_map::NodeForeignItem(..) |
1204 ast_map::NodeVariant(..) |
1205 ast_map::NodeStructCtor(..) => {
1206 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1208 _ => cx.sess().bug(format!("create_function_debug_context: \
1209 unexpected sort of node: {:?}",
1213 // This can be the case for functions inlined from another crate
1214 if span == codemap::DUMMY_SP {
1215 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1218 let loc = span_start(cx, span);
1219 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
1221 let function_type_metadata = unsafe {
1222 let fn_signature = get_function_signature(cx,
1227 llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
1230 // Get_template_parameters() will append a `<...>` clause to the function
1231 // name if necessary.
1232 let mut function_name = String::from_str(token::get_ident(ident).get());
1233 let template_parameters = get_template_parameters(cx,
1237 &mut function_name);
1239 // There is no ast_map::Path for ast::ExprFnBlock-type functions. For now,
1240 // just don't put them into a namespace. In the future this could be improved
1241 // somehow (storing a path in the ast_map, or construct a path using the
1242 // enclosing function).
1243 let (linkage_name, containing_scope) = if has_path {
1244 let namespace_node = namespace_for_item(cx, ast_util::local_def(fn_ast_id));
1245 let linkage_name = namespace_node.mangled_name_of_contained_item(
1246 function_name.as_slice());
1247 let containing_scope = namespace_node.scope;
1248 (linkage_name, containing_scope)
1250 (function_name.as_slice().to_string(), file_metadata)
1253 // Clang sets this parameter to the opening brace of the function's block,
1254 // so let's do this too.
1255 let scope_line = span_start(cx, top_level_block.span).line;
1257 let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id);
1259 let fn_metadata = function_name.as_slice().with_c_str(|function_name| {
1260 linkage_name.as_slice().with_c_str(|linkage_name| {
1262 llvm::LLVMDIBuilderCreateFunction(
1269 function_type_metadata,
1272 scope_line as c_uint,
1273 FlagPrototyped as c_uint,
1274 cx.sess().opts.optimize != config::No,
1276 template_parameters,
1282 // Initialize fn debug context (including scope map and namespace map)
1283 let fn_debug_context = box FunctionDebugContextData {
1284 scope_map: RefCell::new(HashMap::new()),
1285 fn_metadata: fn_metadata,
1286 argument_counter: Cell::new(1),
1287 source_locations_enabled: Cell::new(false),
1290 let arg_pats = fn_decl.inputs.iter().map(|arg_ref| arg_ref.pat).collect::<Vec<_>>();
1291 populate_scope_map(cx,
1292 arg_pats.as_slice(),
1295 &mut *fn_debug_context.scope_map.borrow_mut());
1297 return FunctionDebugContext { repr: FunctionDebugContext(fn_debug_context) };
1299 fn get_function_signature(cx: &CrateContext,
1300 fn_ast_id: ast::NodeId,
1301 fn_decl: &ast::FnDecl,
1302 param_substs: ¶m_substs,
1303 error_span: Span) -> DIArray {
1304 if cx.sess().opts.debuginfo == LimitedDebugInfo {
1305 return create_DIArray(DIB(cx), []);
1308 let mut signature = Vec::with_capacity(fn_decl.inputs.len() + 1);
1310 // Return type -- llvm::DIBuilder wants this at index 0
1311 match fn_decl.output.node {
1313 signature.push(ptr::mut_null());
1316 assert_type_for_node_id(cx, fn_ast_id, error_span);
1318 let return_type = ty::node_id_to_type(cx.tcx(), fn_ast_id);
1319 let return_type = return_type.substp(cx.tcx(), param_substs);
1320 signature.push(type_metadata(cx, return_type, codemap::DUMMY_SP));
1325 for arg in fn_decl.inputs.iter() {
1326 assert_type_for_node_id(cx, arg.pat.id, arg.pat.span);
1327 let arg_type = ty::node_id_to_type(cx.tcx(), arg.pat.id);
1328 let arg_type = arg_type.substp(cx.tcx(), param_substs);
1329 signature.push(type_metadata(cx, arg_type, codemap::DUMMY_SP));
1332 return create_DIArray(DIB(cx), signature.as_slice());
1335 fn get_template_parameters(cx: &CrateContext,
1336 generics: &ast::Generics,
1337 param_substs: ¶m_substs,
1338 file_metadata: DIFile,
1339 name_to_append_suffix_to: &mut String)
1341 let self_type = param_substs.substs.self_ty();
1343 // Only true for static default methods:
1344 let has_self_type = self_type.is_some();
1346 if !generics.is_type_parameterized() && !has_self_type {
1347 return create_DIArray(DIB(cx), []);
1350 name_to_append_suffix_to.push_char('<');
1352 // The list to be filled with template parameters:
1353 let mut template_params: Vec<DIDescriptor> =
1354 Vec::with_capacity(generics.ty_params.len() + 1);
1358 let actual_self_type = self_type.unwrap();
1359 // Add self type name to <...> clause of function name
1360 let actual_self_type_name = compute_debuginfo_type_name(
1365 name_to_append_suffix_to.push_str(actual_self_type_name.as_slice());
1367 if generics.is_type_parameterized() {
1368 name_to_append_suffix_to.push_str(",");
1371 // Only create type information if full debuginfo is enabled
1372 if cx.sess().opts.debuginfo == FullDebugInfo {
1373 let actual_self_type_metadata = type_metadata(cx,
1377 let ident = special_idents::type_self;
1379 let param_metadata = token::get_ident(ident).get()
1380 .with_c_str(|name| {
1382 llvm::LLVMDIBuilderCreateTemplateTypeParameter(
1386 actual_self_type_metadata,
1393 template_params.push(param_metadata);
1397 // Handle other generic parameters
1398 let actual_types = param_substs.substs.types.get_slice(subst::FnSpace);
1399 for (index, &ast::TyParam{ ident: ident, .. }) in generics.ty_params.iter().enumerate() {
1400 let actual_type = actual_types[index];
1401 // Add actual type name to <...> clause of function name
1402 let actual_type_name = compute_debuginfo_type_name(cx,
1405 name_to_append_suffix_to.push_str(actual_type_name.as_slice());
1407 if index != generics.ty_params.len() - 1 {
1408 name_to_append_suffix_to.push_str(",");
1411 // Again, only create type information if full debuginfo is enabled
1412 if cx.sess().opts.debuginfo == FullDebugInfo {
1413 let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP);
1414 let param_metadata = token::get_ident(ident).get()
1415 .with_c_str(|name| {
1417 llvm::LLVMDIBuilderCreateTemplateTypeParameter(
1421 actual_type_metadata,
1427 template_params.push(param_metadata);
1431 name_to_append_suffix_to.push_char('>');
1433 return create_DIArray(DIB(cx), template_params.as_slice());
1437 //=-----------------------------------------------------------------------------
1438 // Module-Internal debug info creation functions
1439 //=-----------------------------------------------------------------------------
1441 fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
1443 // The is_local_to_unit flag indicates whether a function is local to the
1444 // current compilation unit (i.e. if it is *static* in the C-sense). The
1445 // *reachable* set should provide a good approximation of this, as it
1446 // contains everything that might leak out of the current crate (by being
1447 // externally visible or by being inlined into something externally visible).
1448 // It might better to use the `exported_items` set from `driver::CrateAnalysis`
1449 // in the future, but (atm) this set is not available in the translation pass.
1450 !cx.reachable().contains(&node_id)
1453 #[allow(non_snake_case)]
1454 fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
1456 llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
1460 fn compile_unit_metadata(cx: &CrateContext) {
1461 let work_dir = &cx.sess().working_dir;
1462 let compile_unit_name = match cx.sess().local_crate_source_file {
1463 None => fallback_path(cx),
1464 Some(ref abs_path) => {
1465 if abs_path.is_relative() {
1466 cx.sess().warn("debuginfo: Invalid path to crate's local root source file!");
1469 match abs_path.path_relative_from(work_dir) {
1470 Some(ref p) if p.is_relative() => {
1471 // prepend "./" if necessary
1473 let prefix = &[dotdot[0], ::std::path::SEP_BYTE];
1474 let mut path_bytes = Vec::from_slice(p.as_vec());
1476 if path_bytes.slice_to(2) != prefix &&
1477 path_bytes.slice_to(2) != dotdot {
1478 path_bytes.insert(0, prefix[0]);
1479 path_bytes.insert(1, prefix[1]);
1482 path_bytes.as_slice().to_c_str()
1484 _ => fallback_path(cx)
1490 debug!("compile_unit_metadata: {:?}", compile_unit_name);
1491 let producer = format!("rustc version {}",
1492 (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
1494 let compile_unit_name = compile_unit_name.as_ptr();
1495 work_dir.as_vec().with_c_str(|work_dir| {
1496 producer.with_c_str(|producer| {
1497 "".with_c_str(|flags| {
1498 "".with_c_str(|split_name| {
1500 llvm::LLVMDIBuilderCreateCompileUnit(
1501 debug_context(cx).builder,
1506 cx.sess().opts.optimize != config::No,
1516 fn fallback_path(cx: &CrateContext) -> CString {
1517 cx.link_meta().crate_name.as_slice().to_c_str()
1521 fn declare_local(bcx: Block,
1522 variable_ident: ast::Ident,
1523 variable_type: ty::t,
1524 scope_metadata: DIScope,
1525 variable_access: VariableAccess,
1526 variable_kind: VariableKind,
1528 let cx: &CrateContext = bcx.ccx();
1530 let filename = span_start(cx, span).file.name.clone();
1531 let file_metadata = file_metadata(cx, filename.as_slice());
1533 let name = token::get_ident(variable_ident);
1534 let loc = span_start(cx, span);
1535 let type_metadata = type_metadata(cx, variable_type, span);
1537 let (argument_index, dwarf_tag) = match variable_kind {
1538 ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
1540 CapturedVariable => (0, DW_TAG_auto_variable)
1543 let (var_alloca, var_metadata) = name.get().with_c_str(|name| {
1544 match variable_access {
1545 DirectVariable { alloca } => (
1548 llvm::LLVMDIBuilderCreateLocalVariable(
1556 cx.sess().opts.optimize != config::No,
1561 IndirectVariable { alloca, address_operations } => (
1564 llvm::LLVMDIBuilderCreateComplexVariable(
1572 address_operations.as_ptr(),
1573 address_operations.len() as c_uint,
1580 set_debug_location(cx, DebugLocation::new(scope_metadata,
1582 loc.col.to_uint()));
1584 let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
1590 llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
1593 match variable_kind {
1594 ArgumentVariable(_) | CapturedVariable => {
1598 .source_locations_enabled
1600 set_debug_location(cx, UnknownLocation);
1602 _ => { /* nothing to do */ }
1606 fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
1607 match debug_context(cx).created_files.borrow().find_equiv(&full_path) {
1608 Some(file_metadata) => return *file_metadata,
1612 debug!("file_metadata: {}", full_path);
1614 // FIXME (#9639): This needs to handle non-utf8 paths
1615 let work_dir = cx.sess().working_dir.as_str().unwrap();
1617 if full_path.starts_with(work_dir) {
1618 full_path.slice(work_dir.len() + 1u, full_path.len())
1624 file_name.with_c_str(|file_name| {
1625 work_dir.with_c_str(|work_dir| {
1627 llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir)
1632 let mut created_files = debug_context(cx).created_files.borrow_mut();
1633 created_files.insert(full_path.to_string(), file_metadata);
1634 return file_metadata;
1637 /// Finds the scope metadata node for the given AST node.
1638 fn scope_metadata(fcx: &FunctionContext,
1639 node_id: ast::NodeId,
1642 let scope_map = &fcx.debug_context.get_ref(fcx.ccx, span).scope_map;
1643 match scope_map.borrow().find_copy(&node_id) {
1644 Some(scope_metadata) => scope_metadata,
1646 let node = fcx.ccx.tcx().map.get(node_id);
1648 fcx.ccx.sess().span_bug(span,
1649 format!("debuginfo: Could not find scope info for node {:?}",
1655 fn basic_type_metadata(cx: &CrateContext, t: ty::t) -> DIType {
1657 debug!("basic_type_metadata: {:?}", ty::get(t));
1659 let (name, encoding) = match ty::get(t).sty {
1660 ty::ty_nil => ("()".to_string(), DW_ATE_unsigned),
1661 ty::ty_bot => ("!".to_string(), DW_ATE_unsigned),
1662 ty::ty_bool => ("bool".to_string(), DW_ATE_boolean),
1663 ty::ty_char => ("char".to_string(), DW_ATE_unsigned_char),
1664 ty::ty_int(int_ty) => match int_ty {
1665 ast::TyI => ("int".to_string(), DW_ATE_signed),
1666 ast::TyI8 => ("i8".to_string(), DW_ATE_signed),
1667 ast::TyI16 => ("i16".to_string(), DW_ATE_signed),
1668 ast::TyI32 => ("i32".to_string(), DW_ATE_signed),
1669 ast::TyI64 => ("i64".to_string(), DW_ATE_signed)
1671 ty::ty_uint(uint_ty) => match uint_ty {
1672 ast::TyU => ("uint".to_string(), DW_ATE_unsigned),
1673 ast::TyU8 => ("u8".to_string(), DW_ATE_unsigned),
1674 ast::TyU16 => ("u16".to_string(), DW_ATE_unsigned),
1675 ast::TyU32 => ("u32".to_string(), DW_ATE_unsigned),
1676 ast::TyU64 => ("u64".to_string(), DW_ATE_unsigned)
1678 ty::ty_float(float_ty) => match float_ty {
1679 ast::TyF32 => ("f32".to_string(), DW_ATE_float),
1680 ast::TyF64 => ("f64".to_string(), DW_ATE_float),
1682 _ => cx.sess().bug("debuginfo::basic_type_metadata - t is invalid type")
1685 let llvm_type = type_of::type_of(cx, t);
1686 let (size, align) = size_and_align_of(cx, llvm_type);
1687 let ty_metadata = name.with_c_str(|name| {
1689 llvm::LLVMDIBuilderCreateBasicType(
1692 bytes_to_bits(size),
1693 bytes_to_bits(align),
1701 fn pointer_type_metadata(cx: &CrateContext,
1702 pointer_type: ty::t,
1703 pointee_type_metadata: DIType)
1705 let pointer_llvm_type = type_of::type_of(cx, pointer_type);
1706 let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
1707 let name = compute_debuginfo_type_name(cx, pointer_type, false);
1708 let ptr_metadata = name.as_slice().with_c_str(|name| {
1710 llvm::LLVMDIBuilderCreatePointerType(
1712 pointee_type_metadata,
1713 bytes_to_bits(pointer_size),
1714 bytes_to_bits(pointer_align),
1718 return ptr_metadata;
1721 //=-----------------------------------------------------------------------------
1722 // Common facilities for record-like types (structs, enums, tuples)
1723 //=-----------------------------------------------------------------------------
1726 FixedMemberOffset { bytes: uint },
1727 // For ComputedMemberOffset, the offset is read from the llvm type definition
1728 ComputedMemberOffset
1731 // Description of a type member, which can either be a regular field (as in
1732 // structs or tuples) or an enum variant
1733 struct MemberDescription {
1736 type_metadata: DIType,
1737 offset: MemberOffset,
1741 // A factory for MemberDescriptions. It produces a list of member descriptions
1742 // for some record-like type. MemberDescriptionFactories are used to defer the
1743 // creation of type member descriptions in order to break cycles arising from
1744 // recursive type definitions.
1745 enum MemberDescriptionFactory {
1746 StructMDF(StructMemberDescriptionFactory),
1747 TupleMDF(TupleMemberDescriptionFactory),
1748 EnumMDF(EnumMemberDescriptionFactory),
1749 VariantMDF(VariantMemberDescriptionFactory)
1752 impl MemberDescriptionFactory {
1753 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
1755 StructMDF(ref this) => {
1756 this.create_member_descriptions(cx)
1758 TupleMDF(ref this) => {
1759 this.create_member_descriptions(cx)
1761 EnumMDF(ref this) => {
1762 this.create_member_descriptions(cx)
1764 VariantMDF(ref this) => {
1765 this.create_member_descriptions(cx)
1771 // A description of some recursive type. It can either be already finished (as
1772 // with FinalMetadata) or it is not yet finished, but contains all information
1773 // needed to generate the missing parts of the description. See the documentation
1774 // section on Recursive Types at the top of this file for more information.
1775 enum RecursiveTypeDescription {
1776 UnfinishedMetadata {
1777 unfinished_type: ty::t,
1778 unique_type_id: UniqueTypeId,
1779 metadata_stub: DICompositeType,
1781 member_description_factory: MemberDescriptionFactory,
1783 FinalMetadata(DICompositeType)
1786 fn create_and_register_recursive_type_forward_declaration(
1788 unfinished_type: ty::t,
1789 unique_type_id: UniqueTypeId,
1790 metadata_stub: DICompositeType,
1792 member_description_factory: MemberDescriptionFactory)
1793 -> RecursiveTypeDescription {
1795 // Insert the stub into the TypeMap in order to allow for recursive references
1796 let mut type_map = debug_context(cx).type_map.borrow_mut();
1797 type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata_stub);
1798 type_map.register_type_with_metadata(cx, unfinished_type, metadata_stub);
1800 UnfinishedMetadata {
1801 unfinished_type: unfinished_type,
1802 unique_type_id: unique_type_id,
1803 metadata_stub: metadata_stub,
1804 llvm_type: llvm_type,
1805 member_description_factory: member_description_factory,
1809 impl RecursiveTypeDescription {
1810 // Finishes up the description of the type in question (mostly by providing
1811 // descriptions of the fields of the given type) and returns the final type metadata.
1812 fn finalize(&self, cx: &CrateContext) -> MetadataCreationResult {
1814 FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
1815 UnfinishedMetadata {
1820 ref member_description_factory,
1823 // Make sure that we have a forward declaration of the type in
1824 // the TypeMap so that recursive references are possible. This
1825 // will always be the case if the RecursiveTypeDescription has
1826 // been properly created through the
1827 // create_and_register_recursive_type_forward_declaration() function.
1829 let type_map = debug_context(cx).type_map.borrow();
1830 if type_map.find_metadata_for_unique_id(unique_type_id).is_none() ||
1831 type_map.find_metadata_for_type(unfinished_type).is_none() {
1832 cx.sess().bug(format!("Forward declaration of potentially recursive type \
1833 '{}' was not found in TypeMap!",
1834 ppaux::ty_to_string(cx.tcx(), unfinished_type))
1839 // ... then create the member descriptions ...
1840 let member_descriptions =
1841 member_description_factory.create_member_descriptions(cx);
1843 // ... and attach them to the stub to complete it.
1844 set_members_of_composite_type(cx,
1847 member_descriptions.as_slice());
1848 return MetadataCreationResult::new(metadata_stub, true);
1855 //=-----------------------------------------------------------------------------
1857 //=-----------------------------------------------------------------------------
1859 // Creates MemberDescriptions for the fields of a struct
1860 struct StructMemberDescriptionFactory {
1861 fields: Vec<ty::field>,
1866 impl StructMemberDescriptionFactory {
1867 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
1868 if self.fields.len() == 0 {
1872 let field_size = if self.is_simd {
1873 machine::llsize_of_alloc(cx, type_of::type_of(cx, self.fields.get(0).mt.ty)) as uint
1878 self.fields.iter().enumerate().map(|(i, field)| {
1879 let name = if field.ident.name == special_idents::unnamed_field.name {
1882 token::get_ident(field.ident).get().to_string()
1885 let offset = if self.is_simd {
1886 assert!(field_size != 0xdeadbeef);
1887 FixedMemberOffset { bytes: i * field_size }
1889 ComputedMemberOffset
1894 llvm_type: type_of::type_of(cx, field.mt.ty),
1895 type_metadata: type_metadata(cx, field.mt.ty, self.span),
1904 fn prepare_struct_metadata(cx: &CrateContext,
1907 substs: &subst::Substs,
1908 unique_type_id: UniqueTypeId,
1910 -> RecursiveTypeDescription {
1911 let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
1912 let struct_llvm_type = type_of::type_of(cx, struct_type);
1914 let (containing_scope, _) = get_namespace_and_span_for_item(cx, def_id);
1916 let struct_metadata_stub = create_struct_stub(cx,
1918 struct_name.as_slice(),
1922 let fields = ty::struct_fields(cx.tcx(), def_id, substs);
1924 create_and_register_recursive_type_forward_declaration(
1928 struct_metadata_stub,
1930 StructMDF(StructMemberDescriptionFactory {
1932 is_simd: ty::type_is_simd(cx.tcx(), struct_type),
1939 //=-----------------------------------------------------------------------------
1941 //=-----------------------------------------------------------------------------
1943 // Creates MemberDescriptions for the fields of a tuple
1944 struct TupleMemberDescriptionFactory {
1945 component_types: Vec<ty::t> ,
1949 impl TupleMemberDescriptionFactory {
1950 fn create_member_descriptions(&self, cx: &CrateContext)
1951 -> Vec<MemberDescription> {
1952 self.component_types.iter().map(|&component_type| {
1954 name: "".to_string(),
1955 llvm_type: type_of::type_of(cx, component_type),
1956 type_metadata: type_metadata(cx, component_type, self.span),
1957 offset: ComputedMemberOffset,
1964 fn prepare_tuple_metadata(cx: &CrateContext,
1966 component_types: &[ty::t],
1967 unique_type_id: UniqueTypeId,
1969 -> RecursiveTypeDescription {
1970 let tuple_name = compute_debuginfo_type_name(cx, tuple_type, false);
1971 let tuple_llvm_type = type_of::type_of(cx, tuple_type);
1973 create_and_register_recursive_type_forward_declaration(
1977 create_struct_stub(cx,
1979 tuple_name.as_slice(),
1981 UNKNOWN_SCOPE_METADATA),
1983 TupleMDF(TupleMemberDescriptionFactory {
1984 component_types: Vec::from_slice(component_types),
1991 //=-----------------------------------------------------------------------------
1993 //=-----------------------------------------------------------------------------
1995 // Describes the members of an enum value: An enum is described as a union of
1996 // structs in DWARF. This MemberDescriptionFactory provides the description for
1997 // the members of this union; so for every variant of the given enum, this factory
1998 // will produce one MemberDescription (all with no name and a fixed offset of
2000 struct EnumMemberDescriptionFactory {
2002 type_rep: Rc<adt::Repr>,
2003 variants: Rc<Vec<Rc<ty::VariantInfo>>>,
2004 discriminant_type_metadata: Option<DIType>,
2005 containing_scope: DIScope,
2006 file_metadata: DIFile,
2010 impl EnumMemberDescriptionFactory {
2011 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
2012 match *self.type_rep {
2013 adt::General(_, ref struct_defs, _) => {
2014 let discriminant_info = RegularDiscriminant(self.discriminant_type_metadata
2020 .map(|(i, struct_def)| {
2021 let (variant_type_metadata,
2023 member_desc_factory) =
2024 describe_enum_variant(cx,
2027 &**self.variants.get(i),
2029 self.containing_scope,
2032 let member_descriptions = member_desc_factory
2033 .create_member_descriptions(cx);
2035 set_members_of_composite_type(cx,
2036 variant_type_metadata,
2038 member_descriptions.as_slice());
2040 name: "".to_string(),
2041 llvm_type: variant_llvm_type,
2042 type_metadata: variant_type_metadata,
2043 offset: FixedMemberOffset { bytes: 0 },
2048 adt::Univariant(ref struct_def, _) => {
2049 assert!(self.variants.len() <= 1);
2051 if self.variants.len() == 0 {
2054 let (variant_type_metadata,
2056 member_description_factory) =
2057 describe_enum_variant(cx,
2060 &**self.variants.get(0),
2062 self.containing_scope,
2065 let member_descriptions =
2066 member_description_factory.create_member_descriptions(cx);
2068 set_members_of_composite_type(cx,
2069 variant_type_metadata,
2071 member_descriptions.as_slice());
2074 name: "".to_string(),
2075 llvm_type: variant_llvm_type,
2076 type_metadata: variant_type_metadata,
2077 offset: FixedMemberOffset { bytes: 0 },
2083 adt::RawNullablePointer { nndiscr: non_null_variant_index, nnty, .. } => {
2084 // As far as debuginfo is concerned, the pointer this enum
2085 // represents is still wrapped in a struct. This is to make the
2086 // DWARF representation of enums uniform.
2088 // First create a description of the artificial wrapper struct:
2089 let non_null_variant = self.variants.get(non_null_variant_index as uint);
2090 let non_null_variant_ident = non_null_variant.name;
2091 let non_null_variant_name = token::get_ident(non_null_variant_ident);
2093 // The llvm type and metadata of the pointer
2094 let non_null_llvm_type = type_of::type_of(cx, nnty);
2095 let non_null_type_metadata = type_metadata(cx, nnty, self.span);
2097 // The type of the artificial struct wrapping the pointer
2098 let artificial_struct_llvm_type = Type::struct_(cx,
2099 &[non_null_llvm_type],
2102 // For the metadata of the wrapper struct, we need to create a
2103 // MemberDescription of the struct's single field.
2104 let sole_struct_member_description = MemberDescription {
2105 name: match non_null_variant.arg_names {
2106 Some(ref names) => token::get_ident(*names.get(0)).get().to_string(),
2107 None => "".to_string()
2109 llvm_type: non_null_llvm_type,
2110 type_metadata: non_null_type_metadata,
2111 offset: FixedMemberOffset { bytes: 0 },
2115 let unique_type_id = debug_context(cx).type_map
2117 .get_unique_type_id_of_enum_variant(
2120 non_null_variant_name.get());
2122 // Now we can create the metadata of the artificial struct
2123 let artificial_struct_metadata =
2124 composite_type_metadata(cx,
2125 artificial_struct_llvm_type,
2126 non_null_variant_name.get(),
2128 &[sole_struct_member_description],
2129 self.containing_scope,
2133 // Encode the information about the null variant in the union
2135 let null_variant_index = (1 - non_null_variant_index) as uint;
2136 let null_variant_ident = self.variants.get(null_variant_index).name;
2137 let null_variant_name = token::get_ident(null_variant_ident);
2138 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
2142 // Finally create the (singleton) list of descriptions of union
2146 name: union_member_name,
2147 llvm_type: artificial_struct_llvm_type,
2148 type_metadata: artificial_struct_metadata,
2149 offset: FixedMemberOffset { bytes: 0 },
2154 adt::StructWrappedNullablePointer { nonnull: ref struct_def,
2157 // Create a description of the non-null variant
2158 let (variant_type_metadata, variant_llvm_type, member_description_factory) =
2159 describe_enum_variant(cx,
2162 &**self.variants.get(nndiscr as uint),
2163 OptimizedDiscriminant(ptrfield),
2164 self.containing_scope,
2167 let variant_member_descriptions =
2168 member_description_factory.create_member_descriptions(cx);
2170 set_members_of_composite_type(cx,
2171 variant_type_metadata,
2173 variant_member_descriptions.as_slice());
2175 // Encode the information about the null variant in the union
2177 let null_variant_index = (1 - nndiscr) as uint;
2178 let null_variant_ident = self.variants.get(null_variant_index).name;
2179 let null_variant_name = token::get_ident(null_variant_ident);
2180 let discrfield = match ptrfield {
2181 adt::ThinPointer(field) => format!("{}", field),
2182 adt::FatPointer(field, pair) => format!("{}${}", field, pair)
2184 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
2188 // Create the (singleton) list of descriptions of union members.
2191 name: union_member_name,
2192 llvm_type: variant_llvm_type,
2193 type_metadata: variant_type_metadata,
2194 offset: FixedMemberOffset { bytes: 0 },
2199 adt::CEnum(..) => cx.sess().span_bug(self.span, "This should be unreachable.")
2204 // Creates MemberDescriptions for the fields of a single enum variant.
2205 struct VariantMemberDescriptionFactory {
2206 args: Vec<(String, ty::t)> ,
2207 discriminant_type_metadata: Option<DIType>,
2211 impl VariantMemberDescriptionFactory {
2212 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
2213 self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
2215 name: name.to_string(),
2216 llvm_type: type_of::type_of(cx, ty),
2217 type_metadata: match self.discriminant_type_metadata {
2218 Some(metadata) if i == 0 => metadata,
2219 _ => type_metadata(cx, ty, self.span)
2221 offset: ComputedMemberOffset,
2222 flags: if self.discriminant_type_metadata.is_some() && i == 0 {
2232 enum EnumDiscriminantInfo {
2233 RegularDiscriminant(DIType),
2234 OptimizedDiscriminant(adt::PointerField),
2238 // Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type
2239 // of the variant, and (3) a MemberDescriptionFactory for producing the
2240 // descriptions of the fields of the variant. This is a rudimentary version of a
2241 // full RecursiveTypeDescription.
2242 fn describe_enum_variant(cx: &CrateContext,
2244 struct_def: &adt::Struct,
2245 variant_info: &ty::VariantInfo,
2246 discriminant_info: EnumDiscriminantInfo,
2247 containing_scope: DIScope,
2249 -> (DICompositeType, Type, MemberDescriptionFactory) {
2250 let variant_llvm_type =
2251 Type::struct_(cx, struct_def.fields
2253 .map(|&t| type_of::type_of(cx, t))
2254 .collect::<Vec<_>>()
2257 // Could do some consistency checks here: size, align, field count, discr type
2259 let variant_name = token::get_ident(variant_info.name);
2260 let variant_name = variant_name.get();
2261 let unique_type_id = debug_context(cx).type_map
2263 .get_unique_type_id_of_enum_variant(
2268 let metadata_stub = create_struct_stub(cx,
2274 // Get the argument names from the enum variant info
2275 let mut arg_names: Vec<_> = match variant_info.arg_names {
2276 Some(ref names) => {
2279 token::get_ident(*ident).get().to_string().into_string()
2282 None => variant_info.args.iter().map(|_| "".to_string()).collect()
2285 // If this is not a univariant enum, there is also the (unnamed) discriminant field.
2286 match discriminant_info {
2287 RegularDiscriminant(_) => arg_names.insert(0, "".to_string()),
2288 _ => { /* do nothing */ }
2291 // Build an array of (field name, field type) pairs to be captured in the factory closure.
2292 let args: Vec<(String, ty::t)> = arg_names.iter()
2293 .zip(struct_def.fields.iter())
2294 .map(|(s, &t)| (s.to_string(), t))
2297 let member_description_factory =
2298 VariantMDF(VariantMemberDescriptionFactory {
2300 discriminant_type_metadata: match discriminant_info {
2301 RegularDiscriminant(discriminant_type_metadata) => {
2302 Some(discriminant_type_metadata)
2309 (metadata_stub, variant_llvm_type, member_description_factory)
2312 fn prepare_enum_metadata(cx: &CrateContext,
2314 enum_def_id: ast::DefId,
2315 unique_type_id: UniqueTypeId,
2317 -> RecursiveTypeDescription {
2318 let enum_name = compute_debuginfo_type_name(cx, enum_type, false);
2320 let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, enum_def_id);
2321 let loc = span_start(cx, definition_span);
2322 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2324 let variants = ty::enum_variants(cx.tcx(), enum_def_id);
2326 let enumerators_metadata: Vec<DIDescriptor> = variants
2329 token::get_ident(v.name).get().with_c_str(|name| {
2331 llvm::LLVMDIBuilderCreateEnumerator(
2334 v.disr_val as c_ulonglong)
2340 let discriminant_type_metadata = |inttype| {
2341 // We can reuse the type of the discriminant for all monomorphized
2342 // instances of an enum because it doesn't depend on any type parameters.
2343 // The def_id, uniquely identifying the enum's polytype acts as key in
2345 let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
2347 .find_copy(&enum_def_id);
2348 match cached_discriminant_type_metadata {
2349 Some(discriminant_type_metadata) => discriminant_type_metadata,
2351 let discriminant_llvm_type = adt::ll_inttype(cx, inttype);
2352 let (discriminant_size, discriminant_align) =
2353 size_and_align_of(cx, discriminant_llvm_type);
2354 let discriminant_base_type_metadata = type_metadata(cx,
2355 adt::ty_of_inttype(inttype),
2357 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
2359 let discriminant_type_metadata = discriminant_name.get().with_c_str(|name| {
2361 llvm::LLVMDIBuilderCreateEnumerationType(
2365 UNKNOWN_FILE_METADATA,
2366 UNKNOWN_LINE_NUMBER,
2367 bytes_to_bits(discriminant_size),
2368 bytes_to_bits(discriminant_align),
2369 create_DIArray(DIB(cx), enumerators_metadata.as_slice()),
2370 discriminant_base_type_metadata)
2374 debug_context(cx).created_enum_disr_types
2376 .insert(enum_def_id, discriminant_type_metadata);
2378 discriminant_type_metadata
2383 let type_rep = adt::represent_type(cx, enum_type);
2385 let discriminant_type_metadata = match *type_rep {
2386 adt::CEnum(inttype, _, _) => {
2387 return FinalMetadata(discriminant_type_metadata(inttype))
2389 adt::RawNullablePointer { .. } |
2390 adt::StructWrappedNullablePointer { .. } |
2391 adt::Univariant(..) => None,
2392 adt::General(inttype, _, _) => Some(discriminant_type_metadata(inttype)),
2395 let enum_llvm_type = type_of::type_of(cx, enum_type);
2396 let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
2398 let unique_type_id_str = debug_context(cx)
2401 .get_unique_type_id_as_string(unique_type_id);
2403 let enum_metadata = enum_name.as_slice().with_c_str(|enum_name| {
2404 unique_type_id_str.as_slice().with_c_str(|unique_type_id_str| {
2406 llvm::LLVMDIBuilderCreateUnionType(
2410 UNKNOWN_FILE_METADATA,
2411 UNKNOWN_LINE_NUMBER,
2412 bytes_to_bits(enum_type_size),
2413 bytes_to_bits(enum_type_align),
2422 return create_and_register_recursive_type_forward_declaration(
2428 EnumMDF(EnumMemberDescriptionFactory {
2429 enum_type: enum_type,
2430 type_rep: type_rep.clone(),
2432 discriminant_type_metadata: discriminant_type_metadata,
2433 containing_scope: containing_scope,
2434 file_metadata: file_metadata,
2439 fn get_enum_discriminant_name(cx: &CrateContext,
2441 -> token::InternedString {
2442 let name = if def_id.krate == ast::LOCAL_CRATE {
2443 cx.tcx().map.get_path_elem(def_id.node).name()
2445 csearch::get_item_path(cx.tcx(), def_id).last().unwrap().name()
2448 token::get_name(name)
2452 /// Creates debug information for a composite type, that is, anything that
2453 /// results in a LLVM struct.
2455 /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
2456 fn composite_type_metadata(cx: &CrateContext,
2457 composite_llvm_type: Type,
2458 composite_type_name: &str,
2459 composite_type_unique_id: UniqueTypeId,
2460 member_descriptions: &[MemberDescription],
2461 containing_scope: DIScope,
2463 // Ignore source location information as long as it
2464 // can't be reconstructed for non-local crates.
2465 _file_metadata: DIFile,
2466 _definition_span: Span)
2467 -> DICompositeType {
2468 // Create the (empty) struct metadata node ...
2469 let composite_type_metadata = create_struct_stub(cx,
2470 composite_llvm_type,
2471 composite_type_name,
2472 composite_type_unique_id,
2474 // ... and immediately create and add the member descriptions.
2475 set_members_of_composite_type(cx,
2476 composite_type_metadata,
2477 composite_llvm_type,
2478 member_descriptions);
2480 return composite_type_metadata;
2483 fn set_members_of_composite_type(cx: &CrateContext,
2484 composite_type_metadata: DICompositeType,
2485 composite_llvm_type: Type,
2486 member_descriptions: &[MemberDescription]) {
2487 // In some rare cases LLVM metadata uniquing would lead to an existing type
2488 // description being used instead of a new one created in create_struct_stub.
2489 // This would cause a hard to trace assertion in DICompositeType::SetTypeArray().
2490 // The following check makes sure that we get a better error message if this
2491 // should happen again due to some regression.
2493 let mut composite_types_completed =
2494 debug_context(cx).composite_types_completed.borrow_mut();
2495 if composite_types_completed.contains(&composite_type_metadata) {
2496 let (llvm_version_major, llvm_version_minor) = unsafe {
2497 (llvm::LLVMVersionMajor(), llvm::LLVMVersionMinor())
2500 let actual_llvm_version = llvm_version_major * 1000000 + llvm_version_minor * 1000;
2501 let min_supported_llvm_version = 3 * 1000000 + 4 * 1000;
2503 if actual_llvm_version < min_supported_llvm_version {
2504 cx.sess().warn(format!("This version of rustc was built with LLVM \
2505 {}.{}. Rustc just ran into a known \
2506 debuginfo corruption problem thatoften \
2507 occurs with LLVM versions below 3.4. \
2508 Please use a rustc built with anewer \
2511 llvm_version_minor).as_slice());
2513 cx.sess().bug("debuginfo::set_members_of_composite_type() - \
2514 Already completed forward declaration re-encountered.");
2517 composite_types_completed.insert(composite_type_metadata);
2521 let member_metadata: Vec<DIDescriptor> = member_descriptions
2524 .map(|(i, member_description)| {
2525 let (member_size, member_align) = size_and_align_of(cx, member_description.llvm_type);
2526 let member_offset = match member_description.offset {
2527 FixedMemberOffset { bytes } => bytes as u64,
2528 ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
2531 member_description.name.as_slice().with_c_str(|member_name| {
2533 llvm::LLVMDIBuilderCreateMemberType(
2535 composite_type_metadata,
2537 UNKNOWN_FILE_METADATA,
2538 UNKNOWN_LINE_NUMBER,
2539 bytes_to_bits(member_size),
2540 bytes_to_bits(member_align),
2541 bytes_to_bits(member_offset),
2542 member_description.flags,
2543 member_description.type_metadata)
2550 let type_array = create_DIArray(DIB(cx), member_metadata.as_slice());
2551 llvm::LLVMDICompositeTypeSetTypeArray(composite_type_metadata, type_array);
2555 // A convenience wrapper around LLVMDIBuilderCreateStructType(). Does not do any
2556 // caching, does not add any fields to the struct. This can be done later with
2557 // set_members_of_composite_type().
2558 fn create_struct_stub(cx: &CrateContext,
2559 struct_llvm_type: Type,
2560 struct_type_name: &str,
2561 unique_type_id: UniqueTypeId,
2562 containing_scope: DIScope)
2563 -> DICompositeType {
2564 let (struct_size, struct_align) = size_and_align_of(cx, struct_llvm_type);
2566 let unique_type_id_str = debug_context(cx).type_map
2568 .get_unique_type_id_as_string(unique_type_id);
2569 let metadata_stub = unsafe {
2570 struct_type_name.with_c_str(|name| {
2571 unique_type_id_str.as_slice().with_c_str(|unique_type_id| {
2572 // LLVMDIBuilderCreateStructType() wants an empty array. A null
2573 // pointer will lead to hard to trace and debug LLVM assertions
2574 // later on in llvm/lib/IR/Value.cpp.
2575 let empty_array = create_DIArray(DIB(cx), []);
2577 llvm::LLVMDIBuilderCreateStructType(
2581 UNKNOWN_FILE_METADATA,
2582 UNKNOWN_LINE_NUMBER,
2583 bytes_to_bits(struct_size),
2584 bytes_to_bits(struct_align),
2595 return metadata_stub;
2598 fn at_box_metadata(cx: &CrateContext,
2599 at_pointer_type: ty::t,
2600 content_type: ty::t,
2601 unique_type_id: UniqueTypeId)
2602 -> MetadataCreationResult {
2603 let content_type_metadata = type_metadata(cx, content_type, codemap::DUMMY_SP);
2605 return_if_metadata_created_in_meantime!(cx, unique_type_id);
2607 let content_type_name = compute_debuginfo_type_name(cx, content_type, true);
2608 let content_type_name = content_type_name.as_slice();
2609 let content_llvm_type = type_of::type_of(cx, content_type);
2611 let box_type_name = format!("GcBox<{}>", content_type_name);
2612 let box_llvm_type = Type::at_box(cx, content_llvm_type);
2613 let member_llvm_types = box_llvm_type.field_types();
2614 assert!(box_layout_is_correct(cx,
2615 member_llvm_types.as_slice(),
2616 content_llvm_type));
2618 let int_type = ty::mk_int();
2619 let nil_pointer_type = ty::mk_nil_ptr(cx.tcx());
2620 let nil_pointer_type_metadata = type_metadata(cx,
2623 let member_descriptions = [
2625 name: "refcnt".to_string(),
2626 llvm_type: *member_llvm_types.get(0),
2627 type_metadata: type_metadata(cx, int_type, codemap::DUMMY_SP),
2628 offset: ComputedMemberOffset,
2629 flags: FLAGS_ARTIFICAL,
2632 name: "drop_glue".to_string(),
2633 llvm_type: *member_llvm_types.get(1),
2634 type_metadata: nil_pointer_type_metadata,
2635 offset: ComputedMemberOffset,
2636 flags: FLAGS_ARTIFICAL,
2639 name: "prev".to_string(),
2640 llvm_type: *member_llvm_types.get(2),
2641 type_metadata: nil_pointer_type_metadata,
2642 offset: ComputedMemberOffset,
2643 flags: FLAGS_ARTIFICAL,
2646 name: "next".to_string(),
2647 llvm_type: *member_llvm_types.get(3),
2648 type_metadata: nil_pointer_type_metadata,
2649 offset: ComputedMemberOffset,
2650 flags: FLAGS_ARTIFICAL,
2653 name: "val".to_string(),
2654 llvm_type: *member_llvm_types.get(4),
2655 type_metadata: content_type_metadata,
2656 offset: ComputedMemberOffset,
2657 flags: FLAGS_ARTIFICAL,
2661 let gc_box_unique_id = debug_context(cx).type_map
2663 .get_unique_type_id_of_gc_box(cx, content_type);
2665 let gc_box_metadata = composite_type_metadata(
2668 box_type_name.as_slice(),
2670 member_descriptions,
2671 UNKNOWN_SCOPE_METADATA,
2672 UNKNOWN_FILE_METADATA,
2675 let gc_pointer_metadata = pointer_type_metadata(cx,
2679 return MetadataCreationResult::new(gc_pointer_metadata, false);
2681 // Unfortunately, we cannot assert anything but the correct types here---and
2682 // not whether the 'next' and 'prev' pointers are in the correct order.
2683 fn box_layout_is_correct(cx: &CrateContext,
2684 member_llvm_types: &[Type],
2685 content_llvm_type: Type)
2687 member_llvm_types.len() == 5 &&
2688 member_llvm_types[0] == cx.int_type() &&
2689 member_llvm_types[1] == Type::generic_glue_fn(cx).ptr_to() &&
2690 member_llvm_types[2] == Type::i8(cx).ptr_to() &&
2691 member_llvm_types[3] == Type::i8(cx).ptr_to() &&
2692 member_llvm_types[4] == content_llvm_type
2697 fn fixed_vec_metadata(cx: &CrateContext,
2698 unique_type_id: UniqueTypeId,
2699 element_type: ty::t,
2702 -> MetadataCreationResult {
2703 let element_type_metadata = type_metadata(cx, element_type, span);
2705 return_if_metadata_created_in_meantime!(cx, unique_type_id);
2707 let element_llvm_type = type_of::type_of(cx, element_type);
2708 let (element_type_size, element_type_align) = size_and_align_of(cx, element_llvm_type);
2710 let subrange = unsafe {
2711 llvm::LLVMDIBuilderGetOrCreateSubrange(
2717 let subscripts = create_DIArray(DIB(cx), [subrange]);
2718 let metadata = unsafe {
2719 llvm::LLVMDIBuilderCreateArrayType(
2721 bytes_to_bits(element_type_size * (len as u64)),
2722 bytes_to_bits(element_type_align),
2723 element_type_metadata,
2727 return MetadataCreationResult::new(metadata, false);
2730 fn vec_slice_metadata(cx: &CrateContext,
2732 element_type: ty::t,
2733 unique_type_id: UniqueTypeId,
2735 -> MetadataCreationResult {
2736 let data_ptr_type = ty::mk_ptr(cx.tcx(), ty::mt {
2738 mutbl: ast::MutImmutable
2741 let element_type_metadata = type_metadata(cx, data_ptr_type, span);
2743 return_if_metadata_created_in_meantime!(cx, unique_type_id);
2745 let slice_llvm_type = type_of::type_of(cx, vec_type);
2746 let slice_type_name = compute_debuginfo_type_name(cx, vec_type, true);
2748 let member_llvm_types = slice_llvm_type.field_types();
2749 assert!(slice_layout_is_correct(cx,
2750 member_llvm_types.as_slice(),
2752 let member_descriptions = [
2754 name: "data_ptr".to_string(),
2755 llvm_type: *member_llvm_types.get(0),
2756 type_metadata: element_type_metadata,
2757 offset: ComputedMemberOffset,
2758 flags: FLAGS_ARTIFICAL
2761 name: "length".to_string(),
2762 llvm_type: *member_llvm_types.get(1),
2763 type_metadata: type_metadata(cx, ty::mk_uint(), span),
2764 offset: ComputedMemberOffset,
2765 flags: FLAGS_ARTIFICAL
2769 assert!(member_descriptions.len() == member_llvm_types.len());
2771 let loc = span_start(cx, span);
2772 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2774 let metadata = composite_type_metadata(cx,
2776 slice_type_name.as_slice(),
2778 member_descriptions,
2779 UNKNOWN_SCOPE_METADATA,
2782 return MetadataCreationResult::new(metadata, false);
2784 fn slice_layout_is_correct(cx: &CrateContext,
2785 member_llvm_types: &[Type],
2786 element_type: ty::t)
2788 member_llvm_types.len() == 2 &&
2789 member_llvm_types[0] == type_of::type_of(cx, element_type).ptr_to() &&
2790 member_llvm_types[1] == cx.int_type()
2794 fn subroutine_type_metadata(cx: &CrateContext,
2795 unique_type_id: UniqueTypeId,
2796 signature: &ty::FnSig,
2798 -> MetadataCreationResult {
2799 let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs.len() + 1);
2802 signature_metadata.push(match ty::get(signature.output).sty {
2803 ty::ty_nil => ptr::mut_null(),
2804 _ => type_metadata(cx, signature.output, span)
2807 // regular arguments
2808 for &argument_type in signature.inputs.iter() {
2809 signature_metadata.push(type_metadata(cx, argument_type, span));
2812 return_if_metadata_created_in_meantime!(cx, unique_type_id);
2814 return MetadataCreationResult::new(
2816 llvm::LLVMDIBuilderCreateSubroutineType(
2818 UNKNOWN_FILE_METADATA,
2819 create_DIArray(DIB(cx), signature_metadata.as_slice()))
2824 // FIXME(1563) This is all a bit of a hack because 'trait pointer' is an ill-
2825 // defined concept. For the case of an actual trait pointer (i.e., Box<Trait>,
2826 // &Trait), trait_object_type should be the whole thing (e.g, Box<Trait>) and
2827 // trait_type should be the actual trait (e.g., Trait). Where the trait is part
2828 // of a DST struct, there is no trait_object_type and the results of this
2829 // function will be a little bit weird.
2830 fn trait_pointer_metadata(cx: &CrateContext,
2832 trait_object_type: Option<ty::t>,
2833 unique_type_id: UniqueTypeId)
2835 // The implementation provided here is a stub. It makes sure that the trait
2836 // type is assigned the correct name, size, namespace, and source location.
2837 // But it does not describe the trait's methods.
2839 let def_id = match ty::get(trait_type).sty {
2840 ty::ty_trait(box ty::TyTrait { def_id, .. }) => def_id,
2842 let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_type);
2843 cx.sess().bug(format!("debuginfo: Unexpected trait-object type in \
2844 trait_pointer_metadata(): {}",
2845 pp_type_name.as_slice()).as_slice());
2849 let trait_object_type = trait_object_type.unwrap_or(trait_type);
2850 let trait_type_name =
2851 compute_debuginfo_type_name(cx, trait_object_type, false);
2853 let (containing_scope, _) = get_namespace_and_span_for_item(cx, def_id);
2855 let trait_llvm_type = type_of::type_of(cx, trait_object_type);
2857 composite_type_metadata(cx,
2859 trait_type_name.as_slice(),
2863 UNKNOWN_FILE_METADATA,
2867 fn type_metadata(cx: &CrateContext,
2869 usage_site_span: Span)
2871 // Get the unique type id of this type.
2872 let unique_type_id = {
2873 let mut type_map = debug_context(cx).type_map.borrow_mut();
2874 // First, try to find the type in TypeMap. If we have seen it before, we
2875 // can exit early here.
2876 match type_map.find_metadata_for_type(t) {
2881 // The ty::t is not in the TypeMap but maybe we have already seen
2882 // an equivalent type (e.g. only differing in region arguments).
2883 // In order to find out, generate the unique type id and look
2885 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
2886 match type_map.find_metadata_for_unique_id(unique_type_id) {
2888 // There is already an equivalent type in the TypeMap.
2889 // Register this ty::t as an alias in the cache and
2890 // return the cached metadata.
2891 type_map.register_type_with_metadata(cx, t, metadata);
2895 // There really is no type metadata for this type, so
2896 // proceed by creating it.
2904 debug!("type_metadata: {:?}", ty::get(t));
2906 let sty = &ty::get(t).sty;
2907 let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty {
2914 ty::ty_float(_) => {
2915 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
2917 ty::ty_enum(def_id, _) => {
2918 prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span).finalize(cx)
2920 ty::ty_box(pointee_type) => {
2921 at_box_metadata(cx, t, pointee_type, unique_type_id)
2923 ty::ty_vec(typ, Some(len)) => {
2924 fixed_vec_metadata(cx, unique_type_id, typ, len, usage_site_span)
2926 // FIXME Can we do better than this for unsized vec/str fields?
2927 ty::ty_vec(typ, None) => fixed_vec_metadata(cx, unique_type_id, typ, 0, usage_site_span),
2928 ty::ty_str => fixed_vec_metadata(cx, unique_type_id, ty::mk_i8(), 0, usage_site_span),
2929 ty::ty_trait(..) => {
2930 MetadataCreationResult::new(
2931 trait_pointer_metadata(cx, t, None, unique_type_id),
2934 ty::ty_uniq(ty) | ty::ty_ptr(ty::mt{ty, ..}) | ty::ty_rptr(_, ty::mt{ty, ..}) => {
2935 match ty::get(ty).sty {
2936 ty::ty_vec(typ, None) => {
2937 vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span)
2940 vec_slice_metadata(cx, t, ty::mk_u8(), unique_type_id, usage_site_span)
2942 ty::ty_trait(..) => {
2943 MetadataCreationResult::new(
2944 trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
2948 let pointee_metadata = type_metadata(cx, ty, usage_site_span);
2950 match debug_context(cx).type_map
2952 .find_metadata_for_unique_id(unique_type_id) {
2953 Some(metadata) => return metadata,
2954 None => { /* proceed normally */ }
2957 MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
2962 ty::ty_bare_fn(ref barefnty) => {
2963 subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
2965 ty::ty_closure(ref closurety) => {
2966 subroutine_type_metadata(cx, unique_type_id, &closurety.sig, usage_site_span)
2968 ty::ty_struct(def_id, ref substs) => {
2969 prepare_struct_metadata(cx,
2974 usage_site_span).finalize(cx)
2976 ty::ty_tup(ref elements) => {
2977 prepare_tuple_metadata(cx,
2979 elements.as_slice(),
2981 usage_site_span).finalize(cx)
2984 cx.sess().bug(format!("debuginfo: unexpected type in type_metadata: {:?}",
2990 let mut type_map = debug_context(cx).type_map.borrow_mut();
2992 if already_stored_in_typemap {
2993 // Also make sure that we already have a TypeMap entry entry for the unique type id.
2994 let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
2995 Some(metadata) => metadata,
2997 let unique_type_id_str =
2998 type_map.get_unique_type_id_as_string(unique_type_id);
2999 let error_message = format!("Expected type metadata for unique \
3000 type id '{}' to already be in \
3001 the debuginfo::TypeMap but it \
3002 was not. (ty::t = {})",
3003 unique_type_id_str.as_slice(),
3004 ppaux::ty_to_string(cx.tcx(), t));
3005 cx.sess().span_bug(usage_site_span, error_message.as_slice());
3009 match type_map.find_metadata_for_type(t) {
3011 if metadata != metadata_for_uid {
3012 let unique_type_id_str =
3013 type_map.get_unique_type_id_as_string(unique_type_id);
3014 let error_message = format!("Mismatch between ty::t and \
3015 UniqueTypeId maps in \
3016 debuginfo::TypeMap. \
3017 UniqueTypeId={}, ty::t={}",
3018 unique_type_id_str.as_slice(),
3019 ppaux::ty_to_string(cx.tcx(), t));
3020 cx.sess().span_bug(usage_site_span, error_message.as_slice());
3024 type_map.register_type_with_metadata(cx, t, metadata);
3028 type_map.register_type_with_metadata(cx, t, metadata);
3029 type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata);
3036 struct MetadataCreationResult {
3038 already_stored_in_typemap: bool
3041 impl MetadataCreationResult {
3042 fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationResult {
3043 MetadataCreationResult {
3045 already_stored_in_typemap: already_stored_in_typemap
3050 #[deriving(PartialEq)]
3051 enum DebugLocation {
3052 KnownLocation { scope: DIScope, line: uint, col: uint },
3056 impl DebugLocation {
3057 fn new(scope: DIScope, line: uint, col: uint) -> DebugLocation {
3066 fn set_debug_location(cx: &CrateContext, debug_location: DebugLocation) {
3067 if debug_location == debug_context(cx).current_debug_location.get() {
3073 match debug_location {
3074 KnownLocation { scope, line, .. } => {
3075 // Always set the column to zero like Clang and GCC
3076 let col = UNKNOWN_COLUMN_NUMBER;
3077 debug!("setting debug location to {} {}", line, col);
3078 let elements = [C_i32(cx, line as i32), C_i32(cx, col as i32),
3079 scope, ptr::mut_null()];
3081 metadata_node = llvm::LLVMMDNodeInContext(debug_context(cx).llcontext,
3083 elements.len() as c_uint);
3086 UnknownLocation => {
3087 debug!("clearing debug location ");
3088 metadata_node = ptr::mut_null();
3093 llvm::LLVMSetCurrentDebugLocation(cx.raw_builder(), metadata_node);
3096 debug_context(cx).current_debug_location.set(debug_location);
3099 //=-----------------------------------------------------------------------------
3100 // Utility Functions
3101 //=-----------------------------------------------------------------------------
3103 fn contains_nodebug_attribute(attributes: &[ast::Attribute]) -> bool {
3104 attributes.iter().any(|attr| {
3105 let meta_item: &ast::MetaItem = &*attr.node.value;
3106 match meta_item.node {
3107 ast::MetaWord(ref value) => value.get() == "no_debug",
3113 /// Return codemap::Loc corresponding to the beginning of the span
3114 fn span_start(cx: &CrateContext, span: Span) -> codemap::Loc {
3115 cx.sess().codemap().lookup_char_pos(span.lo)
3118 fn size_and_align_of(cx: &CrateContext, llvm_type: Type) -> (u64, u64) {
3119 (machine::llsize_of_alloc(cx, llvm_type), machine::llalign_of_min(cx, llvm_type))
3122 fn bytes_to_bits(bytes: u64) -> c_ulonglong {
3123 (bytes * 8) as c_ulonglong
3127 fn debug_context<'a>(cx: &'a CrateContext) -> &'a CrateDebugContext {
3128 let debug_context: &'a CrateDebugContext = cx.dbg_cx().get_ref();
3133 #[allow(non_snake_case)]
3134 fn DIB(cx: &CrateContext) -> DIBuilderRef {
3135 cx.dbg_cx().get_ref().builder
3138 fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
3139 match fcx.debug_context.repr {
3140 FunctionDebugContext(_) => false,
3145 fn assert_type_for_node_id(cx: &CrateContext, node_id: ast::NodeId, error_span: Span) {
3146 if !cx.tcx().node_types.borrow().contains_key(&(node_id as uint)) {
3147 cx.sess().span_bug(error_span, "debuginfo: Could not find type for node id!");
3151 fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: ast::DefId)
3152 -> (DIScope, Span) {
3153 let containing_scope = namespace_for_item(cx, def_id).scope;
3154 let definition_span = if def_id.krate == ast::LOCAL_CRATE {
3155 cx.tcx().map.span(def_id.node)
3157 // For external items there is no span information
3161 (containing_scope, definition_span)
3164 // This procedure builds the *scope map* for a given function, which maps any
3165 // given ast::NodeId in the function's AST to the correct DIScope metadata instance.
3167 // This builder procedure walks the AST in execution order and keeps track of
3168 // what belongs to which scope, creating DIScope DIEs along the way, and
3169 // introducing *artificial* lexical scope descriptors where necessary. These
3170 // artificial scopes allow GDB to correctly handle name shadowing.
3171 fn populate_scope_map(cx: &CrateContext,
3172 arg_pats: &[Gc<ast::Pat>],
3173 fn_entry_block: &ast::Block,
3174 fn_metadata: DISubprogram,
3175 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3176 let def_map = &cx.tcx().def_map;
3178 struct ScopeStackEntry {
3179 scope_metadata: DIScope,
3180 ident: Option<ast::Ident>
3183 let mut scope_stack = vec!(ScopeStackEntry { scope_metadata: fn_metadata,
3186 // Push argument identifiers onto the stack so arguments integrate nicely
3187 // with variable shadowing.
3188 for &arg_pat in arg_pats.iter() {
3189 pat_util::pat_bindings(def_map, &*arg_pat, |_, _, _, path1| {
3190 scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata,
3191 ident: Some(path1.node) });
3195 // Clang creates a separate scope for function bodies, so let's do this too.
3197 fn_entry_block.span,
3200 |cx, scope_stack, scope_map| {
3201 walk_block(cx, fn_entry_block, scope_stack, scope_map);
3204 // local helper functions for walking the AST.
3205 fn with_new_scope(cx: &CrateContext,
3207 scope_stack: &mut Vec<ScopeStackEntry> ,
3208 scope_map: &mut HashMap<ast::NodeId, DIScope>,
3209 inner_walk: |&CrateContext,
3210 &mut Vec<ScopeStackEntry> ,
3211 &mut HashMap<ast::NodeId, DIScope>|) {
3212 // Create a new lexical scope and push it onto the stack
3213 let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
3214 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
3215 let parent_scope = scope_stack.last().unwrap().scope_metadata;
3217 let scope_metadata = unsafe {
3218 llvm::LLVMDIBuilderCreateLexicalBlock(
3223 loc.col.to_uint() as c_uint,
3227 scope_stack.push(ScopeStackEntry { scope_metadata: scope_metadata,
3230 inner_walk(cx, scope_stack, scope_map);
3232 // pop artificial scopes
3233 while scope_stack.last().unwrap().ident.is_some() {
3237 if scope_stack.last().unwrap().scope_metadata != scope_metadata {
3238 cx.sess().span_bug(scope_span, "debuginfo: Inconsistency in scope management.");
3244 fn walk_block(cx: &CrateContext,
3246 scope_stack: &mut Vec<ScopeStackEntry> ,
3247 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3248 scope_map.insert(block.id, scope_stack.last().unwrap().scope_metadata);
3250 // The interesting things here are statements and the concluding expression.
3251 for statement in block.stmts.iter() {
3252 scope_map.insert(ast_util::stmt_id(&**statement),
3253 scope_stack.last().unwrap().scope_metadata);
3255 match statement.node {
3256 ast::StmtDecl(ref decl, _) =>
3257 walk_decl(cx, &**decl, scope_stack, scope_map),
3258 ast::StmtExpr(ref exp, _) |
3259 ast::StmtSemi(ref exp, _) =>
3260 walk_expr(cx, &**exp, scope_stack, scope_map),
3261 ast::StmtMac(..) => () // Ignore macros (which should be expanded anyway).
3265 for exp in block.expr.iter() {
3266 walk_expr(cx, &**exp, scope_stack, scope_map);
3270 fn walk_decl(cx: &CrateContext,
3272 scope_stack: &mut Vec<ScopeStackEntry> ,
3273 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3275 codemap::Spanned { node: ast::DeclLocal(local), .. } => {
3276 scope_map.insert(local.id, scope_stack.last().unwrap().scope_metadata);
3278 walk_pattern(cx, local.pat, scope_stack, scope_map);
3280 for exp in local.init.iter() {
3281 walk_expr(cx, &**exp, scope_stack, scope_map);
3288 fn walk_pattern(cx: &CrateContext,
3290 scope_stack: &mut Vec<ScopeStackEntry> ,
3291 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3293 let def_map = &cx.tcx().def_map;
3295 // Unfortunately, we cannot just use pat_util::pat_bindings() or
3296 // ast_util::walk_pat() here because we have to visit *all* nodes in
3297 // order to put them into the scope map. The above functions don't do that.
3299 ast::PatIdent(_, ref path1, ref sub_pat_opt) => {
3301 // Check if this is a binding. If so we need to put it on the
3302 // scope stack and maybe introduce an artificial scope
3303 if pat_util::pat_is_binding(def_map, &*pat) {
3305 let ident = path1.node;
3307 // LLVM does not properly generate 'DW_AT_start_scope' fields
3308 // for variable DIEs. For this reason we have to introduce
3309 // an artificial scope at bindings whenever a variable with
3310 // the same name is declared in *any* parent scope.
3312 // Otherwise the following error occurs:
3316 // do_something(); // 'gdb print x' correctly prints 10
3319 // do_something(); // 'gdb print x' prints 0, because it
3320 // // already reads the uninitialized 'x'
3321 // // from the next line...
3323 // do_something(); // 'gdb print x' correctly prints 100
3326 // Is there already a binding with that name?
3327 // N.B.: this comparison must be UNhygienic... because
3328 // gdb knows nothing about the context, so any two
3329 // variables with the same name will cause the problem.
3330 let need_new_scope = scope_stack
3332 .any(|entry| entry.ident.iter().any(|i| i.name == ident.name));
3335 // Create a new lexical scope and push it onto the stack
3336 let loc = cx.sess().codemap().lookup_char_pos(pat.span.lo);
3337 let file_metadata = file_metadata(cx,
3341 let parent_scope = scope_stack.last().unwrap().scope_metadata;
3343 let scope_metadata = unsafe {
3344 llvm::LLVMDIBuilderCreateLexicalBlock(
3349 loc.col.to_uint() as c_uint,
3353 scope_stack.push(ScopeStackEntry {
3354 scope_metadata: scope_metadata,
3359 // Push a new entry anyway so the name can be found
3360 let prev_metadata = scope_stack.last().unwrap().scope_metadata;
3361 scope_stack.push(ScopeStackEntry {
3362 scope_metadata: prev_metadata,
3368 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3370 for &sub_pat in sub_pat_opt.iter() {
3371 walk_pattern(cx, sub_pat, scope_stack, scope_map);
3375 ast::PatWild(_) => {
3376 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3379 ast::PatEnum(_, ref sub_pats_opt) => {
3380 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3382 for ref sub_pats in sub_pats_opt.iter() {
3383 for &p in sub_pats.iter() {
3384 walk_pattern(cx, p, scope_stack, scope_map);
3389 ast::PatStruct(_, ref field_pats, _) => {
3390 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3392 for &ast::FieldPat { pat: sub_pat, .. } in field_pats.iter() {
3393 walk_pattern(cx, sub_pat, scope_stack, scope_map);
3397 ast::PatTup(ref sub_pats) => {
3398 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3400 for sub_pat in sub_pats.iter() {
3401 walk_pattern(cx, sub_pat.clone(), scope_stack, scope_map);
3405 ast::PatBox(ref sub_pat) | ast::PatRegion(ref sub_pat) => {
3406 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3407 walk_pattern(cx, sub_pat.clone(), scope_stack, scope_map);
3410 ast::PatLit(ref exp) => {
3411 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3412 walk_expr(cx, &**exp, scope_stack, scope_map);
3415 ast::PatRange(ref exp1, ref exp2) => {
3416 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3417 walk_expr(cx, &**exp1, scope_stack, scope_map);
3418 walk_expr(cx, &**exp2, scope_stack, scope_map);
3421 ast::PatVec(ref front_sub_pats, ref middle_sub_pats, ref back_sub_pats) => {
3422 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3424 for &sub_pat in front_sub_pats.iter() {
3425 walk_pattern(cx, sub_pat, scope_stack, scope_map);
3428 for &sub_pat in middle_sub_pats.iter() {
3429 walk_pattern(cx, sub_pat, scope_stack, scope_map);
3432 for &sub_pat in back_sub_pats.iter() {
3433 walk_pattern(cx, sub_pat, scope_stack, scope_map);
3438 cx.sess().span_bug(pat.span, "debuginfo::populate_scope_map() - \
3439 Found unexpanded macro.");
3444 fn walk_expr(cx: &CrateContext,
3446 scope_stack: &mut Vec<ScopeStackEntry> ,
3447 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3449 scope_map.insert(exp.id, scope_stack.last().unwrap().scope_metadata);
3455 ast::ExprPath(_) => {}
3457 ast::ExprCast(ref sub_exp, _) |
3458 ast::ExprAddrOf(_, ref sub_exp) |
3459 ast::ExprField(ref sub_exp, _, _) |
3460 ast::ExprParen(ref sub_exp) =>
3461 walk_expr(cx, &**sub_exp, scope_stack, scope_map),
3463 ast::ExprBox(ref place, ref sub_expr) => {
3464 walk_expr(cx, &**place, scope_stack, scope_map);
3465 walk_expr(cx, &**sub_expr, scope_stack, scope_map);
3468 ast::ExprRet(exp_opt) => match exp_opt {
3469 Some(sub_exp) => walk_expr(cx, &*sub_exp, scope_stack, scope_map),
3473 ast::ExprUnary(_, ref sub_exp) => {
3474 walk_expr(cx, &**sub_exp, scope_stack, scope_map);
3477 ast::ExprAssignOp(_, ref lhs, ref rhs) |
3478 ast::ExprIndex(ref lhs, ref rhs) |
3479 ast::ExprBinary(_, ref lhs, ref rhs) => {
3480 walk_expr(cx, &**lhs, scope_stack, scope_map);
3481 walk_expr(cx, &**rhs, scope_stack, scope_map);
3484 ast::ExprVec(ref init_expressions) |
3485 ast::ExprTup(ref init_expressions) => {
3486 for ie in init_expressions.iter() {
3487 walk_expr(cx, &**ie, scope_stack, scope_map);
3491 ast::ExprAssign(ref sub_exp1, ref sub_exp2) |
3492 ast::ExprRepeat(ref sub_exp1, ref sub_exp2) => {
3493 walk_expr(cx, &**sub_exp1, scope_stack, scope_map);
3494 walk_expr(cx, &**sub_exp2, scope_stack, scope_map);
3497 ast::ExprIf(ref cond_exp, ref then_block, ref opt_else_exp) => {
3498 walk_expr(cx, &**cond_exp, scope_stack, scope_map);
3504 |cx, scope_stack, scope_map| {
3505 walk_block(cx, &**then_block, scope_stack, scope_map);
3508 match *opt_else_exp {
3509 Some(ref else_exp) =>
3510 walk_expr(cx, &**else_exp, scope_stack, scope_map),
3515 ast::ExprWhile(ref cond_exp, ref loop_body, _) => {
3516 walk_expr(cx, &**cond_exp, scope_stack, scope_map);
3522 |cx, scope_stack, scope_map| {
3523 walk_block(cx, &**loop_body, scope_stack, scope_map);
3527 ast::ExprForLoop(ref pattern, ref head, ref body, _) => {
3528 walk_expr(cx, &**head, scope_stack, scope_map);
3534 |cx, scope_stack, scope_map| {
3535 scope_map.insert(exp.id,
3543 walk_block(cx, &**body, scope_stack, scope_map);
3547 ast::ExprMac(_) => {
3548 cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
3549 Found unexpanded macro.");
3552 ast::ExprLoop(ref block, _) |
3553 ast::ExprBlock(ref block) => {
3558 |cx, scope_stack, scope_map| {
3559 walk_block(cx, &**block, scope_stack, scope_map);
3563 ast::ExprFnBlock(_, ref decl, ref block) |
3564 ast::ExprProc(ref decl, ref block) |
3565 ast::ExprUnboxedFn(_, _, ref decl, ref block) => {
3570 |cx, scope_stack, scope_map| {
3571 for &ast::Arg { pat: ref pattern, .. } in decl.inputs.iter() {
3572 walk_pattern(cx, pattern.clone(), scope_stack, scope_map);
3575 walk_block(cx, &**block, scope_stack, scope_map);
3579 ast::ExprCall(ref fn_exp, ref args) => {
3580 walk_expr(cx, &**fn_exp, scope_stack, scope_map);
3582 for arg_exp in args.iter() {
3583 walk_expr(cx, &**arg_exp, scope_stack, scope_map);
3587 ast::ExprMethodCall(_, _, ref args) => {
3588 for arg_exp in args.iter() {
3589 walk_expr(cx, &**arg_exp, scope_stack, scope_map);
3593 ast::ExprMatch(ref discriminant_exp, ref arms) => {
3594 walk_expr(cx, &**discriminant_exp, scope_stack, scope_map);
3596 // For each arm we have to first walk the pattern as these might
3597 // introduce new artificial scopes. It should be sufficient to
3598 // walk only one pattern per arm, as they all must contain the
3599 // same binding names.
3601 for arm_ref in arms.iter() {
3602 let arm_span = arm_ref.pats.get(0).span;
3608 |cx, scope_stack, scope_map| {
3609 for &pat in arm_ref.pats.iter() {
3610 walk_pattern(cx, pat, scope_stack, scope_map);
3613 for guard_exp in arm_ref.guard.iter() {
3614 walk_expr(cx, &**guard_exp, scope_stack, scope_map)
3617 walk_expr(cx, &*arm_ref.body, scope_stack, scope_map);
3622 ast::ExprStruct(_, ref fields, ref base_exp) => {
3623 for &ast::Field { expr: ref exp, .. } in fields.iter() {
3624 walk_expr(cx, &**exp, scope_stack, scope_map);
3628 Some(ref exp) => walk_expr(cx, &**exp, scope_stack, scope_map),
3633 ast::ExprInlineAsm(ast::InlineAsm { inputs: ref inputs,
3634 outputs: ref outputs,
3636 // inputs, outputs: ~[(String, Gc<expr>)]
3637 for &(_, ref exp) in inputs.iter() {
3638 walk_expr(cx, &**exp, scope_stack, scope_map);
3641 for &(_, ref exp, _) in outputs.iter() {
3642 walk_expr(cx, &**exp, scope_stack, scope_map);
3650 //=-----------------------------------------------------------------------------
3651 // Type Names for Debug Info
3652 //=-----------------------------------------------------------------------------
3654 // Compute the name of the type as it should be stored in debuginfo. Does not do
3655 // any caching, i.e. calling the function twice with the same type will also do
3656 // the work twice. The `qualified` parameter only affects the first level of the
3657 // type name, further levels (i.e. type parameters) are always fully qualified.
3658 fn compute_debuginfo_type_name(cx: &CrateContext,
3662 let mut result = String::with_capacity(64);
3663 push_debuginfo_type_name(cx, t, qualified, &mut result);
3667 // Pushes the name of the type as it should be stored in debuginfo on the
3668 // `output` String. See also compute_debuginfo_type_name().
3669 fn push_debuginfo_type_name(cx: &CrateContext,
3672 output:&mut String) {
3673 match ty::get(t).sty {
3674 ty::ty_nil => output.push_str("()"),
3675 ty::ty_bot => output.push_str("!"),
3676 ty::ty_bool => output.push_str("bool"),
3677 ty::ty_char => output.push_str("char"),
3678 ty::ty_str => output.push_str("str"),
3679 ty::ty_int(ast::TyI) => output.push_str("int"),
3680 ty::ty_int(ast::TyI8) => output.push_str("i8"),
3681 ty::ty_int(ast::TyI16) => output.push_str("i16"),
3682 ty::ty_int(ast::TyI32) => output.push_str("i32"),
3683 ty::ty_int(ast::TyI64) => output.push_str("i64"),
3684 ty::ty_uint(ast::TyU) => output.push_str("uint"),
3685 ty::ty_uint(ast::TyU8) => output.push_str("u8"),
3686 ty::ty_uint(ast::TyU16) => output.push_str("u16"),
3687 ty::ty_uint(ast::TyU32) => output.push_str("u32"),
3688 ty::ty_uint(ast::TyU64) => output.push_str("u64"),
3689 ty::ty_float(ast::TyF32) => output.push_str("f32"),
3690 ty::ty_float(ast::TyF64) => output.push_str("f64"),
3691 ty::ty_struct(def_id, ref substs) |
3692 ty::ty_enum(def_id, ref substs) => {
3693 push_item_name(cx, def_id, qualified, output);
3694 push_type_params(cx, substs, output);
3696 ty::ty_tup(ref component_types) => {
3697 output.push_char('(');
3698 for &component_type in component_types.iter() {
3699 push_debuginfo_type_name(cx, component_type, true, output);
3700 output.push_str(", ");
3704 output.push_char(')');
3706 ty::ty_uniq(inner_type) => {
3707 output.push_str("Box<");
3708 push_debuginfo_type_name(cx, inner_type, true, output);
3709 output.push_char('>');
3711 ty::ty_box(inner_type) => {
3712 output.push_char('@');
3713 push_debuginfo_type_name(cx, inner_type, true, output);
3715 ty::ty_ptr(ty::mt { ty: inner_type, mutbl } ) => {
3716 output.push_char('*');
3718 ast::MutImmutable => output.push_str("const "),
3719 ast::MutMutable => output.push_str("mut "),
3722 push_debuginfo_type_name(cx, inner_type, true, output);
3724 ty::ty_rptr(_, ty::mt { ty: inner_type, mutbl }) => {
3725 output.push_char('&');
3726 if mutbl == ast::MutMutable {
3727 output.push_str("mut ");
3730 push_debuginfo_type_name(cx, inner_type, true, output);
3732 ty::ty_vec(inner_type, optional_length) => {
3733 output.push_char('[');
3734 push_debuginfo_type_name(cx, inner_type, true, output);
3736 match optional_length {
3738 output.push_str(format!(", ..{}", len).as_slice());
3740 None => { /* nothing to do */ }
3743 output.push_char(']');
3745 ty::ty_trait(ref trait_data) => {
3746 push_item_name(cx, trait_data.def_id, false, output);
3747 push_type_params(cx, &trait_data.substs, output);
3749 ty::ty_bare_fn(ty::BareFnTy{ fn_style, abi, ref sig } ) => {
3750 if fn_style == ast::UnsafeFn {
3751 output.push_str("unsafe ");
3754 if abi != ::syntax::abi::Rust {
3755 output.push_str("extern \"");
3756 output.push_str(abi.name());
3757 output.push_str("\" ");
3760 output.push_str("fn(");
3762 if sig.inputs.len() > 0 {
3763 for ¶meter_type in sig.inputs.iter() {
3764 push_debuginfo_type_name(cx, parameter_type, true, output);
3765 output.push_str(", ");
3772 if sig.inputs.len() > 0 {
3773 output.push_str(", ...");
3775 output.push_str("...");
3779 output.push_char(')');
3781 if !ty::type_is_nil(sig.output) {
3782 output.push_str(" -> ");
3783 push_debuginfo_type_name(cx, sig.output, true, output);
3786 ty::ty_closure(box ty::ClosureTy { fn_style,
3790 .. // omitting bounds ...
3792 if fn_style == ast::UnsafeFn {
3793 output.push_str("unsafe ");
3796 if onceness == ast::Once {
3797 output.push_str("once ");
3800 let param_list_closing_char;
3802 ty::UniqTraitStore => {
3803 output.push_str("proc(");
3804 param_list_closing_char = ')';
3806 ty::RegionTraitStore(_, ast::MutMutable) => {
3807 output.push_str("&mut|");
3808 param_list_closing_char = '|';
3810 ty::RegionTraitStore(_, ast::MutImmutable) => {
3811 output.push_str("&|");
3812 param_list_closing_char = '|';
3816 if sig.inputs.len() > 0 {
3817 for ¶meter_type in sig.inputs.iter() {
3818 push_debuginfo_type_name(cx, parameter_type, true, output);
3819 output.push_str(", ");
3826 if sig.inputs.len() > 0 {
3827 output.push_str(", ...");
3829 output.push_str("...");
3833 output.push_char(param_list_closing_char);
3835 if !ty::type_is_nil(sig.output) {
3836 output.push_str(" -> ");
3837 push_debuginfo_type_name(cx, sig.output, true, output);
3840 ty::ty_unboxed_closure(..) => {
3841 output.push_str("closure");
3846 ty::ty_param(_) => {
3847 cx.sess().bug(format!("debuginfo: Trying to create type name for \
3848 unexpected type: {}", ppaux::ty_to_string(cx.tcx(), t)).as_slice());
3852 fn push_item_name(cx: &CrateContext,
3855 output: &mut String) {
3856 ty::with_path(cx.tcx(), def_id, |mut path| {
3858 if def_id.krate == ast::LOCAL_CRATE {
3859 output.push_str(crate_root_namespace(cx));
3860 output.push_str("::");
3863 let mut path_element_count = 0u;
3864 for path_element in path {
3865 let name = token::get_name(path_element.name());
3866 output.push_str(name.get());
3867 output.push_str("::");
3868 path_element_count += 1;
3871 if path_element_count == 0 {
3872 cx.sess().bug("debuginfo: Encountered empty item path!");
3878 let name = token::get_name(path.last()
3879 .expect("debuginfo: Empty item path?")
3881 output.push_str(name.get());
3886 // Pushes the type parameters in the given `Substs` to the output string.
3887 // This ignores region parameters, since they can't reliably be
3888 // reconstructed for items from non-local crates. For local crates, this
3889 // would be possible but with inlining and LTO we have to use the least
3890 // common denominator - otherwise we would run into conflicts.
3891 fn push_type_params(cx: &CrateContext,
3892 substs: &subst::Substs,
3893 output: &mut String) {
3894 if substs.types.is_empty() {
3898 output.push_char('<');
3900 for &type_parameter in substs.types.iter() {
3901 push_debuginfo_type_name(cx, type_parameter, true, output);
3902 output.push_str(", ");
3908 output.push_char('>');
3913 //=-----------------------------------------------------------------------------
3914 // Namespace Handling
3915 //=-----------------------------------------------------------------------------
3917 struct NamespaceTreeNode {
3920 parent: Option<Weak<NamespaceTreeNode>>,
3923 impl NamespaceTreeNode {
3924 fn mangled_name_of_contained_item(&self, item_name: &str) -> String {
3925 fn fill_nested(node: &NamespaceTreeNode, output: &mut String) {
3927 Some(ref parent) => fill_nested(&*parent.upgrade().unwrap(), output),
3930 let string = token::get_name(node.name);
3931 output.push_str(format!("{}", string.get().len()).as_slice());
3932 output.push_str(string.get());
3935 let mut name = String::from_str("_ZN");
3936 fill_nested(self, &mut name);
3937 name.push_str(format!("{}", item_name.len()).as_slice());
3938 name.push_str(item_name);
3939 name.push_char('E');
3944 fn crate_root_namespace<'a>(cx: &'a CrateContext) -> &'a str {
3945 cx.link_meta().crate_name.as_slice()
3948 fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTreeNode> {
3949 ty::with_path(cx.tcx(), def_id, |path| {
3950 // prepend crate name if not already present
3951 let krate = if def_id.krate == ast::LOCAL_CRATE {
3952 let crate_namespace_ident = token::str_to_ident(crate_root_namespace(cx));
3953 Some(ast_map::PathMod(crate_namespace_ident.name))
3957 let mut path = krate.move_iter().chain(path).peekable();
3959 let mut current_key = Vec::new();
3960 let mut parent_node: Option<Rc<NamespaceTreeNode>> = None;
3962 // Create/Lookup namespace for each element of the path.
3964 // Emulate a for loop so we can use peek below.
3965 let path_element = match path.next() {
3969 // Ignore the name of the item (the last path element).
3970 if path.peek().is_none() {
3974 let name = path_element.name();
3975 current_key.push(name);
3977 let existing_node = debug_context(cx).namespace_map.borrow()
3978 .find_copy(¤t_key);
3979 let current_node = match existing_node {
3980 Some(existing_node) => existing_node,
3982 // create and insert
3983 let parent_scope = match parent_node {
3984 Some(ref node) => node.scope,
3985 None => ptr::mut_null()
3987 let namespace_name = token::get_name(name);
3988 let scope = namespace_name.get().with_c_str(|namespace_name| {
3990 llvm::LLVMDIBuilderCreateNameSpace(
3994 // cannot reconstruct file ...
3996 // ... or line information, but that's not so important.
4001 let node = Rc::new(NamespaceTreeNode {
4004 parent: parent_node.map(|parent| parent.downgrade()),
4007 debug_context(cx).namespace_map.borrow_mut()
4008 .insert(current_key.clone(), node.clone());
4014 parent_node = Some(current_node);
4020 cx.sess().bug(format!("debuginfo::namespace_for_item(): \
4021 path too short for {:?}",
4022 def_id).as_slice());