Fix a bunch of errors in reid-llvm-lib
This commit is contained in:
parent
c23160bc32
commit
0203213b28
@ -20,13 +20,13 @@ pub struct ModuleValue(pub(crate) usize);
|
|||||||
#[derive(Clone, Hash, Copy, PartialEq, Eq, PartialOrd)]
|
#[derive(Clone, Hash, Copy, PartialEq, Eq, PartialOrd)]
|
||||||
pub struct TypeValue(pub(crate) ModuleValue, pub(crate) usize);
|
pub struct TypeValue(pub(crate) ModuleValue, pub(crate) usize);
|
||||||
|
|
||||||
#[derive(Clone, Hash, Copy, PartialEq, Eq)]
|
#[derive(Clone, Hash, Copy, PartialEq, Eq, PartialOrd)]
|
||||||
pub struct FunctionValue(pub(crate) ModuleValue, pub(crate) usize);
|
pub struct FunctionValue(pub(crate) ModuleValue, pub(crate) usize);
|
||||||
|
|
||||||
#[derive(Clone, Hash, Copy, PartialEq, Eq)]
|
#[derive(Clone, Hash, Copy, PartialEq, Eq, PartialOrd)]
|
||||||
pub struct BlockValue(pub(crate) FunctionValue, pub(crate) usize);
|
pub struct BlockValue(pub(crate) FunctionValue, pub(crate) usize);
|
||||||
|
|
||||||
#[derive(Clone, Hash, Copy, PartialEq, Eq)]
|
#[derive(Clone, Hash, Copy, PartialEq, Eq, PartialOrd)]
|
||||||
pub struct InstructionValue(pub(crate) BlockValue, pub(crate) usize);
|
pub struct InstructionValue(pub(crate) BlockValue, pub(crate) usize);
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Hash, Copy, PartialEq, Eq)]
|
||||||
@ -278,7 +278,7 @@ impl Builder {
|
|||||||
let function = module.functions.get_unchecked_mut(block.0.1);
|
let function = module.functions.get_unchecked_mut(block.0.1);
|
||||||
let block = function.blocks.get_unchecked_mut(block.1);
|
let block = function.blocks.get_unchecked_mut(block.1);
|
||||||
if let Some(_) = &block.data.terminator {
|
if let Some(_) = &block.data.terminator {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::BlockAlreadyTerminated)
|
||||||
} else {
|
} else {
|
||||||
block.data.terminator = Some(value);
|
block.data.terminator = Some(value);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -297,7 +297,7 @@ impl Builder {
|
|||||||
let function = module.functions.get_unchecked_mut(block.0.1);
|
let function = module.functions.get_unchecked_mut(block.0.1);
|
||||||
let block = function.blocks.get_unchecked_mut(block.1);
|
let block = function.blocks.get_unchecked_mut(block.1);
|
||||||
if let Some(_) = &block.data.terminator_location {
|
if let Some(_) = &block.data.terminator_location {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::BlockTerminatorLocated)
|
||||||
} else {
|
} else {
|
||||||
block.data.terminator_location = Some(location);
|
block.data.terminator_location = Some(location);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -411,84 +411,120 @@ impl Builder {
|
|||||||
if match_types(&lhs, &rhs, &self)?.category().integer() {
|
if match_types(&lhs, &rhs, &self)?.category().integer() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::TypeNotInteger(lhs, lhs.get_type(&self)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::FAdd(lhs, rhs) => {
|
Instr::FAdd(lhs, rhs) => {
|
||||||
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::Real {
|
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::Real {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::TypeWrongCategory(
|
||||||
|
lhs,
|
||||||
|
lhs.get_type(&self)?,
|
||||||
|
TypeCategory::Real,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::Sub(lhs, rhs) => {
|
Instr::Sub(lhs, rhs) => {
|
||||||
if match_types(&lhs, &rhs, &self)?.category().integer() {
|
if match_types(&lhs, &rhs, &self)?.category().integer() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::TypeNotInteger(lhs, lhs.get_type(&self)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::FSub(lhs, rhs) => {
|
Instr::FSub(lhs, rhs) => {
|
||||||
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::Real {
|
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::Real {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::TypeWrongCategory(
|
||||||
|
lhs,
|
||||||
|
lhs.get_type(&self)?,
|
||||||
|
TypeCategory::Real,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::Mul(lhs, rhs) => {
|
Instr::Mul(lhs, rhs) => {
|
||||||
if match_types(&lhs, &rhs, &self)?.category().integer() {
|
if match_types(&lhs, &rhs, &self)?.category().integer() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::TypeNotInteger(lhs, lhs.get_type(&self)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::FMul(lhs, rhs) => {
|
Instr::FMul(lhs, rhs) => {
|
||||||
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::Real {
|
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::Real {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::TypeWrongCategory(
|
||||||
|
lhs,
|
||||||
|
lhs.get_type(&self)?,
|
||||||
|
TypeCategory::Real,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::UDiv(lhs, rhs) => {
|
Instr::UDiv(lhs, rhs) => {
|
||||||
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::UnsignedInteger {
|
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::UnsignedInteger {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::TypeWrongCategory(
|
||||||
|
lhs,
|
||||||
|
lhs.get_type(&self)?,
|
||||||
|
TypeCategory::UnsignedInteger,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::SDiv(lhs, rhs) => {
|
Instr::SDiv(lhs, rhs) => {
|
||||||
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::SignedInteger {
|
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::SignedInteger {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::TypeWrongCategory(
|
||||||
|
lhs,
|
||||||
|
lhs.get_type(&self)?,
|
||||||
|
TypeCategory::SignedInteger,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::FDiv(lhs, rhs) => {
|
Instr::FDiv(lhs, rhs) => {
|
||||||
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::Real {
|
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::Real {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::TypeWrongCategory(
|
||||||
|
lhs,
|
||||||
|
lhs.get_type(&self)?,
|
||||||
|
TypeCategory::Real,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::URem(lhs, rhs) => {
|
Instr::URem(lhs, rhs) => {
|
||||||
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::UnsignedInteger {
|
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::UnsignedInteger {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::TypeWrongCategory(
|
||||||
|
lhs,
|
||||||
|
lhs.get_type(&self)?,
|
||||||
|
TypeCategory::UnsignedInteger,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::SRem(lhs, rhs) => {
|
Instr::SRem(lhs, rhs) => {
|
||||||
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::SignedInteger {
|
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::SignedInteger {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::TypeWrongCategory(
|
||||||
|
lhs,
|
||||||
|
lhs.get_type(&self)?,
|
||||||
|
TypeCategory::SignedInteger,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::FRem(lhs, rhs) => {
|
Instr::FRem(lhs, rhs) => {
|
||||||
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::Real {
|
if match_types(&lhs, &rhs, &self)?.category() == TypeCategory::Real {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::TypeWrongCategory(
|
||||||
|
lhs,
|
||||||
|
lhs.get_type(&self)?,
|
||||||
|
TypeCategory::Real,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::And(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
Instr::And(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
||||||
@ -499,7 +535,7 @@ impl Builder {
|
|||||||
if t.category().comparable() || !t.category().integer() {
|
if t.category().comparable() || !t.category().integer() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null) // TODO error: Types not comparable
|
Err(ErrorKind::TypeNotComparable(lhs, t))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::FCmp(_, lhs, rhs) => {
|
Instr::FCmp(_, lhs, rhs) => {
|
||||||
@ -507,17 +543,17 @@ impl Builder {
|
|||||||
if t.category().comparable() || t.category() != TypeCategory::Real {
|
if t.category().comparable() || t.category() != TypeCategory::Real {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null) // TODO error: Types not comparable
|
Err(ErrorKind::TypeNotComparable(lhs, t))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::FunctionCall(fun, params) => {
|
Instr::FunctionCall(fun, params) => {
|
||||||
let param_types = self.function_data(&fun).params;
|
let param_types = self.function_data(&fun).params;
|
||||||
if param_types.len() != params.len() {
|
if param_types.len() != params.len() {
|
||||||
return Err(ErrorKind::Null); // TODO error: invalid amount of params
|
return Err(ErrorKind::InvalidLenParams(params.len(), param_types.len()));
|
||||||
}
|
}
|
||||||
for (a, b) in param_types.iter().zip(params) {
|
for (a, b) in param_types.iter().zip(params) {
|
||||||
if *a != b.get_type(&self)? {
|
if *a != b.get_type(&self)? {
|
||||||
return Err(ErrorKind::TypesIncompatible(a.clone(), b.get_type(&self)?)); // TODO error: params do not match
|
return Err(ErrorKind::TypesIncompatible(a.clone(), b.get_type(&self)?));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -530,7 +566,7 @@ impl Builder {
|
|||||||
// incoming values come from blocks that are added later
|
// incoming values come from blocks that are added later
|
||||||
// than the one where this one exists.
|
// than the one where this one exists.
|
||||||
|
|
||||||
let first = iter.next().ok_or(ErrorKind::Null)?;
|
let first = iter.next().ok_or(ErrorKind::EmptyPhiList)?;
|
||||||
for item in iter {
|
for item in iter {
|
||||||
match_types(first, item, &self)?;
|
match_types(first, item, &self)?;
|
||||||
}
|
}
|
||||||
@ -543,10 +579,10 @@ impl Builder {
|
|||||||
if *ptr_ty_inner == load_ty {
|
if *ptr_ty_inner == load_ty {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null) // TODO error: inner type mismatch
|
Err(ErrorKind::TypesIncompatible(*ptr_ty_inner, load_ty))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null) // TODO error: not a pointer
|
Err(ErrorKind::NotPointer(ptr, ptr_ty))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::Store(ptr, _) => {
|
Instr::Store(ptr, _) => {
|
||||||
@ -554,21 +590,25 @@ impl Builder {
|
|||||||
if let Type::Ptr(_) = ty {
|
if let Type::Ptr(_) = ty {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null) // TODO error: not a pointer
|
Err(ErrorKind::NotPointer(ptr, ty))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::ArrayAlloca(_, val) => {
|
Instr::ArrayAlloca(_, val) => {
|
||||||
if val.get_type(self)?.category() == TypeCategory::UnsignedInteger {
|
if val.get_type(self)?.category() == TypeCategory::UnsignedInteger {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null) // TODO error: not a pointer
|
Err(ErrorKind::TypeWrongCategory(
|
||||||
|
val,
|
||||||
|
val.get_type(self)?,
|
||||||
|
TypeCategory::UnsignedInteger,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::GetElemPtr(ptr_val, _) => {
|
Instr::GetElemPtr(ptr_val, _) => {
|
||||||
let ptr_ty = ptr_val.get_type(&self)?;
|
let ptr_ty = ptr_val.get_type(&self)?;
|
||||||
match ptr_ty {
|
match ptr_ty {
|
||||||
Type::Ptr(_) => Ok(()),
|
Type::Ptr(_) => Ok(()),
|
||||||
_ => Err(ErrorKind::Null),
|
_ => Err(ErrorKind::NotPointer(ptr_val, ptr_ty)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::GetStructElemPtr(ptr_val, idx) => {
|
Instr::GetStructElemPtr(ptr_val, idx) => {
|
||||||
@ -578,16 +618,16 @@ impl Builder {
|
|||||||
match self.type_data(&val).kind {
|
match self.type_data(&val).kind {
|
||||||
CustomTypeKind::NamedStruct(NamedStruct(_, fields)) => {
|
CustomTypeKind::NamedStruct(NamedStruct(_, fields)) => {
|
||||||
if fields.len() <= idx as usize {
|
if fields.len() <= idx as usize {
|
||||||
return Err(ErrorKind::Null); // TODO error: no such field
|
return Err(ErrorKind::NoSuchField(*ty, idx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null) // TODO error: not a struct
|
Err(ErrorKind::NotStruct(ptr_val, *ty))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null) // TODO error: not a pointer
|
Err(ErrorKind::NotPointer(ptr_val, ptr_ty))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::ExtractValue(val, _) => {
|
Instr::ExtractValue(val, _) => {
|
||||||
@ -597,7 +637,7 @@ impl Builder {
|
|||||||
CustomTypeKind::NamedStruct(_) => Ok(()),
|
CustomTypeKind::NamedStruct(_) => Ok(()),
|
||||||
},
|
},
|
||||||
Type::Array(_, _) => Ok(()),
|
Type::Array(_, _) => Ok(()),
|
||||||
_ => Err(ErrorKind::Null),
|
_ => Err(ErrorKind::NotExtractable(val, val_ty)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::Trunc(instr, ty) => instr.cast_to(self, &ty).map(|_| ()),
|
Instr::Trunc(instr, ty) => instr.cast_to(self, &ty).map(|_| ()),
|
||||||
@ -621,7 +661,7 @@ impl Builder {
|
|||||||
if let Type::Ptr(_) = val_ty {
|
if let Type::Ptr(_) = val_ty {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::NotPointer(val, val_ty))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -695,7 +735,7 @@ impl InstructionValue {
|
|||||||
.params
|
.params
|
||||||
.get(*nth)
|
.get(*nth)
|
||||||
.cloned()
|
.cloned()
|
||||||
.ok_or(ErrorKind::Null),
|
.ok_or(ErrorKind::NoSuchParam(self.0.0, *nth)),
|
||||||
Constant(c) => Ok(c.get_type()),
|
Constant(c) => Ok(c.get_type()),
|
||||||
Add(lhs, rhs) => match_types(lhs, rhs, &builder),
|
Add(lhs, rhs) => match_types(lhs, rhs, &builder),
|
||||||
FAdd(lhs, rhs) => match_types(lhs, rhs, &builder),
|
FAdd(lhs, rhs) => match_types(lhs, rhs, &builder),
|
||||||
@ -715,7 +755,10 @@ impl InstructionValue {
|
|||||||
ICmp(_, _, _) => Ok(Type::Bool),
|
ICmp(_, _, _) => Ok(Type::Bool),
|
||||||
FCmp(_, _, _) => Ok(Type::Bool),
|
FCmp(_, _, _) => Ok(Type::Bool),
|
||||||
FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret),
|
FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret),
|
||||||
Phi(values) => values.first().ok_or(ErrorKind::Null).and_then(|v| v.get_type(&builder)),
|
Phi(values) => values
|
||||||
|
.first()
|
||||||
|
.ok_or(ErrorKind::EmptyPhiList)
|
||||||
|
.and_then(|v| v.get_type(&builder)),
|
||||||
Alloca(ty) => Ok(Type::Ptr(Box::new(ty.clone()))),
|
Alloca(ty) => Ok(Type::Ptr(Box::new(ty.clone()))),
|
||||||
Load(_, ty) => Ok(ty.clone()),
|
Load(_, ty) => Ok(ty.clone()),
|
||||||
Store(_, value) => value.get_type(builder),
|
Store(_, value) => value.get_type(builder),
|
||||||
@ -757,7 +800,7 @@ impl InstructionValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Type::Array(elem_ty, _) => *elem_ty.clone(),
|
Type::Array(elem_ty, _) => *elem_ty.clone(),
|
||||||
_ => return Err(ErrorKind::Null),
|
_ => return Err(ErrorKind::NotExtractable(*instr, instr_ty)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Trunc(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()),
|
Trunc(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()),
|
||||||
@ -786,8 +829,9 @@ impl InstructionValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cast_to(&self, builder: &Builder, ty: &Type) -> CompileResult<Instr> {
|
fn cast_to(&self, builder: &Builder, ty: &Type) -> CompileResult<Instr> {
|
||||||
self.get_type(builder)?
|
let own_type = self.get_type(builder)?;
|
||||||
|
own_type
|
||||||
.cast_instruction(*self, &ty)
|
.cast_instruction(*self, &ty)
|
||||||
.ok_or(ErrorKind::Null)
|
.ok_or(ErrorKind::ImpossibleCast(own_type, ty.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,32 @@ pub enum ErrorKind {
|
|||||||
Null,
|
Null,
|
||||||
#[error("Types {0:?} and {1:?} incompatible")]
|
#[error("Types {0:?} and {1:?} incompatible")]
|
||||||
TypesIncompatible(Type, Type),
|
TypesIncompatible(Type, Type),
|
||||||
|
#[error("Phi list of values is empty")]
|
||||||
|
EmptyPhiList,
|
||||||
|
#[error("Type {1:?} of value {0:?} is not extractable")]
|
||||||
|
NotExtractable(InstructionValue, Type),
|
||||||
|
#[error("Type {0:?} is not castable to {1:?}")]
|
||||||
|
ImpossibleCast(Type, Type),
|
||||||
|
#[error("Block is already terminated")]
|
||||||
|
BlockAlreadyTerminated,
|
||||||
|
#[error("Block terminator already has a location")]
|
||||||
|
BlockTerminatorLocated,
|
||||||
|
#[error("Value {0:?} must be an integer type. Is {1:?}")]
|
||||||
|
TypeNotInteger(InstructionValue, Type),
|
||||||
|
#[error("Value {0:?} must be a {2:?} type. Is {1:?}")]
|
||||||
|
TypeWrongCategory(InstructionValue, Type, TypeCategory),
|
||||||
|
#[error("Value {0:?} must be comparable, was {1:?}")]
|
||||||
|
TypeNotComparable(InstructionValue, Type),
|
||||||
|
#[error("Got {0:?} parameters, expected {1:?}")]
|
||||||
|
InvalidLenParams(usize, usize),
|
||||||
|
#[error("Value {0:?} is not a pointer, is {1:?}")]
|
||||||
|
NotPointer(InstructionValue, Type),
|
||||||
|
#[error("Value {0:?} is not a struct, is {1:?}")]
|
||||||
|
NotStruct(InstructionValue, Type),
|
||||||
|
#[error("Struct {0:?} has no such field as {1:?}")]
|
||||||
|
NoSuchField(Type, u32),
|
||||||
|
#[error("Function {0:?} has no such parameter as {1:?}")]
|
||||||
|
NoSuchParam(FunctionValue, usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type CompileResult<T> = Result<T, ErrorKind>;
|
pub type CompileResult<T> = Result<T, ErrorKind>;
|
||||||
@ -600,7 +626,7 @@ impl ConstValueKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone)]
|
||||||
pub enum TypeCategory {
|
pub enum TypeCategory {
|
||||||
SignedInteger,
|
SignedInteger,
|
||||||
UnsignedInteger,
|
UnsignedInteger,
|
||||||
|
@ -5,10 +5,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use llvm_sys::{
|
use llvm_sys::{
|
||||||
core::{
|
core::{LLVMCreateMemoryBufferWithMemoryRange, LLVMDisposeMemoryBuffer, LLVMGetBufferSize, LLVMGetBufferStart},
|
||||||
LLVMCreateMemoryBufferWithMemoryRange, LLVMDisposeMemoryBuffer, LLVMGetBufferSize,
|
|
||||||
LLVMGetBufferStart,
|
|
||||||
},
|
|
||||||
error::LLVMDisposeErrorMessage,
|
error::LLVMDisposeErrorMessage,
|
||||||
prelude::LLVMMemoryBufferRef,
|
prelude::LLVMMemoryBufferRef,
|
||||||
};
|
};
|
||||||
@ -32,9 +29,7 @@ pub fn from_cstring(pointer: *mut c_char) -> Option<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cstring_to_err(value: *mut c_char) -> Result<(), String> {
|
fn cstring_to_err(value: *mut c_char) -> Result<(), String> {
|
||||||
from_cstring(value)
|
from_cstring(value).filter(|s| !s.is_empty()).map_or(Ok(()), |s| Err(s))
|
||||||
.filter(|s| !s.is_empty())
|
|
||||||
.map_or(Ok(()), |s| Err(s))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Utility struct for LLVM's Error Messages, which need to be disposed
|
/// Utility struct for LLVM's Error Messages, which need to be disposed
|
||||||
@ -75,12 +70,8 @@ impl MemoryBufferHolder {
|
|||||||
pub fn empty(name: &str) -> MemoryBufferHolder {
|
pub fn empty(name: &str) -> MemoryBufferHolder {
|
||||||
let array = [0i8; 0];
|
let array = [0i8; 0];
|
||||||
unsafe {
|
unsafe {
|
||||||
let buffer = LLVMCreateMemoryBufferWithMemoryRange(
|
let buffer =
|
||||||
array.as_ptr(),
|
LLVMCreateMemoryBufferWithMemoryRange(array.as_ptr(), array.len(), into_cstring(name).as_ptr(), 0);
|
||||||
array.len(),
|
|
||||||
into_cstring(name).as_ptr(),
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
MemoryBufferHolder { buffer }
|
MemoryBufferHolder { buffer }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,20 +104,12 @@ impl Drop for MemoryBufferHolder {
|
|||||||
|
|
||||||
/// Make sure types for given instructions match. Return Ok(type) if they do,
|
/// Make sure types for given instructions match. Return Ok(type) if they do,
|
||||||
/// and error otherwise.
|
/// and error otherwise.
|
||||||
pub fn match_types(
|
pub fn match_types(lhs: &InstructionValue, rhs: &InstructionValue, builder: &Builder) -> CompileResult<Type> {
|
||||||
lhs: &InstructionValue,
|
let lhs_t = lhs.get_type(&builder)?;
|
||||||
rhs: &InstructionValue,
|
let rhs_t = rhs.get_type(&builder)?;
|
||||||
builder: &Builder,
|
if lhs_t == rhs_t {
|
||||||
) -> CompileResult<Type> {
|
Ok(lhs_t)
|
||||||
let lhs_type = lhs.get_type(&builder);
|
|
||||||
let rhs_type = rhs.get_type(&builder);
|
|
||||||
if let (Ok(lhs_t), Ok(rhs_t)) = (lhs_type, rhs_type) {
|
|
||||||
if lhs_t == rhs_t {
|
|
||||||
Ok(lhs_t)
|
|
||||||
} else {
|
|
||||||
Err(ErrorKind::Null)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorKind::Null)
|
Err(ErrorKind::TypesIncompatible(lhs_t, rhs_t))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user