From 62e346af4b7a1aac43db627f19d2511d5649e5d7 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Wed, 2 Sep 2015 16:55:28 -0700 Subject: [PATCH] Support void in platform intrinsic generator. --- src/etc/platform-intrinsics/generator.py | 33 +++++++++++++++++++++--- src/librustc_platform_intrinsics/lib.rs | 4 +++ src/librustc_platform_intrinsics/x86.rs | 2 +- src/librustc_trans/trans/intrinsic.rs | 1 + src/librustc_typeck/check/intrinsic.rs | 4 +++ 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/etc/platform-intrinsics/generator.py b/src/etc/platform-intrinsics/generator.py index 2102bd9c488b..b62c35246cab 100644 --- a/src/etc/platform-intrinsics/generator.py +++ b/src/etc/platform-intrinsics/generator.py @@ -17,7 +17,7 @@ import textwrap import itertools SPEC = re.compile( - r'^(?:(?P[iusfIUSF])(?:\((?P\d+)-(?P\d+)\)|' + r'^(?:(?PV)|(?P[iusfIUSF])(?:\((?P\d+)-(?P\d+)\)|' r'(?P\d+)(:?/(?P\d+))?)' r'|(?P\d+)(?P[vShdnwusDMC]*)(?Px\d+)?)' r'(?:(?PPm|Pc)(?P/.*)?)?$' @@ -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; diff --git a/src/librustc_platform_intrinsics/lib.rs b/src/librustc_platform_intrinsics/lib.rs index 8c8beb031eba..95da12a23782 100755 --- a/src/librustc_platform_intrinsics/lib.rs +++ b/src/librustc_platform_intrinsics/lib.rs @@ -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, Option>, /* const */ bool), @@ -54,6 +55,9 @@ fn agg(flatten: bool, types: Vec) -> Type { fn p(const_: bool, elem: Type, llvm_elem: Option) -> Type { Type::Pointer(Box::new(elem), llvm_elem.map(Box::new), const_) } +fn void() -> Type { + Type::Void +} mod x86; mod arm; diff --git a/src/librustc_platform_intrinsics/x86.rs b/src/librustc_platform_intrinsics/x86.rs index 661603866ae0..26421cb3e80e 100644 --- a/src/librustc_platform_intrinsics/x86.rs +++ b/src/librustc_platform_intrinsics/x86.rs @@ -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; diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index c2dee20b3bb9..a6816a99d28a 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -936,6 +936,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, any_changes_needed: &mut bool) -> Vec { 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)] diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 54f6ec0f0eda..4501d1c618a7 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -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)) |