Check SIMD vector types

This commit is contained in:
Seo Sanghyeon 2013-05-02 20:47:11 +09:00
parent 8e0c6fa5b6
commit f3217a5c9c
2 changed files with 51 additions and 3 deletions

View File

@ -2381,6 +2381,14 @@ pub fn type_is_signed(ty: t) -> bool {
}
}
pub fn type_is_machine(ty: t) -> bool {
match get(ty).sty {
ty_int(ast::ty_i) | ty_uint(ast::ty_u) | ty_float(ast::ty_f) => false,
ty_int(*) | ty_uint(*) | ty_float(*) => true,
_ => false
}
}
// Whether a type is Plain Old Data -- meaning it does not contain pointers
// that the cycle collector might care about.
pub fn type_is_pod(cx: ctxt, ty: t) -> bool {
@ -3896,7 +3904,7 @@ pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool {
attrs: ref attrs,
_
}, _)) => attr::attrs_contains_name(*attrs, attr),
_ => tcx.sess.bug(fmt!("lookup_packed: %? is not an item",
_ => tcx.sess.bug(fmt!("has_attr: %? is not an item",
did))
}
} else {
@ -3908,11 +3916,16 @@ pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool {
}
}
/// Determine whether an item is annotated with `#[packed]` or not
/// Determine whether an item is annotated with `#[packed]`
pub fn lookup_packed(tcx: ctxt, did: def_id) -> bool {
has_attr(tcx, did, "packed")
}
/// Determine whether an item is annotated with `#[simd]`
pub fn lookup_simd(tcx: ctxt, did: def_id) -> bool {
has_attr(tcx, did, "simd")
}
// Look up a field ID, whether or not it's local
// Takes a list of type substs in case the struct is generic
pub fn lookup_field_type(tcx: ctxt,

View File

@ -561,8 +561,14 @@ pub fn check_no_duplicate_fields(tcx: ty::ctxt,
}
pub fn check_struct(ccx: @mut CrateCtxt, id: ast::node_id, span: span) {
let tcx = ccx.tcx;
// Check that the class is instantiable
check_instantiable(ccx.tcx, span, id);
check_instantiable(tcx, span, id);
if ty::lookup_simd(tcx, local_def(id)) {
check_simd(tcx, span, id);
}
}
pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) {
@ -3047,6 +3053,35 @@ pub fn check_instantiable(tcx: ty::ctxt,
}
}
pub fn check_simd(tcx: ty::ctxt, sp: span, id: ast::node_id) {
let t = ty::node_id_to_type(tcx, id);
if ty::type_needs_subst(t) {
tcx.sess.span_err(sp, "SIMD vector cannot be generic");
return;
}
match ty::get(t).sty {
ty::ty_struct(did, ref substs) => {
let fields = ty::lookup_struct_fields(tcx, did);
if fields.is_empty() {
tcx.sess.span_err(sp, "SIMD vector cannot be empty");
return;
}
let e = ty::lookup_field_type(tcx, did, fields[0].id, substs);
if !vec::all(fields,
|f| ty::lookup_field_type(tcx, did, f.id, substs) == e) {
tcx.sess.span_err(sp, "SIMD vector should be homogeneous");
return;
}
if !ty::type_is_machine(e) {
tcx.sess.span_err(sp, "SIMD vector element type should be \
machine type");
return;
}
}
_ => ()
}
}
pub fn check_enum_variants(ccx: @mut CrateCtxt,
sp: span,
vs: &[ast::variant],