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