]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / compiler / rustc_codegen_llvm / src / debuginfo / metadata.rs
CommitLineData
f035d41b 1use self::EnumTagInfo::*;
dfeec247
XL
2use self::MemberDescriptionFactory::*;
3use self::RecursiveTypeDescription::*;
1a4d82fc 4
0531ce1d 5use super::namespace::mangled_name_of_instance;
c30ab7b3 6use super::type_names::compute_debuginfo_type_name;
dfeec247 7use super::utils::{
ba9703b0 8 create_DIArray, debug_context, get_namespace_for_item, is_node_local_to_unit, DIB,
dfeec247 9};
e74abb32 10use super::CrateDebugContext;
d9579d0f 11
60c5eb7d
XL
12use crate::abi;
13use crate::common::CodegenCx;
9fa01778 14use crate::llvm;
dfeec247
XL
15use crate::llvm::debuginfo::{
16 DIArray, DICompositeType, DIDescriptor, DIFile, DIFlags, DILexicalBlock, DIScope, DIType,
17 DebugEmissionKind,
18};
60c5eb7d 19use crate::value::Value;
d9579d0f 20
6a06907d 21use cstr::cstr;
dfeec247 22use rustc_codegen_ssa::traits::*;
dfeec247
XL
23use rustc_data_structures::fingerprint::Fingerprint;
24use rustc_data_structures::fx::FxHashMap;
dfeec247
XL
25use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
26use rustc_fs_util::path_to_c_string;
27use rustc_hir::def::CtorKind;
29967ef6 28use rustc_hir::def_id::{DefId, LOCAL_CRATE};
dfeec247 29use rustc_index::vec::{Idx, IndexVec};
ba9703b0 30use rustc_middle::ich::NodeIdHashingMode;
ba9703b0
XL
31use rustc_middle::mir::{self, Field, GeneratorLayout};
32use rustc_middle::ty::layout::{self, IntegerExt, PrimitiveExt, TyAndLayout};
f035d41b 33use rustc_middle::ty::subst::GenericArgKind;
ba9703b0 34use rustc_middle::ty::Instance;
f035d41b 35use rustc_middle::ty::{self, AdtKind, GeneratorSubsts, ParamEnv, Ty, TyCtxt};
ba9703b0
XL
36use rustc_middle::{bug, span_bug};
37use rustc_session::config::{self, DebugInfo};
dfeec247 38use rustc_span::symbol::{Interner, Symbol};
ba9703b0 39use rustc_span::{self, SourceFile, SourceFileHash, Span};
f035d41b 40use rustc_target::abi::{Abi, Align, HasDataLayout, Integer, LayoutOf, TagEncoding};
ba9703b0
XL
41use rustc_target::abi::{Int, Pointer, F32, F64};
42use rustc_target::abi::{Primitive, Size, VariantIdx, Variants};
3dfed10e 43use tracing::debug;
1a4d82fc 44
dfeec247 45use libc::{c_longlong, c_uint};
dc9dc135 46use std::collections::hash_map::Entry;
b7449926
XL
47use std::fmt::{self, Write};
48use std::hash::{Hash, Hasher};
8faf50e0 49use std::iter;
ff7c6d11 50use std::path::{Path, PathBuf};
dfeec247 51use std::ptr;
1a4d82fc 52
b7449926
XL
53impl PartialEq for llvm::Metadata {
54 fn eq(&self, other: &Self) -> bool {
0731742a 55 ptr::eq(self, other)
b7449926
XL
56 }
57}
58
59impl Eq for llvm::Metadata {}
60
61impl Hash for llvm::Metadata {
62 fn hash<H: Hasher>(&self, hasher: &mut H) {
63 (self as *const Self).hash(hasher);
64 }
65}
66
67impl fmt::Debug for llvm::Metadata {
9fa01778 68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
b7449926
XL
69 (self as *const Self).fmt(f)
70 }
71}
c30ab7b3 72
54a0048b 73// From DWARF 5.
60c5eb7d 74// See http://www.dwarfstd.org/ShowIssue.php?issue=140129.1.
54a0048b 75const DW_LANG_RUST: c_uint = 0x1c;
1a4d82fc
JJ
76#[allow(non_upper_case_globals)]
77const DW_ATE_boolean: c_uint = 0x02;
78#[allow(non_upper_case_globals)]
79const DW_ATE_float: c_uint = 0x04;
80#[allow(non_upper_case_globals)]
81const DW_ATE_signed: c_uint = 0x05;
82#[allow(non_upper_case_globals)]
83const DW_ATE_unsigned: c_uint = 0x07;
84#[allow(non_upper_case_globals)]
85const DW_ATE_unsigned_char: c_uint = 0x08;
86
d9579d0f
AL
87pub const UNKNOWN_LINE_NUMBER: c_uint = 0;
88pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
1a4d82fc 89
b7449926 90pub const NO_SCOPE_METADATA: Option<&DIScope> = None;
1a4d82fc 91
85aaf69f 92#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
f9f354fc 93pub struct UniqueTypeId(Symbol);
1a4d82fc 94
60c5eb7d
XL
95/// The `TypeMap` is where the `CrateDebugContext` holds the type metadata nodes
96/// created so far. The metadata nodes are indexed by `UniqueTypeId`, and, for
97/// faster lookup, also by `Ty`. The `TypeMap` is responsible for creating
98/// `UniqueTypeId`s.
0bf4aa26 99#[derive(Default)]
b7449926 100pub struct TypeMap<'ll, 'tcx> {
60c5eb7d 101 /// The `UniqueTypeId`s created so far.
5bcae85e 102 unique_id_interner: Interner,
60c5eb7d 103 /// A map from `UniqueTypeId` to debuginfo metadata for that type. This is a 1:1 mapping.
b7449926 104 unique_id_to_metadata: FxHashMap<UniqueTypeId, &'ll DIType>,
60c5eb7d 105 /// A map from types to debuginfo metadata. This is an N:1 mapping.
b7449926 106 type_to_metadata: FxHashMap<Ty<'tcx>, &'ll DIType>,
60c5eb7d 107 /// A map from types to `UniqueTypeId`. This is an N:1 mapping.
dfeec247 108 type_to_unique_id: FxHashMap<Ty<'tcx>, UniqueTypeId>,
1a4d82fc
JJ
109}
110
b7449926 111impl TypeMap<'ll, 'tcx> {
60c5eb7d
XL
112 /// Adds a Ty to metadata mapping to the TypeMap. The method will fail if
113 /// the mapping already exists.
dfeec247 114 fn register_type_with_metadata(&mut self, type_: Ty<'tcx>, metadata: &'ll DIType) {
1a4d82fc 115 if self.type_to_metadata.insert(type_, metadata).is_some() {
60c5eb7d 116 bug!("type metadata for `Ty` '{}' is already in the `TypeMap`!", type_);
1a4d82fc
JJ
117 }
118 }
119
60c5eb7d
XL
120 /// Removes a `Ty`-to-metadata mapping.
121 /// This is useful when computing the metadata for a potentially
122 /// recursive type (e.g., a function pointer of the form:
123 ///
124 /// fn foo() -> impl Copy { foo }
125 ///
126 /// This kind of type cannot be properly represented
127 /// via LLVM debuginfo. As a workaround,
128 /// we register a temporary Ty to metadata mapping
129 /// for the function before we compute its actual metadata.
130 /// If the metadata computation ends up recursing back to the
131 /// original function, it will use the temporary mapping
132 /// for the inner self-reference, preventing us from
133 /// recursing forever.
134 ///
135 /// This function is used to remove the temporary metadata
136 /// mapping after we've computed the actual metadata.
dfeec247 137 fn remove_type(&mut self, type_: Ty<'tcx>) {
532ac7d7 138 if self.type_to_metadata.remove(type_).is_none() {
60c5eb7d 139 bug!("type metadata `Ty` '{}' is not in the `TypeMap`!", type_);
532ac7d7
XL
140 }
141 }
142
60c5eb7d
XL
143 /// Adds a `UniqueTypeId` to metadata mapping to the `TypeMap`. The method will
144 /// fail if the mapping already exists.
b7449926
XL
145 fn register_unique_id_with_metadata(
146 &mut self,
147 unique_type_id: UniqueTypeId,
148 metadata: &'ll DIType,
149 ) {
1a4d82fc 150 if self.unique_id_to_metadata.insert(unique_type_id, metadata).is_some() {
dfeec247
XL
151 bug!(
152 "type metadata for unique ID '{}' is already in the `TypeMap`!",
153 self.get_unique_type_id_as_string(unique_type_id)
154 );
1a4d82fc
JJ
155 }
156 }
157
b7449926 158 fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<&'ll DIType> {
1a4d82fc
JJ
159 self.type_to_metadata.get(&type_).cloned()
160 }
161
b7449926 162 fn find_metadata_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<&'ll DIType> {
1a4d82fc
JJ
163 self.unique_id_to_metadata.get(&unique_type_id).cloned()
164 }
165
60c5eb7d
XL
166 /// Gets the string representation of a `UniqueTypeId`. This method will fail if
167 /// the ID is unknown.
476ff2be 168 fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> &str {
1a4d82fc
JJ
169 let UniqueTypeId(interner_key) = unique_type_id;
170 self.unique_id_interner.get(interner_key)
171 }
172
60c5eb7d
XL
173 /// Gets the `UniqueTypeId` for the given type. If the `UniqueTypeId` for the given
174 /// type has been requested before, this is just a table lookup. Otherwise, an
175 /// ID will be generated and stored for later lookup.
dfeec247
XL
176 fn get_unique_type_id_of_type<'a>(
177 &mut self,
178 cx: &CodegenCx<'a, 'tcx>,
179 type_: Ty<'tcx>,
180 ) -> UniqueTypeId {
60c5eb7d 181 // Let's see if we already have something in the cache.
0bf4aa26
XL
182 if let Some(unique_type_id) = self.type_to_unique_id.get(&type_).cloned() {
183 return unique_type_id;
184 }
60c5eb7d 185 // If not, generate one.
1a4d82fc 186
c30ab7b3
SL
187 // The hasher we are using to generate the UniqueTypeId. We want
188 // something that provides more than the 64 bits of the DefaultHasher.
e74abb32 189 let mut hasher = StableHasher::new();
94b46f34 190 let mut hcx = cx.tcx.create_stable_hashing_context();
fc512014 191 let type_ = cx.tcx.erase_regions(type_);
94b46f34
XL
192 hcx.while_hashing_spans(false, |hcx| {
193 hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
194 type_.hash_stable(hcx, &mut hasher);
195 });
196 });
e74abb32 197 let unique_type_id = hasher.finish::<Fingerprint>().to_hex();
abe05a73 198
c30ab7b3 199 let key = self.unique_id_interner.intern(&unique_type_id);
1a4d82fc
JJ
200 self.type_to_unique_id.insert(type_, UniqueTypeId(key));
201
ba9703b0 202 UniqueTypeId(key)
1a4d82fc
JJ
203 }
204
60c5eb7d
XL
205 /// Gets the `UniqueTypeId` for an enum variant. Enum variants are not really
206 /// types of their own, so they need special handling. We still need a
207 /// `UniqueTypeId` for them, since to debuginfo they *are* real types.
dfeec247
XL
208 fn get_unique_type_id_of_enum_variant<'a>(
209 &mut self,
210 cx: &CodegenCx<'a, 'tcx>,
211 enum_type: Ty<'tcx>,
212 variant_name: &str,
213 ) -> UniqueTypeId {
1a4d82fc 214 let enum_type_id = self.get_unique_type_id_of_type(cx, enum_type);
dfeec247
XL
215 let enum_variant_type_id =
216 format!("{}::{}", self.get_unique_type_id_as_string(enum_type_id), variant_name);
c30ab7b3 217 let interner_key = self.unique_id_interner.intern(&enum_variant_type_id);
1a4d82fc
JJ
218 UniqueTypeId(interner_key)
219 }
532ac7d7 220
60c5eb7d
XL
221 /// Gets the unique type ID string for an enum variant part.
222 /// Variant parts are not types and shouldn't really have their own ID,
223 /// but it makes `set_members_of_composite_type()` simpler.
74b04a01
XL
224 fn get_unique_type_id_str_of_enum_variant_part(
225 &mut self,
226 enum_type_id: UniqueTypeId,
227 ) -> String {
228 format!("{}_variant_part", self.get_unique_type_id_as_string(enum_type_id))
532ac7d7 229 }
1a4d82fc
JJ
230}
231
60c5eb7d
XL
232/// A description of some recursive type. It can either be already finished (as
233/// with `FinalMetadata`) or it is not yet finished, but contains all information
234/// needed to generate the missing parts of the description. See the
235/// documentation section on Recursive Types at the top of this file for more
236/// information.
b7449926 237enum RecursiveTypeDescription<'ll, 'tcx> {
d9579d0f
AL
238 UnfinishedMetadata {
239 unfinished_type: Ty<'tcx>,
240 unique_type_id: UniqueTypeId,
b7449926 241 metadata_stub: &'ll DICompositeType,
a1dfa0c6 242 member_holding_stub: &'ll DICompositeType,
b7449926 243 member_description_factory: MemberDescriptionFactory<'ll, 'tcx>,
d9579d0f 244 },
dfeec247 245 FinalMetadata(&'ll DICompositeType),
d9579d0f
AL
246}
247
b7449926
XL
248fn create_and_register_recursive_type_forward_declaration(
249 cx: &CodegenCx<'ll, 'tcx>,
d9579d0f
AL
250 unfinished_type: Ty<'tcx>,
251 unique_type_id: UniqueTypeId,
b7449926 252 metadata_stub: &'ll DICompositeType,
a1dfa0c6 253 member_holding_stub: &'ll DICompositeType,
b7449926
XL
254 member_description_factory: MemberDescriptionFactory<'ll, 'tcx>,
255) -> RecursiveTypeDescription<'ll, 'tcx> {
60c5eb7d 256 // Insert the stub into the `TypeMap` in order to allow for recursive references.
d9579d0f 257 let mut type_map = debug_context(cx).type_map.borrow_mut();
54a0048b
SL
258 type_map.register_unique_id_with_metadata(unique_type_id, metadata_stub);
259 type_map.register_type_with_metadata(unfinished_type, metadata_stub);
d9579d0f
AL
260
261 UnfinishedMetadata {
3b2f2976
XL
262 unfinished_type,
263 unique_type_id,
264 metadata_stub,
a1dfa0c6 265 member_holding_stub,
3b2f2976 266 member_description_factory,
d9579d0f
AL
267 }
268}
269
b7449926 270impl RecursiveTypeDescription<'ll, 'tcx> {
60c5eb7d
XL
271 /// Finishes up the description of the type in question (mostly by providing
272 /// descriptions of the fields of the given type) and returns the final type
273 /// metadata.
b7449926 274 fn finalize(&self, cx: &CodegenCx<'ll, 'tcx>) -> MetadataCreationResult<'ll> {
d9579d0f
AL
275 match *self {
276 FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
277 UnfinishedMetadata {
278 unfinished_type,
279 unique_type_id,
280 metadata_stub,
a1dfa0c6 281 member_holding_stub,
d9579d0f 282 ref member_description_factory,
d9579d0f
AL
283 } => {
284 // Make sure that we have a forward declaration of the type in
285 // the TypeMap so that recursive references are possible. This
286 // will always be the case if the RecursiveTypeDescription has
287 // been properly created through the
60c5eb7d 288 // `create_and_register_recursive_type_forward_declaration()`
d9579d0f
AL
289 // function.
290 {
291 let type_map = debug_context(cx).type_map.borrow();
dfeec247
XL
292 if type_map.find_metadata_for_unique_id(unique_type_id).is_none()
293 || type_map.find_metadata_for_type(unfinished_type).is_none()
294 {
295 bug!(
296 "Forward declaration of potentially recursive type \
54a0048b 297 '{:?}' was not found in TypeMap!",
dfeec247
XL
298 unfinished_type
299 );
d9579d0f
AL
300 }
301 }
302
303 // ... then create the member descriptions ...
dfeec247 304 let member_descriptions = member_description_factory.create_member_descriptions(cx);
d9579d0f
AL
305
306 // ... and attach them to the stub to complete it.
dfeec247
XL
307 set_members_of_composite_type(
308 cx,
309 unfinished_type,
310 member_holding_stub,
311 member_descriptions,
312 );
ba9703b0 313 MetadataCreationResult::new(metadata_stub, true)
d9579d0f
AL
314 }
315 }
316 }
317}
318
60c5eb7d
XL
319/// Returns from the enclosing function if the type metadata with the given
320/// unique ID can be found in the type map.
1a4d82fc 321macro_rules! return_if_metadata_created_in_meantime {
dfeec247
XL
322 ($cx: expr, $unique_type_id: expr) => {
323 if let Some(metadata) =
324 debug_context($cx).type_map.borrow().find_metadata_for_unique_id($unique_type_id)
0bf4aa26
XL
325 {
326 return MetadataCreationResult::new(metadata, true);
b039eaaf 327 }
dfeec247 328 };
1a4d82fc
JJ
329}
330
b7449926
XL
331fn fixed_vec_metadata(
332 cx: &CodegenCx<'ll, 'tcx>,
333 unique_type_id: UniqueTypeId,
334 array_or_slice_type: Ty<'tcx>,
335 element_type: Ty<'tcx>,
336 span: Span,
337) -> MetadataCreationResult<'ll> {
d9579d0f
AL
338 let element_type_metadata = type_metadata(cx, element_type, span);
339
340 return_if_metadata_created_in_meantime!(cx, unique_type_id);
1a4d82fc 341
ff7c6d11 342 let (size, align) = cx.size_and_align_of(array_or_slice_type);
1a4d82fc 343
1b1a35ee 344 let upper_bound = match array_or_slice_type.kind() {
416331ca 345 ty::Array(_, len) => len.eval_usize(cx.tcx, ty::ParamEnv::reveal_all()) as c_longlong,
dfeec247 346 _ => -1,
d9579d0f 347 };
1a4d82fc 348
dfeec247
XL
349 let subrange =
350 unsafe { Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)) };
1a4d82fc 351
d9579d0f
AL
352 let subscripts = create_DIArray(DIB(cx), &[subrange]);
353 let metadata = unsafe {
5bcae85e 354 llvm::LLVMRustDIBuilderCreateArrayType(
d9579d0f 355 DIB(cx),
ff7c6d11 356 size.bits(),
a1dfa0c6 357 align.bits() as u32,
d9579d0f 358 element_type_metadata,
dfeec247
XL
359 subscripts,
360 )
d9579d0f 361 };
1a4d82fc 362
ba9703b0 363 MetadataCreationResult::new(metadata, false)
1a4d82fc
JJ
364}
365
b7449926
XL
366fn vec_slice_metadata(
367 cx: &CodegenCx<'ll, 'tcx>,
368 slice_ptr_type: Ty<'tcx>,
369 element_type: Ty<'tcx>,
370 unique_type_id: UniqueTypeId,
371 span: Span,
372) -> MetadataCreationResult<'ll> {
2c00a5a8 373 let data_ptr_type = cx.tcx.mk_imm_ptr(element_type);
1a4d82fc 374
ff7c6d11 375 let data_ptr_metadata = type_metadata(cx, data_ptr_type, span);
1a4d82fc 376
d9579d0f 377 return_if_metadata_created_in_meantime!(cx, unique_type_id);
1a4d82fc 378
48663c56 379 let slice_type_name = compute_debuginfo_type_name(cx.tcx, slice_ptr_type, true);
ff7c6d11
XL
380
381 let (pointer_size, pointer_align) = cx.size_and_align_of(data_ptr_type);
2c00a5a8 382 let (usize_size, usize_align) = cx.size_and_align_of(cx.tcx.types.usize);
1a4d82fc 383
b7449926 384 let member_descriptions = vec![
d9579d0f 385 MemberDescription {
0bf4aa26 386 name: "data_ptr".to_owned(),
ff7c6d11 387 type_metadata: data_ptr_metadata,
94b46f34 388 offset: Size::ZERO,
ff7c6d11
XL
389 size: pointer_size,
390 align: pointer_align,
476ff2be 391 flags: DIFlags::FlagZero,
a1dfa0c6 392 discriminant: None,
f035d41b 393 source_info: None,
d9579d0f
AL
394 },
395 MemberDescription {
0bf4aa26 396 name: "length".to_owned(),
2c00a5a8 397 type_metadata: type_metadata(cx, cx.tcx.types.usize, span),
ff7c6d11
XL
398 offset: pointer_size,
399 size: usize_size,
400 align: usize_align,
476ff2be 401 flags: DIFlags::FlagZero,
a1dfa0c6 402 discriminant: None,
f035d41b 403 source_info: None,
d9579d0f
AL
404 },
405 ];
1a4d82fc 406
7cac9316 407 let file_metadata = unknown_file_metadata(cx);
1a4d82fc 408
dfeec247
XL
409 let metadata = composite_type_metadata(
410 cx,
411 slice_ptr_type,
412 &slice_type_name[..],
413 unique_type_id,
414 member_descriptions,
415 NO_SCOPE_METADATA,
416 file_metadata,
417 span,
418 );
ff7c6d11 419 MetadataCreationResult::new(metadata, false)
d9579d0f 420}
1a4d82fc 421
b7449926
XL
422fn subroutine_type_metadata(
423 cx: &CodegenCx<'ll, 'tcx>,
424 unique_type_id: UniqueTypeId,
425 signature: ty::PolyFnSig<'tcx>,
426 span: Span,
427) -> MetadataCreationResult<'ll> {
dfeec247 428 let signature =
fc512014 429 cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), signature);
1a4d82fc 430
b7449926 431 let signature_metadata: Vec<_> = iter::once(
8faf50e0 432 // return type
1b1a35ee 433 match signature.output().kind() {
b7449926 434 ty::Tuple(ref tys) if tys.is_empty() => None,
dfeec247
XL
435 _ => Some(type_metadata(cx, signature.output(), span)),
436 },
437 )
438 .chain(
8faf50e0 439 // regular arguments
dfeec247
XL
440 signature.inputs().iter().map(|argument_type| Some(type_metadata(cx, argument_type, span))),
441 )
442 .collect();
1a4d82fc 443
d9579d0f 444 return_if_metadata_created_in_meantime!(cx, unique_type_id);
1a4d82fc 445
ba9703b0 446 MetadataCreationResult::new(
d9579d0f 447 unsafe {
5bcae85e 448 llvm::LLVMRustDIBuilderCreateSubroutineType(
d9579d0f 449 DIB(cx),
dfeec247
XL
450 create_DIArray(DIB(cx), &signature_metadata[..]),
451 )
1a4d82fc 452 },
dfeec247 453 false,
ba9703b0 454 )
1a4d82fc
JJ
455}
456
416331ca
XL
457// FIXME(1563): This is all a bit of a hack because 'trait pointer' is an ill-
458// defined concept. For the case of an actual trait pointer (i.e., `Box<Trait>`,
459// `&Trait`), `trait_object_type` should be the whole thing (e.g, `Box<Trait>`) and
460// `trait_type` should be the actual trait (e.g., `Trait`). Where the trait is part
461// of a DST struct, there is no `trait_object_type` and the results of this
1a4d82fc 462// function will be a little bit weird.
b7449926
XL
463fn trait_pointer_metadata(
464 cx: &CodegenCx<'ll, 'tcx>,
465 trait_type: Ty<'tcx>,
466 trait_object_type: Option<Ty<'tcx>>,
467 unique_type_id: UniqueTypeId,
468) -> &'ll DIType {
1a4d82fc
JJ
469 // The implementation provided here is a stub. It makes sure that the trait
470 // type is assigned the correct name, size, namespace, and source location.
416331ca 471 // However, it does not describe the trait's methods.
1a4d82fc 472
1b1a35ee 473 let containing_scope = match trait_type.kind() {
dfeec247
XL
474 ty::Dynamic(ref data, ..) => {
475 data.principal_def_id().map(|did| get_namespace_for_item(cx, did))
476 }
1a4d82fc 477 _ => {
dfeec247
XL
478 bug!(
479 "debuginfo: unexpected trait-object type in \
54a0048b 480 trait_pointer_metadata(): {:?}",
dfeec247
XL
481 trait_type
482 );
1a4d82fc
JJ
483 }
484 };
485
486 let trait_object_type = trait_object_type.unwrap_or(trait_type);
dfeec247 487 let trait_type_name = compute_debuginfo_type_name(cx.tcx, trait_object_type, false);
1a4d82fc 488
5bcae85e 489 let file_metadata = unknown_file_metadata(cx);
1a4d82fc 490
2c00a5a8 491 let layout = cx.layout_of(cx.tcx.mk_mut_ptr(trait_type));
abe05a73
XL
492
493 assert_eq!(abi::FAT_PTR_ADDR, 0);
494 assert_eq!(abi::FAT_PTR_EXTRA, 1);
ff7c6d11
XL
495
496 let data_ptr_field = layout.field(cx, 0);
497 let vtable_field = layout.field(cx, 1);
b7449926 498 let member_descriptions = vec![
abe05a73 499 MemberDescription {
0bf4aa26 500 name: "pointer".to_owned(),
dfeec247
XL
501 type_metadata: type_metadata(
502 cx,
2c00a5a8 503 cx.tcx.mk_mut_ptr(cx.tcx.types.u8),
dfeec247
XL
504 rustc_span::DUMMY_SP,
505 ),
ff7c6d11
XL
506 offset: layout.fields.offset(0),
507 size: data_ptr_field.size,
a1dfa0c6 508 align: data_ptr_field.align.abi,
abe05a73 509 flags: DIFlags::FlagArtificial,
a1dfa0c6 510 discriminant: None,
f035d41b 511 source_info: None,
abe05a73
XL
512 },
513 MemberDescription {
0bf4aa26 514 name: "vtable".to_owned(),
dfeec247 515 type_metadata: type_metadata(cx, vtable_field.ty, rustc_span::DUMMY_SP),
ff7c6d11
XL
516 offset: layout.fields.offset(1),
517 size: vtable_field.size,
a1dfa0c6 518 align: vtable_field.align.abi,
abe05a73 519 flags: DIFlags::FlagArtificial,
a1dfa0c6 520 discriminant: None,
f035d41b 521 source_info: None,
abe05a73
XL
522 },
523 ];
524
dfeec247
XL
525 composite_type_metadata(
526 cx,
527 trait_object_type,
528 &trait_type_name[..],
529 unique_type_id,
530 member_descriptions,
531 containing_scope,
532 file_metadata,
533 rustc_span::DUMMY_SP,
534 )
1a4d82fc
JJ
535}
536
dfeec247 537pub fn type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>, usage_site_span: Span) -> &'ll DIType {
60c5eb7d 538 // Get the unique type ID of this type.
1a4d82fc
JJ
539 let unique_type_id = {
540 let mut type_map = debug_context(cx).type_map.borrow_mut();
60c5eb7d 541 // First, try to find the type in `TypeMap`. If we have seen it before, we
1a4d82fc
JJ
542 // can exit early here.
543 match type_map.find_metadata_for_type(t) {
544 Some(metadata) => {
545 return metadata;
dfeec247 546 }
1a4d82fc 547 None => {
60c5eb7d 548 // The Ty is not in the `TypeMap` but maybe we have already seen
0731742a 549 // an equivalent type (e.g., only differing in region arguments).
60c5eb7d 550 // In order to find out, generate the unique type ID and look
1a4d82fc
JJ
551 // that up.
552 let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
553 match type_map.find_metadata_for_unique_id(unique_type_id) {
554 Some(metadata) => {
555 // There is already an equivalent type in the TypeMap.
556 // Register this Ty as an alias in the cache and
557 // return the cached metadata.
54a0048b 558 type_map.register_type_with_metadata(t, metadata);
1a4d82fc 559 return metadata;
dfeec247 560 }
1a4d82fc
JJ
561 None => {
562 // There really is no type metadata for this type, so
563 // proceed by creating it.
564 unique_type_id
565 }
566 }
567 }
568 }
569 };
570
571 debug!("type_metadata: {:?}", t);
572
1b1a35ee 573 let ptr_metadata = |ty: Ty<'tcx>| match *ty.kind() {
dfeec247
XL
574 ty::Slice(typ) => Ok(vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span)),
575 ty::Str => Ok(vec_slice_metadata(cx, t, cx.tcx.types.u8, unique_type_id, usage_site_span)),
576 ty::Dynamic(..) => Ok(MetadataCreationResult::new(
577 trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
578 false,
579 )),
580 _ => {
581 let pointee_metadata = type_metadata(cx, ty, usage_site_span);
32a655c1 582
dfeec247
XL
583 if let Some(metadata) =
584 debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id)
585 {
586 return Err(metadata);
32a655c1 587 }
dfeec247
XL
588
589 Ok(MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata), false))
32a655c1
SL
590 }
591 };
592
1b1a35ee 593 let MetadataCreationResult { metadata, already_stored_in_typemap } = match *t.kind() {
dfeec247 594 ty::Never | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => {
1a4d82fc
JJ
595 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
596 }
b7449926 597 ty::Tuple(ref elements) if elements.is_empty() => {
1a4d82fc
JJ
598 MetadataCreationResult::new(basic_type_metadata(cx, t), false)
599 }
dfeec247 600 ty::Array(typ, _) | ty::Slice(typ) => {
ff7c6d11 601 fixed_vec_metadata(cx, unique_type_id, t, typ, usage_site_span)
85aaf69f 602 }
dfeec247 603 ty::Str => fixed_vec_metadata(cx, unique_type_id, t, cx.tcx.types.i8, usage_site_span),
b7449926 604 ty::Dynamic(..) => {
dfeec247 605 MetadataCreationResult::new(trait_pointer_metadata(cx, t, None, unique_type_id), false)
1a4d82fc 606 }
b7449926 607 ty::Foreign(..) => {
dfeec247 608 MetadataCreationResult::new(foreign_type_metadata(cx, t, unique_type_id), false)
1a4d82fc 609 }
dfeec247
XL
610 ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _) => match ptr_metadata(ty) {
611 Ok(res) => res,
612 Err(metadata) => return metadata,
613 },
614 ty::Adt(def, _) if def.is_box() => match ptr_metadata(t.boxed_ty()) {
615 Ok(res) => res,
616 Err(metadata) => return metadata,
617 },
b7449926 618 ty::FnDef(..) | ty::FnPtr(_) => {
dfeec247
XL
619 if let Some(metadata) =
620 debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id)
0bf4aa26
XL
621 {
622 return metadata;
623 }
c1a9b12d 624
532ac7d7
XL
625 // It's possible to create a self-referential
626 // type in Rust by using 'impl trait':
627 //
628 // fn foo() -> impl Copy { foo }
629 //
60c5eb7d
XL
630 // See `TypeMap::remove_type` for more detals
631 // about the workaround.
532ac7d7
XL
632
633 let temp_type = {
634 unsafe {
635 // The choice of type here is pretty arbitrary -
636 // anything reading the debuginfo for a recursive
74b04a01 637 // type is going to see *something* weird - the only
60c5eb7d 638 // question is what exactly it will see.
74b04a01 639 let name = "<recur_type>";
532ac7d7
XL
640 llvm::LLVMRustDIBuilderCreateBasicType(
641 DIB(cx),
74b04a01
XL
642 name.as_ptr().cast(),
643 name.len(),
f9f354fc 644 cx.size_of(t).bits(),
dfeec247
XL
645 DW_ATE_unsigned,
646 )
532ac7d7
XL
647 }
648 };
649
650 let type_map = &debug_context(cx).type_map;
651 type_map.borrow_mut().register_type_with_metadata(t, temp_type);
652
dfeec247
XL
653 let fn_metadata =
654 subroutine_type_metadata(cx, unique_type_id, t.fn_sig(cx.tcx), usage_site_span)
655 .metadata;
532ac7d7
XL
656
657 type_map.borrow_mut().remove_type(t);
658
60c5eb7d 659 // This is actually a function pointer, so wrap it in pointer DI.
c1a9b12d 660 MetadataCreationResult::new(pointer_type_metadata(cx, t, fn_metadata), false)
1a4d82fc 661 }
b7449926 662 ty::Closure(def_id, substs) => {
ba9703b0 663 let upvar_tys: Vec<_> = substs.as_closure().upvar_tys().collect();
416331ca 664 let containing_scope = get_namespace_for_item(cx, def_id);
dfeec247
XL
665 prepare_tuple_metadata(
666 cx,
667 t,
668 &upvar_tys,
669 unique_type_id,
670 usage_site_span,
671 Some(containing_scope),
672 )
673 .finalize(cx)
1a4d82fc 674 }
dfeec247
XL
675 ty::Generator(def_id, substs, _) => {
676 let upvar_tys: Vec<_> = substs
677 .as_generator()
ba9703b0 678 .prefix_tys()
dfeec247
XL
679 .map(|t| cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
680 .collect();
681 prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span, upvar_tys)
682 .finalize(cx)
ea8adc8c 683 }
b7449926 684 ty::Adt(def, ..) => match def.adt_kind() {
9e0c209e 685 AdtKind::Struct => {
dfeec247 686 prepare_struct_metadata(cx, t, unique_type_id, usage_site_span).finalize(cx)
9e0c209e
SL
687 }
688 AdtKind::Union => {
dfeec247 689 prepare_union_metadata(cx, t, unique_type_id, usage_site_span).finalize(cx)
9e0c209e
SL
690 }
691 AdtKind::Enum => {
dfeec247
XL
692 prepare_enum_metadata(cx, t, def.did, unique_type_id, usage_site_span, vec![])
693 .finalize(cx)
9e0c209e
SL
694 }
695 },
b7449926 696 ty::Tuple(ref elements) => {
48663c56 697 let tys: Vec<_> = elements.iter().map(|k| k.expect_ty()).collect();
dfeec247
XL
698 prepare_tuple_metadata(cx, t, &tys, unique_type_id, usage_site_span, NO_SCOPE_METADATA)
699 .finalize(cx)
1a4d82fc 700 }
3dfed10e
XL
701 // Type parameters from polymorphized functions.
702 ty::Param(_) => MetadataCreationResult::new(param_type_metadata(cx, t), false),
dfeec247 703 _ => bug!("debuginfo: unexpected type in type_metadata: {:?}", t),
1a4d82fc
JJ
704 };
705
706 {
707 let mut type_map = debug_context(cx).type_map.borrow_mut();
708
709 if already_stored_in_typemap {
60c5eb7d 710 // Also make sure that we already have a `TypeMap` entry for the unique type ID.
1a4d82fc
JJ
711 let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
712 Some(metadata) => metadata,
713 None => {
dfeec247
XL
714 span_bug!(
715 usage_site_span,
716 "expected type metadata for unique \
60c5eb7d
XL
717 type ID '{}' to already be in \
718 the `debuginfo::TypeMap` but it \
54a0048b 719 was not. (Ty = {})",
dfeec247
XL
720 type_map.get_unique_type_id_as_string(unique_type_id),
721 t
722 );
1a4d82fc
JJ
723 }
724 };
725
726 match type_map.find_metadata_for_type(t) {
727 Some(metadata) => {
728 if metadata != metadata_for_uid {
dfeec247
XL
729 span_bug!(
730 usage_site_span,
731 "mismatch between `Ty` and \
60c5eb7d
XL
732 `UniqueTypeId` maps in \
733 `debuginfo::TypeMap`. \
54a0048b 734 UniqueTypeId={}, Ty={}",
dfeec247
XL
735 type_map.get_unique_type_id_as_string(unique_type_id),
736 t
737 );
1a4d82fc
JJ
738 }
739 }
740 None => {
54a0048b 741 type_map.register_type_with_metadata(t, metadata);
1a4d82fc
JJ
742 }
743 }
744 } else {
54a0048b
SL
745 type_map.register_type_with_metadata(t, metadata);
746 type_map.register_unique_id_with_metadata(unique_type_id, metadata);
1a4d82fc
JJ
747 }
748 }
749
750 metadata
751}
752
ba9703b0
XL
753fn hex_encode(data: &[u8]) -> String {
754 let mut hex_string = String::with_capacity(data.len() * 2);
755 for byte in data.iter() {
756 write!(&mut hex_string, "{:02x}", byte).unwrap();
757 }
758 hex_string
759}
760
29967ef6
XL
761pub fn file_metadata(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) -> &'ll DIFile {
762 debug!("file_metadata: file_name: {}", source_file.name);
7cac9316 763
ba9703b0
XL
764 let hash = Some(&source_file.src_hash);
765 let file_name = Some(source_file.name.to_string());
29967ef6 766 let directory = if source_file.is_real_file() && !source_file.is_imported() {
dc9dc135 767 Some(cx.sess().working_dir.0.to_string_lossy().to_string())
7cac9316
XL
768 } else {
769 // If the path comes from an upstream crate we assume it has been made
770 // independent of the compiler's working directory one way or another.
dc9dc135
XL
771 None
772 };
ba9703b0 773 file_metadata_raw(cx, file_name, directory, hash)
e9174d1e
SL
774}
775
b7449926 776pub fn unknown_file_metadata(cx: &CodegenCx<'ll, '_>) -> &'ll DIFile {
ba9703b0 777 file_metadata_raw(cx, None, None, None)
e9174d1e
SL
778}
779
dfeec247
XL
780fn file_metadata_raw(
781 cx: &CodegenCx<'ll, '_>,
782 file_name: Option<String>,
783 directory: Option<String>,
ba9703b0 784 hash: Option<&SourceFileHash>,
dfeec247 785) -> &'ll DIFile {
dc9dc135
XL
786 let key = (file_name, directory);
787
788 match debug_context(cx).created_files.borrow_mut().entry(key) {
ba9703b0 789 Entry::Occupied(o) => o.get(),
dc9dc135
XL
790 Entry::Vacant(v) => {
791 let (file_name, directory) = v.key();
792 debug!("file_metadata: file_name: {:?}, directory: {:?}", file_name, directory);
793
74b04a01
XL
794 let file_name = file_name.as_deref().unwrap_or("<unknown>");
795 let directory = directory.as_deref().unwrap_or("");
dc9dc135 796
ba9703b0
XL
797 let (hash_kind, hash_value) = match hash {
798 Some(hash) => {
799 let kind = match hash.kind {
800 rustc_span::SourceFileHashAlgorithm::Md5 => llvm::ChecksumKind::MD5,
801 rustc_span::SourceFileHashAlgorithm::Sha1 => llvm::ChecksumKind::SHA1,
29967ef6 802 rustc_span::SourceFileHashAlgorithm::Sha256 => llvm::ChecksumKind::SHA256,
ba9703b0
XL
803 };
804 (kind, hex_encode(hash.hash_bytes()))
805 }
806 None => (llvm::ChecksumKind::None, String::new()),
807 };
808
dc9dc135 809 let file_metadata = unsafe {
74b04a01
XL
810 llvm::LLVMRustDIBuilderCreateFile(
811 DIB(cx),
812 file_name.as_ptr().cast(),
813 file_name.len(),
814 directory.as_ptr().cast(),
815 directory.len(),
ba9703b0
XL
816 hash_kind,
817 hash_value.as_ptr().cast(),
818 hash_value.len(),
74b04a01 819 )
dc9dc135 820 };
7cac9316 821
dc9dc135
XL
822 v.insert(file_metadata);
823 file_metadata
824 }
e9174d1e 825 }
d9579d0f
AL
826}
827
f035d41b
XL
828trait MsvcBasicName {
829 fn msvc_basic_name(self) -> &'static str;
830}
831
5869c6ff 832impl MsvcBasicName for ty::IntTy {
f035d41b
XL
833 fn msvc_basic_name(self) -> &'static str {
834 match self {
5869c6ff
XL
835 ty::IntTy::Isize => "ptrdiff_t",
836 ty::IntTy::I8 => "__int8",
837 ty::IntTy::I16 => "__int16",
838 ty::IntTy::I32 => "__int32",
839 ty::IntTy::I64 => "__int64",
840 ty::IntTy::I128 => "__int128",
f035d41b
XL
841 }
842 }
843}
844
5869c6ff 845impl MsvcBasicName for ty::UintTy {
f035d41b
XL
846 fn msvc_basic_name(self) -> &'static str {
847 match self {
5869c6ff
XL
848 ty::UintTy::Usize => "size_t",
849 ty::UintTy::U8 => "unsigned __int8",
850 ty::UintTy::U16 => "unsigned __int16",
851 ty::UintTy::U32 => "unsigned __int32",
852 ty::UintTy::U64 => "unsigned __int64",
853 ty::UintTy::U128 => "unsigned __int128",
f035d41b
XL
854 }
855 }
856}
857
5869c6ff 858impl MsvcBasicName for ty::FloatTy {
f035d41b
XL
859 fn msvc_basic_name(self) -> &'static str {
860 match self {
5869c6ff
XL
861 ty::FloatTy::F32 => "float",
862 ty::FloatTy::F64 => "double",
f035d41b
XL
863 }
864 }
865}
866
b7449926 867fn basic_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
d9579d0f
AL
868 debug!("basic_type_metadata: {:?}", t);
869
f035d41b
XL
870 // When targeting MSVC, emit MSVC style type names for compatibility with
871 // .natvis visualizers (and perhaps other existing native debuggers?)
29967ef6 872 let msvc_like_names = cx.tcx.sess.target.is_like_msvc;
f035d41b 873
1b1a35ee 874 let (name, encoding) = match t.kind() {
b7449926 875 ty::Never => ("!", DW_ATE_unsigned),
dfeec247 876 ty::Tuple(ref elements) if elements.is_empty() => ("()", DW_ATE_unsigned),
b7449926
XL
877 ty::Bool => ("bool", DW_ATE_boolean),
878 ty::Char => ("char", DW_ATE_unsigned_char),
f035d41b
XL
879 ty::Int(int_ty) if msvc_like_names => (int_ty.msvc_basic_name(), DW_ATE_signed),
880 ty::Uint(uint_ty) if msvc_like_names => (uint_ty.msvc_basic_name(), DW_ATE_unsigned),
881 ty::Float(float_ty) if msvc_like_names => (float_ty.msvc_basic_name(), DW_ATE_float),
dfeec247
XL
882 ty::Int(int_ty) => (int_ty.name_str(), DW_ATE_signed),
883 ty::Uint(uint_ty) => (uint_ty.name_str(), DW_ATE_unsigned),
884 ty::Float(float_ty) => (float_ty.name_str(), DW_ATE_float),
885 _ => bug!("debuginfo::basic_type_metadata - `t` is invalid type"),
d9579d0f
AL
886 };
887
d9579d0f 888 let ty_metadata = unsafe {
5bcae85e 889 llvm::LLVMRustDIBuilderCreateBasicType(
d9579d0f 890 DIB(cx),
74b04a01
XL
891 name.as_ptr().cast(),
892 name.len(),
f9f354fc 893 cx.size_of(t).bits(),
dfeec247
XL
894 encoding,
895 )
d9579d0f
AL
896 };
897
f035d41b
XL
898 if !msvc_like_names {
899 return ty_metadata;
900 }
901
1b1a35ee 902 let typedef_name = match t.kind() {
f035d41b
XL
903 ty::Int(int_ty) => int_ty.name_str(),
904 ty::Uint(uint_ty) => uint_ty.name_str(),
905 ty::Float(float_ty) => float_ty.name_str(),
906 _ => return ty_metadata,
907 };
908
909 let typedef_metadata = unsafe {
910 llvm::LLVMRustDIBuilderCreateTypedef(
911 DIB(cx),
912 ty_metadata,
913 typedef_name.as_ptr().cast(),
914 typedef_name.len(),
915 unknown_file_metadata(cx),
916 0,
917 None,
918 )
919 };
920
921 typedef_metadata
d9579d0f
AL
922}
923
b7449926
XL
924fn foreign_type_metadata(
925 cx: &CodegenCx<'ll, 'tcx>,
926 t: Ty<'tcx>,
927 unique_type_id: UniqueTypeId,
928) -> &'ll DIType {
abe05a73
XL
929 debug!("foreign_type_metadata: {:?}", t);
930
48663c56 931 let name = compute_debuginfo_type_name(cx.tcx, t, false);
f035d41b 932 create_struct_stub(cx, t, &name, unique_type_id, NO_SCOPE_METADATA, DIFlags::FlagZero)
abe05a73
XL
933}
934
b7449926
XL
935fn pointer_type_metadata(
936 cx: &CodegenCx<'ll, 'tcx>,
937 pointer_type: Ty<'tcx>,
938 pointee_type_metadata: &'ll DIType,
939) -> &'ll DIType {
ff7c6d11 940 let (pointer_size, pointer_align) = cx.size_and_align_of(pointer_type);
48663c56 941 let name = compute_debuginfo_type_name(cx.tcx, pointer_type, false);
ff7c6d11 942 unsafe {
5bcae85e 943 llvm::LLVMRustDIBuilderCreatePointerType(
d9579d0f
AL
944 DIB(cx),
945 pointee_type_metadata,
ff7c6d11 946 pointer_size.bits(),
a1dfa0c6 947 pointer_align.bits() as u32,
74b04a01
XL
948 0, // Ignore DWARF address space.
949 name.as_ptr().cast(),
950 name.len(),
dfeec247 951 )
ff7c6d11 952 }
d9579d0f
AL
953}
954
3dfed10e
XL
955fn param_type_metadata(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
956 debug!("param_type_metadata: {:?}", t);
957 let name = format!("{:?}", t);
958 unsafe {
959 llvm::LLVMRustDIBuilderCreateBasicType(
960 DIB(cx),
961 name.as_ptr().cast(),
962 name.len(),
963 Size::ZERO.bits(),
964 DW_ATE_unsigned,
965 )
966 }
967}
968
dc9dc135
XL
969pub fn compile_unit_metadata(
970 tcx: TyCtxt<'_>,
971 codegen_unit_name: &str,
972 debug_context: &CrateDebugContext<'ll, '_>,
973) -> &'ll DIDescriptor {
2c00a5a8 974 let mut name_in_debuginfo = match tcx.sess.local_crate_source_file {
7cac9316 975 Some(ref path) => path.clone(),
2c00a5a8 976 None => PathBuf::from(&*tcx.crate_name(LOCAL_CRATE).as_str()),
d9579d0f
AL
977 };
978
7cac9316 979 // The OSX linker has an idiosyncrasy where it will ignore some debuginfo
60c5eb7d 980 // if multiple object files with the same `DW_AT_name` are linked together.
7cac9316 981 // As a workaround we generate unique names for each object file. Those do
6a06907d 982 // not correspond to an actual source file but that is harmless.
29967ef6 983 if tcx.sess.target.is_like_osx {
ff7c6d11
XL
984 name_in_debuginfo.push("@");
985 name_in_debuginfo.push(codegen_unit_name);
7cac9316
XL
986 }
987
988 debug!("compile_unit_metadata: {:?}", name_in_debuginfo);
dfeec247
XL
989 let rustc_producer =
990 format!("rustc version {}", option_env!("CFG_VERSION").expect("CFG_VERSION"),);
cc61c64b 991 // FIXME(#41252) Remove "clang LLVM" if we can get GDB and LLVM to play nice.
416331ca 992 let producer = format!("clang LLVM ({})", rustc_producer);
d9579d0f 993
b7449926 994 let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
6a06907d 995 let work_dir = tcx.sess.working_dir.0.to_string_lossy();
d9579d0f 996 let flags = "\0";
fc512014 997 let out_dir = &tcx.output_filenames(LOCAL_CRATE).out_directory;
5869c6ff
XL
998 let split_name = if tcx.sess.target_can_use_split_dwarf() {
999 tcx.output_filenames(LOCAL_CRATE)
6a06907d
XL
1000 .split_dwarf_path(tcx.sess.split_debuginfo(), Some(codegen_unit_name))
1001 .map(|f| out_dir.join(f))
5869c6ff
XL
1002 } else {
1003 None
1004 }
1005 .unwrap_or_default();
fc512014 1006 let split_name = split_name.to_str().unwrap();
48663c56
XL
1007
1008 // FIXME(#60020):
1009 //
1010 // This should actually be
1011 //
60c5eb7d 1012 // let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
48663c56 1013 //
60c5eb7d 1014 // That is, we should set LLVM's emission kind to `LineTablesOnly` if
48663c56
XL
1015 // we are compiling with "limited" debuginfo. However, some of the
1016 // existing tools relied on slightly more debuginfo being generated than
1017 // would be the case with `LineTablesOnly`, and we did not want to break
1018 // these tools in a "drive-by fix", without a good idea or plan about
1019 // what limited debuginfo should exactly look like. So for now we keep
1020 // the emission kind as `FullDebug`.
1021 //
1022 // See https://github.com/rust-lang/rust/issues/60020 for details.
1023 let kind = DebugEmissionKind::FullDebug;
1024 assert!(tcx.sess.opts.debuginfo != DebugInfo::None);
8bb4bdeb
XL
1025
1026 unsafe {
6a06907d 1027 let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile(
dfeec247 1028 debug_context.builder,
74b04a01
XL
1029 name_in_debuginfo.as_ptr().cast(),
1030 name_in_debuginfo.len(),
6a06907d
XL
1031 work_dir.as_ptr().cast(),
1032 work_dir.len(),
ba9703b0
XL
1033 llvm::ChecksumKind::None,
1034 ptr::null(),
1035 0,
dfeec247 1036 );
8bb4bdeb 1037
041b39d2 1038 let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
5bcae85e 1039 debug_context.builder,
d9579d0f 1040 DW_LANG_RUST,
6a06907d 1041 compile_unit_file,
74b04a01
XL
1042 producer.as_ptr().cast(),
1043 producer.len(),
2c00a5a8 1044 tcx.sess.opts.optimize != config::OptLevel::No,
e74abb32 1045 flags.as_ptr().cast(),
d9579d0f 1046 0,
6a06907d
XL
1047 // NB: this doesn't actually have any perceptible effect, it seems. LLVM will instead
1048 // put the path supplied to `MCSplitDwarfFile` into the debug info of the final
1049 // output(s).
e74abb32 1050 split_name.as_ptr().cast(),
74b04a01 1051 split_name.len(),
dfeec247 1052 kind,
fc512014
XL
1053 0,
1054 tcx.sess.opts.debugging_opts.split_dwarf_inlining,
dfeec247 1055 );
041b39d2 1056
2c00a5a8 1057 if tcx.sess.opts.debugging_opts.profile {
dfeec247
XL
1058 let cu_desc_metadata =
1059 llvm::LLVMRustMetadataAsValue(debug_context.llcontext, unit_metadata);
f9f354fc
XL
1060 let default_gcda_path = &tcx.output_filenames(LOCAL_CRATE).with_extension("gcda");
1061 let gcda_path =
1062 tcx.sess.opts.debugging_opts.profile_emit.as_ref().unwrap_or(default_gcda_path);
041b39d2
XL
1063
1064 let gcov_cu_info = [
dfeec247
XL
1065 path_to_mdstring(
1066 debug_context.llcontext,
1067 &tcx.output_filenames(LOCAL_CRATE).with_extension("gcno"),
1068 ),
f9f354fc 1069 path_to_mdstring(debug_context.llcontext, &gcda_path),
041b39d2
XL
1070 cu_desc_metadata,
1071 ];
dfeec247
XL
1072 let gcov_metadata = llvm::LLVMMDNodeInContext(
1073 debug_context.llcontext,
1074 gcov_cu_info.as_ptr(),
1075 gcov_cu_info.len() as c_uint,
1076 );
041b39d2 1077
6a06907d 1078 let llvm_gcov_ident = cstr!("llvm.gcov");
dfeec247
XL
1079 llvm::LLVMAddNamedMetadataOperand(
1080 debug_context.llmod,
1081 llvm_gcov_ident.as_ptr(),
1082 gcov_metadata,
1083 );
041b39d2
XL
1084 }
1085
416331ca
XL
1086 // Insert `llvm.ident` metadata on the wasm32 targets since that will
1087 // get hooked up to the "producer" sections `processed-by` information.
1088 if tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
1089 let name_metadata = llvm::LLVMMDStringInContext(
1090 debug_context.llcontext,
e74abb32 1091 rustc_producer.as_ptr().cast(),
416331ca
XL
1092 rustc_producer.as_bytes().len() as c_uint,
1093 );
1094 llvm::LLVMAddNamedMetadataOperand(
1095 debug_context.llmod,
6a06907d 1096 cstr!("llvm.ident").as_ptr(),
416331ca
XL
1097 llvm::LLVMMDNodeInContext(debug_context.llcontext, &name_metadata, 1),
1098 );
1099 }
1100
041b39d2 1101 return unit_metadata;
d9579d0f 1102 };
041b39d2 1103
b7449926 1104 fn path_to_mdstring(llcx: &'ll llvm::Context, path: &Path) -> &'ll Value {
a1dfa0c6 1105 let path_str = path_to_c_string(path);
041b39d2 1106 unsafe {
dfeec247
XL
1107 llvm::LLVMMDStringInContext(
1108 llcx,
1109 path_str.as_ptr(),
1110 path_str.as_bytes().len() as c_uint,
1111 )
041b39d2
XL
1112 }
1113 }
d9579d0f
AL
1114}
1115
b7449926
XL
1116struct MetadataCreationResult<'ll> {
1117 metadata: &'ll DIType,
dfeec247 1118 already_stored_in_typemap: bool,
1a4d82fc
JJ
1119}
1120
b7449926
XL
1121impl MetadataCreationResult<'ll> {
1122 fn new(metadata: &'ll DIType, already_stored_in_typemap: bool) -> Self {
dfeec247 1123 MetadataCreationResult { metadata, already_stored_in_typemap }
1a4d82fc
JJ
1124 }
1125}
1126
f035d41b
XL
1127#[derive(Debug)]
1128struct SourceInfo<'ll> {
1129 file: &'ll DIFile,
1130 line: u32,
1131}
1132
60c5eb7d
XL
1133/// Description of a type member, which can either be a regular field (as in
1134/// structs or tuples) or an enum variant.
d9579d0f 1135#[derive(Debug)]
b7449926 1136struct MemberDescription<'ll> {
d9579d0f 1137 name: String,
b7449926 1138 type_metadata: &'ll DIType,
ff7c6d11
XL
1139 offset: Size,
1140 size: Size,
1141 align: Align,
476ff2be 1142 flags: DIFlags,
a1dfa0c6 1143 discriminant: Option<u64>,
f035d41b 1144 source_info: Option<SourceInfo<'ll>>,
d9579d0f
AL
1145}
1146
48663c56 1147impl<'ll> MemberDescription<'ll> {
dfeec247
XL
1148 fn into_metadata(
1149 self,
1150 cx: &CodegenCx<'ll, '_>,
1151 composite_type_metadata: &'ll DIScope,
1152 ) -> &'ll DIType {
f035d41b
XL
1153 let (file, line) = self
1154 .source_info
1155 .map(|info| (info.file, info.line))
1156 .unwrap_or_else(|| (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER));
48663c56
XL
1157 unsafe {
1158 llvm::LLVMRustDIBuilderCreateVariantMemberType(
1159 DIB(cx),
1160 composite_type_metadata,
74b04a01
XL
1161 self.name.as_ptr().cast(),
1162 self.name.len(),
f035d41b
XL
1163 file,
1164 line,
48663c56
XL
1165 self.size.bits(),
1166 self.align.bits() as u32,
1167 self.offset.bits(),
fc512014 1168 self.discriminant.map(|v| cx.const_u64(v)),
48663c56 1169 self.flags,
dfeec247
XL
1170 self.type_metadata,
1171 )
48663c56
XL
1172 }
1173 }
1174}
1175
60c5eb7d
XL
1176/// A factory for `MemberDescription`s. It produces a list of member descriptions
1177/// for some record-like type. `MemberDescriptionFactory`s are used to defer the
1178/// creation of type member descriptions in order to break cycles arising from
1179/// recursive type definitions.
b7449926 1180enum MemberDescriptionFactory<'ll, 'tcx> {
d9579d0f
AL
1181 StructMDF(StructMemberDescriptionFactory<'tcx>),
1182 TupleMDF(TupleMemberDescriptionFactory<'tcx>),
b7449926 1183 EnumMDF(EnumMemberDescriptionFactory<'ll, 'tcx>),
9e0c209e 1184 UnionMDF(UnionMemberDescriptionFactory<'tcx>),
dfeec247 1185 VariantMDF(VariantMemberDescriptionFactory<'ll, 'tcx>),
d9579d0f
AL
1186}
1187
b7449926 1188impl MemberDescriptionFactory<'ll, 'tcx> {
dfeec247 1189 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) -> Vec<MemberDescription<'ll>> {
d9579d0f 1190 match *self {
dfeec247
XL
1191 StructMDF(ref this) => this.create_member_descriptions(cx),
1192 TupleMDF(ref this) => this.create_member_descriptions(cx),
1193 EnumMDF(ref this) => this.create_member_descriptions(cx),
1194 UnionMDF(ref this) => this.create_member_descriptions(cx),
1195 VariantMDF(ref this) => this.create_member_descriptions(cx),
d9579d0f
AL
1196 }
1197 }
1198}
1199
1200//=-----------------------------------------------------------------------------
1201// Structs
1202//=-----------------------------------------------------------------------------
1203
60c5eb7d 1204/// Creates `MemberDescription`s for the fields of a struct.
d9579d0f 1205struct StructMemberDescriptionFactory<'tcx> {
476ff2be
SL
1206 ty: Ty<'tcx>,
1207 variant: &'tcx ty::VariantDef,
d9579d0f
AL
1208 span: Span,
1209}
1210
1211impl<'tcx> StructMemberDescriptionFactory<'tcx> {
dfeec247 1212 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) -> Vec<MemberDescription<'ll>> {
476ff2be 1213 let layout = cx.layout_of(self.ty);
dfeec247
XL
1214 self.variant
1215 .fields
1216 .iter()
1217 .enumerate()
1218 .map(|(i, f)| {
1219 let name = if self.variant.ctor_kind == CtorKind::Fn {
1220 format!("__{}", i)
1221 } else {
1222 f.ident.to_string()
1223 };
1224 let field = layout.field(cx, i);
1225 MemberDescription {
1226 name,
1227 type_metadata: type_metadata(cx, field.ty, self.span),
1228 offset: layout.fields.offset(i),
1229 size: field.size,
1230 align: field.align.abi,
1231 flags: DIFlags::FlagZero,
1232 discriminant: None,
f035d41b 1233 source_info: None,
dfeec247
XL
1234 }
1235 })
1236 .collect()
1a4d82fc
JJ
1237 }
1238}
1239
b7449926
XL
1240fn prepare_struct_metadata(
1241 cx: &CodegenCx<'ll, 'tcx>,
1242 struct_type: Ty<'tcx>,
1243 unique_type_id: UniqueTypeId,
1244 span: Span,
1245) -> RecursiveTypeDescription<'ll, 'tcx> {
48663c56 1246 let struct_name = compute_debuginfo_type_name(cx.tcx, struct_type, false);
d9579d0f 1247
1b1a35ee 1248 let (struct_def_id, variant) = match struct_type.kind() {
b7449926 1249 ty::Adt(def, _) => (def.did, def.non_enum_variant()),
dfeec247 1250 _ => bug!("prepare_struct_metadata on a non-ADT"),
e9174d1e
SL
1251 };
1252
041b39d2 1253 let containing_scope = get_namespace_for_item(cx, struct_def_id);
1a4d82fc 1254
f035d41b
XL
1255 let struct_metadata_stub = create_struct_stub(
1256 cx,
1257 struct_type,
1258 &struct_name,
1259 unique_type_id,
1260 Some(containing_scope),
1261 DIFlags::FlagZero,
1262 );
85aaf69f 1263
d9579d0f
AL
1264 create_and_register_recursive_type_forward_declaration(
1265 cx,
1266 struct_type,
1267 unique_type_id,
1268 struct_metadata_stub,
a1dfa0c6 1269 struct_metadata_stub,
dfeec247 1270 StructMDF(StructMemberDescriptionFactory { ty: struct_type, variant, span }),
d9579d0f 1271 )
1a4d82fc
JJ
1272}
1273
1274//=-----------------------------------------------------------------------------
d9579d0f 1275// Tuples
1a4d82fc
JJ
1276//=-----------------------------------------------------------------------------
1277
60c5eb7d 1278/// Creates `MemberDescription`s for the fields of a tuple.
d9579d0f 1279struct TupleMemberDescriptionFactory<'tcx> {
476ff2be 1280 ty: Ty<'tcx>,
d9579d0f
AL
1281 component_types: Vec<Ty<'tcx>>,
1282 span: Span,
1a4d82fc
JJ
1283}
1284
d9579d0f 1285impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
dfeec247 1286 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) -> Vec<MemberDescription<'ll>> {
476ff2be 1287 let layout = cx.layout_of(self.ty);
dfeec247
XL
1288 self.component_types
1289 .iter()
1290 .enumerate()
1291 .map(|(i, &component_type)| {
1292 let (size, align) = cx.size_and_align_of(component_type);
1293 MemberDescription {
1294 name: format!("__{}", i),
1295 type_metadata: type_metadata(cx, component_type, self.span),
1296 offset: layout.fields.offset(i),
1297 size,
1298 align,
1299 flags: DIFlags::FlagZero,
1300 discriminant: None,
f035d41b 1301 source_info: None,
dfeec247
XL
1302 }
1303 })
1304 .collect()
d9579d0f 1305 }
1a4d82fc
JJ
1306}
1307
b7449926
XL
1308fn prepare_tuple_metadata(
1309 cx: &CodegenCx<'ll, 'tcx>,
1310 tuple_type: Ty<'tcx>,
1311 component_types: &[Ty<'tcx>],
1312 unique_type_id: UniqueTypeId,
1313 span: Span,
416331ca 1314 containing_scope: Option<&'ll DIScope>,
b7449926 1315) -> RecursiveTypeDescription<'ll, 'tcx> {
48663c56 1316 let tuple_name = compute_debuginfo_type_name(cx.tcx, tuple_type, false);
1a4d82fc 1317
f035d41b
XL
1318 let struct_stub = create_struct_stub(
1319 cx,
1320 tuple_type,
1321 &tuple_name[..],
1322 unique_type_id,
1323 containing_scope,
1324 DIFlags::FlagZero,
1325 );
a1dfa0c6 1326
d9579d0f
AL
1327 create_and_register_recursive_type_forward_declaration(
1328 cx,
1329 tuple_type,
1330 unique_type_id,
a1dfa0c6
XL
1331 struct_stub,
1332 struct_stub,
d9579d0f 1333 TupleMDF(TupleMemberDescriptionFactory {
476ff2be 1334 ty: tuple_type,
d9579d0f 1335 component_types: component_types.to_vec(),
3b2f2976 1336 span,
dfeec247 1337 }),
d9579d0f 1338 )
1a4d82fc
JJ
1339}
1340
9e0c209e
SL
1341//=-----------------------------------------------------------------------------
1342// Unions
1343//=-----------------------------------------------------------------------------
1344
1345struct UnionMemberDescriptionFactory<'tcx> {
ba9703b0 1346 layout: TyAndLayout<'tcx>,
476ff2be 1347 variant: &'tcx ty::VariantDef,
9e0c209e
SL
1348 span: Span,
1349}
1350
1351impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
dfeec247
XL
1352 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) -> Vec<MemberDescription<'ll>> {
1353 self.variant
1354 .fields
1355 .iter()
1356 .enumerate()
1357 .map(|(i, f)| {
1358 let field = self.layout.field(cx, i);
1359 MemberDescription {
1360 name: f.ident.to_string(),
1361 type_metadata: type_metadata(cx, field.ty, self.span),
1362 offset: Size::ZERO,
1363 size: field.size,
1364 align: field.align.abi,
1365 flags: DIFlags::FlagZero,
1366 discriminant: None,
f035d41b 1367 source_info: None,
dfeec247
XL
1368 }
1369 })
1370 .collect()
9e0c209e
SL
1371 }
1372}
1373
b7449926
XL
1374fn prepare_union_metadata(
1375 cx: &CodegenCx<'ll, 'tcx>,
1376 union_type: Ty<'tcx>,
1377 unique_type_id: UniqueTypeId,
1378 span: Span,
1379) -> RecursiveTypeDescription<'ll, 'tcx> {
48663c56 1380 let union_name = compute_debuginfo_type_name(cx.tcx, union_type, false);
9e0c209e 1381
1b1a35ee 1382 let (union_def_id, variant) = match union_type.kind() {
b7449926 1383 ty::Adt(def, _) => (def.did, def.non_enum_variant()),
dfeec247 1384 _ => bug!("prepare_union_metadata on a non-ADT"),
9e0c209e
SL
1385 };
1386
041b39d2 1387 let containing_scope = get_namespace_for_item(cx, union_def_id);
9e0c209e 1388
dfeec247
XL
1389 let union_metadata_stub =
1390 create_union_stub(cx, union_type, &union_name, unique_type_id, containing_scope);
9e0c209e
SL
1391
1392 create_and_register_recursive_type_forward_declaration(
1393 cx,
1394 union_type,
1395 unique_type_id,
1396 union_metadata_stub,
a1dfa0c6 1397 union_metadata_stub,
dfeec247 1398 UnionMDF(UnionMemberDescriptionFactory { layout: cx.layout_of(union_type), variant, span }),
9e0c209e
SL
1399 )
1400}
1a4d82fc 1401
d9579d0f
AL
1402//=-----------------------------------------------------------------------------
1403// Enums
1404//=-----------------------------------------------------------------------------
1a4d82fc 1405
ba9703b0
XL
1406/// DWARF variant support is only available starting in LLVM 8, but
1407/// on MSVC we have to use the fallback mode, because LLVM doesn't
1408/// lower variant parts to PDB.
9fa01778 1409fn use_enum_fallback(cx: &CodegenCx<'_, '_>) -> bool {
29967ef6 1410 cx.sess().target.is_like_msvc
a1dfa0c6
XL
1411}
1412
60c5eb7d
XL
1413// FIXME(eddyb) maybe precompute this? Right now it's computed once
1414// per generator monomorphization, but it doesn't depend on substs.
1415fn generator_layout_and_saved_local_names(
1416 tcx: TyCtxt<'tcx>,
1417 def_id: DefId,
f9f354fc 1418) -> (&'tcx GeneratorLayout<'tcx>, IndexVec<mir::GeneratorSavedLocal, Option<Symbol>>) {
60c5eb7d 1419 let body = tcx.optimized_mir(def_id);
6a06907d 1420 let generator_layout = body.generator_layout().unwrap();
dfeec247 1421 let mut generator_saved_local_names = IndexVec::from_elem(None, &generator_layout.field_tys);
60c5eb7d 1422
dfeec247 1423 let state_arg = mir::Local::new(1);
60c5eb7d 1424 for var in &body.var_debug_info {
fc512014
XL
1425 let place = if let mir::VarDebugInfoContents::Place(p) = var.value { p } else { continue };
1426 if place.local != state_arg {
60c5eb7d
XL
1427 continue;
1428 }
fc512014 1429 match place.projection[..] {
60c5eb7d
XL
1430 [
1431 // Deref of the `Pin<&mut Self>` state argument.
1432 mir::ProjectionElem::Field(..),
1433 mir::ProjectionElem::Deref,
1434
1435 // Field of a variant of the state.
1436 mir::ProjectionElem::Downcast(_, variant),
1437 mir::ProjectionElem::Field(field, _),
1438 ] => {
1439 let name = &mut generator_saved_local_names[
1440 generator_layout.variant_fields[variant][field]
1441 ];
1442 if name.is_none() {
1443 name.replace(var.name);
1444 }
1445 }
1446 _ => {}
1447 }
1448 }
1449 (generator_layout, generator_saved_local_names)
1450}
1451
1452/// Describes the members of an enum value; an enum is described as a union of
1453/// structs in DWARF. This `MemberDescriptionFactory` provides the description for
1454/// the members of this union; so for every variant of the given enum, this
1455/// factory will produce one `MemberDescription` (all with no name and a fixed
1456/// offset of zero bytes).
b7449926 1457struct EnumMemberDescriptionFactory<'ll, 'tcx> {
d9579d0f 1458 enum_type: Ty<'tcx>,
ba9703b0 1459 layout: TyAndLayout<'tcx>,
f035d41b 1460 tag_type_metadata: Option<&'ll DIType>,
b7449926 1461 containing_scope: &'ll DIScope,
d9579d0f 1462 span: Span,
1a4d82fc
JJ
1463}
1464
b7449926 1465impl EnumMemberDescriptionFactory<'ll, 'tcx> {
dfeec247 1466 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) -> Vec<MemberDescription<'ll>> {
1b1a35ee 1467 let generator_variant_info_data = match *self.enum_type.kind() {
60c5eb7d
XL
1468 ty::Generator(def_id, ..) => {
1469 Some(generator_layout_and_saved_local_names(cx.tcx, def_id))
1470 }
1471 _ => None,
1472 };
1473
1b1a35ee 1474 let variant_info_for = |index: VariantIdx| match *self.enum_type.kind() {
dfeec247 1475 ty::Adt(adt, _) => VariantInfo::Adt(&adt.variants[index]),
f035d41b 1476 ty::Generator(def_id, _, _) => {
dfeec247
XL
1477 let (generator_layout, generator_saved_local_names) =
1478 generator_variant_info_data.as_ref().unwrap();
1479 VariantInfo::Generator {
f035d41b 1480 def_id,
dfeec247
XL
1481 generator_layout: *generator_layout,
1482 generator_saved_local_names,
1483 variant_index: index,
48663c56 1484 }
48663c56 1485 }
dfeec247 1486 _ => bug!(),
48663c56 1487 };
a1dfa0c6
XL
1488
1489 // This will always find the metadata in the type map.
1490 let fallback = use_enum_fallback(cx);
1491 let self_metadata = if fallback {
1492 self.containing_scope
1493 } else {
1494 type_metadata(cx, self.enum_type, self.span)
1495 };
1b1a35ee 1496 let flags = match self.enum_type.kind() {
f035d41b
XL
1497 ty::Generator(..) => DIFlags::FlagArtificial,
1498 _ => DIFlags::FlagZero,
1499 };
a1dfa0c6 1500
ff7c6d11 1501 match self.layout.variants {
ba9703b0 1502 Variants::Single { index } => {
1b1a35ee 1503 if let ty::Adt(adt, _) = self.enum_type.kind() {
48663c56
XL
1504 if adt.variants.is_empty() {
1505 return vec![];
1506 }
1507 }
1508
1509 let variant_info = variant_info_for(index);
dfeec247
XL
1510 let (variant_type_metadata, member_description_factory) = describe_enum_variant(
1511 cx,
1512 self.layout,
1513 variant_info,
f035d41b 1514 NoTag,
dfeec247
XL
1515 self_metadata,
1516 self.span,
1517 );
1518
1519 let member_descriptions = member_description_factory.create_member_descriptions(cx);
1520
1521 set_members_of_composite_type(
1522 cx,
1523 self.enum_type,
1524 variant_type_metadata,
1525 member_descriptions,
1526 );
1527 vec![MemberDescription {
1528 name: if fallback { String::new() } else { variant_info.variant_name() },
1529 type_metadata: variant_type_metadata,
1530 offset: Size::ZERO,
1531 size: self.layout.size,
1532 align: self.layout.align.abi,
f035d41b 1533 flags,
dfeec247 1534 discriminant: None,
f035d41b 1535 source_info: variant_info.source_info(cx),
dfeec247 1536 }]
ff7c6d11 1537 }
ba9703b0 1538 Variants::Multiple {
f035d41b
XL
1539 tag_encoding: TagEncoding::Direct,
1540 tag_field,
532ac7d7
XL
1541 ref variants,
1542 ..
1543 } => {
f035d41b
XL
1544 let tag_info = if fallback {
1545 RegularTag {
1546 tag_field: Field::from(tag_field),
1547 tag_type_metadata: self.tag_type_metadata.unwrap(),
48663c56 1548 }
a1dfa0c6
XL
1549 } else {
1550 // This doesn't matter in this case.
f035d41b 1551 NoTag
a1dfa0c6 1552 };
dfeec247
XL
1553 variants
1554 .iter_enumerated()
1555 .map(|(i, _)| {
1556 let variant = self.layout.for_variant(cx, i);
1557 let variant_info = variant_info_for(i);
1558 let (variant_type_metadata, member_desc_factory) = describe_enum_variant(
1559 cx,
1560 variant,
1561 variant_info,
f035d41b 1562 tag_info,
dfeec247
XL
1563 self_metadata,
1564 self.span,
1565 );
1566
1567 let member_descriptions =
1568 member_desc_factory.create_member_descriptions(cx);
1569
1570 set_members_of_composite_type(
1571 cx,
1572 self.enum_type,
1573 variant_type_metadata,
1574 member_descriptions,
1575 );
1576
1577 MemberDescription {
1578 name: if fallback {
1579 String::new()
1580 } else {
1581 variant_info.variant_name()
1582 },
1583 type_metadata: variant_type_metadata,
1584 offset: Size::ZERO,
1585 size: self.layout.size,
1586 align: self.layout.align.abi,
f035d41b 1587 flags,
dfeec247
XL
1588 discriminant: Some(
1589 self.layout.ty.discriminant_for_variant(cx.tcx, i).unwrap().val
1590 as u64,
1591 ),
f035d41b 1592 source_info: variant_info.source_info(cx),
dfeec247
XL
1593 }
1594 })
1595 .collect()
ff7c6d11 1596 }
ba9703b0 1597 Variants::Multiple {
f035d41b
XL
1598 tag_encoding:
1599 TagEncoding::Niche { ref niche_variants, niche_start, dataful_variant },
1600 ref tag,
a1dfa0c6 1601 ref variants,
f035d41b 1602 tag_field,
a1dfa0c6
XL
1603 } => {
1604 if fallback {
1605 let variant = self.layout.for_variant(cx, dataful_variant);
60c5eb7d 1606 // Create a description of the non-null variant.
dfeec247
XL
1607 let (variant_type_metadata, member_description_factory) = describe_enum_variant(
1608 cx,
1609 variant,
1610 variant_info_for(dataful_variant),
f035d41b 1611 OptimizedTag,
dfeec247
XL
1612 self.containing_scope,
1613 self.span,
1614 );
1a4d82fc 1615
a1dfa0c6
XL
1616 let variant_member_descriptions =
1617 member_description_factory.create_member_descriptions(cx);
1a4d82fc 1618
dfeec247
XL
1619 set_members_of_composite_type(
1620 cx,
1621 self.enum_type,
1622 variant_type_metadata,
1623 variant_member_descriptions,
1624 );
a1dfa0c6
XL
1625
1626 // Encode the information about the null variant in the union
1627 // member's name.
1628 let mut name = String::from("RUST$ENCODED$ENUM$");
1629 // Right now it's not even going to work for `niche_start > 0`,
1630 // and for multiple niche variants it only supports the first.
dfeec247
XL
1631 fn compute_field_path<'a, 'tcx>(
1632 cx: &CodegenCx<'a, 'tcx>,
1633 name: &mut String,
ba9703b0 1634 layout: TyAndLayout<'tcx>,
dfeec247
XL
1635 offset: Size,
1636 size: Size,
1637 ) {
a1dfa0c6
XL
1638 for i in 0..layout.fields.count() {
1639 let field_offset = layout.fields.offset(i);
1640 if field_offset > offset {
1641 continue;
1642 }
1643 let inner_offset = offset - field_offset;
1644 let field = layout.field(cx, i);
1645 if inner_offset + size <= field.size {
1646 write!(name, "{}$", i).unwrap();
1647 compute_field_path(cx, name, field, inner_offset, size);
1648 }
ff7c6d11
XL
1649 }
1650 }
dfeec247
XL
1651 compute_field_path(
1652 cx,
1653 &mut name,
1654 self.layout,
f035d41b
XL
1655 self.layout.fields.offset(tag_field),
1656 self.layout.field(cx, tag_field).size,
dfeec247 1657 );
f035d41b
XL
1658 let variant_info = variant_info_for(*niche_variants.start());
1659 variant_info.map_struct_name(|variant_name| {
48663c56
XL
1660 name.push_str(variant_name);
1661 });
a1dfa0c6
XL
1662
1663 // Create the (singleton) list of descriptions of union members.
dfeec247
XL
1664 vec![MemberDescription {
1665 name,
1666 type_metadata: variant_type_metadata,
1667 offset: Size::ZERO,
1668 size: variant.size,
1669 align: variant.align.abi,
f035d41b 1670 flags,
dfeec247 1671 discriminant: None,
f035d41b 1672 source_info: variant_info.source_info(cx),
dfeec247 1673 }]
a1dfa0c6 1674 } else {
dfeec247
XL
1675 variants
1676 .iter_enumerated()
1677 .map(|(i, _)| {
1678 let variant = self.layout.for_variant(cx, i);
1679 let variant_info = variant_info_for(i);
1680 let (variant_type_metadata, member_desc_factory) =
1681 describe_enum_variant(
1682 cx,
1683 variant,
1684 variant_info,
f035d41b 1685 OptimizedTag,
dfeec247
XL
1686 self_metadata,
1687 self.span,
1688 );
1689
1690 let member_descriptions =
1691 member_desc_factory.create_member_descriptions(cx);
1692
1693 set_members_of_composite_type(
1694 cx,
1695 self.enum_type,
1696 variant_type_metadata,
1697 member_descriptions,
1698 );
1699
1700 let niche_value = if i == dataful_variant {
1701 None
1702 } else {
1703 let value = (i.as_u32() as u128)
1704 .wrapping_sub(niche_variants.start().as_u32() as u128)
1705 .wrapping_add(niche_start);
29967ef6 1706 let value = tag.value.size(cx).truncate(value);
dfeec247
XL
1707 // NOTE(eddyb) do *NOT* remove this assert, until
1708 // we pass the full 128-bit value to LLVM, otherwise
1709 // truncation will be silent and remain undetected.
1710 assert_eq!(value as u64 as u128, value);
1711 Some(value as u64)
1712 };
1713
1714 MemberDescription {
1715 name: variant_info.variant_name(),
1716 type_metadata: variant_type_metadata,
1717 offset: Size::ZERO,
1718 size: self.layout.size,
1719 align: self.layout.align.abi,
f035d41b 1720 flags,
dfeec247 1721 discriminant: niche_value,
f035d41b 1722 source_info: variant_info.source_info(cx),
dfeec247
XL
1723 }
1724 })
1725 .collect()
ff7c6d11 1726 }
ff7c6d11 1727 }
1a4d82fc
JJ
1728 }
1729 }
d9579d0f 1730}
1a4d82fc 1731
60c5eb7d 1732// Creates `MemberDescription`s for the fields of a single enum variant.
b7449926 1733struct VariantMemberDescriptionFactory<'ll, 'tcx> {
60c5eb7d 1734 /// Cloned from the `layout::Struct` describing the variant.
ba9703b0 1735 offsets: Vec<Size>,
d9579d0f 1736 args: Vec<(String, Ty<'tcx>)>,
f035d41b 1737 tag_type_metadata: Option<&'ll DIType>,
d9579d0f
AL
1738 span: Span,
1739}
1a4d82fc 1740
b7449926 1741impl VariantMemberDescriptionFactory<'ll, 'tcx> {
dfeec247
XL
1742 fn create_member_descriptions(&self, cx: &CodegenCx<'ll, 'tcx>) -> Vec<MemberDescription<'ll>> {
1743 self.args
1744 .iter()
1745 .enumerate()
1746 .map(|(i, &(ref name, ty))| {
f035d41b
XL
1747 // Discriminant is always the first field of our variant
1748 // when using the enum fallback.
1749 let is_artificial_discr = use_enum_fallback(cx) && i == 0;
dfeec247
XL
1750 let (size, align) = cx.size_and_align_of(ty);
1751 MemberDescription {
1752 name: name.to_string(),
f035d41b
XL
1753 type_metadata: if is_artificial_discr {
1754 self.tag_type_metadata.unwrap_or_else(|| type_metadata(cx, ty, self.span))
dfeec247
XL
1755 } else {
1756 type_metadata(cx, ty, self.span)
1757 },
1758 offset: self.offsets[i],
1759 size,
1760 align,
f035d41b
XL
1761 flags: if is_artificial_discr {
1762 DIFlags::FlagArtificial
1763 } else {
1764 DIFlags::FlagZero
1765 },
dfeec247 1766 discriminant: None,
f035d41b 1767 source_info: None,
dfeec247
XL
1768 }
1769 })
1770 .collect()
1a4d82fc 1771 }
d9579d0f 1772}
1a4d82fc 1773
f035d41b
XL
1774// FIXME: terminology here should be aligned with `abi::TagEncoding`.
1775// `OptimizedTag` is `TagEncoding::Niche`, `RegularTag` is `TagEncoding::Direct`.
1776// `NoTag` should be removed; users should use `Option<EnumTagInfo>` instead.
d9579d0f 1777#[derive(Copy, Clone)]
f035d41b
XL
1778enum EnumTagInfo<'ll> {
1779 RegularTag { tag_field: Field, tag_type_metadata: &'ll DIType },
1780 OptimizedTag,
1781 NoTag,
d9579d0f 1782}
1a4d82fc 1783
48663c56 1784#[derive(Copy, Clone)]
60c5eb7d 1785enum VariantInfo<'a, 'tcx> {
48663c56 1786 Adt(&'tcx ty::VariantDef),
60c5eb7d 1787 Generator {
f035d41b 1788 def_id: DefId,
60c5eb7d 1789 generator_layout: &'tcx GeneratorLayout<'tcx>,
f9f354fc 1790 generator_saved_local_names: &'a IndexVec<mir::GeneratorSavedLocal, Option<Symbol>>,
60c5eb7d
XL
1791 variant_index: VariantIdx,
1792 },
48663c56
XL
1793}
1794
60c5eb7d 1795impl<'tcx> VariantInfo<'_, 'tcx> {
48663c56
XL
1796 fn map_struct_name<R>(&self, f: impl FnOnce(&str) -> R) -> R {
1797 match self {
1798 VariantInfo::Adt(variant) => f(&variant.ident.as_str()),
f035d41b
XL
1799 VariantInfo::Generator { variant_index, .. } => {
1800 f(&GeneratorSubsts::variant_name(*variant_index))
dfeec247 1801 }
48663c56
XL
1802 }
1803 }
1804
1805 fn variant_name(&self) -> String {
1806 match self {
1807 VariantInfo::Adt(variant) => variant.ident.to_string(),
60c5eb7d 1808 VariantInfo::Generator { variant_index, .. } => {
48663c56
XL
1809 // Since GDB currently prints out the raw discriminant along
1810 // with every variant, make each variant name be just the value
1811 // of the discriminant. The struct name for the variant includes
1812 // the actual variant description.
dc9dc135 1813 format!("{}", variant_index.as_usize())
48663c56
XL
1814 }
1815 }
1816 }
1817
1818 fn field_name(&self, i: usize) -> String {
60c5eb7d 1819 let field_name = match *self {
dfeec247
XL
1820 VariantInfo::Adt(variant) if variant.ctor_kind != CtorKind::Fn => {
1821 Some(variant.fields[i].ident.name)
1822 }
60c5eb7d
XL
1823 VariantInfo::Generator {
1824 generator_layout,
1825 generator_saved_local_names,
1826 variant_index,
1827 ..
dfeec247
XL
1828 } => {
1829 generator_saved_local_names
1830 [generator_layout.variant_fields[variant_index][i.into()]]
1831 }
48663c56
XL
1832 _ => None,
1833 };
60c5eb7d 1834 field_name.map(|name| name.to_string()).unwrap_or_else(|| format!("__{}", i))
48663c56 1835 }
f035d41b
XL
1836
1837 fn source_info(&self, cx: &CodegenCx<'ll, 'tcx>) -> Option<SourceInfo<'ll>> {
1838 match self {
1839 VariantInfo::Generator { def_id, variant_index, .. } => {
5869c6ff
XL
1840 let span = cx.tcx.generator_layout(*def_id).unwrap().variant_source_info
1841 [*variant_index]
1842 .span;
f035d41b
XL
1843 if !span.is_dummy() {
1844 let loc = cx.lookup_debug_loc(span.lo());
6a06907d 1845 return Some(SourceInfo { file: file_metadata(cx, &loc.file), line: loc.line });
f035d41b
XL
1846 }
1847 }
1848 _ => {}
1849 }
1850 None
1851 }
1852
f035d41b
XL
1853 fn is_artificial(&self) -> bool {
1854 match self {
1855 VariantInfo::Generator { .. } => true,
1856 VariantInfo::Adt(..) => false,
1857 }
1858 }
48663c56
XL
1859}
1860
60c5eb7d
XL
1861/// Returns a tuple of (1) `type_metadata_stub` of the variant, (2) a
1862/// `MemberDescriptionFactory` for producing the descriptions of the
1863/// fields of the variant. This is a rudimentary version of a full
1864/// `RecursiveTypeDescription`.
b7449926
XL
1865fn describe_enum_variant(
1866 cx: &CodegenCx<'ll, 'tcx>,
ba9703b0 1867 layout: layout::TyAndLayout<'tcx>,
60c5eb7d 1868 variant: VariantInfo<'_, 'tcx>,
f035d41b 1869 discriminant_info: EnumTagInfo<'ll>,
b7449926
XL
1870 containing_scope: &'ll DIScope,
1871 span: Span,
1872) -> (&'ll DICompositeType, MemberDescriptionFactory<'ll, 'tcx>) {
48663c56 1873 let metadata_stub = variant.map_struct_name(|variant_name| {
dfeec247
XL
1874 let unique_type_id = debug_context(cx)
1875 .type_map
1876 .borrow_mut()
1877 .get_unique_type_id_of_enum_variant(cx, layout.ty, &variant_name);
f035d41b
XL
1878 create_struct_stub(
1879 cx,
1880 layout.ty,
1881 &variant_name,
1882 unique_type_id,
1883 Some(containing_scope),
1884 // FIXME(tmandry): This doesn't seem to have any effect.
1885 if variant.is_artificial() { DIFlags::FlagArtificial } else { DIFlags::FlagZero },
1886 )
48663c56 1887 });
1a4d82fc 1888
d9579d0f 1889 // Build an array of (field name, field type) pairs to be captured in the factory closure.
a1dfa0c6
XL
1890 let (offsets, args) = if use_enum_fallback(cx) {
1891 // If this is not a univariant enum, there is also the discriminant field.
1892 let (discr_offset, discr_arg) = match discriminant_info {
f035d41b 1893 RegularTag { tag_field, .. } => {
a1dfa0c6
XL
1894 // We have the layout of an enum variant, we need the layout of the outer enum
1895 let enum_layout = cx.layout_of(layout.ty);
f035d41b 1896 let offset = enum_layout.fields.offset(tag_field.as_usize());
dfeec247 1897 let args =
f035d41b 1898 ("RUST$ENUM$DISR".to_owned(), enum_layout.field(cx, tag_field.as_usize()).ty);
48663c56 1899 (Some(offset), Some(args))
a1dfa0c6
XL
1900 }
1901 _ => (None, None),
ff7c6d11 1902 };
a1dfa0c6 1903 (
dfeec247
XL
1904 discr_offset
1905 .into_iter()
1906 .chain((0..layout.fields.count()).map(|i| layout.fields.offset(i)))
1907 .collect(),
1908 discr_arg
1909 .into_iter()
1910 .chain(
1911 (0..layout.fields.count())
1912 .map(|i| (variant.field_name(i), layout.field(cx, i).ty)),
1913 )
1914 .collect(),
a1dfa0c6
XL
1915 )
1916 } else {
1917 (
dfeec247
XL
1918 (0..layout.fields.count()).map(|i| layout.fields.offset(i)).collect(),
1919 (0..layout.fields.count())
1920 .map(|i| (variant.field_name(i), layout.field(cx, i).ty))
1921 .collect(),
a1dfa0c6
XL
1922 )
1923 };
1a4d82fc 1924
dfeec247
XL
1925 let member_description_factory = VariantMDF(VariantMemberDescriptionFactory {
1926 offsets,
1927 args,
f035d41b
XL
1928 tag_type_metadata: match discriminant_info {
1929 RegularTag { tag_type_metadata, .. } => Some(tag_type_metadata),
dfeec247
XL
1930 _ => None,
1931 },
1932 span,
1933 });
1a4d82fc 1934
ff7c6d11 1935 (metadata_stub, member_description_factory)
d9579d0f 1936}
1a4d82fc 1937
b7449926
XL
1938fn prepare_enum_metadata(
1939 cx: &CodegenCx<'ll, 'tcx>,
1940 enum_type: Ty<'tcx>,
1941 enum_def_id: DefId,
1942 unique_type_id: UniqueTypeId,
1943 span: Span,
48663c56 1944 outer_field_tys: Vec<Ty<'tcx>>,
b7449926 1945) -> RecursiveTypeDescription<'ll, 'tcx> {
f035d41b
XL
1946 let tcx = cx.tcx;
1947 let enum_name = compute_debuginfo_type_name(tcx, enum_type, false);
1948 // FIXME(tmandry): This doesn't seem to have any effect.
1b1a35ee 1949 let enum_flags = match enum_type.kind() {
f035d41b
XL
1950 ty::Generator(..) => DIFlags::FlagArtificial,
1951 _ => DIFlags::FlagZero,
1952 };
1a4d82fc 1953
041b39d2 1954 let containing_scope = get_namespace_for_item(cx, enum_def_id);
e9174d1e
SL
1955 // FIXME: This should emit actual file metadata for the enum, but we
1956 // currently can't get the necessary information when it comes to types
1957 // imported from other crates. Formerly we violated the ODR when performing
1958 // LTO because we emitted debuginfo for the same type with varying file
1959 // metadata, so as a workaround we pretend that the type comes from
1960 // <unknown>
1961 let file_metadata = unknown_file_metadata(cx);
1a4d82fc 1962
ba9703b0 1963 let discriminant_type_metadata = |discr: Primitive| {
1b1a35ee 1964 let enumerators_metadata: Vec<_> = match enum_type.kind() {
48663c56 1965 ty::Adt(def, _) => def
f035d41b 1966 .discriminants(tcx)
48663c56
XL
1967 .zip(&def.variants)
1968 .map(|((_, discr), v)| {
74b04a01 1969 let name = v.ident.as_str();
1b1a35ee 1970 let is_unsigned = match discr.ty.kind() {
74b04a01
XL
1971 ty::Int(_) => false,
1972 ty::Uint(_) => true,
1973 _ => bug!("non integer discriminant"),
1974 };
48663c56
XL
1975 unsafe {
1976 Some(llvm::LLVMRustDIBuilderCreateEnumerator(
1977 DIB(cx),
74b04a01
XL
1978 name.as_ptr().cast(),
1979 name.len(),
48663c56 1980 // FIXME: what if enumeration has i128 discriminant?
74b04a01
XL
1981 discr.val as i64,
1982 is_unsigned,
dfeec247 1983 ))
48663c56
XL
1984 }
1985 })
1986 .collect(),
1987 ty::Generator(_, substs, _) => substs
e74abb32 1988 .as_generator()
f035d41b 1989 .variant_range(enum_def_id, tcx)
48663c56 1990 .map(|variant_index| {
f035d41b
XL
1991 debug_assert_eq!(tcx.types.u32, substs.as_generator().discr_ty(tcx));
1992 let name = GeneratorSubsts::variant_name(variant_index);
48663c56
XL
1993 unsafe {
1994 Some(llvm::LLVMRustDIBuilderCreateEnumerator(
1995 DIB(cx),
74b04a01
XL
1996 name.as_ptr().cast(),
1997 name.len(),
f035d41b 1998 // Generators use u32 as discriminant type, verified above.
74b04a01
XL
1999 variant_index.as_u32().into(),
2000 true, // IsUnsigned
dfeec247 2001 ))
48663c56
XL
2002 }
2003 })
2004 .collect(),
2005 _ => bug!(),
2006 };
a1dfa0c6 2007
ff7c6d11 2008 let disr_type_key = (enum_def_id, discr);
dfeec247
XL
2009 let cached_discriminant_type_metadata =
2010 debug_context(cx).created_enum_disr_types.borrow().get(&disr_type_key).cloned();
d9579d0f
AL
2011 match cached_discriminant_type_metadata {
2012 Some(discriminant_type_metadata) => discriminant_type_metadata,
2013 None => {
dfeec247 2014 let (discriminant_size, discriminant_align) = (discr.size(cx), discr.align(cx));
d9579d0f 2015 let discriminant_base_type_metadata =
f035d41b 2016 type_metadata(cx, discr.to_ty(tcx), rustc_span::DUMMY_SP);
1a4d82fc 2017
74b04a01 2018 let item_name;
1b1a35ee 2019 let discriminant_name = match enum_type.kind() {
74b04a01 2020 ty::Adt(..) => {
f035d41b 2021 item_name = tcx.item_name(enum_def_id).as_str();
74b04a01
XL
2022 &*item_name
2023 }
2024 ty::Generator(..) => enum_name.as_str(),
48663c56
XL
2025 _ => bug!(),
2026 };
2027
d9579d0f 2028 let discriminant_type_metadata = unsafe {
5bcae85e 2029 llvm::LLVMRustDIBuilderCreateEnumerationType(
d9579d0f
AL
2030 DIB(cx),
2031 containing_scope,
74b04a01
XL
2032 discriminant_name.as_ptr().cast(),
2033 discriminant_name.len(),
5bcae85e 2034 file_metadata,
d9579d0f 2035 UNKNOWN_LINE_NUMBER,
ff7c6d11 2036 discriminant_size.bits(),
a1dfa0c6 2037 discriminant_align.abi.bits() as u32,
d9579d0f 2038 create_DIArray(DIB(cx), &enumerators_metadata),
dfeec247
XL
2039 discriminant_base_type_metadata,
2040 true,
2041 )
d9579d0f 2042 };
1a4d82fc 2043
dfeec247
XL
2044 debug_context(cx)
2045 .created_enum_disr_types
2046 .borrow_mut()
2047 .insert(disr_type_key, discriminant_type_metadata);
1a4d82fc 2048
d9579d0f 2049 discriminant_type_metadata
1a4d82fc
JJ
2050 }
2051 }
d9579d0f 2052 };
1a4d82fc 2053
ff7c6d11 2054 let layout = cx.layout_of(enum_type);
1a4d82fc 2055
ba9703b0
XL
2056 if let (
2057 &Abi::Scalar(_),
f035d41b 2058 &Variants::Multiple { tag_encoding: TagEncoding::Direct, ref tag, .. },
ba9703b0
XL
2059 ) = (&layout.abi, &layout.variants)
2060 {
f035d41b 2061 return FinalMetadata(discriminant_type_metadata(tag.value));
ff7c6d11
XL
2062 }
2063
a1dfa0c6
XL
2064 if use_enum_fallback(cx) {
2065 let discriminant_type_metadata = match layout.variants {
ba9703b0 2066 Variants::Single { .. }
f035d41b
XL
2067 | Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, .. } => None,
2068 Variants::Multiple { tag_encoding: TagEncoding::Direct, ref tag, .. } => {
2069 Some(discriminant_type_metadata(tag.value))
ba9703b0 2070 }
a1dfa0c6
XL
2071 };
2072
74b04a01
XL
2073 let enum_metadata = {
2074 let type_map = debug_context(cx).type_map.borrow();
2075 let unique_type_id_str = type_map.get_unique_type_id_as_string(unique_type_id);
2076
2077 unsafe {
2078 llvm::LLVMRustDIBuilderCreateUnionType(
2079 DIB(cx),
2080 containing_scope,
2081 enum_name.as_ptr().cast(),
2082 enum_name.len(),
2083 file_metadata,
2084 UNKNOWN_LINE_NUMBER,
2085 layout.size.bits(),
2086 layout.align.abi.bits() as u32,
f035d41b 2087 enum_flags,
74b04a01
XL
2088 None,
2089 0, // RuntimeLang
2090 unique_type_id_str.as_ptr().cast(),
2091 unique_type_id_str.len(),
2092 )
2093 }
a1dfa0c6
XL
2094 };
2095
2096 return create_and_register_recursive_type_forward_declaration(
2097 cx,
2098 enum_type,
2099 unique_type_id,
2100 enum_metadata,
2101 enum_metadata,
2102 EnumMDF(EnumMemberDescriptionFactory {
2103 enum_type,
2104 layout,
f035d41b 2105 tag_type_metadata: discriminant_type_metadata,
a1dfa0c6
XL
2106 containing_scope,
2107 span,
2108 }),
2109 );
2110 }
2111
1b1a35ee 2112 let discriminator_name = match enum_type.kind() {
74b04a01
XL
2113 ty::Generator(..) => "__state",
2114 _ => "",
48663c56 2115 };
532ac7d7 2116 let discriminator_metadata = match layout.variants {
a1dfa0c6 2117 // A single-variant enum has no discriminant.
ba9703b0 2118 Variants::Single { .. } => None,
a1dfa0c6 2119
ba9703b0 2120 Variants::Multiple {
f035d41b 2121 tag_encoding: TagEncoding::Niche { .. }, ref tag, tag_field, ..
532ac7d7 2122 } => {
a1dfa0c6 2123 // Find the integer type of the correct size.
f035d41b
XL
2124 let size = tag.value.size(cx);
2125 let align = tag.value.align(cx);
a1dfa0c6 2126
f035d41b 2127 let tag_type = match tag.value {
ba9703b0
XL
2128 Int(t, _) => t,
2129 F32 => Integer::I32,
2130 F64 => Integer::I64,
2131 Pointer => cx.data_layout().ptr_sized_integer(),
dfeec247
XL
2132 }
2133 .to_ty(cx.tcx, false);
a1dfa0c6 2134
f035d41b 2135 let tag_metadata = basic_type_metadata(cx, tag_type);
a1dfa0c6
XL
2136 unsafe {
2137 Some(llvm::LLVMRustDIBuilderCreateMemberType(
2138 DIB(cx),
2139 containing_scope,
74b04a01
XL
2140 discriminator_name.as_ptr().cast(),
2141 discriminator_name.len(),
a1dfa0c6
XL
2142 file_metadata,
2143 UNKNOWN_LINE_NUMBER,
2144 size.bits(),
2145 align.abi.bits() as u32,
f035d41b 2146 layout.fields.offset(tag_field).bits(),
a1dfa0c6 2147 DIFlags::FlagArtificial,
f035d41b 2148 tag_metadata,
dfeec247 2149 ))
a1dfa0c6 2150 }
dfeec247 2151 }
a1dfa0c6 2152
f035d41b
XL
2153 Variants::Multiple { tag_encoding: TagEncoding::Direct, ref tag, tag_field, .. } => {
2154 let discr_type = tag.value.to_ty(cx.tcx);
a1dfa0c6
XL
2155 let (size, align) = cx.size_and_align_of(discr_type);
2156
2157 let discr_metadata = basic_type_metadata(cx, discr_type);
2158 unsafe {
2159 Some(llvm::LLVMRustDIBuilderCreateMemberType(
2160 DIB(cx),
2161 containing_scope,
74b04a01
XL
2162 discriminator_name.as_ptr().cast(),
2163 discriminator_name.len(),
a1dfa0c6
XL
2164 file_metadata,
2165 UNKNOWN_LINE_NUMBER,
2166 size.bits(),
2167 align.bits() as u32,
f035d41b 2168 layout.fields.offset(tag_field).bits(),
a1dfa0c6 2169 DIFlags::FlagArtificial,
dfeec247
XL
2170 discr_metadata,
2171 ))
a1dfa0c6 2172 }
dfeec247 2173 }
a1dfa0c6
XL
2174 };
2175
48663c56 2176 let mut outer_fields = match layout.variants {
ba9703b0
XL
2177 Variants::Single { .. } => vec![],
2178 Variants::Multiple { .. } => {
48663c56
XL
2179 let tuple_mdf = TupleMemberDescriptionFactory {
2180 ty: enum_type,
2181 component_types: outer_field_tys,
dfeec247 2182 span,
48663c56
XL
2183 };
2184 tuple_mdf
2185 .create_member_descriptions(cx)
2186 .into_iter()
2187 .map(|desc| Some(desc.into_metadata(cx, containing_scope)))
2188 .collect()
2189 }
2190 };
2191
74b04a01
XL
2192 let variant_part_unique_type_id_str = debug_context(cx)
2193 .type_map
2194 .borrow_mut()
2195 .get_unique_type_id_str_of_enum_variant_part(unique_type_id);
a1dfa0c6 2196 let empty_array = create_DIArray(DIB(cx), &[]);
74b04a01 2197 let name = "";
a1dfa0c6
XL
2198 let variant_part = unsafe {
2199 llvm::LLVMRustDIBuilderCreateVariantPart(
2200 DIB(cx),
2201 containing_scope,
74b04a01
XL
2202 name.as_ptr().cast(),
2203 name.len(),
a1dfa0c6
XL
2204 file_metadata,
2205 UNKNOWN_LINE_NUMBER,
2206 layout.size.bits(),
2207 layout.align.abi.bits() as u32,
f035d41b 2208 enum_flags,
a1dfa0c6
XL
2209 discriminator_metadata,
2210 empty_array,
74b04a01
XL
2211 variant_part_unique_type_id_str.as_ptr().cast(),
2212 variant_part_unique_type_id_str.len(),
dfeec247 2213 )
a1dfa0c6 2214 };
48663c56 2215 outer_fields.push(Some(variant_part));
a1dfa0c6 2216
74b04a01
XL
2217 let struct_wrapper = {
2218 // The variant part must be wrapped in a struct according to DWARF.
2219 let type_array = create_DIArray(DIB(cx), &outer_fields);
2220
2221 let type_map = debug_context(cx).type_map.borrow();
2222 let unique_type_id_str = type_map.get_unique_type_id_as_string(unique_type_id);
2223
2224 unsafe {
2225 llvm::LLVMRustDIBuilderCreateStructType(
2226 DIB(cx),
2227 Some(containing_scope),
2228 enum_name.as_ptr().cast(),
2229 enum_name.len(),
2230 file_metadata,
2231 UNKNOWN_LINE_NUMBER,
2232 layout.size.bits(),
2233 layout.align.abi.bits() as u32,
f035d41b 2234 enum_flags,
74b04a01
XL
2235 None,
2236 type_array,
2237 0,
2238 None,
2239 unique_type_id_str.as_ptr().cast(),
2240 unique_type_id_str.len(),
2241 )
2242 }
d9579d0f 2243 };
1a4d82fc 2244
ba9703b0 2245 create_and_register_recursive_type_forward_declaration(
d9579d0f
AL
2246 cx,
2247 enum_type,
2248 unique_type_id,
a1dfa0c6
XL
2249 struct_wrapper,
2250 variant_part,
d9579d0f 2251 EnumMDF(EnumMemberDescriptionFactory {
3b2f2976 2252 enum_type,
ff7c6d11 2253 layout,
f035d41b 2254 tag_type_metadata: None,
3b2f2976 2255 containing_scope,
3b2f2976 2256 span,
d9579d0f 2257 }),
ba9703b0 2258 )
d9579d0f 2259}
1a4d82fc 2260
d9579d0f
AL
2261/// Creates debug information for a composite type, that is, anything that
2262/// results in a LLVM struct.
2263///
2264/// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
b7449926
XL
2265fn composite_type_metadata(
2266 cx: &CodegenCx<'ll, 'tcx>,
2267 composite_type: Ty<'tcx>,
2268 composite_type_name: &str,
2269 composite_type_unique_id: UniqueTypeId,
2270 member_descriptions: Vec<MemberDescription<'ll>>,
2271 containing_scope: Option<&'ll DIScope>,
2272
2273 // Ignore source location information as long as it
2274 // can't be reconstructed for non-local crates.
2275 _file_metadata: &'ll DIFile,
2276 _definition_span: Span,
2277) -> &'ll DICompositeType {
d9579d0f 2278 // Create the (empty) struct metadata node ...
dfeec247
XL
2279 let composite_type_metadata = create_struct_stub(
2280 cx,
2281 composite_type,
2282 composite_type_name,
2283 composite_type_unique_id,
2284 containing_scope,
f035d41b 2285 DIFlags::FlagZero,
dfeec247 2286 );
d9579d0f 2287 // ... and immediately create and add the member descriptions.
dfeec247 2288 set_members_of_composite_type(cx, composite_type, composite_type_metadata, member_descriptions);
1a4d82fc 2289
0bf4aa26 2290 composite_type_metadata
d9579d0f 2291}
1a4d82fc 2292
dfeec247
XL
2293fn set_members_of_composite_type(
2294 cx: &CodegenCx<'ll, 'tcx>,
2295 composite_type: Ty<'tcx>,
2296 composite_type_metadata: &'ll DICompositeType,
2297 member_descriptions: Vec<MemberDescription<'ll>>,
2298) {
d9579d0f
AL
2299 // In some rare cases LLVM metadata uniquing would lead to an existing type
2300 // description being used instead of a new one created in
2301 // create_struct_stub. This would cause a hard to trace assertion in
2302 // DICompositeType::SetTypeArray(). The following check makes sure that we
2303 // get a better error message if this should happen again due to some
2304 // regression.
2305 {
2306 let mut composite_types_completed =
2307 debug_context(cx).composite_types_completed.borrow_mut();
e74abb32 2308 if !composite_types_completed.insert(&composite_type_metadata) {
dfeec247
XL
2309 bug!(
2310 "debuginfo::set_members_of_composite_type() - \
2311 Already completed forward declaration re-encountered."
2312 );
d9579d0f
AL
2313 }
2314 }
1a4d82fc 2315
b7449926
XL
2316 let member_metadata: Vec<_> = member_descriptions
2317 .into_iter()
48663c56 2318 .map(|desc| Some(desc.into_metadata(cx, composite_type_metadata)))
d9579d0f 2319 .collect();
1a4d82fc 2320
a1dfa0c6 2321 let type_params = compute_type_parameters(cx, composite_type);
d9579d0f
AL
2322 unsafe {
2323 let type_array = create_DIArray(DIB(cx), &member_metadata[..]);
a1dfa0c6 2324 llvm::LLVMRustDICompositeTypeReplaceArrays(
dfeec247
XL
2325 DIB(cx),
2326 composite_type_metadata,
2327 Some(type_array),
5869c6ff 2328 Some(type_params),
dfeec247 2329 );
a1dfa0c6
XL
2330 }
2331}
2332
60c5eb7d 2333/// Computes the type parameters for a type, if any, for the given metadata.
5869c6ff 2334fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> &'ll DIArray {
1b1a35ee 2335 if let ty::Adt(def, substs) = *ty.kind() {
74b04a01 2336 if substs.types().next().is_some() {
a1dfa0c6
XL
2337 let generics = cx.tcx.generics_of(def.did);
2338 let names = get_parameter_names(cx, generics);
dfeec247
XL
2339 let template_params: Vec<_> = substs
2340 .iter()
2341 .zip(names)
2342 .filter_map(|(kind, name)| {
2343 if let GenericArgKind::Type(ty) = kind.unpack() {
2344 let actual_type =
2345 cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
2346 let actual_type_metadata =
2347 type_metadata(cx, actual_type, rustc_span::DUMMY_SP);
74b04a01 2348 let name = &name.as_str();
dfeec247
XL
2349 Some(unsafe {
2350 Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
2351 DIB(cx),
2352 None,
74b04a01
XL
2353 name.as_ptr().cast(),
2354 name.len(),
dfeec247 2355 actual_type_metadata,
dfeec247
XL
2356 ))
2357 })
2358 } else {
2359 None
2360 }
2361 })
2362 .collect();
a1dfa0c6 2363
5869c6ff 2364 return create_DIArray(DIB(cx), &template_params[..]);
a1dfa0c6
XL
2365 }
2366 }
5869c6ff 2367 return create_DIArray(DIB(cx), &[]);
a1dfa0c6 2368
dfeec247
XL
2369 fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) -> Vec<Symbol> {
2370 let mut names = generics
2371 .parent
6a06907d 2372 .map_or_else(Vec::new, |def_id| get_parameter_names(cx, cx.tcx.generics_of(def_id)));
a1dfa0c6
XL
2373 names.extend(generics.params.iter().map(|param| param.name));
2374 names
d9579d0f
AL
2375 }
2376}
1a4d82fc 2377
60c5eb7d
XL
2378/// A convenience wrapper around `LLVMRustDIBuilderCreateStructType()`. Does not do
2379/// any caching, does not add any fields to the struct. This can be done later
2380/// with `set_members_of_composite_type()`.
b7449926
XL
2381fn create_struct_stub(
2382 cx: &CodegenCx<'ll, 'tcx>,
2383 struct_type: Ty<'tcx>,
2384 struct_type_name: &str,
2385 unique_type_id: UniqueTypeId,
2386 containing_scope: Option<&'ll DIScope>,
f035d41b 2387 flags: DIFlags,
b7449926 2388) -> &'ll DICompositeType {
ff7c6d11 2389 let (struct_size, struct_align) = cx.size_and_align_of(struct_type);
1a4d82fc 2390
74b04a01
XL
2391 let type_map = debug_context(cx).type_map.borrow();
2392 let unique_type_id = type_map.get_unique_type_id_as_string(unique_type_id);
2393
d9579d0f 2394 let metadata_stub = unsafe {
60c5eb7d 2395 // `LLVMRustDIBuilderCreateStructType()` wants an empty array. A null
d9579d0f 2396 // pointer will lead to hard to trace and debug LLVM assertions
60c5eb7d 2397 // later on in `llvm/lib/IR/Value.cpp`.
d9579d0f 2398 let empty_array = create_DIArray(DIB(cx), &[]);
1a4d82fc 2399
5bcae85e 2400 llvm::LLVMRustDIBuilderCreateStructType(
d9579d0f
AL
2401 DIB(cx),
2402 containing_scope,
74b04a01
XL
2403 struct_type_name.as_ptr().cast(),
2404 struct_type_name.len(),
5bcae85e 2405 unknown_file_metadata(cx),
d9579d0f 2406 UNKNOWN_LINE_NUMBER,
ff7c6d11 2407 struct_size.bits(),
a1dfa0c6 2408 struct_align.bits() as u32,
f035d41b 2409 flags,
b7449926 2410 None,
d9579d0f
AL
2411 empty_array,
2412 0,
b7449926 2413 None,
74b04a01
XL
2414 unique_type_id.as_ptr().cast(),
2415 unique_type_id.len(),
dfeec247 2416 )
d9579d0f 2417 };
1a4d82fc 2418
0bf4aa26 2419 metadata_stub
d9579d0f 2420}
1a4d82fc 2421
b7449926
XL
2422fn create_union_stub(
2423 cx: &CodegenCx<'ll, 'tcx>,
2424 union_type: Ty<'tcx>,
2425 union_type_name: &str,
2426 unique_type_id: UniqueTypeId,
2427 containing_scope: &'ll DIScope,
2428) -> &'ll DICompositeType {
ff7c6d11 2429 let (union_size, union_align) = cx.size_and_align_of(union_type);
9e0c209e 2430
74b04a01
XL
2431 let type_map = debug_context(cx).type_map.borrow();
2432 let unique_type_id = type_map.get_unique_type_id_as_string(unique_type_id);
2433
9e0c209e 2434 let metadata_stub = unsafe {
60c5eb7d 2435 // `LLVMRustDIBuilderCreateUnionType()` wants an empty array. A null
9e0c209e 2436 // pointer will lead to hard to trace and debug LLVM assertions
60c5eb7d 2437 // later on in `llvm/lib/IR/Value.cpp`.
9e0c209e
SL
2438 let empty_array = create_DIArray(DIB(cx), &[]);
2439
2440 llvm::LLVMRustDIBuilderCreateUnionType(
2441 DIB(cx),
2442 containing_scope,
74b04a01
XL
2443 union_type_name.as_ptr().cast(),
2444 union_type_name.len(),
9e0c209e
SL
2445 unknown_file_metadata(cx),
2446 UNKNOWN_LINE_NUMBER,
ff7c6d11 2447 union_size.bits(),
a1dfa0c6 2448 union_align.bits() as u32,
476ff2be 2449 DIFlags::FlagZero,
b7449926 2450 Some(empty_array),
9e0c209e 2451 0, // RuntimeLang
74b04a01
XL
2452 unique_type_id.as_ptr().cast(),
2453 unique_type_id.len(),
dfeec247 2454 )
9e0c209e
SL
2455 };
2456
0bf4aa26 2457 metadata_stub
9e0c209e
SL
2458}
2459
d9579d0f
AL
2460/// Creates debug information for the given global variable.
2461///
2462/// Adds the created metadata nodes directly to the crate's IR.
dfeec247 2463pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global: &'ll Value) {
2c00a5a8 2464 if cx.dbg_cx.is_none() {
d9579d0f
AL
2465 return;
2466 }
1a4d82fc 2467
ba9703b0
XL
2468 // Only create type information if full debuginfo is enabled
2469 if cx.sess().opts.debuginfo != DebugInfo::Full {
2470 return;
2471 }
2472
2c00a5a8 2473 let tcx = cx.tcx;
0531ce1d 2474
60c5eb7d
XL
2475 // We may want to remove the namespace scope if we're in an extern block (see
2476 // https://github.com/rust-lang/rust/pull/46457#issuecomment-351750952).
0531ce1d
XL
2477 let var_scope = get_namespace_for_item(cx, def_id);
2478 let span = tcx.def_span(def_id);
1a4d82fc 2479
8faf50e0 2480 let (file_metadata, line_number) = if !span.is_dummy() {
ba9703b0 2481 let loc = cx.lookup_debug_loc(span.lo());
29967ef6 2482 (file_metadata(cx, &loc.file), loc.line)
d9579d0f 2483 } else {
6a06907d 2484 (unknown_file_metadata(cx), UNKNOWN_LINE_NUMBER)
d9579d0f 2485 };
1a4d82fc 2486
0531ce1d 2487 let is_local_to_unit = is_node_local_to_unit(cx, def_id);
3dfed10e 2488 let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, ty::ParamEnv::reveal_all());
d9579d0f 2489 let type_metadata = type_metadata(cx, variable_type, span);
74b04a01 2490 let var_name = tcx.item_name(def_id).as_str();
3dfed10e 2491 let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id)).name;
74b04a01
XL
2492 // When empty, linkage_name field is omitted,
2493 // which is what we want for no_mangle statics
f035d41b 2494 let linkage_name = if var_name == linkage_name { "" } else { linkage_name };
476ff2be 2495
cc61c64b 2496 let global_align = cx.align_of(variable_type);
476ff2be 2497
d9579d0f 2498 unsafe {
dfeec247
XL
2499 llvm::LLVMRustDIBuilderCreateStaticVariable(
2500 DIB(cx),
2501 Some(var_scope),
74b04a01
XL
2502 var_name.as_ptr().cast(),
2503 var_name.len(),
2504 linkage_name.as_ptr().cast(),
2505 linkage_name.len(),
dfeec247 2506 file_metadata,
6a06907d 2507 line_number,
dfeec247
XL
2508 type_metadata,
2509 is_local_to_unit,
2510 global,
2511 None,
2512 global_align.bytes() as u32,
476ff2be 2513 );
d9579d0f
AL
2514 }
2515}
1a4d82fc 2516
abe05a73
XL
2517/// Creates debug information for the given vtable, which is for the
2518/// given type.
2519///
2520/// Adds the created metadata nodes directly to the crate's IR.
dc9dc135 2521pub fn create_vtable_metadata(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, vtable: &'ll Value) {
2c00a5a8 2522 if cx.dbg_cx.is_none() {
abe05a73
XL
2523 return;
2524 }
2525
ba9703b0
XL
2526 // Only create type information if full debuginfo is enabled
2527 if cx.sess().opts.debuginfo != DebugInfo::Full {
2528 return;
2529 }
2530
dfeec247 2531 let type_metadata = type_metadata(cx, ty, rustc_span::DUMMY_SP);
abe05a73
XL
2532
2533 unsafe {
60c5eb7d 2534 // `LLVMRustDIBuilderCreateStructType()` wants an empty array. A null
abe05a73 2535 // pointer will lead to hard to trace and debug LLVM assertions
60c5eb7d 2536 // later on in `llvm/lib/IR/Value.cpp`.
abe05a73 2537 let empty_array = create_DIArray(DIB(cx), &[]);
74b04a01 2538 let name = "vtable";
abe05a73 2539
60c5eb7d 2540 // Create a new one each time. We don't want metadata caching
abe05a73
XL
2541 // here, because each vtable will refer to a unique containing
2542 // type.
2543 let vtable_type = llvm::LLVMRustDIBuilderCreateStructType(
2544 DIB(cx),
2545 NO_SCOPE_METADATA,
74b04a01
XL
2546 name.as_ptr().cast(),
2547 name.len(),
abe05a73
XL
2548 unknown_file_metadata(cx),
2549 UNKNOWN_LINE_NUMBER,
94b46f34 2550 Size::ZERO.bits(),
a1dfa0c6 2551 cx.tcx.data_layout.pointer_align.abi.bits() as u32,
abe05a73 2552 DIFlags::FlagArtificial,
b7449926 2553 None,
abe05a73
XL
2554 empty_array,
2555 0,
b7449926 2556 Some(type_metadata),
74b04a01
XL
2557 name.as_ptr().cast(),
2558 name.len(),
abe05a73
XL
2559 );
2560
74b04a01 2561 let linkage_name = "";
dfeec247
XL
2562 llvm::LLVMRustDIBuilderCreateStaticVariable(
2563 DIB(cx),
2564 NO_SCOPE_METADATA,
74b04a01
XL
2565 name.as_ptr().cast(),
2566 name.len(),
2567 linkage_name.as_ptr().cast(),
2568 linkage_name.len(),
dfeec247
XL
2569 unknown_file_metadata(cx),
2570 UNKNOWN_LINE_NUMBER,
2571 vtable_type,
2572 true,
2573 vtable,
2574 None,
2575 0,
2576 );
abe05a73
XL
2577 }
2578}
a1dfa0c6 2579
60c5eb7d 2580/// Creates an "extension" of an existing `DIScope` into another file.
a1dfa0c6
XL
2581pub fn extend_scope_to_file(
2582 cx: &CodegenCx<'ll, '_>,
2583 scope_metadata: &'ll DIScope,
29967ef6 2584 file: &SourceFile,
a1dfa0c6 2585) -> &'ll DILexicalBlock {
29967ef6 2586 let file_metadata = file_metadata(cx, file);
dfeec247 2587 unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlockFile(DIB(cx), scope_metadata, file_metadata) }
a1dfa0c6 2588}