1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
14 This module serves the purpose of generating debug symbols. We use LLVM's
15 [source level debugging](http://llvm.org/docs/SourceLevelDebugging.html)
16 features for generating the debug information. The general principle is this:
18 Given the right metadata in the LLVM IR, the LLVM code generator is able to
19 create DWARF debug symbols for the given code. The
20 [metadata](http://llvm.org/docs/LangRef.html#metadata-type) is structured much
21 like DWARF *debugging information entries* (DIE), representing type information
22 such as datatype layout, function signatures, block layout, variable location
23 and scope information, etc. It is the purpose of this module to generate correct
24 metadata and insert it into the LLVM IR.
26 As the exact format of metadata trees may change between different LLVM
27 versions, we now use LLVM
28 [DIBuilder](http://llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html) to
29 create metadata where possible. This will hopefully ease the adaption of this
30 module to future LLVM versions.
32 The public API of the module is a set of functions that will insert the correct
33 metadata into the LLVM IR when called with the right parameters. The module is
34 thus driven from an outside client with functions like
35 `debuginfo::create_local_var_metadata(bcx: block, local: &ast::local)`.
37 Internally the module will try to reuse already created metadata by utilizing a
38 cache. The way to get a shared metadata node when needed is thus to just call
39 the corresponding function in this module:
41 let file_metadata = file_metadata(crate_context, path);
43 The function will take care of probing the cache for an existing node for that
46 All private state used by the module is stored within either the
47 CrateDebugContext struct (owned by the CrateContext) or the FunctionDebugContext
48 (owned by the FunctionContext).
50 This file consists of three conceptual sections:
51 1. The public interface of the module
52 2. Module-internal metadata creation functions
53 3. Minor utility functions
58 Some kinds of types, such as structs and enums can be recursive. That means that
59 the type definition of some type X refers to some other type which in turn
60 (transitively) refers to X. This introduces cycles into the type referral graph.
61 A naive algorithm doing an on-demand, depth-first traversal of this graph when
62 describing types, can get trapped in an endless loop when it reaches such a
65 For example, the following simple type for a singly-linked list...
70 tail: Option<Box<List>>,
74 will generate the following callstack with a naive DFS algorithm:
79 describe(t = Option<Box<List>>)
80 describe(t = Box<List>)
81 describe(t = List) // at the beginning again...
85 To break cycles like these, we use "forward declarations". That is, when the
86 algorithm encounters a possibly recursive type (any struct or enum), it
87 immediately creates a type description node and inserts it into the cache
88 *before* describing the members of the type. This type description is just a
89 stub (as type members are not described and added to it yet) but it allows the
90 algorithm to already refer to the type. After the stub is inserted into the
91 cache, the algorithm continues as before. If it now encounters a recursive
92 reference, it will hit the cache and does not try to describe the type anew.
94 This behaviour is encapsulated in the 'RecursiveTypeDescription' enum, which
95 represents a kind of continuation, storing all state needed to continue
96 traversal at the type members after the type has been registered with the cache.
97 (This implementation approach might be a tad over-engineered and may change in
101 ## Source Locations and Line Information
103 In addition to data type descriptions the debugging information must also allow
104 to map machine code locations back to source code locations in order to be useful.
105 This functionality is also handled in this module. The following functions allow
106 to control source mappings:
108 + set_source_location()
109 + clear_source_location()
110 + start_emitting_source_locations()
112 `set_source_location()` allows to set the current source location. All IR
113 instructions created after a call to this function will be linked to the given
114 source location, until another location is specified with
115 `set_source_location()` or the source location is cleared with
116 `clear_source_location()`. In the later case, subsequent IR instruction will not
117 be linked to any source location. As you can see, this is a stateful API
118 (mimicking the one in LLVM), so be careful with source locations set by previous
119 calls. It's probably best to not rely on any specific state being present at a
122 One topic that deserves some extra attention is *function prologues*. At the
123 beginning of a function's machine code there are typically a few instructions
124 for loading argument values into allocas and checking if there's enough stack
125 space for the function to execute. This *prologue* is not visible in the source
126 code and LLVM puts a special PROLOGUE END marker into the line table at the
127 first non-prologue instruction of the function. In order to find out where the
128 prologue ends, LLVM looks for the first instruction in the function body that is
129 linked to a source location. So, when generating prologue instructions we have
130 to make sure that we don't emit source location information until the 'real'
131 function body begins. For this reason, source location emission is disabled by
132 default for any new function being translated and is only activated after a call
133 to the third function from the list above, `start_emitting_source_locations()`.
134 This function should be called right before regularly starting to translate the
135 top-level block of the given function.
137 There is one exception to the above rule: `llvm.dbg.declare` instruction must be
138 linked to the source location of the variable being declared. For function
139 parameters these `llvm.dbg.declare` instructions typically occur in the middle
140 of the prologue, however, they are ignored by LLVM's prologue detection. The
141 `create_argument_metadata()` and related functions take care of linking the
142 `llvm.dbg.declare` instructions to the correct source locations even while
143 source location emission is still disabled, so there is no need to do anything
144 special with source location handling here.
146 ## Unique Type Identification
148 In order for link-time optimization to work properly, LLVM needs a unique type
149 identifier that tells it across compilation units which types are the same as
150 others. This type identifier is created by TypeMap::get_unique_type_id_of_type()
151 using the following algorithm:
153 (1) Primitive types have their name as ID
154 (2) Structs, enums and traits have a multipart identifier
156 (1) The first part is the SVH (strict version hash) of the crate they were
157 originally defined in
159 (2) The second part is the ast::NodeId of the definition in their original
162 (3) The final part is a concatenation of the type IDs of their concrete type
163 arguments if they are generic types.
165 (3) Tuple-, pointer and function types are structurally identified, which means
166 that they are equivalent if their component types are equivalent (i.e. (int,
167 int) is the same regardless in which crate it is used).
169 This algorithm also provides a stable ID for types that are defined in one crate
170 but instantiated from metadata within another crate. We just have to take care
171 to always map crate and node IDs back to the original crate context.
173 As a side-effect these unique type IDs also help to solve a problem arising from
174 lifetime parameters. Since lifetime parameters are completely omitted in
175 debuginfo, more than one `ty::t` instance may map to the same debuginfo type
176 metadata, that is, some struct `Struct<'a>` may have N instantiations with
177 different concrete substitutions for `'a`, and thus there will be N `ty::t`
178 instances for the type `Struct<'a>` even though it is not generic otherwise.
179 Unfortunately this means that we cannot use `ty::type_id()` as cheap identifier
180 for type metadata---we have done this in the past, but it led to unnecessary
181 metadata duplication in the best case and LLVM assertions in the worst. However,
182 the unique type ID as described above *can* be used as identifier. Since it is
183 comparatively expensive to construct, though, `ty::type_id()` is still used
184 additionally as an optimization for cases where the exact same type has been
185 seen before (which is most of the time). */
188 use driver::config::{FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
190 use llvm::{ModuleRef, ContextRef, ValueRef};
191 use llvm::debuginfo::*;
192 use metadata::csearch;
194 use middle::trans::adt;
195 use middle::trans::common::*;
196 use middle::trans::machine;
197 use middle::trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef};
198 use middle::trans::type_of;
199 use middle::trans::type_::Type;
202 use middle::pat_util;
205 use libc::{c_uint, c_ulonglong, c_longlong};
206 use std::c_str::{CString, ToCStr};
207 use std::cell::{Cell, RefCell};
208 use std::collections::HashMap;
209 use std::collections::HashSet;
211 use std::rc::{Rc, Weak};
212 use syntax::util::interner::Interner;
213 use syntax::codemap::{Span, Pos};
214 use syntax::{abi, ast, codemap, ast_util, ast_map};
215 use syntax::ast_util::PostExpansionMethod;
216 use syntax::parse::token;
217 use syntax::parse::token::special_idents;
219 static DW_LANG_RUST: c_uint = 0x9000;
221 static DW_TAG_auto_variable: c_uint = 0x100;
222 static DW_TAG_arg_variable: c_uint = 0x101;
224 static DW_ATE_boolean: c_uint = 0x02;
225 static DW_ATE_float: c_uint = 0x04;
226 static DW_ATE_signed: c_uint = 0x05;
227 static DW_ATE_unsigned: c_uint = 0x07;
228 static DW_ATE_unsigned_char: c_uint = 0x08;
230 static UNKNOWN_LINE_NUMBER: c_uint = 0;
231 static UNKNOWN_COLUMN_NUMBER: c_uint = 0;
233 // ptr::null() doesn't work :(
234 static UNKNOWN_FILE_METADATA: DIFile = (0 as DIFile);
235 static UNKNOWN_SCOPE_METADATA: DIScope = (0 as DIScope);
237 static FLAGS_NONE: c_uint = 0;
238 static FLAGS_ARTIFICAL: c_uint = llvm::debuginfo::FlagArtificial as c_uint;
240 //=-----------------------------------------------------------------------------
241 // Public Interface of debuginfo module
242 //=-----------------------------------------------------------------------------
244 #[deriving(Copy, Show, Hash, Eq, PartialEq, Clone)]
245 struct UniqueTypeId(ast::Name);
247 // The TypeMap is where the CrateDebugContext holds the type metadata nodes
248 // created so far. The metadata nodes are indexed by UniqueTypeId, and, for
249 // faster lookup, also by ty::t. The TypeMap is responsible for creating
252 // The UniqueTypeIds created so far
253 unique_id_interner: Interner<Rc<String>>,
254 // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
255 unique_id_to_metadata: HashMap<UniqueTypeId, DIType>,
256 // A map from ty::type_id() to debuginfo metadata. This is a N:1 mapping.
257 type_to_metadata: HashMap<uint, DIType>,
258 // A map from ty::type_id() to UniqueTypeId. This is a N:1 mapping.
259 type_to_unique_id: HashMap<uint, UniqueTypeId>
264 fn new() -> TypeMap {
266 unique_id_interner: Interner::new(),
267 type_to_metadata: HashMap::new(),
268 unique_id_to_metadata: HashMap::new(),
269 type_to_unique_id: HashMap::new(),
273 // Adds a ty::t to metadata mapping to the TypeMap. The method will fail if
274 // the mapping already exists.
275 fn register_type_with_metadata(&mut self,
279 if !self.type_to_metadata.insert(ty::type_id(type_), metadata) {
280 cx.sess().bug(format!("Type metadata for ty::t '{}' is already in the TypeMap!",
281 ppaux::ty_to_string(cx.tcx(), type_)).as_slice());
285 // Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
286 // fail if the mapping already exists.
287 fn register_unique_id_with_metadata(&mut self,
289 unique_type_id: UniqueTypeId,
291 if !self.unique_id_to_metadata.insert(unique_type_id, metadata) {
292 let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id);
293 cx.sess().bug(format!("Type metadata for unique id '{}' is already in the TypeMap!",
294 unique_type_id_str.as_slice()).as_slice());
298 fn find_metadata_for_type(&self, type_: ty::t) -> Option<DIType> {
299 self.type_to_metadata.find_copy(&ty::type_id(type_))
302 fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<DIType> {
303 self.unique_id_to_metadata.find_copy(&unique_type_id)
306 // Get the string representation of a UniqueTypeId. This method will fail if
307 // the id is unknown.
308 fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> Rc<String> {
309 let UniqueTypeId(interner_key) = unique_type_id;
310 self.unique_id_interner.get(interner_key)
313 // Get the UniqueTypeId for the given type. If the UniqueTypeId for the given
314 // type has been requested before, this is just a table lookup. Otherwise an
315 // ID will be generated and stored for later lookup.
316 fn get_unique_type_id_of_type(&mut self, cx: &CrateContext, type_: ty::t) -> UniqueTypeId {
318 // basic type -> {:name of the type:}
319 // tuple -> {tuple_(:param-uid:)*}
320 // struct -> {struct_:svh: / :node-id:_<(:param-uid:),*> }
321 // enum -> {enum_:svh: / :node-id:_<(:param-uid:),*> }
322 // enum variant -> {variant_:variant-name:_:enum-uid:}
323 // reference (&) -> {& :pointee-uid:}
324 // mut reference (&mut) -> {&mut :pointee-uid:}
325 // ptr (*) -> {* :pointee-uid:}
326 // mut ptr (*mut) -> {*mut :pointee-uid:}
327 // unique ptr (~) -> {~ :pointee-uid:}
328 // @-ptr (@) -> {@ :pointee-uid:}
329 // sized vec ([T, ..x]) -> {[:size:] :element-uid:}
330 // unsized vec ([T]) -> {[] :element-uid:}
331 // trait (T) -> {trait_:svh: / :node-id:_<(:param-uid:),*> }
332 // closure -> {<unsafe_> <once_> :store-sigil: |(:param-uid:),* <,_...>| -> \
333 // :return-type-uid: : (:bounds:)*}
334 // function -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \
335 // :return-type-uid:}
336 // unique vec box (~[]) -> {HEAP_VEC_BOX<:pointee-uid:>}
337 // gc box -> {GC_BOX<:pointee-uid:>}
339 match self.type_to_unique_id.find_copy(&ty::type_id(type_)) {
340 Some(unique_type_id) => return unique_type_id,
341 None => { /* generate one */}
344 let mut unique_type_id = String::with_capacity(256);
345 unique_type_id.push_char('{');
347 match ty::get(type_).sty {
356 push_debuginfo_type_name(cx, type_, false, &mut unique_type_id);
358 ty::ty_enum(def_id, ref substs) => {
359 unique_type_id.push_str("enum ");
360 from_def_id_and_substs(self, cx, def_id, substs, &mut unique_type_id);
362 ty::ty_struct(def_id, ref substs) => {
363 unique_type_id.push_str("struct ");
364 from_def_id_and_substs(self, cx, def_id, substs, &mut unique_type_id);
366 ty::ty_tup(ref component_types) => {
367 unique_type_id.push_str("tuple ");
368 for &component_type in component_types.iter() {
369 let component_type_id =
370 self.get_unique_type_id_of_type(cx, component_type);
371 let component_type_id =
372 self.get_unique_type_id_as_string(component_type_id);
373 unique_type_id.push_str(component_type_id.as_slice());
376 ty::ty_box(inner_type) => {
377 unique_type_id.push_char('@');
378 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
379 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
380 unique_type_id.push_str(inner_type_id.as_slice());
382 ty::ty_uniq(inner_type) => {
383 unique_type_id.push_char('~');
384 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
385 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
386 unique_type_id.push_str(inner_type_id.as_slice());
388 ty::ty_ptr(ty::mt { ty: inner_type, mutbl } ) => {
389 unique_type_id.push_char('*');
390 if mutbl == ast::MutMutable {
391 unique_type_id.push_str("mut");
394 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
395 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
396 unique_type_id.push_str(inner_type_id.as_slice());
398 ty::ty_rptr(_, ty::mt { ty: inner_type, mutbl }) => {
399 unique_type_id.push_char('&');
400 if mutbl == ast::MutMutable {
401 unique_type_id.push_str("mut");
404 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
405 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
406 unique_type_id.push_str(inner_type_id.as_slice());
408 ty::ty_vec(inner_type, optional_length) => {
409 match optional_length {
411 unique_type_id.push_str(format!("[{}]", len).as_slice());
414 unique_type_id.push_str("[]");
418 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
419 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
420 unique_type_id.push_str(inner_type_id.as_slice());
422 ty::ty_trait(ref trait_data) => {
423 unique_type_id.push_str("trait ");
425 from_def_id_and_substs(self,
429 &mut unique_type_id);
431 ty::ty_bare_fn(ty::BareFnTy{ fn_style, abi, ref sig } ) => {
432 if fn_style == ast::UnsafeFn {
433 unique_type_id.push_str("unsafe ");
436 unique_type_id.push_str(abi.name());
438 unique_type_id.push_str(" fn(");
440 for ¶meter_type in sig.inputs.iter() {
441 let parameter_type_id =
442 self.get_unique_type_id_of_type(cx, parameter_type);
443 let parameter_type_id =
444 self.get_unique_type_id_as_string(parameter_type_id);
445 unique_type_id.push_str(parameter_type_id.as_slice());
446 unique_type_id.push_char(',');
450 unique_type_id.push_str("...");
453 unique_type_id.push_str(")->");
454 let return_type_id = self.get_unique_type_id_of_type(cx, sig.output);
455 let return_type_id = self.get_unique_type_id_as_string(return_type_id);
456 unique_type_id.push_str(return_type_id.as_slice());
458 ty::ty_closure(box ty::ClosureTy { fn_style,
464 if fn_style == ast::UnsafeFn {
465 unique_type_id.push_str("unsafe ");
468 if onceness == ast::Once {
469 unique_type_id.push_str("once ");
473 ty::UniqTraitStore => unique_type_id.push_str("~|"),
474 ty::RegionTraitStore(_, ast::MutMutable) => {
475 unique_type_id.push_str("&mut|")
477 ty::RegionTraitStore(_, ast::MutImmutable) => {
478 unique_type_id.push_str("&|")
482 for ¶meter_type in sig.inputs.iter() {
483 let parameter_type_id =
484 self.get_unique_type_id_of_type(cx, parameter_type);
485 let parameter_type_id =
486 self.get_unique_type_id_as_string(parameter_type_id);
487 unique_type_id.push_str(parameter_type_id.as_slice());
488 unique_type_id.push_char(',');
492 unique_type_id.push_str("...");
495 unique_type_id.push_str("|->");
497 let return_type_id = self.get_unique_type_id_of_type(cx, sig.output);
498 let return_type_id = self.get_unique_type_id_as_string(return_type_id);
499 unique_type_id.push_str(return_type_id.as_slice());
501 unique_type_id.push_char(':');
503 for bound in bounds.builtin_bounds.iter() {
505 ty::BoundSend => unique_type_id.push_str("Send"),
506 ty::BoundSized => unique_type_id.push_str("Sized"),
507 ty::BoundCopy => unique_type_id.push_str("Copy"),
508 ty::BoundSync => unique_type_id.push_str("Sync"),
510 unique_type_id.push_char('+');
514 cx.sess().bug(format!("get_unique_type_id_of_type() - unexpected type: {}, {:?}",
515 ppaux::ty_to_string(cx.tcx(), type_).as_slice(),
516 ty::get(type_).sty).as_slice())
520 unique_type_id.push_char('}');
522 // Trim to size before storing permanently
523 unique_type_id.shrink_to_fit();
525 let key = self.unique_id_interner.intern(Rc::new(unique_type_id));
526 self.type_to_unique_id.insert(ty::type_id(type_), UniqueTypeId(key));
528 return UniqueTypeId(key);
530 fn from_def_id_and_substs(type_map: &mut TypeMap,
533 substs: &subst::Substs,
534 output: &mut String) {
535 use std::num::ToStrRadix;
537 // First, find out the 'real' def_id of the type. Items inlined from
538 // other crates have to be mapped back to their source.
539 let source_def_id = if def_id.krate == ast::LOCAL_CRATE {
540 match cx.external_srcs().borrow().find_copy(&def_id.node) {
541 Some(source_def_id) => {
542 // The given def_id identifies the inlined copy of a
543 // type definition, let's take the source of the copy.
552 // Get the crate hash as first part of the identifier.
553 let crate_hash = if source_def_id.krate == ast::LOCAL_CRATE {
554 cx.link_meta().crate_hash.clone()
556 cx.sess().cstore.get_crate_hash(source_def_id.krate)
559 output.push_str(crate_hash.as_str());
560 output.push_str("/");
561 output.push_str(def_id.node.to_str_radix(16).as_slice());
563 // Maybe check that there is no self type here.
565 let tps = substs.types.get_slice(subst::TypeSpace);
567 output.push_char('<');
569 for &type_parameter in tps.iter() {
571 type_map.get_unique_type_id_of_type(cx, type_parameter);
573 type_map.get_unique_type_id_as_string(param_type_id);
574 output.push_str(param_type_id.as_slice());
575 output.push_char(',');
578 output.push_char('>');
583 // Get the UniqueTypeId for an enum variant. Enum variants are not really
584 // types of their own, so they need special handling. We still need a
585 // UniqueTypeId for them, since to debuginfo they *are* real types.
586 fn get_unique_type_id_of_enum_variant(&mut self,
591 let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
592 let enum_variant_type_id = format!("{}::{}",
593 self.get_unique_type_id_as_string(enum_type_id)
596 let interner_key = self.unique_id_interner.intern(Rc::new(enum_variant_type_id));
597 UniqueTypeId(interner_key)
600 fn get_unique_type_id_of_gc_box(&mut self,
604 let element_type_id = self.get_unique_type_id_of_type(cx, element_type);
605 let gc_box_type_id = format!("{{GC_BOX<{}>}}",
606 self.get_unique_type_id_as_string(element_type_id)
608 let interner_key = self.unique_id_interner.intern(Rc::new(gc_box_type_id));
609 UniqueTypeId(interner_key)
613 // Returns from the enclosing function if the type metadata with the given
614 // unique id can be found in the type map
615 macro_rules! return_if_metadata_created_in_meantime(
616 ($cx: expr, $unique_type_id: expr) => (
617 match debug_context($cx).type_map
619 .find_metadata_for_unique_id($unique_type_id) {
620 Some(metadata) => return MetadataCreationResult::new(metadata, true),
621 None => { /* proceed normally */ }
627 /// A context object for maintaining all state needed by the debuginfo module.
628 pub struct CrateDebugContext {
629 llcontext: ContextRef,
630 builder: DIBuilderRef,
631 current_debug_location: Cell<DebugLocation>,
632 created_files: RefCell<HashMap<String, DIFile>>,
633 created_enum_disr_types: RefCell<HashMap<ast::DefId, DIType>>,
635 type_map: RefCell<TypeMap>,
636 namespace_map: RefCell<HashMap<Vec<ast::Name>, Rc<NamespaceTreeNode>>>,
638 // This collection is used to assert that composite types (structs, enums,
639 // ...) have their members only set once:
640 composite_types_completed: RefCell<HashSet<DIType>>,
643 impl CrateDebugContext {
644 pub fn new(llmod: ModuleRef) -> CrateDebugContext {
645 debug!("CrateDebugContext::new");
646 let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) };
647 // DIBuilder inherits context from the module, so we'd better use the same one
648 let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
649 return CrateDebugContext {
650 llcontext: llcontext,
652 current_debug_location: Cell::new(UnknownLocation),
653 created_files: RefCell::new(HashMap::new()),
654 created_enum_disr_types: RefCell::new(HashMap::new()),
655 type_map: RefCell::new(TypeMap::new()),
656 namespace_map: RefCell::new(HashMap::new()),
657 composite_types_completed: RefCell::new(HashSet::new()),
662 pub struct FunctionDebugContext {
663 repr: FunctionDebugContextRepr,
666 enum FunctionDebugContextRepr {
667 DebugInfo(Box<FunctionDebugContextData>),
669 FunctionWithoutDebugInfo,
672 impl FunctionDebugContext {
673 fn get_ref<'a>(&'a self,
676 -> &'a FunctionDebugContextData {
678 DebugInfo(box ref data) => data,
679 DebugInfoDisabled => {
680 cx.sess().span_bug(span,
681 FunctionDebugContext::debuginfo_disabled_message());
683 FunctionWithoutDebugInfo => {
684 cx.sess().span_bug(span,
685 FunctionDebugContext::should_be_ignored_message());
690 fn debuginfo_disabled_message() -> &'static str {
691 "debuginfo: Error trying to access FunctionDebugContext although debug info is disabled!"
694 fn should_be_ignored_message() -> &'static str {
695 "debuginfo: Error trying to access FunctionDebugContext for function that should be \
696 ignored by debug info!"
700 struct FunctionDebugContextData {
701 scope_map: RefCell<HashMap<ast::NodeId, DIScope>>,
702 fn_metadata: DISubprogram,
703 argument_counter: Cell<uint>,
704 source_locations_enabled: Cell<bool>,
707 enum VariableAccess<'a> {
708 // The llptr given is an alloca containing the variable's value
709 DirectVariable { alloca: ValueRef },
710 // The llptr given is an alloca containing the start of some pointer chain
711 // leading to the variable's content.
712 IndirectVariable { alloca: ValueRef, address_operations: &'a [ValueRef] }
716 ArgumentVariable(uint /*index*/),
721 /// Create any deferred debug metadata nodes
722 pub fn finalize(cx: &CrateContext) {
723 if cx.dbg_cx().is_none() {
728 compile_unit_metadata(cx);
730 llvm::LLVMDIBuilderFinalize(DIB(cx));
731 llvm::LLVMDIBuilderDispose(DIB(cx));
732 // Debuginfo generation in LLVM by default uses a higher
733 // version of dwarf than OS X currently understands. We can
734 // instruct LLVM to emit an older version of dwarf, however,
735 // for OS X to understand. For more info see #11352
736 // This can be overridden using --llvm-opts -dwarf-version,N.
737 if cx.sess().targ_cfg.os == abi::OsMacos ||
738 cx.sess().targ_cfg.os == abi::OsiOS {
739 "Dwarf Version".with_c_str(
740 |s| llvm::LLVMRustAddModuleFlag(cx.llmod(), s, 2));
743 // Prevent bitcode readers from deleting the debug info.
744 "Debug Info Version".with_c_str(
745 |s| llvm::LLVMRustAddModuleFlag(cx.llmod(), s,
746 llvm::LLVMRustDebugMetadataVersion));
750 /// Creates debug information for the given global variable.
752 /// Adds the created metadata nodes directly to the crate's IR.
753 pub fn create_global_var_metadata(cx: &CrateContext,
754 node_id: ast::NodeId,
756 if cx.dbg_cx().is_none() {
760 // Don't create debuginfo for globals inlined from other crates. The other
761 // crate should already contain debuginfo for it. More importantly, the
762 // global might not even exist in un-inlined form anywhere which would lead
763 // to a linker errors.
764 if cx.external_srcs().borrow().contains_key(&node_id) {
768 let var_item = cx.tcx().map.get(node_id);
770 let (ident, span) = match var_item {
771 ast_map::NodeItem(item) => {
773 ast::ItemStatic(..) => (item.ident, item.span),
777 format!("debuginfo::\
778 create_global_var_metadata() -
779 Captured var-id refers to \
780 unexpected ast_item variant: {:?}",
781 var_item).as_slice())
785 _ => cx.sess().bug(format!("debuginfo::create_global_var_metadata() \
786 - Captured var-id refers to unexpected \
787 ast_map variant: {:?}",
788 var_item).as_slice())
791 let (file_metadata, line_number) = if span != codemap::DUMMY_SP {
792 let loc = span_start(cx, span);
793 (file_metadata(cx, loc.file.name.as_slice()), loc.line as c_uint)
795 (UNKNOWN_FILE_METADATA, UNKNOWN_LINE_NUMBER)
798 let is_local_to_unit = is_node_local_to_unit(cx, node_id);
799 let variable_type = ty::node_id_to_type(cx.tcx(), node_id);
800 let type_metadata = type_metadata(cx, variable_type, span);
801 let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
802 let var_name = token::get_ident(ident).get().to_string();
804 namespace_node.mangled_name_of_contained_item(var_name.as_slice());
805 let var_scope = namespace_node.scope;
807 var_name.as_slice().with_c_str(|var_name| {
808 linkage_name.as_slice().with_c_str(|linkage_name| {
810 llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
825 /// Creates debug information for the given local variable.
827 /// Adds the created metadata nodes directly to the crate's IR.
828 pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) {
829 if fn_should_be_ignored(bcx.fcx) {
834 let def_map = &cx.tcx().def_map;
836 pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path1| {
837 let var_ident = path1.node;
839 let datum = match bcx.fcx.lllocals.borrow().find_copy(&node_id) {
840 Some(datum) => datum,
842 bcx.sess().span_bug(span,
843 format!("no entry in lllocals table for {:?}",
844 node_id).as_slice());
848 let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
854 DirectVariable { alloca: datum.val },
860 /// Creates debug information for a variable captured in a closure.
862 /// Adds the created metadata nodes directly to the crate's IR.
863 pub fn create_captured_var_metadata(bcx: Block,
864 node_id: ast::NodeId,
865 env_data_type: ty::t,
866 env_pointer: ValueRef,
868 closure_store: ty::TraitStore,
870 if fn_should_be_ignored(bcx.fcx) {
876 let ast_item = cx.tcx().map.find(node_id);
878 let variable_ident = match ast_item {
880 cx.sess().span_bug(span, "debuginfo::create_captured_var_metadata: node not found");
882 Some(ast_map::NodeLocal(pat)) | Some(ast_map::NodeArg(pat)) => {
884 ast::PatIdent(_, ref path1, _) => {
891 "debuginfo::create_captured_var_metadata() - \
892 Captured var-id refers to unexpected \
893 ast_map variant: {:?}",
894 ast_item).as_slice());
901 format!("debuginfo::create_captured_var_metadata() - \
902 Captured var-id refers to unexpected \
903 ast_map variant: {:?}",
904 ast_item).as_slice());
908 let variable_type = node_id_type(bcx, node_id);
909 let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata;
911 let llvm_env_data_type = type_of::type_of(cx, env_data_type);
912 let byte_offset_of_var_in_env = machine::llelement_offset(cx,
916 let address_operations = unsafe {
917 [llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref()),
918 llvm::LLVMDIBuilderCreateOpPlus(Type::i64(cx).to_ref()),
919 C_i64(cx, byte_offset_of_var_in_env as i64),
920 llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref())]
923 let address_op_count = match closure_store {
924 ty::RegionTraitStore(..) => {
925 address_operations.len()
927 ty::UniqTraitStore => {
928 address_operations.len() - 1
932 let variable_access = IndirectVariable {
934 address_operations: address_operations.slice_to(address_op_count)
946 /// Creates debug information for a local variable introduced in the head of a
947 /// match-statement arm.
949 /// Adds the created metadata nodes directly to the crate's IR.
950 pub fn create_match_binding_metadata(bcx: Block,
951 variable_ident: ast::Ident,
952 binding: BindingInfo) {
953 if fn_should_be_ignored(bcx.fcx) {
957 let scope_metadata = scope_metadata(bcx.fcx, binding.id, binding.span);
959 [llvm::LLVMDIBuilderCreateOpDeref(bcx.ccx().int_type().to_ref())]
961 // Regardless of the actual type (`T`) we're always passed the stack slot (alloca)
962 // for the binding. For ByRef bindings that's a `T*` but for ByMove bindings we
963 // actually have `T**`. So to get the actual variable we need to dereference once
964 // more. For ByCopy we just use the stack slot we created for the binding.
965 let var_type = match binding.trmode {
966 TrByCopy(llbinding) => DirectVariable {
969 TrByMove => IndirectVariable {
970 alloca: binding.llmatch,
971 address_operations: aops
973 TrByRef => DirectVariable {
974 alloca: binding.llmatch
987 /// Creates debug information for the given function argument.
989 /// Adds the created metadata nodes directly to the crate's IR.
990 pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) {
991 if fn_should_be_ignored(bcx.fcx) {
998 let def_map = &cx.tcx().def_map;
999 let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata;
1001 pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path1| {
1002 let llarg = match bcx.fcx.lllocals.borrow().find_copy(&node_id) {
1005 bcx.sess().span_bug(span,
1006 format!("no entry in lllocals table for {:?}",
1007 node_id).as_slice());
1011 if unsafe { llvm::LLVMIsAAllocaInst(llarg.val) } == ptr::null_mut() {
1012 cx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \
1013 Referenced variable location is not an alloca!");
1016 let argument_index = {
1017 let counter = &fcx.debug_context.get_ref(cx, span).argument_counter;
1018 let argument_index = counter.get();
1019 counter.set(argument_index + 1);
1027 DirectVariable { alloca: llarg.val },
1028 ArgumentVariable(argument_index),
1033 pub fn get_cleanup_debug_loc_for_ast_node(node_id: ast::NodeId,
1037 // A debug location needs two things:
1038 // (1) A span (of which only the beginning will actually be used)
1039 // (2) An AST node-id which will be used to look up the lexical scope
1040 // for the location in the functions scope-map
1042 // This function will calculate the debug location for compiler-generated
1043 // cleanup calls that are executed when control-flow leaves the
1044 // scope identified by `node_id`.
1046 // For everything but block-like things we can simply take id and span of
1047 // the given expression, meaning that from a debugger's view cleanup code is
1048 // executed at the same source location as the statement/expr itself.
1050 // Blocks are a special case. Here we want the cleanup to be linked to the
1051 // closing curly brace of the block. The *scope* the cleanup is executed in
1052 // is up to debate: It could either still be *within* the block being
1053 // cleaned up, meaning that locals from the block are still visible in the
1055 // Or it could be in the scope that the block is contained in, so any locals
1056 // from within the block are already considered out-of-scope and thus not
1057 // accessible in the debugger anymore.
1059 // The current implementation opts for the second option: cleanup of a block
1060 // already happens in the parent scope of the block. The main reason for
1061 // this decision is that scoping becomes controlflow dependent when variable
1062 // shadowing is involved and it's impossible to decide statically which
1063 // scope is actually left when the cleanup code is executed.
1064 // In practice it shouldn't make much of a difference.
1066 let cleanup_span = if is_block {
1068 lo: node_span.hi - codemap::BytePos(1), // closing brace should always be 1 byte...
1070 expn_id: node_span.expn_id
1082 /// Sets the current debug location at the beginning of the span.
1084 /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). The node_id
1085 /// parameter is used to reliably find the correct visibility scope for the code
1087 pub fn set_source_location(fcx: &FunctionContext,
1088 node_id: ast::NodeId,
1090 match fcx.debug_context.repr {
1091 DebugInfoDisabled => return,
1092 FunctionWithoutDebugInfo => {
1093 set_debug_location(fcx.ccx, UnknownLocation);
1096 DebugInfo(box ref function_debug_context) => {
1099 debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span));
1101 if function_debug_context.source_locations_enabled.get() {
1102 let loc = span_start(cx, span);
1103 let scope = scope_metadata(fcx, node_id, span);
1105 set_debug_location(cx, DebugLocation::new(scope,
1107 loc.col.to_uint()));
1109 set_debug_location(cx, UnknownLocation);
1115 /// Clears the current debug location.
1117 /// Instructions generated hereafter won't be assigned a source location.
1118 pub fn clear_source_location(fcx: &FunctionContext) {
1119 if fn_should_be_ignored(fcx) {
1123 set_debug_location(fcx.ccx, UnknownLocation);
1126 /// Enables emitting source locations for the given functions.
1128 /// Since we don't want source locations to be emitted for the function prelude,
1129 /// they are disabled when beginning to translate a new function. This functions
1130 /// switches source location emitting on and must therefore be called before the
1131 /// first real statement/expression of the function is translated.
1132 pub fn start_emitting_source_locations(fcx: &FunctionContext) {
1133 match fcx.debug_context.repr {
1134 DebugInfo(box ref data) => {
1135 data.source_locations_enabled.set(true)
1137 _ => { /* safe to ignore */ }
1141 /// Creates the function-specific debug context.
1143 /// Returns the FunctionDebugContext for the function which holds state needed
1144 /// for debug info creation. The function may also return another variant of the
1145 /// FunctionDebugContext enum which indicates why no debuginfo should be created
1146 /// for the function.
1147 pub fn create_function_debug_context(cx: &CrateContext,
1148 fn_ast_id: ast::NodeId,
1149 param_substs: ¶m_substs,
1150 llfn: ValueRef) -> FunctionDebugContext {
1151 if cx.sess().opts.debuginfo == NoDebugInfo {
1152 return FunctionDebugContext { repr: DebugInfoDisabled };
1155 // Clear the debug location so we don't assign them in the function prelude.
1156 // Do this here already, in case we do an early exit from this function.
1157 set_debug_location(cx, UnknownLocation);
1159 if fn_ast_id == ast::DUMMY_NODE_ID {
1160 // This is a function not linked to any source location, so don't
1161 // generate debuginfo for it.
1162 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1165 let empty_generics = ast_util::empty_generics();
1167 let fnitem = cx.tcx().map.get(fn_ast_id);
1169 let (ident, fn_decl, generics, top_level_block, span, has_path) = match fnitem {
1170 ast_map::NodeItem(ref item) => {
1171 if contains_nodebug_attribute(item.attrs.as_slice()) {
1172 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1176 ast::ItemFn(ref fn_decl, _, _, ref generics, ref top_level_block) => {
1177 (item.ident, &**fn_decl, generics, &**top_level_block, item.span, true)
1180 cx.sess().span_bug(item.span,
1181 "create_function_debug_context: item bound to non-function");
1185 ast_map::NodeImplItem(ref item) => {
1187 ast::MethodImplItem(ref method) => {
1188 if contains_nodebug_attribute(method.attrs.as_slice()) {
1189 return FunctionDebugContext {
1190 repr: FunctionWithoutDebugInfo
1195 method.pe_fn_decl(),
1196 method.pe_generics(),
1201 ast::TypeImplItem(ref typedef) => {
1202 cx.sess().span_bug(typedef.span,
1203 "create_function_debug_context() \
1204 called on associated type?!")
1208 ast_map::NodeExpr(ref expr) => {
1210 ast::ExprFnBlock(_, ref fn_decl, ref top_level_block) |
1211 ast::ExprProc(ref fn_decl, ref top_level_block) |
1212 ast::ExprUnboxedFn(_, _, ref fn_decl, ref top_level_block) => {
1213 let name = format!("fn{}", token::gensym("fn"));
1214 let name = token::str_to_ident(name.as_slice());
1216 // This is not quite right. It should actually inherit
1217 // the generics of the enclosing function.
1221 // Don't try to lookup the item path:
1224 _ => cx.sess().span_bug(expr.span,
1225 "create_function_debug_context: expected an expr_fn_block here")
1228 ast_map::NodeTraitItem(ref trait_method) => {
1229 match **trait_method {
1230 ast::ProvidedMethod(ref method) => {
1231 if contains_nodebug_attribute(method.attrs.as_slice()) {
1232 return FunctionDebugContext {
1233 repr: FunctionWithoutDebugInfo
1238 method.pe_fn_decl(),
1239 method.pe_generics(),
1246 .bug(format!("create_function_debug_context: \
1247 unexpected sort of node: {:?}",
1252 ast_map::NodeForeignItem(..) |
1253 ast_map::NodeVariant(..) |
1254 ast_map::NodeStructCtor(..) => {
1255 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1257 _ => cx.sess().bug(format!("create_function_debug_context: \
1258 unexpected sort of node: {:?}",
1262 // This can be the case for functions inlined from another crate
1263 if span == codemap::DUMMY_SP {
1264 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1267 let loc = span_start(cx, span);
1268 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
1270 let function_type_metadata = unsafe {
1271 let fn_signature = get_function_signature(cx,
1276 llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
1279 // Get_template_parameters() will append a `<...>` clause to the function
1280 // name if necessary.
1281 let mut function_name = String::from_str(token::get_ident(ident).get());
1282 let template_parameters = get_template_parameters(cx,
1286 &mut function_name);
1288 // There is no ast_map::Path for ast::ExprFnBlock-type functions. For now,
1289 // just don't put them into a namespace. In the future this could be improved
1290 // somehow (storing a path in the ast_map, or construct a path using the
1291 // enclosing function).
1292 let (linkage_name, containing_scope) = if has_path {
1293 let namespace_node = namespace_for_item(cx, ast_util::local_def(fn_ast_id));
1294 let linkage_name = namespace_node.mangled_name_of_contained_item(
1295 function_name.as_slice());
1296 let containing_scope = namespace_node.scope;
1297 (linkage_name, containing_scope)
1299 (function_name.as_slice().to_string(), file_metadata)
1302 // Clang sets this parameter to the opening brace of the function's block,
1303 // so let's do this too.
1304 let scope_line = span_start(cx, top_level_block.span).line;
1306 let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id);
1308 let fn_metadata = function_name.as_slice().with_c_str(|function_name| {
1309 linkage_name.as_slice().with_c_str(|linkage_name| {
1311 llvm::LLVMDIBuilderCreateFunction(
1318 function_type_metadata,
1321 scope_line as c_uint,
1322 FlagPrototyped as c_uint,
1323 cx.sess().opts.optimize != config::No,
1325 template_parameters,
1331 // Initialize fn debug context (including scope map and namespace map)
1332 let fn_debug_context = box FunctionDebugContextData {
1333 scope_map: RefCell::new(HashMap::new()),
1334 fn_metadata: fn_metadata,
1335 argument_counter: Cell::new(1),
1336 source_locations_enabled: Cell::new(false),
1339 populate_scope_map(cx,
1340 fn_decl.inputs.as_slice(),
1344 &mut *fn_debug_context.scope_map.borrow_mut());
1346 return FunctionDebugContext { repr: DebugInfo(fn_debug_context) };
1348 fn get_function_signature(cx: &CrateContext,
1349 fn_ast_id: ast::NodeId,
1350 fn_decl: &ast::FnDecl,
1351 param_substs: ¶m_substs,
1352 error_reporting_span: Span) -> DIArray {
1353 if cx.sess().opts.debuginfo == LimitedDebugInfo {
1354 return create_DIArray(DIB(cx), []);
1357 let mut signature = Vec::with_capacity(fn_decl.inputs.len() + 1);
1359 // Return type -- llvm::DIBuilder wants this at index 0
1360 match fn_decl.output.node {
1362 signature.push(ptr::null_mut());
1365 assert_type_for_node_id(cx, fn_ast_id, error_reporting_span);
1367 let return_type = ty::node_id_to_type(cx.tcx(), fn_ast_id);
1368 let return_type = return_type.substp(cx.tcx(), param_substs);
1369 signature.push(type_metadata(cx, return_type, codemap::DUMMY_SP));
1374 for arg in fn_decl.inputs.iter() {
1375 assert_type_for_node_id(cx, arg.pat.id, arg.pat.span);
1376 let arg_type = ty::node_id_to_type(cx.tcx(), arg.pat.id);
1377 let arg_type = arg_type.substp(cx.tcx(), param_substs);
1378 signature.push(type_metadata(cx, arg_type, codemap::DUMMY_SP));
1381 return create_DIArray(DIB(cx), signature.as_slice());
1384 fn get_template_parameters(cx: &CrateContext,
1385 generics: &ast::Generics,
1386 param_substs: ¶m_substs,
1387 file_metadata: DIFile,
1388 name_to_append_suffix_to: &mut String)
1390 let self_type = param_substs.substs.self_ty();
1392 // Only true for static default methods:
1393 let has_self_type = self_type.is_some();
1395 if !generics.is_type_parameterized() && !has_self_type {
1396 return create_DIArray(DIB(cx), []);
1399 name_to_append_suffix_to.push_char('<');
1401 // The list to be filled with template parameters:
1402 let mut template_params: Vec<DIDescriptor> =
1403 Vec::with_capacity(generics.ty_params.len() + 1);
1407 let actual_self_type = self_type.unwrap();
1408 // Add self type name to <...> clause of function name
1409 let actual_self_type_name = compute_debuginfo_type_name(
1414 name_to_append_suffix_to.push_str(actual_self_type_name.as_slice());
1416 if generics.is_type_parameterized() {
1417 name_to_append_suffix_to.push_str(",");
1420 // Only create type information if full debuginfo is enabled
1421 if cx.sess().opts.debuginfo == FullDebugInfo {
1422 let actual_self_type_metadata = type_metadata(cx,
1426 let ident = special_idents::type_self;
1428 let param_metadata = token::get_ident(ident).get()
1429 .with_c_str(|name| {
1431 llvm::LLVMDIBuilderCreateTemplateTypeParameter(
1435 actual_self_type_metadata,
1442 template_params.push(param_metadata);
1446 // Handle other generic parameters
1447 let actual_types = param_substs.substs.types.get_slice(subst::FnSpace);
1448 for (index, &ast::TyParam{ ident: ident, .. }) in generics.ty_params.iter().enumerate() {
1449 let actual_type = actual_types[index];
1450 // Add actual type name to <...> clause of function name
1451 let actual_type_name = compute_debuginfo_type_name(cx,
1454 name_to_append_suffix_to.push_str(actual_type_name.as_slice());
1456 if index != generics.ty_params.len() - 1 {
1457 name_to_append_suffix_to.push_str(",");
1460 // Again, only create type information if full debuginfo is enabled
1461 if cx.sess().opts.debuginfo == FullDebugInfo {
1462 let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP);
1463 let param_metadata = token::get_ident(ident).get()
1464 .with_c_str(|name| {
1466 llvm::LLVMDIBuilderCreateTemplateTypeParameter(
1470 actual_type_metadata,
1476 template_params.push(param_metadata);
1480 name_to_append_suffix_to.push_char('>');
1482 return create_DIArray(DIB(cx), template_params.as_slice());
1486 //=-----------------------------------------------------------------------------
1487 // Module-Internal debug info creation functions
1488 //=-----------------------------------------------------------------------------
1490 fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
1492 // The is_local_to_unit flag indicates whether a function is local to the
1493 // current compilation unit (i.e. if it is *static* in the C-sense). The
1494 // *reachable* set should provide a good approximation of this, as it
1495 // contains everything that might leak out of the current crate (by being
1496 // externally visible or by being inlined into something externally visible).
1497 // It might better to use the `exported_items` set from `driver::CrateAnalysis`
1498 // in the future, but (atm) this set is not available in the translation pass.
1499 !cx.reachable().contains(&node_id)
1502 #[allow(non_snake_case)]
1503 fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
1505 llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
1509 fn compile_unit_metadata(cx: &CrateContext) {
1510 let work_dir = &cx.sess().working_dir;
1511 let compile_unit_name = match cx.sess().local_crate_source_file {
1512 None => fallback_path(cx),
1513 Some(ref abs_path) => {
1514 if abs_path.is_relative() {
1515 cx.sess().warn("debuginfo: Invalid path to crate's local root source file!");
1518 match abs_path.path_relative_from(work_dir) {
1519 Some(ref p) if p.is_relative() => {
1520 // prepend "./" if necessary
1522 let prefix = &[dotdot[0], ::std::path::SEP_BYTE];
1523 let mut path_bytes = Vec::from_slice(p.as_vec());
1525 if path_bytes.slice_to(2) != prefix &&
1526 path_bytes.slice_to(2) != dotdot {
1527 path_bytes.insert(0, prefix[0]);
1528 path_bytes.insert(1, prefix[1]);
1531 path_bytes.as_slice().to_c_str()
1533 _ => fallback_path(cx)
1539 debug!("compile_unit_metadata: {:?}", compile_unit_name);
1540 let producer = format!("rustc version {}",
1541 (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
1543 let compile_unit_name = compile_unit_name.as_ptr();
1544 work_dir.as_vec().with_c_str(|work_dir| {
1545 producer.with_c_str(|producer| {
1546 "".with_c_str(|flags| {
1547 "".with_c_str(|split_name| {
1549 llvm::LLVMDIBuilderCreateCompileUnit(
1550 debug_context(cx).builder,
1555 cx.sess().opts.optimize != config::No,
1565 fn fallback_path(cx: &CrateContext) -> CString {
1566 cx.link_meta().crate_name.as_slice().to_c_str()
1570 fn declare_local(bcx: Block,
1571 variable_ident: ast::Ident,
1572 variable_type: ty::t,
1573 scope_metadata: DIScope,
1574 variable_access: VariableAccess,
1575 variable_kind: VariableKind,
1577 let cx: &CrateContext = bcx.ccx();
1579 let filename = span_start(cx, span).file.name.clone();
1580 let file_metadata = file_metadata(cx, filename.as_slice());
1582 let name = token::get_ident(variable_ident);
1583 let loc = span_start(cx, span);
1584 let type_metadata = type_metadata(cx, variable_type, span);
1586 let (argument_index, dwarf_tag) = match variable_kind {
1587 ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
1589 CapturedVariable => (0, DW_TAG_auto_variable)
1592 let (var_alloca, var_metadata) = name.get().with_c_str(|name| {
1593 match variable_access {
1594 DirectVariable { alloca } => (
1597 llvm::LLVMDIBuilderCreateLocalVariable(
1605 cx.sess().opts.optimize != config::No,
1610 IndirectVariable { alloca, address_operations } => (
1613 llvm::LLVMDIBuilderCreateComplexVariable(
1621 address_operations.as_ptr(),
1622 address_operations.len() as c_uint,
1629 set_debug_location(cx, DebugLocation::new(scope_metadata,
1631 loc.col.to_uint()));
1633 let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
1639 llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
1642 match variable_kind {
1643 ArgumentVariable(_) | CapturedVariable => {
1647 .source_locations_enabled
1649 set_debug_location(cx, UnknownLocation);
1651 _ => { /* nothing to do */ }
1655 fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
1656 match debug_context(cx).created_files.borrow().find_equiv(&full_path) {
1657 Some(file_metadata) => return *file_metadata,
1661 debug!("file_metadata: {}", full_path);
1663 // FIXME (#9639): This needs to handle non-utf8 paths
1664 let work_dir = cx.sess().working_dir.as_str().unwrap();
1666 if full_path.starts_with(work_dir) {
1667 full_path.slice(work_dir.len() + 1u, full_path.len())
1673 file_name.with_c_str(|file_name| {
1674 work_dir.with_c_str(|work_dir| {
1676 llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir)
1681 let mut created_files = debug_context(cx).created_files.borrow_mut();
1682 created_files.insert(full_path.to_string(), file_metadata);
1683 return file_metadata;
1686 /// Finds the scope metadata node for the given AST node.
1687 fn scope_metadata(fcx: &FunctionContext,
1688 node_id: ast::NodeId,
1689 error_reporting_span: Span)
1691 let scope_map = &fcx.debug_context
1692 .get_ref(fcx.ccx, error_reporting_span)
1694 match scope_map.borrow().find_copy(&node_id) {
1695 Some(scope_metadata) => scope_metadata,
1697 let node = fcx.ccx.tcx().map.get(node_id);
1699 fcx.ccx.sess().span_bug(error_reporting_span,
1700 format!("debuginfo: Could not find scope info for node {:?}",
1706 fn basic_type_metadata(cx: &CrateContext, t: ty::t) -> DIType {
1708 debug!("basic_type_metadata: {:?}", ty::get(t));
1710 let (name, encoding) = match ty::get(t).sty {
1711 ty::ty_nil => ("()".to_string(), DW_ATE_unsigned),
1712 ty::ty_bot => ("!".to_string(), DW_ATE_unsigned),
1713 ty::ty_bool => ("bool".to_string(), DW_ATE_boolean),
1714 ty::ty_char => ("char".to_string(), DW_ATE_unsigned_char),
1715 ty::ty_int(int_ty) => match int_ty {
1716 ast::TyI => ("int".to_string(), DW_ATE_signed),
1717 ast::TyI8 => ("i8".to_string(), DW_ATE_signed),
1718 ast::TyI16 => ("i16".to_string(), DW_ATE_signed),
1719 ast::TyI32 => ("i32".to_string(), DW_ATE_signed),
1720 ast::TyI64 => ("i64".to_string(), DW_ATE_signed)
1722 ty::ty_uint(uint_ty) => match uint_ty {
1723 ast::TyU => ("uint".to_string(), DW_ATE_unsigned),
1724 ast::TyU8 => ("u8".to_string(), DW_ATE_unsigned),
1725 ast::TyU16 => ("u16".to_string(), DW_ATE_unsigned),
1726 ast::TyU32 => ("u32".to_string(), DW_ATE_unsigned),
1727 ast::TyU64 => ("u64".to_string(), DW_ATE_unsigned)
1729 ty::ty_float(float_ty) => match float_ty {
1730 ast::TyF32 => ("f32".to_string(), DW_ATE_float),
1731 ast::TyF64 => ("f64".to_string(), DW_ATE_float),
1733 _ => cx.sess().bug("debuginfo::basic_type_metadata - t is invalid type")
1736 let llvm_type = type_of::type_of(cx, t);
1737 let (size, align) = size_and_align_of(cx, llvm_type);
1738 let ty_metadata = name.with_c_str(|name| {
1740 llvm::LLVMDIBuilderCreateBasicType(
1743 bytes_to_bits(size),
1744 bytes_to_bits(align),
1752 fn pointer_type_metadata(cx: &CrateContext,
1753 pointer_type: ty::t,
1754 pointee_type_metadata: DIType)
1756 let pointer_llvm_type = type_of::type_of(cx, pointer_type);
1757 let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
1758 let name = compute_debuginfo_type_name(cx, pointer_type, false);
1759 let ptr_metadata = name.as_slice().with_c_str(|name| {
1761 llvm::LLVMDIBuilderCreatePointerType(
1763 pointee_type_metadata,
1764 bytes_to_bits(pointer_size),
1765 bytes_to_bits(pointer_align),
1769 return ptr_metadata;
1772 //=-----------------------------------------------------------------------------
1773 // Common facilities for record-like types (structs, enums, tuples)
1774 //=-----------------------------------------------------------------------------
1777 FixedMemberOffset { bytes: uint },
1778 // For ComputedMemberOffset, the offset is read from the llvm type definition
1779 ComputedMemberOffset
1782 // Description of a type member, which can either be a regular field (as in
1783 // structs or tuples) or an enum variant
1784 struct MemberDescription {
1787 type_metadata: DIType,
1788 offset: MemberOffset,
1792 // A factory for MemberDescriptions. It produces a list of member descriptions
1793 // for some record-like type. MemberDescriptionFactories are used to defer the
1794 // creation of type member descriptions in order to break cycles arising from
1795 // recursive type definitions.
1796 enum MemberDescriptionFactory {
1797 StructMDF(StructMemberDescriptionFactory),
1798 TupleMDF(TupleMemberDescriptionFactory),
1799 EnumMDF(EnumMemberDescriptionFactory),
1800 VariantMDF(VariantMemberDescriptionFactory)
1803 impl MemberDescriptionFactory {
1804 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
1806 StructMDF(ref this) => {
1807 this.create_member_descriptions(cx)
1809 TupleMDF(ref this) => {
1810 this.create_member_descriptions(cx)
1812 EnumMDF(ref this) => {
1813 this.create_member_descriptions(cx)
1815 VariantMDF(ref this) => {
1816 this.create_member_descriptions(cx)
1822 // A description of some recursive type. It can either be already finished (as
1823 // with FinalMetadata) or it is not yet finished, but contains all information
1824 // needed to generate the missing parts of the description. See the documentation
1825 // section on Recursive Types at the top of this file for more information.
1826 enum RecursiveTypeDescription {
1827 UnfinishedMetadata {
1828 unfinished_type: ty::t,
1829 unique_type_id: UniqueTypeId,
1830 metadata_stub: DICompositeType,
1832 member_description_factory: MemberDescriptionFactory,
1834 FinalMetadata(DICompositeType)
1837 fn create_and_register_recursive_type_forward_declaration(
1839 unfinished_type: ty::t,
1840 unique_type_id: UniqueTypeId,
1841 metadata_stub: DICompositeType,
1843 member_description_factory: MemberDescriptionFactory)
1844 -> RecursiveTypeDescription {
1846 // Insert the stub into the TypeMap in order to allow for recursive references
1847 let mut type_map = debug_context(cx).type_map.borrow_mut();
1848 type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata_stub);
1849 type_map.register_type_with_metadata(cx, unfinished_type, metadata_stub);
1851 UnfinishedMetadata {
1852 unfinished_type: unfinished_type,
1853 unique_type_id: unique_type_id,
1854 metadata_stub: metadata_stub,
1855 llvm_type: llvm_type,
1856 member_description_factory: member_description_factory,
1860 impl RecursiveTypeDescription {
1861 // Finishes up the description of the type in question (mostly by providing
1862 // descriptions of the fields of the given type) and returns the final type metadata.
1863 fn finalize(&self, cx: &CrateContext) -> MetadataCreationResult {
1865 FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
1866 UnfinishedMetadata {
1871 ref member_description_factory,
1874 // Make sure that we have a forward declaration of the type in
1875 // the TypeMap so that recursive references are possible. This
1876 // will always be the case if the RecursiveTypeDescription has
1877 // been properly created through the
1878 // create_and_register_recursive_type_forward_declaration() function.
1880 let type_map = debug_context(cx).type_map.borrow();
1881 if type_map.find_metadata_for_unique_id(unique_type_id).is_none() ||
1882 type_map.find_metadata_for_type(unfinished_type).is_none() {
1883 cx.sess().bug(format!("Forward declaration of potentially recursive type \
1884 '{}' was not found in TypeMap!",
1885 ppaux::ty_to_string(cx.tcx(), unfinished_type))
1890 // ... then create the member descriptions ...
1891 let member_descriptions =
1892 member_description_factory.create_member_descriptions(cx);
1894 // ... and attach them to the stub to complete it.
1895 set_members_of_composite_type(cx,
1898 member_descriptions.as_slice());
1899 return MetadataCreationResult::new(metadata_stub, true);
1906 //=-----------------------------------------------------------------------------
1908 //=-----------------------------------------------------------------------------
1910 // Creates MemberDescriptions for the fields of a struct
1911 struct StructMemberDescriptionFactory {
1912 fields: Vec<ty::field>,
1917 impl StructMemberDescriptionFactory {
1918 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
1919 if self.fields.len() == 0 {
1923 let field_size = if self.is_simd {
1924 machine::llsize_of_alloc(cx, type_of::type_of(cx, self.fields.get(0).mt.ty)) as uint
1929 self.fields.iter().enumerate().map(|(i, field)| {
1930 let name = if field.ident.name == special_idents::unnamed_field.name {
1933 token::get_ident(field.ident).get().to_string()
1936 let offset = if self.is_simd {
1937 assert!(field_size != 0xdeadbeef);
1938 FixedMemberOffset { bytes: i * field_size }
1940 ComputedMemberOffset
1945 llvm_type: type_of::type_of(cx, field.mt.ty),
1946 type_metadata: type_metadata(cx, field.mt.ty, self.span),
1955 fn prepare_struct_metadata(cx: &CrateContext,
1958 substs: &subst::Substs,
1959 unique_type_id: UniqueTypeId,
1961 -> RecursiveTypeDescription {
1962 let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
1963 let struct_llvm_type = type_of::type_of(cx, struct_type);
1965 let (containing_scope, _) = get_namespace_and_span_for_item(cx, def_id);
1967 let struct_metadata_stub = create_struct_stub(cx,
1969 struct_name.as_slice(),
1973 let fields = ty::struct_fields(cx.tcx(), def_id, substs);
1975 create_and_register_recursive_type_forward_declaration(
1979 struct_metadata_stub,
1981 StructMDF(StructMemberDescriptionFactory {
1983 is_simd: ty::type_is_simd(cx.tcx(), struct_type),
1990 //=-----------------------------------------------------------------------------
1992 //=-----------------------------------------------------------------------------
1994 // Creates MemberDescriptions for the fields of a tuple
1995 struct TupleMemberDescriptionFactory {
1996 component_types: Vec<ty::t> ,
2000 impl TupleMemberDescriptionFactory {
2001 fn create_member_descriptions(&self, cx: &CrateContext)
2002 -> Vec<MemberDescription> {
2003 self.component_types.iter().map(|&component_type| {
2005 name: "".to_string(),
2006 llvm_type: type_of::type_of(cx, component_type),
2007 type_metadata: type_metadata(cx, component_type, self.span),
2008 offset: ComputedMemberOffset,
2015 fn prepare_tuple_metadata(cx: &CrateContext,
2017 component_types: &[ty::t],
2018 unique_type_id: UniqueTypeId,
2020 -> RecursiveTypeDescription {
2021 let tuple_name = compute_debuginfo_type_name(cx, tuple_type, false);
2022 let tuple_llvm_type = type_of::type_of(cx, tuple_type);
2024 create_and_register_recursive_type_forward_declaration(
2028 create_struct_stub(cx,
2030 tuple_name.as_slice(),
2032 UNKNOWN_SCOPE_METADATA),
2034 TupleMDF(TupleMemberDescriptionFactory {
2035 component_types: Vec::from_slice(component_types),
2042 //=-----------------------------------------------------------------------------
2044 //=-----------------------------------------------------------------------------
2046 // Describes the members of an enum value: An enum is described as a union of
2047 // structs in DWARF. This MemberDescriptionFactory provides the description for
2048 // the members of this union; so for every variant of the given enum, this factory
2049 // will produce one MemberDescription (all with no name and a fixed offset of
2051 struct EnumMemberDescriptionFactory {
2053 type_rep: Rc<adt::Repr>,
2054 variants: Rc<Vec<Rc<ty::VariantInfo>>>,
2055 discriminant_type_metadata: Option<DIType>,
2056 containing_scope: DIScope,
2057 file_metadata: DIFile,
2061 impl EnumMemberDescriptionFactory {
2062 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
2063 match *self.type_rep {
2064 adt::General(_, ref struct_defs, _) => {
2065 let discriminant_info = RegularDiscriminant(self.discriminant_type_metadata
2071 .map(|(i, struct_def)| {
2072 let (variant_type_metadata,
2074 member_desc_factory) =
2075 describe_enum_variant(cx,
2078 &**self.variants.get(i),
2080 self.containing_scope,
2083 let member_descriptions = member_desc_factory
2084 .create_member_descriptions(cx);
2086 set_members_of_composite_type(cx,
2087 variant_type_metadata,
2089 member_descriptions.as_slice());
2091 name: "".to_string(),
2092 llvm_type: variant_llvm_type,
2093 type_metadata: variant_type_metadata,
2094 offset: FixedMemberOffset { bytes: 0 },
2099 adt::Univariant(ref struct_def, _) => {
2100 assert!(self.variants.len() <= 1);
2102 if self.variants.len() == 0 {
2105 let (variant_type_metadata,
2107 member_description_factory) =
2108 describe_enum_variant(cx,
2111 &**self.variants.get(0),
2113 self.containing_scope,
2116 let member_descriptions =
2117 member_description_factory.create_member_descriptions(cx);
2119 set_members_of_composite_type(cx,
2120 variant_type_metadata,
2122 member_descriptions.as_slice());
2125 name: "".to_string(),
2126 llvm_type: variant_llvm_type,
2127 type_metadata: variant_type_metadata,
2128 offset: FixedMemberOffset { bytes: 0 },
2134 adt::RawNullablePointer { nndiscr: non_null_variant_index, nnty, .. } => {
2135 // As far as debuginfo is concerned, the pointer this enum
2136 // represents is still wrapped in a struct. This is to make the
2137 // DWARF representation of enums uniform.
2139 // First create a description of the artificial wrapper struct:
2140 let non_null_variant = self.variants.get(non_null_variant_index as uint);
2141 let non_null_variant_ident = non_null_variant.name;
2142 let non_null_variant_name = token::get_ident(non_null_variant_ident);
2144 // The llvm type and metadata of the pointer
2145 let non_null_llvm_type = type_of::type_of(cx, nnty);
2146 let non_null_type_metadata = type_metadata(cx, nnty, self.span);
2148 // The type of the artificial struct wrapping the pointer
2149 let artificial_struct_llvm_type = Type::struct_(cx,
2150 &[non_null_llvm_type],
2153 // For the metadata of the wrapper struct, we need to create a
2154 // MemberDescription of the struct's single field.
2155 let sole_struct_member_description = MemberDescription {
2156 name: match non_null_variant.arg_names {
2157 Some(ref names) => token::get_ident(*names.get(0)).get().to_string(),
2158 None => "".to_string()
2160 llvm_type: non_null_llvm_type,
2161 type_metadata: non_null_type_metadata,
2162 offset: FixedMemberOffset { bytes: 0 },
2166 let unique_type_id = debug_context(cx).type_map
2168 .get_unique_type_id_of_enum_variant(
2171 non_null_variant_name.get());
2173 // Now we can create the metadata of the artificial struct
2174 let artificial_struct_metadata =
2175 composite_type_metadata(cx,
2176 artificial_struct_llvm_type,
2177 non_null_variant_name.get(),
2179 &[sole_struct_member_description],
2180 self.containing_scope,
2184 // Encode the information about the null variant in the union
2186 let null_variant_index = (1 - non_null_variant_index) as uint;
2187 let null_variant_ident = self.variants.get(null_variant_index).name;
2188 let null_variant_name = token::get_ident(null_variant_ident);
2189 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
2193 // Finally create the (singleton) list of descriptions of union
2197 name: union_member_name,
2198 llvm_type: artificial_struct_llvm_type,
2199 type_metadata: artificial_struct_metadata,
2200 offset: FixedMemberOffset { bytes: 0 },
2205 adt::StructWrappedNullablePointer { nonnull: ref struct_def,
2208 // Create a description of the non-null variant
2209 let (variant_type_metadata, variant_llvm_type, member_description_factory) =
2210 describe_enum_variant(cx,
2213 &**self.variants.get(nndiscr as uint),
2214 OptimizedDiscriminant(ptrfield),
2215 self.containing_scope,
2218 let variant_member_descriptions =
2219 member_description_factory.create_member_descriptions(cx);
2221 set_members_of_composite_type(cx,
2222 variant_type_metadata,
2224 variant_member_descriptions.as_slice());
2226 // Encode the information about the null variant in the union
2228 let null_variant_index = (1 - nndiscr) as uint;
2229 let null_variant_ident = self.variants.get(null_variant_index).name;
2230 let null_variant_name = token::get_ident(null_variant_ident);
2231 let discrfield = match ptrfield {
2232 adt::ThinPointer(field) => format!("{}", field),
2233 adt::FatPointer(field, pair) => format!("{}${}", field, pair)
2235 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
2239 // Create the (singleton) list of descriptions of union members.
2242 name: union_member_name,
2243 llvm_type: variant_llvm_type,
2244 type_metadata: variant_type_metadata,
2245 offset: FixedMemberOffset { bytes: 0 },
2250 adt::CEnum(..) => cx.sess().span_bug(self.span, "This should be unreachable.")
2255 // Creates MemberDescriptions for the fields of a single enum variant.
2256 struct VariantMemberDescriptionFactory {
2257 args: Vec<(String, ty::t)> ,
2258 discriminant_type_metadata: Option<DIType>,
2262 impl VariantMemberDescriptionFactory {
2263 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
2264 self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
2266 name: name.to_string(),
2267 llvm_type: type_of::type_of(cx, ty),
2268 type_metadata: match self.discriminant_type_metadata {
2269 Some(metadata) if i == 0 => metadata,
2270 _ => type_metadata(cx, ty, self.span)
2272 offset: ComputedMemberOffset,
2273 flags: if self.discriminant_type_metadata.is_some() && i == 0 {
2283 enum EnumDiscriminantInfo {
2284 RegularDiscriminant(DIType),
2285 OptimizedDiscriminant(adt::PointerField),
2289 // Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type
2290 // of the variant, and (3) a MemberDescriptionFactory for producing the
2291 // descriptions of the fields of the variant. This is a rudimentary version of a
2292 // full RecursiveTypeDescription.
2293 fn describe_enum_variant(cx: &CrateContext,
2295 struct_def: &adt::Struct,
2296 variant_info: &ty::VariantInfo,
2297 discriminant_info: EnumDiscriminantInfo,
2298 containing_scope: DIScope,
2300 -> (DICompositeType, Type, MemberDescriptionFactory) {
2301 let variant_llvm_type =
2302 Type::struct_(cx, struct_def.fields
2304 .map(|&t| type_of::type_of(cx, t))
2305 .collect::<Vec<_>>()
2308 // Could do some consistency checks here: size, align, field count, discr type
2310 let variant_name = token::get_ident(variant_info.name);
2311 let variant_name = variant_name.get();
2312 let unique_type_id = debug_context(cx).type_map
2314 .get_unique_type_id_of_enum_variant(
2319 let metadata_stub = create_struct_stub(cx,
2325 // Get the argument names from the enum variant info
2326 let mut arg_names: Vec<_> = match variant_info.arg_names {
2327 Some(ref names) => {
2330 token::get_ident(*ident).get().to_string().into_string()
2333 None => variant_info.args.iter().map(|_| "".to_string()).collect()
2336 // If this is not a univariant enum, there is also the (unnamed) discriminant field.
2337 match discriminant_info {
2338 RegularDiscriminant(_) => arg_names.insert(0, "".to_string()),
2339 _ => { /* do nothing */ }
2342 // Build an array of (field name, field type) pairs to be captured in the factory closure.
2343 let args: Vec<(String, ty::t)> = arg_names.iter()
2344 .zip(struct_def.fields.iter())
2345 .map(|(s, &t)| (s.to_string(), t))
2348 let member_description_factory =
2349 VariantMDF(VariantMemberDescriptionFactory {
2351 discriminant_type_metadata: match discriminant_info {
2352 RegularDiscriminant(discriminant_type_metadata) => {
2353 Some(discriminant_type_metadata)
2360 (metadata_stub, variant_llvm_type, member_description_factory)
2363 fn prepare_enum_metadata(cx: &CrateContext,
2365 enum_def_id: ast::DefId,
2366 unique_type_id: UniqueTypeId,
2368 -> RecursiveTypeDescription {
2369 let enum_name = compute_debuginfo_type_name(cx, enum_type, false);
2371 let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, enum_def_id);
2372 let loc = span_start(cx, definition_span);
2373 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2375 let variants = ty::enum_variants(cx.tcx(), enum_def_id);
2377 let enumerators_metadata: Vec<DIDescriptor> = variants
2380 token::get_ident(v.name).get().with_c_str(|name| {
2382 llvm::LLVMDIBuilderCreateEnumerator(
2385 v.disr_val as c_ulonglong)
2391 let discriminant_type_metadata = |inttype| {
2392 // We can reuse the type of the discriminant for all monomorphized
2393 // instances of an enum because it doesn't depend on any type parameters.
2394 // The def_id, uniquely identifying the enum's polytype acts as key in
2396 let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
2398 .find_copy(&enum_def_id);
2399 match cached_discriminant_type_metadata {
2400 Some(discriminant_type_metadata) => discriminant_type_metadata,
2402 let discriminant_llvm_type = adt::ll_inttype(cx, inttype);
2403 let (discriminant_size, discriminant_align) =
2404 size_and_align_of(cx, discriminant_llvm_type);
2405 let discriminant_base_type_metadata = type_metadata(cx,
2406 adt::ty_of_inttype(inttype),
2408 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
2410 let discriminant_type_metadata = discriminant_name.get().with_c_str(|name| {
2412 llvm::LLVMDIBuilderCreateEnumerationType(
2416 UNKNOWN_FILE_METADATA,
2417 UNKNOWN_LINE_NUMBER,
2418 bytes_to_bits(discriminant_size),
2419 bytes_to_bits(discriminant_align),
2420 create_DIArray(DIB(cx), enumerators_metadata.as_slice()),
2421 discriminant_base_type_metadata)
2425 debug_context(cx).created_enum_disr_types
2427 .insert(enum_def_id, discriminant_type_metadata);
2429 discriminant_type_metadata
2434 let type_rep = adt::represent_type(cx, enum_type);
2436 let discriminant_type_metadata = match *type_rep {
2437 adt::CEnum(inttype, _, _) => {
2438 return FinalMetadata(discriminant_type_metadata(inttype))
2440 adt::RawNullablePointer { .. } |
2441 adt::StructWrappedNullablePointer { .. } |
2442 adt::Univariant(..) => None,
2443 adt::General(inttype, _, _) => Some(discriminant_type_metadata(inttype)),
2446 let enum_llvm_type = type_of::type_of(cx, enum_type);
2447 let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
2449 let unique_type_id_str = debug_context(cx)
2452 .get_unique_type_id_as_string(unique_type_id);
2454 let enum_metadata = enum_name.as_slice().with_c_str(|enum_name| {
2455 unique_type_id_str.as_slice().with_c_str(|unique_type_id_str| {
2457 llvm::LLVMDIBuilderCreateUnionType(
2461 UNKNOWN_FILE_METADATA,
2462 UNKNOWN_LINE_NUMBER,
2463 bytes_to_bits(enum_type_size),
2464 bytes_to_bits(enum_type_align),
2473 return create_and_register_recursive_type_forward_declaration(
2479 EnumMDF(EnumMemberDescriptionFactory {
2480 enum_type: enum_type,
2481 type_rep: type_rep.clone(),
2483 discriminant_type_metadata: discriminant_type_metadata,
2484 containing_scope: containing_scope,
2485 file_metadata: file_metadata,
2490 fn get_enum_discriminant_name(cx: &CrateContext,
2492 -> token::InternedString {
2493 let name = if def_id.krate == ast::LOCAL_CRATE {
2494 cx.tcx().map.get_path_elem(def_id.node).name()
2496 csearch::get_item_path(cx.tcx(), def_id).last().unwrap().name()
2499 token::get_name(name)
2503 /// Creates debug information for a composite type, that is, anything that
2504 /// results in a LLVM struct.
2506 /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
2507 fn composite_type_metadata(cx: &CrateContext,
2508 composite_llvm_type: Type,
2509 composite_type_name: &str,
2510 composite_type_unique_id: UniqueTypeId,
2511 member_descriptions: &[MemberDescription],
2512 containing_scope: DIScope,
2514 // Ignore source location information as long as it
2515 // can't be reconstructed for non-local crates.
2516 _file_metadata: DIFile,
2517 _definition_span: Span)
2518 -> DICompositeType {
2519 // Create the (empty) struct metadata node ...
2520 let composite_type_metadata = create_struct_stub(cx,
2521 composite_llvm_type,
2522 composite_type_name,
2523 composite_type_unique_id,
2525 // ... and immediately create and add the member descriptions.
2526 set_members_of_composite_type(cx,
2527 composite_type_metadata,
2528 composite_llvm_type,
2529 member_descriptions);
2531 return composite_type_metadata;
2534 fn set_members_of_composite_type(cx: &CrateContext,
2535 composite_type_metadata: DICompositeType,
2536 composite_llvm_type: Type,
2537 member_descriptions: &[MemberDescription]) {
2538 // In some rare cases LLVM metadata uniquing would lead to an existing type
2539 // description being used instead of a new one created in create_struct_stub.
2540 // This would cause a hard to trace assertion in DICompositeType::SetTypeArray().
2541 // The following check makes sure that we get a better error message if this
2542 // should happen again due to some regression.
2544 let mut composite_types_completed =
2545 debug_context(cx).composite_types_completed.borrow_mut();
2546 if composite_types_completed.contains(&composite_type_metadata) {
2547 let (llvm_version_major, llvm_version_minor) = unsafe {
2548 (llvm::LLVMVersionMajor(), llvm::LLVMVersionMinor())
2551 let actual_llvm_version = llvm_version_major * 1000000 + llvm_version_minor * 1000;
2552 let min_supported_llvm_version = 3 * 1000000 + 4 * 1000;
2554 if actual_llvm_version < min_supported_llvm_version {
2555 cx.sess().warn(format!("This version of rustc was built with LLVM \
2556 {}.{}. Rustc just ran into a known \
2557 debuginfo corruption problem thatoften \
2558 occurs with LLVM versions below 3.4. \
2559 Please use a rustc built with anewer \
2562 llvm_version_minor).as_slice());
2564 cx.sess().bug("debuginfo::set_members_of_composite_type() - \
2565 Already completed forward declaration re-encountered.");
2568 composite_types_completed.insert(composite_type_metadata);
2572 let member_metadata: Vec<DIDescriptor> = member_descriptions
2575 .map(|(i, member_description)| {
2576 let (member_size, member_align) = size_and_align_of(cx, member_description.llvm_type);
2577 let member_offset = match member_description.offset {
2578 FixedMemberOffset { bytes } => bytes as u64,
2579 ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
2582 member_description.name.as_slice().with_c_str(|member_name| {
2584 llvm::LLVMDIBuilderCreateMemberType(
2586 composite_type_metadata,
2588 UNKNOWN_FILE_METADATA,
2589 UNKNOWN_LINE_NUMBER,
2590 bytes_to_bits(member_size),
2591 bytes_to_bits(member_align),
2592 bytes_to_bits(member_offset),
2593 member_description.flags,
2594 member_description.type_metadata)
2601 let type_array = create_DIArray(DIB(cx), member_metadata.as_slice());
2602 llvm::LLVMDICompositeTypeSetTypeArray(composite_type_metadata, type_array);
2606 // A convenience wrapper around LLVMDIBuilderCreateStructType(). Does not do any
2607 // caching, does not add any fields to the struct. This can be done later with
2608 // set_members_of_composite_type().
2609 fn create_struct_stub(cx: &CrateContext,
2610 struct_llvm_type: Type,
2611 struct_type_name: &str,
2612 unique_type_id: UniqueTypeId,
2613 containing_scope: DIScope)
2614 -> DICompositeType {
2615 let (struct_size, struct_align) = size_and_align_of(cx, struct_llvm_type);
2617 let unique_type_id_str = debug_context(cx).type_map
2619 .get_unique_type_id_as_string(unique_type_id);
2620 let metadata_stub = unsafe {
2621 struct_type_name.with_c_str(|name| {
2622 unique_type_id_str.as_slice().with_c_str(|unique_type_id| {
2623 // LLVMDIBuilderCreateStructType() wants an empty array. A null
2624 // pointer will lead to hard to trace and debug LLVM assertions
2625 // later on in llvm/lib/IR/Value.cpp.
2626 let empty_array = create_DIArray(DIB(cx), []);
2628 llvm::LLVMDIBuilderCreateStructType(
2632 UNKNOWN_FILE_METADATA,
2633 UNKNOWN_LINE_NUMBER,
2634 bytes_to_bits(struct_size),
2635 bytes_to_bits(struct_align),
2646 return metadata_stub;
2649 fn at_box_metadata(cx: &CrateContext,
2650 at_pointer_type: ty::t,
2651 content_type: ty::t,
2652 unique_type_id: UniqueTypeId)
2653 -> MetadataCreationResult {
2654 let content_type_metadata = type_metadata(cx, content_type, codemap::DUMMY_SP);
2656 return_if_metadata_created_in_meantime!(cx, unique_type_id);
2658 let content_type_name = compute_debuginfo_type_name(cx, content_type, true);
2659 let content_type_name = content_type_name.as_slice();
2660 let content_llvm_type = type_of::type_of(cx, content_type);
2662 let box_type_name = format!("GcBox<{}>", content_type_name);
2663 let box_llvm_type = Type::at_box(cx, content_llvm_type);
2664 let member_llvm_types = box_llvm_type.field_types();
2665 assert!(box_layout_is_correct(cx,
2666 member_llvm_types.as_slice(),
2667 content_llvm_type));
2669 let int_type = ty::mk_int();
2670 let nil_pointer_type = ty::mk_nil_ptr(cx.tcx());
2671 let nil_pointer_type_metadata = type_metadata(cx,
2674 let member_descriptions = [
2676 name: "refcnt".to_string(),
2677 llvm_type: *member_llvm_types.get(0),
2678 type_metadata: type_metadata(cx, int_type, codemap::DUMMY_SP),
2679 offset: ComputedMemberOffset,
2680 flags: FLAGS_ARTIFICAL,
2683 name: "drop_glue".to_string(),
2684 llvm_type: *member_llvm_types.get(1),
2685 type_metadata: nil_pointer_type_metadata,
2686 offset: ComputedMemberOffset,
2687 flags: FLAGS_ARTIFICAL,
2690 name: "prev".to_string(),
2691 llvm_type: *member_llvm_types.get(2),
2692 type_metadata: nil_pointer_type_metadata,
2693 offset: ComputedMemberOffset,
2694 flags: FLAGS_ARTIFICAL,
2697 name: "next".to_string(),
2698 llvm_type: *member_llvm_types.get(3),
2699 type_metadata: nil_pointer_type_metadata,
2700 offset: ComputedMemberOffset,
2701 flags: FLAGS_ARTIFICAL,
2704 name: "val".to_string(),
2705 llvm_type: *member_llvm_types.get(4),
2706 type_metadata: content_type_metadata,
2707 offset: ComputedMemberOffset,
2708 flags: FLAGS_ARTIFICAL,
2712 let gc_box_unique_id = debug_context(cx).type_map
2714 .get_unique_type_id_of_gc_box(cx, content_type);
2716 let gc_box_metadata = composite_type_metadata(
2719 box_type_name.as_slice(),
2721 member_descriptions,
2722 UNKNOWN_SCOPE_METADATA,
2723 UNKNOWN_FILE_METADATA,
2726 let gc_pointer_metadata = pointer_type_metadata(cx,
2730 return MetadataCreationResult::new(gc_pointer_metadata, false);
2732 // Unfortunately, we cannot assert anything but the correct types here---and
2733 // not whether the 'next' and 'prev' pointers are in the correct order.
2734 fn box_layout_is_correct(cx: &CrateContext,
2735 member_llvm_types: &[Type],
2736 content_llvm_type: Type)
2738 member_llvm_types.len() == 5 &&
2739 member_llvm_types[0] == cx.int_type() &&
2740 member_llvm_types[1] == Type::generic_glue_fn(cx).ptr_to() &&
2741 member_llvm_types[2] == Type::i8(cx).ptr_to() &&
2742 member_llvm_types[3] == Type::i8(cx).ptr_to() &&
2743 member_llvm_types[4] == content_llvm_type
2748 fn fixed_vec_metadata(cx: &CrateContext,
2749 unique_type_id: UniqueTypeId,
2750 element_type: ty::t,
2753 -> MetadataCreationResult {
2754 let element_type_metadata = type_metadata(cx, element_type, span);
2756 return_if_metadata_created_in_meantime!(cx, unique_type_id);
2758 let element_llvm_type = type_of::type_of(cx, element_type);
2759 let (element_type_size, element_type_align) = size_and_align_of(cx, element_llvm_type);
2761 let subrange = unsafe {
2762 llvm::LLVMDIBuilderGetOrCreateSubrange(
2768 let subscripts = create_DIArray(DIB(cx), [subrange]);
2769 let metadata = unsafe {
2770 llvm::LLVMDIBuilderCreateArrayType(
2772 bytes_to_bits(element_type_size * (len as u64)),
2773 bytes_to_bits(element_type_align),
2774 element_type_metadata,
2778 return MetadataCreationResult::new(metadata, false);
2781 fn vec_slice_metadata(cx: &CrateContext,
2783 element_type: ty::t,
2784 unique_type_id: UniqueTypeId,
2786 -> MetadataCreationResult {
2787 let data_ptr_type = ty::mk_ptr(cx.tcx(), ty::mt {
2789 mutbl: ast::MutImmutable
2792 let element_type_metadata = type_metadata(cx, data_ptr_type, span);
2794 return_if_metadata_created_in_meantime!(cx, unique_type_id);
2796 let slice_llvm_type = type_of::type_of(cx, vec_type);
2797 let slice_type_name = compute_debuginfo_type_name(cx, vec_type, true);
2799 let member_llvm_types = slice_llvm_type.field_types();
2800 assert!(slice_layout_is_correct(cx,
2801 member_llvm_types.as_slice(),
2803 let member_descriptions = [
2805 name: "data_ptr".to_string(),
2806 llvm_type: *member_llvm_types.get(0),
2807 type_metadata: element_type_metadata,
2808 offset: ComputedMemberOffset,
2809 flags: FLAGS_ARTIFICAL
2812 name: "length".to_string(),
2813 llvm_type: *member_llvm_types.get(1),
2814 type_metadata: type_metadata(cx, ty::mk_uint(), span),
2815 offset: ComputedMemberOffset,
2816 flags: FLAGS_ARTIFICAL
2820 assert!(member_descriptions.len() == member_llvm_types.len());
2822 let loc = span_start(cx, span);
2823 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2825 let metadata = composite_type_metadata(cx,
2827 slice_type_name.as_slice(),
2829 member_descriptions,
2830 UNKNOWN_SCOPE_METADATA,
2833 return MetadataCreationResult::new(metadata, false);
2835 fn slice_layout_is_correct(cx: &CrateContext,
2836 member_llvm_types: &[Type],
2837 element_type: ty::t)
2839 member_llvm_types.len() == 2 &&
2840 member_llvm_types[0] == type_of::type_of(cx, element_type).ptr_to() &&
2841 member_llvm_types[1] == cx.int_type()
2845 fn subroutine_type_metadata(cx: &CrateContext,
2846 unique_type_id: UniqueTypeId,
2847 signature: &ty::FnSig,
2849 -> MetadataCreationResult {
2850 let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs.len() + 1);
2853 signature_metadata.push(match ty::get(signature.output).sty {
2854 ty::ty_nil => ptr::null_mut(),
2855 _ => type_metadata(cx, signature.output, span)
2858 // regular arguments
2859 for &argument_type in signature.inputs.iter() {
2860 signature_metadata.push(type_metadata(cx, argument_type, span));
2863 return_if_metadata_created_in_meantime!(cx, unique_type_id);
2865 return MetadataCreationResult::new(
2867 llvm::LLVMDIBuilderCreateSubroutineType(
2869 UNKNOWN_FILE_METADATA,
2870 create_DIArray(DIB(cx), signature_metadata.as_slice()))
2875 // FIXME(1563) This is all a bit of a hack because 'trait pointer' is an ill-
2876 // defined concept. For the case of an actual trait pointer (i.e., Box<Trait>,
2877 // &Trait), trait_object_type should be the whole thing (e.g, Box<Trait>) and
2878 // trait_type should be the actual trait (e.g., Trait). Where the trait is part
2879 // of a DST struct, there is no trait_object_type and the results of this
2880 // function will be a little bit weird.
2881 fn trait_pointer_metadata(cx: &CrateContext,
2883 trait_object_type: Option<ty::t>,
2884 unique_type_id: UniqueTypeId)
2886 // The implementation provided here is a stub. It makes sure that the trait
2887 // type is assigned the correct name, size, namespace, and source location.
2888 // But it does not describe the trait's methods.
2890 let def_id = match ty::get(trait_type).sty {
2891 ty::ty_trait(box ty::TyTrait { def_id, .. }) => def_id,
2893 let pp_type_name = ppaux::ty_to_string(cx.tcx(), trait_type);
2894 cx.sess().bug(format!("debuginfo: Unexpected trait-object type in \
2895 trait_pointer_metadata(): {}",
2896 pp_type_name.as_slice()).as_slice());
2900 let trait_object_type = trait_object_type.unwrap_or(trait_type);
2901 let trait_type_name =
2902 compute_debuginfo_type_name(cx, trait_object_type, false);
2904 let (containing_scope, _) = get_namespace_and_span_for_item(cx, def_id);
2906 let trait_llvm_type = type_of::type_of(cx, trait_object_type);
2908 composite_type_metadata(cx,
2910 trait_type_name.as_slice(),
2914 UNKNOWN_FILE_METADATA,
2918 fn type_metadata(cx: &CrateContext,
2920 usage_site_span: Span)
2922 // Get the unique type id of this type.
2923 let unique_type_id = {
2924 let mut type_map = debug_context(cx).type_map.borrow_mut();
2925 // First, try to find the type in TypeMap. If we have seen it before, we
2926 // can exit early here.
2927 match type_map.find_metadata_for_type(t) {
2932 // The ty::t is not in the TypeMap but maybe we have already seen
2933 // an equivalent type (e.g. only differing in region arguments).
2934 // In order to find out, generate the unique type id and look
2936 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
2937 match type_map.find_metadata_for_unique_id(unique_type_id) {
2939 // There is already an equivalent type in the TypeMap.
2940 // Register this ty::t as an alias in the cache and
2941 // return the cached metadata.
2942 type_map.register_type_with_metadata(cx, t, metadata);
2946 // There really is no type metadata for this type, so
2947 // proceed by creating it.
2955 debug!("type_metadata: {:?}", ty::get(t));
2957 let sty = &ty::get(t).sty;
2958 let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty {
2965 ty::ty_float(_) => {
2966 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
2968 ty::ty_enum(def_id, _) => {
2969 prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span).finalize(cx)
2971 ty::ty_box(pointee_type) => {
2972 at_box_metadata(cx, t, pointee_type, unique_type_id)
2974 ty::ty_vec(typ, Some(len)) => {
2975 fixed_vec_metadata(cx, unique_type_id, typ, len, usage_site_span)
2977 // FIXME Can we do better than this for unsized vec/str fields?
2978 ty::ty_vec(typ, None) => fixed_vec_metadata(cx, unique_type_id, typ, 0, usage_site_span),
2979 ty::ty_str => fixed_vec_metadata(cx, unique_type_id, ty::mk_i8(), 0, usage_site_span),
2980 ty::ty_trait(..) => {
2981 MetadataCreationResult::new(
2982 trait_pointer_metadata(cx, t, None, unique_type_id),
2985 ty::ty_uniq(ty) | ty::ty_ptr(ty::mt{ty, ..}) | ty::ty_rptr(_, ty::mt{ty, ..}) => {
2986 match ty::get(ty).sty {
2987 ty::ty_vec(typ, None) => {
2988 vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span)
2991 vec_slice_metadata(cx, t, ty::mk_u8(), unique_type_id, usage_site_span)
2993 ty::ty_trait(..) => {
2994 MetadataCreationResult::new(
2995 trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
2999 let pointee_metadata = type_metadata(cx, ty, usage_site_span);
3001 match debug_context(cx).type_map
3003 .find_metadata_for_unique_id(unique_type_id) {
3004 Some(metadata) => return metadata,
3005 None => { /* proceed normally */ }
3008 MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
3013 ty::ty_bare_fn(ref barefnty) => {
3014 subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
3016 ty::ty_closure(ref closurety) => {
3017 subroutine_type_metadata(cx, unique_type_id, &closurety.sig, usage_site_span)
3019 ty::ty_struct(def_id, ref substs) => {
3020 prepare_struct_metadata(cx,
3025 usage_site_span).finalize(cx)
3027 ty::ty_tup(ref elements) => {
3028 prepare_tuple_metadata(cx,
3030 elements.as_slice(),
3032 usage_site_span).finalize(cx)
3035 cx.sess().bug(format!("debuginfo: unexpected type in type_metadata: {:?}",
3041 let mut type_map = debug_context(cx).type_map.borrow_mut();
3043 if already_stored_in_typemap {
3044 // Also make sure that we already have a TypeMap entry entry for the unique type id.
3045 let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
3046 Some(metadata) => metadata,
3048 let unique_type_id_str =
3049 type_map.get_unique_type_id_as_string(unique_type_id);
3050 let error_message = format!("Expected type metadata for unique \
3051 type id '{}' to already be in \
3052 the debuginfo::TypeMap but it \
3053 was not. (ty::t = {})",
3054 unique_type_id_str.as_slice(),
3055 ppaux::ty_to_string(cx.tcx(), t));
3056 cx.sess().span_bug(usage_site_span, error_message.as_slice());
3060 match type_map.find_metadata_for_type(t) {
3062 if metadata != metadata_for_uid {
3063 let unique_type_id_str =
3064 type_map.get_unique_type_id_as_string(unique_type_id);
3065 let error_message = format!("Mismatch between ty::t and \
3066 UniqueTypeId maps in \
3067 debuginfo::TypeMap. \
3068 UniqueTypeId={}, ty::t={}",
3069 unique_type_id_str.as_slice(),
3070 ppaux::ty_to_string(cx.tcx(), t));
3071 cx.sess().span_bug(usage_site_span, error_message.as_slice());
3075 type_map.register_type_with_metadata(cx, t, metadata);
3079 type_map.register_type_with_metadata(cx, t, metadata);
3080 type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata);
3087 struct MetadataCreationResult {
3089 already_stored_in_typemap: bool
3092 impl MetadataCreationResult {
3093 fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationResult {
3094 MetadataCreationResult {
3096 already_stored_in_typemap: already_stored_in_typemap
3101 #[deriving(PartialEq)]
3102 enum DebugLocation {
3103 KnownLocation { scope: DIScope, line: uint, col: uint },
3107 impl DebugLocation {
3108 fn new(scope: DIScope, line: uint, col: uint) -> DebugLocation {
3117 fn set_debug_location(cx: &CrateContext, debug_location: DebugLocation) {
3118 if debug_location == debug_context(cx).current_debug_location.get() {
3124 match debug_location {
3125 KnownLocation { scope, line, .. } => {
3126 // Always set the column to zero like Clang and GCC
3127 let col = UNKNOWN_COLUMN_NUMBER;
3128 debug!("setting debug location to {} {}", line, col);
3129 let elements = [C_i32(cx, line as i32), C_i32(cx, col as i32),
3130 scope, ptr::null_mut()];
3132 metadata_node = llvm::LLVMMDNodeInContext(debug_context(cx).llcontext,
3134 elements.len() as c_uint);
3137 UnknownLocation => {
3138 debug!("clearing debug location ");
3139 metadata_node = ptr::null_mut();
3144 llvm::LLVMSetCurrentDebugLocation(cx.raw_builder(), metadata_node);
3147 debug_context(cx).current_debug_location.set(debug_location);
3150 //=-----------------------------------------------------------------------------
3151 // Utility Functions
3152 //=-----------------------------------------------------------------------------
3154 fn contains_nodebug_attribute(attributes: &[ast::Attribute]) -> bool {
3155 attributes.iter().any(|attr| {
3156 let meta_item: &ast::MetaItem = &*attr.node.value;
3157 match meta_item.node {
3158 ast::MetaWord(ref value) => value.get() == "no_debug",
3164 /// Return codemap::Loc corresponding to the beginning of the span
3165 fn span_start(cx: &CrateContext, span: Span) -> codemap::Loc {
3166 cx.sess().codemap().lookup_char_pos(span.lo)
3169 fn size_and_align_of(cx: &CrateContext, llvm_type: Type) -> (u64, u64) {
3170 (machine::llsize_of_alloc(cx, llvm_type), machine::llalign_of_min(cx, llvm_type))
3173 fn bytes_to_bits(bytes: u64) -> c_ulonglong {
3174 (bytes * 8) as c_ulonglong
3178 fn debug_context<'a>(cx: &'a CrateContext) -> &'a CrateDebugContext {
3179 let debug_context: &'a CrateDebugContext = cx.dbg_cx().get_ref();
3184 #[allow(non_snake_case)]
3185 fn DIB(cx: &CrateContext) -> DIBuilderRef {
3186 cx.dbg_cx().get_ref().builder
3189 fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
3190 match fcx.debug_context.repr {
3191 DebugInfo(_) => false,
3196 fn assert_type_for_node_id(cx: &CrateContext,
3197 node_id: ast::NodeId,
3198 error_reporting_span: Span) {
3199 if !cx.tcx().node_types.borrow().contains_key(&(node_id as uint)) {
3200 cx.sess().span_bug(error_reporting_span,
3201 "debuginfo: Could not find type for node id!");
3205 fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: ast::DefId)
3206 -> (DIScope, Span) {
3207 let containing_scope = namespace_for_item(cx, def_id).scope;
3208 let definition_span = if def_id.krate == ast::LOCAL_CRATE {
3209 cx.tcx().map.span(def_id.node)
3211 // For external items there is no span information
3215 (containing_scope, definition_span)
3218 // This procedure builds the *scope map* for a given function, which maps any
3219 // given ast::NodeId in the function's AST to the correct DIScope metadata instance.
3221 // This builder procedure walks the AST in execution order and keeps track of
3222 // what belongs to which scope, creating DIScope DIEs along the way, and
3223 // introducing *artificial* lexical scope descriptors where necessary. These
3224 // artificial scopes allow GDB to correctly handle name shadowing.
3225 fn populate_scope_map(cx: &CrateContext,
3227 fn_entry_block: &ast::Block,
3228 fn_metadata: DISubprogram,
3229 fn_ast_id: ast::NodeId,
3230 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3231 let def_map = &cx.tcx().def_map;
3233 struct ScopeStackEntry {
3234 scope_metadata: DIScope,
3235 ident: Option<ast::Ident>
3238 let mut scope_stack = vec!(ScopeStackEntry { scope_metadata: fn_metadata,
3240 scope_map.insert(fn_ast_id, fn_metadata);
3242 // Push argument identifiers onto the stack so arguments integrate nicely
3243 // with variable shadowing.
3244 for arg in args.iter() {
3245 pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, _, path1| {
3246 scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata,
3247 ident: Some(path1.node) });
3248 scope_map.insert(node_id, fn_metadata);
3252 // Clang creates a separate scope for function bodies, so let's do this too.
3254 fn_entry_block.span,
3257 |cx, scope_stack, scope_map| {
3258 walk_block(cx, fn_entry_block, scope_stack, scope_map);
3261 // local helper functions for walking the AST.
3262 fn with_new_scope(cx: &CrateContext,
3264 scope_stack: &mut Vec<ScopeStackEntry> ,
3265 scope_map: &mut HashMap<ast::NodeId, DIScope>,
3266 inner_walk: |&CrateContext,
3267 &mut Vec<ScopeStackEntry> ,
3268 &mut HashMap<ast::NodeId, DIScope>|) {
3269 // Create a new lexical scope and push it onto the stack
3270 let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
3271 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
3272 let parent_scope = scope_stack.last().unwrap().scope_metadata;
3274 let scope_metadata = unsafe {
3275 llvm::LLVMDIBuilderCreateLexicalBlock(
3280 loc.col.to_uint() as c_uint,
3284 scope_stack.push(ScopeStackEntry { scope_metadata: scope_metadata,
3287 inner_walk(cx, scope_stack, scope_map);
3289 // pop artificial scopes
3290 while scope_stack.last().unwrap().ident.is_some() {
3294 if scope_stack.last().unwrap().scope_metadata != scope_metadata {
3295 cx.sess().span_bug(scope_span, "debuginfo: Inconsistency in scope management.");
3301 fn walk_block(cx: &CrateContext,
3303 scope_stack: &mut Vec<ScopeStackEntry> ,
3304 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3305 scope_map.insert(block.id, scope_stack.last().unwrap().scope_metadata);
3307 // The interesting things here are statements and the concluding expression.
3308 for statement in block.stmts.iter() {
3309 scope_map.insert(ast_util::stmt_id(&**statement),
3310 scope_stack.last().unwrap().scope_metadata);
3312 match statement.node {
3313 ast::StmtDecl(ref decl, _) =>
3314 walk_decl(cx, &**decl, scope_stack, scope_map),
3315 ast::StmtExpr(ref exp, _) |
3316 ast::StmtSemi(ref exp, _) =>
3317 walk_expr(cx, &**exp, scope_stack, scope_map),
3318 ast::StmtMac(..) => () // Ignore macros (which should be expanded anyway).
3322 for exp in block.expr.iter() {
3323 walk_expr(cx, &**exp, scope_stack, scope_map);
3327 fn walk_decl(cx: &CrateContext,
3329 scope_stack: &mut Vec<ScopeStackEntry> ,
3330 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3332 codemap::Spanned { node: ast::DeclLocal(ref local), .. } => {
3333 scope_map.insert(local.id, scope_stack.last().unwrap().scope_metadata);
3335 walk_pattern(cx, &*local.pat, scope_stack, scope_map);
3337 for exp in local.init.iter() {
3338 walk_expr(cx, &**exp, scope_stack, scope_map);
3345 fn walk_pattern(cx: &CrateContext,
3347 scope_stack: &mut Vec<ScopeStackEntry> ,
3348 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3350 let def_map = &cx.tcx().def_map;
3352 // Unfortunately, we cannot just use pat_util::pat_bindings() or
3353 // ast_util::walk_pat() here because we have to visit *all* nodes in
3354 // order to put them into the scope map. The above functions don't do that.
3356 ast::PatIdent(_, ref path1, ref sub_pat_opt) => {
3358 // Check if this is a binding. If so we need to put it on the
3359 // scope stack and maybe introduce an artificial scope
3360 if pat_util::pat_is_binding(def_map, &*pat) {
3362 let ident = path1.node;
3364 // LLVM does not properly generate 'DW_AT_start_scope' fields
3365 // for variable DIEs. For this reason we have to introduce
3366 // an artificial scope at bindings whenever a variable with
3367 // the same name is declared in *any* parent scope.
3369 // Otherwise the following error occurs:
3373 // do_something(); // 'gdb print x' correctly prints 10
3376 // do_something(); // 'gdb print x' prints 0, because it
3377 // // already reads the uninitialized 'x'
3378 // // from the next line...
3380 // do_something(); // 'gdb print x' correctly prints 100
3383 // Is there already a binding with that name?
3384 // N.B.: this comparison must be UNhygienic... because
3385 // gdb knows nothing about the context, so any two
3386 // variables with the same name will cause the problem.
3387 let need_new_scope = scope_stack
3389 .any(|entry| entry.ident.iter().any(|i| i.name == ident.name));
3392 // Create a new lexical scope and push it onto the stack
3393 let loc = cx.sess().codemap().lookup_char_pos(pat.span.lo);
3394 let file_metadata = file_metadata(cx,
3398 let parent_scope = scope_stack.last().unwrap().scope_metadata;
3400 let scope_metadata = unsafe {
3401 llvm::LLVMDIBuilderCreateLexicalBlock(
3406 loc.col.to_uint() as c_uint,
3410 scope_stack.push(ScopeStackEntry {
3411 scope_metadata: scope_metadata,
3416 // Push a new entry anyway so the name can be found
3417 let prev_metadata = scope_stack.last().unwrap().scope_metadata;
3418 scope_stack.push(ScopeStackEntry {
3419 scope_metadata: prev_metadata,
3425 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3427 for sub_pat in sub_pat_opt.iter() {
3428 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3432 ast::PatWild(_) => {
3433 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3436 ast::PatEnum(_, ref sub_pats_opt) => {
3437 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3439 for sub_pats in sub_pats_opt.iter() {
3440 for p in sub_pats.iter() {
3441 walk_pattern(cx, &**p, scope_stack, scope_map);
3446 ast::PatStruct(_, ref field_pats, _) => {
3447 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3449 for &ast::FieldPat { pat: ref sub_pat, .. } in field_pats.iter() {
3450 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3454 ast::PatTup(ref sub_pats) => {
3455 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3457 for sub_pat in sub_pats.iter() {
3458 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3462 ast::PatBox(ref sub_pat) | ast::PatRegion(ref sub_pat) => {
3463 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3464 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3467 ast::PatLit(ref exp) => {
3468 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3469 walk_expr(cx, &**exp, scope_stack, scope_map);
3472 ast::PatRange(ref exp1, ref exp2) => {
3473 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3474 walk_expr(cx, &**exp1, scope_stack, scope_map);
3475 walk_expr(cx, &**exp2, scope_stack, scope_map);
3478 ast::PatVec(ref front_sub_pats, ref middle_sub_pats, ref back_sub_pats) => {
3479 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3481 for sub_pat in front_sub_pats.iter() {
3482 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3485 for sub_pat in middle_sub_pats.iter() {
3486 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3489 for sub_pat in back_sub_pats.iter() {
3490 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
3495 cx.sess().span_bug(pat.span, "debuginfo::populate_scope_map() - \
3496 Found unexpanded macro.");
3501 fn walk_expr(cx: &CrateContext,
3503 scope_stack: &mut Vec<ScopeStackEntry> ,
3504 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3506 scope_map.insert(exp.id, scope_stack.last().unwrap().scope_metadata);
3512 ast::ExprPath(_) => {}
3514 ast::ExprCast(ref sub_exp, _) |
3515 ast::ExprAddrOf(_, ref sub_exp) |
3516 ast::ExprField(ref sub_exp, _, _) |
3517 ast::ExprTupField(ref sub_exp, _, _) |
3518 ast::ExprParen(ref sub_exp) =>
3519 walk_expr(cx, &**sub_exp, scope_stack, scope_map),
3521 ast::ExprBox(ref place, ref sub_expr) => {
3522 walk_expr(cx, &**place, scope_stack, scope_map);
3523 walk_expr(cx, &**sub_expr, scope_stack, scope_map);
3526 ast::ExprRet(ref exp_opt) => match *exp_opt {
3527 Some(ref sub_exp) => walk_expr(cx, &**sub_exp, scope_stack, scope_map),
3531 ast::ExprUnary(_, ref sub_exp) => {
3532 walk_expr(cx, &**sub_exp, scope_stack, scope_map);
3535 ast::ExprAssignOp(_, ref lhs, ref rhs) |
3536 ast::ExprIndex(ref lhs, ref rhs) |
3537 ast::ExprBinary(_, ref lhs, ref rhs) => {
3538 walk_expr(cx, &**lhs, scope_stack, scope_map);
3539 walk_expr(cx, &**rhs, scope_stack, scope_map);
3542 ast::ExprSlice(ref base, ref start, ref end, _) => {
3543 walk_expr(cx, &**base, scope_stack, scope_map);
3544 start.as_ref().map(|x| walk_expr(cx, &**x, scope_stack, scope_map));
3545 end.as_ref().map(|x| walk_expr(cx, &**x, scope_stack, scope_map));
3548 ast::ExprVec(ref init_expressions) |
3549 ast::ExprTup(ref init_expressions) => {
3550 for ie in init_expressions.iter() {
3551 walk_expr(cx, &**ie, scope_stack, scope_map);
3555 ast::ExprAssign(ref sub_exp1, ref sub_exp2) |
3556 ast::ExprRepeat(ref sub_exp1, ref sub_exp2) => {
3557 walk_expr(cx, &**sub_exp1, scope_stack, scope_map);
3558 walk_expr(cx, &**sub_exp2, scope_stack, scope_map);
3561 ast::ExprIf(ref cond_exp, ref then_block, ref opt_else_exp) => {
3562 walk_expr(cx, &**cond_exp, scope_stack, scope_map);
3568 |cx, scope_stack, scope_map| {
3569 walk_block(cx, &**then_block, scope_stack, scope_map);
3572 match *opt_else_exp {
3573 Some(ref else_exp) =>
3574 walk_expr(cx, &**else_exp, scope_stack, scope_map),
3579 ast::ExprIfLet(..) => {
3580 cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
3581 Found unexpanded if-let.");
3584 ast::ExprWhile(ref cond_exp, ref loop_body, _) => {
3585 walk_expr(cx, &**cond_exp, scope_stack, scope_map);
3591 |cx, scope_stack, scope_map| {
3592 walk_block(cx, &**loop_body, scope_stack, scope_map);
3596 ast::ExprForLoop(ref pattern, ref head, ref body, _) => {
3597 walk_expr(cx, &**head, scope_stack, scope_map);
3603 |cx, scope_stack, scope_map| {
3604 scope_map.insert(exp.id,
3612 walk_block(cx, &**body, scope_stack, scope_map);
3616 ast::ExprMac(_) => {
3617 cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
3618 Found unexpanded macro.");
3621 ast::ExprLoop(ref block, _) |
3622 ast::ExprBlock(ref block) => {
3627 |cx, scope_stack, scope_map| {
3628 walk_block(cx, &**block, scope_stack, scope_map);
3632 ast::ExprFnBlock(_, ref decl, ref block) |
3633 ast::ExprProc(ref decl, ref block) |
3634 ast::ExprUnboxedFn(_, _, ref decl, ref block) => {
3639 |cx, scope_stack, scope_map| {
3640 for &ast::Arg { pat: ref pattern, .. } in decl.inputs.iter() {
3641 walk_pattern(cx, &**pattern, scope_stack, scope_map);
3644 walk_block(cx, &**block, scope_stack, scope_map);
3648 ast::ExprCall(ref fn_exp, ref args) => {
3649 walk_expr(cx, &**fn_exp, scope_stack, scope_map);
3651 for arg_exp in args.iter() {
3652 walk_expr(cx, &**arg_exp, scope_stack, scope_map);
3656 ast::ExprMethodCall(_, _, ref args) => {
3657 for arg_exp in args.iter() {
3658 walk_expr(cx, &**arg_exp, scope_stack, scope_map);
3662 ast::ExprMatch(ref discriminant_exp, ref arms, _) => {
3663 walk_expr(cx, &**discriminant_exp, scope_stack, scope_map);
3665 // For each arm we have to first walk the pattern as these might
3666 // introduce new artificial scopes. It should be sufficient to
3667 // walk only one pattern per arm, as they all must contain the
3668 // same binding names.
3670 for arm_ref in arms.iter() {
3671 let arm_span = arm_ref.pats.get(0).span;
3677 |cx, scope_stack, scope_map| {
3678 for pat in arm_ref.pats.iter() {
3679 walk_pattern(cx, &**pat, scope_stack, scope_map);
3682 for guard_exp in arm_ref.guard.iter() {
3683 walk_expr(cx, &**guard_exp, scope_stack, scope_map)
3686 walk_expr(cx, &*arm_ref.body, scope_stack, scope_map);
3691 ast::ExprStruct(_, ref fields, ref base_exp) => {
3692 for &ast::Field { expr: ref exp, .. } in fields.iter() {
3693 walk_expr(cx, &**exp, scope_stack, scope_map);
3697 Some(ref exp) => walk_expr(cx, &**exp, scope_stack, scope_map),
3702 ast::ExprInlineAsm(ast::InlineAsm { inputs: ref inputs,
3703 outputs: ref outputs,
3705 // inputs, outputs: ~[(String, Gc<expr>)]
3706 for &(_, ref exp) in inputs.iter() {
3707 walk_expr(cx, &**exp, scope_stack, scope_map);
3710 for &(_, ref exp, _) in outputs.iter() {
3711 walk_expr(cx, &**exp, scope_stack, scope_map);
3719 //=-----------------------------------------------------------------------------
3720 // Type Names for Debug Info
3721 //=-----------------------------------------------------------------------------
3723 // Compute the name of the type as it should be stored in debuginfo. Does not do
3724 // any caching, i.e. calling the function twice with the same type will also do
3725 // the work twice. The `qualified` parameter only affects the first level of the
3726 // type name, further levels (i.e. type parameters) are always fully qualified.
3727 fn compute_debuginfo_type_name(cx: &CrateContext,
3731 let mut result = String::with_capacity(64);
3732 push_debuginfo_type_name(cx, t, qualified, &mut result);
3736 // Pushes the name of the type as it should be stored in debuginfo on the
3737 // `output` String. See also compute_debuginfo_type_name().
3738 fn push_debuginfo_type_name(cx: &CrateContext,
3741 output:&mut String) {
3742 match ty::get(t).sty {
3743 ty::ty_nil => output.push_str("()"),
3744 ty::ty_bot => output.push_str("!"),
3745 ty::ty_bool => output.push_str("bool"),
3746 ty::ty_char => output.push_str("char"),
3747 ty::ty_str => output.push_str("str"),
3748 ty::ty_int(ast::TyI) => output.push_str("int"),
3749 ty::ty_int(ast::TyI8) => output.push_str("i8"),
3750 ty::ty_int(ast::TyI16) => output.push_str("i16"),
3751 ty::ty_int(ast::TyI32) => output.push_str("i32"),
3752 ty::ty_int(ast::TyI64) => output.push_str("i64"),
3753 ty::ty_uint(ast::TyU) => output.push_str("uint"),
3754 ty::ty_uint(ast::TyU8) => output.push_str("u8"),
3755 ty::ty_uint(ast::TyU16) => output.push_str("u16"),
3756 ty::ty_uint(ast::TyU32) => output.push_str("u32"),
3757 ty::ty_uint(ast::TyU64) => output.push_str("u64"),
3758 ty::ty_float(ast::TyF32) => output.push_str("f32"),
3759 ty::ty_float(ast::TyF64) => output.push_str("f64"),
3760 ty::ty_struct(def_id, ref substs) |
3761 ty::ty_enum(def_id, ref substs) => {
3762 push_item_name(cx, def_id, qualified, output);
3763 push_type_params(cx, substs, output);
3765 ty::ty_tup(ref component_types) => {
3766 output.push_char('(');
3767 for &component_type in component_types.iter() {
3768 push_debuginfo_type_name(cx, component_type, true, output);
3769 output.push_str(", ");
3773 output.push_char(')');
3775 ty::ty_uniq(inner_type) => {
3776 output.push_str("Box<");
3777 push_debuginfo_type_name(cx, inner_type, true, output);
3778 output.push_char('>');
3780 ty::ty_box(inner_type) => {
3781 output.push_char('@');
3782 push_debuginfo_type_name(cx, inner_type, true, output);
3784 ty::ty_ptr(ty::mt { ty: inner_type, mutbl } ) => {
3785 output.push_char('*');
3787 ast::MutImmutable => output.push_str("const "),
3788 ast::MutMutable => output.push_str("mut "),
3791 push_debuginfo_type_name(cx, inner_type, true, output);
3793 ty::ty_rptr(_, ty::mt { ty: inner_type, mutbl }) => {
3794 output.push_char('&');
3795 if mutbl == ast::MutMutable {
3796 output.push_str("mut ");
3799 push_debuginfo_type_name(cx, inner_type, true, output);
3801 ty::ty_vec(inner_type, optional_length) => {
3802 output.push_char('[');
3803 push_debuginfo_type_name(cx, inner_type, true, output);
3805 match optional_length {
3807 output.push_str(format!(", ..{}", len).as_slice());
3809 None => { /* nothing to do */ }
3812 output.push_char(']');
3814 ty::ty_trait(ref trait_data) => {
3815 push_item_name(cx, trait_data.def_id, false, output);
3816 push_type_params(cx, &trait_data.substs, output);
3818 ty::ty_bare_fn(ty::BareFnTy{ fn_style, abi, ref sig } ) => {
3819 if fn_style == ast::UnsafeFn {
3820 output.push_str("unsafe ");
3823 if abi != ::syntax::abi::Rust {
3824 output.push_str("extern \"");
3825 output.push_str(abi.name());
3826 output.push_str("\" ");
3829 output.push_str("fn(");
3831 if sig.inputs.len() > 0 {
3832 for ¶meter_type in sig.inputs.iter() {
3833 push_debuginfo_type_name(cx, parameter_type, true, output);
3834 output.push_str(", ");
3841 if sig.inputs.len() > 0 {
3842 output.push_str(", ...");
3844 output.push_str("...");
3848 output.push_char(')');
3850 if !ty::type_is_nil(sig.output) {
3851 output.push_str(" -> ");
3852 push_debuginfo_type_name(cx, sig.output, true, output);
3855 ty::ty_closure(box ty::ClosureTy { fn_style,
3859 .. // omitting bounds ...
3861 if fn_style == ast::UnsafeFn {
3862 output.push_str("unsafe ");
3865 if onceness == ast::Once {
3866 output.push_str("once ");
3869 let param_list_closing_char;
3871 ty::UniqTraitStore => {
3872 output.push_str("proc(");
3873 param_list_closing_char = ')';
3875 ty::RegionTraitStore(_, ast::MutMutable) => {
3876 output.push_str("&mut|");
3877 param_list_closing_char = '|';
3879 ty::RegionTraitStore(_, ast::MutImmutable) => {
3880 output.push_str("&|");
3881 param_list_closing_char = '|';
3885 if sig.inputs.len() > 0 {
3886 for ¶meter_type in sig.inputs.iter() {
3887 push_debuginfo_type_name(cx, parameter_type, true, output);
3888 output.push_str(", ");
3895 if sig.inputs.len() > 0 {
3896 output.push_str(", ...");
3898 output.push_str("...");
3902 output.push_char(param_list_closing_char);
3904 if !ty::type_is_nil(sig.output) {
3905 output.push_str(" -> ");
3906 push_debuginfo_type_name(cx, sig.output, true, output);
3909 ty::ty_unboxed_closure(..) => {
3910 output.push_str("closure");
3915 ty::ty_param(_) => {
3916 cx.sess().bug(format!("debuginfo: Trying to create type name for \
3917 unexpected type: {}", ppaux::ty_to_string(cx.tcx(), t)).as_slice());
3921 fn push_item_name(cx: &CrateContext,
3924 output: &mut String) {
3925 ty::with_path(cx.tcx(), def_id, |mut path| {
3927 if def_id.krate == ast::LOCAL_CRATE {
3928 output.push_str(crate_root_namespace(cx));
3929 output.push_str("::");
3932 let mut path_element_count = 0u;
3933 for path_element in path {
3934 let name = token::get_name(path_element.name());
3935 output.push_str(name.get());
3936 output.push_str("::");
3937 path_element_count += 1;
3940 if path_element_count == 0 {
3941 cx.sess().bug("debuginfo: Encountered empty item path!");
3947 let name = token::get_name(path.last()
3948 .expect("debuginfo: Empty item path?")
3950 output.push_str(name.get());
3955 // Pushes the type parameters in the given `Substs` to the output string.
3956 // This ignores region parameters, since they can't reliably be
3957 // reconstructed for items from non-local crates. For local crates, this
3958 // would be possible but with inlining and LTO we have to use the least
3959 // common denominator - otherwise we would run into conflicts.
3960 fn push_type_params(cx: &CrateContext,
3961 substs: &subst::Substs,
3962 output: &mut String) {
3963 if substs.types.is_empty() {
3967 output.push_char('<');
3969 for &type_parameter in substs.types.iter() {
3970 push_debuginfo_type_name(cx, type_parameter, true, output);
3971 output.push_str(", ");
3977 output.push_char('>');
3982 //=-----------------------------------------------------------------------------
3983 // Namespace Handling
3984 //=-----------------------------------------------------------------------------
3986 struct NamespaceTreeNode {
3989 parent: Option<Weak<NamespaceTreeNode>>,
3992 impl NamespaceTreeNode {
3993 fn mangled_name_of_contained_item(&self, item_name: &str) -> String {
3994 fn fill_nested(node: &NamespaceTreeNode, output: &mut String) {
3996 Some(ref parent) => fill_nested(&*parent.upgrade().unwrap(), output),
3999 let string = token::get_name(node.name);
4000 output.push_str(format!("{}", string.get().len()).as_slice());
4001 output.push_str(string.get());
4004 let mut name = String::from_str("_ZN");
4005 fill_nested(self, &mut name);
4006 name.push_str(format!("{}", item_name.len()).as_slice());
4007 name.push_str(item_name);
4008 name.push_char('E');
4013 fn crate_root_namespace<'a>(cx: &'a CrateContext) -> &'a str {
4014 cx.link_meta().crate_name.as_slice()
4017 fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTreeNode> {
4018 ty::with_path(cx.tcx(), def_id, |path| {
4019 // prepend crate name if not already present
4020 let krate = if def_id.krate == ast::LOCAL_CRATE {
4021 let crate_namespace_ident = token::str_to_ident(crate_root_namespace(cx));
4022 Some(ast_map::PathMod(crate_namespace_ident.name))
4026 let mut path = krate.into_iter().chain(path).peekable();
4028 let mut current_key = Vec::new();
4029 let mut parent_node: Option<Rc<NamespaceTreeNode>> = None;
4031 // Create/Lookup namespace for each element of the path.
4033 // Emulate a for loop so we can use peek below.
4034 let path_element = match path.next() {
4038 // Ignore the name of the item (the last path element).
4039 if path.peek().is_none() {
4043 let name = path_element.name();
4044 current_key.push(name);
4046 let existing_node = debug_context(cx).namespace_map.borrow()
4047 .find_copy(¤t_key);
4048 let current_node = match existing_node {
4049 Some(existing_node) => existing_node,
4051 // create and insert
4052 let parent_scope = match parent_node {
4053 Some(ref node) => node.scope,
4054 None => ptr::null_mut()
4056 let namespace_name = token::get_name(name);
4057 let scope = namespace_name.get().with_c_str(|namespace_name| {
4059 llvm::LLVMDIBuilderCreateNameSpace(
4063 // cannot reconstruct file ...
4065 // ... or line information, but that's not so important.
4070 let node = Rc::new(NamespaceTreeNode {
4073 parent: parent_node.map(|parent| parent.downgrade()),
4076 debug_context(cx).namespace_map.borrow_mut()
4077 .insert(current_key.clone(), node.clone());
4083 parent_node = Some(current_node);
4089 cx.sess().bug(format!("debuginfo::namespace_for_item(): \
4090 path too short for {:?}",
4091 def_id).as_slice());