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, |  | ||||||
| ) -> CompileResult<Type> { |  | ||||||
|     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 { |     if lhs_t == rhs_t { | ||||||
|         Ok(lhs_t) |         Ok(lhs_t) | ||||||
|     } else { |     } else { | ||||||
|             Err(ErrorKind::Null) |         Err(ErrorKind::TypesIncompatible(lhs_t, rhs_t)) | ||||||
|         } |  | ||||||
|     } else { |  | ||||||
|         Err(ErrorKind::Null) |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user