Skip to content

Commit

Permalink
auto merge of rust-lang#7710 : michaelwoerister/rust/WP4, r=jdm
Browse files Browse the repository at this point in the history
This pull request includes various improvements:

+ Composite types (structs, tuples, boxes, etc) are now handled more cleanly by debuginfo generation. Most notably, field offsets are now extracted directly from LLVM types, as opposed to trying to reconstruct them. This leads to more stable handling of edge cases (e.g. packed structs or structs implementing drop).

+ `debuginfo.rs` in general has seen a major cleanup. This includes better formatting, more readable variable and function names, removal of dead code, and better factoring of functionality.

+ Handling of `VariantInfo` in `ty.rs` has been improved. That is, the `type VariantInfo = @VariantInfo_` typedef has been replaced with explicit uses of @VariantInfo, and the duplicated logic for creating VariantInfo instances in `ty::enum_variants()` and `typeck::check::mod::check_enum_variants()` has been unified into a single constructor function. Both function now look nicer too :)

+ Debug info generation for enum types is now mostly supported. This includes:
  + Good support for C-style enums. Both DWARF and `gdb` know how to handle them.
  + Proper description of tuple- and struct-style enum variants as unions of structs.
  + Proper handling of univariant enums without discriminator field.
  + Unfortunately `gdb` always prints all possible interpretations of a union, so debug output of enums is verbose and unintuitive. Neither `LLVM` nor `gdb` support DWARF's `DW_TAG_variant` which allows to properly describe tagged unions. Adding support for this to `LLVM` seems doable. `gdb` however is another story. In the future we might be able to use `gdb`'s Python scripting support to alleviate this problem. In agreement with @jdm this is not a high priority for now.

+ The debuginfo test suite has been extended with 14 test files including tests for packed structs (with Drop), boxed structs, boxed vecs, vec slices, c-style enums (standalone and embedded), empty enums, tuple- and struct-style enums, and various pointer types to the above.

~~What is not yet included is DI support for some enum edge-cases represented as described in `trans::adt::NullablePointer`.~~

Cheers,
Michael

PS: closes rust-lang#7819,  fixes rust-lang#7712
  • Loading branch information
