提交 079c390d 编写于 作者: V Vadim Petrochenkov

Generate debuginfo for unions

上级 d9b332bd
......@@ -786,7 +786,10 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
usage_site_span).finalize(cx)
}
ty::TyUnion(..) => {
unimplemented!();
prepare_union_metadata(cx,
t,
unique_type_id,
usage_site_span).finalize(cx)
}
ty::TyTuple(ref elements) => {
prepare_tuple_metadata(cx,
......@@ -1038,6 +1041,7 @@ enum MemberDescriptionFactory<'tcx> {
StructMDF(StructMemberDescriptionFactory<'tcx>),
TupleMDF(TupleMemberDescriptionFactory<'tcx>),
EnumMDF(EnumMemberDescriptionFactory<'tcx>),
UnionMDF(UnionMemberDescriptionFactory<'tcx>),
VariantMDF(VariantMemberDescriptionFactory<'tcx>)
}
......@@ -1054,6 +1058,9 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
EnumMDF(ref this) => {
this.create_member_descriptions(cx)
}
UnionMDF(ref this) => {
this.create_member_descriptions(cx)
}
VariantMDF(ref this) => {
this.create_member_descriptions(cx)
}
......@@ -1154,7 +1161,6 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
)
}
//=-----------------------------------------------------------------------------
// Tuples
//=-----------------------------------------------------------------------------
......@@ -1209,6 +1215,66 @@ fn prepare_tuple_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
)
}
//=-----------------------------------------------------------------------------
// Unions
//=-----------------------------------------------------------------------------
struct UnionMemberDescriptionFactory<'tcx> {
variant: ty::VariantDef<'tcx>,
substs: &'tcx Substs<'tcx>,
span: Span,
}
impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
-> Vec<MemberDescription> {
self.variant.fields.iter().map(|field| {
let fty = monomorphize::field_ty(cx.tcx(), self.substs, field);
MemberDescription {
name: field.name.to_string(),
llvm_type: type_of::type_of(cx, fty),
type_metadata: type_metadata(cx, fty, self.span),
offset: FixedMemberOffset { bytes: 0 },
flags: FLAGS_NONE,
}
}).collect()
}
}
fn prepare_union_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
union_type: Ty<'tcx>,
unique_type_id: UniqueTypeId,
span: Span)
-> RecursiveTypeDescription<'tcx> {
let union_name = compute_debuginfo_type_name(cx, union_type, false);
let union_llvm_type = type_of::in_memory_type_of(cx, union_type);
let (union_def_id, variant, substs) = match union_type.sty {
ty::TyUnion(def, substs) => (def.did, def.struct_variant(), substs),
_ => bug!("prepare_union_metadata on a non-union")
};
let (containing_scope, _) = get_namespace_and_span_for_item(cx, union_def_id);
let union_metadata_stub = create_union_stub(cx,
union_llvm_type,
&union_name,
unique_type_id,
containing_scope);
create_and_register_recursive_type_forward_declaration(
cx,
union_type,
unique_type_id,
union_metadata_stub,
union_llvm_type,
UnionMDF(UnionMemberDescriptionFactory {
variant: variant,
substs: substs,
span: span,
})
)
}
//=-----------------------------------------------------------------------------
// Enums
......@@ -1798,6 +1864,42 @@ fn create_struct_stub(cx: &CrateContext,
return metadata_stub;
}
fn create_union_stub(cx: &CrateContext,
union_llvm_type: Type,
union_type_name: &str,
unique_type_id: UniqueTypeId,
containing_scope: DIScope)
-> DICompositeType {
let (union_size, union_align) = size_and_align_of(cx, union_llvm_type);
let unique_type_id_str = debug_context(cx).type_map
.borrow()
.get_unique_type_id_as_string(unique_type_id);
let name = CString::new(union_type_name).unwrap();
let unique_type_id = CString::new(unique_type_id_str.as_bytes()).unwrap();
let metadata_stub = unsafe {
// LLVMRustDIBuilderCreateUnionType() wants an empty array. A null
// pointer will lead to hard to trace and debug LLVM assertions
// later on in llvm/lib/IR/Value.cpp.
let empty_array = create_DIArray(DIB(cx), &[]);
llvm::LLVMRustDIBuilderCreateUnionType(
DIB(cx),
containing_scope,
name.as_ptr(),
unknown_file_metadata(cx),
UNKNOWN_LINE_NUMBER,
bytes_to_bits(union_size),
bytes_to_bits(union_align),
0, // Flags
empty_array,
0, // RuntimeLang
unique_type_id.as_ptr())
};
return metadata_stub;
}
/// Creates debug information for the given global variable.
///
/// Adds the created metadata nodes directly to the crate's IR.
......
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// min-lldb-version: 310
// compile-flags:-g
// === GDB TESTS ===================================================================================
// gdb-command:run
// gdb-command:print u
// gdb-check:$1 = {a = 11 '\v', b = 11}
// gdb-command:print union_smoke::SU
// gdb-check:$2 = {a = 10 '\n', b = 10}
// === LLDB TESTS ==================================================================================
// lldb-command:run
// lldb-command:print a
// lldb-check:[...]$0 = {a = 11 '\v', b = 11}
// lldb-command:print union_smoke::SU
// lldb-check:[...]$1 = {a = 10 '\n', b = 10}
#![allow(unused)]
#![feature(omit_gdb_pretty_printer_section)]
#![omit_gdb_pretty_printer_section]
#![feature(untagged_unions)]
union U {
a: u8,
b: u64,
}
static SU: U = U { a: 10 };
fn main() {
let u = U { b: 11 };
zzz(); // #break
}
fn zzz() {()}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册