Consolidate checking for msvc when generating debuginfo
If the target we're generating code for is msvc, then we do two main things differently: we generate type names in a C++ style instead of a Rust style and we generate debuginfo for enums differently. I've refactored the code so that there is one function (`cpp_like_debuginfo`) which determines if we should use the C++ style of naming types and other debuginfo generation or the regular Rust one.
This commit is contained in:
parent
f8abed9ed4
commit
836addcbc4
@ -18,6 +18,7 @@ use crate::llvm::debuginfo::{
|
|||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
|
|
||||||
use cstr::cstr;
|
use cstr::cstr;
|
||||||
|
use rustc_codegen_ssa::debuginfo::type_names::cpp_like_debuginfo;
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
@ -933,16 +934,16 @@ fn basic_type_metadata<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'l
|
|||||||
|
|
||||||
// When targeting MSVC, emit MSVC style type names for compatibility with
|
// When targeting MSVC, emit MSVC style type names for compatibility with
|
||||||
// .natvis visualizers (and perhaps other existing native debuggers?)
|
// .natvis visualizers (and perhaps other existing native debuggers?)
|
||||||
let msvc_like_names = cx.tcx.sess.target.is_like_msvc;
|
let cpp_like_debuginfo = cpp_like_debuginfo(cx.tcx);
|
||||||
|
|
||||||
let (name, encoding) = match t.kind() {
|
let (name, encoding) = match t.kind() {
|
||||||
ty::Never => ("!", DW_ATE_unsigned),
|
ty::Never => ("!", DW_ATE_unsigned),
|
||||||
ty::Tuple(elements) if elements.is_empty() => ("()", DW_ATE_unsigned),
|
ty::Tuple(elements) if elements.is_empty() => ("()", DW_ATE_unsigned),
|
||||||
ty::Bool => ("bool", DW_ATE_boolean),
|
ty::Bool => ("bool", DW_ATE_boolean),
|
||||||
ty::Char => ("char", DW_ATE_unsigned_char),
|
ty::Char => ("char", DW_ATE_unsigned_char),
|
||||||
ty::Int(int_ty) if msvc_like_names => (int_ty.msvc_basic_name(), DW_ATE_signed),
|
ty::Int(int_ty) if cpp_like_debuginfo => (int_ty.msvc_basic_name(), DW_ATE_signed),
|
||||||
ty::Uint(uint_ty) if msvc_like_names => (uint_ty.msvc_basic_name(), DW_ATE_unsigned),
|
ty::Uint(uint_ty) if cpp_like_debuginfo => (uint_ty.msvc_basic_name(), DW_ATE_unsigned),
|
||||||
ty::Float(float_ty) if msvc_like_names => (float_ty.msvc_basic_name(), DW_ATE_float),
|
ty::Float(float_ty) if cpp_like_debuginfo => (float_ty.msvc_basic_name(), DW_ATE_float),
|
||||||
ty::Int(int_ty) => (int_ty.name_str(), DW_ATE_signed),
|
ty::Int(int_ty) => (int_ty.name_str(), DW_ATE_signed),
|
||||||
ty::Uint(uint_ty) => (uint_ty.name_str(), DW_ATE_unsigned),
|
ty::Uint(uint_ty) => (uint_ty.name_str(), DW_ATE_unsigned),
|
||||||
ty::Float(float_ty) => (float_ty.name_str(), DW_ATE_float),
|
ty::Float(float_ty) => (float_ty.name_str(), DW_ATE_float),
|
||||||
@ -959,7 +960,7 @@ fn basic_type_metadata<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'l
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
if !msvc_like_names {
|
if !cpp_like_debuginfo {
|
||||||
return ty_metadata;
|
return ty_metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1521,13 +1522,6 @@ fn prepare_union_metadata<'ll, 'tcx>(
|
|||||||
// Enums
|
// Enums
|
||||||
//=-----------------------------------------------------------------------------
|
//=-----------------------------------------------------------------------------
|
||||||
|
|
||||||
/// DWARF variant support is only available starting in LLVM 8, but
|
|
||||||
/// on MSVC we have to use the fallback mode, because LLVM doesn't
|
|
||||||
/// lower variant parts to PDB.
|
|
||||||
fn use_enum_fallback(cx: &CodegenCx<'_, '_>) -> bool {
|
|
||||||
cx.sess().target.is_like_msvc
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME(eddyb) maybe precompute this? Right now it's computed once
|
// FIXME(eddyb) maybe precompute this? Right now it's computed once
|
||||||
// per generator monomorphization, but it doesn't depend on substs.
|
// per generator monomorphization, but it doesn't depend on substs.
|
||||||
fn generator_layout_and_saved_local_names<'tcx>(
|
fn generator_layout_and_saved_local_names<'tcx>(
|
||||||
@ -1602,7 +1596,10 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
|
|||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let fallback = use_enum_fallback(cx);
|
// While LLVM supports generating debuginfo for variant types (enums), it doesn't support
|
||||||
|
// lowering that debuginfo to CodeView records for msvc targets. So if we are targeting
|
||||||
|
// msvc, then we need to use a different, fallback encoding of the debuginfo.
|
||||||
|
let fallback = cpp_like_debuginfo(cx.tcx);
|
||||||
// This will always find the metadata in the type map.
|
// This will always find the metadata in the type map.
|
||||||
let self_metadata = type_metadata(cx, self.enum_type, self.span);
|
let self_metadata = type_metadata(cx, self.enum_type, self.span);
|
||||||
|
|
||||||
@ -2155,7 +2152,10 @@ fn prepare_enum_metadata<'ll, 'tcx>(
|
|||||||
return FinalMetadata(discriminant_type_metadata(tag.value));
|
return FinalMetadata(discriminant_type_metadata(tag.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
if use_enum_fallback(cx) {
|
// While LLVM supports generating debuginfo for variant types (enums), it doesn't support
|
||||||
|
// lowering that debuginfo to CodeView records for msvc targets. So if we are targeting
|
||||||
|
// msvc, then we need to use a different encoding of the debuginfo.
|
||||||
|
if cpp_like_debuginfo(tcx) {
|
||||||
let discriminant_type_metadata = match layout.variants {
|
let discriminant_type_metadata = match layout.variants {
|
||||||
Variants::Single { .. } => None,
|
Variants::Single { .. } => None,
|
||||||
Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, tag, .. }
|
Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, tag, .. }
|
||||||
|
@ -53,14 +53,14 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
) {
|
) {
|
||||||
// When targeting MSVC, emit C++ style type names for compatibility with
|
// When targeting MSVC, emit C++ style type names for compatibility with
|
||||||
// .natvis visualizers (and perhaps other existing native debuggers?)
|
// .natvis visualizers (and perhaps other existing native debuggers?)
|
||||||
let cpp_like_names = cpp_like_names(tcx);
|
let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
|
||||||
|
|
||||||
match *t.kind() {
|
match *t.kind() {
|
||||||
ty::Bool => output.push_str("bool"),
|
ty::Bool => output.push_str("bool"),
|
||||||
ty::Char => output.push_str("char"),
|
ty::Char => output.push_str("char"),
|
||||||
ty::Str => output.push_str("str"),
|
ty::Str => output.push_str("str"),
|
||||||
ty::Never => {
|
ty::Never => {
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
output.push_str("never$");
|
output.push_str("never$");
|
||||||
} else {
|
} else {
|
||||||
output.push('!');
|
output.push('!');
|
||||||
@ -71,7 +71,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
ty::Float(float_ty) => output.push_str(float_ty.name_str()),
|
ty::Float(float_ty) => output.push_str(float_ty.name_str()),
|
||||||
ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output),
|
ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output),
|
||||||
ty::Adt(def, substs) => {
|
ty::Adt(def, substs) => {
|
||||||
if def.is_enum() && cpp_like_names {
|
if def.is_enum() && cpp_like_debuginfo {
|
||||||
msvc_enum_fallback(tcx, t, def, substs, output, visited);
|
msvc_enum_fallback(tcx, t, def, substs, output, visited);
|
||||||
} else {
|
} else {
|
||||||
push_item_name(tcx, def.did, qualified, output);
|
push_item_name(tcx, def.did, qualified, output);
|
||||||
@ -79,7 +79,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Tuple(component_types) => {
|
ty::Tuple(component_types) => {
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
output.push_str("tuple$<");
|
output.push_str("tuple$<");
|
||||||
} else {
|
} else {
|
||||||
output.push('(');
|
output.push('(');
|
||||||
@ -87,20 +87,20 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
|
|
||||||
for component_type in component_types {
|
for component_type in component_types {
|
||||||
push_debuginfo_type_name(tcx, component_type.expect_ty(), true, output, visited);
|
push_debuginfo_type_name(tcx, component_type.expect_ty(), true, output, visited);
|
||||||
push_arg_separator(cpp_like_names, output);
|
push_arg_separator(cpp_like_debuginfo, output);
|
||||||
}
|
}
|
||||||
if !component_types.is_empty() {
|
if !component_types.is_empty() {
|
||||||
pop_arg_separator(output);
|
pop_arg_separator(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
push_close_angle_bracket(cpp_like_names, output);
|
push_close_angle_bracket(cpp_like_debuginfo, output);
|
||||||
} else {
|
} else {
|
||||||
output.push(')');
|
output.push(')');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl }) => {
|
ty::RawPtr(ty::TypeAndMut { ty: inner_type, mutbl }) => {
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
match mutbl {
|
match mutbl {
|
||||||
hir::Mutability::Not => output.push_str("ptr_const$<"),
|
hir::Mutability::Not => output.push_str("ptr_const$<"),
|
||||||
hir::Mutability::Mut => output.push_str("ptr_mut$<"),
|
hir::Mutability::Mut => output.push_str("ptr_mut$<"),
|
||||||
@ -115,8 +115,8 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
|
|
||||||
push_debuginfo_type_name(tcx, inner_type, qualified, output, visited);
|
push_debuginfo_type_name(tcx, inner_type, qualified, output, visited);
|
||||||
|
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
push_close_angle_bracket(cpp_like_names, output);
|
push_close_angle_bracket(cpp_like_debuginfo, output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Ref(_, inner_type, mutbl) => {
|
ty::Ref(_, inner_type, mutbl) => {
|
||||||
@ -126,7 +126,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
// types out to aid debugging in MSVC.
|
// types out to aid debugging in MSVC.
|
||||||
let is_slice_or_str = matches!(*inner_type.kind(), ty::Slice(_) | ty::Str);
|
let is_slice_or_str = matches!(*inner_type.kind(), ty::Slice(_) | ty::Str);
|
||||||
|
|
||||||
if !cpp_like_names {
|
if !cpp_like_debuginfo {
|
||||||
output.push('&');
|
output.push('&');
|
||||||
output.push_str(mutbl.prefix_str());
|
output.push_str(mutbl.prefix_str());
|
||||||
} else if !is_slice_or_str {
|
} else if !is_slice_or_str {
|
||||||
@ -138,12 +138,12 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
|
|
||||||
push_debuginfo_type_name(tcx, inner_type, qualified, output, visited);
|
push_debuginfo_type_name(tcx, inner_type, qualified, output, visited);
|
||||||
|
|
||||||
if cpp_like_names && !is_slice_or_str {
|
if cpp_like_debuginfo && !is_slice_or_str {
|
||||||
push_close_angle_bracket(cpp_like_names, output);
|
push_close_angle_bracket(cpp_like_debuginfo, output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Array(inner_type, len) => {
|
ty::Array(inner_type, len) => {
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
output.push_str("array$<");
|
output.push_str("array$<");
|
||||||
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
|
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
|
||||||
match len.val {
|
match len.val {
|
||||||
@ -162,7 +162,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Slice(inner_type) => {
|
ty::Slice(inner_type) => {
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
output.push_str("slice$<");
|
output.push_str("slice$<");
|
||||||
} else {
|
} else {
|
||||||
output.push('[');
|
output.push('[');
|
||||||
@ -170,8 +170,8 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
|
|
||||||
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
|
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
|
||||||
|
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
push_close_angle_bracket(cpp_like_names, output);
|
push_close_angle_bracket(cpp_like_debuginfo, output);
|
||||||
} else {
|
} else {
|
||||||
output.push(']');
|
output.push(']');
|
||||||
}
|
}
|
||||||
@ -179,7 +179,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
ty::Dynamic(ref trait_data, ..) => {
|
ty::Dynamic(ref trait_data, ..) => {
|
||||||
let auto_traits: SmallVec<[DefId; 4]> = trait_data.auto_traits().collect();
|
let auto_traits: SmallVec<[DefId; 4]> = trait_data.auto_traits().collect();
|
||||||
|
|
||||||
let has_enclosing_parens = if cpp_like_names {
|
let has_enclosing_parens = if cpp_like_debuginfo {
|
||||||
output.push_str("dyn$<");
|
output.push_str("dyn$<");
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
@ -216,14 +216,14 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (item_def_id, ty) in projection_bounds {
|
for (item_def_id, ty) in projection_bounds {
|
||||||
push_arg_separator(cpp_like_names, output);
|
push_arg_separator(cpp_like_debuginfo, output);
|
||||||
|
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
output.push_str("assoc$<");
|
output.push_str("assoc$<");
|
||||||
push_item_name(tcx, item_def_id, false, output);
|
push_item_name(tcx, item_def_id, false, output);
|
||||||
push_arg_separator(cpp_like_names, output);
|
push_arg_separator(cpp_like_debuginfo, output);
|
||||||
push_debuginfo_type_name(tcx, ty, true, output, visited);
|
push_debuginfo_type_name(tcx, ty, true, output, visited);
|
||||||
push_close_angle_bracket(cpp_like_names, output);
|
push_close_angle_bracket(cpp_like_debuginfo, output);
|
||||||
} else {
|
} else {
|
||||||
push_item_name(tcx, item_def_id, false, output);
|
push_item_name(tcx, item_def_id, false, output);
|
||||||
output.push('=');
|
output.push('=');
|
||||||
@ -231,11 +231,11 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
push_close_angle_bracket(cpp_like_names, output);
|
push_close_angle_bracket(cpp_like_debuginfo, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if auto_traits.len() != 0 {
|
if auto_traits.len() != 0 {
|
||||||
push_auto_trait_separator(cpp_like_names, output);
|
push_auto_trait_separator(cpp_like_debuginfo, output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,14 +252,14 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
|
|
||||||
for auto_trait in auto_traits {
|
for auto_trait in auto_traits {
|
||||||
output.push_str(&auto_trait);
|
output.push_str(&auto_trait);
|
||||||
push_auto_trait_separator(cpp_like_names, output);
|
push_auto_trait_separator(cpp_like_debuginfo, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
pop_auto_trait_separator(output);
|
pop_auto_trait_separator(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
push_close_angle_bracket(cpp_like_names, output);
|
push_close_angle_bracket(cpp_like_debuginfo, output);
|
||||||
} else if has_enclosing_parens {
|
} else if has_enclosing_parens {
|
||||||
output.push(')');
|
output.push(')');
|
||||||
}
|
}
|
||||||
@ -279,7 +279,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
// use a dummy string that should make it clear
|
// use a dummy string that should make it clear
|
||||||
// that something unusual is going on
|
// that something unusual is going on
|
||||||
if !visited.insert(t) {
|
if !visited.insert(t) {
|
||||||
output.push_str(if cpp_like_names {
|
output.push_str(if cpp_like_debuginfo {
|
||||||
"recursive_type$"
|
"recursive_type$"
|
||||||
} else {
|
} else {
|
||||||
"<recursive_type>"
|
"<recursive_type>"
|
||||||
@ -290,7 +290,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
let sig =
|
let sig =
|
||||||
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), t.fn_sig(tcx));
|
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), t.fn_sig(tcx));
|
||||||
|
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
// Format as a C++ function pointer: return_type (*)(params...)
|
// Format as a C++ function pointer: return_type (*)(params...)
|
||||||
if sig.output().is_unit() {
|
if sig.output().is_unit() {
|
||||||
output.push_str("void");
|
output.push_str("void");
|
||||||
@ -313,7 +313,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
if !sig.inputs().is_empty() {
|
if !sig.inputs().is_empty() {
|
||||||
for ¶meter_type in sig.inputs() {
|
for ¶meter_type in sig.inputs() {
|
||||||
push_debuginfo_type_name(tcx, parameter_type, true, output, visited);
|
push_debuginfo_type_name(tcx, parameter_type, true, output, visited);
|
||||||
push_arg_separator(cpp_like_names, output);
|
push_arg_separator(cpp_like_debuginfo, output);
|
||||||
}
|
}
|
||||||
pop_arg_separator(output);
|
pop_arg_separator(output);
|
||||||
}
|
}
|
||||||
@ -328,7 +328,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
|
|
||||||
output.push(')');
|
output.push(')');
|
||||||
|
|
||||||
if !cpp_like_names && !sig.output().is_unit() {
|
if !cpp_like_debuginfo && !sig.output().is_unit() {
|
||||||
output.push_str(" -> ");
|
output.push_str(" -> ");
|
||||||
push_debuginfo_type_name(tcx, sig.output(), true, output, visited);
|
push_debuginfo_type_name(tcx, sig.output(), true, output, visited);
|
||||||
}
|
}
|
||||||
@ -426,9 +426,9 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
|
|
||||||
const NON_CPP_AUTO_TRAIT_SEPARATOR: &str = " + ";
|
const NON_CPP_AUTO_TRAIT_SEPARATOR: &str = " + ";
|
||||||
|
|
||||||
fn push_auto_trait_separator(cpp_like_names: bool, output: &mut String) {
|
fn push_auto_trait_separator(cpp_like_debuginfo: bool, output: &mut String) {
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
push_arg_separator(cpp_like_names, output);
|
push_arg_separator(cpp_like_debuginfo, output);
|
||||||
} else {
|
} else {
|
||||||
output.push_str(NON_CPP_AUTO_TRAIT_SEPARATOR);
|
output.push_str(NON_CPP_AUTO_TRAIT_SEPARATOR);
|
||||||
}
|
}
|
||||||
@ -457,11 +457,11 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
|
|||||||
t: Ty<'tcx>,
|
t: Ty<'tcx>,
|
||||||
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
|
trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
|
||||||
) -> String {
|
) -> String {
|
||||||
let cpp_like_names = cpp_like_names(tcx);
|
let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
|
||||||
|
|
||||||
let mut vtable_name = String::with_capacity(64);
|
let mut vtable_name = String::with_capacity(64);
|
||||||
|
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
vtable_name.push_str("impl$<");
|
vtable_name.push_str("impl$<");
|
||||||
} else {
|
} else {
|
||||||
vtable_name.push('<');
|
vtable_name.push('<');
|
||||||
@ -470,7 +470,7 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
|
|||||||
let mut visited = FxHashSet::default();
|
let mut visited = FxHashSet::default();
|
||||||
push_debuginfo_type_name(tcx, t, true, &mut vtable_name, &mut visited);
|
push_debuginfo_type_name(tcx, t, true, &mut vtable_name, &mut visited);
|
||||||
|
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
vtable_name.push_str(", ");
|
vtable_name.push_str(", ");
|
||||||
} else {
|
} else {
|
||||||
vtable_name.push_str(" as ");
|
vtable_name.push_str(" as ");
|
||||||
@ -486,9 +486,9 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
|
|||||||
vtable_name.push_str("_");
|
vtable_name.push_str("_");
|
||||||
}
|
}
|
||||||
|
|
||||||
push_close_angle_bracket(cpp_like_names, &mut vtable_name);
|
push_close_angle_bracket(cpp_like_debuginfo, &mut vtable_name);
|
||||||
|
|
||||||
let suffix = if cpp_like_names { "::vtable$" } else { "::{vtable}" };
|
let suffix = if cpp_like_debuginfo { "::vtable$" } else { "::{vtable}" };
|
||||||
|
|
||||||
vtable_name.reserve_exact(suffix.len());
|
vtable_name.reserve_exact(suffix.len());
|
||||||
vtable_name.push_str(suffix);
|
vtable_name.push_str(suffix);
|
||||||
@ -521,7 +521,7 @@ fn push_unqualified_item_name(
|
|||||||
DefPathData::ClosureExpr if tcx.generator_kind(def_id).is_some() => {
|
DefPathData::ClosureExpr if tcx.generator_kind(def_id).is_some() => {
|
||||||
// Generators look like closures, but we want to treat them differently
|
// Generators look like closures, but we want to treat them differently
|
||||||
// in the debug info.
|
// in the debug info.
|
||||||
if cpp_like_names(tcx) {
|
if cpp_like_debuginfo(tcx) {
|
||||||
write!(output, "generator${}", disambiguated_data.disambiguator).unwrap();
|
write!(output, "generator${}", disambiguated_data.disambiguator).unwrap();
|
||||||
} else {
|
} else {
|
||||||
write!(output, "{{generator#{}}}", disambiguated_data.disambiguator).unwrap();
|
write!(output, "{{generator#{}}}", disambiguated_data.disambiguator).unwrap();
|
||||||
@ -532,7 +532,7 @@ fn push_unqualified_item_name(
|
|||||||
output.push_str(name.as_str());
|
output.push_str(name.as_str());
|
||||||
}
|
}
|
||||||
DefPathDataName::Anon { namespace } => {
|
DefPathDataName::Anon { namespace } => {
|
||||||
if cpp_like_names(tcx) {
|
if cpp_like_debuginfo(tcx) {
|
||||||
write!(output, "{}${}", namespace, disambiguated_data.disambiguator).unwrap();
|
write!(output, "{}${}", namespace, disambiguated_data.disambiguator).unwrap();
|
||||||
} else {
|
} else {
|
||||||
write!(output, "{{{}#{}}}", namespace, disambiguated_data.disambiguator)
|
write!(output, "{{{}#{}}}", namespace, disambiguated_data.disambiguator)
|
||||||
@ -560,7 +560,7 @@ fn push_generic_params_internal<'tcx>(
|
|||||||
|
|
||||||
debug_assert_eq!(substs, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs));
|
debug_assert_eq!(substs, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs));
|
||||||
|
|
||||||
let cpp_like_names = cpp_like_names(tcx);
|
let cpp_like_debuginfo = cpp_like_debuginfo(tcx);
|
||||||
|
|
||||||
output.push('<');
|
output.push('<');
|
||||||
|
|
||||||
@ -575,10 +575,10 @@ fn push_generic_params_internal<'tcx>(
|
|||||||
other => bug!("Unexpected non-erasable generic: {:?}", other),
|
other => bug!("Unexpected non-erasable generic: {:?}", other),
|
||||||
}
|
}
|
||||||
|
|
||||||
push_arg_separator(cpp_like_names, output);
|
push_arg_separator(cpp_like_debuginfo, output);
|
||||||
}
|
}
|
||||||
pop_arg_separator(output);
|
pop_arg_separator(output);
|
||||||
push_close_angle_bracket(cpp_like_names, output);
|
push_close_angle_bracket(cpp_like_debuginfo, output);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -617,7 +617,7 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: &'tcx ty::Const<'tcx>, output:
|
|||||||
// avoiding collisions and will make the emitted type names shorter.
|
// avoiding collisions and will make the emitted type names shorter.
|
||||||
let hash: u64 = hasher.finish();
|
let hash: u64 = hasher.finish();
|
||||||
|
|
||||||
if cpp_like_names(tcx) {
|
if cpp_like_debuginfo(tcx) {
|
||||||
write!(output, "CONST${:x}", hash)
|
write!(output, "CONST${:x}", hash)
|
||||||
} else {
|
} else {
|
||||||
write!(output, "{{CONST#{:x}}}", hash)
|
write!(output, "{{CONST#{:x}}}", hash)
|
||||||
@ -634,10 +634,10 @@ pub fn push_generic_params<'tcx>(tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, out
|
|||||||
push_generic_params_internal(tcx, substs, output, &mut visited);
|
push_generic_params_internal(tcx, substs, output, &mut visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_close_angle_bracket(cpp_like_names: bool, output: &mut String) {
|
fn push_close_angle_bracket(cpp_like_debuginfo: bool, output: &mut String) {
|
||||||
// MSVC debugger always treats `>>` as a shift, even when parsing templates,
|
// MSVC debugger always treats `>>` as a shift, even when parsing templates,
|
||||||
// so add a space to avoid confusion.
|
// so add a space to avoid confusion.
|
||||||
if cpp_like_names && output.ends_with('>') {
|
if cpp_like_debuginfo && output.ends_with('>') {
|
||||||
output.push(' ')
|
output.push(' ')
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -652,11 +652,11 @@ fn pop_close_angle_bracket(output: &mut String) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_arg_separator(cpp_like_names: bool, output: &mut String) {
|
fn push_arg_separator(cpp_like_debuginfo: bool, output: &mut String) {
|
||||||
// Natvis does not always like having spaces between parts of the type name
|
// Natvis does not always like having spaces between parts of the type name
|
||||||
// and this causes issues when we need to write a typename in natvis, for example
|
// and this causes issues when we need to write a typename in natvis, for example
|
||||||
// as part of a cast like the `HashMap` visualizer does.
|
// as part of a cast like the `HashMap` visualizer does.
|
||||||
if cpp_like_names {
|
if cpp_like_debuginfo {
|
||||||
output.push(',');
|
output.push(',');
|
||||||
} else {
|
} else {
|
||||||
output.push_str(", ");
|
output.push_str(", ");
|
||||||
@ -673,6 +673,7 @@ fn pop_arg_separator(output: &mut String) {
|
|||||||
output.pop();
|
output.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cpp_like_names(tcx: TyCtxt<'_>) -> bool {
|
/// Check if we should generate C++ like names and debug information.
|
||||||
|
pub fn cpp_like_debuginfo(tcx: TyCtxt<'_>) -> bool {
|
||||||
tcx.sess.target.is_like_msvc
|
tcx.sess.target.is_like_msvc
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user