Support void in platform intrinsic generator.

This commit is contained in:
Huon Wilson 2015-09-02 16:55:28 -07:00
parent add04307f9
commit 62e346af4b
5 changed files with 39 additions and 5 deletions

View File

@ -17,7 +17,7 @@ import textwrap
import itertools
SPEC = re.compile(
r'^(?:(?P<id>[iusfIUSF])(?:\((?P<start>\d+)-(?P<end>\d+)\)|'
r'^(?:(?P<void>V)|(?P<id>[iusfIUSF])(?:\((?P<start>\d+)-(?P<end>\d+)\)|'
r'(?P<width>\d+)(:?/(?P<llvm_width>\d+))?)'
r'|(?P<reference>\d+)(?P<modifiers>[vShdnwusDMC]*)(?P<force_width>x\d+)?)'
r'(?:(?P<pointer>Pm|Pc)(?P<llvm_pointer>/.*)?)?$'
@ -97,6 +97,19 @@ class Type(object):
def modify(self, spec, width):
raise NotImplementedError()
class Void(Type):
def __init__(self):
Type.__init__(self, 0)
def compiler_ctor(self):
return 'void()'
def rust_name(self):
return '()'
def type_info(self, platform_info):
return None
class Number(Type):
def __init__(self, bitwidth):
Type.__init__(self, bitwidth)
@ -289,7 +302,10 @@ class TypeSpec(object):
id = match.group('id')
reference = match.group('reference')
if id is not None:
if match.group('void') is not None:
assert spec == 'V'
yield Void()
elif id is not None:
is_vector = id.islower()
type_ctors = TYPE_ID_LOOKUP[id.lower()]
@ -436,11 +452,15 @@ def parse_args():
## Type specifier grammar
```
type := ( vector | scalar | aggregate | reference ) pointer?
type := core_type pointer?
core_type := void | vector | scalar | aggregate | reference
pointer := 'Pm' llvm_pointer? | 'Pc' llvm_pointer?
llvm_pointer := '/' type
void := 'V'
vector := vector_elem width |
vector_elem := 'i' | 'u' | 's' | 'f'
@ -472,6 +492,11 @@ def parse_args():
in Rust, but is `i8*` in LLVM. (This defaults to the main
type).
## Void
The `V` type corresponds to `void` in LLVM (`()` in
Rust). It's likely to only work in return position.
## Vectors
The vector grammar is a pattern describing many possibilities
@ -586,7 +611,7 @@ class CompilerDefs(object):
#![allow(unused_imports)]
use {{Intrinsic, i, i_, u, u_, f, v, agg, p}};
use {{Intrinsic, i, i_, u, u_, f, v, agg, p, void}};
use IntrinsicDef::Named;
use rustc::middle::ty;

View File

@ -30,6 +30,7 @@ pub struct Intrinsic {
#[derive(Clone, Hash, Eq, PartialEq)]
pub enum Type {
Void,
Integer(/* signed */ bool, u8, /* llvm width */ u8),
Float(u8),
Pointer(Box<Type>, Option<Box<Type>>, /* const */ bool),
@ -54,6 +55,9 @@ fn agg(flatten: bool, types: Vec<Type>) -> Type {
fn p(const_: bool, elem: Type, llvm_elem: Option<Type>) -> Type {
Type::Pointer(Box::new(elem), llvm_elem.map(Box::new), const_)
}
fn void() -> Type {
Type::Void
}
mod x86;
mod arm;

View File

@ -13,7 +13,7 @@
#![allow(unused_imports)]
use {Intrinsic, i, i_, u, u_, f, v, agg, p};
use {Intrinsic, i, i_, u, u_, f, v, agg, p, void};
use IntrinsicDef::Named;
use rustc::middle::ty;

View File

@ -936,6 +936,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
any_changes_needed: &mut bool) -> Vec<Type> {
use intrinsics::Type::*;
match *t {
Void => vec![Type::void(ccx)],
Integer(_signed, width, llvm_width) => {
*any_changes_needed |= width != llvm_width;
vec![Type::ix(ccx, llvm_width as u64)]

View File

@ -464,6 +464,10 @@ fn match_intrinsic_type_to_type<'tcx, 'a>(
};
match *expected {
Void => match t.sty {
ty::TyTuple(ref v) if v.is_empty() => {},
_ => simple_error(&format!("`{}`", t), "()"),
},
// (The width we pass to LLVM doesn't concern the type checker.)
Integer(signed, bits, _llvm_width) => match (signed, bits, &t.sty) {
(true, 8, &ty::TyInt(hir::IntTy::TyI8)) |