]> git.proxmox.com Git - rustc.git/blame - src/librustc_trans/trans/debuginfo/metadata.rs
Imported Upstream version 1.3.0+dfsg1
[rustc.git] / src / librustc_trans / trans / debuginfo / metadata.rs
CommitLineData
d9579d0f 1// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
1a4d82fc
JJ
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
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.
10
d9579d0f 11use self::RecursiveTypeDescription::*;
1a4d82fc
JJ
12use self::MemberOffset::*;
13use self::MemberDescriptionFactory::*;
1a4d82fc 14use self::EnumDiscriminantInfo::*;
1a4d82fc 15
d9579d0f
AL
16use super::utils::{debug_context, DIB, span_start, bytes_to_bits, size_and_align_of,
17 get_namespace_and_span_for_item, create_DIArray,
18 fn_should_be_ignored, is_node_local_to_unit};
19use super::namespace::namespace_for_item;
20use super::type_names::{compute_debuginfo_type_name, push_debuginfo_type_name};
21use super::{declare_local, VariableKind, VariableAccess};
22
23use llvm::{self, ValueRef};
24use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};
25
1a4d82fc 26use metadata::csearch;
d9579d0f 27use middle::pat_util;
1a4d82fc 28use middle::subst::{self, Substs};
62682a34 29use rustc::ast_map;
d9579d0f 30use trans::{type_of, adt, machine, monomorphize};
c1a9b12d
SL
31use trans::common::{self, CrateContext, FunctionContext, Block};
32use trans::_match::{BindingInfo, TransBindingMode};
1a4d82fc 33use trans::type_::Type;
c1a9b12d 34use middle::ty::{self, Ty};
d9579d0f
AL
35use session::config::{self, FullDebugInfo};
36use util::nodemap::FnvHashMap;
c34b1796 37use util::common::path2cstr;
1a4d82fc 38
85aaf69f 39use libc::{c_uint, c_longlong};
c34b1796
AL
40use std::ffi::CString;
41use std::path::Path;
1a4d82fc 42use std::ptr;
d9579d0f 43use std::rc::Rc;
1a4d82fc 44use syntax::util::interner::Interner;
d9579d0f 45use syntax::codemap::Span;
62682a34 46use syntax::{ast, codemap, ast_util};
1a4d82fc
JJ
47use syntax::parse::token::{self, special_idents};
48
1a4d82fc 49
d9579d0f 50const DW_LANG_RUST: c_uint = 0x9000;
1a4d82fc
JJ
51#[allow(non_upper_case_globals)]
52const DW_ATE_boolean: c_uint = 0x02;
53#[allow(non_upper_case_globals)]
54const DW_ATE_float: c_uint = 0x04;
55#[allow(non_upper_case_globals)]
56const DW_ATE_signed: c_uint = 0x05;
57#[allow(non_upper_case_globals)]
58const DW_ATE_unsigned: c_uint = 0x07;
59#[allow(non_upper_case_globals)]
60const DW_ATE_unsigned_char: c_uint = 0x08;
61
d9579d0f
AL
62pub const UNKNOWN_LINE_NUMBER: c_uint = 0;
63pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
1a4d82fc
JJ
64
65// ptr::null() doesn't work :(
66const UNKNOWN_FILE_METADATA: DIFile = (0 as DIFile);
67const UNKNOWN_SCOPE_METADATA: DIScope = (0 as DIScope);
68
69const FLAGS_NONE: c_uint = 0;
70
85aaf69f 71#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
d9579d0f 72pub struct UniqueTypeId(ast::Name);
1a4d82fc
JJ
73
74// The TypeMap is where the CrateDebugContext holds the type metadata nodes
75// created so far. The metadata nodes are indexed by UniqueTypeId, and, for
76// faster lookup, also by Ty. The TypeMap is responsible for creating
77// UniqueTypeIds.
d9579d0f 78pub struct TypeMap<'tcx> {
1a4d82fc
JJ
79 // The UniqueTypeIds created so far
80 unique_id_interner: Interner<Rc<String>>,
81 // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
82 unique_id_to_metadata: FnvHashMap<UniqueTypeId, DIType>,
83 // A map from types to debuginfo metadata. This is a N:1 mapping.
84 type_to_metadata: FnvHashMap<Ty<'tcx>, DIType>,
85 // A map from types to UniqueTypeId. This is a N:1 mapping.
86 type_to_unique_id: FnvHashMap<Ty<'tcx>, UniqueTypeId>
87}
88
89impl<'tcx> TypeMap<'tcx> {
d9579d0f 90 pub fn new() -> TypeMap<'tcx> {
1a4d82fc
JJ
91 TypeMap {
92 unique_id_interner: Interner::new(),
85aaf69f
SL
93 type_to_metadata: FnvHashMap(),
94 unique_id_to_metadata: FnvHashMap(),
95 type_to_unique_id: FnvHashMap(),
1a4d82fc
JJ
96 }
97 }
98
99 // Adds a Ty to metadata mapping to the TypeMap. The method will fail if
100 // the mapping already exists.
101 fn register_type_with_metadata<'a>(&mut self,
102 cx: &CrateContext<'a, 'tcx>,
103 type_: Ty<'tcx>,
104 metadata: DIType) {
105 if self.type_to_metadata.insert(type_, metadata).is_some() {
106 cx.sess().bug(&format!("Type metadata for Ty '{}' is already in the TypeMap!",
62682a34 107 type_));
1a4d82fc
JJ
108 }
109 }
110
111 // Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
112 // fail if the mapping already exists.
113 fn register_unique_id_with_metadata(&mut self,
114 cx: &CrateContext,
115 unique_type_id: UniqueTypeId,
116 metadata: DIType) {
117 if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
118 let unique_type_id_str = self.get_unique_type_id_as_string(unique_type_id);
119 cx.sess().bug(&format!("Type metadata for unique id '{}' is already in the TypeMap!",
c34b1796 120 &unique_type_id_str[..]));
1a4d82fc
JJ
121 }
122 }
123
124 fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<DIType> {
125 self.type_to_metadata.get(&type_).cloned()
126 }
127
128 fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<DIType> {
129 self.unique_id_to_metadata.get(&unique_type_id).cloned()
130 }
131
132 // Get the string representation of a UniqueTypeId. This method will fail if
133 // the id is unknown.
134 fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> Rc<String> {
135 let UniqueTypeId(interner_key) = unique_type_id;
136 self.unique_id_interner.get(interner_key)
137 }
138
139 // Get the UniqueTypeId for the given type. If the UniqueTypeId for the given
140 // type has been requested before, this is just a table lookup. Otherwise an
141 // ID will be generated and stored for later lookup.
142 fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
143 type_: Ty<'tcx>) -> UniqueTypeId {
144
d9579d0f
AL
145 // basic type -> {:name of the type:}
146 // tuple -> {tuple_(:param-uid:)*}
147 // struct -> {struct_:svh: / :node-id:_<(:param-uid:),*> }
148 // enum -> {enum_:svh: / :node-id:_<(:param-uid:),*> }
149 // enum variant -> {variant_:variant-name:_:enum-uid:}
150 // reference (&) -> {& :pointee-uid:}
151 // mut reference (&mut) -> {&mut :pointee-uid:}
152 // ptr (*) -> {* :pointee-uid:}
153 // mut ptr (*mut) -> {*mut :pointee-uid:}
154 // unique ptr (box) -> {box :pointee-uid:}
155 // @-ptr (@) -> {@ :pointee-uid:}
156 // sized vec ([T; x]) -> {[:size:] :element-uid:}
157 // unsized vec ([T]) -> {[] :element-uid:}
158 // trait (T) -> {trait_:svh: / :node-id:_<(:param-uid:),*> }
159 // closure -> {<unsafe_> <once_> :store-sigil: |(:param-uid:),* <,_...>| -> \
1a4d82fc 160 // :return-type-uid: : (:bounds:)*}
d9579d0f 161 // function -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \
1a4d82fc 162 // :return-type-uid:}
1a4d82fc
JJ
163
164 match self.type_to_unique_id.get(&type_).cloned() {
165 Some(unique_type_id) => return unique_type_id,
166 None => { /* generate one */}
167 };
168
169 let mut unique_type_id = String::with_capacity(256);
170 unique_type_id.push('{');
171
172 match type_.sty {
62682a34
SL
173 ty::TyBool |
174 ty::TyChar |
175 ty::TyStr |
176 ty::TyInt(_) |
177 ty::TyUint(_) |
178 ty::TyFloat(_) => {
1a4d82fc
JJ
179 push_debuginfo_type_name(cx, type_, false, &mut unique_type_id);
180 },
62682a34 181 ty::TyEnum(def_id, substs) => {
1a4d82fc
JJ
182 unique_type_id.push_str("enum ");
183 from_def_id_and_substs(self, cx, def_id, substs, &mut unique_type_id);
184 },
62682a34 185 ty::TyStruct(def_id, substs) => {
1a4d82fc
JJ
186 unique_type_id.push_str("struct ");
187 from_def_id_and_substs(self, cx, def_id, substs, &mut unique_type_id);
188 },
62682a34 189 ty::TyTuple(ref component_types) if component_types.is_empty() => {
1a4d82fc
JJ
190 push_debuginfo_type_name(cx, type_, false, &mut unique_type_id);
191 },
62682a34 192 ty::TyTuple(ref component_types) => {
1a4d82fc 193 unique_type_id.push_str("tuple ");
85aaf69f 194 for &component_type in component_types {
1a4d82fc
JJ
195 let component_type_id =
196 self.get_unique_type_id_of_type(cx, component_type);
197 let component_type_id =
198 self.get_unique_type_id_as_string(component_type_id);
85aaf69f 199 unique_type_id.push_str(&component_type_id[..]);
1a4d82fc
JJ
200 }
201 },
62682a34 202 ty::TyBox(inner_type) => {
d9579d0f 203 unique_type_id.push_str("box ");
1a4d82fc
JJ
204 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
205 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
85aaf69f 206 unique_type_id.push_str(&inner_type_id[..]);
1a4d82fc 207 },
c1a9b12d 208 ty::TyRawPtr(ty::TypeAndMut { ty: inner_type, mutbl } ) => {
1a4d82fc
JJ
209 unique_type_id.push('*');
210 if mutbl == ast::MutMutable {
211 unique_type_id.push_str("mut");
212 }
213
214 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
215 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
85aaf69f 216 unique_type_id.push_str(&inner_type_id[..]);
1a4d82fc 217 },
c1a9b12d 218 ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => {
1a4d82fc
JJ
219 unique_type_id.push('&');
220 if mutbl == ast::MutMutable {
221 unique_type_id.push_str("mut");
222 }
223
224 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
225 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
85aaf69f 226 unique_type_id.push_str(&inner_type_id[..]);
1a4d82fc 227 },
62682a34
SL
228 ty::TyArray(inner_type, len) => {
229 unique_type_id.push_str(&format!("[{}]", len));
230
231 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
232 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
233 unique_type_id.push_str(&inner_type_id[..]);
234 },
235 ty::TySlice(inner_type) => {
236 unique_type_id.push_str("[]");
1a4d82fc
JJ
237
238 let inner_type_id = self.get_unique_type_id_of_type(cx, inner_type);
239 let inner_type_id = self.get_unique_type_id_as_string(inner_type_id);
85aaf69f 240 unique_type_id.push_str(&inner_type_id[..]);
1a4d82fc 241 },
62682a34 242 ty::TyTrait(ref trait_data) => {
1a4d82fc
JJ
243 unique_type_id.push_str("trait ");
244
c1a9b12d 245 let principal = cx.tcx().erase_late_bound_regions(&trait_data.principal);
1a4d82fc
JJ
246
247 from_def_id_and_substs(self,
248 cx,
249 principal.def_id,
250 principal.substs,
251 &mut unique_type_id);
252 },
62682a34 253 ty::TyBareFn(_, &ty::BareFnTy{ unsafety, abi, ref sig } ) => {
1a4d82fc
JJ
254 if unsafety == ast::Unsafety::Unsafe {
255 unique_type_id.push_str("unsafe ");
256 }
257
258 unique_type_id.push_str(abi.name());
259
260 unique_type_id.push_str(" fn(");
261
c1a9b12d 262 let sig = cx.tcx().erase_late_bound_regions(sig);
1a4d82fc 263
85aaf69f 264 for &parameter_type in &sig.inputs {
1a4d82fc
JJ
265 let parameter_type_id =
266 self.get_unique_type_id_of_type(cx, parameter_type);
267 let parameter_type_id =
268 self.get_unique_type_id_as_string(parameter_type_id);
85aaf69f 269 unique_type_id.push_str(&parameter_type_id[..]);
1a4d82fc
JJ
270 unique_type_id.push(',');
271 }
272
273 if sig.variadic {
274 unique_type_id.push_str("...");
275 }
276
277 unique_type_id.push_str(")->");
278 match sig.output {
279 ty::FnConverging(ret_ty) => {
280 let return_type_id = self.get_unique_type_id_of_type(cx, ret_ty);
281 let return_type_id = self.get_unique_type_id_as_string(return_type_id);
85aaf69f 282 unique_type_id.push_str(&return_type_id[..]);
1a4d82fc
JJ
283 }
284 ty::FnDiverging => {
285 unique_type_id.push_str("!");
286 }
287 }
288 },
c1a9b12d
SL
289 ty::TyClosure(_, ref substs) if substs.upvar_tys.is_empty() => {
290 push_debuginfo_type_name(cx, type_, false, &mut unique_type_id);
291 },
292 ty::TyClosure(_, ref substs) => {
293 unique_type_id.push_str("closure ");
294 for upvar_type in &substs.upvar_tys {
295 let upvar_type_id =
296 self.get_unique_type_id_of_type(cx, upvar_type);
297 let upvar_type_id =
298 self.get_unique_type_id_as_string(upvar_type_id);
299 unique_type_id.push_str(&upvar_type_id[..]);
300 }
1a4d82fc
JJ
301 },
302 _ => {
62682a34
SL
303 cx.sess().bug(&format!("get_unique_type_id_of_type() - unexpected type: {:?}",
304 type_))
1a4d82fc
JJ
305 }
306 };
307
308 unique_type_id.push('}');
309
310 // Trim to size before storing permanently
311 unique_type_id.shrink_to_fit();
312
313 let key = self.unique_id_interner.intern(Rc::new(unique_type_id));
314 self.type_to_unique_id.insert(type_, UniqueTypeId(key));
315
316 return UniqueTypeId(key);
317
318 fn from_def_id_and_substs<'a, 'tcx>(type_map: &mut TypeMap<'tcx>,
319 cx: &CrateContext<'a, 'tcx>,
320 def_id: ast::DefId,
321 substs: &subst::Substs<'tcx>,
322 output: &mut String) {
323 // First, find out the 'real' def_id of the type. Items inlined from
324 // other crates have to be mapped back to their source.
325 let source_def_id = if def_id.krate == ast::LOCAL_CRATE {
326 match cx.external_srcs().borrow().get(&def_id.node).cloned() {
327 Some(source_def_id) => {
328 // The given def_id identifies the inlined copy of a
329 // type definition, let's take the source of the copy.
330 source_def_id
331 }
332 None => def_id
333 }
334 } else {
335 def_id
336 };
337
338 // Get the crate hash as first part of the identifier.
339 let crate_hash = if source_def_id.krate == ast::LOCAL_CRATE {
340 cx.link_meta().crate_hash.clone()
341 } else {
342 cx.sess().cstore.get_crate_hash(source_def_id.krate)
343 };
344
345 output.push_str(crate_hash.as_str());
346 output.push_str("/");
c34b1796 347 output.push_str(&format!("{:x}", def_id.node));
1a4d82fc
JJ
348
349 // Maybe check that there is no self type here.
350
351 let tps = substs.types.get_slice(subst::TypeSpace);
9346a6ac 352 if !tps.is_empty() {
1a4d82fc
JJ
353 output.push('<');
354
85aaf69f 355 for &type_parameter in tps {
1a4d82fc
JJ
356 let param_type_id =
357 type_map.get_unique_type_id_of_type(cx, type_parameter);
358 let param_type_id =
359 type_map.get_unique_type_id_as_string(param_type_id);
85aaf69f 360 output.push_str(&param_type_id[..]);
1a4d82fc
JJ
361 output.push(',');
362 }
363
364 output.push('>');
365 }
366 }
367 }
368
1a4d82fc
JJ
369 // Get the UniqueTypeId for an enum variant. Enum variants are not really
370 // types of their own, so they need special handling. We still need a
371 // UniqueTypeId for them, since to debuginfo they *are* real types.
372 fn get_unique_type_id_of_enum_variant<'a>(&mut self,
373 cx: &CrateContext<'a, 'tcx>,
374 enum_type: Ty<'tcx>,
375 variant_name: &str)
376 -> UniqueTypeId {
377 let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
378 let enum_variant_type_id = format!("{}::{}",
c34b1796 379 &self.get_unique_type_id_as_string(enum_type_id),
1a4d82fc
JJ
380 variant_name);
381 let interner_key = self.unique_id_interner.intern(Rc::new(enum_variant_type_id));
382 UniqueTypeId(interner_key)
383 }
384}
385
d9579d0f
AL
386// A description of some recursive type. It can either be already finished (as
387// with FinalMetadata) or it is not yet finished, but contains all information
388// needed to generate the missing parts of the description. See the
389// documentation section on Recursive Types at the top of this file for more
390// information.
391enum RecursiveTypeDescription<'tcx> {
392 UnfinishedMetadata {
393 unfinished_type: Ty<'tcx>,
394 unique_type_id: UniqueTypeId,
395 metadata_stub: DICompositeType,
396 llvm_type: Type,
397 member_description_factory: MemberDescriptionFactory<'tcx>,
398 },
399 FinalMetadata(DICompositeType)
400}
401
402fn create_and_register_recursive_type_forward_declaration<'a, 'tcx>(
403 cx: &CrateContext<'a, 'tcx>,
404 unfinished_type: Ty<'tcx>,
405 unique_type_id: UniqueTypeId,
406 metadata_stub: DICompositeType,
407 llvm_type: Type,
408 member_description_factory: MemberDescriptionFactory<'tcx>)
409 -> RecursiveTypeDescription<'tcx> {
410
411 // Insert the stub into the TypeMap in order to allow for recursive references
412 let mut type_map = debug_context(cx).type_map.borrow_mut();
413 type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata_stub);
414 type_map.register_type_with_metadata(cx, unfinished_type, metadata_stub);
415
416 UnfinishedMetadata {
417 unfinished_type: unfinished_type,
418 unique_type_id: unique_type_id,
419 metadata_stub: metadata_stub,
420 llvm_type: llvm_type,
421 member_description_factory: member_description_factory,
422 }
423}
424
425impl<'tcx> RecursiveTypeDescription<'tcx> {
426 // Finishes up the description of the type in question (mostly by providing
427 // descriptions of the fields of the given type) and returns the final type
428 // metadata.
429 fn finalize<'a>(&self, cx: &CrateContext<'a, 'tcx>) -> MetadataCreationResult {
430 match *self {
431 FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
432 UnfinishedMetadata {
433 unfinished_type,
434 unique_type_id,
435 metadata_stub,
436 llvm_type,
437 ref member_description_factory,
438 ..
439 } => {
440 // Make sure that we have a forward declaration of the type in
441 // the TypeMap so that recursive references are possible. This
442 // will always be the case if the RecursiveTypeDescription has
443 // been properly created through the
444 // create_and_register_recursive_type_forward_declaration()
445 // function.
446 {
447 let type_map = debug_context(cx).type_map.borrow();
448 if type_map.find_metadata_for_unique_id(unique_type_id).is_none() ||
449 type_map.find_metadata_for_type(unfinished_type).is_none() {
450 cx.sess().bug(&format!("Forward declaration of potentially recursive type \
62682a34
SL
451 '{:?}' was not found in TypeMap!",
452 unfinished_type)
d9579d0f
AL
453 );
454 }
455 }
456
457 // ... then create the member descriptions ...
458 let member_descriptions =
459 member_description_factory.create_member_descriptions(cx);
460
461 // ... and attach them to the stub to complete it.
462 set_members_of_composite_type(cx,
463 metadata_stub,
464 llvm_type,
465 &member_descriptions[..]);
466 return MetadataCreationResult::new(metadata_stub, true);
467 }
468 }
469 }
470}
471
1a4d82fc
JJ
472// Returns from the enclosing function if the type metadata with the given
473// unique id can be found in the type map
474macro_rules! return_if_metadata_created_in_meantime {
475 ($cx: expr, $unique_type_id: expr) => (
476 match debug_context($cx).type_map
477 .borrow()
478 .find_metadata_for_unique_id($unique_type_id) {
479 Some(metadata) => return MetadataCreationResult::new(metadata, true),
480 None => { /* proceed normally */ }
481 };
482 )
483}
484
d9579d0f
AL
485fn fixed_vec_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
486 unique_type_id: UniqueTypeId,
487 element_type: Ty<'tcx>,
488 len: Option<u64>,
489 span: Span)
490 -> MetadataCreationResult {
491 let element_type_metadata = type_metadata(cx, element_type, span);
492
493 return_if_metadata_created_in_meantime!(cx, unique_type_id);
1a4d82fc 494
d9579d0f
AL
495 let element_llvm_type = type_of::type_of(cx, element_type);
496 let (element_type_size, element_type_align) = size_and_align_of(cx, element_llvm_type);
1a4d82fc 497
d9579d0f
AL
498 let (array_size_in_bytes, upper_bound) = match len {
499 Some(len) => (element_type_size * len, len as c_longlong),
500 None => (0, -1)
501 };
1a4d82fc 502
d9579d0f
AL
503 let subrange = unsafe {
504 llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)
505 };
1a4d82fc 506
d9579d0f
AL
507 let subscripts = create_DIArray(DIB(cx), &[subrange]);
508 let metadata = unsafe {
509 llvm::LLVMDIBuilderCreateArrayType(
510 DIB(cx),
511 bytes_to_bits(array_size_in_bytes),
512 bytes_to_bits(element_type_align),
513 element_type_metadata,
514 subscripts)
515 };
1a4d82fc 516
d9579d0f 517 return MetadataCreationResult::new(metadata, false);
1a4d82fc
JJ
518}
519
d9579d0f
AL
520fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
521 vec_type: Ty<'tcx>,
522 element_type: Ty<'tcx>,
523 unique_type_id: UniqueTypeId,
524 span: Span)
525 -> MetadataCreationResult {
c1a9b12d 526 let data_ptr_type = cx.tcx().mk_ptr(ty::TypeAndMut {
d9579d0f
AL
527 ty: element_type,
528 mutbl: ast::MutImmutable
529 });
1a4d82fc 530
d9579d0f 531 let element_type_metadata = type_metadata(cx, data_ptr_type, span);
1a4d82fc 532
d9579d0f 533 return_if_metadata_created_in_meantime!(cx, unique_type_id);
1a4d82fc 534
d9579d0f
AL
535 let slice_llvm_type = type_of::type_of(cx, vec_type);
536 let slice_type_name = compute_debuginfo_type_name(cx, vec_type, true);
1a4d82fc 537
d9579d0f
AL
538 let member_llvm_types = slice_llvm_type.field_types();
539 assert!(slice_layout_is_correct(cx,
540 &member_llvm_types[..],
541 element_type));
542 let member_descriptions = [
543 MemberDescription {
544 name: "data_ptr".to_string(),
545 llvm_type: member_llvm_types[0],
546 type_metadata: element_type_metadata,
547 offset: ComputedMemberOffset,
548 flags: FLAGS_NONE
549 },
550 MemberDescription {
551 name: "length".to_string(),
552 llvm_type: member_llvm_types[1],
553 type_metadata: type_metadata(cx, cx.tcx().types.usize, span),
554 offset: ComputedMemberOffset,
555 flags: FLAGS_NONE
556 },
557 ];
1a4d82fc 558
d9579d0f 559 assert!(member_descriptions.len() == member_llvm_types.len());
1a4d82fc 560
d9579d0f
AL
561 let loc = span_start(cx, span);
562 let file_metadata = file_metadata(cx, &loc.file.name);
1a4d82fc 563
d9579d0f
AL
564 let metadata = composite_type_metadata(cx,
565 slice_llvm_type,
566 &slice_type_name[..],
567 unique_type_id,
568 &member_descriptions,
569 UNKNOWN_SCOPE_METADATA,
570 file_metadata,
571 span);
572 return MetadataCreationResult::new(metadata, false);
1a4d82fc 573
d9579d0f
AL
574 fn slice_layout_is_correct<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
575 member_llvm_types: &[Type],
576 element_type: Ty<'tcx>)
577 -> bool {
578 member_llvm_types.len() == 2 &&
579 member_llvm_types[0] == type_of::type_of(cx, element_type).ptr_to() &&
580 member_llvm_types[1] == cx.int_type()
1a4d82fc 581 }
d9579d0f 582}
1a4d82fc 583
d9579d0f
AL
584fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
585 unique_type_id: UniqueTypeId,
586 signature: &ty::PolyFnSig<'tcx>,
587 span: Span)
588 -> MetadataCreationResult
589{
c1a9b12d 590 let signature = cx.tcx().erase_late_bound_regions(signature);
1a4d82fc 591
d9579d0f 592 let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs.len() + 1);
1a4d82fc 593
d9579d0f
AL
594 // return type
595 signature_metadata.push(match signature.output {
596 ty::FnConverging(ret_ty) => match ret_ty.sty {
62682a34 597 ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(),
d9579d0f
AL
598 _ => type_metadata(cx, ret_ty, span)
599 },
600 ty::FnDiverging => diverging_type_metadata(cx)
601 });
1a4d82fc 602
d9579d0f
AL
603 // regular arguments
604 for &argument_type in &signature.inputs {
605 signature_metadata.push(type_metadata(cx, argument_type, span));
1a4d82fc
JJ
606 }
607
d9579d0f 608 return_if_metadata_created_in_meantime!(cx, unique_type_id);
1a4d82fc 609
d9579d0f
AL
610 return MetadataCreationResult::new(
611 unsafe {
612 llvm::LLVMDIBuilderCreateSubroutineType(
613 DIB(cx),
614 UNKNOWN_FILE_METADATA,
615 create_DIArray(DIB(cx), &signature_metadata[..]))
1a4d82fc
JJ
616 },
617 false);
618}
619
620// FIXME(1563) This is all a bit of a hack because 'trait pointer' is an ill-
621// defined concept. For the case of an actual trait pointer (i.e., Box<Trait>,
622// &Trait), trait_object_type should be the whole thing (e.g, Box<Trait>) and
623// trait_type should be the actual trait (e.g., Trait). Where the trait is part
624// of a DST struct, there is no trait_object_type and the results of this
625// function will be a little bit weird.
626fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
627 trait_type: Ty<'tcx>,
628 trait_object_type: Option<Ty<'tcx>>,
629 unique_type_id: UniqueTypeId)
630 -> DIType {
631 // The implementation provided here is a stub. It makes sure that the trait
632 // type is assigned the correct name, size, namespace, and source location.
633 // But it does not describe the trait's methods.
634
635 let def_id = match trait_type.sty {
62682a34 636 ty::TyTrait(ref data) => data.principal_def_id(),
1a4d82fc 637 _ => {
1a4d82fc 638 cx.sess().bug(&format!("debuginfo: Unexpected trait-object type in \
62682a34
SL
639 trait_pointer_metadata(): {:?}",
640 trait_type));
1a4d82fc
JJ
641 }
642 };
643
644 let trait_object_type = trait_object_type.unwrap_or(trait_type);
645 let trait_type_name =
646 compute_debuginfo_type_name(cx, trait_object_type, false);
647
648 let (containing_scope, _) = get_namespace_and_span_for_item(cx, def_id);
649
650 let trait_llvm_type = type_of::type_of(cx, trait_object_type);
651
652 composite_type_metadata(cx,
653 trait_llvm_type,
85aaf69f 654 &trait_type_name[..],
1a4d82fc
JJ
655 unique_type_id,
656 &[],
657 containing_scope,
658 UNKNOWN_FILE_METADATA,
659 codemap::DUMMY_SP)
660}
661
d9579d0f
AL
662pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
663 t: Ty<'tcx>,
664 usage_site_span: Span)
665 -> DIType {
1a4d82fc
JJ
666 // Get the unique type id of this type.
667 let unique_type_id = {
668 let mut type_map = debug_context(cx).type_map.borrow_mut();
669 // First, try to find the type in TypeMap. If we have seen it before, we
670 // can exit early here.
671 match type_map.find_metadata_for_type(t) {
672 Some(metadata) => {
673 return metadata;
674 },
675 None => {
676 // The Ty is not in the TypeMap but maybe we have already seen
677 // an equivalent type (e.g. only differing in region arguments).
678 // In order to find out, generate the unique type id and look
679 // that up.
680 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
681 match type_map.find_metadata_for_unique_id(unique_type_id) {
682 Some(metadata) => {
683 // There is already an equivalent type in the TypeMap.
684 // Register this Ty as an alias in the cache and
685 // return the cached metadata.
686 type_map.register_type_with_metadata(cx, t, metadata);
687 return metadata;
688 },
689 None => {
690 // There really is no type metadata for this type, so
691 // proceed by creating it.
692 unique_type_id
693 }
694 }
695 }
696 }
697 };
698
699 debug!("type_metadata: {:?}", t);
700
701 let sty = &t.sty;
702 let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty {
62682a34
SL
703 ty::TyBool |
704 ty::TyChar |
705 ty::TyInt(_) |
706 ty::TyUint(_) |
707 ty::TyFloat(_) => {
1a4d82fc
JJ
708 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
709 }
62682a34 710 ty::TyTuple(ref elements) if elements.is_empty() => {
1a4d82fc
JJ
711 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
712 }
62682a34 713 ty::TyEnum(def_id, _) => {
1a4d82fc
JJ
714 prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span).finalize(cx)
715 }
62682a34
SL
716 ty::TyArray(typ, len) => {
717 fixed_vec_metadata(cx, unique_type_id, typ, Some(len as u64), usage_site_span)
718 }
719 ty::TySlice(typ) => {
720 fixed_vec_metadata(cx, unique_type_id, typ, None, usage_site_span)
85aaf69f 721 }
62682a34 722 ty::TyStr => {
85aaf69f 723 fixed_vec_metadata(cx, unique_type_id, cx.tcx().types.i8, None, usage_site_span)
1a4d82fc 724 }
62682a34 725 ty::TyTrait(..) => {
1a4d82fc
JJ
726 MetadataCreationResult::new(
727 trait_pointer_metadata(cx, t, None, unique_type_id),
728 false)
729 }
c1a9b12d
SL
730 ty::TyBox(ty) |
731 ty::TyRawPtr(ty::TypeAndMut{ty, ..}) |
732 ty::TyRef(_, ty::TypeAndMut{ty, ..}) => {
1a4d82fc 733 match ty.sty {
62682a34 734 ty::TySlice(typ) => {
1a4d82fc
JJ
735 vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span)
736 }
62682a34 737 ty::TyStr => {
1a4d82fc
JJ
738 vec_slice_metadata(cx, t, cx.tcx().types.u8, unique_type_id, usage_site_span)
739 }
62682a34 740 ty::TyTrait(..) => {
1a4d82fc
JJ
741 MetadataCreationResult::new(
742 trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
743 false)
744 }
745 _ => {
746 let pointee_metadata = type_metadata(cx, ty, usage_site_span);
747
748 match debug_context(cx).type_map
749 .borrow()
750 .find_metadata_for_unique_id(unique_type_id) {
751 Some(metadata) => return metadata,
752 None => { /* proceed normally */ }
753 };
754
755 MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
756 false)
757 }
758 }
759 }
62682a34 760 ty::TyBareFn(_, ref barefnty) => {
c1a9b12d
SL
761 let fn_metadata = subroutine_type_metadata(cx,
762 unique_type_id,
763 &barefnty.sig,
764 usage_site_span).metadata;
765 match debug_context(cx).type_map
766 .borrow()
767 .find_metadata_for_unique_id(unique_type_id) {
768 Some(metadata) => return metadata,
769 None => { /* proceed normally */ }
770 };
771
772 // This is actually a function pointer, so wrap it in pointer DI
773 MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false)
774
1a4d82fc 775 }
c1a9b12d
SL
776 ty::TyClosure(_, ref substs) => {
777 prepare_tuple_metadata(cx,
778 t,
779 &substs.upvar_tys,
780 unique_type_id,
781 usage_site_span).finalize(cx)
1a4d82fc 782 }
62682a34 783 ty::TyStruct(def_id, substs) => {
1a4d82fc
JJ
784 prepare_struct_metadata(cx,
785 t,
786 def_id,
787 substs,
788 unique_type_id,
789 usage_site_span).finalize(cx)
790 }
62682a34 791 ty::TyTuple(ref elements) => {
1a4d82fc
JJ
792 prepare_tuple_metadata(cx,
793 t,
85aaf69f 794 &elements[..],
1a4d82fc
JJ
795 unique_type_id,
796 usage_site_span).finalize(cx)
797 }
798 _ => {
799 cx.sess().bug(&format!("debuginfo: unexpected type in type_metadata: {:?}",
c34b1796 800 sty))
1a4d82fc
JJ
801 }
802 };
803
804 {
805 let mut type_map = debug_context(cx).type_map.borrow_mut();
806
807 if already_stored_in_typemap {
808 // Also make sure that we already have a TypeMap entry entry for the unique type id.
809 let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
810 Some(metadata) => metadata,
811 None => {
812 let unique_type_id_str =
813 type_map.get_unique_type_id_as_string(unique_type_id);
814 let error_message = format!("Expected type metadata for unique \
815 type id '{}' to already be in \
816 the debuginfo::TypeMap but it \
817 was not. (Ty = {})",
85aaf69f 818 &unique_type_id_str[..],
62682a34 819 t);
85aaf69f 820 cx.sess().span_bug(usage_site_span, &error_message[..]);
1a4d82fc
JJ
821 }
822 };
823
824 match type_map.find_metadata_for_type(t) {
825 Some(metadata) => {
826 if metadata != metadata_for_uid {
827 let unique_type_id_str =
828 type_map.get_unique_type_id_as_string(unique_type_id);
829 let error_message = format!("Mismatch between Ty and \
830 UniqueTypeId maps in \
831 debuginfo::TypeMap. \
832 UniqueTypeId={}, Ty={}",
85aaf69f 833 &unique_type_id_str[..],
62682a34 834 t);
85aaf69f 835 cx.sess().span_bug(usage_site_span, &error_message[..]);
1a4d82fc
JJ
836 }
837 }
838 None => {
839 type_map.register_type_with_metadata(cx, t, metadata);
840 }
841 }
842 } else {
843 type_map.register_type_with_metadata(cx, t, metadata);
844 type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata);
845 }
846 }
847
848 metadata
849}
850
d9579d0f
AL
851pub fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
852 match debug_context(cx).created_files.borrow().get(full_path) {
853 Some(file_metadata) => return *file_metadata,
854 None => ()
855 }
856
857 debug!("file_metadata: {}", full_path);
858
859 // FIXME (#9639): This needs to handle non-utf8 paths
860 let work_dir = cx.sess().working_dir.to_str().unwrap();
861 let file_name =
862 if full_path.starts_with(work_dir) {
863 &full_path[work_dir.len() + 1..full_path.len()]
864 } else {
865 full_path
866 };
867
868 let file_name = CString::new(file_name).unwrap();
869 let work_dir = CString::new(work_dir).unwrap();
870 let file_metadata = unsafe {
871 llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name.as_ptr(),
872 work_dir.as_ptr())
873 };
874
875 let mut created_files = debug_context(cx).created_files.borrow_mut();
876 created_files.insert(full_path.to_string(), file_metadata);
877 return file_metadata;
878}
879
880/// Finds the scope metadata node for the given AST node.
881pub fn scope_metadata(fcx: &FunctionContext,
882 node_id: ast::NodeId,
883 error_reporting_span: Span)
884 -> DIScope {
885 let scope_map = &fcx.debug_context
886 .get_ref(fcx.ccx, error_reporting_span)
887 .scope_map;
888 match scope_map.borrow().get(&node_id).cloned() {
889 Some(scope_metadata) => scope_metadata,
890 None => {
891 let node = fcx.ccx.tcx().map.get(node_id);
892
893 fcx.ccx.sess().span_bug(error_reporting_span,
894 &format!("debuginfo: Could not find scope info for node {:?}",
895 node));
896 }
897 }
898}
899
c1a9b12d 900pub fn diverging_type_metadata(cx: &CrateContext) -> DIType {
d9579d0f
AL
901 unsafe {
902 llvm::LLVMDIBuilderCreateBasicType(
903 DIB(cx),
904 "!\0".as_ptr() as *const _,
905 bytes_to_bits(0),
906 bytes_to_bits(0),
907 DW_ATE_unsigned)
908 }
909}
910
911fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
912 t: Ty<'tcx>) -> DIType {
913
914 debug!("basic_type_metadata: {:?}", t);
915
916 let (name, encoding) = match t.sty {
62682a34 917 ty::TyTuple(ref elements) if elements.is_empty() =>
d9579d0f 918 ("()".to_string(), DW_ATE_unsigned),
62682a34
SL
919 ty::TyBool => ("bool".to_string(), DW_ATE_boolean),
920 ty::TyChar => ("char".to_string(), DW_ATE_unsigned_char),
921 ty::TyInt(int_ty) => match int_ty {
d9579d0f
AL
922 ast::TyIs => ("isize".to_string(), DW_ATE_signed),
923 ast::TyI8 => ("i8".to_string(), DW_ATE_signed),
924 ast::TyI16 => ("i16".to_string(), DW_ATE_signed),
925 ast::TyI32 => ("i32".to_string(), DW_ATE_signed),
926 ast::TyI64 => ("i64".to_string(), DW_ATE_signed)
927 },
62682a34 928 ty::TyUint(uint_ty) => match uint_ty {
d9579d0f
AL
929 ast::TyUs => ("usize".to_string(), DW_ATE_unsigned),
930 ast::TyU8 => ("u8".to_string(), DW_ATE_unsigned),
931 ast::TyU16 => ("u16".to_string(), DW_ATE_unsigned),
932 ast::TyU32 => ("u32".to_string(), DW_ATE_unsigned),
933 ast::TyU64 => ("u64".to_string(), DW_ATE_unsigned)
934 },
62682a34 935 ty::TyFloat(float_ty) => match float_ty {
d9579d0f
AL
936 ast::TyF32 => ("f32".to_string(), DW_ATE_float),
937 ast::TyF64 => ("f64".to_string(), DW_ATE_float),
938 },
939 _ => cx.sess().bug("debuginfo::basic_type_metadata - t is invalid type")
940 };
941
942 let llvm_type = type_of::type_of(cx, t);
943 let (size, align) = size_and_align_of(cx, llvm_type);
944 let name = CString::new(name).unwrap();
945 let ty_metadata = unsafe {
946 llvm::LLVMDIBuilderCreateBasicType(
947 DIB(cx),
948 name.as_ptr(),
949 bytes_to_bits(size),
950 bytes_to_bits(align),
951 encoding)
952 };
953
954 return ty_metadata;
955}
956
957fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
958 pointer_type: Ty<'tcx>,
959 pointee_type_metadata: DIType)
960 -> DIType {
961 let pointer_llvm_type = type_of::type_of(cx, pointer_type);
962 let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
963 let name = compute_debuginfo_type_name(cx, pointer_type, false);
964 let name = CString::new(name).unwrap();
965 let ptr_metadata = unsafe {
966 llvm::LLVMDIBuilderCreatePointerType(
967 DIB(cx),
968 pointee_type_metadata,
969 bytes_to_bits(pointer_size),
970 bytes_to_bits(pointer_align),
971 name.as_ptr())
972 };
973 return ptr_metadata;
974}
975
976pub fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
977 let work_dir = &cx.sess().working_dir;
978 let compile_unit_name = match cx.sess().local_crate_source_file {
979 None => fallback_path(cx),
980 Some(ref abs_path) => {
981 if abs_path.is_relative() {
982 cx.sess().warn("debuginfo: Invalid path to crate's local root source file!");
983 fallback_path(cx)
984 } else {
985 match abs_path.relative_from(work_dir) {
986 Some(ref p) if p.is_relative() => {
987 if p.starts_with(Path::new("./")) {
988 path2cstr(p)
989 } else {
990 path2cstr(&Path::new(".").join(p))
991 }
992 }
993 _ => fallback_path(cx)
994 }
995 }
996 }
997 };
998
999 debug!("compile_unit_metadata: {:?}", compile_unit_name);
1000 let producer = format!("rustc version {}",
1001 (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
1002
1003 let compile_unit_name = compile_unit_name.as_ptr();
1004 let work_dir = path2cstr(&work_dir);
1005 let producer = CString::new(producer).unwrap();
1006 let flags = "\0";
1007 let split_name = "\0";
1008 return unsafe {
1009 llvm::LLVMDIBuilderCreateCompileUnit(
1010 debug_context(cx).builder,
1011 DW_LANG_RUST,
1012 compile_unit_name,
1013 work_dir.as_ptr(),
1014 producer.as_ptr(),
1015 cx.sess().opts.optimize != config::No,
1016 flags.as_ptr() as *const _,
1017 0,
1018 split_name.as_ptr() as *const _)
1019 };
1020
1021 fn fallback_path(cx: &CrateContext) -> CString {
1022 CString::new(cx.link_meta().crate_name.clone()).unwrap()
1023 }
1024}
1025
1a4d82fc
JJ
1026struct MetadataCreationResult {
1027 metadata: DIType,
1028 already_stored_in_typemap: bool
1029}
1030
1031impl MetadataCreationResult {
1032 fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationResult {
1033 MetadataCreationResult {
1034 metadata: metadata,
1035 already_stored_in_typemap: already_stored_in_typemap
1036 }
1037 }
1038}
1039
d9579d0f
AL
1040#[derive(Debug)]
1041enum MemberOffset {
1042 FixedMemberOffset { bytes: usize },
1043 // For ComputedMemberOffset, the offset is read from the llvm type definition.
1044 ComputedMemberOffset
1045}
1046
1047// Description of a type member, which can either be a regular field (as in
1048// structs or tuples) or an enum variant.
1049#[derive(Debug)]
1050struct MemberDescription {
1051 name: String,
1052 llvm_type: Type,
1053 type_metadata: DIType,
1054 offset: MemberOffset,
1055 flags: c_uint
1056}
1057
1058// A factory for MemberDescriptions. It produces a list of member descriptions
1059// for some record-like type. MemberDescriptionFactories are used to defer the
1060// creation of type member descriptions in order to break cycles arising from
1061// recursive type definitions.
1062enum MemberDescriptionFactory<'tcx> {
1063 StructMDF(StructMemberDescriptionFactory<'tcx>),
1064 TupleMDF(TupleMemberDescriptionFactory<'tcx>),
1065 EnumMDF(EnumMemberDescriptionFactory<'tcx>),
1066 VariantMDF(VariantMemberDescriptionFactory<'tcx>)
1067}
1068
1069impl<'tcx> MemberDescriptionFactory<'tcx> {
1070 fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1071 -> Vec<MemberDescription> {
1072 match *self {
1073 StructMDF(ref this) => {
1074 this.create_member_descriptions(cx)
1075 }
1076 TupleMDF(ref this) => {
1077 this.create_member_descriptions(cx)
1078 }
1079 EnumMDF(ref this) => {
1080 this.create_member_descriptions(cx)
1081 }
1082 VariantMDF(ref this) => {
1083 this.create_member_descriptions(cx)
1084 }
1085 }
1086 }
1087}
1088
1089//=-----------------------------------------------------------------------------
1090// Structs
1091//=-----------------------------------------------------------------------------
1092
1093// Creates MemberDescriptions for the fields of a struct
1094struct StructMemberDescriptionFactory<'tcx> {
c1a9b12d 1095 fields: Vec<ty::Field<'tcx>>,
d9579d0f
AL
1096 is_simd: bool,
1097 span: Span,
1098}
1099
1100impl<'tcx> StructMemberDescriptionFactory<'tcx> {
1101 fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1102 -> Vec<MemberDescription> {
1103 if self.fields.is_empty() {
1104 return Vec::new();
1105 }
1106
1107 let field_size = if self.is_simd {
1108 machine::llsize_of_alloc(cx, type_of::type_of(cx, self.fields[0].mt.ty)) as usize
1109 } else {
1110 0xdeadbeef
1111 };
1112
1113 self.fields.iter().enumerate().map(|(i, field)| {
1114 let name = if field.name == special_idents::unnamed_field.name {
1115 format!("__{}", i)
1116 } else {
c1a9b12d 1117 field.name.to_string()
d9579d0f 1118 };
1a4d82fc 1119
d9579d0f
AL
1120 let offset = if self.is_simd {
1121 assert!(field_size != 0xdeadbeef);
1122 FixedMemberOffset { bytes: i * field_size }
1123 } else {
1124 ComputedMemberOffset
1125 };
1126
1127 MemberDescription {
1128 name: name,
1129 llvm_type: type_of::type_of(cx, field.mt.ty),
1130 type_metadata: type_metadata(cx, field.mt.ty, self.span),
1131 offset: offset,
1132 flags: FLAGS_NONE,
1133 }
1134 }).collect()
1a4d82fc
JJ
1135 }
1136}
1137
1a4d82fc 1138
d9579d0f
AL
1139fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1140 struct_type: Ty<'tcx>,
1141 def_id: ast::DefId,
1142 substs: &subst::Substs<'tcx>,
1143 unique_type_id: UniqueTypeId,
1144 span: Span)
1145 -> RecursiveTypeDescription<'tcx> {
1146 let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
1147 let struct_llvm_type = type_of::in_memory_type_of(cx, struct_type);
1148
1149 let (containing_scope, _) = get_namespace_and_span_for_item(cx, def_id);
1a4d82fc 1150
d9579d0f
AL
1151 let struct_metadata_stub = create_struct_stub(cx,
1152 struct_llvm_type,
1153 &struct_name,
1154 unique_type_id,
1155 containing_scope);
85aaf69f 1156
c1a9b12d 1157 let mut fields = cx.tcx().struct_fields(def_id, substs);
1a4d82fc 1158
d9579d0f 1159 // The `Ty` values returned by `ty::struct_fields` can still contain
62682a34 1160 // `TyProjection` variants, so normalize those away.
d9579d0f
AL
1161 for field in &mut fields {
1162 field.mt.ty = monomorphize::normalize_associated_type(cx.tcx(), &field.mt.ty);
1a4d82fc
JJ
1163 }
1164
d9579d0f
AL
1165 create_and_register_recursive_type_forward_declaration(
1166 cx,
1167 struct_type,
1168 unique_type_id,
1169 struct_metadata_stub,
1170 struct_llvm_type,
1171 StructMDF(StructMemberDescriptionFactory {
1172 fields: fields,
c1a9b12d 1173 is_simd: struct_type.is_simd(cx.tcx()),
d9579d0f
AL
1174 span: span,
1175 })
1176 )
1a4d82fc
JJ
1177}
1178
d9579d0f 1179
1a4d82fc 1180//=-----------------------------------------------------------------------------
d9579d0f 1181// Tuples
1a4d82fc
JJ
1182//=-----------------------------------------------------------------------------
1183
d9579d0f
AL
1184// Creates MemberDescriptions for the fields of a tuple
1185struct TupleMemberDescriptionFactory<'tcx> {
1186 component_types: Vec<Ty<'tcx>>,
1187 span: Span,
1a4d82fc
JJ
1188}
1189
d9579d0f
AL
1190impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
1191 fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1192 -> Vec<MemberDescription> {
1193 self.component_types
1194 .iter()
1195 .enumerate()
1196 .map(|(i, &component_type)| {
1197 MemberDescription {
1198 name: format!("__{}", i),
1199 llvm_type: type_of::type_of(cx, component_type),
1200 type_metadata: type_metadata(cx, component_type, self.span),
1201 offset: ComputedMemberOffset,
1202 flags: FLAGS_NONE,
1203 }
1204 }).collect()
1205 }
1a4d82fc
JJ
1206}
1207
d9579d0f
AL
1208fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1209 tuple_type: Ty<'tcx>,
1210 component_types: &[Ty<'tcx>],
1211 unique_type_id: UniqueTypeId,
1212 span: Span)
1213 -> RecursiveTypeDescription<'tcx> {
1214 let tuple_name = compute_debuginfo_type_name(cx, tuple_type, false);
1215 let tuple_llvm_type = type_of::type_of(cx, tuple_type);
1a4d82fc 1216
d9579d0f
AL
1217 create_and_register_recursive_type_forward_declaration(
1218 cx,
1219 tuple_type,
1220 unique_type_id,
1221 create_struct_stub(cx,
1222 tuple_llvm_type,
1223 &tuple_name[..],
1224 unique_type_id,
1225 UNKNOWN_SCOPE_METADATA),
1226 tuple_llvm_type,
1227 TupleMDF(TupleMemberDescriptionFactory {
1228 component_types: component_types.to_vec(),
1229 span: span,
1230 })
1231 )
1a4d82fc
JJ
1232}
1233
1a4d82fc 1234
d9579d0f
AL
1235//=-----------------------------------------------------------------------------
1236// Enums
1237//=-----------------------------------------------------------------------------
1a4d82fc 1238
d9579d0f
AL
1239// Describes the members of an enum value: An enum is described as a union of
1240// structs in DWARF. This MemberDescriptionFactory provides the description for
1241// the members of this union; so for every variant of the given enum, this
1242// factory will produce one MemberDescription (all with no name and a fixed
1243// offset of zero bytes).
1244struct EnumMemberDescriptionFactory<'tcx> {
1245 enum_type: Ty<'tcx>,
1246 type_rep: Rc<adt::Repr<'tcx>>,
1247 variants: Rc<Vec<Rc<ty::VariantInfo<'tcx>>>>,
1248 discriminant_type_metadata: Option<DIType>,
1249 containing_scope: DIScope,
1250 file_metadata: DIFile,
1251 span: Span,
1a4d82fc
JJ
1252}
1253
d9579d0f
AL
1254impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
1255 fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1256 -> Vec<MemberDescription> {
1257 match *self.type_rep {
1258 adt::General(_, ref struct_defs, _) => {
1259 let discriminant_info = RegularDiscriminant(self.discriminant_type_metadata
1260 .expect(""));
1a4d82fc 1261
d9579d0f
AL
1262 struct_defs
1263 .iter()
1264 .enumerate()
1265 .map(|(i, struct_def)| {
1266 let (variant_type_metadata,
1267 variant_llvm_type,
1268 member_desc_factory) =
1269 describe_enum_variant(cx,
1270 self.enum_type,
1271 struct_def,
c1a9b12d 1272 &*self.variants[i],
d9579d0f
AL
1273 discriminant_info,
1274 self.containing_scope,
1275 self.span);
1a4d82fc 1276
d9579d0f
AL
1277 let member_descriptions = member_desc_factory
1278 .create_member_descriptions(cx);
1a4d82fc 1279
d9579d0f
AL
1280 set_members_of_composite_type(cx,
1281 variant_type_metadata,
1282 variant_llvm_type,
1283 &member_descriptions);
1284 MemberDescription {
1285 name: "".to_string(),
1286 llvm_type: variant_llvm_type,
1287 type_metadata: variant_type_metadata,
1288 offset: FixedMemberOffset { bytes: 0 },
1289 flags: FLAGS_NONE
1290 }
1291 }).collect()
1292 },
1293 adt::Univariant(ref struct_def, _) => {
1294 assert!(self.variants.len() <= 1);
1a4d82fc 1295
d9579d0f
AL
1296 if self.variants.is_empty() {
1297 vec![]
1298 } else {
1299 let (variant_type_metadata,
1300 variant_llvm_type,
1301 member_description_factory) =
1302 describe_enum_variant(cx,
1303 self.enum_type,
1304 struct_def,
c1a9b12d 1305 &*self.variants[0],
d9579d0f
AL
1306 NoDiscriminant,
1307 self.containing_scope,
1308 self.span);
1a4d82fc 1309
d9579d0f
AL
1310 let member_descriptions =
1311 member_description_factory.create_member_descriptions(cx);
1a4d82fc 1312
d9579d0f
AL
1313 set_members_of_composite_type(cx,
1314 variant_type_metadata,
1315 variant_llvm_type,
1316 &member_descriptions[..]);
1317 vec![
1318 MemberDescription {
1319 name: "".to_string(),
1320 llvm_type: variant_llvm_type,
1321 type_metadata: variant_type_metadata,
1322 offset: FixedMemberOffset { bytes: 0 },
1323 flags: FLAGS_NONE
1324 }
1325 ]
1326 }
1327 }
1328 adt::RawNullablePointer { nndiscr: non_null_variant_index, nnty, .. } => {
1329 // As far as debuginfo is concerned, the pointer this enum
1330 // represents is still wrapped in a struct. This is to make the
1331 // DWARF representation of enums uniform.
1a4d82fc 1332
d9579d0f 1333 // First create a description of the artificial wrapper struct:
c1a9b12d
SL
1334 let non_null_variant = &self.variants[non_null_variant_index as usize];
1335 let non_null_variant_name = non_null_variant.name.as_str();
1a4d82fc 1336
d9579d0f
AL
1337 // The llvm type and metadata of the pointer
1338 let non_null_llvm_type = type_of::type_of(cx, nnty);
1339 let non_null_type_metadata = type_metadata(cx, nnty, self.span);
1a4d82fc 1340
d9579d0f
AL
1341 // The type of the artificial struct wrapping the pointer
1342 let artificial_struct_llvm_type = Type::struct_(cx,
1343 &[non_null_llvm_type],
1344 false);
1a4d82fc 1345
d9579d0f
AL
1346 // For the metadata of the wrapper struct, we need to create a
1347 // MemberDescription of the struct's single field.
1348 let sole_struct_member_description = MemberDescription {
1349 name: match non_null_variant.arg_names {
c1a9b12d 1350 Some(ref names) => names[0].to_string(),
d9579d0f
AL
1351 None => "__0".to_string()
1352 },
1353 llvm_type: non_null_llvm_type,
1354 type_metadata: non_null_type_metadata,
1355 offset: FixedMemberOffset { bytes: 0 },
1356 flags: FLAGS_NONE
1357 };
1a4d82fc 1358
d9579d0f
AL
1359 let unique_type_id = debug_context(cx).type_map
1360 .borrow_mut()
1361 .get_unique_type_id_of_enum_variant(
1362 cx,
1363 self.enum_type,
1364 &non_null_variant_name);
1a4d82fc 1365
d9579d0f
AL
1366 // Now we can create the metadata of the artificial struct
1367 let artificial_struct_metadata =
1368 composite_type_metadata(cx,
1369 artificial_struct_llvm_type,
1370 &non_null_variant_name,
1371 unique_type_id,
1372 &[sole_struct_member_description],
1373 self.containing_scope,
1374 self.file_metadata,
1375 codemap::DUMMY_SP);
1a4d82fc 1376
d9579d0f
AL
1377 // Encode the information about the null variant in the union
1378 // member's name.
1379 let null_variant_index = (1 - non_null_variant_index) as usize;
c1a9b12d 1380 let null_variant_name = self.variants[null_variant_index].name;
d9579d0f
AL
1381 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
1382 0,
1383 null_variant_name);
1a4d82fc 1384
d9579d0f
AL
1385 // Finally create the (singleton) list of descriptions of union
1386 // members.
1387 vec![
1388 MemberDescription {
1389 name: union_member_name,
1390 llvm_type: artificial_struct_llvm_type,
1391 type_metadata: artificial_struct_metadata,
1392 offset: FixedMemberOffset { bytes: 0 },
1393 flags: FLAGS_NONE
1394 }
1395 ]
1396 },
1397 adt::StructWrappedNullablePointer { nonnull: ref struct_def,
1398 nndiscr,
1399 ref discrfield, ..} => {
1400 // Create a description of the non-null variant
1401 let (variant_type_metadata, variant_llvm_type, member_description_factory) =
1402 describe_enum_variant(cx,
1403 self.enum_type,
1404 struct_def,
c1a9b12d 1405 &*self.variants[nndiscr as usize],
d9579d0f
AL
1406 OptimizedDiscriminant,
1407 self.containing_scope,
1408 self.span);
1a4d82fc 1409
d9579d0f
AL
1410 let variant_member_descriptions =
1411 member_description_factory.create_member_descriptions(cx);
1a4d82fc 1412
d9579d0f
AL
1413 set_members_of_composite_type(cx,
1414 variant_type_metadata,
1415 variant_llvm_type,
1416 &variant_member_descriptions[..]);
1a4d82fc 1417
d9579d0f
AL
1418 // Encode the information about the null variant in the union
1419 // member's name.
1420 let null_variant_index = (1 - nndiscr) as usize;
c1a9b12d 1421 let null_variant_name = self.variants[null_variant_index].name;
d9579d0f
AL
1422 let discrfield = discrfield.iter()
1423 .skip(1)
1424 .map(|x| x.to_string())
c1a9b12d 1425 .collect::<Vec<_>>().join("$");
d9579d0f
AL
1426 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
1427 discrfield,
1428 null_variant_name);
1a4d82fc 1429
d9579d0f
AL
1430 // Create the (singleton) list of descriptions of union members.
1431 vec![
1432 MemberDescription {
1433 name: union_member_name,
1434 llvm_type: variant_llvm_type,
1435 type_metadata: variant_type_metadata,
1436 offset: FixedMemberOffset { bytes: 0 },
1437 flags: FLAGS_NONE
1438 }
1439 ]
1440 },
1441 adt::CEnum(..) => cx.sess().span_bug(self.span, "This should be unreachable.")
1a4d82fc
JJ
1442 }
1443 }
d9579d0f 1444}
1a4d82fc 1445
d9579d0f
AL
1446// Creates MemberDescriptions for the fields of a single enum variant.
1447struct VariantMemberDescriptionFactory<'tcx> {
1448 args: Vec<(String, Ty<'tcx>)>,
1449 discriminant_type_metadata: Option<DIType>,
1450 span: Span,
1451}
1a4d82fc 1452
d9579d0f
AL
1453impl<'tcx> VariantMemberDescriptionFactory<'tcx> {
1454 fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1455 -> Vec<MemberDescription> {
1456 self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
1457 MemberDescription {
1458 name: name.to_string(),
1459 llvm_type: type_of::type_of(cx, ty),
1460 type_metadata: match self.discriminant_type_metadata {
1461 Some(metadata) if i == 0 => metadata,
1462 _ => type_metadata(cx, ty, self.span)
1463 },
1464 offset: ComputedMemberOffset,
1465 flags: FLAGS_NONE
1a4d82fc 1466 }
d9579d0f 1467 }).collect()
1a4d82fc 1468 }
d9579d0f 1469}
1a4d82fc 1470
d9579d0f
AL
1471#[derive(Copy, Clone)]
1472enum EnumDiscriminantInfo {
1473 RegularDiscriminant(DIType),
1474 OptimizedDiscriminant,
1475 NoDiscriminant
1476}
1a4d82fc 1477
d9579d0f
AL
1478// Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type
1479// of the variant, and (3) a MemberDescriptionFactory for producing the
1480// descriptions of the fields of the variant. This is a rudimentary version of a
1481// full RecursiveTypeDescription.
1482fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1483 enum_type: Ty<'tcx>,
1484 struct_def: &adt::Struct<'tcx>,
1485 variant_info: &ty::VariantInfo<'tcx>,
1486 discriminant_info: EnumDiscriminantInfo,
1487 containing_scope: DIScope,
1488 span: Span)
1489 -> (DICompositeType, Type, MemberDescriptionFactory<'tcx>) {
1490 let variant_llvm_type =
1491 Type::struct_(cx, &struct_def.fields
1492 .iter()
1493 .map(|&t| type_of::type_of(cx, t))
1494 .collect::<Vec<_>>()
1495 ,
1496 struct_def.packed);
1497 // Could do some consistency checks here: size, align, field count, discr type
1a4d82fc 1498
c1a9b12d 1499 let variant_name = variant_info.name.as_str();
d9579d0f
AL
1500 let unique_type_id = debug_context(cx).type_map
1501 .borrow_mut()
1502 .get_unique_type_id_of_enum_variant(
1503 cx,
1504 enum_type,
c1a9b12d 1505 &variant_name);
1a4d82fc 1506
d9579d0f
AL
1507 let metadata_stub = create_struct_stub(cx,
1508 variant_llvm_type,
c1a9b12d 1509 &variant_name,
d9579d0f
AL
1510 unique_type_id,
1511 containing_scope);
1a4d82fc 1512
d9579d0f
AL
1513 // Get the argument names from the enum variant info
1514 let mut arg_names: Vec<_> = match variant_info.arg_names {
1515 Some(ref names) => {
1516 names.iter()
c1a9b12d 1517 .map(|name| name.to_string())
d9579d0f
AL
1518 .collect()
1519 }
1520 None => {
1521 variant_info.args
1522 .iter()
1523 .enumerate()
1524 .map(|(i, _)| format!("__{}", i))
1525 .collect()
1526 }
1527 };
1a4d82fc 1528
d9579d0f
AL
1529 // If this is not a univariant enum, there is also the discriminant field.
1530 match discriminant_info {
1531 RegularDiscriminant(_) => arg_names.insert(0, "RUST$ENUM$DISR".to_string()),
1532 _ => { /* do nothing */ }
1533 };
1a4d82fc 1534
d9579d0f
AL
1535 // Build an array of (field name, field type) pairs to be captured in the factory closure.
1536 let args: Vec<(String, Ty)> = arg_names.iter()
62682a34 1537 .zip(&struct_def.fields)
d9579d0f
AL
1538 .map(|(s, &t)| (s.to_string(), t))
1539 .collect();
1a4d82fc 1540
d9579d0f
AL
1541 let member_description_factory =
1542 VariantMDF(VariantMemberDescriptionFactory {
1543 args: args,
1544 discriminant_type_metadata: match discriminant_info {
1545 RegularDiscriminant(discriminant_type_metadata) => {
1546 Some(discriminant_type_metadata)
1a4d82fc 1547 }
d9579d0f
AL
1548 _ => None
1549 },
1550 span: span,
1551 });
1a4d82fc 1552
d9579d0f
AL
1553 (metadata_stub, variant_llvm_type, member_description_factory)
1554}
1a4d82fc 1555
d9579d0f
AL
1556fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1557 enum_type: Ty<'tcx>,
1558 enum_def_id: ast::DefId,
1559 unique_type_id: UniqueTypeId,
1560 span: Span)
1561 -> RecursiveTypeDescription<'tcx> {
1562 let enum_name = compute_debuginfo_type_name(cx, enum_type, false);
1a4d82fc 1563
d9579d0f
AL
1564 let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, enum_def_id);
1565 let loc = span_start(cx, definition_span);
1566 let file_metadata = file_metadata(cx, &loc.file.name);
1a4d82fc 1567
c1a9b12d 1568 let variants = cx.tcx().enum_variants(enum_def_id);
1a4d82fc 1569
d9579d0f
AL
1570 let enumerators_metadata: Vec<DIDescriptor> = variants
1571 .iter()
1572 .map(|v| {
c1a9b12d 1573 let token = v.name.as_str();
d9579d0f
AL
1574 let name = CString::new(token.as_bytes()).unwrap();
1575 unsafe {
1576 llvm::LLVMDIBuilderCreateEnumerator(
1577 DIB(cx),
1578 name.as_ptr(),
1579 v.disr_val as u64)
1a4d82fc 1580 }
d9579d0f
AL
1581 })
1582 .collect();
1a4d82fc 1583
d9579d0f 1584 let discriminant_type_metadata = |inttype| {
c1a9b12d 1585 let disr_type_key = (enum_def_id, inttype);
d9579d0f
AL
1586 let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
1587 .borrow()
c1a9b12d 1588 .get(&disr_type_key).cloned();
d9579d0f
AL
1589 match cached_discriminant_type_metadata {
1590 Some(discriminant_type_metadata) => discriminant_type_metadata,
1591 None => {
1592 let discriminant_llvm_type = adt::ll_inttype(cx, inttype);
1593 let (discriminant_size, discriminant_align) =
1594 size_and_align_of(cx, discriminant_llvm_type);
1595 let discriminant_base_type_metadata =
1596 type_metadata(cx,
1597 adt::ty_of_inttype(cx.tcx(), inttype),
1598 codemap::DUMMY_SP);
1599 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
1a4d82fc 1600
d9579d0f
AL
1601 let name = CString::new(discriminant_name.as_bytes()).unwrap();
1602 let discriminant_type_metadata = unsafe {
1603 llvm::LLVMDIBuilderCreateEnumerationType(
1604 DIB(cx),
1605 containing_scope,
1606 name.as_ptr(),
1607 UNKNOWN_FILE_METADATA,
1608 UNKNOWN_LINE_NUMBER,
1609 bytes_to_bits(discriminant_size),
1610 bytes_to_bits(discriminant_align),
1611 create_DIArray(DIB(cx), &enumerators_metadata),
1612 discriminant_base_type_metadata)
1613 };
1a4d82fc 1614
d9579d0f
AL
1615 debug_context(cx).created_enum_disr_types
1616 .borrow_mut()
c1a9b12d 1617 .insert(disr_type_key, discriminant_type_metadata);
1a4d82fc 1618
d9579d0f 1619 discriminant_type_metadata
1a4d82fc
JJ
1620 }
1621 }
d9579d0f 1622 };
1a4d82fc 1623
d9579d0f 1624 let type_rep = adt::represent_type(cx, enum_type);
1a4d82fc 1625
d9579d0f
AL
1626 let discriminant_type_metadata = match *type_rep {
1627 adt::CEnum(inttype, _, _) => {
1628 return FinalMetadata(discriminant_type_metadata(inttype))
1629 },
1630 adt::RawNullablePointer { .. } |
1631 adt::StructWrappedNullablePointer { .. } |
1632 adt::Univariant(..) => None,
1633 adt::General(inttype, _, _) => Some(discriminant_type_metadata(inttype)),
1634 };
1a4d82fc 1635
d9579d0f
AL
1636 let enum_llvm_type = type_of::type_of(cx, enum_type);
1637 let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
1a4d82fc 1638
d9579d0f
AL
1639 let unique_type_id_str = debug_context(cx)
1640 .type_map
1641 .borrow()
1642 .get_unique_type_id_as_string(unique_type_id);
1a4d82fc 1643
d9579d0f
AL
1644 let enum_name = CString::new(enum_name).unwrap();
1645 let unique_type_id_str = CString::new(unique_type_id_str.as_bytes()).unwrap();
1646 let enum_metadata = unsafe {
1647 llvm::LLVMDIBuilderCreateUnionType(
1648 DIB(cx),
1649 containing_scope,
1650 enum_name.as_ptr(),
62682a34 1651 file_metadata,
d9579d0f
AL
1652 UNKNOWN_LINE_NUMBER,
1653 bytes_to_bits(enum_type_size),
1654 bytes_to_bits(enum_type_align),
1655 0, // Flags
1656 ptr::null_mut(),
1657 0, // RuntimeLang
1658 unique_type_id_str.as_ptr())
1659 };
1a4d82fc 1660
d9579d0f
AL
1661 return create_and_register_recursive_type_forward_declaration(
1662 cx,
1663 enum_type,
1664 unique_type_id,
1665 enum_metadata,
1666 enum_llvm_type,
1667 EnumMDF(EnumMemberDescriptionFactory {
1668 enum_type: enum_type,
1669 type_rep: type_rep.clone(),
1670 variants: variants,
1671 discriminant_type_metadata: discriminant_type_metadata,
1672 containing_scope: containing_scope,
1673 file_metadata: file_metadata,
1674 span: span,
1675 }),
1676 );
1a4d82fc 1677
d9579d0f
AL
1678 fn get_enum_discriminant_name(cx: &CrateContext,
1679 def_id: ast::DefId)
1680 -> token::InternedString {
1681 let name = if def_id.krate == ast::LOCAL_CRATE {
1682 cx.tcx().map.get_path_elem(def_id.node).name()
1683 } else {
1684 csearch::get_item_path(cx.tcx(), def_id).last().unwrap().name()
1685 };
1a4d82fc 1686
c1a9b12d 1687 name.as_str()
d9579d0f
AL
1688 }
1689}
1a4d82fc 1690
d9579d0f
AL
1691/// Creates debug information for a composite type, that is, anything that
1692/// results in a LLVM struct.
1693///
1694/// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
1695fn composite_type_metadata(cx: &CrateContext,
1696 composite_llvm_type: Type,
1697 composite_type_name: &str,
1698 composite_type_unique_id: UniqueTypeId,
1699 member_descriptions: &[MemberDescription],
1700 containing_scope: DIScope,
1a4d82fc 1701
d9579d0f
AL
1702 // Ignore source location information as long as it
1703 // can't be reconstructed for non-local crates.
1704 _file_metadata: DIFile,
1705 _definition_span: Span)
1706 -> DICompositeType {
1707 // Create the (empty) struct metadata node ...
1708 let composite_type_metadata = create_struct_stub(cx,
1709 composite_llvm_type,
1710 composite_type_name,
1711 composite_type_unique_id,
1712 containing_scope);
1713 // ... and immediately create and add the member descriptions.
1714 set_members_of_composite_type(cx,
1715 composite_type_metadata,
1716 composite_llvm_type,
1717 member_descriptions);
1a4d82fc 1718
d9579d0f
AL
1719 return composite_type_metadata;
1720}
1a4d82fc 1721
d9579d0f
AL
1722fn set_members_of_composite_type(cx: &CrateContext,
1723 composite_type_metadata: DICompositeType,
1724 composite_llvm_type: Type,
1725 member_descriptions: &[MemberDescription]) {
1726 // In some rare cases LLVM metadata uniquing would lead to an existing type
1727 // description being used instead of a new one created in
1728 // create_struct_stub. This would cause a hard to trace assertion in
1729 // DICompositeType::SetTypeArray(). The following check makes sure that we
1730 // get a better error message if this should happen again due to some
1731 // regression.
1732 {
1733 let mut composite_types_completed =
1734 debug_context(cx).composite_types_completed.borrow_mut();
1735 if composite_types_completed.contains(&composite_type_metadata) {
1736 cx.sess().bug("debuginfo::set_members_of_composite_type() - \
1737 Already completed forward declaration re-encountered.");
1738 } else {
1739 composite_types_completed.insert(composite_type_metadata);
1740 }
1741 }
1a4d82fc 1742
d9579d0f
AL
1743 let member_metadata: Vec<DIDescriptor> = member_descriptions
1744 .iter()
1745 .enumerate()
1746 .map(|(i, member_description)| {
1747 let (member_size, member_align) = size_and_align_of(cx, member_description.llvm_type);
1748 let member_offset = match member_description.offset {
1749 FixedMemberOffset { bytes } => bytes as u64,
1750 ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
1751 };
1a4d82fc 1752
d9579d0f
AL
1753 let member_name = member_description.name.as_bytes();
1754 let member_name = CString::new(member_name).unwrap();
1755 unsafe {
1756 llvm::LLVMDIBuilderCreateMemberType(
1757 DIB(cx),
1758 composite_type_metadata,
1759 member_name.as_ptr(),
1760 UNKNOWN_FILE_METADATA,
1761 UNKNOWN_LINE_NUMBER,
1762 bytes_to_bits(member_size),
1763 bytes_to_bits(member_align),
1764 bytes_to_bits(member_offset),
1765 member_description.flags,
1766 member_description.type_metadata)
1a4d82fc 1767 }
d9579d0f
AL
1768 })
1769 .collect();
1a4d82fc 1770
d9579d0f
AL
1771 unsafe {
1772 let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
1773 llvm::LLVMDICompositeTypeSetTypeArray(DIB(cx), composite_type_metadata, type_array);
1774 }
1775}
1a4d82fc 1776
d9579d0f
AL
1777// A convenience wrapper around LLVMDIBuilderCreateStructType(). Does not do any
1778// caching, does not add any fields to the struct. This can be done later with
1779// set_members_of_composite_type().
1780fn create_struct_stub(cx: &CrateContext,
1781 struct_llvm_type: Type,
1782 struct_type_name: &str,
1783 unique_type_id: UniqueTypeId,
1784 containing_scope: DIScope)
1785 -> DICompositeType {
1786 let (struct_size, struct_align) = size_and_align_of(cx, struct_llvm_type);
1a4d82fc 1787
d9579d0f
AL
1788 let unique_type_id_str = debug_context(cx).type_map
1789 .borrow()
1790 .get_unique_type_id_as_string(unique_type_id);
1791 let name = CString::new(struct_type_name).unwrap();
1792 let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
1793 let metadata_stub = unsafe {
1794 // LLVMDIBuilderCreateStructType() wants an empty array. A null
1795 // pointer will lead to hard to trace and debug LLVM assertions
1796 // later on in llvm/lib/IR/Value.cpp.
1797 let empty_array = create_DIArray(DIB(cx), &[]);
1a4d82fc 1798
d9579d0f
AL
1799 llvm::LLVMDIBuilderCreateStructType(
1800 DIB(cx),
1801 containing_scope,
1802 name.as_ptr(),
1803 UNKNOWN_FILE_METADATA,
1804 UNKNOWN_LINE_NUMBER,
1805 bytes_to_bits(struct_size),
1806 bytes_to_bits(struct_align),
1807 0,
1808 ptr::null_mut(),
1809 empty_array,
1810 0,
1811 ptr::null_mut(),
1812 unique_type_id.as_ptr())
1813 };
1a4d82fc 1814
d9579d0f
AL
1815 return metadata_stub;
1816}
1a4d82fc 1817
d9579d0f
AL
1818/// Creates debug information for the given global variable.
1819///
1820/// Adds the created metadata nodes directly to the crate's IR.
1821pub fn create_global_var_metadata(cx: &CrateContext,
1822 node_id: ast::NodeId,
1823 global: ValueRef) {
1824 if cx.dbg_cx().is_none() {
1825 return;
1826 }
1a4d82fc 1827
d9579d0f
AL
1828 // Don't create debuginfo for globals inlined from other crates. The other
1829 // crate should already contain debuginfo for it. More importantly, the
1830 // global might not even exist in un-inlined form anywhere which would lead
1831 // to a linker errors.
1832 if cx.external_srcs().borrow().contains_key(&node_id) {
1833 return;
1834 }
1a4d82fc 1835
d9579d0f 1836 let var_item = cx.tcx().map.get(node_id);
1a4d82fc 1837
d9579d0f
AL
1838 let (name, span) = match var_item {
1839 ast_map::NodeItem(item) => {
1840 match item.node {
1841 ast::ItemStatic(..) => (item.ident.name, item.span),
1842 ast::ItemConst(..) => (item.ident.name, item.span),
1843 _ => {
1844 cx.sess()
1845 .span_bug(item.span,
1846 &format!("debuginfo::\
1847 create_global_var_metadata() -
1848 Captured var-id refers to \
1849 unexpected ast_item variant: {:?}",
1850 var_item))
1a4d82fc
JJ
1851 }
1852 }
d9579d0f
AL
1853 },
1854 _ => cx.sess().bug(&format!("debuginfo::create_global_var_metadata() \
1855 - Captured var-id refers to unexpected \
1856 ast_map variant: {:?}",
1857 var_item))
1858 };
1a4d82fc 1859
d9579d0f
AL
1860 let (file_metadata, line_number) = if span != codemap::DUMMY_SP {
1861 let loc = span_start(cx, span);
1862 (file_metadata(cx, &loc.file.name), loc.line as c_uint)
1863 } else {
1864 (UNKNOWN_FILE_METADATA, UNKNOWN_LINE_NUMBER)
1865 };
1a4d82fc 1866
d9579d0f 1867 let is_local_to_unit = is_node_local_to_unit(cx, node_id);
c1a9b12d 1868 let variable_type = cx.tcx().node_id_to_type(node_id);
d9579d0f
AL
1869 let type_metadata = type_metadata(cx, variable_type, span);
1870 let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
c1a9b12d 1871 let var_name = name.to_string();
d9579d0f
AL
1872 let linkage_name =
1873 namespace_node.mangled_name_of_contained_item(&var_name[..]);
1874 let var_scope = namespace_node.scope;
1a4d82fc 1875
d9579d0f
AL
1876 let var_name = CString::new(var_name).unwrap();
1877 let linkage_name = CString::new(linkage_name).unwrap();
1878 unsafe {
1879 llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
1880 var_scope,
1881 var_name.as_ptr(),
1882 linkage_name.as_ptr(),
1883 file_metadata,
1884 line_number,
1885 type_metadata,
1886 is_local_to_unit,
1887 global,
1888 ptr::null_mut());
1889 }
1890}
1a4d82fc 1891
d9579d0f
AL
1892/// Creates debug information for the given local variable.
1893///
1894/// This function assumes that there's a datum for each pattern component of the
1895/// local in `bcx.fcx.lllocals`.
1896/// Adds the created metadata nodes directly to the crate's IR.
1897pub fn create_local_var_metadata(bcx: Block, local: &ast::Local) {
1898 if bcx.unreachable.get() ||
1899 fn_should_be_ignored(bcx.fcx) ||
1900 bcx.sess().opts.debuginfo != FullDebugInfo {
1901 return;
1a4d82fc 1902 }
1a4d82fc 1903
d9579d0f
AL
1904 let cx = bcx.ccx();
1905 let def_map = &cx.tcx().def_map;
1906 let locals = bcx.fcx.lllocals.borrow();
1a4d82fc 1907
d9579d0f
AL
1908 pat_util::pat_bindings(def_map, &*local.pat, |_, node_id, span, var_ident| {
1909 let datum = match locals.get(&node_id) {
1910 Some(datum) => datum,
1911 None => {
1912 bcx.sess().span_bug(span,
1913 &format!("no entry in lllocals table for {}",
1914 node_id));
1a4d82fc 1915 }
d9579d0f 1916 };
1a4d82fc 1917
d9579d0f
AL
1918 if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() {
1919 cx.sess().span_bug(span, "debuginfo::create_local_var_metadata() - \
1920 Referenced variable location is not an alloca!");
1921 }
1a4d82fc 1922
d9579d0f 1923 let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
1a4d82fc 1924
d9579d0f
AL
1925 declare_local(bcx,
1926 var_ident.node.name,
1927 datum.ty,
1928 scope_metadata,
1929 VariableAccess::DirectVariable { alloca: datum.val },
1930 VariableKind::LocalVariable,
1931 span);
1932 })
1933}
1a4d82fc 1934
d9579d0f
AL
1935/// Creates debug information for a variable captured in a closure.
1936///
1937/// Adds the created metadata nodes directly to the crate's IR.
1938pub fn create_captured_var_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1939 node_id: ast::NodeId,
1940 env_pointer: ValueRef,
1941 env_index: usize,
1942 captured_by_ref: bool,
1943 span: Span) {
1944 if bcx.unreachable.get() ||
1945 fn_should_be_ignored(bcx.fcx) ||
1946 bcx.sess().opts.debuginfo != FullDebugInfo {
1947 return;
1948 }
1a4d82fc 1949
d9579d0f 1950 let cx = bcx.ccx();
1a4d82fc 1951
d9579d0f 1952 let ast_item = cx.tcx().map.find(node_id);
1a4d82fc 1953
d9579d0f
AL
1954 let variable_name = match ast_item {
1955 None => {
1956 cx.sess().span_bug(span, "debuginfo::create_captured_var_metadata: node not found");
1957 }
1958 Some(ast_map::NodeLocal(pat)) | Some(ast_map::NodeArg(pat)) => {
1959 match pat.node {
1960 ast::PatIdent(_, ref path1, _) => {
1961 path1.node.name
1a4d82fc 1962 }
d9579d0f
AL
1963 _ => {
1964 cx.sess()
1965 .span_bug(span,
1966 &format!(
1967 "debuginfo::create_captured_var_metadata() - \
1968 Captured var-id refers to unexpected \
1969 ast_map variant: {:?}",
1970 ast_item));
1a4d82fc
JJ
1971 }
1972 }
1a4d82fc 1973 }
d9579d0f
AL
1974 _ => {
1975 cx.sess()
1976 .span_bug(span,
1977 &format!("debuginfo::create_captured_var_metadata() - \
1978 Captured var-id refers to unexpected \
1979 ast_map variant: {:?}",
1980 ast_item));
1a4d82fc 1981 }
d9579d0f 1982 };
1a4d82fc 1983
d9579d0f
AL
1984 let variable_type = common::node_id_type(bcx, node_id);
1985 let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata;
1a4d82fc 1986
d9579d0f
AL
1987 // env_pointer is the alloca containing the pointer to the environment,
1988 // so it's type is **EnvironmentType. In order to find out the type of
1989 // the environment we have to "dereference" two times.
1990 let llvm_env_data_type = common::val_ty(env_pointer).element_type()
1991 .element_type();
1992 let byte_offset_of_var_in_env = machine::llelement_offset(cx,
1993 llvm_env_data_type,
1994 env_index);
1a4d82fc 1995
d9579d0f
AL
1996 let address_operations = unsafe {
1997 [llvm::LLVMDIBuilderCreateOpDeref(),
1998 llvm::LLVMDIBuilderCreateOpPlus(),
1999 byte_offset_of_var_in_env as i64,
2000 llvm::LLVMDIBuilderCreateOpDeref()]
2001 };
1a4d82fc 2002
d9579d0f
AL
2003 let address_op_count = if captured_by_ref {
2004 address_operations.len()
2005 } else {
2006 address_operations.len() - 1
2007 };
1a4d82fc 2008
d9579d0f
AL
2009 let variable_access = VariableAccess::IndirectVariable {
2010 alloca: env_pointer,
2011 address_operations: &address_operations[..address_op_count]
2012 };
1a4d82fc 2013
d9579d0f
AL
2014 declare_local(bcx,
2015 variable_name,
2016 variable_type,
2017 scope_metadata,
2018 variable_access,
2019 VariableKind::CapturedVariable,
2020 span);
1a4d82fc
JJ
2021}
2022
d9579d0f
AL
2023/// Creates debug information for a local variable introduced in the head of a
2024/// match-statement arm.
2025///
2026/// Adds the created metadata nodes directly to the crate's IR.
2027pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
2028 variable_name: ast::Name,
2029 binding: BindingInfo<'tcx>) {
2030 if bcx.unreachable.get() ||
2031 fn_should_be_ignored(bcx.fcx) ||
2032 bcx.sess().opts.debuginfo != FullDebugInfo {
2033 return;
2034 }
1a4d82fc 2035
d9579d0f
AL
2036 let scope_metadata = scope_metadata(bcx.fcx, binding.id, binding.span);
2037 let aops = unsafe {
2038 [llvm::LLVMDIBuilderCreateOpDeref()]
2039 };
2040 // Regardless of the actual type (`T`) we're always passed the stack slot
2041 // (alloca) for the binding. For ByRef bindings that's a `T*` but for ByMove
2042 // bindings we actually have `T**`. So to get the actual variable we need to
2043 // dereference once more. For ByCopy we just use the stack slot we created
2044 // for the binding.
2045 let var_access = match binding.trmode {
c1a9b12d
SL
2046 TransBindingMode::TrByCopy(llbinding) |
2047 TransBindingMode::TrByMoveIntoCopy(llbinding) => VariableAccess::DirectVariable {
d9579d0f
AL
2048 alloca: llbinding
2049 },
c1a9b12d 2050 TransBindingMode::TrByMoveRef => VariableAccess::IndirectVariable {
d9579d0f
AL
2051 alloca: binding.llmatch,
2052 address_operations: &aops
2053 },
c1a9b12d 2054 TransBindingMode::TrByRef => VariableAccess::DirectVariable {
d9579d0f 2055 alloca: binding.llmatch
1a4d82fc 2056 }
d9579d0f 2057 };
1a4d82fc 2058
d9579d0f
AL
2059 declare_local(bcx,
2060 variable_name,
2061 binding.ty,
2062 scope_metadata,
2063 var_access,
2064 VariableKind::LocalVariable,
2065 binding.span);
1a4d82fc
JJ
2066}
2067
d9579d0f
AL
2068/// Creates debug information for the given function argument.
2069///
2070/// This function assumes that there's a datum for each pattern component of the
2071/// argument in `bcx.fcx.lllocals`.
2072/// Adds the created metadata nodes directly to the crate's IR.
2073pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) {
2074 if bcx.unreachable.get() ||
2075 fn_should_be_ignored(bcx.fcx) ||
2076 bcx.sess().opts.debuginfo != FullDebugInfo {
2077 return;
2078 }
1a4d82fc 2079
d9579d0f
AL
2080 let def_map = &bcx.tcx().def_map;
2081 let scope_metadata = bcx
2082 .fcx
2083 .debug_context
2084 .get_ref(bcx.ccx(), arg.pat.span)
2085 .fn_metadata;
2086 let locals = bcx.fcx.lllocals.borrow();
1a4d82fc 2087
d9579d0f
AL
2088 pat_util::pat_bindings(def_map, &*arg.pat, |_, node_id, span, var_ident| {
2089 let datum = match locals.get(&node_id) {
2090 Some(v) => v,
1a4d82fc 2091 None => {
d9579d0f
AL
2092 bcx.sess().span_bug(span,
2093 &format!("no entry in lllocals table for {}",
2094 node_id));
1a4d82fc 2095 }
d9579d0f 2096 };
1a4d82fc 2097
d9579d0f
AL
2098 if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() {
2099 bcx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \
2100 Referenced variable location is not an alloca!");
1a4d82fc 2101 }
1a4d82fc 2102
d9579d0f
AL
2103 let argument_index = {
2104 let counter = &bcx
2105 .fcx
2106 .debug_context
2107 .get_ref(bcx.ccx(), span)
2108 .argument_counter;
2109 let argument_index = counter.get();
2110 counter.set(argument_index + 1);
2111 argument_index
2112 };
1a4d82fc 2113
d9579d0f
AL
2114 declare_local(bcx,
2115 var_ident.node.name,
2116 datum.ty,
2117 scope_metadata,
2118 VariableAccess::DirectVariable { alloca: datum.val },
2119 VariableKind::ArgumentVariable(argument_index),
2120 span);
2121 })
1a4d82fc 2122}