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.
11 //! # Debug Info Module
13 //! This module serves the purpose of generating debug symbols. We use LLVM's
14 //! [source level debugging](http://llvm.org/docs/SourceLevelDebugging.html)
15 //! features for generating the debug information. The general principle is this:
17 //! Given the right metadata in the LLVM IR, the LLVM code generator is able to
18 //! create DWARF debug symbols for the given code. The
19 //! [metadata](http://llvm.org/docs/LangRef.html#metadata-type) is structured much
20 //! like DWARF *debugging information entries* (DIE), representing type information
21 //! such as datatype layout, function signatures, block layout, variable location
22 //! and scope information, etc. It is the purpose of this module to generate correct
23 //! metadata and insert it into the LLVM IR.
25 //! As the exact format of metadata trees may change between different LLVM
26 //! versions, we now use LLVM
27 //! [DIBuilder](http://llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html) to
28 //! create metadata where possible. This will hopefully ease the adaption of this
29 //! module to future LLVM versions.
31 //! The public API of the module is a set of functions that will insert the correct
32 //! metadata into the LLVM IR when called with the right parameters. The module is
33 //! thus driven from an outside client with functions like
34 //! `debuginfo::create_local_var_metadata(bcx: block, local: &ast::local)`.
36 //! Internally the module will try to reuse already created metadata by utilizing a
37 //! cache. The way to get a shared metadata node when needed is thus to just call
38 //! the corresponding function in this module:
40 //! let file_metadata = file_metadata(crate_context, path);
42 //! The function will take care of probing the cache for an existing node for that
45 //! All private state used by the module is stored within either the
46 //! CrateDebugContext struct (owned by the CrateContext) or the FunctionDebugContext
47 //! (owned by the FunctionContext).
49 //! This file consists of three conceptual sections:
50 //! 1. The public interface of the module
51 //! 2. Module-internal metadata creation functions
52 //! 3. Minor utility functions
55 //! ## Recursive Types
57 //! Some kinds of types, such as structs and enums can be recursive. That means that
58 //! the type definition of some type X refers to some other type which in turn
59 //! (transitively) refers to X. This introduces cycles into the type referral graph.
60 //! A naive algorithm doing an on-demand, depth-first traversal of this graph when
61 //! describing types, can get trapped in an endless loop when it reaches such a
64 //! For example, the following simple type for a singly-linked list...
69 //! tail: Option<Box<List>>,
73 //! will generate the following callstack with a naive DFS algorithm:
76 //! describe(t = List)
78 //! describe(t = Option<Box<List>>)
79 //! describe(t = Box<List>)
80 //! describe(t = List) // at the beginning again...
84 //! To break cycles like these, we use "forward declarations". That is, when the
85 //! algorithm encounters a possibly recursive type (any struct or enum), it
86 //! immediately creates a type description node and inserts it into the cache
87 //! *before* describing the members of the type. This type description is just a
88 //! stub (as type members are not described and added to it yet) but it allows the
89 //! algorithm to already refer to the type. After the stub is inserted into the
90 //! cache, the algorithm continues as before. If it now encounters a recursive
91 //! reference, it will hit the cache and does not try to describe the type anew.
93 //! This behaviour is encapsulated in the 'RecursiveTypeDescription' enum, which
94 //! represents a kind of continuation, storing all state needed to continue
95 //! traversal at the type members after the type has been registered with the cache.
96 //! (This implementation approach might be a tad over-engineered and may change in
100 //! ## Source Locations and Line Information
102 //! In addition to data type descriptions the debugging information must also allow
103 //! to map machine code locations back to source code locations in order to be useful.
104 //! This functionality is also handled in this module. The following functions allow
105 //! to control source mappings:
107 //! + set_source_location()
108 //! + clear_source_location()
109 //! + start_emitting_source_locations()
111 //! `set_source_location()` allows to set the current source location. All IR
112 //! instructions created after a call to this function will be linked to the given
113 //! source location, until another location is specified with
114 //! `set_source_location()` or the source location is cleared with
115 //! `clear_source_location()`. In the later case, subsequent IR instruction will not
116 //! be linked to any source location. As you can see, this is a stateful API
117 //! (mimicking the one in LLVM), so be careful with source locations set by previous
118 //! calls. It's probably best to not rely on any specific state being present at a
119 //! given point in code.
121 //! One topic that deserves some extra attention is *function prologues*. At the
122 //! beginning of a function's machine code there are typically a few instructions
123 //! for loading argument values into allocas and checking if there's enough stack
124 //! space for the function to execute. This *prologue* is not visible in the source
125 //! code and LLVM puts a special PROLOGUE END marker into the line table at the
126 //! first non-prologue instruction of the function. In order to find out where the
127 //! prologue ends, LLVM looks for the first instruction in the function body that is
128 //! linked to a source location. So, when generating prologue instructions we have
129 //! to make sure that we don't emit source location information until the 'real'
130 //! function body begins. For this reason, source location emission is disabled by
131 //! default for any new function being translated and is only activated after a call
132 //! to the third function from the list above, `start_emitting_source_locations()`.
133 //! This function should be called right before regularly starting to translate the
134 //! top-level block of the given function.
136 //! There is one exception to the above rule: `llvm.dbg.declare` instruction must be
137 //! linked to the source location of the variable being declared. For function
138 //! parameters these `llvm.dbg.declare` instructions typically occur in the middle
139 //! of the prologue, however, they are ignored by LLVM's prologue detection. The
140 //! `create_argument_metadata()` and related functions take care of linking the
141 //! `llvm.dbg.declare` instructions to the correct source locations even while
142 //! source location emission is still disabled, so there is no need to do anything
143 //! special with source location handling here.
145 //! ## Unique Type Identification
147 //! In order for link-time optimization to work properly, LLVM needs a unique type
148 //! identifier that tells it across compilation units which types are the same as
149 //! others. This type identifier is created by TypeMap::get_unique_type_id_of_type()
150 //! using the following algorithm:
152 //! (1) Primitive types have their name as ID
153 //! (2) Structs, enums and traits have a multipart identifier
155 //! (1) The first part is the SVH (strict version hash) of the crate they were
156 //! originally defined in
158 //! (2) The second part is the ast::NodeId of the definition in their original
161 //! (3) The final part is a concatenation of the type IDs of their concrete type
162 //! arguments if they are generic types.
164 //! (3) Tuple-, pointer and function types are structurally identified, which means
165 //! that they are equivalent if their component types are equivalent (i.e. (int,
166 //! int) is the same regardless in which crate it is used).
168 //! This algorithm also provides a stable ID for types that are defined in one crate
169 //! but instantiated from metadata within another crate. We just have to take care
170 //! to always map crate and node IDs back to the original crate context.
172 //! As a side-effect these unique type IDs also help to solve a problem arising from
173 //! lifetime parameters. Since lifetime parameters are completely omitted in
174 //! debuginfo, more than one `Ty` instance may map to the same debuginfo type
175 //! metadata, that is, some struct `Struct<'a>` may have N instantiations with
176 //! different concrete substitutions for `'a`, and thus there will be N `Ty`
177 //! instances for the type `Struct<'a>` even though it is not generic otherwise.
178 //! Unfortunately this means that we cannot use `ty::type_id()` as cheap identifier
179 //! for type metadata---we have done this in the past, but it led to unnecessary
180 //! metadata duplication in the best case and LLVM assertions in the worst. However,
181 //! the unique type ID as described above *can* be used as identifier. Since it is
182 //! comparatively expensive to construct, though, `ty::type_id()` is still used
183 //! additionally as an optimization for cases where the exact same type has been
184 //! seen before (which is most of the time).
185 use self::VariableAccess
::*;
186 use self::VariableKind
::*;
187 use self::MemberOffset
::*;
188 use self::MemberDescriptionFactory
::*;
189 use self::RecursiveTypeDescription
::*;
190 use self::EnumDiscriminantInfo
::*;
191 use self::InternalDebugLocation
::*;
194 use llvm
::{ModuleRef, ContextRef, ValueRef}
;
195 use llvm
::debuginfo
::*;
196 use metadata
::csearch
;
197 use middle
::subst
::{self, Substs}
;
198 use trans
::{self, adt, machine, type_of}
;
199 use trans
::common
::{self, NodeIdAndSpan
, CrateContext
, FunctionContext
, Block
, C_bytes
,
200 NormalizingClosureTyper
};
202 use trans
::_match
::{BindingInfo, TrByCopy, TrByMove, TrByRef}
;
203 use trans
::monomorphize
;
204 use trans
::type_
::Type
;
205 use middle
::ty
::{self, Ty, ClosureTyper}
;
206 use middle
::pat_util
;
207 use session
::config
::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}
;
208 use util
::nodemap
::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet}
;
210 use util
::common
::path2cstr
;
212 use libc
::{c_uint, c_longlong}
;
213 use std
::cell
::{Cell, RefCell}
;
214 use std
::ffi
::CString
;
217 use std
::rc
::{Rc, Weak}
;
218 use syntax
::util
::interner
::Interner
;
219 use syntax
::codemap
::{Span, Pos}
;
220 use syntax
::{ast, codemap, ast_util, ast_map, attr}
;
221 use syntax
::parse
::token
::{self, special_idents}
;
223 const DW_LANG_RUST
: c_uint
= 0x9000;
225 #[allow(non_upper_case_globals)]
226 const DW_TAG_auto_variable
: c_uint
= 0x100;
227 #[allow(non_upper_case_globals)]
228 const DW_TAG_arg_variable
: c_uint
= 0x101;
230 #[allow(non_upper_case_globals)]
231 const DW_ATE_boolean
: c_uint
= 0x02;
232 #[allow(non_upper_case_globals)]
233 const DW_ATE_float
: c_uint
= 0x04;
234 #[allow(non_upper_case_globals)]
235 const DW_ATE_signed
: c_uint
= 0x05;
236 #[allow(non_upper_case_globals)]
237 const DW_ATE_unsigned
: c_uint
= 0x07;
238 #[allow(non_upper_case_globals)]
239 const DW_ATE_unsigned_char
: c_uint
= 0x08;
241 const UNKNOWN_LINE_NUMBER
: c_uint
= 0;
242 const UNKNOWN_COLUMN_NUMBER
: c_uint
= 0;
244 // ptr::null() doesn't work :(
245 const UNKNOWN_FILE_METADATA
: DIFile
= (0 as DIFile
);
246 const UNKNOWN_SCOPE_METADATA
: DIScope
= (0 as DIScope
);
248 const FLAGS_NONE
: c_uint
= 0;
250 //=-----------------------------------------------------------------------------
251 // Public Interface of debuginfo module
252 //=-----------------------------------------------------------------------------
254 #[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
255 struct UniqueTypeId(ast
::Name
);
257 // The TypeMap is where the CrateDebugContext holds the type metadata nodes
258 // created so far. The metadata nodes are indexed by UniqueTypeId, and, for
259 // faster lookup, also by Ty. The TypeMap is responsible for creating
261 struct TypeMap
<'tcx
> {
262 // The UniqueTypeIds created so far
263 unique_id_interner
: Interner
<Rc
<String
>>,
264 // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
265 unique_id_to_metadata
: FnvHashMap
<UniqueTypeId
, DIType
>,
266 // A map from types to debuginfo metadata. This is a N:1 mapping.
267 type_to_metadata
: FnvHashMap
<Ty
<'tcx
>, DIType
>,
268 // A map from types to UniqueTypeId. This is a N:1 mapping.
269 type_to_unique_id
: FnvHashMap
<Ty
<'tcx
>, UniqueTypeId
>
272 impl<'tcx
> TypeMap
<'tcx
> {
274 fn new() -> TypeMap
<'tcx
> {
276 unique_id_interner
: Interner
::new(),
277 type_to_metadata
: FnvHashMap(),
278 unique_id_to_metadata
: FnvHashMap(),
279 type_to_unique_id
: FnvHashMap(),
283 // Adds a Ty to metadata mapping to the TypeMap. The method will fail if
284 // the mapping already exists.
285 fn register_type_with_metadata
<'a
>(&mut self,
286 cx
: &CrateContext
<'a
, 'tcx
>,
289 if self.type_to_metadata
.insert(type_
, metadata
).is_some() {
290 cx
.sess().bug(&format
!("Type metadata for Ty '{}' is already in the TypeMap!",
291 ppaux
::ty_to_string(cx
.tcx(), type_
)));
295 // Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
296 // fail if the mapping already exists.
297 fn register_unique_id_with_metadata(&mut self,
299 unique_type_id
: UniqueTypeId
,
301 if self.unique_id_to_metadata
.insert(unique_type_id
, metadata
).is_some() {
302 let unique_type_id_str
= self.get_unique_type_id_as_string(unique_type_id
);
303 cx
.sess().bug(&format
!("Type metadata for unique id '{}' is already in the TypeMap!",
304 &unique_type_id_str
[..]));
308 fn find_metadata_for_type(&self, type_
: Ty
<'tcx
>) -> Option
<DIType
> {
309 self.type_to_metadata
.get(&type_
).cloned()
312 fn find_metadata_for_unique_id(&self, unique_type_id
: UniqueTypeId
) -> Option
<DIType
> {
313 self.unique_id_to_metadata
.get(&unique_type_id
).cloned()
316 // Get the string representation of a UniqueTypeId. This method will fail if
317 // the id is unknown.
318 fn get_unique_type_id_as_string(&self, unique_type_id
: UniqueTypeId
) -> Rc
<String
> {
319 let UniqueTypeId(interner_key
) = unique_type_id
;
320 self.unique_id_interner
.get(interner_key
)
323 // Get the UniqueTypeId for the given type. If the UniqueTypeId for the given
324 // type has been requested before, this is just a table lookup. Otherwise an
325 // ID will be generated and stored for later lookup.
326 fn get_unique_type_id_of_type
<'a
>(&mut self, cx
: &CrateContext
<'a
, 'tcx
>,
327 type_
: Ty
<'tcx
>) -> UniqueTypeId
{
329 // basic type -> {:name of the type:}
330 // tuple -> {tuple_(:param-uid:)*}
331 // struct -> {struct_:svh: / :node-id:_<(:param-uid:),*> }
332 // enum -> {enum_:svh: / :node-id:_<(:param-uid:),*> }
333 // enum variant -> {variant_:variant-name:_:enum-uid:}
334 // reference (&) -> {& :pointee-uid:}
335 // mut reference (&mut) -> {&mut :pointee-uid:}
336 // ptr (*) -> {* :pointee-uid:}
337 // mut ptr (*mut) -> {*mut :pointee-uid:}
338 // unique ptr (~) -> {~ :pointee-uid:}
339 // @-ptr (@) -> {@ :pointee-uid:}
340 // sized vec ([T; x]) -> {[:size:] :element-uid:}
341 // unsized vec ([T]) -> {[] :element-uid:}
342 // trait (T) -> {trait_:svh: / :node-id:_<(:param-uid:),*> }
343 // closure -> {<unsafe_> <once_> :store-sigil: |(:param-uid:),* <,_...>| -> \
344 // :return-type-uid: : (:bounds:)*}
345 // function -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \
346 // :return-type-uid:}
347 // unique vec box (~[]) -> {HEAP_VEC_BOX<:pointee-uid:>}
348 // gc box -> {GC_BOX<:pointee-uid:>}
350 match self.type_to_unique_id
.get(&type_
).cloned() {
351 Some(unique_type_id
) => return unique_type_id
,
352 None
=> { /* generate one */}
355 let mut unique_type_id
= String
::with_capacity(256);
356 unique_type_id
.push('
{'
);
365 push_debuginfo_type_name(cx
, type_
, false, &mut unique_type_id
);
367 ty
::ty_enum(def_id
, substs
) => {
368 unique_type_id
.push_str("enum ");
369 from_def_id_and_substs(self, cx
, def_id
, substs
, &mut unique_type_id
);
371 ty
::ty_struct(def_id
, substs
) => {
372 unique_type_id
.push_str("struct ");
373 from_def_id_and_substs(self, cx
, def_id
, substs
, &mut unique_type_id
);
375 ty
::ty_tup(ref component_types
) if component_types
.is_empty() => {
376 push_debuginfo_type_name(cx
, type_
, false, &mut unique_type_id
);
378 ty
::ty_tup(ref component_types
) => {
379 unique_type_id
.push_str("tuple ");
380 for &component_type
in component_types
{
381 let component_type_id
=
382 self.get_unique_type_id_of_type(cx
, component_type
);
383 let component_type_id
=
384 self.get_unique_type_id_as_string(component_type_id
);
385 unique_type_id
.push_str(&component_type_id
[..]);
388 ty
::ty_uniq(inner_type
) => {
389 unique_type_id
.push('
~'
);
390 let inner_type_id
= self.get_unique_type_id_of_type(cx
, inner_type
);
391 let inner_type_id
= self.get_unique_type_id_as_string(inner_type_id
);
392 unique_type_id
.push_str(&inner_type_id
[..]);
394 ty
::ty_ptr(ty
::mt { ty: inner_type, mutbl }
) => {
395 unique_type_id
.push('
*'
);
396 if mutbl
== ast
::MutMutable
{
397 unique_type_id
.push_str("mut");
400 let inner_type_id
= self.get_unique_type_id_of_type(cx
, inner_type
);
401 let inner_type_id
= self.get_unique_type_id_as_string(inner_type_id
);
402 unique_type_id
.push_str(&inner_type_id
[..]);
404 ty
::ty_rptr(_
, ty
::mt { ty: inner_type, mutbl }
) => {
405 unique_type_id
.push('
&'
);
406 if mutbl
== ast
::MutMutable
{
407 unique_type_id
.push_str("mut");
410 let inner_type_id
= self.get_unique_type_id_of_type(cx
, inner_type
);
411 let inner_type_id
= self.get_unique_type_id_as_string(inner_type_id
);
412 unique_type_id
.push_str(&inner_type_id
[..]);
414 ty
::ty_vec(inner_type
, optional_length
) => {
415 match optional_length
{
417 unique_type_id
.push_str(&format
!("[{}]", len
));
420 unique_type_id
.push_str("[]");
424 let inner_type_id
= self.get_unique_type_id_of_type(cx
, inner_type
);
425 let inner_type_id
= self.get_unique_type_id_as_string(inner_type_id
);
426 unique_type_id
.push_str(&inner_type_id
[..]);
428 ty
::ty_trait(ref trait_data
) => {
429 unique_type_id
.push_str("trait ");
432 ty
::erase_late_bound_regions(cx
.tcx(),
433 &trait_data
.principal
);
435 from_def_id_and_substs(self,
439 &mut unique_type_id
);
441 ty
::ty_bare_fn(_
, &ty
::BareFnTy{ unsafety, abi, ref sig }
) => {
442 if unsafety
== ast
::Unsafety
::Unsafe
{
443 unique_type_id
.push_str("unsafe ");
446 unique_type_id
.push_str(abi
.name());
448 unique_type_id
.push_str(" fn(");
450 let sig
= ty
::erase_late_bound_regions(cx
.tcx(), sig
);
452 for ¶meter_type
in &sig
.inputs
{
453 let parameter_type_id
=
454 self.get_unique_type_id_of_type(cx
, parameter_type
);
455 let parameter_type_id
=
456 self.get_unique_type_id_as_string(parameter_type_id
);
457 unique_type_id
.push_str(¶meter_type_id
[..]);
458 unique_type_id
.push('
,'
);
462 unique_type_id
.push_str("...");
465 unique_type_id
.push_str(")->");
467 ty
::FnConverging(ret_ty
) => {
468 let return_type_id
= self.get_unique_type_id_of_type(cx
, ret_ty
);
469 let return_type_id
= self.get_unique_type_id_as_string(return_type_id
);
470 unique_type_id
.push_str(&return_type_id
[..]);
473 unique_type_id
.push_str("!");
477 ty
::ty_closure(def_id
, substs
) => {
478 let typer
= NormalizingClosureTyper
::new(cx
.tcx());
479 let closure_ty
= typer
.closure_type(def_id
, substs
);
480 self.get_unique_type_id_of_closure_type(cx
,
482 &mut unique_type_id
);
485 cx
.sess().bug(&format
!("get_unique_type_id_of_type() - unexpected type: {}, {:?}",
486 &ppaux
::ty_to_string(cx
.tcx(), type_
),
491 unique_type_id
.push('
}'
);
493 // Trim to size before storing permanently
494 unique_type_id
.shrink_to_fit();
496 let key
= self.unique_id_interner
.intern(Rc
::new(unique_type_id
));
497 self.type_to_unique_id
.insert(type_
, UniqueTypeId(key
));
499 return UniqueTypeId(key
);
501 fn from_def_id_and_substs
<'a
, 'tcx
>(type_map
: &mut TypeMap
<'tcx
>,
502 cx
: &CrateContext
<'a
, 'tcx
>,
504 substs
: &subst
::Substs
<'tcx
>,
505 output
: &mut String
) {
506 // First, find out the 'real' def_id of the type. Items inlined from
507 // other crates have to be mapped back to their source.
508 let source_def_id
= if def_id
.krate
== ast
::LOCAL_CRATE
{
509 match cx
.external_srcs().borrow().get(&def_id
.node
).cloned() {
510 Some(source_def_id
) => {
511 // The given def_id identifies the inlined copy of a
512 // type definition, let's take the source of the copy.
521 // Get the crate hash as first part of the identifier.
522 let crate_hash
= if source_def_id
.krate
== ast
::LOCAL_CRATE
{
523 cx
.link_meta().crate_hash
.clone()
525 cx
.sess().cstore
.get_crate_hash(source_def_id
.krate
)
528 output
.push_str(crate_hash
.as_str());
529 output
.push_str("/");
530 output
.push_str(&format
!("{:x}", def_id
.node
));
532 // Maybe check that there is no self type here.
534 let tps
= substs
.types
.get_slice(subst
::TypeSpace
);
538 for &type_parameter
in tps
{
540 type_map
.get_unique_type_id_of_type(cx
, type_parameter
);
542 type_map
.get_unique_type_id_as_string(param_type_id
);
543 output
.push_str(¶m_type_id
[..]);
552 fn get_unique_type_id_of_closure_type
<'a
>(&mut self,
553 cx
: &CrateContext
<'a
, 'tcx
>,
554 closure_ty
: ty
::ClosureTy
<'tcx
>,
555 unique_type_id
: &mut String
) {
556 let ty
::ClosureTy
{ unsafety
,
558 abi
: _
} = closure_ty
;
560 if unsafety
== ast
::Unsafety
::Unsafe
{
561 unique_type_id
.push_str("unsafe ");
564 unique_type_id
.push_str("|");
566 let sig
= ty
::erase_late_bound_regions(cx
.tcx(), sig
);
568 for ¶meter_type
in &sig
.inputs
{
569 let parameter_type_id
=
570 self.get_unique_type_id_of_type(cx
, parameter_type
);
571 let parameter_type_id
=
572 self.get_unique_type_id_as_string(parameter_type_id
);
573 unique_type_id
.push_str(¶meter_type_id
[..]);
574 unique_type_id
.push('
,'
);
578 unique_type_id
.push_str("...");
581 unique_type_id
.push_str("|->");
584 ty
::FnConverging(ret_ty
) => {
585 let return_type_id
= self.get_unique_type_id_of_type(cx
, ret_ty
);
586 let return_type_id
= self.get_unique_type_id_as_string(return_type_id
);
587 unique_type_id
.push_str(&return_type_id
[..]);
590 unique_type_id
.push_str("!");
595 // Get the UniqueTypeId for an enum variant. Enum variants are not really
596 // types of their own, so they need special handling. We still need a
597 // UniqueTypeId for them, since to debuginfo they *are* real types.
598 fn get_unique_type_id_of_enum_variant
<'a
>(&mut self,
599 cx
: &CrateContext
<'a
, 'tcx
>,
603 let enum_type_id
= self.get_unique_type_id_of_type(cx
, enum_type
);
604 let enum_variant_type_id
= format
!("{}::{}",
605 &self.get_unique_type_id_as_string(enum_type_id
),
607 let interner_key
= self.unique_id_interner
.intern(Rc
::new(enum_variant_type_id
));
608 UniqueTypeId(interner_key
)
612 // Returns from the enclosing function if the type metadata with the given
613 // unique id can be found in the type map
614 macro_rules
! return_if_metadata_created_in_meantime
{
615 ($cx
: expr
, $unique_type_id
: expr
) => (
616 match debug_context($cx
).type_map
618 .find_metadata_for_unique_id($unique_type_id
) {
619 Some(metadata
) => return MetadataCreationResult
::new(metadata
, true),
620 None
=> { /* proceed normally */ }
626 /// A context object for maintaining all state needed by the debuginfo module.
627 pub struct CrateDebugContext
<'tcx
> {
628 llcontext
: ContextRef
,
629 builder
: DIBuilderRef
,
630 current_debug_location
: Cell
<InternalDebugLocation
>,
631 created_files
: RefCell
<FnvHashMap
<String
, DIFile
>>,
632 created_enum_disr_types
: RefCell
<DefIdMap
<DIType
>>,
634 type_map
: RefCell
<TypeMap
<'tcx
>>,
635 namespace_map
: RefCell
<FnvHashMap
<Vec
<ast
::Name
>, Rc
<NamespaceTreeNode
>>>,
637 // This collection is used to assert that composite types (structs, enums,
638 // ...) have their members only set once:
639 composite_types_completed
: RefCell
<FnvHashSet
<DIType
>>,
642 impl<'tcx
> CrateDebugContext
<'tcx
> {
643 pub fn new(llmod
: ModuleRef
) -> CrateDebugContext
<'tcx
> {
644 debug
!("CrateDebugContext::new");
645 let builder
= unsafe { llvm::LLVMDIBuilderCreate(llmod) }
;
646 // DIBuilder inherits context from the module, so we'd better use the same one
647 let llcontext
= unsafe { llvm::LLVMGetModuleContext(llmod) }
;
648 return CrateDebugContext
{
649 llcontext
: llcontext
,
651 current_debug_location
: Cell
::new(UnknownLocation
),
652 created_files
: RefCell
::new(FnvHashMap()),
653 created_enum_disr_types
: RefCell
::new(DefIdMap()),
654 type_map
: RefCell
::new(TypeMap
::new()),
655 namespace_map
: RefCell
::new(FnvHashMap()),
656 composite_types_completed
: RefCell
::new(FnvHashSet()),
661 pub enum FunctionDebugContext
{
662 RegularContext(Box
<FunctionDebugContextData
>),
664 FunctionWithoutDebugInfo
,
667 impl FunctionDebugContext
{
668 fn get_ref
<'a
>(&'a
self,
671 -> &'a FunctionDebugContextData
{
673 FunctionDebugContext
::RegularContext(box ref data
) => data
,
674 FunctionDebugContext
::DebugInfoDisabled
=> {
675 cx
.sess().span_bug(span
,
676 FunctionDebugContext
::debuginfo_disabled_message());
678 FunctionDebugContext
::FunctionWithoutDebugInfo
=> {
679 cx
.sess().span_bug(span
,
680 FunctionDebugContext
::should_be_ignored_message());
685 fn debuginfo_disabled_message() -> &'
static str {
686 "debuginfo: Error trying to access FunctionDebugContext although debug info is disabled!"
689 fn should_be_ignored_message() -> &'
static str {
690 "debuginfo: Error trying to access FunctionDebugContext for function that should be \
691 ignored by debug info!"
695 struct FunctionDebugContextData
{
696 scope_map
: RefCell
<NodeMap
<DIScope
>>,
697 fn_metadata
: DISubprogram
,
698 argument_counter
: Cell
<usize>,
699 source_locations_enabled
: Cell
<bool
>,
700 source_location_override
: Cell
<bool
>,
703 enum VariableAccess
<'a
> {
704 // The llptr given is an alloca containing the variable's value
705 DirectVariable { alloca: ValueRef }
,
706 // The llptr given is an alloca containing the start of some pointer chain
707 // leading to the variable's content.
708 IndirectVariable { alloca: ValueRef, address_operations: &'a [i64] }
712 ArgumentVariable(usize /*index*/),
717 /// Create any deferred debug metadata nodes
718 pub fn finalize(cx
: &CrateContext
) {
719 if cx
.dbg_cx().is_none() {
724 let _
= compile_unit_metadata(cx
);
726 if needs_gdb_debug_scripts_section(cx
) {
727 // Add a .debug_gdb_scripts section to this compile-unit. This will
728 // cause GDB to try and load the gdb_load_rust_pretty_printers.py file,
729 // which activates the Rust pretty printers for binary this section is
731 get_or_insert_gdb_debug_scripts_section_global(cx
);
735 llvm
::LLVMDIBuilderFinalize(DIB(cx
));
736 llvm
::LLVMDIBuilderDispose(DIB(cx
));
737 // Debuginfo generation in LLVM by default uses a higher
738 // version of dwarf than OS X currently understands. We can
739 // instruct LLVM to emit an older version of dwarf, however,
740 // for OS X to understand. For more info see #11352
741 // This can be overridden using --llvm-opts -dwarf-version,N.
742 // Android has the same issue (#22398)
743 if cx
.sess().target
.target
.options
.is_like_osx
||
744 cx
.sess().target
.target
.options
.is_like_android
{
745 llvm
::LLVMRustAddModuleFlag(cx
.llmod(),
746 "Dwarf Version\0".as_ptr() as *const _
,
750 // Prevent bitcode readers from deleting the debug info.
751 let ptr
= "Debug Info Version\0".as_ptr();
752 llvm
::LLVMRustAddModuleFlag(cx
.llmod(), ptr
as *const _
,
753 llvm
::LLVMRustDebugMetadataVersion
);
757 /// Creates debug information for the given global variable.
759 /// Adds the created metadata nodes directly to the crate's IR.
760 pub fn create_global_var_metadata(cx
: &CrateContext
,
761 node_id
: ast
::NodeId
,
763 if cx
.dbg_cx().is_none() {
767 // Don't create debuginfo for globals inlined from other crates. The other
768 // crate should already contain debuginfo for it. More importantly, the
769 // global might not even exist in un-inlined form anywhere which would lead
770 // to a linker errors.
771 if cx
.external_srcs().borrow().contains_key(&node_id
) {
775 let var_item
= cx
.tcx().map
.get(node_id
);
777 let (name
, span
) = match var_item
{
778 ast_map
::NodeItem(item
) => {
780 ast
::ItemStatic(..) => (item
.ident
.name
, item
.span
),
781 ast
::ItemConst(..) => (item
.ident
.name
, item
.span
),
785 &format
!("debuginfo::\
786 create_global_var_metadata() -
787 Captured var-id refers to \
788 unexpected ast_item variant: {:?}",
793 _
=> cx
.sess().bug(&format
!("debuginfo::create_global_var_metadata() \
794 - Captured var-id refers to unexpected \
795 ast_map variant: {:?}",
799 let (file_metadata
, line_number
) = if span
!= codemap
::DUMMY_SP
{
800 let loc
= span_start(cx
, span
);
801 (file_metadata(cx
, &loc
.file
.name
), loc
.line
as c_uint
)
803 (UNKNOWN_FILE_METADATA
, UNKNOWN_LINE_NUMBER
)
806 let is_local_to_unit
= is_node_local_to_unit(cx
, node_id
);
807 let variable_type
= ty
::node_id_to_type(cx
.tcx(), node_id
);
808 let type_metadata
= type_metadata(cx
, variable_type
, span
);
809 let namespace_node
= namespace_for_item(cx
, ast_util
::local_def(node_id
));
810 let var_name
= token
::get_name(name
).to_string();
812 namespace_node
.mangled_name_of_contained_item(&var_name
[..]);
813 let var_scope
= namespace_node
.scope
;
815 let var_name
= CString
::new(var_name
).unwrap();
816 let linkage_name
= CString
::new(linkage_name
).unwrap();
818 llvm
::LLVMDIBuilderCreateStaticVariable(DIB(cx
),
821 linkage_name
.as_ptr(),
831 /// Creates debug information for the given local variable.
833 /// This function assumes that there's a datum for each pattern component of the
834 /// local in `bcx.fcx.lllocals`.
835 /// Adds the created metadata nodes directly to the crate's IR.
836 pub fn create_local_var_metadata(bcx
: Block
, local
: &ast
::Local
) {
837 if bcx
.unreachable
.get() ||
838 fn_should_be_ignored(bcx
.fcx
) ||
839 bcx
.sess().opts
.debuginfo
!= FullDebugInfo
{
844 let def_map
= &cx
.tcx().def_map
;
845 let locals
= bcx
.fcx
.lllocals
.borrow();
847 pat_util
::pat_bindings(def_map
, &*local
.pat
, |_
, node_id
, span
, var_ident
| {
848 let datum
= match locals
.get(&node_id
) {
849 Some(datum
) => datum
,
851 bcx
.sess().span_bug(span
,
852 &format
!("no entry in lllocals table for {}",
857 if unsafe { llvm::LLVMIsAAllocaInst(datum.val) }
== ptr
::null_mut() {
858 cx
.sess().span_bug(span
, "debuginfo::create_local_var_metadata() - \
859 Referenced variable location is not an alloca!");
862 let scope_metadata
= scope_metadata(bcx
.fcx
, node_id
, span
);
868 DirectVariable { alloca: datum.val }
,
874 /// Creates debug information for a variable captured in a closure.
876 /// Adds the created metadata nodes directly to the crate's IR.
877 pub fn create_captured_var_metadata
<'blk
, 'tcx
>(bcx
: Block
<'blk
, 'tcx
>,
878 node_id
: ast
::NodeId
,
879 env_pointer
: ValueRef
,
881 captured_by_ref
: bool
,
883 if bcx
.unreachable
.get() ||
884 fn_should_be_ignored(bcx
.fcx
) ||
885 bcx
.sess().opts
.debuginfo
!= FullDebugInfo
{
891 let ast_item
= cx
.tcx().map
.find(node_id
);
893 let variable_name
= match ast_item
{
895 cx
.sess().span_bug(span
, "debuginfo::create_captured_var_metadata: node not found");
897 Some(ast_map
::NodeLocal(pat
)) | Some(ast_map
::NodeArg(pat
)) => {
899 ast
::PatIdent(_
, ref path1
, _
) => {
906 "debuginfo::create_captured_var_metadata() - \
907 Captured var-id refers to unexpected \
908 ast_map variant: {:?}",
916 &format
!("debuginfo::create_captured_var_metadata() - \
917 Captured var-id refers to unexpected \
918 ast_map variant: {:?}",
923 let variable_type
= common
::node_id_type(bcx
, node_id
);
924 let scope_metadata
= bcx
.fcx
.debug_context
.get_ref(cx
, span
).fn_metadata
;
926 // env_pointer is the alloca containing the pointer to the environment,
927 // so it's type is **EnvironmentType. In order to find out the type of
928 // the environment we have to "dereference" two times.
929 let llvm_env_data_type
= common
::val_ty(env_pointer
).element_type()
931 let byte_offset_of_var_in_env
= machine
::llelement_offset(cx
,
935 let address_operations
= unsafe {
936 [llvm
::LLVMDIBuilderCreateOpDeref(),
937 llvm
::LLVMDIBuilderCreateOpPlus(),
938 byte_offset_of_var_in_env
as i64,
939 llvm
::LLVMDIBuilderCreateOpDeref()]
942 let address_op_count
= if captured_by_ref
{
943 address_operations
.len()
945 address_operations
.len() - 1
948 let variable_access
= IndirectVariable
{
950 address_operations
: &address_operations
[..address_op_count
]
962 /// Creates debug information for a local variable introduced in the head of a
963 /// match-statement arm.
965 /// Adds the created metadata nodes directly to the crate's IR.
966 pub fn create_match_binding_metadata
<'blk
, 'tcx
>(bcx
: Block
<'blk
, 'tcx
>,
967 variable_name
: ast
::Name
,
968 binding
: BindingInfo
<'tcx
>) {
969 if bcx
.unreachable
.get() ||
970 fn_should_be_ignored(bcx
.fcx
) ||
971 bcx
.sess().opts
.debuginfo
!= FullDebugInfo
{
975 let scope_metadata
= scope_metadata(bcx
.fcx
, binding
.id
, binding
.span
);
977 [llvm
::LLVMDIBuilderCreateOpDeref()]
979 // Regardless of the actual type (`T`) we're always passed the stack slot (alloca)
980 // for the binding. For ByRef bindings that's a `T*` but for ByMove bindings we
981 // actually have `T**`. So to get the actual variable we need to dereference once
982 // more. For ByCopy we just use the stack slot we created for the binding.
983 let var_access
= match binding
.trmode
{
984 TrByCopy(llbinding
) => DirectVariable
{
987 TrByMove
=> IndirectVariable
{
988 alloca
: binding
.llmatch
,
989 address_operations
: &aops
991 TrByRef
=> DirectVariable
{
992 alloca
: binding
.llmatch
1005 /// Creates debug information for the given function argument.
1007 /// This function assumes that there's a datum for each pattern component of the
1008 /// argument in `bcx.fcx.lllocals`.
1009 /// Adds the created metadata nodes directly to the crate's IR.
1010 pub fn create_argument_metadata(bcx
: Block
, arg
: &ast
::Arg
) {
1011 if bcx
.unreachable
.get() ||
1012 fn_should_be_ignored(bcx
.fcx
) ||
1013 bcx
.sess().opts
.debuginfo
!= FullDebugInfo
{
1017 let def_map
= &bcx
.tcx().def_map
;
1018 let scope_metadata
= bcx
1021 .get_ref(bcx
.ccx(), arg
.pat
.span
)
1023 let locals
= bcx
.fcx
.lllocals
.borrow();
1025 pat_util
::pat_bindings(def_map
, &*arg
.pat
, |_
, node_id
, span
, var_ident
| {
1026 let datum
= match locals
.get(&node_id
) {
1029 bcx
.sess().span_bug(span
,
1030 &format
!("no entry in lllocals table for {}",
1035 if unsafe { llvm::LLVMIsAAllocaInst(datum.val) }
== ptr
::null_mut() {
1036 bcx
.sess().span_bug(span
, "debuginfo::create_argument_metadata() - \
1037 Referenced variable location is not an alloca!");
1040 let argument_index
= {
1044 .get_ref(bcx
.ccx(), span
)
1046 let argument_index
= counter
.get();
1047 counter
.set(argument_index
+ 1);
1052 var_ident
.node
.name
,
1055 DirectVariable { alloca: datum.val }
,
1056 ArgumentVariable(argument_index
),
1061 pub fn get_cleanup_debug_loc_for_ast_node
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
1062 node_id
: ast
::NodeId
,
1066 // A debug location needs two things:
1067 // (1) A span (of which only the beginning will actually be used)
1068 // (2) An AST node-id which will be used to look up the lexical scope
1069 // for the location in the functions scope-map
1071 // This function will calculate the debug location for compiler-generated
1072 // cleanup calls that are executed when control-flow leaves the
1073 // scope identified by `node_id`.
1075 // For everything but block-like things we can simply take id and span of
1076 // the given expression, meaning that from a debugger's view cleanup code is
1077 // executed at the same source location as the statement/expr itself.
1079 // Blocks are a special case. Here we want the cleanup to be linked to the
1080 // closing curly brace of the block. The *scope* the cleanup is executed in
1081 // is up to debate: It could either still be *within* the block being
1082 // cleaned up, meaning that locals from the block are still visible in the
1084 // Or it could be in the scope that the block is contained in, so any locals
1085 // from within the block are already considered out-of-scope and thus not
1086 // accessible in the debugger anymore.
1088 // The current implementation opts for the second option: cleanup of a block
1089 // already happens in the parent scope of the block. The main reason for
1090 // this decision is that scoping becomes controlflow dependent when variable
1091 // shadowing is involved and it's impossible to decide statically which
1092 // scope is actually left when the cleanup code is executed.
1093 // In practice it shouldn't make much of a difference.
1095 let mut cleanup_span
= node_span
;
1098 // Not all blocks actually have curly braces (e.g. simple closure
1099 // bodies), in which case we also just want to return the span of the
1100 // whole expression.
1101 let code_snippet
= cx
.sess().codemap().span_to_snippet(node_span
);
1102 if let Ok(code_snippet
) = code_snippet
{
1103 let bytes
= code_snippet
.as_bytes();
1105 if !bytes
.is_empty() && &bytes
[bytes
.len()-1..] == b
"}" {
1106 cleanup_span
= Span
{
1107 lo
: node_span
.hi
- codemap
::BytePos(1),
1109 expn_id
: node_span
.expn_id
1121 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
1123 At(ast
::NodeId
, Span
),
1128 pub fn apply(&self, fcx
: &FunctionContext
) {
1130 DebugLoc
::At(node_id
, span
) => {
1131 set_source_location(fcx
, node_id
, span
);
1134 clear_source_location(fcx
);
1140 pub trait ToDebugLoc
{
1141 fn debug_loc(&self) -> DebugLoc
;
1144 impl ToDebugLoc
for ast
::Expr
{
1145 fn debug_loc(&self) -> DebugLoc
{
1146 DebugLoc
::At(self.id
, self.span
)
1150 impl ToDebugLoc
for NodeIdAndSpan
{
1151 fn debug_loc(&self) -> DebugLoc
{
1152 DebugLoc
::At(self.id
, self.span
)
1156 impl ToDebugLoc
for Option
<NodeIdAndSpan
> {
1157 fn debug_loc(&self) -> DebugLoc
{
1159 Some(NodeIdAndSpan { id, span }
) => DebugLoc
::At(id
, span
),
1160 None
=> DebugLoc
::None
1165 /// Sets the current debug location at the beginning of the span.
1167 /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). The node_id
1168 /// parameter is used to reliably find the correct visibility scope for the code
1170 pub fn set_source_location(fcx
: &FunctionContext
,
1171 node_id
: ast
::NodeId
,
1173 match fcx
.debug_context
{
1174 FunctionDebugContext
::DebugInfoDisabled
=> return,
1175 FunctionDebugContext
::FunctionWithoutDebugInfo
=> {
1176 set_debug_location(fcx
.ccx
, UnknownLocation
);
1179 FunctionDebugContext
::RegularContext(box ref function_debug_context
) => {
1180 if function_debug_context
.source_location_override
.get() {
1181 // Just ignore any attempts to set a new debug location while
1182 // the override is active.
1188 debug
!("set_source_location: {}", cx
.sess().codemap().span_to_string(span
));
1190 if function_debug_context
.source_locations_enabled
.get() {
1191 let loc
= span_start(cx
, span
);
1192 let scope
= scope_metadata(fcx
, node_id
, span
);
1194 set_debug_location(cx
, InternalDebugLocation
::new(scope
,
1196 loc
.col
.to_usize()));
1198 set_debug_location(cx
, UnknownLocation
);
1204 /// This function makes sure that all debug locations emitted while executing
1205 /// `wrapped_function` are set to the given `debug_loc`.
1206 pub fn with_source_location_override
<F
, R
>(fcx
: &FunctionContext
,
1207 debug_loc
: DebugLoc
,
1208 wrapped_function
: F
) -> R
1209 where F
: FnOnce() -> R
1211 match fcx
.debug_context
{
1212 FunctionDebugContext
::DebugInfoDisabled
=> {
1215 FunctionDebugContext
::FunctionWithoutDebugInfo
=> {
1216 set_debug_location(fcx
.ccx
, UnknownLocation
);
1219 FunctionDebugContext
::RegularContext(box ref function_debug_context
) => {
1220 if function_debug_context
.source_location_override
.get() {
1223 debug_loc
.apply(fcx
);
1224 function_debug_context
.source_location_override
.set(true);
1225 let result
= wrapped_function();
1226 function_debug_context
.source_location_override
.set(false);
1233 /// Clears the current debug location.
1235 /// Instructions generated hereafter won't be assigned a source location.
1236 pub fn clear_source_location(fcx
: &FunctionContext
) {
1237 if fn_should_be_ignored(fcx
) {
1241 set_debug_location(fcx
.ccx
, UnknownLocation
);
1244 /// Enables emitting source locations for the given functions.
1246 /// Since we don't want source locations to be emitted for the function prelude,
1247 /// they are disabled when beginning to translate a new function. This functions
1248 /// switches source location emitting on and must therefore be called before the
1249 /// first real statement/expression of the function is translated.
1250 pub fn start_emitting_source_locations(fcx
: &FunctionContext
) {
1251 match fcx
.debug_context
{
1252 FunctionDebugContext
::RegularContext(box ref data
) => {
1253 data
.source_locations_enabled
.set(true)
1255 _
=> { /* safe to ignore */ }
1259 /// Creates the function-specific debug context.
1261 /// Returns the FunctionDebugContext for the function which holds state needed
1262 /// for debug info creation. The function may also return another variant of the
1263 /// FunctionDebugContext enum which indicates why no debuginfo should be created
1264 /// for the function.
1265 pub fn create_function_debug_context
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
1266 fn_ast_id
: ast
::NodeId
,
1267 param_substs
: &Substs
<'tcx
>,
1268 llfn
: ValueRef
) -> FunctionDebugContext
{
1269 if cx
.sess().opts
.debuginfo
== NoDebugInfo
{
1270 return FunctionDebugContext
::DebugInfoDisabled
;
1273 // Clear the debug location so we don't assign them in the function prelude.
1274 // Do this here already, in case we do an early exit from this function.
1275 set_debug_location(cx
, UnknownLocation
);
1277 if fn_ast_id
== ast
::DUMMY_NODE_ID
{
1278 // This is a function not linked to any source location, so don't
1279 // generate debuginfo for it.
1280 return FunctionDebugContext
::FunctionWithoutDebugInfo
;
1283 let empty_generics
= ast_util
::empty_generics();
1285 let fnitem
= cx
.tcx().map
.get(fn_ast_id
);
1287 let (name
, fn_decl
, generics
, top_level_block
, span
, has_path
) = match fnitem
{
1288 ast_map
::NodeItem(ref item
) => {
1289 if contains_nodebug_attribute(&item
.attrs
) {
1290 return FunctionDebugContext
::FunctionWithoutDebugInfo
;
1294 ast
::ItemFn(ref fn_decl
, _
, _
, ref generics
, ref top_level_block
) => {
1295 (item
.ident
.name
, fn_decl
, generics
, top_level_block
, item
.span
, true)
1298 cx
.sess().span_bug(item
.span
,
1299 "create_function_debug_context: item bound to non-function");
1303 ast_map
::NodeImplItem(impl_item
) => {
1304 match impl_item
.node
{
1305 ast
::MethodImplItem(ref sig
, ref body
) => {
1306 if contains_nodebug_attribute(&impl_item
.attrs
) {
1307 return FunctionDebugContext
::FunctionWithoutDebugInfo
;
1310 (impl_item
.ident
.name
,
1317 ast
::TypeImplItem(_
) => {
1318 cx
.sess().span_bug(impl_item
.span
,
1319 "create_function_debug_context() \
1320 called on associated type?!")
1322 ast
::MacImplItem(_
) => {
1323 cx
.sess().span_bug(impl_item
.span
,
1324 "create_function_debug_context() \
1325 called on unexpanded macro?!")
1329 ast_map
::NodeExpr(ref expr
) => {
1331 ast
::ExprClosure(_
, ref fn_decl
, ref top_level_block
) => {
1332 let name
= format
!("fn{}", token
::gensym("fn"));
1333 let name
= token
::intern(&name
[..]);
1335 // This is not quite right. It should actually inherit
1336 // the generics of the enclosing function.
1340 // Don't try to lookup the item path:
1343 _
=> cx
.sess().span_bug(expr
.span
,
1344 "create_function_debug_context: expected an expr_fn_block here")
1347 ast_map
::NodeTraitItem(trait_item
) => {
1348 match trait_item
.node
{
1349 ast
::MethodTraitItem(ref sig
, Some(ref body
)) => {
1350 if contains_nodebug_attribute(&trait_item
.attrs
) {
1351 return FunctionDebugContext
::FunctionWithoutDebugInfo
;
1354 (trait_item
.ident
.name
,
1363 .bug(&format
!("create_function_debug_context: \
1364 unexpected sort of node: {:?}",
1369 ast_map
::NodeForeignItem(..) |
1370 ast_map
::NodeVariant(..) |
1371 ast_map
::NodeStructCtor(..) => {
1372 return FunctionDebugContext
::FunctionWithoutDebugInfo
;
1374 _
=> cx
.sess().bug(&format
!("create_function_debug_context: \
1375 unexpected sort of node: {:?}",
1379 // This can be the case for functions inlined from another crate
1380 if span
== codemap
::DUMMY_SP
{
1381 return FunctionDebugContext
::FunctionWithoutDebugInfo
;
1384 let loc
= span_start(cx
, span
);
1385 let file_metadata
= file_metadata(cx
, &loc
.file
.name
);
1387 let function_type_metadata
= unsafe {
1388 let fn_signature
= get_function_signature(cx
,
1393 llvm
::LLVMDIBuilderCreateSubroutineType(DIB(cx
), file_metadata
, fn_signature
)
1396 // Get_template_parameters() will append a `<...>` clause to the function
1397 // name if necessary.
1398 let mut function_name
= String
::from_str(&token
::get_name(name
));
1399 let template_parameters
= get_template_parameters(cx
,
1403 &mut function_name
);
1405 // There is no ast_map::Path for ast::ExprClosure-type functions. For now,
1406 // just don't put them into a namespace. In the future this could be improved
1407 // somehow (storing a path in the ast_map, or construct a path using the
1408 // enclosing function).
1409 let (linkage_name
, containing_scope
) = if has_path
{
1410 let namespace_node
= namespace_for_item(cx
, ast_util
::local_def(fn_ast_id
));
1411 let linkage_name
= namespace_node
.mangled_name_of_contained_item(
1412 &function_name
[..]);
1413 let containing_scope
= namespace_node
.scope
;
1414 (linkage_name
, containing_scope
)
1416 (function_name
.clone(), file_metadata
)
1419 // Clang sets this parameter to the opening brace of the function's block,
1420 // so let's do this too.
1421 let scope_line
= span_start(cx
, top_level_block
.span
).line
;
1423 let is_local_to_unit
= is_node_local_to_unit(cx
, fn_ast_id
);
1425 let function_name
= CString
::new(function_name
).unwrap();
1426 let linkage_name
= CString
::new(linkage_name
).unwrap();
1427 let fn_metadata
= unsafe {
1428 llvm
::LLVMDIBuilderCreateFunction(
1431 function_name
.as_ptr(),
1432 linkage_name
.as_ptr(),
1435 function_type_metadata
,
1438 scope_line
as c_uint
,
1439 FlagPrototyped
as c_uint
,
1440 cx
.sess().opts
.optimize
!= config
::No
,
1442 template_parameters
,
1446 let scope_map
= create_scope_map(cx
,
1452 // Initialize fn debug context (including scope map and namespace map)
1453 let fn_debug_context
= box FunctionDebugContextData
{
1454 scope_map
: RefCell
::new(scope_map
),
1455 fn_metadata
: fn_metadata
,
1456 argument_counter
: Cell
::new(1),
1457 source_locations_enabled
: Cell
::new(false),
1458 source_location_override
: Cell
::new(false),
1463 return FunctionDebugContext
::RegularContext(fn_debug_context
);
1465 fn get_function_signature
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
1466 fn_ast_id
: ast
::NodeId
,
1467 fn_decl
: &ast
::FnDecl
,
1468 param_substs
: &Substs
<'tcx
>,
1469 error_reporting_span
: Span
) -> DIArray
{
1470 if cx
.sess().opts
.debuginfo
== LimitedDebugInfo
{
1471 return create_DIArray(DIB(cx
), &[]);
1474 let mut signature
= Vec
::with_capacity(fn_decl
.inputs
.len() + 1);
1476 // Return type -- llvm::DIBuilder wants this at index 0
1477 assert_type_for_node_id(cx
, fn_ast_id
, error_reporting_span
);
1478 let return_type
= ty
::node_id_to_type(cx
.tcx(), fn_ast_id
);
1479 let return_type
= monomorphize
::apply_param_substs(cx
.tcx(),
1482 if ty
::type_is_nil(return_type
) {
1483 signature
.push(ptr
::null_mut())
1485 signature
.push(type_metadata(cx
, return_type
, codemap
::DUMMY_SP
));
1489 for arg
in &fn_decl
.inputs
{
1490 assert_type_for_node_id(cx
, arg
.pat
.id
, arg
.pat
.span
);
1491 let arg_type
= ty
::node_id_to_type(cx
.tcx(), arg
.pat
.id
);
1492 let arg_type
= monomorphize
::apply_param_substs(cx
.tcx(),
1495 signature
.push(type_metadata(cx
, arg_type
, codemap
::DUMMY_SP
));
1498 return create_DIArray(DIB(cx
), &signature
[..]);
1501 fn get_template_parameters
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
1502 generics
: &ast
::Generics
,
1503 param_substs
: &Substs
<'tcx
>,
1504 file_metadata
: DIFile
,
1505 name_to_append_suffix_to
: &mut String
)
1508 let self_type
= param_substs
.self_ty();
1509 let self_type
= monomorphize
::normalize_associated_type(cx
.tcx(), &self_type
);
1511 // Only true for static default methods:
1512 let has_self_type
= self_type
.is_some();
1514 if !generics
.is_type_parameterized() && !has_self_type
{
1515 return create_DIArray(DIB(cx
), &[]);
1518 name_to_append_suffix_to
.push('
<'
);
1520 // The list to be filled with template parameters:
1521 let mut template_params
: Vec
<DIDescriptor
> =
1522 Vec
::with_capacity(generics
.ty_params
.len() + 1);
1526 let actual_self_type
= self_type
.unwrap();
1527 // Add self type name to <...> clause of function name
1528 let actual_self_type_name
= compute_debuginfo_type_name(
1533 name_to_append_suffix_to
.push_str(&actual_self_type_name
[..]);
1535 if generics
.is_type_parameterized() {
1536 name_to_append_suffix_to
.push_str(",");
1539 // Only create type information if full debuginfo is enabled
1540 if cx
.sess().opts
.debuginfo
== FullDebugInfo
{
1541 let actual_self_type_metadata
= type_metadata(cx
,
1545 let name
= token
::get_name(special_idents
::type_self
.name
);
1547 let name
= CString
::new(name
.as_bytes()).unwrap();
1548 let param_metadata
= unsafe {
1549 llvm
::LLVMDIBuilderCreateTemplateTypeParameter(
1553 actual_self_type_metadata
,
1559 template_params
.push(param_metadata
);
1563 // Handle other generic parameters
1564 let actual_types
= param_substs
.types
.get_slice(subst
::FnSpace
);
1565 for (index
, &ast
::TyParam{ ident, .. }
) in generics
.ty_params
.iter().enumerate() {
1566 let actual_type
= actual_types
[index
];
1567 // Add actual type name to <...> clause of function name
1568 let actual_type_name
= compute_debuginfo_type_name(cx
,
1571 name_to_append_suffix_to
.push_str(&actual_type_name
[..]);
1573 if index
!= generics
.ty_params
.len() - 1 {
1574 name_to_append_suffix_to
.push_str(",");
1577 // Again, only create type information if full debuginfo is enabled
1578 if cx
.sess().opts
.debuginfo
== FullDebugInfo
{
1579 let actual_type_metadata
= type_metadata(cx
, actual_type
, codemap
::DUMMY_SP
);
1580 let ident
= token
::get_ident(ident
);
1581 let name
= CString
::new(ident
.as_bytes()).unwrap();
1582 let param_metadata
= unsafe {
1583 llvm
::LLVMDIBuilderCreateTemplateTypeParameter(
1587 actual_type_metadata
,
1592 template_params
.push(param_metadata
);
1596 name_to_append_suffix_to
.push('
>'
);
1598 return create_DIArray(DIB(cx
), &template_params
[..]);
1602 //=-----------------------------------------------------------------------------
1603 // Module-Internal debug info creation functions
1604 //=-----------------------------------------------------------------------------
1606 fn is_node_local_to_unit(cx
: &CrateContext
, node_id
: ast
::NodeId
) -> bool
1608 // The is_local_to_unit flag indicates whether a function is local to the
1609 // current compilation unit (i.e. if it is *static* in the C-sense). The
1610 // *reachable* set should provide a good approximation of this, as it
1611 // contains everything that might leak out of the current crate (by being
1612 // externally visible or by being inlined into something externally visible).
1613 // It might better to use the `exported_items` set from `driver::CrateAnalysis`
1614 // in the future, but (atm) this set is not available in the translation pass.
1615 !cx
.reachable().contains(&node_id
)
1618 #[allow(non_snake_case)]
1619 fn create_DIArray(builder
: DIBuilderRef
, arr
: &[DIDescriptor
]) -> DIArray
{
1621 llvm
::LLVMDIBuilderGetOrCreateArray(builder
, arr
.as_ptr(), arr
.len() as u32)
1625 fn compile_unit_metadata(cx
: &CrateContext
) -> DIDescriptor
{
1626 let work_dir
= &cx
.sess().working_dir
;
1627 let compile_unit_name
= match cx
.sess().local_crate_source_file
{
1628 None
=> fallback_path(cx
),
1629 Some(ref abs_path
) => {
1630 if abs_path
.is_relative() {
1631 cx
.sess().warn("debuginfo: Invalid path to crate's local root source file!");
1634 match abs_path
.relative_from(work_dir
) {
1635 Some(ref p
) if p
.is_relative() => {
1636 if p
.starts_with(Path
::new("./")) {
1639 path2cstr(&Path
::new(".").join(p
))
1642 _
=> fallback_path(cx
)
1648 debug
!("compile_unit_metadata: {:?}", compile_unit_name
);
1649 let producer
= format
!("rustc version {}",
1650 (option_env
!("CFG_VERSION")).expect("CFG_VERSION"));
1652 let compile_unit_name
= compile_unit_name
.as_ptr();
1653 let work_dir
= path2cstr(&work_dir
);
1654 let producer
= CString
::new(producer
).unwrap();
1656 let split_name
= "\0";
1658 llvm
::LLVMDIBuilderCreateCompileUnit(
1659 debug_context(cx
).builder
,
1664 cx
.sess().opts
.optimize
!= config
::No
,
1665 flags
.as_ptr() as *const _
,
1667 split_name
.as_ptr() as *const _
)
1670 fn fallback_path(cx
: &CrateContext
) -> CString
{
1671 CString
::new(cx
.link_meta().crate_name
.clone()).unwrap()
1675 fn declare_local
<'blk
, 'tcx
>(bcx
: Block
<'blk
, 'tcx
>,
1676 variable_name
: ast
::Name
,
1677 variable_type
: Ty
<'tcx
>,
1678 scope_metadata
: DIScope
,
1679 variable_access
: VariableAccess
,
1680 variable_kind
: VariableKind
,
1682 let cx
: &CrateContext
= bcx
.ccx();
1684 let filename
= span_start(cx
, span
).file
.name
.clone();
1685 let file_metadata
= file_metadata(cx
, &filename
[..]);
1687 let name
= token
::get_name(variable_name
);
1688 let loc
= span_start(cx
, span
);
1689 let type_metadata
= type_metadata(cx
, variable_type
, span
);
1691 let (argument_index
, dwarf_tag
) = match variable_kind
{
1692 ArgumentVariable(index
) => (index
as c_uint
, DW_TAG_arg_variable
),
1694 CapturedVariable
=> (0, DW_TAG_auto_variable
)
1697 let name
= CString
::new(name
.as_bytes()).unwrap();
1698 match (variable_access
, &[][..]) {
1699 (DirectVariable { alloca }
, address_operations
) |
1700 (IndirectVariable {alloca, address_operations}
, _
) => {
1701 let metadata
= unsafe {
1702 llvm
::LLVMDIBuilderCreateVariable(
1710 cx
.sess().opts
.optimize
!= config
::No
,
1712 address_operations
.as_ptr(),
1713 address_operations
.len() as c_uint
,
1716 set_debug_location(cx
, InternalDebugLocation
::new(scope_metadata
,
1718 loc
.col
.to_usize()));
1720 let instr
= llvm
::LLVMDIBuilderInsertDeclareAtEnd(
1724 address_operations
.as_ptr(),
1725 address_operations
.len() as c_uint
,
1728 llvm
::LLVMSetInstDebugLocation(trans
::build
::B(bcx
).llbuilder
, instr
);
1733 match variable_kind
{
1734 ArgumentVariable(_
) | CapturedVariable
=> {
1738 .source_locations_enabled
1740 set_debug_location(cx
, UnknownLocation
);
1742 _
=> { /* nothing to do */ }
1746 fn file_metadata(cx
: &CrateContext
, full_path
: &str) -> DIFile
{
1747 match debug_context(cx
).created_files
.borrow().get(full_path
) {
1748 Some(file_metadata
) => return *file_metadata
,
1752 debug
!("file_metadata: {}", full_path
);
1754 // FIXME (#9639): This needs to handle non-utf8 paths
1755 let work_dir
= cx
.sess().working_dir
.to_str().unwrap();
1757 if full_path
.starts_with(work_dir
) {
1758 &full_path
[work_dir
.len() + 1..full_path
.len()]
1763 let file_name
= CString
::new(file_name
).unwrap();
1764 let work_dir
= CString
::new(work_dir
).unwrap();
1765 let file_metadata
= unsafe {
1766 llvm
::LLVMDIBuilderCreateFile(DIB(cx
), file_name
.as_ptr(),
1770 let mut created_files
= debug_context(cx
).created_files
.borrow_mut();
1771 created_files
.insert(full_path
.to_string(), file_metadata
);
1772 return file_metadata
;
1775 /// Finds the scope metadata node for the given AST node.
1776 fn scope_metadata(fcx
: &FunctionContext
,
1777 node_id
: ast
::NodeId
,
1778 error_reporting_span
: Span
)
1780 let scope_map
= &fcx
.debug_context
1781 .get_ref(fcx
.ccx
, error_reporting_span
)
1783 match scope_map
.borrow().get(&node_id
).cloned() {
1784 Some(scope_metadata
) => scope_metadata
,
1786 let node
= fcx
.ccx
.tcx().map
.get(node_id
);
1788 fcx
.ccx
.sess().span_bug(error_reporting_span
,
1789 &format
!("debuginfo: Could not find scope info for node {:?}",
1795 fn diverging_type_metadata(cx
: &CrateContext
) -> DIType
{
1797 llvm
::LLVMDIBuilderCreateBasicType(
1799 "!\0".as_ptr() as *const _
,
1806 fn basic_type_metadata
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
1807 t
: Ty
<'tcx
>) -> DIType
{
1809 debug
!("basic_type_metadata: {:?}", t
);
1811 let (name
, encoding
) = match t
.sty
{
1812 ty
::ty_tup(ref elements
) if elements
.is_empty() =>
1813 ("()".to_string(), DW_ATE_unsigned
),
1814 ty
::ty_bool
=> ("bool".to_string(), DW_ATE_boolean
),
1815 ty
::ty_char
=> ("char".to_string(), DW_ATE_unsigned_char
),
1816 ty
::ty_int(int_ty
) => match int_ty
{
1817 ast
::TyIs
=> ("isize".to_string(), DW_ATE_signed
),
1818 ast
::TyI8
=> ("i8".to_string(), DW_ATE_signed
),
1819 ast
::TyI16
=> ("i16".to_string(), DW_ATE_signed
),
1820 ast
::TyI32
=> ("i32".to_string(), DW_ATE_signed
),
1821 ast
::TyI64
=> ("i64".to_string(), DW_ATE_signed
)
1823 ty
::ty_uint(uint_ty
) => match uint_ty
{
1824 ast
::TyUs
=> ("usize".to_string(), DW_ATE_unsigned
),
1825 ast
::TyU8
=> ("u8".to_string(), DW_ATE_unsigned
),
1826 ast
::TyU16
=> ("u16".to_string(), DW_ATE_unsigned
),
1827 ast
::TyU32
=> ("u32".to_string(), DW_ATE_unsigned
),
1828 ast
::TyU64
=> ("u64".to_string(), DW_ATE_unsigned
)
1830 ty
::ty_float(float_ty
) => match float_ty
{
1831 ast
::TyF32
=> ("f32".to_string(), DW_ATE_float
),
1832 ast
::TyF64
=> ("f64".to_string(), DW_ATE_float
),
1834 _
=> cx
.sess().bug("debuginfo::basic_type_metadata - t is invalid type")
1837 let llvm_type
= type_of
::type_of(cx
, t
);
1838 let (size
, align
) = size_and_align_of(cx
, llvm_type
);
1839 let name
= CString
::new(name
).unwrap();
1840 let ty_metadata
= unsafe {
1841 llvm
::LLVMDIBuilderCreateBasicType(
1844 bytes_to_bits(size
),
1845 bytes_to_bits(align
),
1852 fn pointer_type_metadata
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
1853 pointer_type
: Ty
<'tcx
>,
1854 pointee_type_metadata
: DIType
)
1856 let pointer_llvm_type
= type_of
::type_of(cx
, pointer_type
);
1857 let (pointer_size
, pointer_align
) = size_and_align_of(cx
, pointer_llvm_type
);
1858 let name
= compute_debuginfo_type_name(cx
, pointer_type
, false);
1859 let name
= CString
::new(name
).unwrap();
1860 let ptr_metadata
= unsafe {
1861 llvm
::LLVMDIBuilderCreatePointerType(
1863 pointee_type_metadata
,
1864 bytes_to_bits(pointer_size
),
1865 bytes_to_bits(pointer_align
),
1868 return ptr_metadata
;
1871 //=-----------------------------------------------------------------------------
1872 // Common facilities for record-like types (structs, enums, tuples)
1873 //=-----------------------------------------------------------------------------
1876 FixedMemberOffset { bytes: usize }
,
1877 // For ComputedMemberOffset, the offset is read from the llvm type definition
1878 ComputedMemberOffset
1881 // Description of a type member, which can either be a regular field (as in
1882 // structs or tuples) or an enum variant
1883 struct MemberDescription
{
1886 type_metadata
: DIType
,
1887 offset
: MemberOffset
,
1891 // A factory for MemberDescriptions. It produces a list of member descriptions
1892 // for some record-like type. MemberDescriptionFactories are used to defer the
1893 // creation of type member descriptions in order to break cycles arising from
1894 // recursive type definitions.
1895 enum MemberDescriptionFactory
<'tcx
> {
1896 StructMDF(StructMemberDescriptionFactory
<'tcx
>),
1897 TupleMDF(TupleMemberDescriptionFactory
<'tcx
>),
1898 EnumMDF(EnumMemberDescriptionFactory
<'tcx
>),
1899 VariantMDF(VariantMemberDescriptionFactory
<'tcx
>)
1902 impl<'tcx
> MemberDescriptionFactory
<'tcx
> {
1903 fn create_member_descriptions
<'a
>(&self, cx
: &CrateContext
<'a
, 'tcx
>)
1904 -> Vec
<MemberDescription
> {
1906 StructMDF(ref this
) => {
1907 this
.create_member_descriptions(cx
)
1909 TupleMDF(ref this
) => {
1910 this
.create_member_descriptions(cx
)
1912 EnumMDF(ref this
) => {
1913 this
.create_member_descriptions(cx
)
1915 VariantMDF(ref this
) => {
1916 this
.create_member_descriptions(cx
)
1922 // A description of some recursive type. It can either be already finished (as
1923 // with FinalMetadata) or it is not yet finished, but contains all information
1924 // needed to generate the missing parts of the description. See the documentation
1925 // section on Recursive Types at the top of this file for more information.
1926 enum RecursiveTypeDescription
<'tcx
> {
1927 UnfinishedMetadata
{
1928 unfinished_type
: Ty
<'tcx
>,
1929 unique_type_id
: UniqueTypeId
,
1930 metadata_stub
: DICompositeType
,
1932 member_description_factory
: MemberDescriptionFactory
<'tcx
>,
1934 FinalMetadata(DICompositeType
)
1937 fn create_and_register_recursive_type_forward_declaration
<'a
, 'tcx
>(
1938 cx
: &CrateContext
<'a
, 'tcx
>,
1939 unfinished_type
: Ty
<'tcx
>,
1940 unique_type_id
: UniqueTypeId
,
1941 metadata_stub
: DICompositeType
,
1943 member_description_factory
: MemberDescriptionFactory
<'tcx
>)
1944 -> RecursiveTypeDescription
<'tcx
> {
1946 // Insert the stub into the TypeMap in order to allow for recursive references
1947 let mut type_map
= debug_context(cx
).type_map
.borrow_mut();
1948 type_map
.register_unique_id_with_metadata(cx
, unique_type_id
, metadata_stub
);
1949 type_map
.register_type_with_metadata(cx
, unfinished_type
, metadata_stub
);
1951 UnfinishedMetadata
{
1952 unfinished_type
: unfinished_type
,
1953 unique_type_id
: unique_type_id
,
1954 metadata_stub
: metadata_stub
,
1955 llvm_type
: llvm_type
,
1956 member_description_factory
: member_description_factory
,
1960 impl<'tcx
> RecursiveTypeDescription
<'tcx
> {
1961 // Finishes up the description of the type in question (mostly by providing
1962 // descriptions of the fields of the given type) and returns the final type metadata.
1963 fn finalize
<'a
>(&self, cx
: &CrateContext
<'a
, 'tcx
>) -> MetadataCreationResult
{
1965 FinalMetadata(metadata
) => MetadataCreationResult
::new(metadata
, false),
1966 UnfinishedMetadata
{
1971 ref member_description_factory
,
1974 // Make sure that we have a forward declaration of the type in
1975 // the TypeMap so that recursive references are possible. This
1976 // will always be the case if the RecursiveTypeDescription has
1977 // been properly created through the
1978 // create_and_register_recursive_type_forward_declaration() function.
1980 let type_map
= debug_context(cx
).type_map
.borrow();
1981 if type_map
.find_metadata_for_unique_id(unique_type_id
).is_none() ||
1982 type_map
.find_metadata_for_type(unfinished_type
).is_none() {
1983 cx
.sess().bug(&format
!("Forward declaration of potentially recursive type \
1984 '{}' was not found in TypeMap!",
1985 ppaux
::ty_to_string(cx
.tcx(), unfinished_type
))
1990 // ... then create the member descriptions ...
1991 let member_descriptions
=
1992 member_description_factory
.create_member_descriptions(cx
);
1994 // ... and attach them to the stub to complete it.
1995 set_members_of_composite_type(cx
,
1998 &member_descriptions
[..]);
1999 return MetadataCreationResult
::new(metadata_stub
, true);
2006 //=-----------------------------------------------------------------------------
2008 //=-----------------------------------------------------------------------------
2010 // Creates MemberDescriptions for the fields of a struct
2011 struct StructMemberDescriptionFactory
<'tcx
> {
2012 fields
: Vec
<ty
::field
<'tcx
>>,
2017 impl<'tcx
> StructMemberDescriptionFactory
<'tcx
> {
2018 fn create_member_descriptions
<'a
>(&self, cx
: &CrateContext
<'a
, 'tcx
>)
2019 -> Vec
<MemberDescription
> {
2020 if self.fields
.is_empty() {
2024 let field_size
= if self.is_simd
{
2025 machine
::llsize_of_alloc(cx
, type_of
::type_of(cx
, self.fields
[0].mt
.ty
)) as usize
2030 self.fields
.iter().enumerate().map(|(i
, field
)| {
2031 let name
= if field
.name
== special_idents
::unnamed_field
.name
{
2034 token
::get_name(field
.name
).to_string()
2037 let offset
= if self.is_simd
{
2038 assert
!(field_size
!= 0xdeadbeef);
2039 FixedMemberOffset { bytes: i * field_size }
2041 ComputedMemberOffset
2046 llvm_type
: type_of
::type_of(cx
, field
.mt
.ty
),
2047 type_metadata
: type_metadata(cx
, field
.mt
.ty
, self.span
),
2056 fn prepare_struct_metadata
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
2057 struct_type
: Ty
<'tcx
>,
2059 substs
: &subst
::Substs
<'tcx
>,
2060 unique_type_id
: UniqueTypeId
,
2062 -> RecursiveTypeDescription
<'tcx
> {
2063 let struct_name
= compute_debuginfo_type_name(cx
, struct_type
, false);
2064 let struct_llvm_type
= type_of
::type_of(cx
, struct_type
);
2066 let (containing_scope
, _
) = get_namespace_and_span_for_item(cx
, def_id
);
2068 let struct_metadata_stub
= create_struct_stub(cx
,
2074 let mut fields
= ty
::struct_fields(cx
.tcx(), def_id
, substs
);
2076 // The `Ty` values returned by `ty::struct_fields` can still contain
2077 // `ty_projection` variants, so normalize those away.
2078 for field
in &mut fields
{
2079 field
.mt
.ty
= monomorphize
::normalize_associated_type(cx
.tcx(), &field
.mt
.ty
);
2082 create_and_register_recursive_type_forward_declaration(
2086 struct_metadata_stub
,
2088 StructMDF(StructMemberDescriptionFactory
{
2090 is_simd
: ty
::type_is_simd(cx
.tcx(), struct_type
),
2097 //=-----------------------------------------------------------------------------
2099 //=-----------------------------------------------------------------------------
2101 // Creates MemberDescriptions for the fields of a tuple
2102 struct TupleMemberDescriptionFactory
<'tcx
> {
2103 component_types
: Vec
<Ty
<'tcx
>>,
2107 impl<'tcx
> TupleMemberDescriptionFactory
<'tcx
> {
2108 fn create_member_descriptions
<'a
>(&self, cx
: &CrateContext
<'a
, 'tcx
>)
2109 -> Vec
<MemberDescription
> {
2110 self.component_types
2113 .map(|(i
, &component_type
)| {
2115 name
: format
!("__{}", i
),
2116 llvm_type
: type_of
::type_of(cx
, component_type
),
2117 type_metadata
: type_metadata(cx
, component_type
, self.span
),
2118 offset
: ComputedMemberOffset
,
2125 fn prepare_tuple_metadata
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
2126 tuple_type
: Ty
<'tcx
>,
2127 component_types
: &[Ty
<'tcx
>],
2128 unique_type_id
: UniqueTypeId
,
2130 -> RecursiveTypeDescription
<'tcx
> {
2131 let tuple_name
= compute_debuginfo_type_name(cx
, tuple_type
, false);
2132 let tuple_llvm_type
= type_of
::type_of(cx
, tuple_type
);
2134 create_and_register_recursive_type_forward_declaration(
2138 create_struct_stub(cx
,
2142 UNKNOWN_SCOPE_METADATA
),
2144 TupleMDF(TupleMemberDescriptionFactory
{
2145 component_types
: component_types
.to_vec(),
2152 //=-----------------------------------------------------------------------------
2154 //=-----------------------------------------------------------------------------
2156 // Describes the members of an enum value: An enum is described as a union of
2157 // structs in DWARF. This MemberDescriptionFactory provides the description for
2158 // the members of this union; so for every variant of the given enum, this factory
2159 // will produce one MemberDescription (all with no name and a fixed offset of
2161 struct EnumMemberDescriptionFactory
<'tcx
> {
2162 enum_type
: Ty
<'tcx
>,
2163 type_rep
: Rc
<adt
::Repr
<'tcx
>>,
2164 variants
: Rc
<Vec
<Rc
<ty
::VariantInfo
<'tcx
>>>>,
2165 discriminant_type_metadata
: Option
<DIType
>,
2166 containing_scope
: DIScope
,
2167 file_metadata
: DIFile
,
2171 impl<'tcx
> EnumMemberDescriptionFactory
<'tcx
> {
2172 fn create_member_descriptions
<'a
>(&self, cx
: &CrateContext
<'a
, 'tcx
>)
2173 -> Vec
<MemberDescription
> {
2174 match *self.type_rep
{
2175 adt
::General(_
, ref struct_defs
, _
) => {
2176 let discriminant_info
= RegularDiscriminant(self.discriminant_type_metadata
2182 .map(|(i
, struct_def
)| {
2183 let (variant_type_metadata
,
2185 member_desc_factory
) =
2186 describe_enum_variant(cx
,
2189 &*(*self.variants
)[i
],
2191 self.containing_scope
,
2194 let member_descriptions
= member_desc_factory
2195 .create_member_descriptions(cx
);
2197 set_members_of_composite_type(cx
,
2198 variant_type_metadata
,
2200 &member_descriptions
[..]);
2202 name
: "".to_string(),
2203 llvm_type
: variant_llvm_type
,
2204 type_metadata
: variant_type_metadata
,
2205 offset
: FixedMemberOffset { bytes: 0 }
,
2210 adt
::Univariant(ref struct_def
, _
) => {
2211 assert
!(self.variants
.len() <= 1);
2213 if self.variants
.is_empty() {
2216 let (variant_type_metadata
,
2218 member_description_factory
) =
2219 describe_enum_variant(cx
,
2222 &*(*self.variants
)[0],
2224 self.containing_scope
,
2227 let member_descriptions
=
2228 member_description_factory
.create_member_descriptions(cx
);
2230 set_members_of_composite_type(cx
,
2231 variant_type_metadata
,
2233 &member_descriptions
[..]);
2236 name
: "".to_string(),
2237 llvm_type
: variant_llvm_type
,
2238 type_metadata
: variant_type_metadata
,
2239 offset
: FixedMemberOffset { bytes: 0 }
,
2245 adt
::RawNullablePointer { nndiscr: non_null_variant_index, nnty, .. }
=> {
2246 // As far as debuginfo is concerned, the pointer this enum
2247 // represents is still wrapped in a struct. This is to make the
2248 // DWARF representation of enums uniform.
2250 // First create a description of the artificial wrapper struct:
2251 let non_null_variant
= &(*self.variants
)[non_null_variant_index
as usize];
2252 let non_null_variant_name
= token
::get_name(non_null_variant
.name
);
2254 // The llvm type and metadata of the pointer
2255 let non_null_llvm_type
= type_of
::type_of(cx
, nnty
);
2256 let non_null_type_metadata
= type_metadata(cx
, nnty
, self.span
);
2258 // The type of the artificial struct wrapping the pointer
2259 let artificial_struct_llvm_type
= Type
::struct_(cx
,
2260 &[non_null_llvm_type
],
2263 // For the metadata of the wrapper struct, we need to create a
2264 // MemberDescription of the struct's single field.
2265 let sole_struct_member_description
= MemberDescription
{
2266 name
: match non_null_variant
.arg_names
{
2267 Some(ref names
) => token
::get_name(names
[0]).to_string(),
2268 None
=> "__0".to_string()
2270 llvm_type
: non_null_llvm_type
,
2271 type_metadata
: non_null_type_metadata
,
2272 offset
: FixedMemberOffset { bytes: 0 }
,
2276 let unique_type_id
= debug_context(cx
).type_map
2278 .get_unique_type_id_of_enum_variant(
2281 &non_null_variant_name
);
2283 // Now we can create the metadata of the artificial struct
2284 let artificial_struct_metadata
=
2285 composite_type_metadata(cx
,
2286 artificial_struct_llvm_type
,
2287 &non_null_variant_name
,
2289 &[sole_struct_member_description
],
2290 self.containing_scope
,
2294 // Encode the information about the null variant in the union
2296 let null_variant_index
= (1 - non_null_variant_index
) as usize;
2297 let null_variant_name
= token
::get_name((*self.variants
)[null_variant_index
].name
);
2298 let union_member_name
= format
!("RUST$ENCODED$ENUM${}${}",
2302 // Finally create the (singleton) list of descriptions of union
2306 name
: union_member_name
,
2307 llvm_type
: artificial_struct_llvm_type
,
2308 type_metadata
: artificial_struct_metadata
,
2309 offset
: FixedMemberOffset { bytes: 0 }
,
2314 adt
::StructWrappedNullablePointer
{ nonnull
: ref struct_def
,
2316 ref discrfield
, ..} => {
2317 // Create a description of the non-null variant
2318 let (variant_type_metadata
, variant_llvm_type
, member_description_factory
) =
2319 describe_enum_variant(cx
,
2322 &*(*self.variants
)[nndiscr
as usize],
2323 OptimizedDiscriminant
,
2324 self.containing_scope
,
2327 let variant_member_descriptions
=
2328 member_description_factory
.create_member_descriptions(cx
);
2330 set_members_of_composite_type(cx
,
2331 variant_type_metadata
,
2333 &variant_member_descriptions
[..]);
2335 // Encode the information about the null variant in the union
2337 let null_variant_index
= (1 - nndiscr
) as usize;
2338 let null_variant_name
= token
::get_name((*self.variants
)[null_variant_index
].name
);
2339 let discrfield
= discrfield
.iter()
2341 .map(|x
| x
.to_string())
2342 .collect
::<Vec
<_
>>().connect("$");
2343 let union_member_name
= format
!("RUST$ENCODED$ENUM${}${}",
2347 // Create the (singleton) list of descriptions of union members.
2350 name
: union_member_name
,
2351 llvm_type
: variant_llvm_type
,
2352 type_metadata
: variant_type_metadata
,
2353 offset
: FixedMemberOffset { bytes: 0 }
,
2358 adt
::CEnum(..) => cx
.sess().span_bug(self.span
, "This should be unreachable.")
2363 // Creates MemberDescriptions for the fields of a single enum variant.
2364 struct VariantMemberDescriptionFactory
<'tcx
> {
2365 args
: Vec
<(String
, Ty
<'tcx
>)>,
2366 discriminant_type_metadata
: Option
<DIType
>,
2370 impl<'tcx
> VariantMemberDescriptionFactory
<'tcx
> {
2371 fn create_member_descriptions
<'a
>(&self, cx
: &CrateContext
<'a
, 'tcx
>)
2372 -> Vec
<MemberDescription
> {
2373 self.args
.iter().enumerate().map(|(i
, &(ref name
, ty
))| {
2375 name
: name
.to_string(),
2376 llvm_type
: type_of
::type_of(cx
, ty
),
2377 type_metadata
: match self.discriminant_type_metadata
{
2378 Some(metadata
) if i
== 0 => metadata
,
2379 _
=> type_metadata(cx
, ty
, self.span
)
2381 offset
: ComputedMemberOffset
,
2388 #[derive(Copy, Clone)]
2389 enum EnumDiscriminantInfo
{
2390 RegularDiscriminant(DIType
),
2391 OptimizedDiscriminant
,
2395 // Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type
2396 // of the variant, and (3) a MemberDescriptionFactory for producing the
2397 // descriptions of the fields of the variant. This is a rudimentary version of a
2398 // full RecursiveTypeDescription.
2399 fn describe_enum_variant
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
2400 enum_type
: Ty
<'tcx
>,
2401 struct_def
: &adt
::Struct
<'tcx
>,
2402 variant_info
: &ty
::VariantInfo
<'tcx
>,
2403 discriminant_info
: EnumDiscriminantInfo
,
2404 containing_scope
: DIScope
,
2406 -> (DICompositeType
, Type
, MemberDescriptionFactory
<'tcx
>) {
2407 let variant_llvm_type
=
2408 Type
::struct_(cx
, &struct_def
.fields
2410 .map(|&t
| type_of
::type_of(cx
, t
))
2411 .collect
::<Vec
<_
>>()
2414 // Could do some consistency checks here: size, align, field count, discr type
2416 let variant_name
= token
::get_name(variant_info
.name
);
2417 let variant_name
= &variant_name
;
2418 let unique_type_id
= debug_context(cx
).type_map
2420 .get_unique_type_id_of_enum_variant(
2425 let metadata_stub
= create_struct_stub(cx
,
2431 // Get the argument names from the enum variant info
2432 let mut arg_names
: Vec
<_
> = match variant_info
.arg_names
{
2433 Some(ref names
) => {
2435 .map(|&name
| token
::get_name(name
).to_string())
2442 .map(|(i
, _
)| format
!("__{}", i
))
2447 // If this is not a univariant enum, there is also the discriminant field.
2448 match discriminant_info
{
2449 RegularDiscriminant(_
) => arg_names
.insert(0, "RUST$ENUM$DISR".to_string()),
2450 _
=> { /* do nothing */ }
2453 // Build an array of (field name, field type) pairs to be captured in the factory closure.
2454 let args
: Vec
<(String
, Ty
)> = arg_names
.iter()
2455 .zip(struct_def
.fields
.iter())
2456 .map(|(s
, &t
)| (s
.to_string(), t
))
2459 let member_description_factory
=
2460 VariantMDF(VariantMemberDescriptionFactory
{
2462 discriminant_type_metadata
: match discriminant_info
{
2463 RegularDiscriminant(discriminant_type_metadata
) => {
2464 Some(discriminant_type_metadata
)
2471 (metadata_stub
, variant_llvm_type
, member_description_factory
)
2474 fn prepare_enum_metadata
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
2475 enum_type
: Ty
<'tcx
>,
2476 enum_def_id
: ast
::DefId
,
2477 unique_type_id
: UniqueTypeId
,
2479 -> RecursiveTypeDescription
<'tcx
> {
2480 let enum_name
= compute_debuginfo_type_name(cx
, enum_type
, false);
2482 let (containing_scope
, definition_span
) = get_namespace_and_span_for_item(cx
, enum_def_id
);
2483 let loc
= span_start(cx
, definition_span
);
2484 let file_metadata
= file_metadata(cx
, &loc
.file
.name
);
2486 let variants
= ty
::enum_variants(cx
.tcx(), enum_def_id
);
2488 let enumerators_metadata
: Vec
<DIDescriptor
> = variants
2491 let token
= token
::get_name(v
.name
);
2492 let name
= CString
::new(token
.as_bytes()).unwrap();
2494 llvm
::LLVMDIBuilderCreateEnumerator(
2502 let discriminant_type_metadata
= |inttype
| {
2503 // We can reuse the type of the discriminant for all monomorphized
2504 // instances of an enum because it doesn't depend on any type parameters.
2505 // The def_id, uniquely identifying the enum's polytype acts as key in
2507 let cached_discriminant_type_metadata
= debug_context(cx
).created_enum_disr_types
2509 .get(&enum_def_id
).cloned();
2510 match cached_discriminant_type_metadata
{
2511 Some(discriminant_type_metadata
) => discriminant_type_metadata
,
2513 let discriminant_llvm_type
= adt
::ll_inttype(cx
, inttype
);
2514 let (discriminant_size
, discriminant_align
) =
2515 size_and_align_of(cx
, discriminant_llvm_type
);
2516 let discriminant_base_type_metadata
=
2518 adt
::ty_of_inttype(cx
.tcx(), inttype
),
2520 let discriminant_name
= get_enum_discriminant_name(cx
, enum_def_id
);
2522 let name
= CString
::new(discriminant_name
.as_bytes()).unwrap();
2523 let discriminant_type_metadata
= unsafe {
2524 llvm
::LLVMDIBuilderCreateEnumerationType(
2528 UNKNOWN_FILE_METADATA
,
2529 UNKNOWN_LINE_NUMBER
,
2530 bytes_to_bits(discriminant_size
),
2531 bytes_to_bits(discriminant_align
),
2532 create_DIArray(DIB(cx
), &enumerators_metadata
),
2533 discriminant_base_type_metadata
)
2536 debug_context(cx
).created_enum_disr_types
2538 .insert(enum_def_id
, discriminant_type_metadata
);
2540 discriminant_type_metadata
2545 let type_rep
= adt
::represent_type(cx
, enum_type
);
2547 let discriminant_type_metadata
= match *type_rep
{
2548 adt
::CEnum(inttype
, _
, _
) => {
2549 return FinalMetadata(discriminant_type_metadata(inttype
))
2551 adt
::RawNullablePointer { .. }
|
2552 adt
::StructWrappedNullablePointer { .. }
|
2553 adt
::Univariant(..) => None
,
2554 adt
::General(inttype
, _
, _
) => Some(discriminant_type_metadata(inttype
)),
2557 let enum_llvm_type
= type_of
::type_of(cx
, enum_type
);
2558 let (enum_type_size
, enum_type_align
) = size_and_align_of(cx
, enum_llvm_type
);
2560 let unique_type_id_str
= debug_context(cx
)
2563 .get_unique_type_id_as_string(unique_type_id
);
2565 let enum_name
= CString
::new(enum_name
).unwrap();
2566 let unique_type_id_str
= CString
::new(unique_type_id_str
.as_bytes()).unwrap();
2567 let enum_metadata
= unsafe {
2568 llvm
::LLVMDIBuilderCreateUnionType(
2572 UNKNOWN_FILE_METADATA
,
2573 UNKNOWN_LINE_NUMBER
,
2574 bytes_to_bits(enum_type_size
),
2575 bytes_to_bits(enum_type_align
),
2579 unique_type_id_str
.as_ptr())
2582 return create_and_register_recursive_type_forward_declaration(
2588 EnumMDF(EnumMemberDescriptionFactory
{
2589 enum_type
: enum_type
,
2590 type_rep
: type_rep
.clone(),
2592 discriminant_type_metadata
: discriminant_type_metadata
,
2593 containing_scope
: containing_scope
,
2594 file_metadata
: file_metadata
,
2599 fn get_enum_discriminant_name(cx
: &CrateContext
,
2601 -> token
::InternedString
{
2602 let name
= if def_id
.krate
== ast
::LOCAL_CRATE
{
2603 cx
.tcx().map
.get_path_elem(def_id
.node
).name()
2605 csearch
::get_item_path(cx
.tcx(), def_id
).last().unwrap().name()
2608 token
::get_name(name
)
2612 /// Creates debug information for a composite type, that is, anything that
2613 /// results in a LLVM struct.
2615 /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
2616 fn composite_type_metadata(cx
: &CrateContext
,
2617 composite_llvm_type
: Type
,
2618 composite_type_name
: &str,
2619 composite_type_unique_id
: UniqueTypeId
,
2620 member_descriptions
: &[MemberDescription
],
2621 containing_scope
: DIScope
,
2623 // Ignore source location information as long as it
2624 // can't be reconstructed for non-local crates.
2625 _file_metadata
: DIFile
,
2626 _definition_span
: Span
)
2627 -> DICompositeType
{
2628 // Create the (empty) struct metadata node ...
2629 let composite_type_metadata
= create_struct_stub(cx
,
2630 composite_llvm_type
,
2631 composite_type_name
,
2632 composite_type_unique_id
,
2634 // ... and immediately create and add the member descriptions.
2635 set_members_of_composite_type(cx
,
2636 composite_type_metadata
,
2637 composite_llvm_type
,
2638 member_descriptions
);
2640 return composite_type_metadata
;
2643 fn set_members_of_composite_type(cx
: &CrateContext
,
2644 composite_type_metadata
: DICompositeType
,
2645 composite_llvm_type
: Type
,
2646 member_descriptions
: &[MemberDescription
]) {
2647 // In some rare cases LLVM metadata uniquing would lead to an existing type
2648 // description being used instead of a new one created in create_struct_stub.
2649 // This would cause a hard to trace assertion in DICompositeType::SetTypeArray().
2650 // The following check makes sure that we get a better error message if this
2651 // should happen again due to some regression.
2653 let mut composite_types_completed
=
2654 debug_context(cx
).composite_types_completed
.borrow_mut();
2655 if composite_types_completed
.contains(&composite_type_metadata
) {
2656 let (llvm_version_major
, llvm_version_minor
) = unsafe {
2657 (llvm
::LLVMVersionMajor(), llvm
::LLVMVersionMinor())
2660 let actual_llvm_version
= llvm_version_major
* 1000000 + llvm_version_minor
* 1000;
2661 let min_supported_llvm_version
= 3 * 1000000 + 4 * 1000;
2663 if actual_llvm_version
< min_supported_llvm_version
{
2664 cx
.sess().warn(&format
!("This version of rustc was built with LLVM \
2665 {}.{}. Rustc just ran into a known \
2666 debuginfo corruption problem thatoften \
2667 occurs with LLVM versions below 3.4. \
2668 Please use a rustc built with anewer \
2671 llvm_version_minor
));
2673 cx
.sess().bug("debuginfo::set_members_of_composite_type() - \
2674 Already completed forward declaration re-encountered.");
2677 composite_types_completed
.insert(composite_type_metadata
);
2681 let member_metadata
: Vec
<DIDescriptor
> = member_descriptions
2684 .map(|(i
, member_description
)| {
2685 let (member_size
, member_align
) = size_and_align_of(cx
, member_description
.llvm_type
);
2686 let member_offset
= match member_description
.offset
{
2687 FixedMemberOffset { bytes }
=> bytes
as u64,
2688 ComputedMemberOffset
=> machine
::llelement_offset(cx
, composite_llvm_type
, i
)
2691 let member_name
= member_description
.name
.as_bytes();
2692 let member_name
= CString
::new(member_name
).unwrap();
2694 llvm
::LLVMDIBuilderCreateMemberType(
2696 composite_type_metadata
,
2697 member_name
.as_ptr(),
2698 UNKNOWN_FILE_METADATA
,
2699 UNKNOWN_LINE_NUMBER
,
2700 bytes_to_bits(member_size
),
2701 bytes_to_bits(member_align
),
2702 bytes_to_bits(member_offset
),
2703 member_description
.flags
,
2704 member_description
.type_metadata
)
2710 let type_array
= create_DIArray(DIB(cx
), &member_metadata
[..]);
2711 llvm
::LLVMDICompositeTypeSetTypeArray(DIB(cx
), composite_type_metadata
, type_array
);
2715 // A convenience wrapper around LLVMDIBuilderCreateStructType(). Does not do any
2716 // caching, does not add any fields to the struct. This can be done later with
2717 // set_members_of_composite_type().
2718 fn create_struct_stub(cx
: &CrateContext
,
2719 struct_llvm_type
: Type
,
2720 struct_type_name
: &str,
2721 unique_type_id
: UniqueTypeId
,
2722 containing_scope
: DIScope
)
2723 -> DICompositeType
{
2724 let (struct_size
, struct_align
) = size_and_align_of(cx
, struct_llvm_type
);
2726 let unique_type_id_str
= debug_context(cx
).type_map
2728 .get_unique_type_id_as_string(unique_type_id
);
2729 let name
= CString
::new(struct_type_name
).unwrap();
2730 let unique_type_id
= CString
::new(unique_type_id_str
.as_bytes()).unwrap();
2731 let metadata_stub
= unsafe {
2732 // LLVMDIBuilderCreateStructType() wants an empty array. A null
2733 // pointer will lead to hard to trace and debug LLVM assertions
2734 // later on in llvm/lib/IR/Value.cpp.
2735 let empty_array
= create_DIArray(DIB(cx
), &[]);
2737 llvm
::LLVMDIBuilderCreateStructType(
2741 UNKNOWN_FILE_METADATA
,
2742 UNKNOWN_LINE_NUMBER
,
2743 bytes_to_bits(struct_size
),
2744 bytes_to_bits(struct_align
),
2750 unique_type_id
.as_ptr())
2753 return metadata_stub
;
2756 fn fixed_vec_metadata
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
2757 unique_type_id
: UniqueTypeId
,
2758 element_type
: Ty
<'tcx
>,
2761 -> MetadataCreationResult
{
2762 let element_type_metadata
= type_metadata(cx
, element_type
, span
);
2764 return_if_metadata_created_in_meantime
!(cx
, unique_type_id
);
2766 let element_llvm_type
= type_of
::type_of(cx
, element_type
);
2767 let (element_type_size
, element_type_align
) = size_and_align_of(cx
, element_llvm_type
);
2769 let (array_size_in_bytes
, upper_bound
) = match len
{
2770 Some(len
) => (element_type_size
* len
, len
as c_longlong
),
2774 let subrange
= unsafe {
2775 llvm
::LLVMDIBuilderGetOrCreateSubrange(DIB(cx
), 0, upper_bound
)
2778 let subscripts
= create_DIArray(DIB(cx
), &[subrange
]);
2779 let metadata
= unsafe {
2780 llvm
::LLVMDIBuilderCreateArrayType(
2782 bytes_to_bits(array_size_in_bytes
),
2783 bytes_to_bits(element_type_align
),
2784 element_type_metadata
,
2788 return MetadataCreationResult
::new(metadata
, false);
2791 fn vec_slice_metadata
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
2793 element_type
: Ty
<'tcx
>,
2794 unique_type_id
: UniqueTypeId
,
2796 -> MetadataCreationResult
{
2797 let data_ptr_type
= ty
::mk_ptr(cx
.tcx(), ty
::mt
{
2799 mutbl
: ast
::MutImmutable
2802 let element_type_metadata
= type_metadata(cx
, data_ptr_type
, span
);
2804 return_if_metadata_created_in_meantime
!(cx
, unique_type_id
);
2806 let slice_llvm_type
= type_of
::type_of(cx
, vec_type
);
2807 let slice_type_name
= compute_debuginfo_type_name(cx
, vec_type
, true);
2809 let member_llvm_types
= slice_llvm_type
.field_types();
2810 assert
!(slice_layout_is_correct(cx
,
2811 &member_llvm_types
[..],
2813 let member_descriptions
= [
2815 name
: "data_ptr".to_string(),
2816 llvm_type
: member_llvm_types
[0],
2817 type_metadata
: element_type_metadata
,
2818 offset
: ComputedMemberOffset
,
2822 name
: "length".to_string(),
2823 llvm_type
: member_llvm_types
[1],
2824 type_metadata
: type_metadata(cx
, cx
.tcx().types
.usize, span
),
2825 offset
: ComputedMemberOffset
,
2830 assert
!(member_descriptions
.len() == member_llvm_types
.len());
2832 let loc
= span_start(cx
, span
);
2833 let file_metadata
= file_metadata(cx
, &loc
.file
.name
);
2835 let metadata
= composite_type_metadata(cx
,
2837 &slice_type_name
[..],
2839 &member_descriptions
,
2840 UNKNOWN_SCOPE_METADATA
,
2843 return MetadataCreationResult
::new(metadata
, false);
2845 fn slice_layout_is_correct
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
2846 member_llvm_types
: &[Type
],
2847 element_type
: Ty
<'tcx
>)
2849 member_llvm_types
.len() == 2 &&
2850 member_llvm_types
[0] == type_of
::type_of(cx
, element_type
).ptr_to() &&
2851 member_llvm_types
[1] == cx
.int_type()
2855 fn subroutine_type_metadata
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
2856 unique_type_id
: UniqueTypeId
,
2857 signature
: &ty
::PolyFnSig
<'tcx
>,
2859 -> MetadataCreationResult
2861 let signature
= ty
::erase_late_bound_regions(cx
.tcx(), signature
);
2863 let mut signature_metadata
: Vec
<DIType
> = Vec
::with_capacity(signature
.inputs
.len() + 1);
2866 signature_metadata
.push(match signature
.output
{
2867 ty
::FnConverging(ret_ty
) => match ret_ty
.sty
{
2868 ty
::ty_tup(ref tys
) if tys
.is_empty() => ptr
::null_mut(),
2869 _
=> type_metadata(cx
, ret_ty
, span
)
2871 ty
::FnDiverging
=> diverging_type_metadata(cx
)
2874 // regular arguments
2875 for &argument_type
in &signature
.inputs
{
2876 signature_metadata
.push(type_metadata(cx
, argument_type
, span
));
2879 return_if_metadata_created_in_meantime
!(cx
, unique_type_id
);
2881 return MetadataCreationResult
::new(
2883 llvm
::LLVMDIBuilderCreateSubroutineType(
2885 UNKNOWN_FILE_METADATA
,
2886 create_DIArray(DIB(cx
), &signature_metadata
[..]))
2891 // FIXME(1563) This is all a bit of a hack because 'trait pointer' is an ill-
2892 // defined concept. For the case of an actual trait pointer (i.e., Box<Trait>,
2893 // &Trait), trait_object_type should be the whole thing (e.g, Box<Trait>) and
2894 // trait_type should be the actual trait (e.g., Trait). Where the trait is part
2895 // of a DST struct, there is no trait_object_type and the results of this
2896 // function will be a little bit weird.
2897 fn trait_pointer_metadata
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
2898 trait_type
: Ty
<'tcx
>,
2899 trait_object_type
: Option
<Ty
<'tcx
>>,
2900 unique_type_id
: UniqueTypeId
)
2902 // The implementation provided here is a stub. It makes sure that the trait
2903 // type is assigned the correct name, size, namespace, and source location.
2904 // But it does not describe the trait's methods.
2906 let def_id
= match trait_type
.sty
{
2907 ty
::ty_trait(ref data
) => data
.principal_def_id(),
2909 let pp_type_name
= ppaux
::ty_to_string(cx
.tcx(), trait_type
);
2910 cx
.sess().bug(&format
!("debuginfo: Unexpected trait-object type in \
2911 trait_pointer_metadata(): {}",
2912 &pp_type_name
[..]));
2916 let trait_object_type
= trait_object_type
.unwrap_or(trait_type
);
2917 let trait_type_name
=
2918 compute_debuginfo_type_name(cx
, trait_object_type
, false);
2920 let (containing_scope
, _
) = get_namespace_and_span_for_item(cx
, def_id
);
2922 let trait_llvm_type
= type_of
::type_of(cx
, trait_object_type
);
2924 composite_type_metadata(cx
,
2926 &trait_type_name
[..],
2930 UNKNOWN_FILE_METADATA
,
2934 fn type_metadata
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
2936 usage_site_span
: Span
)
2938 // Get the unique type id of this type.
2939 let unique_type_id
= {
2940 let mut type_map
= debug_context(cx
).type_map
.borrow_mut();
2941 // First, try to find the type in TypeMap. If we have seen it before, we
2942 // can exit early here.
2943 match type_map
.find_metadata_for_type(t
) {
2948 // The Ty is not in the TypeMap but maybe we have already seen
2949 // an equivalent type (e.g. only differing in region arguments).
2950 // In order to find out, generate the unique type id and look
2952 let unique_type_id
= type_map
.get_unique_type_id_of_type(cx
, t
);
2953 match type_map
.find_metadata_for_unique_id(unique_type_id
) {
2955 // There is already an equivalent type in the TypeMap.
2956 // Register this Ty as an alias in the cache and
2957 // return the cached metadata.
2958 type_map
.register_type_with_metadata(cx
, t
, metadata
);
2962 // There really is no type metadata for this type, so
2963 // proceed by creating it.
2971 debug
!("type_metadata: {:?}", t
);
2974 let MetadataCreationResult { metadata, already_stored_in_typemap }
= match *sty
{
2979 ty
::ty_float(_
) => {
2980 MetadataCreationResult
::new(basic_type_metadata(cx
, t
), false)
2982 ty
::ty_tup(ref elements
) if elements
.is_empty() => {
2983 MetadataCreationResult
::new(basic_type_metadata(cx
, t
), false)
2985 ty
::ty_enum(def_id
, _
) => {
2986 prepare_enum_metadata(cx
, t
, def_id
, unique_type_id
, usage_site_span
).finalize(cx
)
2988 ty
::ty_vec(typ
, len
) => {
2989 fixed_vec_metadata(cx
, unique_type_id
, typ
, len
.map(|x
| x
as u64), usage_site_span
)
2992 fixed_vec_metadata(cx
, unique_type_id
, cx
.tcx().types
.i8, None
, usage_site_span
)
2994 ty
::ty_trait(..) => {
2995 MetadataCreationResult
::new(
2996 trait_pointer_metadata(cx
, t
, None
, unique_type_id
),
2999 ty
::ty_uniq(ty
) | ty
::ty_ptr(ty
::mt{ty, ..}
) | ty
::ty_rptr(_
, ty
::mt{ty, ..}
) => {
3001 ty
::ty_vec(typ
, None
) => {
3002 vec_slice_metadata(cx
, t
, typ
, unique_type_id
, usage_site_span
)
3005 vec_slice_metadata(cx
, t
, cx
.tcx().types
.u8, unique_type_id
, usage_site_span
)
3007 ty
::ty_trait(..) => {
3008 MetadataCreationResult
::new(
3009 trait_pointer_metadata(cx
, ty
, Some(t
), unique_type_id
),
3013 let pointee_metadata
= type_metadata(cx
, ty
, usage_site_span
);
3015 match debug_context(cx
).type_map
3017 .find_metadata_for_unique_id(unique_type_id
) {
3018 Some(metadata
) => return metadata
,
3019 None
=> { /* proceed normally */ }
3022 MetadataCreationResult
::new(pointer_type_metadata(cx
, t
, pointee_metadata
),
3027 ty
::ty_bare_fn(_
, ref barefnty
) => {
3028 subroutine_type_metadata(cx
, unique_type_id
, &barefnty
.sig
, usage_site_span
)
3030 ty
::ty_closure(def_id
, substs
) => {
3031 let typer
= NormalizingClosureTyper
::new(cx
.tcx());
3032 let sig
= typer
.closure_type(def_id
, substs
).sig
;
3033 subroutine_type_metadata(cx
, unique_type_id
, &sig
, usage_site_span
)
3035 ty
::ty_struct(def_id
, substs
) => {
3036 prepare_struct_metadata(cx
,
3041 usage_site_span
).finalize(cx
)
3043 ty
::ty_tup(ref elements
) => {
3044 prepare_tuple_metadata(cx
,
3048 usage_site_span
).finalize(cx
)
3051 cx
.sess().bug(&format
!("debuginfo: unexpected type in type_metadata: {:?}",
3057 let mut type_map
= debug_context(cx
).type_map
.borrow_mut();
3059 if already_stored_in_typemap
{
3060 // Also make sure that we already have a TypeMap entry entry for the unique type id.
3061 let metadata_for_uid
= match type_map
.find_metadata_for_unique_id(unique_type_id
) {
3062 Some(metadata
) => metadata
,
3064 let unique_type_id_str
=
3065 type_map
.get_unique_type_id_as_string(unique_type_id
);
3066 let error_message
= format
!("Expected type metadata for unique \
3067 type id '{}' to already be in \
3068 the debuginfo::TypeMap but it \
3069 was not. (Ty = {})",
3070 &unique_type_id_str
[..],
3071 ppaux
::ty_to_string(cx
.tcx(), t
));
3072 cx
.sess().span_bug(usage_site_span
, &error_message
[..]);
3076 match type_map
.find_metadata_for_type(t
) {
3078 if metadata
!= metadata_for_uid
{
3079 let unique_type_id_str
=
3080 type_map
.get_unique_type_id_as_string(unique_type_id
);
3081 let error_message
= format
!("Mismatch between Ty and \
3082 UniqueTypeId maps in \
3083 debuginfo::TypeMap. \
3084 UniqueTypeId={}, Ty={}",
3085 &unique_type_id_str
[..],
3086 ppaux
::ty_to_string(cx
.tcx(), t
));
3087 cx
.sess().span_bug(usage_site_span
, &error_message
[..]);
3091 type_map
.register_type_with_metadata(cx
, t
, metadata
);
3095 type_map
.register_type_with_metadata(cx
, t
, metadata
);
3096 type_map
.register_unique_id_with_metadata(cx
, unique_type_id
, metadata
);
3103 struct MetadataCreationResult
{
3105 already_stored_in_typemap
: bool
3108 impl MetadataCreationResult
{
3109 fn new(metadata
: DIType
, already_stored_in_typemap
: bool
) -> MetadataCreationResult
{
3110 MetadataCreationResult
{
3112 already_stored_in_typemap
: already_stored_in_typemap
3117 #[derive(Copy, Clone, PartialEq)]
3118 enum InternalDebugLocation
{
3119 KnownLocation { scope: DIScope, line: usize, col: usize }
,
3123 impl InternalDebugLocation
{
3124 fn new(scope
: DIScope
, line
: usize, col
: usize) -> InternalDebugLocation
{
3133 fn set_debug_location(cx
: &CrateContext
, debug_location
: InternalDebugLocation
) {
3134 if debug_location
== debug_context(cx
).current_debug_location
.get() {
3140 match debug_location
{
3141 KnownLocation { scope, line, .. }
=> {
3142 // Always set the column to zero like Clang and GCC
3143 let col
= UNKNOWN_COLUMN_NUMBER
;
3144 debug
!("setting debug location to {} {}", line
, col
);
3147 metadata_node
= llvm
::LLVMDIBuilderCreateDebugLocation(
3148 debug_context(cx
).llcontext
,
3155 UnknownLocation
=> {
3156 debug
!("clearing debug location ");
3157 metadata_node
= ptr
::null_mut();
3162 llvm
::LLVMSetCurrentDebugLocation(cx
.raw_builder(), metadata_node
);
3165 debug_context(cx
).current_debug_location
.set(debug_location
);
3168 //=-----------------------------------------------------------------------------
3169 // Utility Functions
3170 //=-----------------------------------------------------------------------------
3172 fn contains_nodebug_attribute(attributes
: &[ast
::Attribute
]) -> bool
{
3173 attributes
.iter().any(|attr
| {
3174 let meta_item
: &ast
::MetaItem
= &*attr
.node
.value
;
3175 match meta_item
.node
{
3176 ast
::MetaWord(ref value
) => &value
[..] == "no_debug",
3182 /// Return codemap::Loc corresponding to the beginning of the span
3183 fn span_start(cx
: &CrateContext
, span
: Span
) -> codemap
::Loc
{
3184 cx
.sess().codemap().lookup_char_pos(span
.lo
)
3187 fn size_and_align_of(cx
: &CrateContext
, llvm_type
: Type
) -> (u64, u64) {
3188 (machine
::llsize_of_alloc(cx
, llvm_type
), machine
::llalign_of_min(cx
, llvm_type
) as u64)
3191 fn bytes_to_bits(bytes
: u64) -> u64 {
3196 fn debug_context
<'a
, 'tcx
>(cx
: &'a CrateContext
<'a
, 'tcx
>)
3197 -> &'a CrateDebugContext
<'tcx
> {
3198 let debug_context
: &'a CrateDebugContext
<'tcx
> = cx
.dbg_cx().as_ref().unwrap();
3203 #[allow(non_snake_case)]
3204 fn DIB(cx
: &CrateContext
) -> DIBuilderRef
{
3205 cx
.dbg_cx().as_ref().unwrap().builder
3208 fn fn_should_be_ignored(fcx
: &FunctionContext
) -> bool
{
3209 match fcx
.debug_context
{
3210 FunctionDebugContext
::RegularContext(_
) => false,
3215 fn assert_type_for_node_id(cx
: &CrateContext
,
3216 node_id
: ast
::NodeId
,
3217 error_reporting_span
: Span
) {
3218 if !cx
.tcx().node_types().contains_key(&node_id
) {
3219 cx
.sess().span_bug(error_reporting_span
,
3220 "debuginfo: Could not find type for node id!");
3224 fn get_namespace_and_span_for_item(cx
: &CrateContext
, def_id
: ast
::DefId
)
3225 -> (DIScope
, Span
) {
3226 let containing_scope
= namespace_for_item(cx
, def_id
).scope
;
3227 let definition_span
= if def_id
.krate
== ast
::LOCAL_CRATE
{
3228 cx
.tcx().map
.span(def_id
.node
)
3230 // For external items there is no span information
3234 (containing_scope
, definition_span
)
3237 // This procedure builds the *scope map* for a given function, which maps any
3238 // given ast::NodeId in the function's AST to the correct DIScope metadata instance.
3240 // This builder procedure walks the AST in execution order and keeps track of
3241 // what belongs to which scope, creating DIScope DIEs along the way, and
3242 // introducing *artificial* lexical scope descriptors where necessary. These
3243 // artificial scopes allow GDB to correctly handle name shadowing.
3244 fn create_scope_map(cx
: &CrateContext
,
3246 fn_entry_block
: &ast
::Block
,
3247 fn_metadata
: DISubprogram
,
3248 fn_ast_id
: ast
::NodeId
)
3249 -> NodeMap
<DIScope
> {
3250 let mut scope_map
= NodeMap();
3252 let def_map
= &cx
.tcx().def_map
;
3254 struct ScopeStackEntry
{
3255 scope_metadata
: DIScope
,
3256 name
: Option
<ast
::Name
>
3259 let mut scope_stack
= vec
!(ScopeStackEntry { scope_metadata: fn_metadata, name: None }
);
3260 scope_map
.insert(fn_ast_id
, fn_metadata
);
3262 // Push argument identifiers onto the stack so arguments integrate nicely
3263 // with variable shadowing.
3265 pat_util
::pat_bindings(def_map
, &*arg
.pat
, |_
, node_id
, _
, path1
| {
3266 scope_stack
.push(ScopeStackEntry
{ scope_metadata
: fn_metadata
,
3267 name
: Some(path1
.node
.name
) });
3268 scope_map
.insert(node_id
, fn_metadata
);
3272 // Clang creates a separate scope for function bodies, so let's do this too.
3274 fn_entry_block
.span
,
3277 |cx
, scope_stack
, scope_map
| {
3278 walk_block(cx
, fn_entry_block
, scope_stack
, scope_map
);
3284 // local helper functions for walking the AST.
3285 fn with_new_scope
<F
>(cx
: &CrateContext
,
3287 scope_stack
: &mut Vec
<ScopeStackEntry
> ,
3288 scope_map
: &mut NodeMap
<DIScope
>,
3289 inner_walk
: F
) where
3290 F
: FnOnce(&CrateContext
, &mut Vec
<ScopeStackEntry
>, &mut NodeMap
<DIScope
>),
3292 // Create a new lexical scope and push it onto the stack
3293 let loc
= cx
.sess().codemap().lookup_char_pos(scope_span
.lo
);
3294 let file_metadata
= file_metadata(cx
, &loc
.file
.name
);
3295 let parent_scope
= scope_stack
.last().unwrap().scope_metadata
;
3297 let scope_metadata
= unsafe {
3298 llvm
::LLVMDIBuilderCreateLexicalBlock(
3303 loc
.col
.to_usize() as c_uint
)
3306 scope_stack
.push(ScopeStackEntry { scope_metadata: scope_metadata, name: None }
);
3308 inner_walk(cx
, scope_stack
, scope_map
);
3310 // pop artificial scopes
3311 while scope_stack
.last().unwrap().name
.is_some() {
3315 if scope_stack
.last().unwrap().scope_metadata
!= scope_metadata
{
3316 cx
.sess().span_bug(scope_span
, "debuginfo: Inconsistency in scope management.");
3322 fn walk_block(cx
: &CrateContext
,
3324 scope_stack
: &mut Vec
<ScopeStackEntry
> ,
3325 scope_map
: &mut NodeMap
<DIScope
>) {
3326 scope_map
.insert(block
.id
, scope_stack
.last().unwrap().scope_metadata
);
3328 // The interesting things here are statements and the concluding expression.
3329 for statement
in &block
.stmts
{
3330 scope_map
.insert(ast_util
::stmt_id(&**statement
),
3331 scope_stack
.last().unwrap().scope_metadata
);
3333 match statement
.node
{
3334 ast
::StmtDecl(ref decl
, _
) =>
3335 walk_decl(cx
, &**decl
, scope_stack
, scope_map
),
3336 ast
::StmtExpr(ref exp
, _
) |
3337 ast
::StmtSemi(ref exp
, _
) =>
3338 walk_expr(cx
, &**exp
, scope_stack
, scope_map
),
3339 ast
::StmtMac(..) => () // Ignore macros (which should be expanded anyway).
3343 if let Some(ref exp
) = block
.expr
{
3344 walk_expr(cx
, &**exp
, scope_stack
, scope_map
);
3348 fn walk_decl(cx
: &CrateContext
,
3350 scope_stack
: &mut Vec
<ScopeStackEntry
> ,
3351 scope_map
: &mut NodeMap
<DIScope
>) {
3353 codemap
::Spanned { node: ast::DeclLocal(ref local), .. }
=> {
3354 scope_map
.insert(local
.id
, scope_stack
.last().unwrap().scope_metadata
);
3356 walk_pattern(cx
, &*local
.pat
, scope_stack
, scope_map
);
3358 if let Some(ref exp
) = local
.init
{
3359 walk_expr(cx
, &**exp
, scope_stack
, scope_map
);
3366 fn walk_pattern(cx
: &CrateContext
,
3368 scope_stack
: &mut Vec
<ScopeStackEntry
> ,
3369 scope_map
: &mut NodeMap
<DIScope
>) {
3371 let def_map
= &cx
.tcx().def_map
;
3373 // Unfortunately, we cannot just use pat_util::pat_bindings() or
3374 // ast_util::walk_pat() here because we have to visit *all* nodes in
3375 // order to put them into the scope map. The above functions don't do that.
3377 ast
::PatIdent(_
, ref path1
, ref sub_pat_opt
) => {
3379 // Check if this is a binding. If so we need to put it on the
3380 // scope stack and maybe introduce an artificial scope
3381 if pat_util
::pat_is_binding(def_map
, &*pat
) {
3383 let name
= path1
.node
.name
;
3385 // LLVM does not properly generate 'DW_AT_start_scope' fields
3386 // for variable DIEs. For this reason we have to introduce
3387 // an artificial scope at bindings whenever a variable with
3388 // the same name is declared in *any* parent scope.
3390 // Otherwise the following error occurs:
3394 // do_something(); // 'gdb print x' correctly prints 10
3397 // do_something(); // 'gdb print x' prints 0, because it
3398 // // already reads the uninitialized 'x'
3399 // // from the next line...
3401 // do_something(); // 'gdb print x' correctly prints 100
3404 // Is there already a binding with that name?
3405 // N.B.: this comparison must be UNhygienic... because
3406 // gdb knows nothing about the context, so any two
3407 // variables with the same name will cause the problem.
3408 let need_new_scope
= scope_stack
3410 .any(|entry
| entry
.name
== Some(name
));
3413 // Create a new lexical scope and push it onto the stack
3414 let loc
= cx
.sess().codemap().lookup_char_pos(pat
.span
.lo
);
3415 let file_metadata
= file_metadata(cx
, &loc
.file
.name
);
3416 let parent_scope
= scope_stack
.last().unwrap().scope_metadata
;
3418 let scope_metadata
= unsafe {
3419 llvm
::LLVMDIBuilderCreateLexicalBlock(
3424 loc
.col
.to_usize() as c_uint
)
3427 scope_stack
.push(ScopeStackEntry
{
3428 scope_metadata
: scope_metadata
,
3433 // Push a new entry anyway so the name can be found
3434 let prev_metadata
= scope_stack
.last().unwrap().scope_metadata
;
3435 scope_stack
.push(ScopeStackEntry
{
3436 scope_metadata
: prev_metadata
,
3442 scope_map
.insert(pat
.id
, scope_stack
.last().unwrap().scope_metadata
);
3444 if let Some(ref sub_pat
) = *sub_pat_opt
{
3445 walk_pattern(cx
, &**sub_pat
, scope_stack
, scope_map
);
3449 ast
::PatWild(_
) => {
3450 scope_map
.insert(pat
.id
, scope_stack
.last().unwrap().scope_metadata
);
3453 ast
::PatEnum(_
, ref sub_pats_opt
) => {
3454 scope_map
.insert(pat
.id
, scope_stack
.last().unwrap().scope_metadata
);
3456 if let Some(ref sub_pats
) = *sub_pats_opt
{
3458 walk_pattern(cx
, &**p
, scope_stack
, scope_map
);
3463 ast
::PatStruct(_
, ref field_pats
, _
) => {
3464 scope_map
.insert(pat
.id
, scope_stack
.last().unwrap().scope_metadata
);
3466 for &codemap
::Spanned
{
3467 node
: ast
::FieldPat { pat: ref sub_pat, .. }
,
3469 } in field_pats
.iter() {
3470 walk_pattern(cx
, &**sub_pat
, scope_stack
, scope_map
);
3474 ast
::PatTup(ref sub_pats
) => {
3475 scope_map
.insert(pat
.id
, scope_stack
.last().unwrap().scope_metadata
);
3477 for sub_pat
in sub_pats
{
3478 walk_pattern(cx
, &**sub_pat
, scope_stack
, scope_map
);
3482 ast
::PatBox(ref sub_pat
) | ast
::PatRegion(ref sub_pat
, _
) => {
3483 scope_map
.insert(pat
.id
, scope_stack
.last().unwrap().scope_metadata
);
3484 walk_pattern(cx
, &**sub_pat
, scope_stack
, scope_map
);
3487 ast
::PatLit(ref exp
) => {
3488 scope_map
.insert(pat
.id
, scope_stack
.last().unwrap().scope_metadata
);
3489 walk_expr(cx
, &**exp
, scope_stack
, scope_map
);
3492 ast
::PatRange(ref exp1
, ref exp2
) => {
3493 scope_map
.insert(pat
.id
, scope_stack
.last().unwrap().scope_metadata
);
3494 walk_expr(cx
, &**exp1
, scope_stack
, scope_map
);
3495 walk_expr(cx
, &**exp2
, scope_stack
, scope_map
);
3498 ast
::PatVec(ref front_sub_pats
, ref middle_sub_pats
, ref back_sub_pats
) => {
3499 scope_map
.insert(pat
.id
, scope_stack
.last().unwrap().scope_metadata
);
3501 for sub_pat
in front_sub_pats
{
3502 walk_pattern(cx
, &**sub_pat
, scope_stack
, scope_map
);
3505 if let Some(ref sub_pat
) = *middle_sub_pats
{
3506 walk_pattern(cx
, &**sub_pat
, scope_stack
, scope_map
);
3509 for sub_pat
in back_sub_pats
{
3510 walk_pattern(cx
, &**sub_pat
, scope_stack
, scope_map
);
3515 cx
.sess().span_bug(pat
.span
, "debuginfo::create_scope_map() - \
3516 Found unexpanded macro.");
3521 fn walk_expr(cx
: &CrateContext
,
3523 scope_stack
: &mut Vec
<ScopeStackEntry
> ,
3524 scope_map
: &mut NodeMap
<DIScope
>) {
3526 scope_map
.insert(exp
.id
, scope_stack
.last().unwrap().scope_metadata
);
3532 ast
::ExprPath(..) => {}
3534 ast
::ExprCast(ref sub_exp
, _
) |
3535 ast
::ExprAddrOf(_
, ref sub_exp
) |
3536 ast
::ExprField(ref sub_exp
, _
) |
3537 ast
::ExprTupField(ref sub_exp
, _
) |
3538 ast
::ExprParen(ref sub_exp
) =>
3539 walk_expr(cx
, &**sub_exp
, scope_stack
, scope_map
),
3541 ast
::ExprBox(ref place
, ref sub_expr
) => {
3543 |e
| walk_expr(cx
, &**e
, scope_stack
, scope_map
));
3544 walk_expr(cx
, &**sub_expr
, scope_stack
, scope_map
);
3547 ast
::ExprRet(ref exp_opt
) => match *exp_opt
{
3548 Some(ref sub_exp
) => walk_expr(cx
, &**sub_exp
, scope_stack
, scope_map
),
3552 ast
::ExprUnary(_
, ref sub_exp
) => {
3553 walk_expr(cx
, &**sub_exp
, scope_stack
, scope_map
);
3556 ast
::ExprAssignOp(_
, ref lhs
, ref rhs
) |
3557 ast
::ExprIndex(ref lhs
, ref rhs
) |
3558 ast
::ExprBinary(_
, ref lhs
, ref rhs
) => {
3559 walk_expr(cx
, &**lhs
, scope_stack
, scope_map
);
3560 walk_expr(cx
, &**rhs
, scope_stack
, scope_map
);
3563 ast
::ExprRange(ref start
, ref end
) => {
3564 start
.as_ref().map(|e
| walk_expr(cx
, &**e
, scope_stack
, scope_map
));
3565 end
.as_ref().map(|e
| walk_expr(cx
, &**e
, scope_stack
, scope_map
));
3568 ast
::ExprVec(ref init_expressions
) |
3569 ast
::ExprTup(ref init_expressions
) => {
3570 for ie
in init_expressions
{
3571 walk_expr(cx
, &**ie
, scope_stack
, scope_map
);
3575 ast
::ExprAssign(ref sub_exp1
, ref sub_exp2
) |
3576 ast
::ExprRepeat(ref sub_exp1
, ref sub_exp2
) => {
3577 walk_expr(cx
, &**sub_exp1
, scope_stack
, scope_map
);
3578 walk_expr(cx
, &**sub_exp2
, scope_stack
, scope_map
);
3581 ast
::ExprIf(ref cond_exp
, ref then_block
, ref opt_else_exp
) => {
3582 walk_expr(cx
, &**cond_exp
, scope_stack
, scope_map
);
3588 |cx
, scope_stack
, scope_map
| {
3589 walk_block(cx
, &**then_block
, scope_stack
, scope_map
);
3592 match *opt_else_exp
{
3593 Some(ref else_exp
) =>
3594 walk_expr(cx
, &**else_exp
, scope_stack
, scope_map
),
3599 ast
::ExprIfLet(..) => {
3600 cx
.sess().span_bug(exp
.span
, "debuginfo::create_scope_map() - \
3601 Found unexpanded if-let.");
3604 ast
::ExprWhile(ref cond_exp
, ref loop_body
, _
) => {
3605 walk_expr(cx
, &**cond_exp
, scope_stack
, scope_map
);
3611 |cx
, scope_stack
, scope_map
| {
3612 walk_block(cx
, &**loop_body
, scope_stack
, scope_map
);
3616 ast
::ExprWhileLet(..) => {
3617 cx
.sess().span_bug(exp
.span
, "debuginfo::create_scope_map() - \
3618 Found unexpanded while-let.");
3621 ast
::ExprForLoop(..) => {
3622 cx
.sess().span_bug(exp
.span
, "debuginfo::create_scope_map() - \
3623 Found unexpanded for loop.");
3626 ast
::ExprMac(_
) => {
3627 cx
.sess().span_bug(exp
.span
, "debuginfo::create_scope_map() - \
3628 Found unexpanded macro.");
3631 ast
::ExprLoop(ref block
, _
) |
3632 ast
::ExprBlock(ref block
) => {
3637 |cx
, scope_stack
, scope_map
| {
3638 walk_block(cx
, &**block
, scope_stack
, scope_map
);
3642 ast
::ExprClosure(_
, ref decl
, ref block
) => {
3647 |cx
, scope_stack
, scope_map
| {
3648 for &ast
::Arg { pat: ref pattern, .. }
in &decl
.inputs
{
3649 walk_pattern(cx
, &**pattern
, scope_stack
, scope_map
);
3652 walk_block(cx
, &**block
, scope_stack
, scope_map
);
3656 ast
::ExprCall(ref fn_exp
, ref args
) => {
3657 walk_expr(cx
, &**fn_exp
, scope_stack
, scope_map
);
3659 for arg_exp
in args
{
3660 walk_expr(cx
, &**arg_exp
, scope_stack
, scope_map
);
3664 ast
::ExprMethodCall(_
, _
, ref args
) => {
3665 for arg_exp
in args
{
3666 walk_expr(cx
, &**arg_exp
, scope_stack
, scope_map
);
3670 ast
::ExprMatch(ref discriminant_exp
, ref arms
, _
) => {
3671 walk_expr(cx
, &**discriminant_exp
, scope_stack
, scope_map
);
3673 // For each arm we have to first walk the pattern as these might
3674 // introduce new artificial scopes. It should be sufficient to
3675 // walk only one pattern per arm, as they all must contain the
3676 // same binding names.
3678 for arm_ref
in arms
{
3679 let arm_span
= arm_ref
.pats
[0].span
;
3685 |cx
, scope_stack
, scope_map
| {
3686 for pat
in &arm_ref
.pats
{
3687 walk_pattern(cx
, &**pat
, scope_stack
, scope_map
);
3690 if let Some(ref guard_exp
) = arm_ref
.guard
{
3691 walk_expr(cx
, &**guard_exp
, scope_stack
, scope_map
)
3694 walk_expr(cx
, &*arm_ref
.body
, scope_stack
, scope_map
);
3699 ast
::ExprStruct(_
, ref fields
, ref base_exp
) => {
3700 for &ast
::Field { expr: ref exp, .. }
in fields
{
3701 walk_expr(cx
, &**exp
, scope_stack
, scope_map
);
3705 Some(ref exp
) => walk_expr(cx
, &**exp
, scope_stack
, scope_map
),
3710 ast
::ExprInlineAsm(ast
::InlineAsm
{ ref inputs
,
3713 // inputs, outputs: Vec<(String, P<Expr>)>
3714 for &(_
, ref exp
) in inputs
{
3715 walk_expr(cx
, &**exp
, scope_stack
, scope_map
);
3718 for &(_
, ref exp
, _
) in outputs
{
3719 walk_expr(cx
, &**exp
, scope_stack
, scope_map
);
3727 //=-----------------------------------------------------------------------------
3728 // Type Names for Debug Info
3729 //=-----------------------------------------------------------------------------
3731 // Compute the name of the type as it should be stored in debuginfo. Does not do
3732 // any caching, i.e. calling the function twice with the same type will also do
3733 // the work twice. The `qualified` parameter only affects the first level of the
3734 // type name, further levels (i.e. type parameters) are always fully qualified.
3735 fn compute_debuginfo_type_name
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
3739 let mut result
= String
::with_capacity(64);
3740 push_debuginfo_type_name(cx
, t
, qualified
, &mut result
);
3744 // Pushes the name of the type as it should be stored in debuginfo on the
3745 // `output` String. See also compute_debuginfo_type_name().
3746 fn push_debuginfo_type_name
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
3749 output
: &mut String
) {
3751 ty
::ty_bool
=> output
.push_str("bool"),
3752 ty
::ty_char
=> output
.push_str("char"),
3753 ty
::ty_str
=> output
.push_str("str"),
3754 ty
::ty_int(ast
::TyIs
) => output
.push_str("isize"),
3755 ty
::ty_int(ast
::TyI8
) => output
.push_str("i8"),
3756 ty
::ty_int(ast
::TyI16
) => output
.push_str("i16"),
3757 ty
::ty_int(ast
::TyI32
) => output
.push_str("i32"),
3758 ty
::ty_int(ast
::TyI64
) => output
.push_str("i64"),
3759 ty
::ty_uint(ast
::TyUs
) => output
.push_str("usize"),
3760 ty
::ty_uint(ast
::TyU8
) => output
.push_str("u8"),
3761 ty
::ty_uint(ast
::TyU16
) => output
.push_str("u16"),
3762 ty
::ty_uint(ast
::TyU32
) => output
.push_str("u32"),
3763 ty
::ty_uint(ast
::TyU64
) => output
.push_str("u64"),
3764 ty
::ty_float(ast
::TyF32
) => output
.push_str("f32"),
3765 ty
::ty_float(ast
::TyF64
) => output
.push_str("f64"),
3766 ty
::ty_struct(def_id
, substs
) |
3767 ty
::ty_enum(def_id
, substs
) => {
3768 push_item_name(cx
, def_id
, qualified
, output
);
3769 push_type_params(cx
, substs
, output
);
3771 ty
::ty_tup(ref component_types
) => {
3773 for &component_type
in component_types
{
3774 push_debuginfo_type_name(cx
, component_type
, true, output
);
3775 output
.push_str(", ");
3777 if !component_types
.is_empty() {
3783 ty
::ty_uniq(inner_type
) => {
3784 output
.push_str("Box<");
3785 push_debuginfo_type_name(cx
, inner_type
, true, output
);
3788 ty
::ty_ptr(ty
::mt { ty: inner_type, mutbl }
) => {
3791 ast
::MutImmutable
=> output
.push_str("const "),
3792 ast
::MutMutable
=> output
.push_str("mut "),
3795 push_debuginfo_type_name(cx
, inner_type
, true, output
);
3797 ty
::ty_rptr(_
, ty
::mt { ty: inner_type, mutbl }
) => {
3799 if mutbl
== ast
::MutMutable
{
3800 output
.push_str("mut ");
3803 push_debuginfo_type_name(cx
, inner_type
, true, output
);
3805 ty
::ty_vec(inner_type
, optional_length
) => {
3807 push_debuginfo_type_name(cx
, inner_type
, true, output
);
3809 match optional_length
{
3811 output
.push_str(&format
!("; {}", len
));
3813 None
=> { /* nothing to do */ }
3818 ty
::ty_trait(ref trait_data
) => {
3819 let principal
= ty
::erase_late_bound_regions(cx
.tcx(), &trait_data
.principal
);
3820 push_item_name(cx
, principal
.def_id
, false, output
);
3821 push_type_params(cx
, principal
.substs
, output
);
3823 ty
::ty_bare_fn(_
, &ty
::BareFnTy{ unsafety, abi, ref sig }
) => {
3824 if unsafety
== ast
::Unsafety
::Unsafe
{
3825 output
.push_str("unsafe ");
3828 if abi
!= ::syntax
::abi
::Rust
{
3829 output
.push_str("extern \"");
3830 output
.push_str(abi
.name());
3831 output
.push_str("\" ");
3834 output
.push_str("fn(");
3836 let sig
= ty
::erase_late_bound_regions(cx
.tcx(), sig
);
3837 if !sig
.inputs
.is_empty() {
3838 for ¶meter_type
in &sig
.inputs
{
3839 push_debuginfo_type_name(cx
, parameter_type
, true, output
);
3840 output
.push_str(", ");
3847 if !sig
.inputs
.is_empty() {
3848 output
.push_str(", ...");
3850 output
.push_str("...");
3857 ty
::FnConverging(result_type
) if ty
::type_is_nil(result_type
) => {}
3858 ty
::FnConverging(result_type
) => {
3859 output
.push_str(" -> ");
3860 push_debuginfo_type_name(cx
, result_type
, true, output
);
3862 ty
::FnDiverging
=> {
3863 output
.push_str(" -> !");
3867 ty
::ty_closure(..) => {
3868 output
.push_str("closure");
3872 ty
::ty_projection(..) |
3873 ty
::ty_param(_
) => {
3874 cx
.sess().bug(&format
!("debuginfo: Trying to create type name for \
3875 unexpected type: {}", ppaux
::ty_to_string(cx
.tcx(), t
)));
3879 fn push_item_name(cx
: &CrateContext
,
3882 output
: &mut String
) {
3883 ty
::with_path(cx
.tcx(), def_id
, |path
| {
3885 if def_id
.krate
== ast
::LOCAL_CRATE
{
3886 output
.push_str(crate_root_namespace(cx
));
3887 output
.push_str("::");
3890 let mut path_element_count
= 0;
3891 for path_element
in path
{
3892 let name
= token
::get_name(path_element
.name());
3893 output
.push_str(&name
);
3894 output
.push_str("::");
3895 path_element_count
+= 1;
3898 if path_element_count
== 0 {
3899 cx
.sess().bug("debuginfo: Encountered empty item path!");
3905 let name
= token
::get_name(path
.last()
3906 .expect("debuginfo: Empty item path?")
3908 output
.push_str(&name
);
3913 // Pushes the type parameters in the given `Substs` to the output string.
3914 // This ignores region parameters, since they can't reliably be
3915 // reconstructed for items from non-local crates. For local crates, this
3916 // would be possible but with inlining and LTO we have to use the least
3917 // common denominator - otherwise we would run into conflicts.
3918 fn push_type_params
<'a
, 'tcx
>(cx
: &CrateContext
<'a
, 'tcx
>,
3919 substs
: &subst
::Substs
<'tcx
>,
3920 output
: &mut String
) {
3921 if substs
.types
.is_empty() {
3927 for &type_parameter
in substs
.types
.iter() {
3928 push_debuginfo_type_name(cx
, type_parameter
, true, output
);
3929 output
.push_str(", ");
3940 //=-----------------------------------------------------------------------------
3941 // Namespace Handling
3942 //=-----------------------------------------------------------------------------
3944 struct NamespaceTreeNode
{
3947 parent
: Option
<Weak
<NamespaceTreeNode
>>,
3950 impl NamespaceTreeNode
{
3951 fn mangled_name_of_contained_item(&self, item_name
: &str) -> String
{
3952 fn fill_nested(node
: &NamespaceTreeNode
, output
: &mut String
) {
3954 Some(ref parent
) => fill_nested(&*parent
.upgrade().unwrap(), output
),
3957 let string
= token
::get_name(node
.name
);
3958 output
.push_str(&format
!("{}", string
.len()));
3959 output
.push_str(&string
);
3962 let mut name
= String
::from_str("_ZN");
3963 fill_nested(self, &mut name
);
3964 name
.push_str(&format
!("{}", item_name
.len()));
3965 name
.push_str(item_name
);
3971 fn crate_root_namespace
<'a
>(cx
: &'a CrateContext
) -> &'a
str {
3972 &cx
.link_meta().crate_name
3975 fn namespace_for_item(cx
: &CrateContext
, def_id
: ast
::DefId
) -> Rc
<NamespaceTreeNode
> {
3976 ty
::with_path(cx
.tcx(), def_id
, |path
| {
3977 // prepend crate name if not already present
3978 let krate
= if def_id
.krate
== ast
::LOCAL_CRATE
{
3979 let crate_namespace_name
= token
::intern(crate_root_namespace(cx
));
3980 Some(ast_map
::PathMod(crate_namespace_name
))
3984 let mut path
= krate
.into_iter().chain(path
).peekable();
3986 let mut current_key
= Vec
::new();
3987 let mut parent_node
: Option
<Rc
<NamespaceTreeNode
>> = None
;
3989 // Create/Lookup namespace for each element of the path.
3991 // Emulate a for loop so we can use peek below.
3992 let path_element
= match path
.next() {
3996 // Ignore the name of the item (the last path element).
3997 if path
.peek().is_none() {
4001 let name
= path_element
.name();
4002 current_key
.push(name
);
4004 let existing_node
= debug_context(cx
).namespace_map
.borrow()
4005 .get(¤t_key
).cloned();
4006 let current_node
= match existing_node
{
4007 Some(existing_node
) => existing_node
,
4009 // create and insert
4010 let parent_scope
= match parent_node
{
4011 Some(ref node
) => node
.scope
,
4012 None
=> ptr
::null_mut()
4014 let namespace_name
= token
::get_name(name
);
4015 let namespace_name
= CString
::new(namespace_name
.as_bytes()).unwrap();
4016 let scope
= unsafe {
4017 llvm
::LLVMDIBuilderCreateNameSpace(
4020 namespace_name
.as_ptr(),
4021 // cannot reconstruct file ...
4023 // ... or line information, but that's not so important.
4027 let node
= Rc
::new(NamespaceTreeNode
{
4030 parent
: parent_node
.map(|parent
| parent
.downgrade()),
4033 debug_context(cx
).namespace_map
.borrow_mut()
4034 .insert(current_key
.clone(), node
.clone());
4040 parent_node
= Some(current_node
);
4046 cx
.sess().bug(&format
!("debuginfo::namespace_for_item(): \
4047 path too short for {:?}",
4055 //=-----------------------------------------------------------------------------
4056 // .debug_gdb_scripts binary section
4057 //=-----------------------------------------------------------------------------
4059 /// Inserts a side-effect free instruction sequence that makes sure that the
4060 /// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
4061 pub fn insert_reference_to_gdb_debug_scripts_section_global(ccx
: &CrateContext
) {
4062 if needs_gdb_debug_scripts_section(ccx
) {
4063 let empty
= CString
::new("").unwrap();
4064 let gdb_debug_scripts_section_global
=
4065 get_or_insert_gdb_debug_scripts_section_global(ccx
);
4067 let volative_load_instruction
=
4068 llvm
::LLVMBuildLoad(ccx
.raw_builder(),
4069 gdb_debug_scripts_section_global
,
4071 llvm
::LLVMSetVolatile(volative_load_instruction
, llvm
::True
);
4076 /// Allocates the global variable responsible for the .debug_gdb_scripts binary
4078 fn get_or_insert_gdb_debug_scripts_section_global(ccx
: &CrateContext
)
4080 let section_var_name
= "__rustc_debug_gdb_scripts_section__";
4082 let section_var
= unsafe {
4083 llvm
::LLVMGetNamedGlobal(ccx
.llmod(),
4084 section_var_name
.as_ptr() as *const _
)
4087 if section_var
== ptr
::null_mut() {
4088 let section_name
= b
".debug_gdb_scripts\0";
4089 let section_contents
= b
"\x01gdb_load_rust_pretty_printers.py\0";
4092 let llvm_type
= Type
::array(&Type
::i8(ccx
),
4093 section_contents
.len() as u64);
4095 let section_var
= declare
::define_global(ccx
, section_var_name
,
4096 llvm_type
).unwrap_or_else(||{
4097 ccx
.sess().bug(&format
!("symbol `{}` is already defined", section_var_name
))
4099 llvm
::LLVMSetSection(section_var
, section_name
.as_ptr() as *const _
);
4100 llvm
::LLVMSetInitializer(section_var
, C_bytes(ccx
, section_contents
));
4101 llvm
::LLVMSetGlobalConstant(section_var
, llvm
::True
);
4102 llvm
::LLVMSetUnnamedAddr(section_var
, llvm
::True
);
4103 llvm
::SetLinkage(section_var
, llvm
::Linkage
::LinkOnceODRLinkage
);
4104 // This should make sure that the whole section is not larger than
4105 // the string it contains. Otherwise we get a warning from GDB.
4106 llvm
::LLVMSetAlignment(section_var
, 1);
4114 fn needs_gdb_debug_scripts_section(ccx
: &CrateContext
) -> bool
{
4115 let omit_gdb_pretty_printer_section
=
4116 attr
::contains_name(&ccx
.tcx()
4120 "omit_gdb_pretty_printer_section");
4122 !omit_gdb_pretty_printer_section
&&
4123 !ccx
.sess().target
.target
.options
.is_like_osx
&&
4124 !ccx
.sess().target
.target
.options
.is_like_windows
&&
4125 ccx
.sess().opts
.debuginfo
!= NoDebugInfo