]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Rollup merge of #92559 - durin42:llvm-14-attributemask, r=nikic
[rust.git] / compiler / rustc_codegen_llvm / src / debuginfo / metadata.rs
index 9160f00363d1edb3857061bbf766f2aaeb0b6918..e8d35cf5697f1050df9f6dfeda5fdffe9e4d003c 100644 (file)
@@ -1037,17 +1037,28 @@ pub fn compile_unit_metadata<'ll, 'tcx>(
 ) -> &'ll DIDescriptor {
     let mut name_in_debuginfo = match tcx.sess.local_crate_source_file {
         Some(ref path) => path.clone(),
-        None => PathBuf::from(&*tcx.crate_name(LOCAL_CRATE).as_str()),
+        None => PathBuf::from(tcx.crate_name(LOCAL_CRATE).as_str()),
     };
 
-    // The OSX linker has an idiosyncrasy where it will ignore some debuginfo
-    // if multiple object files with the same `DW_AT_name` are linked together.
-    // As a workaround we generate unique names for each object file. Those do
-    // not correspond to an actual source file but that is harmless.
-    if tcx.sess.target.is_like_osx {
-        name_in_debuginfo.push("@");
-        name_in_debuginfo.push(codegen_unit_name);
-    }
+    // To avoid breaking split DWARF, we need to ensure that each codegen unit
+    // has a unique `DW_AT_name`. This is because there's a remote chance that
+    // different codegen units for the same module will have entirely
+    // identical DWARF entries for the purpose of the DWO ID, which would
+    // violate Appendix F ("Split Dwarf Object Files") of the DWARF 5
+    // specification. LLVM uses the algorithm specified in section 7.32 "Type
+    // Signature Computation" to compute the DWO ID, which does not include
+    // any fields that would distinguish compilation units. So we must embed
+    // the codegen unit name into the `DW_AT_name`. (Issue #88521.)
+    //
+    // Additionally, the OSX linker has an idiosyncrasy where it will ignore
+    // some debuginfo if multiple object files with the same `DW_AT_name` are
+    // linked together.
+    //
+    // As a workaround for these two issues, we generate unique names for each
+    // object file. Those do not correspond to an actual source file but that
+    // is harmless.
+    name_in_debuginfo.push("@");
+    name_in_debuginfo.push(codegen_unit_name);
 
     debug!("compile_unit_metadata: {:?}", name_in_debuginfo);
     let rustc_producer =
@@ -1059,11 +1070,15 @@ pub fn compile_unit_metadata<'ll, 'tcx>(
     let work_dir = tcx.sess.opts.working_dir.to_string_lossy(FileNameDisplayPreference::Remapped);
     let flags = "\0";
     let output_filenames = tcx.output_filenames(());
-    let out_dir = &output_filenames.out_directory;
     let split_name = if tcx.sess.target_can_use_split_dwarf() {
         output_filenames
-            .split_dwarf_path(tcx.sess.split_debuginfo(), Some(codegen_unit_name))
-            .map(|f| out_dir.join(f))
+            .split_dwarf_path(
+                tcx.sess.split_debuginfo(),
+                tcx.sess.opts.debugging_opts.split_dwarf_kind,
+                Some(codegen_unit_name),
+            )
+            // We get a path relative to the working directory from split_dwarf_path
+            .map(|f| tcx.sess.source_map().path_mapping().map_prefix(f).0)
     } else {
         None
     }
@@ -1360,7 +1375,7 @@ fn closure_saved_names_of_captured_variables(tcx: TyCtxt<'_>, def_id: DefId) ->
                 _ => return None,
             };
             let prefix = if is_ref { "_ref__" } else { "" };
-            Some(prefix.to_owned() + &var.name.as_str())
+            Some(prefix.to_owned() + var.name.as_str())
         })
         .collect::<Vec<_>>()
 }
@@ -1938,7 +1953,7 @@ enum VariantInfo<'a, 'tcx> {
 impl<'tcx> VariantInfo<'_, 'tcx> {
     fn map_struct_name<R>(&self, f: impl FnOnce(&str) -> R) -> R {
         match self {
-            VariantInfo::Adt(variant) => f(&variant.ident.as_str()),
+            VariantInfo::Adt(variant) => f(variant.ident.as_str()),
             VariantInfo::Generator { variant_index, .. } => {
                 f(&GeneratorSubsts::variant_name(*variant_index))
             }
@@ -2103,8 +2118,8 @@ fn prepare_enum_metadata<'ll, 'tcx>(
                 let item_name;
                 let discriminant_name = match enum_type.kind() {
                     ty::Adt(..) => {
-                        item_name = tcx.item_name(enum_def_id).as_str();
-                        &*item_name
+                        item_name = tcx.item_name(enum_def_id);
+                        item_name.as_str()
                     }
                     ty::Generator(..) => enum_name.as_str(),
                     _ => bug!(),
@@ -2437,7 +2452,7 @@ fn compute_type_parameters<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -
                             cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
                         let actual_type_metadata =
                             type_metadata(cx, actual_type, rustc_span::DUMMY_SP);
-                        let name = &name.as_str();
+                        let name = name.as_str();
                         Some(unsafe {
                             Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
                                 DIB(cx),
@@ -2579,7 +2594,8 @@ pub fn create_global_var_metadata<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId, g
     let is_local_to_unit = is_node_local_to_unit(cx, def_id);
     let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, ty::ParamEnv::reveal_all());
     let type_metadata = type_metadata(cx, variable_type, span);
-    let var_name = tcx.item_name(def_id).as_str();
+    let var_name = tcx.item_name(def_id);
+    let var_name = var_name.as_str();
     let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id)).name;
     // When empty, linkage_name field is omitted,
     // which is what we want for no_mangle statics