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
56 ## Recursive Types Some kinds of types, such as structs and enums can be
57 recursive. That means that the type definition of some type X refers to some
58 other type which in turn (transitively) refers to X. This introduces cycles into
59 the type referral graph. A naive algorithm doing an on-demand, depth-first
60 traversal of this graph when describing types, can get trapped in an endless
61 loop when it reaches such a cycle.
63 For example, the following simple type for a singly-linked list...
68 tail: Option<Box<List>>,
72 will generate the following callstack with a naive DFS algorithm:
77 describe(t = Option<Box<List>>)
78 describe(t = Box<List>)
79 describe(t = List) // at the beginning again...
83 To break cycles like these, we use "forward declarations". That is, when the
84 algorithm encounters a possibly recursive type (any struct or enum), it
85 immediately creates a type description node and inserts it into the cache
86 *before* describing the members of the type. This type description is just a
87 stub (as type members are not described and added to it yet) but it allows the
88 algorithm to already refer to the type. After the stub is inserted into the
89 cache, the algorithm continues as before. If it now encounters a recursive
90 reference, it will hit the cache and does not try to describe the type anew.
92 This behaviour is encapsulated in the 'RecursiveTypeDescription' enum, which
93 represents a kind of continuation, storing all state needed to continue
94 traversal at the type members after the type has been registered with the cache.
95 (This implementation approach might be a tad over-engineered and may change in
99 ## Source Locations and Line Information In addition to data type descriptions
100 the debugging information must also allow to map machine code locations back to
101 source code locations in order to be useful. This functionality is also handled
102 in this module. The following functions allow to control source mappings:
104 + set_source_location()
105 + clear_source_location()
106 + start_emitting_source_locations()
108 `set_source_location()` allows to set the current source location. All IR
109 instructions created after a call to this function will be linked to the given
110 source location, until another location is specified with
111 `set_source_location()` or the source location is cleared with
112 `clear_source_location()`. In the later case, subsequent IR instruction will not
113 be linked to any source location. As you can see, this is a stateful API
114 (mimicking the one in LLVM), so be careful with source locations set by previous
115 calls. It's probably best to not rely on any specific state being present at a
118 One topic that deserves some extra attention is *function prologues*. At the
119 beginning of a function's machine code there are typically a few instructions
120 for loading argument values into allocas and checking if there's enough stack
121 space for the function to execute. This *prologue* is not visible in the source
122 code and LLVM puts a special PROLOGUE END marker into the line table at the
123 first non-prologue instruction of the function. In order to find out where the
124 prologue ends, LLVM looks for the first instruction in the function body that is
125 linked to a source location. So, when generating prologue instructions we have
126 to make sure that we don't emit source location information until the 'real'
127 function body begins. For this reason, source location emission is disabled by
128 default for any new function being translated and is only activated after a call
129 to the third function from the list above, `start_emitting_source_locations()`.
130 This function should be called right before regularly starting to translate the
131 top-level block of the given function.
133 There is one exception to the above rule: `llvm.dbg.declare` instruction must be
134 linked to the source location of the variable being declared. For function
135 parameters these `llvm.dbg.declare` instructions typically occur in the middle
136 of the prologue, however, they are ignored by LLVM's prologue detection. The
137 `create_argument_metadata()` and related functions take care of linking the
138 `llvm.dbg.declare` instructions to the correct source locations even while
139 source location emission is still disabled, so there is no need to do anything
140 special with source location handling here.
142 ## Unique Type Identification In order for link-time optimization to work
143 properly, LLVM needs a unique type identifier that tells it across compilation
144 units which types are the same as others. This type identifier is created by
145 TypeMap::get_unique_type_id_of_type() using the following algorithm:
147 (1) Primitive types have their name as ID
148 (2) Structs, enums and traits have a multipart identifier
150 (1) The first part is the SVH (strict version hash) of the crate they were
151 originally defined in
153 (2) The second part is the ast::NodeId of the definition in their original
156 (3) The final part is a concatenation of the type IDs of their concrete type
157 arguments if they are generic types.
159 (3) Tuple-, pointer and function types are structurally identified, which means
160 that they are equivalent if their component types are equivalent (i.e. (int,
161 int) is the same regardless in which crate it is used).
163 This algorithm also provides a stable ID for types that are defined in one crate
164 but instantiated from metadata within another crate. We just have to take care
165 to always map crate and node IDs back to the original crate context.
167 As a side-effect these unique type IDs also help to solve a problem arising from
168 lifetime parameters. Since lifetime parameters are completely omitted in
169 debuginfo, more than one `ty::t` instance may map to the same debuginfo type
170 metadata, that is, some struct `Struct<'a>` may have N instantiations with
171 different concrete substitutions for `'a`, and thus there will be N `ty::t`
172 instances for the type `Struct<'a>` even though it is not generic otherwise.
173 Unfortunately this means that we cannot use `ty::type_id()` as cheap identifier
174 for type metadata---we have done this in the past, but it led to unnecessary
175 metadata duplication in the best case and LLVM assertions in the worst. However,
176 the unique type ID as described above *can* be used as identifier. Since it is
177 comparatively expensive to construct, though, `ty::type_id()` is still used
178 additionally as an optimization for cases where the exact same type has been
179 seen before (which is most of the time). */
182 use driver::config::{FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
184 use lib::llvm::{ModuleRef, ContextRef, ValueRef};
185 use lib::llvm::debuginfo::*;
186 use metadata::csearch;
188 use middle::trans::adt;
189 use middle::trans::common::*;
190 use middle::trans::datum::{Datum, Lvalue};
191 use middle::trans::machine;
192 use middle::trans::type_of;
193 use middle::trans::type_::Type;
196 use middle::pat_util;
199 use libc::{c_uint, c_ulonglong, c_longlong};
200 use std::c_str::{CString, ToCStr};
201 use std::cell::{Cell, RefCell};
202 use std::collections::HashMap;
203 use std::collections::HashSet;
206 use std::rc::{Rc, Weak};
207 use syntax::util::interner::Interner;
208 use syntax::codemap::{Span, Pos};
209 use syntax::{abi, ast, codemap, ast_util, ast_map};
210 use syntax::owned_slice::OwnedSlice;
211 use syntax::parse::token;
212 use syntax::parse::token::special_idents;
214 static DW_LANG_RUST: c_uint = 0x9000;
216 static DW_TAG_auto_variable: c_uint = 0x100;
217 static DW_TAG_arg_variable: c_uint = 0x101;
219 static DW_ATE_boolean: c_uint = 0x02;
220 static DW_ATE_float: c_uint = 0x04;
221 static DW_ATE_signed: c_uint = 0x05;
222 static DW_ATE_unsigned: c_uint = 0x07;
223 static DW_ATE_unsigned_char: c_uint = 0x08;
225 //=-----------------------------------------------------------------------------
226 // Public Interface of debuginfo module
227 //=-----------------------------------------------------------------------------
229 #[deriving(Copy, Show, Hash, Eq, PartialEq, Clone)]
230 struct UniqueTypeId(ast::Name);
232 // The TypeMap is where the CrateDebugContext holds the type metadata nodes
233 // created so far. The metadata nodes are indexed by UniqueTypeId, and, for
234 // faster lookup, also by ty::t. The TypeMap is responsible for creating
237 // The UniqueTypeIds created so far
238 unique_id_interner: Interner<Rc<String>>,
239 // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
240 unique_id_to_metadata: HashMap<UniqueTypeId, DIType>,
241 // A map from ty::type_id() to debuginfo metadata. This is a N:1 mapping.
242 type_to_metadata: HashMap<uint, DIType>,
243 // A map from ty::type_id() to UniqueTypeId. This is a N:1 mapping.
244 type_to_unique_id: HashMap<uint, UniqueTypeId>
249 fn new() -> TypeMap {
251 unique_id_interner: Interner::new(),
252 type_to_metadata: HashMap::new(),
253 unique_id_to_metadata: HashMap::new(),
254 type_to_unique_id: HashMap::new(),
258 // Adds a ty::t to metadata mapping to the TypeMap. The method will fail if
259 // the mapping already exists.
260 fn register_type_with_metadata(&mut self,
264 if !self.type_to_metadata.insert(ty::type_id(type_), metadata) {
265 cx.sess().bug(format!("Type metadata for ty::t '{}' is already in the TypeMap!",
266 ppaux::ty_to_str(cx.tcx(), type_)).as_slice());
270 // Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
271 // fail if the mapping already exists.
272 fn register_unique_id_with_metadata(&mut self,
274 unique_type_id: UniqueTypeId,
276 if !self.unique_id_to_metadata.insert(unique_type_id, metadata) {
277 let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id);
278 cx.sess().bug(format!("Type metadata for unique id '{}' is already in the TypeMap!",
279 unique_type_id_str.as_slice()).as_slice());
283 fn find_metadata_for_type(&self, type_: ty::t) -> Option<DIType> {
284 self.type_to_metadata.find_copy(&ty::type_id(type_))
287 fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<DIType> {
288 self.unique_id_to_metadata.find_copy(&unique_type_id)
291 // Get the string representation of a UniqueTypeId. This method will fail if
292 // the id is unknown.
293 fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> Rc<String> {
294 let UniqueTypeId(interner_key) = unique_type_id;
295 self.unique_id_interner.get(interner_key)
298 // Get the UniqueTypeId for the given type. If the UniqueTypeId for the given
299 // type has been requested before, this is just a table lookup. Otherwise an
300 // ID will be generated and stored for later lookup.
301 fn get_unique_type_id_of_type(&mut self, cx: &CrateContext, type_: ty::t) -> UniqueTypeId {
303 // basic type -> {:name of the type:}
304 // tuple -> {tuple_(:param-uid:)*}
305 // struct -> {struct_:svh: / :node-id:_<(:param-uid:),*> }
306 // enum -> {enum_:svh: / :node-id:_<(:param-uid:),*> }
307 // enum variant -> {variant_:variant-name:_:enum-uid:}
308 // reference (&) -> {& :pointee-uid:}
309 // mut reference (&mut) -> {&mut :pointee-uid:}
310 // ptr (*) -> {* :pointee-uid:}
311 // mut ptr (*mut) -> {*mut :pointee-uid:}
312 // unique ptr (~) -> {~ :pointee-uid:}
313 // @-ptr (@) -> {@ :pointee-uid:}
314 // sized vec ([T, ..x]) -> {[:size:] :element-uid:}
315 // unsized vec ([T]) -> {[] :element-uid:}
316 // trait (T) -> {trait_:svh: / :node-id:_<(:param-uid:),*> }
317 // closure -> {<unsafe_> <once_> :store-sigil: |(:param-uid:),* <,_...>| -> \
318 // :return-type-uid: : (:bounds:)*}
319 // function -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \
320 // :return-type-uid:}
321 // unique vec box (~[]) -> {HEAP_VEC_BOX<:pointee-uid:>}
322 // gc box -> {GC_BOX<:pointee-uid:>}
324 match self.type_to_unique_id.find_copy(&ty::type_id(type_)) {
325 Some(unique_type_id) => return unique_type_id,
326 None => { /* generate one */}
329 let mut unique_type_id = String::with_capacity(256);
330 unique_type_id.push_char('{');
332 match ty::get(type_).sty {
341 unique_type_id.push_str(ppaux::ty_to_str(cx.tcx(), type_).as_slice());
343 ty::ty_enum(def_id, ref substs) => {
344 unique_type_id.push_str("enum ");
345 from_def_id_and_substs(self, cx, def_id, substs, &mut unique_type_id);
347 ty::ty_struct(def_id, ref substs) => {
348 unique_type_id.push_str("struct ");
349 from_def_id_and_substs(self, cx, def_id, substs, &mut unique_type_id);
351 ty::ty_tup(ref component_types) => {
352 unique_type_id.push_str("tuple ");
353 for &component_type in component_types.iter() {
354 let component_type_id =
355 self.get_unique_type_id_of_type(cx, component_type);
356 let component_type_id =
357 self.get_unique_type_id_as_string(component_type_id);
358 unique_type_id.push_str(component_type_id.as_slice());
361 ty::ty_box(inner_type) => {
362 unique_type_id.push_char('@');
363 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
364 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
365 unique_type_id.push_str(inner_type_id.as_slice());
367 ty::ty_uniq(inner_type) => {
368 unique_type_id.push_char('~');
369 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
370 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
371 unique_type_id.push_str(inner_type_id.as_slice());
373 ty::ty_ptr(ty::mt { ty: inner_type, mutbl } ) => {
374 unique_type_id.push_char('*');
375 if mutbl == ast::MutMutable {
376 unique_type_id.push_str("mut");
379 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
380 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
381 unique_type_id.push_str(inner_type_id.as_slice());
383 ty::ty_rptr(_, ty::mt { ty: inner_type, mutbl }) => {
384 unique_type_id.push_char('&');
385 if mutbl == ast::MutMutable {
386 unique_type_id.push_str("mut");
389 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
390 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
391 unique_type_id.push_str(inner_type_id.as_slice());
393 ty::ty_vec(ty::mt { ty: inner_type, .. }, optional_length) => {
394 match optional_length {
396 unique_type_id.push_str(format!("[{}]", len).as_slice());
399 unique_type_id.push_str("[]");
403 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
404 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
405 unique_type_id.push_str(inner_type_id.as_slice());
407 ty::ty_trait(ref trait_data) => {
408 unique_type_id.push_str("trait ");
410 from_def_id_and_substs(self,
414 &mut unique_type_id);
416 ty::ty_bare_fn(ty::BareFnTy{ fn_style, abi, ref sig } ) => {
417 if fn_style == ast::UnsafeFn {
418 unique_type_id.push_str("unsafe ");
421 unique_type_id.push_str(abi.name());
423 unique_type_id.push_str(" fn(");
425 for ¶meter_type in sig.inputs.iter() {
426 let parameter_type_id =
427 self.get_unique_type_id_of_type(cx, parameter_type);
428 let parameter_type_id =
429 self.get_unique_type_id_as_string(parameter_type_id);
430 unique_type_id.push_str(parameter_type_id.as_slice());
431 unique_type_id.push_char(',');
435 unique_type_id.push_str("...");
438 unique_type_id.push_str(")->");
439 let return_type_id = self.get_unique_type_id_of_type(cx, sig.output);
440 let return_type_id = self.get_unique_type_id_as_string(return_type_id);
441 unique_type_id.push_str(return_type_id.as_slice());
443 ty::ty_closure(box ty::ClosureTy { fn_style,
448 if fn_style == ast::UnsafeFn {
449 unique_type_id.push_str("unsafe ");
452 if onceness == ast::Once {
453 unique_type_id.push_str("once ");
457 ty::UniqTraitStore => unique_type_id.push_str("~|"),
458 ty::RegionTraitStore(_, ast::MutMutable) => {
459 unique_type_id.push_str("&mut|")
461 ty::RegionTraitStore(_, ast::MutImmutable) => {
462 unique_type_id.push_str("&|")
466 for ¶meter_type in sig.inputs.iter() {
467 let parameter_type_id =
468 self.get_unique_type_id_of_type(cx, parameter_type);
469 let parameter_type_id =
470 self.get_unique_type_id_as_string(parameter_type_id);
471 unique_type_id.push_str(parameter_type_id.as_slice());
472 unique_type_id.push_char(',');
476 unique_type_id.push_str("...");
479 unique_type_id.push_str("|->");
481 let return_type_id = self.get_unique_type_id_of_type(cx, sig.output);
482 let return_type_id = self.get_unique_type_id_as_string(return_type_id);
483 unique_type_id.push_str(return_type_id.as_slice());
485 unique_type_id.push_char(':');
487 for bound in bounds.iter() {
489 ty::BoundStatic => unique_type_id.push_str("'static"),
490 ty::BoundSend => unique_type_id.push_str("Send"),
491 ty::BoundSized => unique_type_id.push_str("Sized"),
492 ty::BoundCopy => unique_type_id.push_str("Copy"),
493 ty::BoundShare => unique_type_id.push_str("Share"),
495 unique_type_id.push_char('+');
499 cx.sess().bug(format!("get_unique_type_id_of_type() - unexpected type: {}, {:?}",
500 ppaux::ty_to_str(cx.tcx(), type_).as_slice(),
501 ty::get(type_).sty).as_slice())
505 unique_type_id.push_char('}');
507 // Trim to size before storing permanently
508 unique_type_id.shrink_to_fit();
510 let key = self.unique_id_interner.intern(Rc::new(unique_type_id));
511 self.type_to_unique_id.insert(ty::type_id(type_), UniqueTypeId(key));
513 return UniqueTypeId(key);
515 fn from_def_id_and_substs(type_map: &mut TypeMap,
518 substs: &subst::Substs,
519 output: &mut String) {
520 use std::num::ToStrRadix;
522 // First, find out the 'real' def_id of the type. Items inlined from
523 // other crates have to be mapped back to their source.
524 let source_def_id = if def_id.krate == ast::LOCAL_CRATE {
525 match cx.external_srcs.borrow().find_copy(&def_id.node) {
526 Some(source_def_id) => {
527 // The given def_id identifies the inlined copy of a
528 // type definition, let's take the source of the copy.
537 // Get the crate hash as first part of the identifier.
538 let crate_hash = if source_def_id.krate == ast::LOCAL_CRATE {
539 cx.link_meta.crate_hash.clone()
541 cx.sess().cstore.get_crate_hash(source_def_id.krate)
544 output.push_str(crate_hash.as_str());
545 output.push_str("/");
546 output.push_str(def_id.node.to_str_radix(16).as_slice());
548 // Maybe check that there is no self type here.
550 let tps = substs.types.get_vec(subst::TypeSpace);
552 output.push_char('<');
554 for &type_parameter in tps.iter() {
556 type_map.get_unique_type_id_of_type(cx, type_parameter);
558 type_map.get_unique_type_id_as_string(param_type_id);
559 output.push_str(param_type_id.as_slice());
560 output.push_char(',');
563 output.push_char('>');
568 // Get the UniqueTypeId for an enum variant. Enum variants are not really
569 // types of their own, so they need special handling. We still need a
570 // UniqueTypeId for them, since to debuginfo they *are* real types.
571 fn get_unique_type_id_of_enum_variant(&mut self,
576 let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
577 let enum_variant_type_id = format!("{}::{}",
578 self.get_unique_type_id_as_string(enum_type_id)
581 let interner_key = self.unique_id_interner.intern(Rc::new(enum_variant_type_id));
582 UniqueTypeId(interner_key)
585 fn get_unique_type_id_of_heap_vec_box(&mut self,
589 let element_type_id = self.get_unique_type_id_of_type(cx, element_type);
590 let heap_vec_box_type_id = format!("$$HEAP_VEC_BOX<{}>$$",
591 self.get_unique_type_id_as_string(element_type_id)
593 let interner_key = self.unique_id_interner.intern(Rc::new(heap_vec_box_type_id));
594 UniqueTypeId(interner_key)
597 fn get_unique_type_id_of_gc_box(&mut self,
601 let element_type_id = self.get_unique_type_id_of_type(cx, element_type);
602 let gc_box_type_id = format!("$$GC_BOX<{}>$$",
603 self.get_unique_type_id_as_string(element_type_id)
605 let interner_key = self.unique_id_interner.intern(Rc::new(gc_box_type_id));
606 UniqueTypeId(interner_key)
611 /// A context object for maintaining all state needed by the debuginfo module.
612 pub struct CrateDebugContext {
613 llcontext: ContextRef,
614 builder: DIBuilderRef,
615 current_debug_location: Cell<DebugLocation>,
616 created_files: RefCell<HashMap<String, DIFile>>,
617 created_enum_disr_types: RefCell<HashMap<ast::DefId, DIType>>,
619 type_map: RefCell<TypeMap>,
620 namespace_map: RefCell<HashMap<Vec<ast::Name>, Rc<NamespaceTreeNode>>>,
622 // This collection is used to assert that composite types (structs, enums,
623 // ...) have their members only set once:
624 composite_types_completed: RefCell<HashSet<DIType>>,
627 impl CrateDebugContext {
628 pub fn new(llmod: ModuleRef) -> CrateDebugContext {
629 debug!("CrateDebugContext::new");
630 let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) };
631 // DIBuilder inherits context from the module, so we'd better use the same one
632 let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
633 return CrateDebugContext {
634 llcontext: llcontext,
636 current_debug_location: Cell::new(UnknownLocation),
637 created_files: RefCell::new(HashMap::new()),
638 created_enum_disr_types: RefCell::new(HashMap::new()),
639 type_map: RefCell::new(TypeMap::new()),
640 namespace_map: RefCell::new(HashMap::new()),
641 composite_types_completed: RefCell::new(HashSet::new()),
646 pub struct FunctionDebugContext {
647 repr: FunctionDebugContextRepr,
650 enum FunctionDebugContextRepr {
651 FunctionDebugContext(Box<FunctionDebugContextData>),
653 FunctionWithoutDebugInfo,
656 impl FunctionDebugContext {
657 fn get_ref<'a>(&'a self,
660 -> &'a FunctionDebugContextData {
662 FunctionDebugContext(box ref data) => data,
663 DebugInfoDisabled => {
664 cx.sess().span_bug(span,
665 FunctionDebugContext::debuginfo_disabled_message());
667 FunctionWithoutDebugInfo => {
668 cx.sess().span_bug(span,
669 FunctionDebugContext::should_be_ignored_message());
674 fn debuginfo_disabled_message() -> &'static str {
675 "debuginfo: Error trying to access FunctionDebugContext although debug info is disabled!"
678 fn should_be_ignored_message() -> &'static str {
679 "debuginfo: Error trying to access FunctionDebugContext for function that should be \
680 ignored by debug info!"
684 struct FunctionDebugContextData {
685 scope_map: RefCell<HashMap<ast::NodeId, DIScope>>,
686 fn_metadata: DISubprogram,
687 argument_counter: Cell<uint>,
688 source_locations_enabled: Cell<bool>,
691 enum VariableAccess<'a> {
692 // The llptr given is an alloca containing the variable's value
693 DirectVariable { alloca: ValueRef },
694 // The llptr given is an alloca containing the start of some pointer chain
695 // leading to the variable's content.
696 IndirectVariable { alloca: ValueRef, address_operations: &'a [ValueRef] }
700 ArgumentVariable(uint /*index*/),
705 /// Create any deferred debug metadata nodes
706 pub fn finalize(cx: &CrateContext) {
707 if cx.dbg_cx.is_none() {
712 compile_unit_metadata(cx);
714 llvm::LLVMDIBuilderFinalize(DIB(cx));
715 llvm::LLVMDIBuilderDispose(DIB(cx));
716 // Debuginfo generation in LLVM by default uses a higher
717 // version of dwarf than OS X currently understands. We can
718 // instruct LLVM to emit an older version of dwarf, however,
719 // for OS X to understand. For more info see #11352
720 // This can be overridden using --llvm-opts -dwarf-version,N.
721 if cx.sess().targ_cfg.os == abi::OsMacos ||
722 cx.sess().targ_cfg.os == abi::OsiOS {
723 "Dwarf Version".with_c_str(
724 |s| llvm::LLVMRustAddModuleFlag(cx.llmod, s, 2));
726 // FIXME(#13611) this is a kludge fix because the linux bots have
727 // gdb 7.4 which doesn't understand dwarf4, we should
728 // do something more graceful here.
729 "Dwarf Version".with_c_str(
730 |s| llvm::LLVMRustAddModuleFlag(cx.llmod, s, 3));
733 // Prevent bitcode readers from deleting the debug info.
734 "Debug Info Version".with_c_str(
735 |s| llvm::LLVMRustAddModuleFlag(cx.llmod, s,
736 llvm::LLVMRustDebugMetadataVersion));
740 /// Creates debug information for the given global variable.
742 /// Adds the created metadata nodes directly to the crate's IR.
743 pub fn create_global_var_metadata(cx: &CrateContext,
744 node_id: ast::NodeId,
746 if cx.dbg_cx.is_none() {
750 // Don't create debuginfo for globals inlined from other crates. The other
751 // crate should already contain debuginfo for it. More importantly, the
752 // global might not even exist in un-inlined form anywhere which would lead
753 // to a linker errors.
754 if cx.external_srcs.borrow().contains_key(&node_id) {
758 let var_item = cx.tcx.map.get(node_id);
760 let (ident, span) = match var_item {
761 ast_map::NodeItem(item) => {
763 ast::ItemStatic(..) => (item.ident, item.span),
767 format!("debuginfo::\
768 create_global_var_metadata() -
769 Captured var-id refers to \
770 unexpected ast_item variant: {:?}",
771 var_item).as_slice())
775 _ => cx.sess().bug(format!("debuginfo::create_global_var_metadata() \
776 - Captured var-id refers to unexpected \
777 ast_map variant: {:?}",
778 var_item).as_slice())
781 let filename = span_start(cx, span).file.name.clone();
782 let file_metadata = file_metadata(cx, filename.as_slice());
784 let is_local_to_unit = is_node_local_to_unit(cx, node_id);
785 let loc = span_start(cx, span);
787 let variable_type = ty::node_id_to_type(cx.tcx(), node_id);
788 let type_metadata = type_metadata(cx, variable_type, span);
790 let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
791 let var_name = token::get_ident(ident).get().to_str();
793 namespace_node.mangled_name_of_contained_item(var_name.as_slice());
794 let var_scope = namespace_node.scope;
796 var_name.as_slice().with_c_str(|var_name| {
797 linkage_name.as_slice().with_c_str(|linkage_name| {
799 llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
814 /// Creates debug information for the given local variable.
816 /// Adds the created metadata nodes directly to the crate's IR.
817 pub fn create_local_var_metadata(bcx: &Block, local: &ast::Local) {
818 if fn_should_be_ignored(bcx.fcx) {
823 let def_map = &cx.tcx.def_map;
825 pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, path_ref| {
826 let var_ident = ast_util::path_to_ident(path_ref);
828 let datum = match bcx.fcx.lllocals.borrow().find_copy(&node_id) {
829 Some(datum) => datum,
831 bcx.sess().span_bug(span,
832 format!("no entry in lllocals table for {:?}",
833 node_id).as_slice());
837 let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
843 DirectVariable { alloca: datum.val },
849 /// Creates debug information for a variable captured in a closure.
851 /// Adds the created metadata nodes directly to the crate's IR.
852 pub fn create_captured_var_metadata(bcx: &Block,
853 node_id: ast::NodeId,
854 env_data_type: ty::t,
855 env_pointer: ValueRef,
857 closure_store: ty::TraitStore,
859 if fn_should_be_ignored(bcx.fcx) {
865 let ast_item = cx.tcx.map.find(node_id);
867 let variable_ident = match ast_item {
869 cx.sess().span_bug(span, "debuginfo::create_captured_var_metadata: node not found");
871 Some(ast_map::NodeLocal(pat)) | Some(ast_map::NodeArg(pat)) => {
873 ast::PatIdent(_, ref path, _) => {
874 ast_util::path_to_ident(path)
880 "debuginfo::create_captured_var_metadata() - \
881 Captured var-id refers to unexpected \
882 ast_map variant: {:?}",
883 ast_item).as_slice());
890 format!("debuginfo::create_captured_var_metadata() - \
891 Captured var-id refers to unexpected \
892 ast_map variant: {:?}",
893 ast_item).as_slice());
897 let variable_type = node_id_type(bcx, node_id);
898 let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata;
900 let llvm_env_data_type = type_of::type_of(cx, env_data_type);
901 let byte_offset_of_var_in_env = machine::llelement_offset(cx,
905 let address_operations = unsafe {
906 [llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref()),
907 llvm::LLVMDIBuilderCreateOpPlus(Type::i64(cx).to_ref()),
908 C_i64(cx, byte_offset_of_var_in_env as i64),
909 llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref())]
912 let address_op_count = match closure_store {
913 ty::RegionTraitStore(..) => {
914 address_operations.len()
916 ty::UniqTraitStore => {
917 address_operations.len() - 1
921 let variable_access = IndirectVariable {
923 address_operations: address_operations.slice_to(address_op_count)
935 /// Creates debug information for a local variable introduced in the head of a
936 /// match-statement arm.
938 /// Adds the created metadata nodes directly to the crate's IR.
939 pub fn create_match_binding_metadata(bcx: &Block,
940 variable_ident: ast::Ident,
941 node_id: ast::NodeId,
943 datum: Datum<Lvalue>) {
944 if fn_should_be_ignored(bcx.fcx) {
948 let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
954 DirectVariable { alloca: datum.val },
959 /// Creates debug information for the given function argument.
961 /// Adds the created metadata nodes directly to the crate's IR.
962 pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) {
963 if fn_should_be_ignored(bcx.fcx) {
970 let def_map = &cx.tcx.def_map;
971 let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata;
973 pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, path_ref| {
974 let llarg = match bcx.fcx.llargs.borrow().find_copy(&node_id) {
977 bcx.sess().span_bug(span,
978 format!("no entry in llargs table for {:?}",
979 node_id).as_slice());
983 if unsafe { llvm::LLVMIsAAllocaInst(llarg.val) } == ptr::mut_null() {
984 cx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \
985 Referenced variable location is not an alloca!");
988 let argument_ident = ast_util::path_to_ident(path_ref);
990 let argument_index = {
991 let counter = &fcx.debug_context.get_ref(cx, span).argument_counter;
992 let argument_index = counter.get();
993 counter.set(argument_index + 1);
1001 DirectVariable { alloca: llarg.val },
1002 ArgumentVariable(argument_index),
1007 /// Sets the current debug location at the beginning of the span.
1009 /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). The node_id
1010 /// parameter is used to reliably find the correct visibility scope for the code
1012 pub fn set_source_location(fcx: &FunctionContext,
1013 node_id: ast::NodeId,
1015 match fcx.debug_context.repr {
1016 DebugInfoDisabled => return,
1017 FunctionWithoutDebugInfo => {
1018 set_debug_location(fcx.ccx, UnknownLocation);
1021 FunctionDebugContext(box ref function_debug_context) => {
1024 debug!("set_source_location: {}", cx.sess().codemap().span_to_str(span));
1026 if function_debug_context.source_locations_enabled.get() {
1027 let loc = span_start(cx, span);
1028 let scope = scope_metadata(fcx, node_id, span);
1030 set_debug_location(cx, DebugLocation::new(scope,
1032 loc.col.to_uint()));
1034 set_debug_location(cx, UnknownLocation);
1040 /// Clears the current debug location.
1042 /// Instructions generated hereafter won't be assigned a source location.
1043 pub fn clear_source_location(fcx: &FunctionContext) {
1044 if fn_should_be_ignored(fcx) {
1048 set_debug_location(fcx.ccx, UnknownLocation);
1051 /// Enables emitting source locations for the given functions.
1053 /// Since we don't want source locations to be emitted for the function prelude,
1054 /// they are disabled when beginning to translate a new function. This functions
1055 /// switches source location emitting on and must therefore be called before the
1056 /// first real statement/expression of the function is translated.
1057 pub fn start_emitting_source_locations(fcx: &FunctionContext) {
1058 match fcx.debug_context.repr {
1059 FunctionDebugContext(box ref data) => {
1060 data.source_locations_enabled.set(true)
1062 _ => { /* safe to ignore */ }
1066 /// Creates the function-specific debug context.
1068 /// Returns the FunctionDebugContext for the function which holds state needed
1069 /// for debug info creation. The function may also return another variant of the
1070 /// FunctionDebugContext enum which indicates why no debuginfo should be created
1071 /// for the function.
1072 pub fn create_function_debug_context(cx: &CrateContext,
1073 fn_ast_id: ast::NodeId,
1074 param_substs: ¶m_substs,
1075 llfn: ValueRef) -> FunctionDebugContext {
1076 if cx.sess().opts.debuginfo == NoDebugInfo {
1077 return FunctionDebugContext { repr: DebugInfoDisabled };
1080 // Clear the debug location so we don't assign them in the function prelude.
1081 // Do this here already, in case we do an early exit from this function.
1082 set_debug_location(cx, UnknownLocation);
1084 if fn_ast_id == -1 {
1085 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1088 let empty_generics = ast::Generics { lifetimes: Vec::new(),
1089 ty_params: OwnedSlice::empty() };
1091 let fnitem = cx.tcx.map.get(fn_ast_id);
1093 let (ident, fn_decl, generics, top_level_block, span, has_path) = match fnitem {
1094 ast_map::NodeItem(ref item) => {
1096 ast::ItemFn(fn_decl, _, _, ref generics, top_level_block) => {
1097 (item.ident, fn_decl, generics, top_level_block, item.span, true)
1100 cx.sess().span_bug(item.span,
1101 "create_function_debug_context: item bound to non-function");
1105 ast_map::NodeMethod(ref method) => {
1113 ast_map::NodeExpr(ref expr) => {
1115 ast::ExprFnBlock(fn_decl, top_level_block) |
1116 ast::ExprProc(fn_decl, top_level_block) => {
1117 let name = format!("fn{}", token::gensym("fn"));
1118 let name = token::str_to_ident(name.as_slice());
1120 // This is not quite right. It should actually inherit
1121 // the generics of the enclosing function.
1125 // Don't try to lookup the item path:
1128 _ => cx.sess().span_bug(expr.span,
1129 "create_function_debug_context: expected an expr_fn_block here")
1132 ast_map::NodeTraitMethod(ref trait_method) => {
1133 match **trait_method {
1134 ast::Provided(ref method) => {
1144 .bug(format!("create_function_debug_context: \
1145 unexpected sort of node: {:?}",
1150 ast_map::NodeForeignItem(..) |
1151 ast_map::NodeVariant(..) |
1152 ast_map::NodeStructCtor(..) => {
1153 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1155 _ => cx.sess().bug(format!("create_function_debug_context: \
1156 unexpected sort of node: {:?}",
1160 // This can be the case for functions inlined from another crate
1161 if span == codemap::DUMMY_SP {
1162 return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
1165 let loc = span_start(cx, span);
1166 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
1168 let function_type_metadata = unsafe {
1169 let fn_signature = get_function_signature(cx,
1174 llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
1177 // Get_template_parameters() will append a `<...>` clause to the function
1178 // name if necessary.
1179 let mut function_name = String::from_str(token::get_ident(ident).get());
1180 let template_parameters = get_template_parameters(cx,
1184 &mut function_name);
1186 // There is no ast_map::Path for ast::ExprFnBlock-type functions. For now,
1187 // just don't put them into a namespace. In the future this could be improved
1188 // somehow (storing a path in the ast_map, or construct a path using the
1189 // enclosing function).
1190 let (linkage_name, containing_scope) = if has_path {
1191 let namespace_node = namespace_for_item(cx, ast_util::local_def(fn_ast_id));
1192 let linkage_name = namespace_node.mangled_name_of_contained_item(
1193 function_name.as_slice());
1194 let containing_scope = namespace_node.scope;
1195 (linkage_name, containing_scope)
1197 (function_name.as_slice().to_string(), file_metadata)
1200 // Clang sets this parameter to the opening brace of the function's block,
1201 // so let's do this too.
1202 let scope_line = span_start(cx, top_level_block.span).line;
1204 let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id);
1206 let fn_metadata = function_name.as_slice().with_c_str(|function_name| {
1207 linkage_name.as_slice().with_c_str(|linkage_name| {
1209 llvm::LLVMDIBuilderCreateFunction(
1216 function_type_metadata,
1219 scope_line as c_uint,
1220 FlagPrototyped as c_uint,
1221 cx.sess().opts.optimize != config::No,
1223 template_parameters,
1229 // Initialize fn debug context (including scope map and namespace map)
1230 let fn_debug_context = box FunctionDebugContextData {
1231 scope_map: RefCell::new(HashMap::new()),
1232 fn_metadata: fn_metadata,
1233 argument_counter: Cell::new(1),
1234 source_locations_enabled: Cell::new(false),
1237 let arg_pats = fn_decl.inputs.iter().map(|arg_ref| arg_ref.pat).collect::<Vec<_>>();
1238 populate_scope_map(cx,
1239 arg_pats.as_slice(),
1242 &mut *fn_debug_context.scope_map.borrow_mut());
1244 return FunctionDebugContext { repr: FunctionDebugContext(fn_debug_context) };
1246 fn get_function_signature(cx: &CrateContext,
1247 fn_ast_id: ast::NodeId,
1248 fn_decl: &ast::FnDecl,
1249 param_substs: ¶m_substs,
1250 error_span: Span) -> DIArray {
1251 if cx.sess().opts.debuginfo == LimitedDebugInfo {
1252 return create_DIArray(DIB(cx), []);
1255 let mut signature = Vec::with_capacity(fn_decl.inputs.len() + 1);
1257 // Return type -- llvm::DIBuilder wants this at index 0
1258 match fn_decl.output.node {
1260 signature.push(ptr::mut_null());
1263 assert_type_for_node_id(cx, fn_ast_id, error_span);
1265 let return_type = ty::node_id_to_type(cx.tcx(), fn_ast_id);
1266 let return_type = return_type.substp(cx.tcx(), param_substs);
1267 signature.push(type_metadata(cx, return_type, codemap::DUMMY_SP));
1272 for arg in fn_decl.inputs.iter() {
1273 assert_type_for_node_id(cx, arg.pat.id, arg.pat.span);
1274 let arg_type = ty::node_id_to_type(cx.tcx(), arg.pat.id);
1275 let arg_type = arg_type.substp(cx.tcx(), param_substs);
1276 signature.push(type_metadata(cx, arg_type, codemap::DUMMY_SP));
1279 return create_DIArray(DIB(cx), signature.as_slice());
1282 fn get_template_parameters(cx: &CrateContext,
1283 generics: &ast::Generics,
1284 param_substs: ¶m_substs,
1285 file_metadata: DIFile,
1286 name_to_append_suffix_to: &mut String)
1288 let self_type = param_substs.substs.self_ty();
1290 // Only true for static default methods:
1291 let has_self_type = self_type.is_some();
1293 if !generics.is_type_parameterized() && !has_self_type {
1294 return create_DIArray(DIB(cx), []);
1297 name_to_append_suffix_to.push_char('<');
1299 // The list to be filled with template parameters:
1300 let mut template_params: Vec<DIDescriptor> =
1301 Vec::with_capacity(generics.ty_params.len() + 1);
1305 let actual_self_type = self_type.unwrap();
1306 // Add self type name to <...> clause of function name
1307 let actual_self_type_name = ppaux::ty_to_str(cx.tcx(), actual_self_type);
1308 name_to_append_suffix_to.push_str(
1309 actual_self_type_name.as_slice());
1311 if generics.is_type_parameterized() {
1312 name_to_append_suffix_to.push_str(",");
1315 // Only create type information if full debuginfo is enabled
1316 if cx.sess().opts.debuginfo == FullDebugInfo {
1317 let actual_self_type_metadata = type_metadata(cx,
1321 let ident = special_idents::type_self;
1323 let param_metadata = token::get_ident(ident).get()
1324 .with_c_str(|name| {
1326 llvm::LLVMDIBuilderCreateTemplateTypeParameter(
1330 actual_self_type_metadata,
1337 template_params.push(param_metadata);
1341 // Handle other generic parameters
1342 let actual_types = param_substs.substs.types.get_vec(subst::FnSpace);
1343 for (index, &ast::TyParam{ ident: ident, .. }) in generics.ty_params.iter().enumerate() {
1344 let actual_type = *actual_types.get(index);
1345 // Add actual type name to <...> clause of function name
1346 let actual_type_name = ppaux::ty_to_str(cx.tcx(), actual_type);
1347 name_to_append_suffix_to.push_str(actual_type_name.as_slice());
1349 if index != generics.ty_params.len() - 1 {
1350 name_to_append_suffix_to.push_str(",");
1353 // Again, only create type information if full debuginfo is enabled
1354 if cx.sess().opts.debuginfo == FullDebugInfo {
1355 let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP);
1356 let param_metadata = token::get_ident(ident).get()
1357 .with_c_str(|name| {
1359 llvm::LLVMDIBuilderCreateTemplateTypeParameter(
1363 actual_type_metadata,
1369 template_params.push(param_metadata);
1373 name_to_append_suffix_to.push_char('>');
1375 return create_DIArray(DIB(cx), template_params.as_slice());
1379 //=-----------------------------------------------------------------------------
1380 // Module-Internal debug info creation functions
1381 //=-----------------------------------------------------------------------------
1383 fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool
1385 // The is_local_to_unit flag indicates whether a function is local to the
1386 // current compilation unit (i.e. if it is *static* in the C-sense). The
1387 // *reachable* set should provide a good approximation of this, as it
1388 // contains everything that might leak out of the current crate (by being
1389 // externally visible or by being inlined into something externally visible).
1390 // It might better to use the `exported_items` set from `driver::CrateAnalysis`
1391 // in the future, but (atm) this set is not available in the translation pass.
1392 !cx.reachable.contains(&node_id)
1395 #[allow(non_snake_case_functions)]
1396 fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
1398 llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
1402 fn compile_unit_metadata(cx: &CrateContext) {
1403 let work_dir = &cx.sess().working_dir;
1404 let compile_unit_name = match cx.sess().local_crate_source_file {
1405 None => fallback_path(cx),
1406 Some(ref abs_path) => {
1407 if abs_path.is_relative() {
1408 cx.sess().warn("debuginfo: Invalid path to crate's local root source file!");
1411 match abs_path.path_relative_from(work_dir) {
1412 Some(ref p) if p.is_relative() => {
1413 // prepend "./" if necessary
1415 let prefix = &[dotdot[0], ::std::path::SEP_BYTE];
1416 let mut path_bytes = Vec::from_slice(p.as_vec());
1418 if path_bytes.slice_to(2) != prefix &&
1419 path_bytes.slice_to(2) != dotdot {
1420 path_bytes.insert(0, prefix[0]);
1421 path_bytes.insert(1, prefix[1]);
1424 path_bytes.as_slice().to_c_str()
1426 _ => fallback_path(cx)
1432 debug!("compile_unit_metadata: {:?}", compile_unit_name);
1433 let producer = format!("rustc version {}",
1434 (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
1436 compile_unit_name.with_ref(|compile_unit_name| {
1437 work_dir.as_vec().with_c_str(|work_dir| {
1438 producer.with_c_str(|producer| {
1439 "".with_c_str(|flags| {
1440 "".with_c_str(|split_name| {
1442 llvm::LLVMDIBuilderCreateCompileUnit(
1443 debug_context(cx).builder,
1448 cx.sess().opts.optimize != config::No,
1459 fn fallback_path(cx: &CrateContext) -> CString {
1460 cx.link_meta.crateid.name.as_slice().to_c_str()
1464 fn declare_local(bcx: &Block,
1465 variable_ident: ast::Ident,
1466 variable_type: ty::t,
1467 scope_metadata: DIScope,
1468 variable_access: VariableAccess,
1469 variable_kind: VariableKind,
1471 let cx: &CrateContext = bcx.ccx();
1473 let filename = span_start(cx, span).file.name.clone();
1474 let file_metadata = file_metadata(cx, filename.as_slice());
1476 let name = token::get_ident(variable_ident);
1477 let loc = span_start(cx, span);
1478 let type_metadata = type_metadata(cx, variable_type, span);
1480 let (argument_index, dwarf_tag) = match variable_kind {
1481 ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
1483 CapturedVariable => (0, DW_TAG_auto_variable)
1486 let (var_alloca, var_metadata) = name.get().with_c_str(|name| {
1487 match variable_access {
1488 DirectVariable { alloca } => (
1491 llvm::LLVMDIBuilderCreateLocalVariable(
1499 cx.sess().opts.optimize != config::No,
1504 IndirectVariable { alloca, address_operations } => (
1507 llvm::LLVMDIBuilderCreateComplexVariable(
1515 address_operations.as_ptr(),
1516 address_operations.len() as c_uint,
1523 set_debug_location(cx, DebugLocation::new(scope_metadata,
1525 loc.col.to_uint()));
1527 let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
1533 llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
1536 match variable_kind {
1537 ArgumentVariable(_) | CapturedVariable => {
1541 .source_locations_enabled
1543 set_debug_location(cx, UnknownLocation);
1545 _ => { /* nothing to do */ }
1549 fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
1550 match debug_context(cx).created_files.borrow().find_equiv(&full_path) {
1551 Some(file_metadata) => return *file_metadata,
1555 debug!("file_metadata: {}", full_path);
1557 // FIXME (#9639): This needs to handle non-utf8 paths
1558 let work_dir = cx.sess().working_dir.as_str().unwrap();
1560 if full_path.starts_with(work_dir) {
1561 full_path.slice(work_dir.len() + 1u, full_path.len())
1567 file_name.with_c_str(|file_name| {
1568 work_dir.with_c_str(|work_dir| {
1570 llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir)
1575 let mut created_files = debug_context(cx).created_files.borrow_mut();
1576 created_files.insert(full_path.to_string(), file_metadata);
1577 return file_metadata;
1580 /// Finds the scope metadata node for the given AST node.
1581 fn scope_metadata(fcx: &FunctionContext,
1582 node_id: ast::NodeId,
1585 let scope_map = &fcx.debug_context.get_ref(fcx.ccx, span).scope_map;
1586 match scope_map.borrow().find_copy(&node_id) {
1587 Some(scope_metadata) => scope_metadata,
1589 let node = fcx.ccx.tcx.map.get(node_id);
1591 fcx.ccx.sess().span_bug(span,
1592 format!("debuginfo: Could not find scope info for node {:?}",
1598 fn basic_type_metadata(cx: &CrateContext, t: ty::t) -> DIType {
1600 debug!("basic_type_metadata: {:?}", ty::get(t));
1602 let (name, encoding) = match ty::get(t).sty {
1603 ty::ty_nil => ("()".to_string(), DW_ATE_unsigned),
1604 ty::ty_bot => ("!".to_string(), DW_ATE_unsigned),
1605 ty::ty_bool => ("bool".to_string(), DW_ATE_boolean),
1606 ty::ty_char => ("char".to_string(), DW_ATE_unsigned_char),
1607 ty::ty_int(int_ty) => match int_ty {
1608 ast::TyI => ("int".to_string(), DW_ATE_signed),
1609 ast::TyI8 => ("i8".to_string(), DW_ATE_signed),
1610 ast::TyI16 => ("i16".to_string(), DW_ATE_signed),
1611 ast::TyI32 => ("i32".to_string(), DW_ATE_signed),
1612 ast::TyI64 => ("i64".to_string(), DW_ATE_signed)
1614 ty::ty_uint(uint_ty) => match uint_ty {
1615 ast::TyU => ("uint".to_string(), DW_ATE_unsigned),
1616 ast::TyU8 => ("u8".to_string(), DW_ATE_unsigned),
1617 ast::TyU16 => ("u16".to_string(), DW_ATE_unsigned),
1618 ast::TyU32 => ("u32".to_string(), DW_ATE_unsigned),
1619 ast::TyU64 => ("u64".to_string(), DW_ATE_unsigned)
1621 ty::ty_float(float_ty) => match float_ty {
1622 ast::TyF32 => ("f32".to_string(), DW_ATE_float),
1623 ast::TyF64 => ("f64".to_string(), DW_ATE_float),
1625 _ => cx.sess().bug("debuginfo::basic_type_metadata - t is invalid type")
1628 let llvm_type = type_of::type_of(cx, t);
1629 let (size, align) = size_and_align_of(cx, llvm_type);
1630 let ty_metadata = name.with_c_str(|name| {
1632 llvm::LLVMDIBuilderCreateBasicType(
1635 bytes_to_bits(size),
1636 bytes_to_bits(align),
1644 fn pointer_type_metadata(cx: &CrateContext,
1645 pointer_type: ty::t,
1646 pointee_type_metadata: DIType)
1648 let pointer_llvm_type = type_of::type_of(cx, pointer_type);
1649 let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
1650 let name = ppaux::ty_to_str(cx.tcx(), pointer_type);
1651 let ptr_metadata = name.as_slice().with_c_str(|name| {
1653 llvm::LLVMDIBuilderCreatePointerType(
1655 pointee_type_metadata,
1656 bytes_to_bits(pointer_size),
1657 bytes_to_bits(pointer_align),
1661 return ptr_metadata;
1664 //=-----------------------------------------------------------------------------
1665 // Common facilities for record-like types (structs, enums, tuples)
1666 //=-----------------------------------------------------------------------------
1669 FixedMemberOffset { bytes: uint },
1670 // For ComputedMemberOffset, the offset is read from the llvm type definition
1671 ComputedMemberOffset
1674 // Description of a type member, which can either be a regular field (as in
1675 // structs or tuples) or an enum variant
1676 struct MemberDescription {
1679 type_metadata: DIType,
1680 offset: MemberOffset,
1683 // A factory for MemberDescriptions. It produces a list of member descriptions
1684 // for some record-like type. MemberDescriptionFactories are used to defer the
1685 // creation of type member descriptions in order to break cycles arising from
1686 // recursive type definitions.
1687 enum MemberDescriptionFactory {
1688 StructMDF(StructMemberDescriptionFactory),
1689 TupleMDF(TupleMemberDescriptionFactory),
1690 EnumMDF(EnumMemberDescriptionFactory),
1691 VariantMDF(VariantMemberDescriptionFactory)
1694 impl MemberDescriptionFactory {
1695 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
1697 StructMDF(ref this) => {
1698 this.create_member_descriptions(cx)
1700 TupleMDF(ref this) => {
1701 this.create_member_descriptions(cx)
1703 EnumMDF(ref this) => {
1704 this.create_member_descriptions(cx)
1706 VariantMDF(ref this) => {
1707 this.create_member_descriptions(cx)
1713 // A description of some recursive type. It can either be already finished (as
1714 // with FinalMetadata) or it is not yet finished, but contains all information
1715 // needed to generate the missing parts of the description. See the documentation
1716 // section on Recursive Types at the top of this file for more information.
1717 enum RecursiveTypeDescription {
1718 UnfinishedMetadata {
1719 unfinished_type: ty::t,
1720 unique_type_id: UniqueTypeId,
1721 metadata_stub: DICompositeType,
1723 file_metadata: DIFile,
1724 member_description_factory: MemberDescriptionFactory,
1726 FinalMetadata(DICompositeType)
1729 fn create_and_register_recursive_type_forward_declaration(
1731 unfinished_type: ty::t,
1732 unique_type_id: UniqueTypeId,
1733 metadata_stub: DICompositeType,
1735 file_metadata: DIFile,
1736 member_description_factory: MemberDescriptionFactory)
1737 -> RecursiveTypeDescription {
1739 // Insert the stub into the TypeMap in order to allow for recursive references
1740 let mut type_map = debug_context(cx).type_map.borrow_mut();
1741 type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata_stub);
1742 type_map.register_type_with_metadata(cx, unfinished_type, metadata_stub);
1744 UnfinishedMetadata {
1745 unfinished_type: unfinished_type,
1746 unique_type_id: unique_type_id,
1747 metadata_stub: metadata_stub,
1748 llvm_type: llvm_type,
1749 file_metadata: file_metadata,
1750 member_description_factory: member_description_factory,
1754 impl RecursiveTypeDescription {
1755 // Finishes up the description of the type in question (mostly by providing
1756 // descriptions of the fields of the given type) and returns the final type metadata.
1757 fn finalize(&self, cx: &CrateContext) -> MetadataCreationResult {
1759 FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
1760 UnfinishedMetadata {
1766 ref member_description_factory
1768 // Make sure that we have a forward declaration of the type in
1769 // the TypeMap so that recursive references are possible. This
1770 // will always be the case if the RecursiveTypeDescription has
1771 // been properly created through the
1772 // create_and_register_recursive_type_forward_declaration() function.
1774 let type_map = debug_context(cx).type_map.borrow();
1775 if type_map.find_metadata_for_unique_id(unique_type_id).is_none() ||
1776 type_map.find_metadata_for_type(unfinished_type).is_none() {
1777 cx.sess().bug(format!("Forward declaration of potentially recursive type \
1778 '{}' was not found in TypeMap!",
1779 ppaux::ty_to_str(cx.tcx(), unfinished_type))
1784 // ... then create the member descriptions ...
1785 let member_descriptions =
1786 member_description_factory.create_member_descriptions(cx);
1788 // ... and attach them to the stub to complete it.
1789 set_members_of_composite_type(cx,
1792 member_descriptions.as_slice(),
1795 return MetadataCreationResult::new(metadata_stub, true);
1802 //=-----------------------------------------------------------------------------
1804 //=-----------------------------------------------------------------------------
1806 // Creates MemberDescriptions for the fields of a struct
1807 struct StructMemberDescriptionFactory {
1808 fields: Vec<ty::field>,
1813 impl StructMemberDescriptionFactory {
1814 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
1815 if self.fields.len() == 0 {
1819 let field_size = if self.is_simd {
1820 machine::llsize_of_alloc(cx, type_of::type_of(cx, self.fields.get(0).mt.ty)) as uint
1825 self.fields.iter().enumerate().map(|(i, field)| {
1826 let name = if field.ident.name == special_idents::unnamed_field.name {
1829 token::get_ident(field.ident).get().to_string()
1832 let offset = if self.is_simd {
1833 assert!(field_size != 0xdeadbeef);
1834 FixedMemberOffset { bytes: i * field_size }
1836 ComputedMemberOffset
1841 llvm_type: type_of::type_of(cx, field.mt.ty),
1842 type_metadata: type_metadata(cx, field.mt.ty, self.span),
1849 fn prepare_struct_metadata(cx: &CrateContext,
1852 substs: &subst::Substs,
1853 unique_type_id: UniqueTypeId,
1855 -> RecursiveTypeDescription {
1856 let struct_name = ppaux::ty_to_str(cx.tcx(), struct_type);
1857 let struct_llvm_type = type_of::type_of(cx, struct_type);
1859 let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, def_id);
1861 let file_name = span_start(cx, definition_span).file.name.clone();
1862 let file_metadata = file_metadata(cx, file_name.as_slice());
1864 let struct_metadata_stub = create_struct_stub(cx,
1866 struct_name.as_slice(),
1872 let fields = ty::struct_fields(cx.tcx(), def_id, substs);
1874 create_and_register_recursive_type_forward_declaration(
1878 struct_metadata_stub,
1881 StructMDF(StructMemberDescriptionFactory {
1883 is_simd: ty::type_is_simd(cx.tcx(), struct_type),
1890 //=-----------------------------------------------------------------------------
1892 //=-----------------------------------------------------------------------------
1894 // Creates MemberDescriptions for the fields of a tuple
1895 struct TupleMemberDescriptionFactory {
1896 component_types: Vec<ty::t> ,
1900 impl TupleMemberDescriptionFactory {
1901 fn create_member_descriptions(&self, cx: &CrateContext)
1902 -> Vec<MemberDescription> {
1903 self.component_types.iter().map(|&component_type| {
1905 name: "".to_string(),
1906 llvm_type: type_of::type_of(cx, component_type),
1907 type_metadata: type_metadata(cx, component_type, self.span),
1908 offset: ComputedMemberOffset,
1914 fn prepare_tuple_metadata(cx: &CrateContext,
1916 component_types: &[ty::t],
1917 unique_type_id: UniqueTypeId,
1919 -> RecursiveTypeDescription {
1920 let tuple_name = ppaux::ty_to_str(cx.tcx(), tuple_type);
1921 let tuple_llvm_type = type_of::type_of(cx, tuple_type);
1923 let loc = span_start(cx, span);
1924 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
1926 create_and_register_recursive_type_forward_declaration(
1930 create_struct_stub(cx,
1932 tuple_name.as_slice(),
1939 TupleMDF(TupleMemberDescriptionFactory {
1940 component_types: Vec::from_slice(component_types),
1947 //=-----------------------------------------------------------------------------
1949 //=-----------------------------------------------------------------------------
1951 // Describes the members of an enum value: An enum is described as a union of
1952 // structs in DWARF. This MemberDescriptionFactory provides the description for
1953 // the members of this union; so for every variant of the given enum, this factory
1954 // will produce one MemberDescription (all with no name and a fixed offset of
1956 struct EnumMemberDescriptionFactory {
1958 type_rep: Rc<adt::Repr>,
1959 variants: Rc<Vec<Rc<ty::VariantInfo>>>,
1960 discriminant_type_metadata: Option<DIType>,
1961 containing_scope: DIScope,
1962 file_metadata: DIFile,
1966 impl EnumMemberDescriptionFactory {
1967 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
1968 match *self.type_rep {
1969 adt::General(_, ref struct_defs) => {
1970 let discriminant_info = RegularDiscriminant(self.discriminant_type_metadata
1976 .map(|(i, struct_def)| {
1977 let (variant_type_metadata,
1979 member_desc_factory) =
1980 describe_enum_variant(cx,
1983 &**self.variants.get(i),
1985 self.containing_scope,
1989 let member_descriptions = member_desc_factory
1990 .create_member_descriptions(cx);
1992 set_members_of_composite_type(cx,
1993 variant_type_metadata,
1995 member_descriptions.as_slice(),
1999 name: "".to_string(),
2000 llvm_type: variant_llvm_type,
2001 type_metadata: variant_type_metadata,
2002 offset: FixedMemberOffset { bytes: 0 },
2006 adt::Univariant(ref struct_def, _) => {
2007 assert!(self.variants.len() <= 1);
2009 if self.variants.len() == 0 {
2012 let (variant_type_metadata,
2014 member_description_factory) =
2015 describe_enum_variant(cx,
2018 &**self.variants.get(0),
2020 self.containing_scope,
2024 let member_descriptions =
2025 member_description_factory.create_member_descriptions(cx);
2027 set_members_of_composite_type(cx,
2028 variant_type_metadata,
2030 member_descriptions.as_slice(),
2035 name: "".to_string(),
2036 llvm_type: variant_llvm_type,
2037 type_metadata: variant_type_metadata,
2038 offset: FixedMemberOffset { bytes: 0 },
2043 adt::RawNullablePointer { nndiscr: non_null_variant_index, nnty, .. } => {
2044 // As far as debuginfo is concerned, the pointer this enum
2045 // represents is still wrapped in a struct. This is to make the
2046 // DWARF representation of enums uniform.
2048 // First create a description of the artificial wrapper struct:
2049 let non_null_variant = self.variants.get(non_null_variant_index as uint);
2050 let non_null_variant_ident = non_null_variant.name;
2051 let non_null_variant_name = token::get_ident(non_null_variant_ident);
2053 // The llvm type and metadata of the pointer
2054 let non_null_llvm_type = type_of::type_of(cx, nnty);
2055 let non_null_type_metadata = type_metadata(cx, nnty, self.span);
2057 // The type of the artificial struct wrapping the pointer
2058 let artificial_struct_llvm_type = Type::struct_(cx,
2059 &[non_null_llvm_type],
2062 // For the metadata of the wrapper struct, we need to create a
2063 // MemberDescription of the struct's single field.
2064 let sole_struct_member_description = MemberDescription {
2065 name: match non_null_variant.arg_names {
2066 Some(ref names) => token::get_ident(*names.get(0)).get().to_string(),
2067 None => "".to_string()
2069 llvm_type: non_null_llvm_type,
2070 type_metadata: non_null_type_metadata,
2071 offset: FixedMemberOffset { bytes: 0 },
2074 let unique_type_id = debug_context(cx).type_map
2076 .get_unique_type_id_of_enum_variant(
2079 non_null_variant_name.get());
2081 // Now we can create the metadata of the artificial struct
2082 let artificial_struct_metadata =
2083 composite_type_metadata(cx,
2084 artificial_struct_llvm_type,
2085 non_null_variant_name.get(),
2087 &[sole_struct_member_description],
2088 self.containing_scope,
2092 // Encode the information about the null variant in the union
2094 let null_variant_index = (1 - non_null_variant_index) as uint;
2095 let null_variant_ident = self.variants.get(null_variant_index).name;
2096 let null_variant_name = token::get_ident(null_variant_ident);
2097 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
2101 // Finally create the (singleton) list of descriptions of union
2105 name: union_member_name,
2106 llvm_type: artificial_struct_llvm_type,
2107 type_metadata: artificial_struct_metadata,
2108 offset: FixedMemberOffset { bytes: 0 },
2112 adt::StructWrappedNullablePointer { nonnull: ref struct_def,
2115 // Create a description of the non-null variant
2116 let (variant_type_metadata, variant_llvm_type, member_description_factory) =
2117 describe_enum_variant(cx,
2120 &**self.variants.get(nndiscr as uint),
2121 OptimizedDiscriminant(ptrfield),
2122 self.containing_scope,
2126 let variant_member_descriptions =
2127 member_description_factory.create_member_descriptions(cx);
2129 set_members_of_composite_type(cx,
2130 variant_type_metadata,
2132 variant_member_descriptions.as_slice(),
2136 // Encode the information about the null variant in the union
2138 let null_variant_index = (1 - nndiscr) as uint;
2139 let null_variant_ident = self.variants.get(null_variant_index).name;
2140 let null_variant_name = token::get_ident(null_variant_ident);
2141 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
2145 // Create the (singleton) list of descriptions of union members.
2148 name: union_member_name,
2149 llvm_type: variant_llvm_type,
2150 type_metadata: variant_type_metadata,
2151 offset: FixedMemberOffset { bytes: 0 },
2155 adt::CEnum(..) => cx.sess().span_bug(self.span, "This should be unreachable.")
2160 // Creates MemberDescriptions for the fields of a single enum variant.
2161 struct VariantMemberDescriptionFactory {
2162 args: Vec<(String, ty::t)> ,
2163 discriminant_type_metadata: Option<DIType>,
2167 impl VariantMemberDescriptionFactory {
2168 fn create_member_descriptions(&self, cx: &CrateContext) -> Vec<MemberDescription> {
2169 self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
2171 name: name.to_string(),
2172 llvm_type: type_of::type_of(cx, ty),
2173 type_metadata: match self.discriminant_type_metadata {
2174 Some(metadata) if i == 0 => metadata,
2175 _ => type_metadata(cx, ty, self.span)
2177 offset: ComputedMemberOffset,
2183 enum EnumDiscriminantInfo {
2184 RegularDiscriminant(DIType),
2185 OptimizedDiscriminant(uint),
2189 // Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type
2190 // of the variant, and (3) a MemberDescriptionFactory for producing the
2191 // descriptions of the fields of the variant. This is a rudimentary version of a
2192 // full RecursiveTypeDescription.
2193 fn describe_enum_variant(cx: &CrateContext,
2195 struct_def: &adt::Struct,
2196 variant_info: &ty::VariantInfo,
2197 discriminant_info: EnumDiscriminantInfo,
2198 containing_scope: DIScope,
2199 file_metadata: DIFile,
2201 -> (DICompositeType, Type, MemberDescriptionFactory) {
2202 let variant_llvm_type =
2203 Type::struct_(cx, struct_def.fields
2205 .map(|&t| type_of::type_of(cx, t))
2206 .collect::<Vec<_>>()
2209 // Could do some consistency checks here: size, align, field count, discr type
2211 // Find the source code location of the variant's definition
2212 let variant_definition_span = if variant_info.id.krate == ast::LOCAL_CRATE {
2213 cx.tcx.map.span(variant_info.id.node)
2215 // For definitions from other crates we have no location information available.
2219 let variant_name = token::get_ident(variant_info.name);
2220 let variant_name = variant_name.get();
2221 let unique_type_id = debug_context(cx).type_map
2223 .get_unique_type_id_of_enum_variant(
2228 let metadata_stub = create_struct_stub(cx,
2234 variant_definition_span);
2236 // Get the argument names from the enum variant info
2237 let mut arg_names: Vec<_> = match variant_info.arg_names {
2238 Some(ref names) => {
2241 token::get_ident(*ident).get().to_str().into_string()
2244 None => variant_info.args.iter().map(|_| "".to_string()).collect()
2247 // If this is not a univariant enum, there is also the (unnamed) discriminant field.
2248 match discriminant_info {
2249 RegularDiscriminant(_) => arg_names.insert(0, "".to_string()),
2250 _ => { /* do nothing */ }
2253 // Build an array of (field name, field type) pairs to be captured in the factory closure.
2254 let args: Vec<(String, ty::t)> = arg_names.iter()
2255 .zip(struct_def.fields.iter())
2256 .map(|(s, &t)| (s.to_string(), t))
2259 let member_description_factory =
2260 VariantMDF(VariantMemberDescriptionFactory {
2262 discriminant_type_metadata: match discriminant_info {
2263 RegularDiscriminant(discriminant_type_metadata) => {
2264 Some(discriminant_type_metadata)
2271 (metadata_stub, variant_llvm_type, member_description_factory)
2274 fn prepare_enum_metadata(cx: &CrateContext,
2276 enum_def_id: ast::DefId,
2277 unique_type_id: UniqueTypeId,
2279 -> RecursiveTypeDescription {
2280 let enum_name = ppaux::ty_to_str(cx.tcx(), enum_type);
2282 let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, enum_def_id);
2283 let loc = span_start(cx, definition_span);
2284 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2286 let variants = ty::enum_variants(cx.tcx(), enum_def_id);
2288 let enumerators_metadata: Vec<DIDescriptor> = variants
2291 token::get_ident(v.name).get().with_c_str(|name| {
2293 llvm::LLVMDIBuilderCreateEnumerator(
2296 v.disr_val as c_ulonglong)
2302 let discriminant_type_metadata = |inttype| {
2303 // We can reuse the type of the discriminant for all monomorphized
2304 // instances of an enum because it doesn't depend on any type parameters.
2305 // The def_id, uniquely identifying the enum's polytype acts as key in
2307 let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
2309 .find_copy(&enum_def_id);
2310 match cached_discriminant_type_metadata {
2311 Some(discriminant_type_metadata) => discriminant_type_metadata,
2313 let discriminant_llvm_type = adt::ll_inttype(cx, inttype);
2314 let (discriminant_size, discriminant_align) =
2315 size_and_align_of(cx, discriminant_llvm_type);
2316 let discriminant_base_type_metadata = type_metadata(cx,
2317 adt::ty_of_inttype(inttype),
2319 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
2321 let discriminant_type_metadata = discriminant_name.get().with_c_str(|name| {
2323 llvm::LLVMDIBuilderCreateEnumerationType(
2329 bytes_to_bits(discriminant_size),
2330 bytes_to_bits(discriminant_align),
2331 create_DIArray(DIB(cx), enumerators_metadata.as_slice()),
2332 discriminant_base_type_metadata)
2336 debug_context(cx).created_enum_disr_types
2338 .insert(enum_def_id, discriminant_type_metadata);
2340 discriminant_type_metadata
2345 let type_rep = adt::represent_type(cx, enum_type);
2347 let discriminant_type_metadata = match *type_rep {
2348 adt::CEnum(inttype, _, _) => {
2349 return FinalMetadata(discriminant_type_metadata(inttype))
2351 adt::RawNullablePointer { .. } |
2352 adt::StructWrappedNullablePointer { .. } |
2353 adt::Univariant(..) => None,
2354 adt::General(inttype, _) => Some(discriminant_type_metadata(inttype)),
2357 let enum_llvm_type = type_of::type_of(cx, enum_type);
2358 let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
2360 let unique_type_id_str = debug_context(cx)
2363 .get_unique_type_id_as_string(unique_type_id);
2365 let enum_metadata = enum_name.as_slice().with_c_str(|enum_name| {
2366 unique_type_id_str.as_slice().with_c_str(|unique_type_id_str| {
2368 llvm::LLVMDIBuilderCreateUnionType(
2374 bytes_to_bits(enum_type_size),
2375 bytes_to_bits(enum_type_align),
2384 return create_and_register_recursive_type_forward_declaration(
2391 EnumMDF(EnumMemberDescriptionFactory {
2392 enum_type: enum_type,
2393 type_rep: type_rep.clone(),
2395 discriminant_type_metadata: discriminant_type_metadata,
2396 containing_scope: containing_scope,
2397 file_metadata: file_metadata,
2402 fn get_enum_discriminant_name(cx: &CrateContext,
2404 -> token::InternedString {
2405 let name = if def_id.krate == ast::LOCAL_CRATE {
2406 cx.tcx.map.get_path_elem(def_id.node).name()
2408 csearch::get_item_path(&cx.tcx, def_id).last().unwrap().name()
2411 token::get_name(name)
2415 /// Creates debug information for a composite type, that is, anything that
2416 /// results in a LLVM struct.
2418 /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
2419 fn composite_type_metadata(cx: &CrateContext,
2420 composite_llvm_type: Type,
2421 composite_type_name: &str,
2422 composite_type_unique_id: UniqueTypeId,
2423 member_descriptions: &[MemberDescription],
2424 containing_scope: DIScope,
2425 file_metadata: DIFile,
2426 definition_span: Span)
2427 -> DICompositeType {
2428 // Create the (empty) struct metadata node ...
2429 let composite_type_metadata = create_struct_stub(cx,
2430 composite_llvm_type,
2431 composite_type_name,
2432 composite_type_unique_id,
2436 // ... and immediately create and add the member descriptions.
2437 set_members_of_composite_type(cx,
2438 composite_type_metadata,
2439 composite_llvm_type,
2440 member_descriptions,
2444 return composite_type_metadata;
2447 fn set_members_of_composite_type(cx: &CrateContext,
2448 composite_type_metadata: DICompositeType,
2449 composite_llvm_type: Type,
2450 member_descriptions: &[MemberDescription],
2451 file_metadata: DIFile,
2452 definition_span: Span) {
2453 // In some rare cases LLVM metadata uniquing would lead to an existing type
2454 // description being used instead of a new one created in create_struct_stub.
2455 // This would cause a hard to trace assertion in DICompositeType::SetTypeArray().
2456 // The following check makes sure that we get a better error message if this
2457 // should happen again due to some regression.
2459 let mut composite_types_completed =
2460 debug_context(cx).composite_types_completed.borrow_mut();
2461 if composite_types_completed.contains(&composite_type_metadata) {
2462 let (llvm_version_major, llvm_version_minor) = unsafe {
2463 (llvm::LLVMVersionMajor(), llvm::LLVMVersionMinor())
2466 let actual_llvm_version = llvm_version_major * 1000000 + llvm_version_minor * 1000;
2467 let min_supported_llvm_version = 3 * 1000000 + 4 * 1000;
2469 if actual_llvm_version < min_supported_llvm_version {
2470 cx.sess().warn(format!("This version of rustc was built with LLVM \
2471 {}.{}. Rustc just ran into a known \
2472 debuginfo corruption problem thatoften \
2473 occurs with LLVM versions below 3.4. \
2474 Please use a rustc built with anewer \
2477 llvm_version_minor).as_slice());
2479 cx.sess().bug("debuginfo::set_members_of_composite_type() - \
2480 Already completed forward declaration re-encountered.");
2483 composite_types_completed.insert(composite_type_metadata);
2487 let loc = span_start(cx, definition_span);
2489 let member_metadata: Vec<DIDescriptor> = member_descriptions
2492 .map(|(i, member_description)| {
2493 let (member_size, member_align) = size_and_align_of(cx, member_description.llvm_type);
2494 let member_offset = match member_description.offset {
2495 FixedMemberOffset { bytes } => bytes as u64,
2496 ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
2499 member_description.name.as_slice().with_c_str(|member_name| {
2501 llvm::LLVMDIBuilderCreateMemberType(
2503 composite_type_metadata,
2507 bytes_to_bits(member_size),
2508 bytes_to_bits(member_align),
2509 bytes_to_bits(member_offset),
2511 member_description.type_metadata)
2518 let type_array = create_DIArray(DIB(cx), member_metadata.as_slice());
2519 llvm::LLVMDICompositeTypeSetTypeArray(composite_type_metadata, type_array);
2523 // A convenience wrapper around LLVMDIBuilderCreateStructType(). Does not do any
2524 // caching, does not add any fields to the struct. This can be done later with
2525 // set_members_of_composite_type().
2526 fn create_struct_stub(cx: &CrateContext,
2527 struct_llvm_type: Type,
2528 struct_type_name: &str,
2529 unique_type_id: UniqueTypeId,
2530 containing_scope: DIScope,
2531 file_metadata: DIFile,
2532 definition_span: Span)
2533 -> DICompositeType {
2534 let loc = span_start(cx, definition_span);
2535 let (struct_size, struct_align) = size_and_align_of(cx, struct_llvm_type);
2537 let unique_type_id_str = debug_context(cx).type_map
2539 .get_unique_type_id_as_string(unique_type_id);
2540 let metadata_stub = unsafe {
2541 struct_type_name.with_c_str(|name| {
2542 unique_type_id_str.as_slice().with_c_str(|unique_type_id| {
2543 // LLVMDIBuilderCreateStructType() wants an empty array. A null
2544 // pointer will lead to hard to trace and debug LLVM assertions
2545 // later on in llvm/lib/IR/Value.cpp.
2546 let empty_array = create_DIArray(DIB(cx), []);
2548 llvm::LLVMDIBuilderCreateStructType(
2554 bytes_to_bits(struct_size),
2555 bytes_to_bits(struct_align),
2566 return metadata_stub;
2569 fn at_box_metadata(cx: &CrateContext,
2570 at_pointer_type: ty::t,
2571 content_type: ty::t,
2572 unique_type_id: UniqueTypeId)
2573 -> MetadataCreationResult {
2574 let content_type_metadata = type_metadata(cx, content_type, codemap::DUMMY_SP);
2576 match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
2577 Some(metadata) => return MetadataCreationResult::new(metadata, true),
2578 None => { /* proceed */ }
2581 let content_type_name = ppaux::ty_to_str(cx.tcx(), content_type);
2582 let content_type_name = content_type_name.as_slice();
2583 let content_llvm_type = type_of::type_of(cx, content_type);
2585 let box_type_name = format!("GcBox<{}>", content_type_name);
2586 let box_llvm_type = Type::at_box(cx, content_llvm_type);
2587 let member_llvm_types = box_llvm_type.field_types();
2588 assert!(box_layout_is_correct(cx,
2589 member_llvm_types.as_slice(),
2590 content_llvm_type));
2592 let int_type = ty::mk_int();
2593 let nil_pointer_type = ty::mk_nil_ptr(cx.tcx());
2594 let nil_pointer_type_metadata = type_metadata(cx,
2598 let member_descriptions = [
2600 name: "refcnt".to_string(),
2601 llvm_type: *member_llvm_types.get(0),
2602 type_metadata: type_metadata(cx, int_type, codemap::DUMMY_SP),
2603 offset: ComputedMemberOffset,
2606 name: "drop_glue".to_string(),
2607 llvm_type: *member_llvm_types.get(1),
2608 type_metadata: nil_pointer_type_metadata,
2609 offset: ComputedMemberOffset,
2612 name: "prev".to_string(),
2613 llvm_type: *member_llvm_types.get(2),
2614 type_metadata: nil_pointer_type_metadata,
2615 offset: ComputedMemberOffset,
2618 name: "next".to_string(),
2619 llvm_type: *member_llvm_types.get(3),
2620 type_metadata: nil_pointer_type_metadata,
2621 offset: ComputedMemberOffset,
2624 name: "val".to_string(),
2625 llvm_type: *member_llvm_types.get(4),
2626 type_metadata: content_type_metadata,
2627 offset: ComputedMemberOffset,
2631 let loc = span_start(cx, codemap::DUMMY_SP);
2632 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2634 let gc_box_unique_id = debug_context(cx).type_map
2636 .get_unique_type_id_of_gc_box(cx, content_type);
2638 let gc_box_metadata = composite_type_metadata(
2641 box_type_name.as_slice(),
2643 member_descriptions,
2648 let gc_pointer_metadata = pointer_type_metadata(cx,
2652 return MetadataCreationResult::new(gc_pointer_metadata, false);
2654 // Unfortunately, we cannot assert anything but the correct types here---and
2655 // not whether the 'next' and 'prev' pointers are in the correct order.
2656 fn box_layout_is_correct(cx: &CrateContext,
2657 member_llvm_types: &[Type],
2658 content_llvm_type: Type)
2660 member_llvm_types.len() == 5 &&
2661 member_llvm_types[0] == cx.int_type &&
2662 member_llvm_types[1] == Type::generic_glue_fn(cx).ptr_to() &&
2663 member_llvm_types[2] == Type::i8(cx).ptr_to() &&
2664 member_llvm_types[3] == Type::i8(cx).ptr_to() &&
2665 member_llvm_types[4] == content_llvm_type
2670 fn fixed_vec_metadata(cx: &CrateContext,
2671 unique_type_id: UniqueTypeId,
2672 element_type: ty::t,
2675 -> MetadataCreationResult {
2676 let element_type_metadata = type_metadata(cx, element_type, span);
2678 match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
2679 Some(metadata) => return MetadataCreationResult::new(metadata, true),
2680 None => { /* proceed */ }
2683 let element_llvm_type = type_of::type_of(cx, element_type);
2684 let (element_type_size, element_type_align) = size_and_align_of(cx, element_llvm_type);
2686 let subrange = unsafe {
2687 llvm::LLVMDIBuilderGetOrCreateSubrange(
2693 let subscripts = create_DIArray(DIB(cx), [subrange]);
2694 let metadata = unsafe {
2695 llvm::LLVMDIBuilderCreateArrayType(
2697 bytes_to_bits(element_type_size * (len as u64)),
2698 bytes_to_bits(element_type_align),
2699 element_type_metadata,
2703 return MetadataCreationResult::new(metadata, false);
2706 fn heap_vec_metadata(cx: &CrateContext,
2707 vec_pointer_type: ty::t,
2708 element_type: ty::t,
2709 unique_type_id: UniqueTypeId,
2711 -> MetadataCreationResult {
2712 let element_type_metadata = type_metadata(cx, element_type, span);
2713 let element_llvm_type = type_of::type_of(cx, element_type);
2714 let (element_size, element_align) = size_and_align_of(cx, element_llvm_type);
2716 match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
2717 Some(metadata) => return MetadataCreationResult::new(metadata, true),
2718 None => { /* proceed */ }
2721 let vecbox_llvm_type = Type::vec(cx, &element_llvm_type);
2722 let vec_pointer_type_name = ppaux::ty_to_str(cx.tcx(), vec_pointer_type);
2723 let vec_pointer_type_name = vec_pointer_type_name.as_slice();
2725 let member_llvm_types = vecbox_llvm_type.field_types();
2727 let int_type_metadata = type_metadata(cx, ty::mk_int(), span);
2728 let array_type_metadata = unsafe {
2729 llvm::LLVMDIBuilderCreateArrayType(
2731 bytes_to_bits(element_size),
2732 bytes_to_bits(element_align),
2733 element_type_metadata,
2734 create_DIArray(DIB(cx), [llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0, 0)]))
2737 let member_descriptions = [
2739 name: "fill".to_string(),
2740 llvm_type: *member_llvm_types.get(0),
2741 type_metadata: int_type_metadata,
2742 offset: ComputedMemberOffset,
2745 name: "alloc".to_string(),
2746 llvm_type: *member_llvm_types.get(1),
2747 type_metadata: int_type_metadata,
2748 offset: ComputedMemberOffset,
2751 name: "elements".to_string(),
2752 llvm_type: *member_llvm_types.get(2),
2753 type_metadata: array_type_metadata,
2754 offset: ComputedMemberOffset,
2758 assert!(member_descriptions.len() == member_llvm_types.len());
2760 let loc = span_start(cx, span);
2761 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2763 let vec_box_unique_id = debug_context(cx).type_map
2765 .get_unique_type_id_of_heap_vec_box(cx,
2768 let vecbox_metadata = composite_type_metadata(cx,
2770 vec_pointer_type_name,
2772 member_descriptions,
2777 MetadataCreationResult::new(pointer_type_metadata(cx,
2779 vecbox_metadata), false)
2782 fn vec_slice_metadata(cx: &CrateContext,
2784 element_type: ty::t,
2785 unique_type_id: UniqueTypeId,
2787 -> MetadataCreationResult {
2788 let data_ptr_type = ty::mk_ptr(cx.tcx(), ty::mt {
2790 mutbl: ast::MutImmutable
2793 let element_type_metadata = type_metadata(cx, data_ptr_type, span);
2795 match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
2796 Some(metadata) => return MetadataCreationResult::new(metadata, true),
2797 None => { /* proceed */ }
2800 let slice_llvm_type = type_of::type_of(cx, vec_type);
2801 let slice_type_name = ppaux::ty_to_str(cx.tcx(), vec_type);
2803 let member_llvm_types = slice_llvm_type.field_types();
2804 assert!(slice_layout_is_correct(cx,
2805 member_llvm_types.as_slice(),
2807 let member_descriptions = [
2809 name: "data_ptr".to_string(),
2810 llvm_type: *member_llvm_types.get(0),
2811 type_metadata: element_type_metadata,
2812 offset: ComputedMemberOffset,
2815 name: "length".to_string(),
2816 llvm_type: *member_llvm_types.get(1),
2817 type_metadata: type_metadata(cx, ty::mk_uint(), span),
2818 offset: ComputedMemberOffset,
2822 assert!(member_descriptions.len() == member_llvm_types.len());
2824 let loc = span_start(cx, span);
2825 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2827 let metadata = composite_type_metadata(cx,
2829 slice_type_name.as_slice(),
2831 member_descriptions,
2835 return MetadataCreationResult::new(metadata, false);
2837 fn slice_layout_is_correct(cx: &CrateContext,
2838 member_llvm_types: &[Type],
2839 element_type: ty::t)
2841 member_llvm_types.len() == 2 &&
2842 member_llvm_types[0] == type_of::type_of(cx, element_type).ptr_to() &&
2843 member_llvm_types[1] == cx.int_type
2847 fn subroutine_type_metadata(cx: &CrateContext,
2848 unique_type_id: UniqueTypeId,
2849 signature: &ty::FnSig,
2851 -> MetadataCreationResult {
2852 let loc = span_start(cx, span);
2853 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2854 let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs.len() + 1);
2857 signature_metadata.push(match ty::get(signature.output).sty {
2858 ty::ty_nil => ptr::mut_null(),
2859 _ => type_metadata(cx, signature.output, span)
2862 // regular arguments
2863 for &argument_type in signature.inputs.iter() {
2864 signature_metadata.push(type_metadata(cx, argument_type, span));
2867 match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
2868 Some(metadata) => return MetadataCreationResult::new(metadata, true),
2869 None => { /* proceed */ }
2872 return MetadataCreationResult::new(
2874 llvm::LLVMDIBuilderCreateSubroutineType(
2877 create_DIArray(DIB(cx), signature_metadata.as_slice()))
2882 fn trait_metadata(cx: &CrateContext,
2885 substs: &subst::Substs,
2886 trait_store: ty::TraitStore,
2887 _: &ty::BuiltinBounds,
2888 unique_type_id: UniqueTypeId)
2890 // The implementation provided here is a stub. It makes sure that the trait
2891 // type is assigned the correct name, size, namespace, and source location.
2892 // But it does not describe the trait's methods.
2893 let last = ty::with_path(cx.tcx(), def_id, |mut path| path.last().unwrap());
2894 let ident_string = token::get_name(last.name());
2895 let mut name = ppaux::trait_store_to_str(cx.tcx(), trait_store);
2896 name.push_str(ident_string.get());
2898 // Add type and region parameters
2899 let trait_def = ty::lookup_trait_def(cx.tcx(), def_id);
2900 let name = ppaux::parameterized(cx.tcx(), name.as_slice(),
2901 substs, &trait_def.generics);
2903 let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, def_id);
2905 let file_name = span_start(cx, definition_span).file.name.clone();
2906 let file_metadata = file_metadata(cx, file_name.as_slice());
2908 let trait_llvm_type = type_of::type_of(cx, trait_type);
2910 composite_type_metadata(cx,
2920 fn type_metadata(cx: &CrateContext,
2922 usage_site_span: Span)
2924 // Get the unique type id of this type.
2925 let unique_type_id = {
2926 let mut type_map = debug_context(cx).type_map.borrow_mut();
2927 // First, try to find the type in TypeMap. If we have seen it before, we
2928 // can exit early here.
2929 match type_map.find_metadata_for_type(t) {
2934 // The ty::t is not in the TypeMap but maybe we have already seen
2935 // an equivalent type (e.g. only differing in region arguments).
2936 // In order to find out, generate the unique type id and look
2938 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
2939 match type_map.find_metadata_for_unique_id(unique_type_id) {
2941 // There is already an equivalent type in the TypeMap.
2942 // Register this ty::t as an alias in the cache and
2943 // return the cached metadata.
2944 type_map.register_type_with_metadata(cx, t, metadata);
2948 // There really is no type metadata for this type, so
2949 // proceed by creating it.
2957 debug!("type_metadata: {:?}", ty::get(t));
2959 macro_rules! return_if_created_in_meantime(
2961 match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
2962 Some(metadata) => return metadata,
2963 None => { /* proceed normally */ }
2968 let sty = &ty::get(t).sty;
2969 let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty {
2976 ty::ty_float(_) => {
2977 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
2979 ty::ty_enum(def_id, _) => {
2980 prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span).finalize(cx)
2982 ty::ty_box(pointee_type) => {
2983 at_box_metadata(cx, t, pointee_type, unique_type_id)
2985 ty::ty_vec(ref mt, Some(len)) => {
2986 fixed_vec_metadata(cx, unique_type_id, mt.ty, len, usage_site_span)
2988 ty::ty_uniq(pointee_type) => {
2989 match ty::get(pointee_type).sty {
2990 ty::ty_vec(ref mt, None) => {
2991 heap_vec_metadata(cx, pointee_type, mt.ty, unique_type_id, usage_site_span)
2994 let i8_t = ty::mk_i8();
2995 heap_vec_metadata(cx, pointee_type, i8_t, unique_type_id, usage_site_span)
2997 ty::ty_trait(box ty::TyTrait {
3002 MetadataCreationResult::new(
3003 trait_metadata(cx, def_id, t, substs, ty::UniqTraitStore,
3004 bounds, unique_type_id),
3008 let pointee_metadata = type_metadata(cx, pointee_type, usage_site_span);
3009 return_if_created_in_meantime!();
3010 MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
3015 ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => {
3016 match ty::get(mt.ty).sty {
3017 ty::ty_vec(ref mt, None) => {
3018 vec_slice_metadata(cx, t, mt.ty, unique_type_id, usage_site_span)
3021 vec_slice_metadata(cx, t, ty::mk_i8(), unique_type_id, usage_site_span)
3023 ty::ty_trait(box ty::TyTrait {
3028 MetadataCreationResult::new(
3029 trait_metadata(cx, def_id, t, substs,
3030 ty::RegionTraitStore(ty::ReStatic, mt.mutbl),
3031 bounds, unique_type_id),
3035 let pointee = type_metadata(cx, mt.ty, usage_site_span);
3036 return_if_created_in_meantime!();
3037 MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee), false)
3041 ty::ty_bare_fn(ref barefnty) => {
3042 subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
3044 ty::ty_closure(ref closurety) => {
3045 subroutine_type_metadata(cx, unique_type_id, &closurety.sig, usage_site_span)
3047 ty::ty_struct(def_id, ref substs) => {
3048 prepare_struct_metadata(cx,
3053 usage_site_span).finalize(cx)
3055 ty::ty_tup(ref elements) => {
3056 prepare_tuple_metadata(cx,
3058 elements.as_slice(),
3060 usage_site_span).finalize(cx)
3063 cx.sess().bug(format!("debuginfo: unexpected type in type_metadata: {:?}",
3069 let mut type_map = debug_context(cx).type_map.borrow_mut();
3071 if already_stored_in_typemap {
3072 // Also make sure that we already have a TypeMap entry entry for the unique type id.
3073 let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
3074 Some(metadata) => metadata,
3076 let unique_type_id_str =
3077 type_map.get_unique_type_id_as_string(unique_type_id);
3078 let error_message = format!("Expected type metadata for unique \
3079 type id '{}' to already be in \
3080 the debuginfo::TypeMap but it \
3081 was not. (ty::t = {})",
3082 unique_type_id_str.as_slice(),
3083 ppaux::ty_to_str(cx.tcx(), t));
3084 cx.sess().span_bug(usage_site_span, error_message.as_slice());
3088 match type_map.find_metadata_for_type(t) {
3090 if metadata != metadata_for_uid {
3091 let unique_type_id_str =
3092 type_map.get_unique_type_id_as_string(unique_type_id);
3093 let error_message = format!("Mismatch between ty::t and \
3094 UniqueTypeId maps in \
3095 debuginfo::TypeMap. \
3096 UniqueTypeId={}, ty::t={}",
3097 unique_type_id_str.as_slice(),
3098 ppaux::ty_to_str(cx.tcx(), t));
3099 cx.sess().span_bug(usage_site_span, error_message.as_slice());
3103 type_map.register_type_with_metadata(cx, t, metadata);
3107 type_map.register_type_with_metadata(cx, t, metadata);
3108 type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata);
3115 struct MetadataCreationResult {
3117 already_stored_in_typemap: bool
3120 impl MetadataCreationResult {
3121 fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationResult {
3122 MetadataCreationResult {
3124 already_stored_in_typemap: already_stored_in_typemap
3129 #[deriving(PartialEq)]
3130 enum DebugLocation {
3131 KnownLocation { scope: DIScope, line: uint, col: uint },
3135 impl DebugLocation {
3136 fn new(scope: DIScope, line: uint, col: uint) -> DebugLocation {
3145 fn set_debug_location(cx: &CrateContext, debug_location: DebugLocation) {
3146 if debug_location == debug_context(cx).current_debug_location.get() {
3152 match debug_location {
3153 KnownLocation { scope, line, .. } => {
3154 let col = 0u; // Always set the column to zero like Clang and GCC
3155 debug!("setting debug location to {} {}", line, col);
3156 let elements = [C_i32(cx, line as i32), C_i32(cx, col as i32),
3157 scope, ptr::mut_null()];
3159 metadata_node = llvm::LLVMMDNodeInContext(debug_context(cx).llcontext,
3161 elements.len() as c_uint);
3164 UnknownLocation => {
3165 debug!("clearing debug location ");
3166 metadata_node = ptr::mut_null();
3171 llvm::LLVMSetCurrentDebugLocation(cx.builder.b, metadata_node);
3174 debug_context(cx).current_debug_location.set(debug_location);
3177 //=-----------------------------------------------------------------------------
3178 // Utility Functions
3179 //=-----------------------------------------------------------------------------
3181 /// Return codemap::Loc corresponding to the beginning of the span
3182 fn span_start(cx: &CrateContext, span: Span) -> codemap::Loc {
3183 cx.sess().codemap().lookup_char_pos(span.lo)
3186 fn size_and_align_of(cx: &CrateContext, llvm_type: Type) -> (u64, u64) {
3187 (machine::llsize_of_alloc(cx, llvm_type), machine::llalign_of_min(cx, llvm_type))
3190 fn bytes_to_bits(bytes: u64) -> c_ulonglong {
3191 (bytes * 8) as c_ulonglong
3195 fn debug_context<'a>(cx: &'a CrateContext) -> &'a CrateDebugContext {
3196 let debug_context: &'a CrateDebugContext = cx.dbg_cx.get_ref();
3201 #[allow(non_snake_case_functions)]
3202 fn DIB(cx: &CrateContext) -> DIBuilderRef {
3203 cx.dbg_cx.get_ref().builder
3206 fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
3207 match fcx.debug_context.repr {
3208 FunctionDebugContext(_) => false,
3213 fn assert_type_for_node_id(cx: &CrateContext, node_id: ast::NodeId, error_span: Span) {
3214 if !cx.tcx.node_types.borrow().contains_key(&(node_id as uint)) {
3215 cx.sess().span_bug(error_span, "debuginfo: Could not find type for node id!");
3219 fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: ast::DefId)
3220 -> (DIScope, Span) {
3221 let containing_scope = namespace_for_item(cx, def_id).scope;
3222 let definition_span = if def_id.krate == ast::LOCAL_CRATE {
3223 cx.tcx.map.span(def_id.node)
3225 // For external items there is no span information
3229 (containing_scope, definition_span)
3232 // This procedure builds the *scope map* for a given function, which maps any
3233 // given ast::NodeId in the function's AST to the correct DIScope metadata instance.
3235 // This builder procedure walks the AST in execution order and keeps track of
3236 // what belongs to which scope, creating DIScope DIEs along the way, and
3237 // introducing *artificial* lexical scope descriptors where necessary. These
3238 // artificial scopes allow GDB to correctly handle name shadowing.
3239 fn populate_scope_map(cx: &CrateContext,
3240 arg_pats: &[Gc<ast::Pat>],
3241 fn_entry_block: &ast::Block,
3242 fn_metadata: DISubprogram,
3243 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3244 let def_map = &cx.tcx.def_map;
3246 struct ScopeStackEntry {
3247 scope_metadata: DIScope,
3248 ident: Option<ast::Ident>
3251 let mut scope_stack = vec!(ScopeStackEntry { scope_metadata: fn_metadata,
3254 // Push argument identifiers onto the stack so arguments integrate nicely
3255 // with variable shadowing.
3256 for &arg_pat in arg_pats.iter() {
3257 pat_util::pat_bindings(def_map, &*arg_pat, |_, _, _, path_ref| {
3258 let ident = ast_util::path_to_ident(path_ref);
3259 scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata,
3260 ident: Some(ident) });
3264 // Clang creates a separate scope for function bodies, so let's do this too.
3266 fn_entry_block.span,
3269 |cx, scope_stack, scope_map| {
3270 walk_block(cx, fn_entry_block, scope_stack, scope_map);
3273 // local helper functions for walking the AST.
3274 fn with_new_scope(cx: &CrateContext,
3276 scope_stack: &mut Vec<ScopeStackEntry> ,
3277 scope_map: &mut HashMap<ast::NodeId, DIScope>,
3278 inner_walk: |&CrateContext,
3279 &mut Vec<ScopeStackEntry> ,
3280 &mut HashMap<ast::NodeId, DIScope>|) {
3281 // Create a new lexical scope and push it onto the stack
3282 let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
3283 let file_metadata = file_metadata(cx, loc.file.name.as_slice());
3284 let parent_scope = scope_stack.last().unwrap().scope_metadata;
3286 let scope_metadata = unsafe {
3287 llvm::LLVMDIBuilderCreateLexicalBlock(
3292 loc.col.to_uint() as c_uint,
3296 scope_stack.push(ScopeStackEntry { scope_metadata: scope_metadata,
3299 inner_walk(cx, scope_stack, scope_map);
3301 // pop artificial scopes
3302 while scope_stack.last().unwrap().ident.is_some() {
3306 if scope_stack.last().unwrap().scope_metadata != scope_metadata {
3307 cx.sess().span_bug(scope_span, "debuginfo: Inconsistency in scope management.");
3313 fn walk_block(cx: &CrateContext,
3315 scope_stack: &mut Vec<ScopeStackEntry> ,
3316 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3317 scope_map.insert(block.id, scope_stack.last().unwrap().scope_metadata);
3319 // The interesting things here are statements and the concluding expression.
3320 for statement in block.stmts.iter() {
3321 scope_map.insert(ast_util::stmt_id(&**statement),
3322 scope_stack.last().unwrap().scope_metadata);
3324 match statement.node {
3325 ast::StmtDecl(ref decl, _) =>
3326 walk_decl(cx, &**decl, scope_stack, scope_map),
3327 ast::StmtExpr(ref exp, _) |
3328 ast::StmtSemi(ref exp, _) =>
3329 walk_expr(cx, &**exp, scope_stack, scope_map),
3330 ast::StmtMac(..) => () // Ignore macros (which should be expanded anyway).
3334 for exp in block.expr.iter() {
3335 walk_expr(cx, &**exp, scope_stack, scope_map);
3339 fn walk_decl(cx: &CrateContext,
3341 scope_stack: &mut Vec<ScopeStackEntry> ,
3342 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3344 codemap::Spanned { node: ast::DeclLocal(local), .. } => {
3345 scope_map.insert(local.id, scope_stack.last().unwrap().scope_metadata);
3347 walk_pattern(cx, local.pat, scope_stack, scope_map);
3349 for exp in local.init.iter() {
3350 walk_expr(cx, &**exp, scope_stack, scope_map);
3357 fn walk_pattern(cx: &CrateContext,
3359 scope_stack: &mut Vec<ScopeStackEntry> ,
3360 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3362 let def_map = &cx.tcx.def_map;
3364 // Unfortunately, we cannot just use pat_util::pat_bindings() or
3365 // ast_util::walk_pat() here because we have to visit *all* nodes in
3366 // order to put them into the scope map. The above functions don't do that.
3368 ast::PatIdent(_, ref path_ref, ref sub_pat_opt) => {
3370 // Check if this is a binding. If so we need to put it on the
3371 // scope stack and maybe introduce an artificial scope
3372 if pat_util::pat_is_binding(def_map, &*pat) {
3374 let ident = ast_util::path_to_ident(path_ref);
3376 // LLVM does not properly generate 'DW_AT_start_scope' fields
3377 // for variable DIEs. For this reason we have to introduce
3378 // an artificial scope at bindings whenever a variable with
3379 // the same name is declared in *any* parent scope.
3381 // Otherwise the following error occurs:
3385 // do_something(); // 'gdb print x' correctly prints 10
3388 // do_something(); // 'gdb print x' prints 0, because it
3389 // // already reads the uninitialized 'x'
3390 // // from the next line...
3392 // do_something(); // 'gdb print x' correctly prints 100
3395 // Is there already a binding with that name?
3396 // N.B.: this comparison must be UNhygienic... because
3397 // gdb knows nothing about the context, so any two
3398 // variables with the same name will cause the problem.
3399 let need_new_scope = scope_stack
3401 .any(|entry| entry.ident.iter().any(|i| i.name == ident.name));
3404 // Create a new lexical scope and push it onto the stack
3405 let loc = cx.sess().codemap().lookup_char_pos(pat.span.lo);
3406 let file_metadata = file_metadata(cx,
3410 let parent_scope = scope_stack.last().unwrap().scope_metadata;
3412 let scope_metadata = unsafe {
3413 llvm::LLVMDIBuilderCreateLexicalBlock(
3418 loc.col.to_uint() as c_uint,
3422 scope_stack.push(ScopeStackEntry {
3423 scope_metadata: scope_metadata,
3428 // Push a new entry anyway so the name can be found
3429 let prev_metadata = scope_stack.last().unwrap().scope_metadata;
3430 scope_stack.push(ScopeStackEntry {
3431 scope_metadata: prev_metadata,
3437 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3439 for &sub_pat in sub_pat_opt.iter() {
3440 walk_pattern(cx, sub_pat, scope_stack, scope_map);
3444 ast::PatWild | ast::PatWildMulti => {
3445 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3448 ast::PatEnum(_, ref sub_pats_opt) => {
3449 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3451 for ref sub_pats in sub_pats_opt.iter() {
3452 for &p in sub_pats.iter() {
3453 walk_pattern(cx, p, scope_stack, scope_map);
3458 ast::PatStruct(_, ref field_pats, _) => {
3459 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3461 for &ast::FieldPat { pat: sub_pat, .. } in field_pats.iter() {
3462 walk_pattern(cx, sub_pat, scope_stack, scope_map);
3466 ast::PatTup(ref sub_pats) => {
3467 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3469 for sub_pat in sub_pats.iter() {
3470 walk_pattern(cx, sub_pat.clone(), scope_stack, scope_map);
3474 ast::PatBox(ref sub_pat) | ast::PatRegion(ref sub_pat) => {
3475 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3476 walk_pattern(cx, sub_pat.clone(), scope_stack, scope_map);
3479 ast::PatLit(ref exp) => {
3480 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3481 walk_expr(cx, &**exp, scope_stack, scope_map);
3484 ast::PatRange(ref exp1, ref exp2) => {
3485 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3486 walk_expr(cx, &**exp1, scope_stack, scope_map);
3487 walk_expr(cx, &**exp2, scope_stack, scope_map);
3490 ast::PatVec(ref front_sub_pats, ref middle_sub_pats, ref back_sub_pats) => {
3491 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
3493 for &sub_pat in front_sub_pats.iter() {
3494 walk_pattern(cx, sub_pat, scope_stack, scope_map);
3497 for &sub_pat in middle_sub_pats.iter() {
3498 walk_pattern(cx, sub_pat, scope_stack, scope_map);
3501 for &sub_pat in back_sub_pats.iter() {
3502 walk_pattern(cx, sub_pat, scope_stack, scope_map);
3507 cx.sess().span_bug(pat.span, "debuginfo::populate_scope_map() - \
3508 Found unexpanded macro.");
3513 fn walk_expr(cx: &CrateContext,
3515 scope_stack: &mut Vec<ScopeStackEntry> ,
3516 scope_map: &mut HashMap<ast::NodeId, DIScope>) {
3518 scope_map.insert(exp.id, scope_stack.last().unwrap().scope_metadata);
3524 ast::ExprPath(_) => {}
3526 ast::ExprVstore(ref sub_exp, _) |
3527 ast::ExprCast(ref sub_exp, _) |
3528 ast::ExprAddrOf(_, ref sub_exp) |
3529 ast::ExprField(ref sub_exp, _, _) |
3530 ast::ExprParen(ref sub_exp) =>
3531 walk_expr(cx, &**sub_exp, scope_stack, scope_map),
3533 ast::ExprBox(ref place, ref sub_expr) => {
3534 walk_expr(cx, &**place, scope_stack, scope_map);
3535 walk_expr(cx, &**sub_expr, scope_stack, scope_map);
3538 ast::ExprRet(exp_opt) => match exp_opt {
3539 Some(sub_exp) => walk_expr(cx, &*sub_exp, scope_stack, scope_map),
3543 ast::ExprUnary(_, ref sub_exp) => {
3544 walk_expr(cx, &**sub_exp, scope_stack, scope_map);
3547 ast::ExprAssignOp(_, ref lhs, ref rhs) |
3548 ast::ExprIndex(ref lhs, ref rhs) |
3549 ast::ExprBinary(_, ref lhs, ref rhs) => {
3550 walk_expr(cx, &**lhs, scope_stack, scope_map);
3551 walk_expr(cx, &**rhs, scope_stack, scope_map);
3554 ast::ExprVec(ref init_expressions) |
3555 ast::ExprTup(ref init_expressions) => {
3556 for ie in init_expressions.iter() {
3557 walk_expr(cx, &**ie, scope_stack, scope_map);
3561 ast::ExprAssign(ref sub_exp1, ref sub_exp2) |
3562 ast::ExprRepeat(ref sub_exp1, ref sub_exp2) => {
3563 walk_expr(cx, &**sub_exp1, scope_stack, scope_map);
3564 walk_expr(cx, &**sub_exp2, scope_stack, scope_map);
3567 ast::ExprIf(ref cond_exp, ref then_block, ref opt_else_exp) => {
3568 walk_expr(cx, &**cond_exp, scope_stack, scope_map);
3574 |cx, scope_stack, scope_map| {
3575 walk_block(cx, &**then_block, scope_stack, scope_map);
3578 match *opt_else_exp {
3579 Some(ref else_exp) =>
3580 walk_expr(cx, &**else_exp, scope_stack, scope_map),
3585 ast::ExprWhile(ref cond_exp, ref loop_body) => {
3586 walk_expr(cx, &**cond_exp, scope_stack, scope_map);
3592 |cx, scope_stack, scope_map| {
3593 walk_block(cx, &**loop_body, scope_stack, scope_map);
3597 ast::ExprForLoop(_, _, _, _) => {
3598 cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
3599 Found unexpanded for-loop.");
3602 ast::ExprMac(_) => {
3603 cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
3604 Found unexpanded macro.");
3607 ast::ExprLoop(ref block, _) |
3608 ast::ExprBlock(ref block) => {
3613 |cx, scope_stack, scope_map| {
3614 walk_block(cx, &**block, scope_stack, scope_map);
3618 ast::ExprFnBlock(ref decl, ref block) |
3619 ast::ExprProc(ref decl, ref block) => {
3624 |cx, scope_stack, scope_map| {
3625 for &ast::Arg { pat: ref pattern, .. } in decl.inputs.iter() {
3626 walk_pattern(cx, pattern.clone(), scope_stack, scope_map);
3629 walk_block(cx, &**block, scope_stack, scope_map);
3633 ast::ExprCall(ref fn_exp, ref args) => {
3634 walk_expr(cx, &**fn_exp, scope_stack, scope_map);
3636 for arg_exp in args.iter() {
3637 walk_expr(cx, &**arg_exp, scope_stack, scope_map);
3641 ast::ExprMethodCall(_, _, ref args) => {
3642 for arg_exp in args.iter() {
3643 walk_expr(cx, &**arg_exp, scope_stack, scope_map);
3647 ast::ExprMatch(ref discriminant_exp, ref arms) => {
3648 walk_expr(cx, &**discriminant_exp, scope_stack, scope_map);
3650 // For each arm we have to first walk the pattern as these might
3651 // introduce new artificial scopes. It should be sufficient to
3652 // walk only one pattern per arm, as they all must contain the
3653 // same binding names.
3655 for arm_ref in arms.iter() {
3656 let arm_span = arm_ref.pats.get(0).span;
3662 |cx, scope_stack, scope_map| {
3663 for &pat in arm_ref.pats.iter() {
3664 walk_pattern(cx, pat, scope_stack, scope_map);
3667 for guard_exp in arm_ref.guard.iter() {
3668 walk_expr(cx, &**guard_exp, scope_stack, scope_map)
3671 walk_expr(cx, &*arm_ref.body, scope_stack, scope_map);
3676 ast::ExprStruct(_, ref fields, ref base_exp) => {
3677 for &ast::Field { expr: ref exp, .. } in fields.iter() {
3678 walk_expr(cx, &**exp, scope_stack, scope_map);
3682 Some(ref exp) => walk_expr(cx, &**exp, scope_stack, scope_map),
3687 ast::ExprInlineAsm(ast::InlineAsm { inputs: ref inputs,
3688 outputs: ref outputs,
3690 // inputs, outputs: ~[(String, Gc<expr>)]
3691 for &(_, ref exp) in inputs.iter() {
3692 walk_expr(cx, &**exp, scope_stack, scope_map);
3695 for &(_, ref exp) in outputs.iter() {
3696 walk_expr(cx, &**exp, scope_stack, scope_map);
3704 //=-----------------------------------------------------------------------------
3705 // Namespace Handling
3706 //=-----------------------------------------------------------------------------
3708 struct NamespaceTreeNode {
3711 parent: Option<Weak<NamespaceTreeNode>>,
3714 impl NamespaceTreeNode {
3715 fn mangled_name_of_contained_item(&self, item_name: &str) -> String {
3716 fn fill_nested(node: &NamespaceTreeNode, output: &mut String) {
3718 Some(ref parent) => fill_nested(&*parent.upgrade().unwrap(), output),
3721 let string = token::get_name(node.name);
3722 output.push_str(format!("{}", string.get().len()).as_slice());
3723 output.push_str(string.get());
3726 let mut name = String::from_str("_ZN");
3727 fill_nested(self, &mut name);
3728 name.push_str(format!("{}", item_name.len()).as_slice());
3729 name.push_str(item_name);
3730 name.push_char('E');
3735 fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTreeNode> {
3736 ty::with_path(cx.tcx(), def_id, |path| {
3737 // prepend crate name if not already present
3738 let krate = if def_id.krate == ast::LOCAL_CRATE {
3739 let crate_namespace_ident = token::str_to_ident(cx.link_meta
3743 Some(ast_map::PathMod(crate_namespace_ident.name))
3747 let mut path = krate.move_iter().chain(path).peekable();
3749 let mut current_key = Vec::new();
3750 let mut parent_node: Option<Rc<NamespaceTreeNode>> = None;
3752 // Create/Lookup namespace for each element of the path.
3754 // Emulate a for loop so we can use peek below.
3755 let path_element = match path.next() {
3759 // Ignore the name of the item (the last path element).
3760 if path.peek().is_none() {
3764 let name = path_element.name();
3765 current_key.push(name);
3767 let existing_node = debug_context(cx).namespace_map.borrow()
3768 .find_copy(¤t_key);
3769 let current_node = match existing_node {
3770 Some(existing_node) => existing_node,
3772 // create and insert
3773 let parent_scope = match parent_node {
3774 Some(ref node) => node.scope,
3775 None => ptr::mut_null()
3777 let namespace_name = token::get_name(name);
3778 let scope = namespace_name.get().with_c_str(|namespace_name| {
3780 llvm::LLVMDIBuilderCreateNameSpace(
3784 // cannot reconstruct file ...
3786 // ... or line information, but that's not so important.
3791 let node = Rc::new(NamespaceTreeNode {
3794 parent: parent_node.map(|parent| parent.downgrade()),
3797 debug_context(cx).namespace_map.borrow_mut()
3798 .insert(current_key.clone(), node.clone());
3804 parent_node = Some(current_node);
3810 cx.sess().bug(format!("debuginfo::namespace_for_item(): \
3811 path too short for {:?}",
3812 def_id).as_slice());