auto merge of #7710 : michaelwoerister/rust/WP4, r=jdm

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 #7819,  fixes #7712
This commit is contained in:
bors 2013-07-20 09:10:34 -07:00
commit 8aae6edce0
43 changed files with 2736 additions and 749 deletions

View file

@ -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.
*/
@ -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;
}
}

View file

@ -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)

View file

@ -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| {
@ -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;

View file

@ -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,

View file

@ -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();
@ -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)
@ -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);
}
}
@ -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| { });
@ -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;

File diff suppressed because it is too large Load diff

View file

@ -113,3 +113,9 @@ pub fn llalign_of(cx: &CrateContext, ty: Type) -> ValueRef {
llvm::LLVMAlignOf(ty.to_ref()), cx.int_type.to_ref(), False);
}
}
pub fn llelement_offset(cx: &CrateContext, struct_ty: Type, element: uint) -> uint {
unsafe {
return llvm::LLVMOffsetOfElement(cx.td.lltd, struct_ty.to_ref(), element as u32) as uint;
}
}

View file

@ -49,6 +49,8 @@ use syntax::opt_vec;
use syntax::abi::AbiSet;
use syntax;
pub static INITIAL_DISCRIMINANT_VALUE: int = 0;
// Data types
#[deriving(Eq, IterBytes)]
@ -275,7 +277,7 @@ struct ctxt_ {
needs_unwind_cleanup_cache: @mut HashMap<t, bool>,
tc_cache: @mut HashMap<uint, TypeContents>,
ast_ty_to_ty_cache: @mut HashMap<node_id, ast_ty_to_ty_cache_entry>,
enum_var_cache: @mut HashMap<def_id, @~[VariantInfo]>,
enum_var_cache: @mut HashMap<def_id, @~[@VariantInfo]>,
ty_param_defs: @mut HashMap<ast::node_id, TypeParameterDef>,
adjustments: @mut HashMap<ast::node_id, @AutoAdjustment>,
normalized_cache: @mut HashMap<t, t>,
@ -3681,8 +3683,9 @@ fn struct_ctor_id(cx: ctxt, struct_did: ast::def_id) -> Option<ast::def_id> {
// Enum information
#[deriving(Clone)]
pub struct VariantInfo_ {
pub struct VariantInfo {
args: ~[t],
arg_names: Option<~[ast::ident]>,
ctor_ty: t,
name: ast::ident,
id: ast::def_id,
@ -3690,19 +3693,71 @@ pub struct VariantInfo_ {
vis: visibility
}
pub type VariantInfo = @VariantInfo_;
impl VariantInfo {
/// Creates a new VariantInfo from the corresponding ast representation.
///
/// Does not do any caching of the value in the type context.
pub fn from_ast_variant(cx: ctxt,
ast_variant: &ast::variant,
discriminant: int) -> VariantInfo {
let ctor_ty = node_id_to_type(cx, ast_variant.node.id);
match ast_variant.node.kind {
ast::tuple_variant_kind(ref args) => {
let arg_tys = if args.len() > 0 { ty_fn_args(ctor_ty).map(|a| *a) } else { ~[] };
return VariantInfo {
args: arg_tys,
arg_names: None,
ctor_ty: ctor_ty,
name: ast_variant.node.name,
id: ast_util::local_def(ast_variant.node.id),
disr_val: discriminant,
vis: ast_variant.node.vis
};
},
ast::struct_variant_kind(ref struct_def) => {
let fields: &[@struct_field] = struct_def.fields;
assert!(fields.len() > 0);
let arg_tys = ty_fn_args(ctor_ty).map(|a| *a);
let arg_names = do fields.map |field| {
match field.node.kind {
named_field(ident, _) => ident,
unnamed_field => cx.sess.bug(
"enum_variants: all fields in struct must have a name")
}
};
return VariantInfo {
args: arg_tys,
arg_names: Some(arg_names),
ctor_ty: ctor_ty,
name: ast_variant.node.name,
id: ast_util::local_def(ast_variant.node.id),
disr_val: discriminant,
vis: ast_variant.node.vis
};
}
}
}
}
pub fn substd_enum_variants(cx: ctxt,
id: ast::def_id,
substs: &substs)
-> ~[VariantInfo] {
-> ~[@VariantInfo] {
do enum_variants(cx, id).iter().transform |variant_info| {
let substd_args = variant_info.args.iter()
.transform(|aty| subst(cx, substs, *aty)).collect();
let substd_ctor_ty = subst(cx, substs, variant_info.ctor_ty);
@VariantInfo_ {
@VariantInfo {
args: substd_args,
ctor_ty: substd_ctor_ty,
..(**variant_info).clone()
@ -3820,7 +3875,7 @@ pub fn type_is_empty(cx: ctxt, t: t) -> bool {
}
}
pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[VariantInfo] {
pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[@VariantInfo] {
match cx.enum_var_cache.find(&id) {
Some(&variants) => return variants,
_ => { /* fallthrough */ }
@ -3839,61 +3894,31 @@ pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[VariantInfo] {
node: ast::item_enum(ref enum_definition, _),
_
}, _) => {
let mut disr_val = -1;
let mut last_discriminant: Option<int> = None;
@enum_definition.variants.iter().transform(|variant| {
let ctor_ty = node_id_to_type(cx, variant.node.id);
let mut discriminant = match last_discriminant {
Some(val) => val + 1,
None => INITIAL_DISCRIMINANT_VALUE
};
match variant.node.kind {
ast::tuple_variant_kind(ref args) => {
let arg_tys = if args.len() > 0u {
ty_fn_args(ctor_ty).map(|a| *a) }
else {
~[]
};
match variant.node.disr_expr {
Some (ex) => {
disr_val = match const_eval::eval_const_expr(cx,
ex) {
const_eval::const_int(val) => val as int,
_ => cx.sess.bug("enum_variants: bad disr expr")
}
}
_ => disr_val += 1
match variant.node.disr_expr {
Some(e) => match const_eval::eval_const_expr_partial(&cx, e) {
Ok(const_eval::const_int(val)) => discriminant = val as int,
Ok(_) => {
cx.sess.span_err(e.span, "expected signed integer constant");
}
Err(ref err) => {
cx.sess.span_err(e.span, fmt!("expected constant: %s", (*err)));
}
@VariantInfo_{
args: arg_tys,
ctor_ty: ctor_ty,
name: variant.node.name,
id: ast_util::local_def(variant.node.id),
disr_val: disr_val,
vis: variant.node.vis
}
},
ast::struct_variant_kind(struct_def) => {
let arg_tys =
// Is this check needed for structs too, or are they always guaranteed
// to have a valid constructor function?
if struct_def.fields.len() > 0 {
ty_fn_args(ctor_ty).map(|a| *a)
} else {
~[]
};
None => {}
};
assert!(variant.node.disr_expr.is_none());
disr_val += 1;
let variant_info = @VariantInfo::from_ast_variant(cx, variant, discriminant);
last_discriminant = Some(discriminant);
variant_info
@VariantInfo_{
args: arg_tys,
ctor_ty: ctor_ty,
name: variant.node.name,
id: ast_util::local_def(variant.node.id),
disr_val: disr_val,
vis: variant.node.vis
}
}
}
}).collect()
}
_ => cx.sess.bug("enum_variants: id not bound to an enum")
@ -3908,7 +3933,7 @@ pub fn enum_variants(cx: ctxt, id: ast::def_id) -> @~[VariantInfo] {
pub fn enum_variant_with_id(cx: ctxt,
enum_id: ast::def_id,
variant_id: ast::def_id)
-> VariantInfo {
-> @VariantInfo {
let variants = enum_variants(cx, enum_id);
let mut i = 0;
while i < variants.len() {

View file

@ -81,7 +81,7 @@ use middle::const_eval;
use middle::pat_util::pat_id_map;
use middle::pat_util;
use middle::lint::unreachable_code;
use middle::ty::{FnSig, VariantInfo_};
use middle::ty::{FnSig, VariantInfo};
use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty};
use middle::ty::{substs, param_ty, ExprTyProvider};
use middle::ty;
@ -3133,82 +3133,66 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt,
vs: &[ast::variant],
id: ast::node_id) {
fn do_check(ccx: @mut CrateCtxt,
_sp: span,
vs: &[ast::variant],
id: ast::node_id,
disr_vals: &mut ~[int],
disr_val: &mut int,
variants: &mut ~[ty::VariantInfo]) {
id: ast::node_id)
-> ~[@ty::VariantInfo] {
let rty = ty::node_id_to_type(ccx.tcx, id);
let mut variants: ~[@ty::VariantInfo] = ~[];
let mut disr_vals: ~[int] = ~[];
let mut prev_disr_val: Option<int> = None;
for vs.iter().advance |v| {
for v.node.disr_expr.iter().advance |e_ref| {
let e = *e_ref;
debug!("disr expr, checking %s",
pprust::expr_to_str(e, ccx.tcx.sess.intr()));
let declty = ty::mk_int();
let fcx = blank_fn_ctxt(ccx, rty, e.id);
check_const_with_ty(fcx, e.span, e, declty);
// check_expr (from check_const pass) doesn't guarantee
// that the expression is in an form that eval_const_expr can
// handle, so we may still get an internal compiler error
match const_eval::eval_const_expr_partial(&ccx.tcx, e) {
Ok(const_eval::const_int(val)) => {
*disr_val = val as int;
}
Ok(_) => {
ccx.tcx.sess.span_err(e.span, "expected signed integer \
constant");
}
Err(ref err) => {
ccx.tcx.sess.span_err(e.span,
fmt!("expected constant: %s", (*err)));
}
}
}
if disr_vals.contains(&*disr_val) {
ccx.tcx.sess.span_err(v.span,
"discriminator value already exists");
}
disr_vals.push(*disr_val);
let ctor_ty = ty::node_id_to_type(ccx.tcx, v.node.id);
let this_disr_val = *disr_val;
*disr_val += 1;
let arg_tys = match v.node.kind {
ast::tuple_variant_kind(ref args) if args.len() > 0u => {
Some(ty::ty_fn_args(ctor_ty).map(|a| *a))
}
ast::tuple_variant_kind(_) => {
Some(~[])
}
ast::struct_variant_kind(_) => {
Some(ty::lookup_struct_fields(
ccx.tcx, local_def(v.node.id)).map(|cf|
ty::node_id_to_type(ccx.tcx, cf.id.node)))
}
// If the discriminant value is specified explicitly in the enum check whether the
// initialization expression is valid, otherwise use the last value plus one.
let mut current_disr_val = match prev_disr_val {
Some(prev_disr_val) => prev_disr_val + 1,
None => ty::INITIAL_DISCRIMINANT_VALUE
};
match arg_tys {
None => {}
Some(arg_tys) => {
variants.push(
@VariantInfo_{args: arg_tys, ctor_ty: ctor_ty,
name: v.node.name, id: local_def(v.node.id),
disr_val: this_disr_val, vis: v.node.vis});
}
match v.node.disr_expr {
Some(e) => {
debug!("disr expr, checking %s", pprust::expr_to_str(e, ccx.tcx.sess.intr()));
let declty = ty::mk_int();
let fcx = blank_fn_ctxt(ccx, rty, e.id);
check_const_with_ty(fcx, e.span, e, declty);
// check_expr (from check_const pass) doesn't guarantee
// that the expression is in an form that eval_const_expr can
// handle, so we may still get an internal compiler error
match const_eval::eval_const_expr_partial(&ccx.tcx, e) {
Ok(const_eval::const_int(val)) => current_disr_val = val as int,
Ok(_) => {
ccx.tcx.sess.span_err(e.span, "expected signed integer constant");
}
Err(ref err) => {
ccx.tcx.sess.span_err(e.span, fmt!("expected constant: %s", (*err)));
}
}
},
None => ()
};
// Check for duplicate discriminator values
if disr_vals.contains(&current_disr_val) {
ccx.tcx.sess.span_err(v.span, "discriminator value already exists");
}
disr_vals.push(current_disr_val);
let variant_info = @VariantInfo::from_ast_variant(ccx.tcx, v, current_disr_val);
prev_disr_val = Some(current_disr_val);
variants.push(variant_info);
}
return variants;
}
let rty = ty::node_id_to_type(ccx.tcx, id);
let mut disr_vals: ~[int] = ~[];
let mut disr_val = 0;
let mut variants = ~[];
do_check(ccx, sp, vs, id, &mut disr_vals, &mut disr_val, &mut variants);
let variants = do_check(ccx, vs, id);
// cache so that ty::enum_variants won't repeat this work
ccx.tcx.enum_var_cache.insert(local_def(id), @variants);

View file

@ -565,8 +565,8 @@ extern "C" bool LLVMRustStartMultithreading() {
typedef DIBuilder* DIBuilderRef;
template<typename DIT>
DIT unwrapDI(LLVMValueRef ref) {
return DIT(ref ? unwrap<MDNode>(ref) : NULL);
DIT unwrapDI(LLVMValueRef ref) {
return DIT(ref ? unwrap<MDNode>(ref) : NULL);
}
extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) {
@ -604,21 +604,21 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateFile(
extern "C" LLVMValueRef LLVMDIBuilderCreateSubroutineType(
DIBuilderRef Builder,
LLVMValueRef File,
LLVMValueRef File,
LLVMValueRef ParameterTypes) {
return wrap(Builder->createSubroutineType(
unwrapDI<DIFile>(File),
unwrapDI<DIFile>(File),
unwrapDI<DIArray>(ParameterTypes)));
}
extern "C" LLVMValueRef LLVMDIBuilderCreateFunction(
DIBuilderRef Builder,
LLVMValueRef Scope,
LLVMValueRef Scope,
const char* Name,
const char* LinkageName,
LLVMValueRef File,
LLVMValueRef File,
unsigned LineNo,
LLVMValueRef Ty,
LLVMValueRef Ty,
bool isLocalToUnit,
bool isDefinition,
unsigned ScopeLine,
@ -628,11 +628,11 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateFunction(
LLVMValueRef TParam,
LLVMValueRef Decl) {
return wrap(Builder->createFunction(
unwrapDI<DIScope>(Scope), Name, LinkageName,
unwrapDI<DIFile>(File), LineNo,
unwrapDI<DIType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
unwrapDI<DIScope>(Scope), Name, LinkageName,
unwrapDI<DIFile>(File), LineNo,
unwrapDI<DIType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
Flags, isOptimized,
unwrap<Function>(Fn),
unwrap<Function>(Fn),
unwrapDI<MDNode*>(TParam),
unwrapDI<MDNode*>(Decl)));
}
@ -644,10 +644,10 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateBasicType(
uint64_t AlignInBits,
unsigned Encoding) {
return wrap(Builder->createBasicType(
Name, SizeInBits,
Name, SizeInBits,
AlignInBits, Encoding));
}
extern "C" LLVMValueRef LLVMDIBuilderCreatePointerType(
DIBuilderRef Builder,
LLVMValueRef PointeeTy,
@ -672,11 +672,11 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateStructType(
unsigned RunTimeLang,
LLVMValueRef VTableHolder) {
return wrap(Builder->createStructType(
unwrapDI<DIDescriptor>(Scope), Name,
unwrapDI<DIFile>(File), LineNumber,
SizeInBits, AlignInBits, Flags,
unwrapDI<DIType>(DerivedFrom),
unwrapDI<DIArray>(Elements), RunTimeLang,
unwrapDI<DIDescriptor>(Scope), Name,
unwrapDI<DIFile>(File), LineNumber,
SizeInBits, AlignInBits, Flags,
unwrapDI<DIType>(DerivedFrom),
unwrapDI<DIArray>(Elements), RunTimeLang,
unwrapDI<MDNode*>(VTableHolder)));
}
@ -692,12 +692,12 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateMemberType(
unsigned Flags,
LLVMValueRef Ty) {
return wrap(Builder->createMemberType(
unwrapDI<DIDescriptor>(Scope), Name,
unwrapDI<DIDescriptor>(Scope), Name,
unwrapDI<DIFile>(File), LineNo,
SizeInBits, AlignInBits, OffsetInBits, Flags,
SizeInBits, AlignInBits, OffsetInBits, Flags,
unwrapDI<DIType>(Ty)));
}
extern "C" LLVMValueRef LLVMDIBuilderCreateLexicalBlock(
DIBuilderRef Builder,
LLVMValueRef Scope,
@ -705,10 +705,10 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateLexicalBlock(
unsigned Line,
unsigned Col) {
return wrap(Builder->createLexicalBlock(
unwrapDI<DIDescriptor>(Scope),
unwrapDI<DIDescriptor>(Scope),
unwrapDI<DIFile>(File), Line, Col));
}
extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable(
DIBuilderRef Builder,
unsigned Tag,
@ -720,45 +720,45 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable(
bool AlwaysPreserve,
unsigned Flags,
unsigned ArgNo) {
return wrap(Builder->createLocalVariable(Tag,
unwrapDI<DIDescriptor>(Scope), Name,
unwrapDI<DIFile>(File),
LineNo,
return wrap(Builder->createLocalVariable(Tag,
unwrapDI<DIDescriptor>(Scope), Name,
unwrapDI<DIFile>(File),
LineNo,
unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
}
extern "C" LLVMValueRef LLVMDIBuilderCreateArrayType(
DIBuilderRef Builder,
uint64_t Size,
uint64_t AlignInBits,
LLVMValueRef Ty,
uint64_t Size,
uint64_t AlignInBits,
LLVMValueRef Ty,
LLVMValueRef Subscripts) {
return wrap(Builder->createArrayType(Size, AlignInBits,
unwrapDI<DIType>(Ty),
unwrapDI<DIType>(Ty),
unwrapDI<DIArray>(Subscripts)));
}
extern "C" LLVMValueRef LLVMDIBuilderCreateVectorType(
DIBuilderRef Builder,
uint64_t Size,
uint64_t AlignInBits,
LLVMValueRef Ty,
uint64_t Size,
uint64_t AlignInBits,
LLVMValueRef Ty,
LLVMValueRef Subscripts) {
return wrap(Builder->createVectorType(Size, AlignInBits,
unwrapDI<DIType>(Ty),
unwrapDI<DIType>(Ty),
unwrapDI<DIArray>(Subscripts)));
}
extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateSubrange(
DIBuilderRef Builder,
int64_t Lo,
DIBuilderRef Builder,
int64_t Lo,
int64_t Count) {
return wrap(Builder->getOrCreateSubrange(Lo, Count));
}
extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateArray(
DIBuilderRef Builder,
LLVMValueRef* Ptr,
LLVMValueRef* Ptr,
unsigned Count) {
return wrap(Builder->getOrCreateArray(
ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
@ -770,8 +770,8 @@ extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
LLVMValueRef VarInfo,
LLVMBasicBlockRef InsertAtEnd) {
return wrap(Builder->insertDeclare(
unwrap(Val),
unwrapDI<DIVariable>(VarInfo),
unwrap(Val),
unwrapDI<DIVariable>(VarInfo),
unwrap(InsertAtEnd)));
}
@ -781,7 +781,61 @@ extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
LLVMValueRef VarInfo,
LLVMValueRef InsertBefore) {
return wrap(Builder->insertDeclare(
unwrap(Val),
unwrapDI<DIVariable>(VarInfo),
unwrap(Val),
unwrapDI<DIVariable>(VarInfo),
unwrap<Instruction>(InsertBefore)));
}
extern "C" LLVMValueRef LLVMDIBuilderCreateEnumerator(
DIBuilderRef Builder,
const char* Name,
uint64_t Val)
{
return wrap(Builder->createEnumerator(Name, Val));
}
extern "C" LLVMValueRef LLVMDIBuilderCreateEnumerationType(
DIBuilderRef Builder,
LLVMValueRef Scope,
const char* Name,
LLVMValueRef File,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
LLVMValueRef Elements,
LLVMValueRef ClassType)
{
return wrap(Builder->createEnumerationType(
unwrapDI<DIDescriptor>(Scope),
Name,
unwrapDI<DIFile>(File),
LineNumber,
SizeInBits,
AlignInBits,
unwrapDI<DIArray>(Elements),
unwrapDI<DIType>(ClassType)));
}
extern "C" LLVMValueRef LLVMDIBuilderCreateUnionType(
DIBuilderRef Builder,
LLVMValueRef Scope,
const char* Name,
LLVMValueRef File,
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
unsigned Flags,
LLVMValueRef Elements,
unsigned RunTimeLang)
{
return wrap(Builder->createUnionType(
unwrapDI<DIDescriptor>(Scope),
Name,
unwrapDI<DIFile>(File),
LineNumber,
SizeInBits,
AlignInBits,
Flags,
unwrapDI<DIArray>(Elements),
RunTimeLang));
}

View file

@ -608,3 +608,6 @@ LLVMDIBuilderCreateSubroutineType
LLVMDIBuilderGetOrCreateArray
LLVMDIBuilderInsertDeclareAtEnd
LLVMDIBuilderInsertDeclareBefore
LLVMDIBuilderCreateEnumerator
LLVMDIBuilderCreateEnumerationType
LLVMDIBuilderCreateUnionType

View file

@ -10,10 +10,7 @@
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// Caveats - gdb prints any 8-bit value (meaning rust i8 and u8 values)
// as its numerical value along with its associated ASCII char, there
// doesn't seem to be any way around this. Also, gdb doesn't know
// about UTF-32 character encoding and will print a rust char as only
// Gdb doesn't know about UTF-32 character encoding and will print a rust char as only
// its numerical value.
// compile-flags:-Z extra-debug-info
@ -67,49 +64,49 @@
fn main() {
let bool_val: bool = true;
let bool_ref : &bool = &bool_val;
let bool_ref: &bool = &bool_val;
let int_val: int = -1;
let int_ref : &int = &int_val;
let int_ref: &int = &int_val;
let char_val: char = 'a';
let char_ref : &char = &char_val;
let char_ref: &char = &char_val;
let i8_val: i8 = 68;
let i8_ref : &i8 = &i8_val;
let i8_ref: &i8 = &i8_val;
let i16_val: i16 = -16;
let i16_ref : &i16 = &i16_val;
let i16_ref: &i16 = &i16_val;
let i32_val: i32 = -32;
let i32_ref : &i32 = &i32_val;
let i32_ref: &i32 = &i32_val;
let uint_val: i64 = -64;
let i64_ref : &i64 = &uint_val;
let i64_ref: &i64 = &uint_val;
let uint_val: uint = 1;
let uint_ref : &uint = &uint_val;
let uint_ref: &uint = &uint_val;
let u8_val: u8 = 100;
let u8_ref : &u8 = &u8_val;
let u8_ref: &u8 = &u8_val;
let u16_val: u16 = 16;
let u16_ref : &u16 = &u16_val;
let u16_ref: &u16 = &u16_val;
let u32_val: u32 = 32;
let u32_ref : &u32 = &u32_val;
let u32_ref: &u32 = &u32_val;
let u64_val: u64 = 64;
let u64_ref : &u64 = &u64_val;
let u64_ref: &u64 = &u64_val;
let float_val: float = 1.5;
let float_ref : &float = &float_val;
let float_ref: &float = &float_val;
let f32_val: f32 = 2.5;
let f32_ref : &f32 = &f32_val;
let f32_ref: &f32 = &f32_val;
let f64_val: f64 = 3.5;
let f64_ref : &f64 = &f64_val;
let f64_ref: &f64 = &f64_val;
zzz();
}

View file

@ -0,0 +1,42 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print *the_a_ref
// check:$1 = TheA
// debugger:print *the_b_ref
// check:$2 = TheB
// debugger:print *the_c_ref
// check:$3 = TheC
enum ABC { TheA, TheB, TheC }
fn main() {
let the_a = TheA;
let the_a_ref: &ABC = &the_a;
let the_b = TheB;
let the_b_ref: &ABC = &the_b;
let the_c = TheC;
let the_c_ref: &ABC = &the_c;
zzz();
}
fn zzz() {()}

View file

@ -0,0 +1,62 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print *the_a_ref
// check:$1 = {{TheA, x = 0, y = 8970181431921507452}, {TheA, 0, 2088533116, 2088533116}}
// debugger:print *the_b_ref
// check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}}
// debugger:print *univariant_ref
// check:$3 = {4820353753753434}
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
// the size of the discriminant value is machine dependent, this has be taken into account when
// datatype layout should be predictable as in this case.
enum ABC {
TheA { x: i64, y: i64 },
TheB (i64, i32, i32),
}
// This is a special case since it does not have the implicit discriminant field.
enum Univariant {
TheOnlyCase(i64)
}
fn main() {
// 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
// 0b01111100011111000111110001111100 = 2088533116
// 0b0111110001111100 = 31868
// 0b01111100 = 124
let the_a = TheA { x: 0, y: 8970181431921507452 };
let the_a_ref: &ABC = &the_a;
// 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
// 0b00010001000100010001000100010001 = 286331153
// 0b0001000100010001 = 4369
// 0b00010001 = 17
let the_b = TheB (0, 286331153, 286331153);
let the_b_ref: &ABC = &the_b;
let univariant = TheOnlyCase(4820353753753434);
let univariant_ref: &Univariant = &univariant;
zzz();
}
fn zzz() {()}

View file

@ -65,49 +65,49 @@
fn main() {
let bool_box: @bool = @true;
let bool_ref : &bool = bool_box;
let bool_ref: &bool = bool_box;
let int_box: @int = @-1;
let int_ref : &int = int_box;
let int_ref: &int = int_box;
let char_box: @char = @'a';
let char_ref : &char = char_box;
let char_ref: &char = char_box;
let i8_box: @i8 = @68;
let i8_ref : &i8 = i8_box;
let i8_ref: &i8 = i8_box;
let i16_box: @i16 = @-16;
let i16_ref : &i16 = i16_box;
let i16_ref: &i16 = i16_box;
let i32_box: @i32 = @-32;
let i32_ref : &i32 = i32_box;
let i32_ref: &i32 = i32_box;
let i64_box: @i64 = @-64;
let i64_ref : &i64 = i64_box;
let i64_ref: &i64 = i64_box;
let uint_box: @uint = @1;
let uint_ref : &uint = uint_box;
let uint_ref: &uint = uint_box;
let u8_box: @u8 = @100;
let u8_ref : &u8 = u8_box;
let u8_ref: &u8 = u8_box;
let u16_box: @u16 = @16;
let u16_ref : &u16 = u16_box;
let u16_ref: &u16 = u16_box;
let u32_box: @u32 = @32;
let u32_ref : &u32 = u32_box;
let u32_ref: &u32 = u32_box;
let u64_box: @u64 = @64;
let u64_ref : &u64 = u64_box;
let u64_ref: &u64 = u64_box;
let float_box: @float = @1.5;
let float_ref : &float = float_box;
let float_ref: &float = float_box;
let f32_box: @f32 = @2.5;
let f32_ref : &f32 = f32_box;
let f32_ref: &f32 = f32_box;
let f64_box: @f64 = @3.5;
let f64_ref : &f64 = f64_box;
let f64_ref: &f64 = f64_box;
zzz();
}

View file

@ -10,9 +10,6 @@
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// GDB doesn't know about UTF-32 character encoding and will print a rust char as only its numerical
// value.
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
@ -57,20 +54,20 @@ struct SomeStruct {
fn main() {
let stack_val: SomeStruct = SomeStruct { x: 10, y: 23.5 };
let stack_val_ref : &SomeStruct = &stack_val;
let stack_val_interior_ref_1 : &int = &stack_val.x;
let stack_val_interior_ref_2 : &f64 = &stack_val.y;
let ref_to_unnamed : &SomeStruct = &SomeStruct { x: 11, y: 24.5 };
let stack_val_ref: &SomeStruct = &stack_val;
let stack_val_interior_ref_1: &int = &stack_val.x;
let stack_val_interior_ref_2: &f64 = &stack_val.y;
let ref_to_unnamed: &SomeStruct = &SomeStruct { x: 11, y: 24.5 };
let managed_val = @SomeStruct { x: 12, y: 25.5 };
let managed_val_ref : &SomeStruct = managed_val;
let managed_val_interior_ref_1 : &int = &managed_val.x;
let managed_val_interior_ref_2 : &f64 = &managed_val.y;
let managed_val_ref: &SomeStruct = managed_val;
let managed_val_interior_ref_1: &int = &managed_val.x;
let managed_val_interior_ref_2: &f64 = &managed_val.y;
let unique_val = ~SomeStruct { x: 13, y: 26.5 };
let unique_val_ref : &SomeStruct = unique_val;
let unique_val_interior_ref_1 : &int = &unique_val.x;
let unique_val_interior_ref_2 : &f64 = &unique_val.y;
let unique_val_ref: &SomeStruct = unique_val;
let unique_val_interior_ref_1: &int = &unique_val.x;
let unique_val_interior_ref_2: &f64 = &unique_val.y;
zzz();
}

View file

@ -10,9 +10,6 @@
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// GDB doesn't know about UTF-32 character encoding and will print a rust char as only its numerical
// value.
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
@ -32,14 +29,14 @@
fn main() {
let stack_val: (i16, f32) = (-14, -19f32);
let stack_val_ref : &(i16, f32) = &stack_val;
let ref_to_unnamed : &(i16, f32) = &(-15, -20f32);
let stack_val_ref: &(i16, f32) = &stack_val;
let ref_to_unnamed: &(i16, f32) = &(-15, -20f32);
let managed_val : @(i16, f32) = @(-16, -21f32);
let managed_val_ref : &(i16, f32) = managed_val;
let managed_val: @(i16, f32) = @(-16, -21f32);
let managed_val_ref: &(i16, f32) = managed_val;
let unique_val: ~(i16, f32) = ~(-17, -22f32);
let unique_val_ref : &(i16, f32) = unique_val;
let unique_val_ref: &(i16, f32) = unique_val;
zzz();
}

View file

@ -10,8 +10,7 @@
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// Gdb doesn't know
// about UTF-32 character encoding and will print a rust char as only
// Gdb doesn't know about UTF-32 character encoding and will print a rust char as only
// its numerical value.
// compile-flags:-Z extra-debug-info
@ -66,49 +65,49 @@
fn main() {
let bool_box: ~bool = ~true;
let bool_ref : &bool = bool_box;
let bool_ref: &bool = bool_box;
let int_box: ~int = ~-1;
let int_ref : &int = int_box;
let int_ref: &int = int_box;
let char_box: ~char = ~'a';
let char_ref : &char = char_box;
let char_ref: &char = char_box;
let i8_box: ~i8 = ~68;
let i8_ref : &i8 = i8_box;
let i8_ref: &i8 = i8_box;
let i16_box: ~i16 = ~-16;
let i16_ref : &i16 = i16_box;
let i16_ref: &i16 = i16_box;
let i32_box: ~i32 = ~-32;
let i32_ref : &i32 = i32_box;
let i32_ref: &i32 = i32_box;
let i64_box: ~i64 = ~-64;
let i64_ref : &i64 = i64_box;
let i64_ref: &i64 = i64_box;
let uint_box: ~uint = ~1;
let uint_ref : &uint = uint_box;
let uint_ref: &uint = uint_box;
let u8_box: ~u8 = ~100;
let u8_ref : &u8 = u8_box;
let u8_ref: &u8 = u8_box;
let u16_box: ~u16 = ~16;
let u16_ref : &u16 = u16_box;
let u16_ref: &u16 = u16_box;
let u32_box: ~u32 = ~32;
let u32_ref : &u32 = u32_box;
let u32_ref: &u32 = u32_box;
let u64_box: ~u64 = ~64;
let u64_ref : &u64 = u64_box;
let u64_ref: &u64 = u64_box;
let float_box: ~float = ~1.5;
let float_ref : &float = float_box;
let float_ref: &float = float_box;
let f32_box: ~f32 = ~2.5;
let f32_ref : &f32 = f32_box;
let f32_ref: &f32 = f32_box;
let f64_box: ~f64 = ~3.5;
let f64_ref : &f64 = f64_box;
let f64_ref: &f64 = f64_box;
zzz();
}

View file

@ -8,20 +8,20 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// xfail-test
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:set print pretty off
// debugger:break _zzz
// debugger:run
// debugger:finish
// debugger:print a->boxed
// debugger:print *a
// check:$1 = 1
// debugger:print b->boxed
// debugger:print *b
// check:$2 = {2, 3.5}
// debugger:print c->boxed
// debugger:print c->val
// check:$3 = 4
// debugger:print d->boxed
// debugger:print d->val
// check:$4 = false
fn main() {

View file

@ -0,0 +1,59 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print *unique
// check:$1 = {x = 99, y = 999, z = 9999, w = 99999}
// debugger:print managed->val
// check:$2 = {x = 88, y = 888, z = 8888, w = 88888}
// debugger:print *unique_dtor
// check:$3 = {x = 77, y = 777, z = 7777, w = 77777}
// debugger:print managed_dtor->val
// check:$4 = {x = 33, y = 333, z = 3333, w = 33333}
struct StructWithSomePadding {
x: i16,
y: i32,
z: i32,
w: i64
}
struct StructWithDestructor {
x: i16,
y: i32,
z: i32,
w: i64
}
impl Drop for StructWithDestructor {
fn drop(&self) {}
}
fn main() {
let unique = ~StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 };
let managed = @StructWithSomePadding { x: 88, y: 888, z: 8888, w: 88888 };
let unique_dtor = ~StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 };
let managed_dtor = @StructWithDestructor { x: 33, y: 333, z: 3333, w: 33333 };
zzz();
}
fn zzz() {()}

View file

@ -0,0 +1,36 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print managed->val.fill
// check:$1 = 24
// debugger:print *((uint64_t[3]*)(managed->val.elements))
// check:$2 = {7, 8, 9}
// debugger:print unique->fill
// check:$3 = 32
// debugger:print *((uint64_t[4]*)(unique->elements))
// check:$4 = {10, 11, 12, 13}
fn main() {
let managed: @[i64] = @[7, 8, 9];
let unique: ~[i64] = ~[10, 11, 12, 13];
zzz();
}
fn zzz() {()}

View file

@ -0,0 +1,119 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print tuple_interior_padding
// check:$1 = {0, OneHundred}
// debugger:print tuple_padding_at_end
// check:$2 = {{1, OneThousand}, 2}
// debugger:print tuple_different_enums
// check:$3 = {OneThousand, MountainView, OneMillion, Vienna}
// debugger:print padded_struct
// check:$4 = {a = 3, b = OneMillion, c = 4, d = Toronto, e = 5}
// debugger:print packed_struct
// check:$5 = {a = 6, b = OneHundred, c = 7, d = Vienna, e = 8}
// debugger:print non_padded_struct
// check:$6 = {a = OneMillion, b = MountainView, c = OneThousand, d = Toronto}
// debugger:print struct_with_drop
// check:$7 = {{a = OneHundred, b = Vienna}, 9}
enum AnEnum {
OneHundred = 100,
OneThousand = 1000,
OneMillion = 1000000
}
enum AnotherEnum {
MountainView,
Toronto,
Vienna
}
struct PaddedStruct {
a: i16,
b: AnEnum,
c: i16,
d: AnotherEnum,
e: i16
}
#[packed]
struct PackedStruct {
a: i16,
b: AnEnum,
c: i16,
d: AnotherEnum,
e: i16
}
struct NonPaddedStruct {
a: AnEnum,
b: AnotherEnum,
c: AnEnum,
d: AnotherEnum
}
struct StructWithDrop {
a: AnEnum,
b: AnotherEnum
}
impl Drop for StructWithDrop {
fn drop(&self) {()}
}
fn main() {
let tuple_interior_padding = (0_i16, OneHundred);
// It will depend on the machine architecture if any padding is actually involved here
let tuple_padding_at_end = ((1_u64, OneThousand), 2_u64);
let tuple_different_enums = (OneThousand, MountainView, OneMillion, Vienna);
let padded_struct = PaddedStruct {
a: 3,
b: OneMillion,
c: 4,
d: Toronto,
e: 5
};
let packed_struct = PackedStruct {
a: 6,
b: OneHundred,
c: 7,
d: Vienna,
e: 8
};
let non_padded_struct = NonPaddedStruct {
a: OneMillion,
b: MountainView,
c: OneThousand,
d: Toronto
};
let struct_with_drop = (StructWithDrop { a: OneHundred, b: Vienna }, 9_i64);
zzz();
}
fn zzz() {()}

View file

@ -0,0 +1,70 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print auto_one
// check:$1 = One
// debugger:print auto_two
// check:$2 = Two
// debugger:print auto_three
// check:$3 = Three
// debugger:print manual_one_hundred
// check:$4 = OneHundred
// debugger:print manual_one_thousand
// check:$5 = OneThousand
// debugger:print manual_one_million
// check:$6 = OneMillion
// debugger:print single_variant
// check:$7 = TheOnlyVariant
enum AutoDiscriminant {
One,
Two,
Three
}
enum ManualDiscriminant {
OneHundred = 100,
OneThousand = 1000,
OneMillion = 1000000
}
enum SingleVariant {
TheOnlyVariant
}
fn main() {
let auto_one = One;
let auto_two = Two;
let auto_three = Three;
let manual_one_hundred = OneHundred;
let manual_one_thousand = OneThousand;
let manual_one_million = OneMillion;
let single_variant = TheOnlyVariant;
zzz();
}
fn zzz() {()}

View file

@ -10,9 +10,6 @@
// xfail-test
// GDB doesn't know about UTF-32 character encoding and will print a rust char as only its numerical
// value.
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
@ -25,7 +22,7 @@
// check:$2 = false
fn main() {
let (a, b) : (int, bool) = (9898, false);
let (a, b): (int, bool) = (9898, false);
zzz();
}

View file

@ -0,0 +1,88 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:set print pretty off
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print no_padding1
// check:$1 = {x = {0, 1, 2}, y = -3, z = {4.5, 5.5}}
// debugger:print no_padding2
// check:$2 = {x = {6, 7, 8}, y = {{9, 10}, {11, 12}}}
// debugger:print struct_internal_padding
// check:$3 = {x = {13, 14}, y = {15, 16}}
// debugger:print single_vec
// check:$4 = {x = {17, 18, 19, 20, 21}}
// debugger:print struct_padded_at_end
// check:$5 = {x = {22, 23}, y = {24, 25}}
struct NoPadding1 {
x: [u32, ..3],
y: i32,
z: [f32, ..2]
}
struct NoPadding2 {
x: [u32, ..3],
y: [[u32, ..2], ..2]
}
struct StructInternalPadding {
x: [i16, ..2],
y: [i64, ..2]
}
struct SingleVec {
x: [i16, ..5]
}
struct StructPaddedAtEnd {
x: [i64, ..2],
y: [i16, ..2]
}
fn main() {
let no_padding1 = NoPadding1 {
x: [0, 1, 2],
y: -3,
z: [4.5, 5.5]
};
let no_padding2 = NoPadding2 {
x: [6, 7, 8],
y: [[9, 10], [11, 12]]
};
let struct_internal_padding = StructInternalPadding {
x: [13, 14],
y: [15, 16]
};
let single_vec = SingleVec {
x: [17, 18, 19, 20, 21]
};
let struct_padded_at_end = StructPaddedAtEnd {
x: [22, 23],
y: [24, 25]
};
zzz();
}
fn zzz() {()}

View file

@ -10,9 +10,6 @@
// xfail-test
// GDB doesn't know about UTF-32 character encoding and will print a rust char as only its numerical
// value.
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run

View file

@ -0,0 +1,63 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print the_a->val
// check:$1 = {{TheA, x = 0, y = 8970181431921507452}, {TheA, 0, 2088533116, 2088533116}}
// debugger:print the_b->val
// check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}}
// debugger:print univariant->val
// check:$3 = {-9747455}
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
// the size of the discriminant value is machine dependent, this has be taken into account when
// datatype layout should be predictable as in this case.
enum ABC {
TheA { x: i64, y: i64 },
TheB (i64, i32, i32),
}
// This is a special case since it does not have the implicit discriminant field.
enum Univariant {
TheOnlyCase(i64)
}
fn main() {
// In order to avoid endianess trouble all of the following test values consist of a single
// repeated byte. This way each interpretation of the union should look the same, no matter if
// this is a big or little endian machine.
// 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
// 0b01111100011111000111110001111100 = 2088533116
// 0b0111110001111100 = 31868
// 0b01111100 = 124
let the_a = @TheA { x: 0, y: 8970181431921507452 };
// 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
// 0b00010001000100010001000100010001 = 286331153
// 0b0001000100010001 = 4369
// 0b00010001 = 17
let the_b = @TheB (0, 286331153, 286331153);
let univariant = @TheOnlyCase(-9747455);
zzz();
}
fn zzz() {()}

View file

@ -0,0 +1,37 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print unique->val.elements[0]->val
// check:$1 = 10
// debugger:print unique->val.elements[1]->val
// check:$2 = 11
// debugger:print unique->val.elements[2]->val
// check:$3 = 12
// debugger:print unique->val.elements[3]->val
// check:$4 = 13
fn main() {
let unique: ~[@i64] = ~[@10, @11, @12, @13];
zzz();
}
fn zzz() {()}

View file

@ -0,0 +1,47 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:set print pretty off
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print *ordinary_unique
// check:$1 = {-1, -2}
// debugger:print managed_within_unique.val->x
// check:$2 = -3
// debugger:print managed_within_unique.val->y->val
// check:$3 = -4
struct ContainsManaged
{
x: int,
y: @int
}
fn main() {
let ordinary_unique = ~(-1, -2);
// This is a special case: Normally values allocated in the exchange heap are not boxed, unless,
// however, if they contain managed pointers.
// This test case verifies that both cases are handled correctly.
let managed_within_unique = ~ContainsManaged { x: -3, y: @-4 };
zzz();
}
fn zzz() {()}

View file

@ -0,0 +1,40 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print first
// check:$1 = {<No data fields>}
// debugger:print second
// check:$2 = {<No data fields>}
enum ANilEnum {}
enum AnotherNilEnum {}
// I (mw) am not sure this test case makes much sense...
// Also, it relies on some implementation details:
// 1. That empty enums as well as '()' are represented as empty structs
// 2. That gdb prints the string "{<No data fields>}" for empty structs (which may change some time)
fn main() {
unsafe {
let first: ANilEnum = std::cast::transmute(());
let second: AnotherNilEnum = std::cast::transmute(());
zzz();
}
}
fn zzz() {()}

View file

@ -0,0 +1,71 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print some
// check:$1 = {0x12345678}
// debugger:print none
// check:$2 = {0x0}
// debugger:print full
// check:$3 = {454545, 0x87654321, 9988}
// debugger:print empty
// check:$4 = {0, 0x0, 0}
// debugger:print droid
// check:$5 = {id = 675675, range = 10000001, internals = 0x43218765}
// debugger:print void_droid
// check:$6 = {id = 0, range = 0, internals = 0x0}
// If a struct has exactly two variants, one of them is empty, and the other one
// contains a non-nullable pointer, then this value is used as the discriminator.
// The test cases in this file make sure that something readable is generated for
// this kind of types.
enum MoreFields<'self> {
Full(u32, &'self int, i16),
Empty
}
enum NamedFields<'self> {
Droid { id: i32, range: i64, internals: &'self int },
Void
}
fn main() {
let some: Option<&u32> = Some(unsafe { std::cast::transmute(0x12345678) });
let none: Option<&u32> = None;
let full = Full(454545, unsafe { std::cast::transmute(0x87654321) }, 9988);
let int_val = 0;
let mut empty = Full(0, &int_val, 0);
empty = Empty;
let droid = Droid { id: 675675, range: 10000001, internals: unsafe { std::cast::transmute(0x43218765) } };
let mut void_droid = Droid { id: 0, range: 0, internals: &int_val };
void_droid = Void;
zzz();
}
fn zzz() {()}

View file

@ -0,0 +1,219 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:set print pretty off
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print packed
// check:$1 = {x = 123, y = 234, z = 345}
// debugger:print packedInPacked
// check:$2 = {a = 1111, b = {x = 2222, y = 3333, z = 4444}, c = 5555, d = {x = 6666, y = 7777, z = 8888}}
// debugger:print packedInUnpacked
// check:$3 = {a = -1111, b = {x = -2222, y = -3333, z = -4444}, c = -5555, d = {x = -6666, y = -7777, z = -8888}}
// debugger:print unpackedInPacked
// check:$4 = {a = 987, b = {x = 876, y = 765, z = 654}, c = {x = 543, y = 432, z = 321}, d = 210}
// debugger:print packedInPackedWithDrop
// check:$5 = {a = 11, b = {x = 22, y = 33, z = 44}, c = 55, d = {x = 66, y = 77, z = 88}}
// debugger:print packedInUnpackedWithDrop
// check:$6 = {a = -11, b = {x = -22, y = -33, z = -44}, c = -55, d = {x = -66, y = -77, z = -88}}
// debugger:print unpackedInPackedWithDrop
// check:$7 = {a = 98, b = {x = 87, y = 76, z = 65}, c = {x = 54, y = 43, z = 32}, d = 21}
// debugger:print deeplyNested
// check:$8 = {a = {a = 1, b = {x = 2, y = 3, z = 4}, c = 5, d = {x = 6, y = 7, z = 8}}, b = {a = 9, b = {x = 10, y = 11, z = 12}, c = {x = 13, y = 14, z = 15}, d = 16}, c = {a = 17, b = {x = 18, y = 19, z = 20}, c = 21, d = {x = 22, y = 23, z = 24}}, d = {a = 25, b = {x = 26, y = 27, z = 28}, c = 29, d = {x = 30, y = 31, z = 32}}, e = {a = 33, b = {x = 34, y = 35, z = 36}, c = {x = 37, y = 38, z = 39}, d = 40}, f = {a = 41, b = {x = 42, y = 43, z = 44}, c = 45, d = {x = 46, y = 47, z = 48}}}
#[packed]
struct Packed {
x: i16,
y: i32,
z: i64
}
impl Drop for Packed {
fn drop(&self) {}
}
#[packed]
struct PackedInPacked {
a: i32,
b: Packed,
c: i64,
d: Packed
}
struct PackedInUnpacked {
a: i32,
b: Packed,
c: i64,
d: Packed
}
struct Unpacked {
x: i64,
y: i32,
z: i16
}
impl Drop for Unpacked {
fn drop(&self) {}
}
#[packed]
struct UnpackedInPacked {
a: i16,
b: Unpacked,
c: Unpacked,
d: i64
}
#[packed]
struct PackedInPackedWithDrop {
a: i32,
b: Packed,
c: i64,
d: Packed
}
impl Drop for PackedInPackedWithDrop {
fn drop(&self) {}
}
struct PackedInUnpackedWithDrop {
a: i32,
b: Packed,
c: i64,
d: Packed
}
impl Drop for PackedInUnpackedWithDrop {
fn drop(&self) {}
}
#[packed]
struct UnpackedInPackedWithDrop {
a: i16,
b: Unpacked,
c: Unpacked,
d: i64
}
impl Drop for UnpackedInPackedWithDrop {
fn drop(&self) {}
}
struct DeeplyNested {
a: PackedInPacked,
b: UnpackedInPackedWithDrop,
c: PackedInUnpacked,
d: PackedInUnpackedWithDrop,
e: UnpackedInPacked,
f: PackedInPackedWithDrop
}
fn main() {
let packed = Packed { x: 123, y: 234, z: 345 };
let packedInPacked = PackedInPacked {
a: 1111,
b: Packed { x: 2222, y: 3333, z: 4444 },
c: 5555,
d: Packed { x: 6666, y: 7777, z: 8888 }
};
let packedInUnpacked = PackedInUnpacked {
a: -1111,
b: Packed { x: -2222, y: -3333, z: -4444 },
c: -5555,
d: Packed { x: -6666, y: -7777, z: -8888 }
};
let unpackedInPacked = UnpackedInPacked {
a: 987,
b: Unpacked { x: 876, y: 765, z: 654 },
c: Unpacked { x: 543, y: 432, z: 321 },
d: 210
};
let packedInPackedWithDrop = PackedInPackedWithDrop {
a: 11,
b: Packed { x: 22, y: 33, z: 44 },
c: 55,
d: Packed { x: 66, y: 77, z: 88 }
};
let packedInUnpackedWithDrop = PackedInUnpackedWithDrop {
a: -11,
b: Packed { x: -22, y: -33, z: -44 },
c: -55,
d: Packed { x: -66, y: -77, z: -88 }
};
let unpackedInPackedWithDrop = UnpackedInPackedWithDrop {
a: 98,
b: Unpacked { x: 87, y: 76, z: 65 },
c: Unpacked { x: 54, y: 43, z: 32 },
d: 21
};
let deeplyNested = DeeplyNested {
a: PackedInPacked {
a: 1,
b: Packed { x: 2, y: 3, z: 4 },
c: 5,
d: Packed { x: 6, y: 7, z: 8 }
},
b: UnpackedInPackedWithDrop {
a: 9,
b: Unpacked { x: 10, y: 11, z: 12 },
c: Unpacked { x: 13, y: 14, z: 15 },
d: 16
},
c: PackedInUnpacked {
a: 17,
b: Packed { x: 18, y: 19, z: 20 },
c: 21,
d: Packed { x: 22, y: 23, z: 24 }
},
d: PackedInUnpackedWithDrop {
a: 25,
b: Packed { x: 26, y: 27, z: 28 },
c: 29,
d: Packed { x: 30, y: 31, z: 32 }
},
e: UnpackedInPacked {
a: 33,
b: Unpacked { x: 34, y: 35, z: 36 },
c: Unpacked { x: 37, y: 38, z: 39 },
d: 40
},
f: PackedInPackedWithDrop {
a: 41,
b: Packed { x: 42, y: 43, z: 44 },
c: 45,
d: Packed { x: 46, y: 47, z: 48 }
}
};
zzz();
}
fn zzz() {()}

View file

@ -0,0 +1,104 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:set print pretty off
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print packed
// check:$1 = {x = 123, y = 234, z = 345}
// debugger:print packedInPacked
// check:$2 = {a = 1111, b = {x = 2222, y = 3333, z = 4444}, c = 5555, d = {x = 6666, y = 7777, z = 8888}}
// debugger:print packedInUnpacked
// check:$3 = {a = -1111, b = {x = -2222, y = -3333, z = -4444}, c = -5555, d = {x = -6666, y = -7777, z = -8888}}
// debugger:print unpackedInPacked
// check:$4 = {a = 987, b = {x = 876, y = 765, z = 654, w = 543}, c = {x = 432, y = 321, z = 210, w = 109}, d = -98}
// debugger:print sizeof(packed)
// check:$5 = 14
// debugger:print sizeof(packedInPacked)
// check:$6 = 40
#[packed]
struct Packed {
x: i16,
y: i32,
z: i64
}
#[packed]
struct PackedInPacked {
a: i32,
b: Packed,
c: i64,
d: Packed
}
// layout (64 bit): aaaa bbbb bbbb bbbb bb.. .... cccc cccc dddd dddd dddd dd..
struct PackedInUnpacked {
a: i32,
b: Packed,
c: i64,
d: Packed
}
// layout (64 bit): xx.. yyyy zz.. .... wwww wwww
struct Unpacked {
x: i16,
y: i32,
z: i16,
w: i64
}
// layout (64 bit): aabb bbbb bbbb bbbb bbbb bbbb bbcc cccc cccc cccc cccc cccc ccdd dddd dd
#[packed]
struct UnpackedInPacked {
a: i16,
b: Unpacked,
c: Unpacked,
d: i64
}
fn main() {
let packed = Packed { x: 123, y: 234, z: 345 };
let packedInPacked = PackedInPacked {
a: 1111,
b: Packed { x: 2222, y: 3333, z: 4444 },
c: 5555,
d: Packed { x: 6666, y: 7777, z: 8888 }
};
let packedInUnpacked = PackedInUnpacked {
a: -1111,
b: Packed { x: -2222, y: -3333, z: -4444 },
c: -5555,
d: Packed { x: -6666, y: -7777, z: -8888 }
};
let unpackedInPacked = UnpackedInPacked {
a: 987,
b: Unpacked { x: 876, y: 765, z: 654, w: 543 },
c: Unpacked { x: 432, y: 321, z: 210, w: 109 },
d: -98
};
zzz();
}
fn zzz() {()}

View file

@ -35,15 +35,15 @@
fn main() {
let noPadding8 : (i8, u8) = (-100, 100);
let noPadding16 : (i16, i16, u16) = (0, 1, 2);
let noPadding32 : (i32, f32, u32) = (3, 4.5, 5);
let noPadding64 : (i64, f64, u64) = (6, 7.5, 8);
let noPadding8: (i8, u8) = (-100, 100);
let noPadding16: (i16, i16, u16) = (0, 1, 2);
let noPadding32: (i32, f32, u32) = (3, 4.5, 5);
let noPadding64: (i64, f64, u64) = (6, 7.5, 8);
let internalPadding1 : (i16, i32) = (9, 10);
let internalPadding2 : (i16, i32, u32, u64) = (11, 12, 13, 14);
let internalPadding1: (i16, i32) = (9, 10);
let internalPadding2: (i16, i32, u32, u64) = (11, 12, 13, 14);
let paddingAtEnd : (i32, i16) = (15, 16);
let paddingAtEnd: (i32, i16) = (15, 16);
zzz();
}

View file

@ -0,0 +1,69 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:set print union on
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print case1
// check:$1 = {{Case1, 0, {x = 2088533116, y = 2088533116, z = 31868}}, {Case1, 0, 8970181431921507452, 31868}}
// debugger:print case2
// check:$2 = {{Case2, 0, {x = 286331153, y = 286331153, z = 4369}}, {Case2, 0, 1229782938247303441, 4369}}
// debugger:print univariant
// check:$3 = {{x = 123, y = 456, z = 789}}
struct Struct {
x: u32,
y: i32,
z: i16
}
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
// the size of the discriminant value is machine dependent, this has be taken into account when
// datatype layout should be predictable as in this case.
enum Regular {
Case1(u64, Struct),
Case2(u64, u64, i16)
}
enum Univariant {
TheOnlyCase(Struct)
}
fn main() {
// In order to avoid endianess trouble all of the following test values consist of a single
// repeated byte. This way each interpretation of the union should look the same, no matter if
// this is a big or little endian machine.
// 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
// 0b01111100011111000111110001111100 = 2088533116
// 0b0111110001111100 = 31868
// 0b01111100 = 124
let case1 = Case1(0, Struct { x: 2088533116, y: 2088533116, z: 31868 });
// 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
// 0b00010001000100010001000100010001 = 286331153
// 0b0001000100010001 = 4369
// 0b00010001 = 17
let case2 = Case2(0, 1229782938247303441, 4369);
let univariant = TheOnlyCase(Struct { x: 123, y: 456, z: 789 });
zzz();
}
fn zzz() {()}

View file

@ -0,0 +1,73 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:set print union on
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print case1
// check:$1 = {{Case1, a = 0, b = 31868, c = 31868, d = 31868, e = 31868}, {Case1, a = 0, b = 2088533116, c = 2088533116}, {Case1, a = 0, b = 8970181431921507452}}
// debugger:print case2
// check:$2 = {{Case2, a = 0, b = 4369, c = 4369, d = 4369, e = 4369}, {Case2, a = 0, b = 286331153, c = 286331153}, {Case2, a = 0, b = 1229782938247303441}}
// debugger:print case3
// check:$3 = {{Case3, a = 0, b = 22873, c = 22873, d = 22873, e = 22873}, {Case3, a = 0, b = 1499027801, c = 1499027801}, {Case3, a = 0, b = 6438275382588823897}}
// debugger:print univariant
// check:$4 = {a = -1}
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
// the size of the discriminant value is machine dependent, this has be taken into account when
// datatype layout should be predictable as in this case.
enum Regular {
Case1 { a: u64, b: u16, c: u16, d: u16, e: u16},
Case2 { a: u64, b: u32, c: u32},
Case3 { a: u64, b: u64 }
}
enum Univariant {
TheOnlyCase { a: i64 }
}
fn main() {
// In order to avoid endianess trouble all of the following test values consist of a single
// repeated byte. This way each interpretation of the union should look the same, no matter if
// this is a big or little endian machine.
// 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
// 0b01111100011111000111110001111100 = 2088533116
// 0b0111110001111100 = 31868
// 0b01111100 = 124
let case1 = Case1 { a: 0, b: 31868, c: 31868, d: 31868, e: 31868 };
// 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
// 0b00010001000100010001000100010001 = 286331153
// 0b0001000100010001 = 4369
// 0b00010001 = 17
let case2 = Case2 { a: 0, b: 286331153, c: 286331153 };
// 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897
// 0b01011001010110010101100101011001 = 1499027801
// 0b0101100101011001 = 22873
// 0b01011001 = 89
let case3 = Case3 { a: 0, b: 6438275382588823897 };
let univariant = TheOnlyCase { a: -1 };
zzz();
}
fn zzz() {()}

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// xfail-test
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
@ -23,18 +23,21 @@
// debugger:print withDestructor
// check:$3 = {a = {x = 10, y = 20}, guard = -1}
// debugger:print nested
// check:$4 = {a = {a = {x = 7890, y = 9870}}}
struct NoDestructor {
x : i32,
y : i64
x: i32,
y: i64
}
struct WithDestructor {
x : i32,
y : i64
x: i32,
y: i64
}
impl Drop for WithDestructor {
fn finalize(&self) {}
fn drop(&self) {}
}
struct NoDestructorGuarded {
@ -47,6 +50,18 @@ struct WithDestructorGuarded {
guard: i64
}
struct NestedInner {
a: WithDestructor
}
impl Drop for NestedInner {
fn drop(&self) {}
}
struct NestedOuter {
a: NestedInner
}
// The compiler adds a 'destructed' boolean field to structs implementing Drop. This field is used
// at runtime to prevent drop() to be executed more than once (see middle::trans::adt).
@ -65,6 +80,8 @@ fn main() {
// then the debugger will have an invalid offset for the field 'guard' and thus should not be
// able to read its value correctly (dots are padding bytes, D is the boolean destructor flag):
//
// 64 bit
//
// NoDestructorGuarded = 0000....00000000FFFFFFFF
// <--------------><------>
// NoDestructor guard
@ -77,11 +94,31 @@ fn main() {
// <----------------------><------> // How it actually is
// WithDestructor guard
//
// 32 bit
//
// NoDestructorGuarded = 000000000000FFFFFFFF
// <----------><------>
// NoDestructor guard
//
//
// withDestructorGuarded = 000000000000D...FFFFFFFF
// <----------><------> // How debug info says it is
// WithDestructor guard
//
// <--------------><------> // How it actually is
// WithDestructor guard
//
let withDestructor = WithDestructorGuarded {
a: WithDestructor { x: 10, y: 20 },
guard: -1
};
// expected layout (64 bit) = xxxx....yyyyyyyyD.......D...
// <--WithDestructor------>
// <-------NestedInner-------->
// <-------NestedOuter-------->
let nested = NestedOuter { a: NestedInner { a: WithDestructor { x: 7890, y: 9870 } } };
zzz();
}

View file

@ -34,15 +34,15 @@
// check:$7 = {{21, 22}, 23}
fn main() {
let no_padding1 : ((u32, u32), u32, u32) = ((0, 1), 2, 3);
let no_padding2 : (u32, (u32, u32), u32) = (4, (5, 6), 7);
let no_padding3 : (u32, u32, (u32, u32)) = (8, 9, (10, 11));
let no_padding1: ((u32, u32), u32, u32) = ((0, 1), 2, 3);
let no_padding2: (u32, (u32, u32), u32) = (4, (5, 6), 7);
let no_padding3: (u32, u32, (u32, u32)) = (8, 9, (10, 11));
let internal_padding1 : (i16, (i32, i32)) = (12, (13, 14));
let internal_padding2 : (i16, (i16, i32)) = (15, (16, 17));
let internal_padding1: (i16, (i32, i32)) = (12, (13, 14));
let internal_padding2: (i16, (i16, i32)) = (15, (16, 17));
let padding_at_end1 : (i32, (i32, i16)) = (18, (19, 20));
let padding_at_end2 : ((i32, i16), i32) = ((21, 22), 23);
let padding_at_end1: (i32, (i32, i16)) = (18, (19, 20));
let padding_at_end2: ((i32, i16), i32) = ((21, 22), 23);
zzz();
}

View file

@ -0,0 +1,73 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:set print union on
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print case1
// check:$1 = {{Case1, 0, 31868, 31868, 31868, 31868}, {Case1, 0, 2088533116, 2088533116}, {Case1, 0, 8970181431921507452}}
// debugger:print case2
// check:$2 = {{Case2, 0, 4369, 4369, 4369, 4369}, {Case2, 0, 286331153, 286331153}, {Case2, 0, 1229782938247303441}}
// debugger:print case3
// check:$3 = {{Case3, 0, 22873, 22873, 22873, 22873}, {Case3, 0, 1499027801, 1499027801}, {Case3, 0, 6438275382588823897}}
// debugger:print univariant
// check:$4 = {-1}
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
// the size of the discriminant value is machine dependent, this has be taken into account when
// datatype layout should be predictable as in this case.
enum Regular {
Case1(u64, u16, u16, u16, u16),
Case2(u64, u32, u32),
Case3(u64, u64)
}
enum Univariant {
TheOnlyCase(i64)
}
fn main() {
// In order to avoid endianess trouble all of the following test values consist of a single
// repeated byte. This way each interpretation of the union should look the same, no matter if
// this is a big or little endian machine.
// 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
// 0b01111100011111000111110001111100 = 2088533116
// 0b0111110001111100 = 31868
// 0b01111100 = 124
let case1 = Case1(0, 31868, 31868, 31868, 31868);
// 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
// 0b00010001000100010001000100010001 = 286331153
// 0b0001000100010001 = 4369
// 0b00010001 = 17
let case2 = Case2(0, 286331153, 286331153);
// 0b0101100101011001010110010101100101011001010110010101100101011001 = 6438275382588823897
// 0b01011001010110010101100101011001 = 1499027801
// 0b0101100101011001 = 22873
// 0b01011001 = 89
let case3 = Case3(0, 6438275382588823897);
let univariant = TheOnlyCase(-1);
zzz();
}
fn zzz() {()}

View file

@ -0,0 +1,63 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print *the_a
// check:$1 = {{TheA, x = 0, y = 8970181431921507452}, {TheA, 0, 2088533116, 2088533116}}
// debugger:print *the_b
// check:$2 = {{TheB, x = 0, y = 1229782938247303441}, {TheB, 0, 286331153, 286331153}}
// debugger:print *univariant
// check:$3 = {123234}
// The first element is to ensure proper alignment, irrespective of the machines word size. Since
// the size of the discriminant value is machine dependent, this has be taken into account when
// datatype layout should be predictable as in this case.
enum ABC {
TheA { x: i64, y: i64 },
TheB (i64, i32, i32),
}
// This is a special case since it does not have the implicit discriminant field.
enum Univariant {
TheOnlyCase(i64)
}
fn main() {
// In order to avoid endianess trouble all of the following test values consist of a single
// repeated byte. This way each interpretation of the union should look the same, no matter if
// this is a big or little endian machine.
// 0b0111110001111100011111000111110001111100011111000111110001111100 = 8970181431921507452
// 0b01111100011111000111110001111100 = 2088533116
// 0b0111110001111100 = 31868
// 0b01111100 = 124
let the_a = ~TheA { x: 0, y: 8970181431921507452 };
// 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
// 0b00010001000100010001000100010001 = 286331153
// 0b0001000100010001 = 4369
// 0b00010001 = 17
let the_b = ~TheB (0, 286331153, 286331153);
let univariant = ~TheOnlyCase(123234);
zzz();
}
fn zzz() {()}

View file

@ -0,0 +1,72 @@
// Copyright 2013 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.
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:set print pretty off
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print empty.size_in_bytes
// check:$1 = 0
// debugger:print singleton.size_in_bytes
// check:$2 = 8
// debugger:print *((int64_t[1]*)(singleton.data_ptr))
// check:$3 = {1}
// debugger:print multiple.size_in_bytes
// check:$4 = 32
// debugger:print *((int64_t[4]*)(multiple.data_ptr))
// check:$5 = {2, 3, 4, 5}
// debugger:print slice_of_slice.size_in_bytes
// check:$6 = 16
// debugger:print *((int64_t[2]*)(slice_of_slice.data_ptr))
// check:$7 = {3, 4}
// debugger:print padded_tuple.size_in_bytes
// check:$8 = 16
// debugger:print padded_tuple.data_ptr[0]
// check:$9 = {6, 7}
// debugger:print padded_tuple.data_ptr[1]
// check:$10 = {8, 9}
// debugger:print padded_struct.size_in_bytes
// check:$11 = 24
// debugger:print padded_struct.data_ptr[0]
// check:$12 = {x = 10, y = 11, z = 12}
// debugger:print padded_struct.data_ptr[1]
// check:$13 = {x = 13, y = 14, z = 15}
struct AStruct {
x: i16,
y: i32,
z: i16
}
fn main() {
let empty: &[i64] = &[];
let singleton: &[i64] = &[1];
let multiple: &[i64] = &[2, 3, 4, 5];
let slice_of_slice = multiple.slice(1,3);
let padded_tuple: &[(i32, i16)] = &[(6, 7), (8, 9)];
let padded_struct: &[AStruct] = &[
AStruct { x: 10, y: 11, z: 12 },
AStruct { x: 13, y: 14, z: 15 }
];
zzz();
}
fn zzz() {()}

View file

@ -8,28 +8,20 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// xfail-test
// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249
// compile-flags:-Z extra-debug-info
// debugger:set print pretty off
// debugger:break _zzz
// debugger:break zzz
// debugger:run
// debugger:finish
// debugger:print a
// check:$1 = {1, 2, 3}
// debugger:print b.vec[0]
// check:$2 = 4
// debugger:print c->boxed.data[1]
// check:$3 = 8
// debugger:print d->boxed.data[2]
// check:$4 = 12
fn main() {
let a = [1, 2, 3];
let b = &[4, 5, 6];
let c = @[7, 8, 9];
let d = ~[10, 11, 12];
_zzz();
zzz();
}
fn _zzz() {()}
fn zzz() {()}

View file

@ -0,0 +1,27 @@
// Copyright 2013 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.
// compile-flags:-Z debug-info
#[allow(default_methods)];
pub trait TraitWithDefaultMethod {
pub fn method(self) {
()
}
}
struct MyStruct;
impl TraitWithDefaultMethod for MyStruct { }
fn main() {
MyStruct.method();
}