]> git.proxmox.com Git - rustc.git/blame - src/librustc_trans/debuginfo/metadata.rs
New upstream version 1.15.1+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 16use super::utils::{debug_context, DIB, span_start, bytes_to_bits, size_and_align_of,
9e0c209e 17 get_namespace_and_span_for_item, create_DIArray, is_node_local_to_unit};
a7813a04 18use super::namespace::mangled_name_of_item;
c30ab7b3 19use super::type_names::compute_debuginfo_type_name;
9e0c209e 20use super::{CrateDebugContext};
5bcae85e
SL
21use context::SharedCrateContext;
22use session::Session;
d9579d0f
AL
23
24use llvm::{self, ValueRef};
476ff2be
SL
25use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
26 DICompositeType, DILexicalBlock, DIFlags};
d9579d0f 27
c30ab7b3 28use rustc::hir::def::CtorKind;
54a0048b 29use rustc::hir::def_id::DefId;
c30ab7b3 30use rustc::ty::fold::TypeVisitor;
9e0c209e 31use rustc::ty::subst::Substs;
c30ab7b3 32use rustc::ty::util::TypeIdHasher;
9e0c209e 33use rustc::hir;
476ff2be 34use rustc_data_structures::ToHex;
9e0c209e
SL
35use {type_of, machine, monomorphize};
36use common::CrateContext;
54a0048b 37use type_::Type;
9e0c209e
SL
38use rustc::ty::{self, AdtKind, Ty, layout};
39use session::config;
476ff2be 40use util::nodemap::FxHashMap;
c34b1796 41use util::common::path2cstr;
1a4d82fc 42
85aaf69f 43use libc::{c_uint, c_longlong};
c34b1796
AL
44use std::ffi::CString;
45use std::path::Path;
1a4d82fc 46use std::ptr;
3157f602 47use syntax::ast;
476ff2be 48use syntax::symbol::{Interner, InternedString};
3157f602 49use syntax_pos::{self, Span};
1a4d82fc 50
c30ab7b3 51
54a0048b
SL
52// From DWARF 5.
53// See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1
54const DW_LANG_RUST: c_uint = 0x1c;
1a4d82fc
JJ
55#[allow(non_upper_case_globals)]
56const DW_ATE_boolean: c_uint = 0x02;
57#[allow(non_upper_case_globals)]
58const DW_ATE_float: c_uint = 0x04;
59#[allow(non_upper_case_globals)]
60const DW_ATE_signed: c_uint = 0x05;
61#[allow(non_upper_case_globals)]
62const DW_ATE_unsigned: c_uint = 0x07;
63#[allow(non_upper_case_globals)]
64const DW_ATE_unsigned_char: c_uint = 0x08;
65
d9579d0f
AL
66pub const UNKNOWN_LINE_NUMBER: c_uint = 0;
67pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
1a4d82fc
JJ
68
69// ptr::null() doesn't work :(
a7813a04 70pub const NO_SCOPE_METADATA: DIScope = (0 as DIScope);
1a4d82fc 71
85aaf69f 72#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
d9579d0f 73pub struct UniqueTypeId(ast::Name);
1a4d82fc
JJ
74
75// The TypeMap is where the CrateDebugContext holds the type metadata nodes
76// created so far. The metadata nodes are indexed by UniqueTypeId, and, for
77// faster lookup, also by Ty. The TypeMap is responsible for creating
78// UniqueTypeIds.
d9579d0f 79pub struct TypeMap<'tcx> {
1a4d82fc 80 // The UniqueTypeIds created so far
5bcae85e 81 unique_id_interner: Interner,
1a4d82fc 82 // A map from UniqueTypeId to debuginfo metadata for that type. This is a 1:1 mapping.
476ff2be 83 unique_id_to_metadata: FxHashMap<UniqueTypeId, DIType>,
1a4d82fc 84 // A map from types to debuginfo metadata. This is a N:1 mapping.
476ff2be 85 type_to_metadata: FxHashMap<Ty<'tcx>, DIType>,
1a4d82fc 86 // A map from types to UniqueTypeId. This is a N:1 mapping.
476ff2be 87 type_to_unique_id: FxHashMap<Ty<'tcx>, UniqueTypeId>
1a4d82fc
JJ
88}
89
90impl<'tcx> TypeMap<'tcx> {
d9579d0f 91 pub fn new() -> TypeMap<'tcx> {
1a4d82fc
JJ
92 TypeMap {
93 unique_id_interner: Interner::new(),
476ff2be
SL
94 type_to_metadata: FxHashMap(),
95 unique_id_to_metadata: FxHashMap(),
96 type_to_unique_id: FxHashMap(),
1a4d82fc
JJ
97 }
98 }
99
100 // Adds a Ty to metadata mapping to the TypeMap. The method will fail if
101 // the mapping already exists.
102 fn register_type_with_metadata<'a>(&mut self,
1a4d82fc
JJ
103 type_: Ty<'tcx>,
104 metadata: DIType) {
105 if self.type_to_metadata.insert(type_, metadata).is_some() {
54a0048b 106 bug!("Type metadata for Ty '{}' is already in the TypeMap!", type_);
1a4d82fc
JJ
107 }
108 }
109
110 // Adds a UniqueTypeId to metadata mapping to the TypeMap. The method will
111 // fail if the mapping already exists.
112 fn register_unique_id_with_metadata(&mut self,
1a4d82fc
JJ
113 unique_type_id: UniqueTypeId,
114 metadata: DIType) {
115 if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
54a0048b 116 bug!("Type metadata for unique id '{}' is already in the TypeMap!",
476ff2be 117 self.get_unique_type_id_as_string(unique_type_id));
1a4d82fc
JJ
118 }
119 }
120
121 fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<DIType> {
122 self.type_to_metadata.get(&type_).cloned()
123 }
124
125 fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<DIType> {
126 self.unique_id_to_metadata.get(&unique_type_id).cloned()
127 }
128
129 // Get the string representation of a UniqueTypeId. This method will fail if
130 // the id is unknown.
476ff2be 131 fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> &str {
1a4d82fc
JJ
132 let UniqueTypeId(interner_key) = unique_type_id;
133 self.unique_id_interner.get(interner_key)
134 }
135
136 // Get the UniqueTypeId for the given type. If the UniqueTypeId for the given
137 // type has been requested before, this is just a table lookup. Otherwise an
138 // ID will be generated and stored for later lookup.
139 fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
140 type_: Ty<'tcx>) -> UniqueTypeId {
c30ab7b3 141 // Let's see if we already have something in the cache
1a4d82fc
JJ
142 match self.type_to_unique_id.get(&type_).cloned() {
143 Some(unique_type_id) => return unique_type_id,
144 None => { /* generate one */}
145 };
146
c30ab7b3
SL
147 // The hasher we are using to generate the UniqueTypeId. We want
148 // something that provides more than the 64 bits of the DefaultHasher.
1a4d82fc 149
476ff2be 150 let mut type_id_hasher = TypeIdHasher::<[u8; 20]>::new(cx.tcx());
c30ab7b3 151 type_id_hasher.visit_ty(type_);
1a4d82fc 152
476ff2be 153 let unique_type_id = type_id_hasher.finish().to_hex();
c30ab7b3 154 let key = self.unique_id_interner.intern(&unique_type_id);
1a4d82fc
JJ
155 self.type_to_unique_id.insert(type_, UniqueTypeId(key));
156
157 return UniqueTypeId(key);
1a4d82fc
JJ
158 }
159
1a4d82fc
JJ
160 // Get the UniqueTypeId for an enum variant. Enum variants are not really
161 // types of their own, so they need special handling. We still need a
162 // UniqueTypeId for them, since to debuginfo they *are* real types.
163 fn get_unique_type_id_of_enum_variant<'a>(&mut self,
164 cx: &CrateContext<'a, 'tcx>,
165 enum_type: Ty<'tcx>,
166 variant_name: &str)
167 -> UniqueTypeId {
168 let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
169 let enum_variant_type_id = format!("{}::{}",
476ff2be 170 self.get_unique_type_id_as_string(enum_type_id),
1a4d82fc 171 variant_name);
c30ab7b3 172 let interner_key = self.unique_id_interner.intern(&enum_variant_type_id);
1a4d82fc
JJ
173 UniqueTypeId(interner_key)
174 }
175}
176
d9579d0f
AL
177// A description of some recursive type. It can either be already finished (as
178// with FinalMetadata) or it is not yet finished, but contains all information
179// needed to generate the missing parts of the description. See the
180// documentation section on Recursive Types at the top of this file for more
181// information.
182enum RecursiveTypeDescription<'tcx> {
183 UnfinishedMetadata {
184 unfinished_type: Ty<'tcx>,
185 unique_type_id: UniqueTypeId,
186 metadata_stub: DICompositeType,
187 llvm_type: Type,
188 member_description_factory: MemberDescriptionFactory<'tcx>,
189 },
190 FinalMetadata(DICompositeType)
191}
192
193fn create_and_register_recursive_type_forward_declaration<'a, 'tcx>(
194 cx: &CrateContext<'a, 'tcx>,
195 unfinished_type: Ty<'tcx>,
196 unique_type_id: UniqueTypeId,
197 metadata_stub: DICompositeType,
198 llvm_type: Type,
199 member_description_factory: MemberDescriptionFactory<'tcx>)
200 -> RecursiveTypeDescription<'tcx> {
201
202 // Insert the stub into the TypeMap in order to allow for recursive references
203 let mut type_map = debug_context(cx).type_map.borrow_mut();
54a0048b
SL
204 type_map.register_unique_id_with_metadata(unique_type_id, metadata_stub);
205 type_map.register_type_with_metadata(unfinished_type, metadata_stub);
d9579d0f
AL
206
207 UnfinishedMetadata {
208 unfinished_type: unfinished_type,
209 unique_type_id: unique_type_id,
210 metadata_stub: metadata_stub,
211 llvm_type: llvm_type,
212 member_description_factory: member_description_factory,
213 }
214}
215
216impl<'tcx> RecursiveTypeDescription<'tcx> {
217 // Finishes up the description of the type in question (mostly by providing
218 // descriptions of the fields of the given type) and returns the final type
219 // metadata.
220 fn finalize<'a>(&self, cx: &CrateContext<'a, 'tcx>) -> MetadataCreationResult {
221 match *self {
222 FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
223 UnfinishedMetadata {
224 unfinished_type,
225 unique_type_id,
226 metadata_stub,
227 llvm_type,
228 ref member_description_factory,
229 ..
230 } => {
231 // Make sure that we have a forward declaration of the type in
232 // the TypeMap so that recursive references are possible. This
233 // will always be the case if the RecursiveTypeDescription has
234 // been properly created through the
235 // create_and_register_recursive_type_forward_declaration()
236 // function.
237 {
238 let type_map = debug_context(cx).type_map.borrow();
239 if type_map.find_metadata_for_unique_id(unique_type_id).is_none() ||
240 type_map.find_metadata_for_type(unfinished_type).is_none() {
54a0048b
SL
241 bug!("Forward declaration of potentially recursive type \
242 '{:?}' was not found in TypeMap!",
243 unfinished_type);
d9579d0f
AL
244 }
245 }
246
247 // ... then create the member descriptions ...
248 let member_descriptions =
249 member_description_factory.create_member_descriptions(cx);
250
251 // ... and attach them to the stub to complete it.
252 set_members_of_composite_type(cx,
253 metadata_stub,
254 llvm_type,
255 &member_descriptions[..]);
256 return MetadataCreationResult::new(metadata_stub, true);
257 }
258 }
259 }
260}
261
1a4d82fc
JJ
262// Returns from the enclosing function if the type metadata with the given
263// unique id can be found in the type map
264macro_rules! return_if_metadata_created_in_meantime {
265 ($cx: expr, $unique_type_id: expr) => (
266 match debug_context($cx).type_map
267 .borrow()
268 .find_metadata_for_unique_id($unique_type_id) {
269 Some(metadata) => return MetadataCreationResult::new(metadata, true),
270 None => { /* proceed normally */ }
b039eaaf 271 }
1a4d82fc
JJ
272 )
273}
274
d9579d0f
AL
275fn fixed_vec_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
276 unique_type_id: UniqueTypeId,
277 element_type: Ty<'tcx>,
278 len: Option<u64>,
279 span: Span)
280 -> MetadataCreationResult {
281 let element_type_metadata = type_metadata(cx, element_type, span);
282
283 return_if_metadata_created_in_meantime!(cx, unique_type_id);
1a4d82fc 284
d9579d0f
AL
285 let element_llvm_type = type_of::type_of(cx, element_type);
286 let (element_type_size, element_type_align) = size_and_align_of(cx, element_llvm_type);
1a4d82fc 287
d9579d0f
AL
288 let (array_size_in_bytes, upper_bound) = match len {
289 Some(len) => (element_type_size * len, len as c_longlong),
290 None => (0, -1)
291 };
1a4d82fc 292
d9579d0f 293 let subrange = unsafe {
5bcae85e 294 llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)
d9579d0f 295 };
1a4d82fc 296
d9579d0f
AL
297 let subscripts = create_DIArray(DIB(cx), &[subrange]);
298 let metadata = unsafe {
5bcae85e 299 llvm::LLVMRustDIBuilderCreateArrayType(
d9579d0f
AL
300 DIB(cx),
301 bytes_to_bits(array_size_in_bytes),
302 bytes_to_bits(element_type_align),
303 element_type_metadata,
304 subscripts)
305 };
1a4d82fc 306
d9579d0f 307 return MetadataCreationResult::new(metadata, false);
1a4d82fc
JJ
308}
309
d9579d0f
AL
310fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
311 vec_type: Ty<'tcx>,
312 element_type: Ty<'tcx>,
313 unique_type_id: UniqueTypeId,
314 span: Span)
315 -> MetadataCreationResult {
c1a9b12d 316 let data_ptr_type = cx.tcx().mk_ptr(ty::TypeAndMut {
d9579d0f 317 ty: element_type,
e9174d1e 318 mutbl: hir::MutImmutable
d9579d0f 319 });
1a4d82fc 320
d9579d0f 321 let element_type_metadata = type_metadata(cx, data_ptr_type, span);
1a4d82fc 322
d9579d0f 323 return_if_metadata_created_in_meantime!(cx, unique_type_id);
1a4d82fc 324
d9579d0f
AL
325 let slice_llvm_type = type_of::type_of(cx, vec_type);
326 let slice_type_name = compute_debuginfo_type_name(cx, vec_type, true);
1a4d82fc 327
d9579d0f
AL
328 let member_llvm_types = slice_llvm_type.field_types();
329 assert!(slice_layout_is_correct(cx,
330 &member_llvm_types[..],
331 element_type));
332 let member_descriptions = [
333 MemberDescription {
334 name: "data_ptr".to_string(),
335 llvm_type: member_llvm_types[0],
336 type_metadata: element_type_metadata,
337 offset: ComputedMemberOffset,
476ff2be 338 flags: DIFlags::FlagZero,
d9579d0f
AL
339 },
340 MemberDescription {
341 name: "length".to_string(),
342 llvm_type: member_llvm_types[1],
343 type_metadata: type_metadata(cx, cx.tcx().types.usize, span),
344 offset: ComputedMemberOffset,
476ff2be 345 flags: DIFlags::FlagZero,
d9579d0f
AL
346 },
347 ];
1a4d82fc 348
d9579d0f 349 assert!(member_descriptions.len() == member_llvm_types.len());
1a4d82fc 350
d9579d0f 351 let loc = span_start(cx, span);
3157f602 352 let file_metadata = file_metadata(cx, &loc.file.name, &loc.file.abs_path);
1a4d82fc 353
d9579d0f
AL
354 let metadata = composite_type_metadata(cx,
355 slice_llvm_type,
356 &slice_type_name[..],
357 unique_type_id,
358 &member_descriptions,
e9174d1e 359 NO_SCOPE_METADATA,
d9579d0f
AL
360 file_metadata,
361 span);
362 return MetadataCreationResult::new(metadata, false);
1a4d82fc 363
d9579d0f
AL
364 fn slice_layout_is_correct<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
365 member_llvm_types: &[Type],
366 element_type: Ty<'tcx>)
367 -> bool {
368 member_llvm_types.len() == 2 &&
369 member_llvm_types[0] == type_of::type_of(cx, element_type).ptr_to() &&
370 member_llvm_types[1] == cx.int_type()
1a4d82fc 371 }
d9579d0f 372}
1a4d82fc 373
d9579d0f
AL
374fn subroutine_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
375 unique_type_id: UniqueTypeId,
376 signature: &ty::PolyFnSig<'tcx>,
377 span: Span)
378 -> MetadataCreationResult
379{
c1a9b12d 380 let signature = cx.tcx().erase_late_bound_regions(signature);
1a4d82fc 381
476ff2be 382 let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs().len() + 1);
1a4d82fc 383
d9579d0f 384 // return type
476ff2be 385 signature_metadata.push(match signature.output().sty {
5bcae85e 386 ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(),
476ff2be 387 _ => type_metadata(cx, signature.output(), span)
d9579d0f 388 });
1a4d82fc 389
d9579d0f 390 // regular arguments
476ff2be 391 for &argument_type in signature.inputs() {
d9579d0f 392 signature_metadata.push(type_metadata(cx, argument_type, span));
1a4d82fc
JJ
393 }
394
d9579d0f 395 return_if_metadata_created_in_meantime!(cx, unique_type_id);
1a4d82fc 396
d9579d0f
AL
397 return MetadataCreationResult::new(
398 unsafe {
5bcae85e 399 llvm::LLVMRustDIBuilderCreateSubroutineType(
d9579d0f 400 DIB(cx),
5bcae85e 401 unknown_file_metadata(cx),
d9579d0f 402 create_DIArray(DIB(cx), &signature_metadata[..]))
1a4d82fc
JJ
403 },
404 false);
405}
406
407// FIXME(1563) This is all a bit of a hack because 'trait pointer' is an ill-
408// defined concept. For the case of an actual trait pointer (i.e., Box<Trait>,
409// &Trait), trait_object_type should be the whole thing (e.g, Box<Trait>) and
410// trait_type should be the actual trait (e.g., Trait). Where the trait is part
411// of a DST struct, there is no trait_object_type and the results of this
412// function will be a little bit weird.
413fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
414 trait_type: Ty<'tcx>,
415 trait_object_type: Option<Ty<'tcx>>,
416 unique_type_id: UniqueTypeId)
417 -> DIType {
418 // The implementation provided here is a stub. It makes sure that the trait
419 // type is assigned the correct name, size, namespace, and source location.
420 // But it does not describe the trait's methods.
421
476ff2be
SL
422 let containing_scope = match trait_type.sty {
423 ty::TyDynamic(ref data, ..) => if let Some(principal) = data.principal() {
424 let def_id = principal.def_id();
425 get_namespace_and_span_for_item(cx, def_id).0
426 } else {
427 NO_SCOPE_METADATA
428 },
1a4d82fc 429 _ => {
54a0048b
SL
430 bug!("debuginfo: Unexpected trait-object type in \
431 trait_pointer_metadata(): {:?}",
432 trait_type);
1a4d82fc
JJ
433 }
434 };
435
436 let trait_object_type = trait_object_type.unwrap_or(trait_type);
437 let trait_type_name =
438 compute_debuginfo_type_name(cx, trait_object_type, false);
439
1a4d82fc 440 let trait_llvm_type = type_of::type_of(cx, trait_object_type);
5bcae85e 441 let file_metadata = unknown_file_metadata(cx);
1a4d82fc
JJ
442
443 composite_type_metadata(cx,
444 trait_llvm_type,
85aaf69f 445 &trait_type_name[..],
1a4d82fc
JJ
446 unique_type_id,
447 &[],
448 containing_scope,
5bcae85e 449 file_metadata,
3157f602 450 syntax_pos::DUMMY_SP)
1a4d82fc
JJ
451}
452
d9579d0f
AL
453pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
454 t: Ty<'tcx>,
455 usage_site_span: Span)
456 -> DIType {
1a4d82fc
JJ
457 // Get the unique type id of this type.
458 let unique_type_id = {
459 let mut type_map = debug_context(cx).type_map.borrow_mut();
460 // First, try to find the type in TypeMap. If we have seen it before, we
461 // can exit early here.
462 match type_map.find_metadata_for_type(t) {
463 Some(metadata) => {
464 return metadata;
465 },
466 None => {
467 // The Ty is not in the TypeMap but maybe we have already seen
468 // an equivalent type (e.g. only differing in region arguments).
469 // In order to find out, generate the unique type id and look
470 // that up.
471 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
472 match type_map.find_metadata_for_unique_id(unique_type_id) {
473 Some(metadata) => {
474 // There is already an equivalent type in the TypeMap.
475 // Register this Ty as an alias in the cache and
476 // return the cached metadata.
54a0048b 477 type_map.register_type_with_metadata(t, metadata);
1a4d82fc
JJ
478 return metadata;
479 },
480 None => {
481 // There really is no type metadata for this type, so
482 // proceed by creating it.
483 unique_type_id
484 }
485 }
486 }
487 }
488 };
489
490 debug!("type_metadata: {:?}", t);
491
492 let sty = &t.sty;
493 let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty {
5bcae85e 494 ty::TyNever |
62682a34
SL
495 ty::TyBool |
496 ty::TyChar |
497 ty::TyInt(_) |
498 ty::TyUint(_) |
499 ty::TyFloat(_) => {
1a4d82fc
JJ
500 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
501 }
62682a34 502 ty::TyTuple(ref elements) if elements.is_empty() => {
1a4d82fc
JJ
503 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
504 }
62682a34
SL
505 ty::TyArray(typ, len) => {
506 fixed_vec_metadata(cx, unique_type_id, typ, Some(len as u64), usage_site_span)
507 }
508 ty::TySlice(typ) => {
509 fixed_vec_metadata(cx, unique_type_id, typ, None, usage_site_span)
85aaf69f 510 }
62682a34 511 ty::TyStr => {
85aaf69f 512 fixed_vec_metadata(cx, unique_type_id, cx.tcx().types.i8, None, usage_site_span)
1a4d82fc 513 }
476ff2be 514 ty::TyDynamic(..) => {
1a4d82fc
JJ
515 MetadataCreationResult::new(
516 trait_pointer_metadata(cx, t, None, unique_type_id),
517 false)
518 }
c1a9b12d
SL
519 ty::TyBox(ty) |
520 ty::TyRawPtr(ty::TypeAndMut{ty, ..}) |
521 ty::TyRef(_, ty::TypeAndMut{ty, ..}) => {
1a4d82fc 522 match ty.sty {
62682a34 523 ty::TySlice(typ) => {
1a4d82fc
JJ
524 vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span)
525 }
62682a34 526 ty::TyStr => {
1a4d82fc
JJ
527 vec_slice_metadata(cx, t, cx.tcx().types.u8, unique_type_id, usage_site_span)
528 }
476ff2be 529 ty::TyDynamic(..) => {
1a4d82fc
JJ
530 MetadataCreationResult::new(
531 trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
532 false)
533 }
534 _ => {
535 let pointee_metadata = type_metadata(cx, ty, usage_site_span);
536
537 match debug_context(cx).type_map
538 .borrow()
539 .find_metadata_for_unique_id(unique_type_id) {
540 Some(metadata) => return metadata,
541 None => { /* proceed normally */ }
542 };
543
544 MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
545 false)
546 }
547 }
548 }
9e0c209e 549 ty::TyFnDef(.., ref barefnty) | ty::TyFnPtr(ref barefnty) => {
c1a9b12d
SL
550 let fn_metadata = subroutine_type_metadata(cx,
551 unique_type_id,
552 &barefnty.sig,
553 usage_site_span).metadata;
554 match debug_context(cx).type_map
555 .borrow()
556 .find_metadata_for_unique_id(unique_type_id) {
557 Some(metadata) => return metadata,
558 None => { /* proceed normally */ }
559 };
560
561 // This is actually a function pointer, so wrap it in pointer DI
562 MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false)
563
1a4d82fc 564 }
476ff2be
SL
565 ty::TyClosure(def_id, substs) => {
566 let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx()).collect();
c1a9b12d
SL
567 prepare_tuple_metadata(cx,
568 t,
476ff2be 569 &upvar_tys,
c1a9b12d
SL
570 unique_type_id,
571 usage_site_span).finalize(cx)
1a4d82fc 572 }
9e0c209e
SL
573 ty::TyAdt(def, ..) => match def.adt_kind() {
574 AdtKind::Struct => {
575 prepare_struct_metadata(cx,
576 t,
577 unique_type_id,
578 usage_site_span).finalize(cx)
579 }
580 AdtKind::Union => {
581 prepare_union_metadata(cx,
1a4d82fc 582 t,
1a4d82fc
JJ
583 unique_type_id,
584 usage_site_span).finalize(cx)
9e0c209e
SL
585 }
586 AdtKind::Enum => {
587 prepare_enum_metadata(cx,
588 t,
589 def.did,
590 unique_type_id,
591 usage_site_span).finalize(cx)
592 }
593 },
62682a34 594 ty::TyTuple(ref elements) => {
1a4d82fc
JJ
595 prepare_tuple_metadata(cx,
596 t,
85aaf69f 597 &elements[..],
1a4d82fc
JJ
598 unique_type_id,
599 usage_site_span).finalize(cx)
600 }
601 _ => {
54a0048b 602 bug!("debuginfo: unexpected type in type_metadata: {:?}", sty)
1a4d82fc
JJ
603 }
604 };
605
606 {
607 let mut type_map = debug_context(cx).type_map.borrow_mut();
608
609 if already_stored_in_typemap {
b039eaaf 610 // Also make sure that we already have a TypeMap entry for the unique type id.
1a4d82fc
JJ
611 let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
612 Some(metadata) => metadata,
613 None => {
54a0048b
SL
614 span_bug!(usage_site_span,
615 "Expected type metadata for unique \
616 type id '{}' to already be in \
617 the debuginfo::TypeMap but it \
618 was not. (Ty = {})",
476ff2be 619 type_map.get_unique_type_id_as_string(unique_type_id),
54a0048b 620 t);
1a4d82fc
JJ
621 }
622 };
623
624 match type_map.find_metadata_for_type(t) {
625 Some(metadata) => {
626 if metadata != metadata_for_uid {
54a0048b
SL
627 span_bug!(usage_site_span,
628 "Mismatch between Ty and \
629 UniqueTypeId maps in \
630 debuginfo::TypeMap. \
631 UniqueTypeId={}, Ty={}",
476ff2be 632 type_map.get_unique_type_id_as_string(unique_type_id),
54a0048b 633 t);
1a4d82fc
JJ
634 }
635 }
636 None => {
54a0048b 637 type_map.register_type_with_metadata(t, metadata);
1a4d82fc
JJ
638 }
639 }
640 } else {
54a0048b
SL
641 type_map.register_type_with_metadata(t, metadata);
642 type_map.register_unique_id_with_metadata(unique_type_id, metadata);
1a4d82fc
JJ
643 }
644 }
645
646 metadata
647}
648
3157f602 649pub fn file_metadata(cx: &CrateContext, path: &str, full_path: &Option<String>) -> DIFile {
d9579d0f
AL
650 // FIXME (#9639): This needs to handle non-utf8 paths
651 let work_dir = cx.sess().working_dir.to_str().unwrap();
652 let file_name =
3157f602
XL
653 full_path.as_ref().map(|p| p.as_str()).unwrap_or_else(|| {
654 if path.starts_with(work_dir) {
655 &path[work_dir.len() + 1..path.len()]
656 } else {
657 path
658 }
659 });
d9579d0f 660
3157f602 661 file_metadata_(cx, path, file_name, &work_dir)
e9174d1e
SL
662}
663
664pub fn unknown_file_metadata(cx: &CrateContext) -> DIFile {
665 // Regular filenames should not be empty, so we abuse an empty name as the
666 // key for the special unknown file metadata
667 file_metadata_(cx, "", "<unknown>", "")
668
669}
670
671fn file_metadata_(cx: &CrateContext, key: &str, file_name: &str, work_dir: &str) -> DIFile {
3157f602
XL
672 if let Some(file_metadata) = debug_context(cx).created_files.borrow().get(key) {
673 return *file_metadata;
e9174d1e
SL
674 }
675
676 debug!("file_metadata: file_name: {}, work_dir: {}", file_name, work_dir);
677
d9579d0f
AL
678 let file_name = CString::new(file_name).unwrap();
679 let work_dir = CString::new(work_dir).unwrap();
680 let file_metadata = unsafe {
5bcae85e
SL
681 llvm::LLVMRustDIBuilderCreateFile(DIB(cx), file_name.as_ptr(),
682 work_dir.as_ptr())
d9579d0f
AL
683 };
684
685 let mut created_files = debug_context(cx).created_files.borrow_mut();
e9174d1e
SL
686 created_files.insert(key.to_string(), file_metadata);
687 file_metadata
d9579d0f
AL
688}
689
d9579d0f
AL
690fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
691 t: Ty<'tcx>) -> DIType {
692
693 debug!("basic_type_metadata: {:?}", t);
694
695 let (name, encoding) = match t.sty {
5bcae85e 696 ty::TyNever => ("!", DW_ATE_unsigned),
62682a34 697 ty::TyTuple(ref elements) if elements.is_empty() =>
92a42be0
SL
698 ("()", DW_ATE_unsigned),
699 ty::TyBool => ("bool", DW_ATE_boolean),
700 ty::TyChar => ("char", DW_ATE_unsigned_char),
701 ty::TyInt(int_ty) => {
9cc50fc6 702 (int_ty.ty_to_string(), DW_ATE_signed)
d9579d0f 703 },
92a42be0 704 ty::TyUint(uint_ty) => {
9cc50fc6 705 (uint_ty.ty_to_string(), DW_ATE_unsigned)
d9579d0f 706 },
92a42be0 707 ty::TyFloat(float_ty) => {
9cc50fc6 708 (float_ty.ty_to_string(), DW_ATE_float)
d9579d0f 709 },
54a0048b 710 _ => bug!("debuginfo::basic_type_metadata - t is invalid type")
d9579d0f
AL
711 };
712
713 let llvm_type = type_of::type_of(cx, t);
714 let (size, align) = size_and_align_of(cx, llvm_type);
715 let name = CString::new(name).unwrap();
716 let ty_metadata = unsafe {
5bcae85e 717 llvm::LLVMRustDIBuilderCreateBasicType(
d9579d0f
AL
718 DIB(cx),
719 name.as_ptr(),
720 bytes_to_bits(size),
721 bytes_to_bits(align),
722 encoding)
723 };
724
725 return ty_metadata;
726}
727
728fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
729 pointer_type: Ty<'tcx>,
730 pointee_type_metadata: DIType)
731 -> DIType {
732 let pointer_llvm_type = type_of::type_of(cx, pointer_type);
733 let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
734 let name = compute_debuginfo_type_name(cx, pointer_type, false);
735 let name = CString::new(name).unwrap();
736 let ptr_metadata = unsafe {
5bcae85e 737 llvm::LLVMRustDIBuilderCreatePointerType(
d9579d0f
AL
738 DIB(cx),
739 pointee_type_metadata,
740 bytes_to_bits(pointer_size),
741 bytes_to_bits(pointer_align),
742 name.as_ptr())
743 };
744 return ptr_metadata;
745}
746
5bcae85e
SL
747pub fn compile_unit_metadata(scc: &SharedCrateContext,
748 debug_context: &CrateDebugContext,
749 sess: &Session)
750 -> DIDescriptor {
751 let work_dir = &sess.working_dir;
752 let compile_unit_name = match sess.local_crate_source_file {
753 None => fallback_path(scc),
d9579d0f
AL
754 Some(ref abs_path) => {
755 if abs_path.is_relative() {
5bcae85e
SL
756 sess.warn("debuginfo: Invalid path to crate's local root source file!");
757 fallback_path(scc)
d9579d0f 758 } else {
9cc50fc6
SL
759 match abs_path.strip_prefix(work_dir) {
760 Ok(ref p) if p.is_relative() => {
d9579d0f
AL
761 if p.starts_with(Path::new("./")) {
762 path2cstr(p)
763 } else {
764 path2cstr(&Path::new(".").join(p))
765 }
766 }
5bcae85e 767 _ => fallback_path(scc)
d9579d0f
AL
768 }
769 }
770 }
771 };
772
773 debug!("compile_unit_metadata: {:?}", compile_unit_name);
774 let producer = format!("rustc version {}",
775 (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
776
777 let compile_unit_name = compile_unit_name.as_ptr();
778 let work_dir = path2cstr(&work_dir);
779 let producer = CString::new(producer).unwrap();
780 let flags = "\0";
781 let split_name = "\0";
782 return unsafe {
5bcae85e
SL
783 llvm::LLVMRustDIBuilderCreateCompileUnit(
784 debug_context.builder,
d9579d0f
AL
785 DW_LANG_RUST,
786 compile_unit_name,
787 work_dir.as_ptr(),
788 producer.as_ptr(),
5bcae85e 789 sess.opts.optimize != config::OptLevel::No,
d9579d0f
AL
790 flags.as_ptr() as *const _,
791 0,
792 split_name.as_ptr() as *const _)
793 };
794
5bcae85e 795 fn fallback_path(scc: &SharedCrateContext) -> CString {
476ff2be 796 CString::new(scc.link_meta().crate_name.to_string()).unwrap()
d9579d0f
AL
797 }
798}
799
1a4d82fc
JJ
800struct MetadataCreationResult {
801 metadata: DIType,
802 already_stored_in_typemap: bool
803}
804
805impl MetadataCreationResult {
806 fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationResult {
807 MetadataCreationResult {
808 metadata: metadata,
809 already_stored_in_typemap: already_stored_in_typemap
810 }
811 }
812}
813
d9579d0f
AL
814#[derive(Debug)]
815enum MemberOffset {
816 FixedMemberOffset { bytes: usize },
817 // For ComputedMemberOffset, the offset is read from the llvm type definition.
818 ComputedMemberOffset
819}
820
821// Description of a type member, which can either be a regular field (as in
822// structs or tuples) or an enum variant.
823#[derive(Debug)]
824struct MemberDescription {
825 name: String,
826 llvm_type: Type,
827 type_metadata: DIType,
828 offset: MemberOffset,
476ff2be 829 flags: DIFlags,
d9579d0f
AL
830}
831
832// A factory for MemberDescriptions. It produces a list of member descriptions
833// for some record-like type. MemberDescriptionFactories are used to defer the
834// creation of type member descriptions in order to break cycles arising from
835// recursive type definitions.
836enum MemberDescriptionFactory<'tcx> {
837 StructMDF(StructMemberDescriptionFactory<'tcx>),
838 TupleMDF(TupleMemberDescriptionFactory<'tcx>),
839 EnumMDF(EnumMemberDescriptionFactory<'tcx>),
9e0c209e 840 UnionMDF(UnionMemberDescriptionFactory<'tcx>),
d9579d0f
AL
841 VariantMDF(VariantMemberDescriptionFactory<'tcx>)
842}
843
844impl<'tcx> MemberDescriptionFactory<'tcx> {
845 fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
846 -> Vec<MemberDescription> {
847 match *self {
848 StructMDF(ref this) => {
849 this.create_member_descriptions(cx)
850 }
851 TupleMDF(ref this) => {
852 this.create_member_descriptions(cx)
853 }
854 EnumMDF(ref this) => {
855 this.create_member_descriptions(cx)
856 }
9e0c209e
SL
857 UnionMDF(ref this) => {
858 this.create_member_descriptions(cx)
859 }
d9579d0f
AL
860 VariantMDF(ref this) => {
861 this.create_member_descriptions(cx)
862 }
863 }
864 }
865}
866
867//=-----------------------------------------------------------------------------
868// Structs
869//=-----------------------------------------------------------------------------
870
871// Creates MemberDescriptions for the fields of a struct
872struct StructMemberDescriptionFactory<'tcx> {
476ff2be
SL
873 ty: Ty<'tcx>,
874 variant: &'tcx ty::VariantDef,
9e0c209e 875 substs: &'tcx Substs<'tcx>,
d9579d0f
AL
876 span: Span,
877}
878
879impl<'tcx> StructMemberDescriptionFactory<'tcx> {
880 fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
881 -> Vec<MemberDescription> {
476ff2be
SL
882 let layout = cx.layout_of(self.ty);
883
884 let tmp;
885 let offsets = match *layout {
886 layout::Univariant { ref variant, .. } => &variant.offsets,
887 layout::Vector { element, count } => {
888 let element_size = element.size(&cx.tcx().data_layout).bytes();
889 tmp = (0..count).
890 map(|i| layout::Size::from_bytes(i*element_size))
891 .collect::<Vec<layout::Size>>();
892 &tmp
893 }
894 _ => bug!("{} is not a struct", self.ty)
d9579d0f
AL
895 };
896
e9174d1e 897 self.variant.fields.iter().enumerate().map(|(i, f)| {
c30ab7b3 898 let name = if self.variant.ctor_kind == CtorKind::Fn {
d9579d0f
AL
899 format!("__{}", i)
900 } else {
e9174d1e 901 f.name.to_string()
d9579d0f 902 };
e9174d1e 903 let fty = monomorphize::field_ty(cx.tcx(), self.substs, f);
1a4d82fc 904
476ff2be 905 let offset = FixedMemberOffset { bytes: offsets[i].bytes() as usize};
d9579d0f
AL
906
907 MemberDescription {
908 name: name,
e9174d1e
SL
909 llvm_type: type_of::type_of(cx, fty),
910 type_metadata: type_metadata(cx, fty, self.span),
d9579d0f 911 offset: offset,
476ff2be 912 flags: DIFlags::FlagZero,
d9579d0f
AL
913 }
914 }).collect()
1a4d82fc
JJ
915 }
916}
917
1a4d82fc 918
d9579d0f
AL
919fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
920 struct_type: Ty<'tcx>,
d9579d0f
AL
921 unique_type_id: UniqueTypeId,
922 span: Span)
923 -> RecursiveTypeDescription<'tcx> {
924 let struct_name = compute_debuginfo_type_name(cx, struct_type, false);
925 let struct_llvm_type = type_of::in_memory_type_of(cx, struct_type);
926
a7813a04 927 let (struct_def_id, variant, substs) = match struct_type.sty {
9e0c209e
SL
928 ty::TyAdt(def, substs) => (def.did, def.struct_variant(), substs),
929 _ => bug!("prepare_struct_metadata on a non-ADT")
e9174d1e
SL
930 };
931
a7813a04 932 let (containing_scope, _) = get_namespace_and_span_for_item(cx, struct_def_id);
1a4d82fc 933
d9579d0f
AL
934 let struct_metadata_stub = create_struct_stub(cx,
935 struct_llvm_type,
936 &struct_name,
937 unique_type_id,
938 containing_scope);
85aaf69f 939
d9579d0f
AL
940 create_and_register_recursive_type_forward_declaration(
941 cx,
942 struct_type,
943 unique_type_id,
944 struct_metadata_stub,
945 struct_llvm_type,
946 StructMDF(StructMemberDescriptionFactory {
476ff2be 947 ty: struct_type,
e9174d1e
SL
948 variant: variant,
949 substs: substs,
d9579d0f
AL
950 span: span,
951 })
952 )
1a4d82fc
JJ
953}
954
955//=-----------------------------------------------------------------------------
d9579d0f 956// Tuples
1a4d82fc
JJ
957//=-----------------------------------------------------------------------------
958
d9579d0f
AL
959// Creates MemberDescriptions for the fields of a tuple
960struct TupleMemberDescriptionFactory<'tcx> {
476ff2be 961 ty: Ty<'tcx>,
d9579d0f
AL
962 component_types: Vec<Ty<'tcx>>,
963 span: Span,
1a4d82fc
JJ
964}
965
d9579d0f
AL
966impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
967 fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
968 -> Vec<MemberDescription> {
476ff2be
SL
969 let layout = cx.layout_of(self.ty);
970 let offsets = if let layout::Univariant { ref variant, .. } = *layout {
971 &variant.offsets
972 } else {
973 bug!("{} is not a tuple", self.ty);
974 };
975
d9579d0f
AL
976 self.component_types
977 .iter()
978 .enumerate()
979 .map(|(i, &component_type)| {
980 MemberDescription {
981 name: format!("__{}", i),
982 llvm_type: type_of::type_of(cx, component_type),
983 type_metadata: type_metadata(cx, component_type, self.span),
476ff2be
SL
984 offset: FixedMemberOffset { bytes: offsets[i].bytes() as usize },
985 flags: DIFlags::FlagZero,
d9579d0f
AL
986 }
987 }).collect()
988 }
1a4d82fc
JJ
989}
990
d9579d0f
AL
991fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
992 tuple_type: Ty<'tcx>,
993 component_types: &[Ty<'tcx>],
994 unique_type_id: UniqueTypeId,
995 span: Span)
996 -> RecursiveTypeDescription<'tcx> {
997 let tuple_name = compute_debuginfo_type_name(cx, tuple_type, false);
998 let tuple_llvm_type = type_of::type_of(cx, tuple_type);
1a4d82fc 999
d9579d0f
AL
1000 create_and_register_recursive_type_forward_declaration(
1001 cx,
1002 tuple_type,
1003 unique_type_id,
1004 create_struct_stub(cx,
1005 tuple_llvm_type,
1006 &tuple_name[..],
1007 unique_type_id,
e9174d1e 1008 NO_SCOPE_METADATA),
d9579d0f
AL
1009 tuple_llvm_type,
1010 TupleMDF(TupleMemberDescriptionFactory {
476ff2be 1011 ty: tuple_type,
d9579d0f
AL
1012 component_types: component_types.to_vec(),
1013 span: span,
1014 })
1015 )
1a4d82fc
JJ
1016}
1017
9e0c209e
SL
1018//=-----------------------------------------------------------------------------
1019// Unions
1020//=-----------------------------------------------------------------------------
1021
1022struct UnionMemberDescriptionFactory<'tcx> {
476ff2be 1023 variant: &'tcx ty::VariantDef,
9e0c209e
SL
1024 substs: &'tcx Substs<'tcx>,
1025 span: Span,
1026}
1027
1028impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
1029 fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1030 -> Vec<MemberDescription> {
1031 self.variant.fields.iter().map(|field| {
1032 let fty = monomorphize::field_ty(cx.tcx(), self.substs, field);
1033 MemberDescription {
1034 name: field.name.to_string(),
1035 llvm_type: type_of::type_of(cx, fty),
1036 type_metadata: type_metadata(cx, fty, self.span),
1037 offset: FixedMemberOffset { bytes: 0 },
476ff2be 1038 flags: DIFlags::FlagZero,
9e0c209e
SL
1039 }
1040 }).collect()
1041 }
1042}
1043
1044fn prepare_union_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1045 union_type: Ty<'tcx>,
1046 unique_type_id: UniqueTypeId,
1047 span: Span)
1048 -> RecursiveTypeDescription<'tcx> {
1049 let union_name = compute_debuginfo_type_name(cx, union_type, false);
1050 let union_llvm_type = type_of::in_memory_type_of(cx, union_type);
1051
1052 let (union_def_id, variant, substs) = match union_type.sty {
1053 ty::TyAdt(def, substs) => (def.did, def.struct_variant(), substs),
1054 _ => bug!("prepare_union_metadata on a non-ADT")
1055 };
1056
1057 let (containing_scope, _) = get_namespace_and_span_for_item(cx, union_def_id);
1058
1059 let union_metadata_stub = create_union_stub(cx,
1060 union_llvm_type,
1061 &union_name,
1062 unique_type_id,
1063 containing_scope);
1064
1065 create_and_register_recursive_type_forward_declaration(
1066 cx,
1067 union_type,
1068 unique_type_id,
1069 union_metadata_stub,
1070 union_llvm_type,
1071 UnionMDF(UnionMemberDescriptionFactory {
1072 variant: variant,
1073 substs: substs,
1074 span: span,
1075 })
1076 )
1077}
1a4d82fc 1078
d9579d0f
AL
1079//=-----------------------------------------------------------------------------
1080// Enums
1081//=-----------------------------------------------------------------------------
1a4d82fc 1082
d9579d0f
AL
1083// Describes the members of an enum value: An enum is described as a union of
1084// structs in DWARF. This MemberDescriptionFactory provides the description for
1085// the members of this union; so for every variant of the given enum, this
1086// factory will produce one MemberDescription (all with no name and a fixed
1087// offset of zero bytes).
1088struct EnumMemberDescriptionFactory<'tcx> {
1089 enum_type: Ty<'tcx>,
9e0c209e 1090 type_rep: &'tcx layout::Layout,
d9579d0f
AL
1091 discriminant_type_metadata: Option<DIType>,
1092 containing_scope: DIScope,
1093 file_metadata: DIFile,
1094 span: Span,
1a4d82fc
JJ
1095}
1096
d9579d0f
AL
1097impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
1098 fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1099 -> Vec<MemberDescription> {
e9174d1e 1100 let adt = &self.enum_type.ty_adt_def().unwrap();
9e0c209e
SL
1101 let substs = match self.enum_type.sty {
1102 ty::TyAdt(def, ref s) if def.adt_kind() == AdtKind::Enum => s,
1103 _ => bug!("{} is not an enum", self.enum_type)
1104 };
d9579d0f 1105 match *self.type_rep {
9e0c209e 1106 layout::General { ref variants, .. } => {
d9579d0f
AL
1107 let discriminant_info = RegularDiscriminant(self.discriminant_type_metadata
1108 .expect(""));
9e0c209e 1109 variants
d9579d0f
AL
1110 .iter()
1111 .enumerate()
1112 .map(|(i, struct_def)| {
1113 let (variant_type_metadata,
1114 variant_llvm_type,
1115 member_desc_factory) =
1116 describe_enum_variant(cx,
1117 self.enum_type,
1118 struct_def,
e9174d1e 1119 &adt.variants[i],
d9579d0f
AL
1120 discriminant_info,
1121 self.containing_scope,
1122 self.span);
1a4d82fc 1123
d9579d0f
AL
1124 let member_descriptions = member_desc_factory
1125 .create_member_descriptions(cx);
1a4d82fc 1126
d9579d0f
AL
1127 set_members_of_composite_type(cx,
1128 variant_type_metadata,
1129 variant_llvm_type,
1130 &member_descriptions);
1131 MemberDescription {
1132 name: "".to_string(),
1133 llvm_type: variant_llvm_type,
1134 type_metadata: variant_type_metadata,
1135 offset: FixedMemberOffset { bytes: 0 },
476ff2be 1136 flags: DIFlags::FlagZero
d9579d0f
AL
1137 }
1138 }).collect()
1139 },
9e0c209e 1140 layout::Univariant{ ref variant, .. } => {
e9174d1e 1141 assert!(adt.variants.len() <= 1);
1a4d82fc 1142
e9174d1e 1143 if adt.variants.is_empty() {
d9579d0f
AL
1144 vec![]
1145 } else {
1146 let (variant_type_metadata,
1147 variant_llvm_type,
1148 member_description_factory) =
1149 describe_enum_variant(cx,
1150 self.enum_type,
9e0c209e 1151 variant,
e9174d1e 1152 &adt.variants[0],
d9579d0f
AL
1153 NoDiscriminant,
1154 self.containing_scope,
1155 self.span);
1a4d82fc 1156
d9579d0f
AL
1157 let member_descriptions =
1158 member_description_factory.create_member_descriptions(cx);
1a4d82fc 1159
d9579d0f
AL
1160 set_members_of_composite_type(cx,
1161 variant_type_metadata,
1162 variant_llvm_type,
1163 &member_descriptions[..]);
1164 vec![
1165 MemberDescription {
1166 name: "".to_string(),
1167 llvm_type: variant_llvm_type,
1168 type_metadata: variant_type_metadata,
1169 offset: FixedMemberOffset { bytes: 0 },
476ff2be 1170 flags: DIFlags::FlagZero
d9579d0f
AL
1171 }
1172 ]
1173 }
1174 }
9e0c209e 1175 layout::RawNullablePointer { nndiscr: non_null_variant_index, .. } => {
d9579d0f
AL
1176 // As far as debuginfo is concerned, the pointer this enum
1177 // represents is still wrapped in a struct. This is to make the
1178 // DWARF representation of enums uniform.
1a4d82fc 1179
d9579d0f 1180 // First create a description of the artificial wrapper struct:
9e0c209e 1181 let non_null_variant = &adt.variants[non_null_variant_index as usize];
c1a9b12d 1182 let non_null_variant_name = non_null_variant.name.as_str();
1a4d82fc 1183
d9579d0f 1184 // The llvm type and metadata of the pointer
9e0c209e 1185 let nnty = monomorphize::field_ty(cx.tcx(), &substs, &non_null_variant.fields[0] );
d9579d0f
AL
1186 let non_null_llvm_type = type_of::type_of(cx, nnty);
1187 let non_null_type_metadata = type_metadata(cx, nnty, self.span);
1a4d82fc 1188
d9579d0f
AL
1189 // The type of the artificial struct wrapping the pointer
1190 let artificial_struct_llvm_type = Type::struct_(cx,
1191 &[non_null_llvm_type],
1192 false);
1a4d82fc 1193
d9579d0f
AL
1194 // For the metadata of the wrapper struct, we need to create a
1195 // MemberDescription of the struct's single field.
1196 let sole_struct_member_description = MemberDescription {
c30ab7b3
SL
1197 name: match non_null_variant.ctor_kind {
1198 CtorKind::Fn => "__0".to_string(),
1199 CtorKind::Fictive => {
e9174d1e
SL
1200 non_null_variant.fields[0].name.to_string()
1201 }
c30ab7b3 1202 CtorKind::Const => bug!()
d9579d0f
AL
1203 },
1204 llvm_type: non_null_llvm_type,
1205 type_metadata: non_null_type_metadata,
1206 offset: FixedMemberOffset { bytes: 0 },
476ff2be 1207 flags: DIFlags::FlagZero
d9579d0f 1208 };
1a4d82fc 1209
d9579d0f
AL
1210 let unique_type_id = debug_context(cx).type_map
1211 .borrow_mut()
1212 .get_unique_type_id_of_enum_variant(
1213 cx,
1214 self.enum_type,
1215 &non_null_variant_name);
1a4d82fc 1216
d9579d0f
AL
1217 // Now we can create the metadata of the artificial struct
1218 let artificial_struct_metadata =
1219 composite_type_metadata(cx,
1220 artificial_struct_llvm_type,
1221 &non_null_variant_name,
1222 unique_type_id,
1223 &[sole_struct_member_description],
1224 self.containing_scope,
1225 self.file_metadata,
3157f602 1226 syntax_pos::DUMMY_SP);
1a4d82fc 1227
d9579d0f
AL
1228 // Encode the information about the null variant in the union
1229 // member's name.
9e0c209e 1230 let null_variant_index = (1 - non_null_variant_index) as usize;
e9174d1e 1231 let null_variant_name = adt.variants[null_variant_index].name;
d9579d0f
AL
1232 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
1233 0,
1234 null_variant_name);
1a4d82fc 1235
d9579d0f
AL
1236 // Finally create the (singleton) list of descriptions of union
1237 // members.
1238 vec![
1239 MemberDescription {
1240 name: union_member_name,
1241 llvm_type: artificial_struct_llvm_type,
1242 type_metadata: artificial_struct_metadata,
1243 offset: FixedMemberOffset { bytes: 0 },
476ff2be 1244 flags: DIFlags::FlagZero
d9579d0f
AL
1245 }
1246 ]
1247 },
9e0c209e 1248 layout::StructWrappedNullablePointer { nonnull: ref struct_def,
d9579d0f 1249 nndiscr,
476ff2be 1250 ref discrfield_source, ..} => {
d9579d0f
AL
1251 // Create a description of the non-null variant
1252 let (variant_type_metadata, variant_llvm_type, member_description_factory) =
1253 describe_enum_variant(cx,
1254 self.enum_type,
1255 struct_def,
9e0c209e 1256 &adt.variants[nndiscr as usize],
d9579d0f
AL
1257 OptimizedDiscriminant,
1258 self.containing_scope,
1259 self.span);
1a4d82fc 1260
d9579d0f
AL
1261 let variant_member_descriptions =
1262 member_description_factory.create_member_descriptions(cx);
1a4d82fc 1263
d9579d0f
AL
1264 set_members_of_composite_type(cx,
1265 variant_type_metadata,
1266 variant_llvm_type,
1267 &variant_member_descriptions[..]);
1a4d82fc 1268
d9579d0f
AL
1269 // Encode the information about the null variant in the union
1270 // member's name.
9e0c209e 1271 let null_variant_index = (1 - nndiscr) as usize;
e9174d1e 1272 let null_variant_name = adt.variants[null_variant_index].name;
476ff2be 1273 let discrfield_source = discrfield_source.iter()
d9579d0f
AL
1274 .skip(1)
1275 .map(|x| x.to_string())
c1a9b12d 1276 .collect::<Vec<_>>().join("$");
d9579d0f 1277 let union_member_name = format!("RUST$ENCODED$ENUM${}${}",
476ff2be 1278 discrfield_source,
d9579d0f 1279 null_variant_name);
1a4d82fc 1280
d9579d0f
AL
1281 // Create the (singleton) list of descriptions of union members.
1282 vec![
1283 MemberDescription {
1284 name: union_member_name,
1285 llvm_type: variant_llvm_type,
1286 type_metadata: variant_type_metadata,
1287 offset: FixedMemberOffset { bytes: 0 },
476ff2be 1288 flags: DIFlags::FlagZero
d9579d0f
AL
1289 }
1290 ]
1291 },
9e0c209e
SL
1292 layout::CEnum { .. } => span_bug!(self.span, "This should be unreachable."),
1293 ref l @ _ => bug!("Not an enum layout: {:#?}", l)
1a4d82fc
JJ
1294 }
1295 }
d9579d0f 1296}
1a4d82fc 1297
d9579d0f
AL
1298// Creates MemberDescriptions for the fields of a single enum variant.
1299struct VariantMemberDescriptionFactory<'tcx> {
476ff2be
SL
1300 // Cloned from the layout::Struct describing the variant.
1301 offsets: &'tcx [layout::Size],
d9579d0f
AL
1302 args: Vec<(String, Ty<'tcx>)>,
1303 discriminant_type_metadata: Option<DIType>,
1304 span: Span,
1305}
1a4d82fc 1306
d9579d0f
AL
1307impl<'tcx> VariantMemberDescriptionFactory<'tcx> {
1308 fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
1309 -> Vec<MemberDescription> {
1310 self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
1311 MemberDescription {
1312 name: name.to_string(),
1313 llvm_type: type_of::type_of(cx, ty),
1314 type_metadata: match self.discriminant_type_metadata {
1315 Some(metadata) if i == 0 => metadata,
1316 _ => type_metadata(cx, ty, self.span)
1317 },
476ff2be
SL
1318 offset: FixedMemberOffset { bytes: self.offsets[i].bytes() as usize },
1319 flags: DIFlags::FlagZero
1a4d82fc 1320 }
d9579d0f 1321 }).collect()
1a4d82fc 1322 }
d9579d0f 1323}
1a4d82fc 1324
d9579d0f
AL
1325#[derive(Copy, Clone)]
1326enum EnumDiscriminantInfo {
1327 RegularDiscriminant(DIType),
1328 OptimizedDiscriminant,
1329 NoDiscriminant
1330}
1a4d82fc 1331
d9579d0f
AL
1332// Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type
1333// of the variant, and (3) a MemberDescriptionFactory for producing the
1334// descriptions of the fields of the variant. This is a rudimentary version of a
1335// full RecursiveTypeDescription.
1336fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1337 enum_type: Ty<'tcx>,
476ff2be
SL
1338 struct_def: &'tcx layout::Struct,
1339 variant: &'tcx ty::VariantDef,
d9579d0f
AL
1340 discriminant_info: EnumDiscriminantInfo,
1341 containing_scope: DIScope,
1342 span: Span)
1343 -> (DICompositeType, Type, MemberDescriptionFactory<'tcx>) {
9e0c209e
SL
1344 let substs = match enum_type.sty {
1345 ty::TyAdt(def, s) if def.adt_kind() == AdtKind::Enum => s,
1346 ref t @ _ => bug!("{:#?} is not an enum", t)
1347 };
1348
1349 let maybe_discr_and_signed: Option<(layout::Integer, bool)> = match *cx.layout_of(enum_type) {
1350 layout::CEnum {discr, ..} => Some((discr, true)),
1351 layout::General{discr, ..} => Some((discr, false)),
1352 layout::Univariant { .. }
1353 | layout::RawNullablePointer { .. }
1354 | layout::StructWrappedNullablePointer { .. } => None,
1355 ref l @ _ => bug!("This should be unreachable. Type is {:#?} layout is {:#?}", enum_type, l)
1356 };
1357
476ff2be 1358 let mut field_tys = variant.fields.iter().map(|f| {
9e0c209e
SL
1359 monomorphize::field_ty(cx.tcx(), &substs, f)
1360 }).collect::<Vec<_>>();
1361
1362 if let Some((discr, signed)) = maybe_discr_and_signed {
1363 field_tys.insert(0, discr.to_ty(&cx.tcx(), signed));
1364 }
1365
1366
d9579d0f 1367 let variant_llvm_type =
9e0c209e 1368 Type::struct_(cx, &field_tys
d9579d0f 1369 .iter()
9e0c209e 1370 .map(|t| type_of::type_of(cx, t))
d9579d0f
AL
1371 .collect::<Vec<_>>()
1372 ,
1373 struct_def.packed);
1374 // Could do some consistency checks here: size, align, field count, discr type
1a4d82fc 1375
e9174d1e 1376 let variant_name = variant.name.as_str();
d9579d0f
AL
1377 let unique_type_id = debug_context(cx).type_map
1378 .borrow_mut()
1379 .get_unique_type_id_of_enum_variant(
1380 cx,
1381 enum_type,
c1a9b12d 1382 &variant_name);
1a4d82fc 1383
d9579d0f
AL
1384 let metadata_stub = create_struct_stub(cx,
1385 variant_llvm_type,
c1a9b12d 1386 &variant_name,
d9579d0f
AL
1387 unique_type_id,
1388 containing_scope);
1a4d82fc 1389
d9579d0f 1390 // Get the argument names from the enum variant info
c30ab7b3
SL
1391 let mut arg_names: Vec<_> = match variant.ctor_kind {
1392 CtorKind::Const => vec![],
1393 CtorKind::Fn => {
e9174d1e
SL
1394 variant.fields
1395 .iter()
1396 .enumerate()
1397 .map(|(i, _)| format!("__{}", i))
1398 .collect()
d9579d0f 1399 }
c30ab7b3 1400 CtorKind::Fictive => {
e9174d1e
SL
1401 variant.fields
1402 .iter()
1403 .map(|f| f.name.to_string())
1404 .collect()
d9579d0f
AL
1405 }
1406 };
1a4d82fc 1407
d9579d0f
AL
1408 // If this is not a univariant enum, there is also the discriminant field.
1409 match discriminant_info {
1410 RegularDiscriminant(_) => arg_names.insert(0, "RUST$ENUM$DISR".to_string()),
1411 _ => { /* do nothing */ }
1412 };
1a4d82fc 1413
d9579d0f
AL
1414 // Build an array of (field name, field type) pairs to be captured in the factory closure.
1415 let args: Vec<(String, Ty)> = arg_names.iter()
9e0c209e 1416 .zip(field_tys.iter())
d9579d0f
AL
1417 .map(|(s, &t)| (s.to_string(), t))
1418 .collect();
1a4d82fc 1419
d9579d0f
AL
1420 let member_description_factory =
1421 VariantMDF(VariantMemberDescriptionFactory {
476ff2be 1422 offsets: &struct_def.offsets[..],
d9579d0f
AL
1423 args: args,
1424 discriminant_type_metadata: match discriminant_info {
1425 RegularDiscriminant(discriminant_type_metadata) => {
1426 Some(discriminant_type_metadata)
1a4d82fc 1427 }
d9579d0f
AL
1428 _ => None
1429 },
1430 span: span,
1431 });
1a4d82fc 1432
d9579d0f
AL
1433 (metadata_stub, variant_llvm_type, member_description_factory)
1434}
1a4d82fc 1435
d9579d0f
AL
1436fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
1437 enum_type: Ty<'tcx>,
e9174d1e 1438 enum_def_id: DefId,
d9579d0f
AL
1439 unique_type_id: UniqueTypeId,
1440 span: Span)
1441 -> RecursiveTypeDescription<'tcx> {
1442 let enum_name = compute_debuginfo_type_name(cx, enum_type, false);
1a4d82fc 1443
e9174d1e
SL
1444 let (containing_scope, _) = get_namespace_and_span_for_item(cx, enum_def_id);
1445 // FIXME: This should emit actual file metadata for the enum, but we
1446 // currently can't get the necessary information when it comes to types
1447 // imported from other crates. Formerly we violated the ODR when performing
1448 // LTO because we emitted debuginfo for the same type with varying file
1449 // metadata, so as a workaround we pretend that the type comes from
1450 // <unknown>
1451 let file_metadata = unknown_file_metadata(cx);
1a4d82fc 1452
e9174d1e 1453 let variants = &enum_type.ty_adt_def().unwrap().variants;
d9579d0f
AL
1454 let enumerators_metadata: Vec<DIDescriptor> = variants
1455 .iter()
1456 .map(|v| {
c1a9b12d 1457 let token = v.name.as_str();
d9579d0f
AL
1458 let name = CString::new(token.as_bytes()).unwrap();
1459 unsafe {
5bcae85e 1460 llvm::LLVMRustDIBuilderCreateEnumerator(
d9579d0f
AL
1461 DIB(cx),
1462 name.as_ptr(),
54a0048b 1463 v.disr_val.to_u64_unchecked())
1a4d82fc 1464 }
d9579d0f
AL
1465 })
1466 .collect();
1a4d82fc 1467
9e0c209e 1468 let discriminant_type_metadata = |inttype: layout::Integer, signed: bool| {
c1a9b12d 1469 let disr_type_key = (enum_def_id, inttype);
d9579d0f
AL
1470 let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
1471 .borrow()
c1a9b12d 1472 .get(&disr_type_key).cloned();
d9579d0f
AL
1473 match cached_discriminant_type_metadata {
1474 Some(discriminant_type_metadata) => discriminant_type_metadata,
1475 None => {
9e0c209e 1476 let discriminant_llvm_type = Type::from_integer(cx, inttype);
d9579d0f
AL
1477 let (discriminant_size, discriminant_align) =
1478 size_and_align_of(cx, discriminant_llvm_type);
1479 let discriminant_base_type_metadata =
1480 type_metadata(cx,
9e0c209e 1481 inttype.to_ty(&cx.tcx(), signed),
3157f602 1482 syntax_pos::DUMMY_SP);
d9579d0f 1483 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
1a4d82fc 1484
d9579d0f
AL
1485 let name = CString::new(discriminant_name.as_bytes()).unwrap();
1486 let discriminant_type_metadata = unsafe {
5bcae85e 1487 llvm::LLVMRustDIBuilderCreateEnumerationType(
d9579d0f
AL
1488 DIB(cx),
1489 containing_scope,
1490 name.as_ptr(),
5bcae85e 1491 file_metadata,
d9579d0f
AL
1492 UNKNOWN_LINE_NUMBER,
1493 bytes_to_bits(discriminant_size),
1494 bytes_to_bits(discriminant_align),
1495 create_DIArray(DIB(cx), &enumerators_metadata),
1496 discriminant_base_type_metadata)
1497 };
1a4d82fc 1498
d9579d0f
AL
1499 debug_context(cx).created_enum_disr_types
1500 .borrow_mut()
c1a9b12d 1501 .insert(disr_type_key, discriminant_type_metadata);
1a4d82fc 1502
d9579d0f 1503 discriminant_type_metadata
1a4d82fc
JJ
1504 }
1505 }
d9579d0f 1506 };
1a4d82fc 1507
9e0c209e 1508 let type_rep = cx.layout_of(enum_type);
1a4d82fc 1509
d9579d0f 1510 let discriminant_type_metadata = match *type_rep {
9e0c209e
SL
1511 layout::CEnum { discr, signed, .. } => {
1512 return FinalMetadata(discriminant_type_metadata(discr, signed))
d9579d0f 1513 },
9e0c209e
SL
1514 layout::RawNullablePointer { .. } |
1515 layout::StructWrappedNullablePointer { .. } |
1516 layout::Univariant { .. } => None,
1517 layout::General { discr, .. } => Some(discriminant_type_metadata(discr, false)),
1518 ref l @ _ => bug!("Not an enum layout: {:#?}", l)
d9579d0f 1519 };
1a4d82fc 1520
d9579d0f
AL
1521 let enum_llvm_type = type_of::type_of(cx, enum_type);
1522 let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
1a4d82fc 1523
d9579d0f 1524 let enum_name = CString::new(enum_name).unwrap();
476ff2be
SL
1525 let unique_type_id_str = CString::new(
1526 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
1527 ).unwrap();
d9579d0f 1528 let enum_metadata = unsafe {
5bcae85e 1529 llvm::LLVMRustDIBuilderCreateUnionType(
d9579d0f
AL
1530 DIB(cx),
1531 containing_scope,
1532 enum_name.as_ptr(),
62682a34 1533 file_metadata,
d9579d0f
AL
1534 UNKNOWN_LINE_NUMBER,
1535 bytes_to_bits(enum_type_size),
1536 bytes_to_bits(enum_type_align),
476ff2be 1537 DIFlags::FlagZero,
d9579d0f
AL
1538 ptr::null_mut(),
1539 0, // RuntimeLang
1540 unique_type_id_str.as_ptr())
1541 };
1a4d82fc 1542
d9579d0f
AL
1543 return create_and_register_recursive_type_forward_declaration(
1544 cx,
1545 enum_type,
1546 unique_type_id,
1547 enum_metadata,
1548 enum_llvm_type,
1549 EnumMDF(EnumMemberDescriptionFactory {
1550 enum_type: enum_type,
9e0c209e 1551 type_rep: type_rep,
d9579d0f
AL
1552 discriminant_type_metadata: discriminant_type_metadata,
1553 containing_scope: containing_scope,
1554 file_metadata: file_metadata,
1555 span: span,
1556 }),
1557 );
1a4d82fc 1558
d9579d0f 1559 fn get_enum_discriminant_name(cx: &CrateContext,
e9174d1e 1560 def_id: DefId)
476ff2be 1561 -> InternedString {
e9174d1e 1562 cx.tcx().item_name(def_id).as_str()
d9579d0f
AL
1563 }
1564}
1a4d82fc 1565
d9579d0f
AL
1566/// Creates debug information for a composite type, that is, anything that
1567/// results in a LLVM struct.
1568///
1569/// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
1570fn composite_type_metadata(cx: &CrateContext,
1571 composite_llvm_type: Type,
1572 composite_type_name: &str,
1573 composite_type_unique_id: UniqueTypeId,
1574 member_descriptions: &[MemberDescription],
1575 containing_scope: DIScope,
1a4d82fc 1576
d9579d0f
AL
1577 // Ignore source location information as long as it
1578 // can't be reconstructed for non-local crates.
1579 _file_metadata: DIFile,
1580 _definition_span: Span)
1581 -> DICompositeType {
1582 // Create the (empty) struct metadata node ...
1583 let composite_type_metadata = create_struct_stub(cx,
1584 composite_llvm_type,
1585 composite_type_name,
1586 composite_type_unique_id,
1587 containing_scope);
1588 // ... and immediately create and add the member descriptions.
1589 set_members_of_composite_type(cx,
1590 composite_type_metadata,
1591 composite_llvm_type,
1592 member_descriptions);
1a4d82fc 1593
d9579d0f
AL
1594 return composite_type_metadata;
1595}
1a4d82fc 1596
d9579d0f
AL
1597fn set_members_of_composite_type(cx: &CrateContext,
1598 composite_type_metadata: DICompositeType,
1599 composite_llvm_type: Type,
1600 member_descriptions: &[MemberDescription]) {
1601 // In some rare cases LLVM metadata uniquing would lead to an existing type
1602 // description being used instead of a new one created in
1603 // create_struct_stub. This would cause a hard to trace assertion in
1604 // DICompositeType::SetTypeArray(). The following check makes sure that we
1605 // get a better error message if this should happen again due to some
1606 // regression.
1607 {
1608 let mut composite_types_completed =
1609 debug_context(cx).composite_types_completed.borrow_mut();
1610 if composite_types_completed.contains(&composite_type_metadata) {
54a0048b
SL
1611 bug!("debuginfo::set_members_of_composite_type() - \
1612 Already completed forward declaration re-encountered.");
d9579d0f
AL
1613 } else {
1614 composite_types_completed.insert(composite_type_metadata);
1615 }
1616 }
1a4d82fc 1617
d9579d0f
AL
1618 let member_metadata: Vec<DIDescriptor> = member_descriptions
1619 .iter()
1620 .enumerate()
1621 .map(|(i, member_description)| {
1622 let (member_size, member_align) = size_and_align_of(cx, member_description.llvm_type);
1623 let member_offset = match member_description.offset {
1624 FixedMemberOffset { bytes } => bytes as u64,
1625 ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
1626 };
1a4d82fc 1627
d9579d0f
AL
1628 let member_name = member_description.name.as_bytes();
1629 let member_name = CString::new(member_name).unwrap();
1630 unsafe {
5bcae85e 1631 llvm::LLVMRustDIBuilderCreateMemberType(
d9579d0f
AL
1632 DIB(cx),
1633 composite_type_metadata,
1634 member_name.as_ptr(),
5bcae85e 1635 unknown_file_metadata(cx),
d9579d0f
AL
1636 UNKNOWN_LINE_NUMBER,
1637 bytes_to_bits(member_size),
1638 bytes_to_bits(member_align),
1639 bytes_to_bits(member_offset),
1640 member_description.flags,
1641 member_description.type_metadata)
1a4d82fc 1642 }
d9579d0f
AL
1643 })
1644 .collect();
1a4d82fc 1645
d9579d0f
AL
1646 unsafe {
1647 let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
5bcae85e
SL
1648 llvm::LLVMRustDICompositeTypeSetTypeArray(
1649 DIB(cx), composite_type_metadata, type_array);
d9579d0f
AL
1650 }
1651}
1a4d82fc 1652
5bcae85e
SL
1653// A convenience wrapper around LLVMRustDIBuilderCreateStructType(). Does not do
1654// any caching, does not add any fields to the struct. This can be done later
1655// with set_members_of_composite_type().
d9579d0f
AL
1656fn create_struct_stub(cx: &CrateContext,
1657 struct_llvm_type: Type,
1658 struct_type_name: &str,
1659 unique_type_id: UniqueTypeId,
1660 containing_scope: DIScope)
1661 -> DICompositeType {
1662 let (struct_size, struct_align) = size_and_align_of(cx, struct_llvm_type);
1a4d82fc 1663
d9579d0f 1664 let name = CString::new(struct_type_name).unwrap();
476ff2be
SL
1665 let unique_type_id = CString::new(
1666 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
1667 ).unwrap();
d9579d0f 1668 let metadata_stub = unsafe {
5bcae85e 1669 // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
d9579d0f
AL
1670 // pointer will lead to hard to trace and debug LLVM assertions
1671 // later on in llvm/lib/IR/Value.cpp.
1672 let empty_array = create_DIArray(DIB(cx), &[]);
1a4d82fc 1673
5bcae85e 1674 llvm::LLVMRustDIBuilderCreateStructType(
d9579d0f
AL
1675 DIB(cx),
1676 containing_scope,
1677 name.as_ptr(),
5bcae85e 1678 unknown_file_metadata(cx),
d9579d0f
AL
1679 UNKNOWN_LINE_NUMBER,
1680 bytes_to_bits(struct_size),
1681 bytes_to_bits(struct_align),
476ff2be 1682 DIFlags::FlagZero,
d9579d0f
AL
1683 ptr::null_mut(),
1684 empty_array,
1685 0,
1686 ptr::null_mut(),
1687 unique_type_id.as_ptr())
1688 };
1a4d82fc 1689
d9579d0f
AL
1690 return metadata_stub;
1691}
1a4d82fc 1692
9e0c209e
SL
1693fn create_union_stub(cx: &CrateContext,
1694 union_llvm_type: Type,
1695 union_type_name: &str,
1696 unique_type_id: UniqueTypeId,
1697 containing_scope: DIScope)
1698 -> DICompositeType {
1699 let (union_size, union_align) = size_and_align_of(cx, union_llvm_type);
1700
9e0c209e 1701 let name = CString::new(union_type_name).unwrap();
476ff2be
SL
1702 let unique_type_id = CString::new(
1703 debug_context(cx).type_map.borrow().get_unique_type_id_as_string(unique_type_id).as_bytes()
1704 ).unwrap();
9e0c209e
SL
1705 let metadata_stub = unsafe {
1706 // LLVMRustDIBuilderCreateUnionType() wants an empty array. A null
1707 // pointer will lead to hard to trace and debug LLVM assertions
1708 // later on in llvm/lib/IR/Value.cpp.
1709 let empty_array = create_DIArray(DIB(cx), &[]);
1710
1711 llvm::LLVMRustDIBuilderCreateUnionType(
1712 DIB(cx),
1713 containing_scope,
1714 name.as_ptr(),
1715 unknown_file_metadata(cx),
1716 UNKNOWN_LINE_NUMBER,
1717 bytes_to_bits(union_size),
1718 bytes_to_bits(union_align),
476ff2be 1719 DIFlags::FlagZero,
9e0c209e
SL
1720 empty_array,
1721 0, // RuntimeLang
1722 unique_type_id.as_ptr())
1723 };
1724
1725 return metadata_stub;
1726}
1727
d9579d0f
AL
1728/// Creates debug information for the given global variable.
1729///
1730/// Adds the created metadata nodes directly to the crate's IR.
1731pub fn create_global_var_metadata(cx: &CrateContext,
1732 node_id: ast::NodeId,
1733 global: ValueRef) {
1734 if cx.dbg_cx().is_none() {
1735 return;
1736 }
1a4d82fc 1737
c30ab7b3
SL
1738 let tcx = cx.tcx();
1739
d9579d0f
AL
1740 // Don't create debuginfo for globals inlined from other crates. The other
1741 // crate should already contain debuginfo for it. More importantly, the
1742 // global might not even exist in un-inlined form anywhere which would lead
1743 // to a linker errors.
c30ab7b3 1744 if tcx.map.is_inlined_node_id(node_id) {
d9579d0f
AL
1745 return;
1746 }
1a4d82fc 1747
c30ab7b3 1748 let node_def_id = tcx.map.local_def_id(node_id);
a7813a04 1749 let (var_scope, span) = get_namespace_and_span_for_item(cx, node_def_id);
1a4d82fc 1750
3157f602 1751 let (file_metadata, line_number) = if span != syntax_pos::DUMMY_SP {
d9579d0f 1752 let loc = span_start(cx, span);
3157f602 1753 (file_metadata(cx, &loc.file.name, &loc.file.abs_path), loc.line as c_uint)
d9579d0f 1754 } else {
5bcae85e 1755 (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
d9579d0f 1756 };
1a4d82fc 1757
d9579d0f 1758 let is_local_to_unit = is_node_local_to_unit(cx, node_id);
476ff2be 1759 let variable_type = tcx.erase_regions(&tcx.item_type(node_def_id));
d9579d0f 1760 let type_metadata = type_metadata(cx, variable_type, span);
c30ab7b3 1761 let var_name = tcx.item_name(node_def_id).to_string();
a7813a04 1762 let linkage_name = mangled_name_of_item(cx, node_def_id, "");
1a4d82fc 1763
d9579d0f
AL
1764 let var_name = CString::new(var_name).unwrap();
1765 let linkage_name = CString::new(linkage_name).unwrap();
476ff2be
SL
1766
1767 let ty = cx.tcx().item_type(node_def_id);
1768 let global_align = type_of::align_of(cx, ty);
1769
d9579d0f 1770 unsafe {
5bcae85e
SL
1771 llvm::LLVMRustDIBuilderCreateStaticVariable(DIB(cx),
1772 var_scope,
1773 var_name.as_ptr(),
1774 linkage_name.as_ptr(),
1775 file_metadata,
1776 line_number,
1777 type_metadata,
1778 is_local_to_unit,
1779 global,
476ff2be
SL
1780 ptr::null_mut(),
1781 global_align as u64,
1782 );
d9579d0f
AL
1783 }
1784}
1a4d82fc 1785
9e0c209e
SL
1786// Creates an "extension" of an existing DIScope into another file.
1787pub fn extend_scope_to_file(ccx: &CrateContext,
1788 scope_metadata: DIScope,
1789 file: &syntax_pos::FileMap)
1790 -> DILexicalBlock {
1791 let file_metadata = file_metadata(ccx, &file.name, &file.abs_path);
1792 unsafe {
1793 llvm::LLVMRustDIBuilderCreateLexicalBlockFile(
1794 DIB(ccx),
1795 scope_metadata,
1796 file_metadata)
d9579d0f 1797 }
1a4d82fc 1798}