bors committed Jul 20, 2013
2 parents 3a1db2d + a1303cc commit 8aae6ed
Show file tree
Hide file tree
Showing 43 changed files with 2,728 additions and 741 deletions.
39 changes: 39 additions & 0 deletions src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1635,6 +1635,14 @@ pub mod llvm {
#[fast_ffi]
pub unsafe fn LLVMABIAlignmentOfType(TD: TargetDataRef,
Ty: TypeRef) -> c_uint;

/** Computes the byte offset of the indexed struct element for a target. */
#[fast_ffi]
pub unsafe fn LLVMOffsetOfElement(TD: TargetDataRef,
StructTy: TypeRef,
Element: c_uint)
-> c_ulonglong;

/**
* Returns the minimum alignment of a type when part of a call frame.
*/
Expand Down Expand Up @@ -2089,6 +2097,37 @@ pub mod llvm {
Val: ValueRef,
VarInfo: DIVariable,
InsertBefore: ValueRef) -> ValueRef;

#[fast_ffi]
pub unsafe fn LLVMDIBuilderCreateEnumerator(
Builder: DIBuilderRef,
Name: *c_char,
Val: c_ulonglong) -> ValueRef;

#[fast_ffi]
pub unsafe fn LLVMDIBuilderCreateEnumerationType(
Builder: DIBuilderRef,
Scope: ValueRef,
Name: *c_char,
File: ValueRef,
LineNumber: c_uint,
SizeInBits: c_ulonglong,
AlignInBits: c_ulonglong,
Elements: ValueRef,
ClassType: ValueRef) -> ValueRef;

#[fast_ffi]
pub unsafe fn LLVMDIBuilderCreateUnionType(
Builder: DIBuilderRef,
Scope: ValueRef,
Name: *c_char,
File: ValueRef,
LineNumber: c_uint,
SizeInBits: c_ulonglong,
AlignInBits: c_ulonglong,
Flags: c_uint ,
Elements: ValueRef,
RunTimeLang: c_uint) -> ValueRef;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub fn maybe_get_item_ast(tcx: ty::ctxt, def: ast::def_id,
}

pub fn get_enum_variants(tcx: ty::ctxt, def: ast::def_id)
-> ~[ty::VariantInfo] {
-> ~[@ty::VariantInfo] {
let cstore = tcx.cstore;
let cdata = cstore::get_crate_data(cstore, def.crate);
return decoder::get_enum_variants(cstore.intr, cdata, def.node, tcx)
Expand Down
19 changes: 12 additions & 7 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -737,11 +737,11 @@ pub fn maybe_get_item_ast(cdata: cmd, tcx: ty::ctxt,
}

pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::node_id,
tcx: ty::ctxt) -> ~[ty::VariantInfo] {
tcx: ty::ctxt) -> ~[@ty::VariantInfo] {
let data = cdata.data;
let items = reader::get_doc(reader::Doc(data), tag_items);
let item = find_item(id, items);
let mut infos: ~[ty::VariantInfo] = ~[];
let mut infos: ~[@ty::VariantInfo] = ~[];
let variant_ids = enum_variant_ids(item, cdata);
let mut disr_val = 0;
for variant_ids.iter().advance |did| {
Expand All @@ -757,11 +757,16 @@ pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::node_id,
Some(val) => { disr_val = val; }
_ => { /* empty */ }
}
infos.push(@ty::VariantInfo_{args: arg_tys,
ctor_ty: ctor_ty, name: name,
// I'm not even sure if we encode visibility
// for variants -- TEST -- tjc
id: *did, disr_val: disr_val, vis: ast::inherited});
infos.push(@ty::VariantInfo{
args: arg_tys,
arg_names: None,
ctor_ty: ctor_ty,
name: name,
// I'm not even sure if we encode visibility
// for variants -- TEST -- tjc
id: *did,
disr_val: disr_val,
vis: ast::inherited});
disr_val += 1;
}
return infos;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ pub enum Repr {
}

/// For structs, and struct-like parts of anything fancier.
struct Struct {
pub struct Struct {
size: u64,
align: u64,
packed: bool,
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
let _icx = push_ctxt("iter_structural_ty");

fn iter_variant(cx: block, repr: &adt::Repr, av: ValueRef,
variant: ty::VariantInfo,
variant: @ty::VariantInfo,
tps: &[ty::t], f: val_and_ty_fn) -> block {
let _icx = push_ctxt("iter_variant");
let tcx = cx.tcx();
Expand Down Expand Up @@ -1141,7 +1141,7 @@ pub fn trans_stmt(cx: block, s: &ast::stmt) -> block {
bcx = init_local(bcx, *local);
if cx.sess().opts.extra_debuginfo
&& fcx_has_nonzero_span(bcx.fcx) {
debuginfo::create_local_var(bcx, *local);
debuginfo::create_local_var_metadata(bcx, *local);
}
}
ast::decl_item(i) => trans_item(cx.fcx.ccx, i)
Expand Down Expand Up @@ -1773,7 +1773,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt,
bcx = _match::store_arg(bcx, args[arg_n].pat, llarg);

if fcx.ccx.sess.opts.extra_debuginfo && fcx_has_nonzero_span(fcx) {
debuginfo::create_arg(bcx, &args[arg_n], args[arg_n].ty.span);
debuginfo::create_argument_metadata(bcx, &args[arg_n], args[arg_n].ty.span);
}
}

Expand Down Expand Up @@ -1947,7 +1947,7 @@ pub fn trans_fn(ccx: @mut CrateContext,
|fcx| {
if ccx.sess.opts.extra_debuginfo
&& fcx_has_nonzero_span(fcx) {
debuginfo::create_function(fcx);
debuginfo::create_function_metadata(fcx);
}
},
|_bcx| { });
Expand Down Expand Up @@ -2109,7 +2109,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>(
}

pub fn trans_enum_def(ccx: @mut CrateContext, enum_definition: &ast::enum_def,
id: ast::node_id, vi: @~[ty::VariantInfo],
id: ast::node_id, vi: @~[@ty::VariantInfo],
i: &mut uint) {
for enum_definition.variants.iter().advance |variant| {
let disr_val = vi[*i].disr_val;
Expand Down
Loading

0 comments on commit 8aae6ed

Please sign in to comment.