/// Map a VHDL type to the corresponding LLHD type.
Map a VHDL type to the corresponding LLHD type.
Map a VHDL type to the corresponding LLHD type .
pub fn map_type(&self, ty: &Ty) -> Result<llhd::Type> {
        let ty = self.deref_named_type(ty)?;
        Ok(match *ty {
            Ty::Named(..) => unreachable!(),
            Ty::Null => llhd::void_ty(),
            Ty::Int(ref ty) => {
                let diff = match ty.dir {
                    hir::Dir::To => &ty.right_bound - &ty.left_bound,
                    hir::Dir::Downto => &ty.left_bound - &ty.right_bound,
                };
                if diff.is_negative() {
                    llhd::void_ty()
                } else {
                    llhd::int_ty(diff.bits() as usize)
                }
            }
            Ty::Enum(ref ty) => {
                let hir = self.lazy_hir(ty.decl)?;
                match hir.data.as_ref().unwrap().value {
                    hir::TypeData::Enum(ref lits) => llhd::enum_ty(lits.len()),
                    _ => unreachable!(),
                }
            }
            Ty::Physical(ref ty) => {
                self.emit(DiagBuilder2::error(format!(
                    "cannot generate code for physical type `{}`",
                    ty
                )));
                return Err(());
            }
            Ty::Access(ref ty) => llhd::pointer_ty(self.map_type(ty)?),
            Ty::Array(ref ty) => {
                let mut llty = self.map_type(&ty.element)?;
                for index in ty.indices.iter().rev() {
                    match *index {
                        ArrayIndex::Unbounded(_) => {
                            self.emit(
                                DiagBuilder2::error(format!("type `{}` is unbounded", ty)), // TODO: What span should we use here?
                            );
                            return Err(());
                        }
                        ArrayIndex::Constrained(ref ty) => {
                            let num = match **ty {
                                Ty::Int(ref ty) => {
                                    let l = ty.len();
                                    if l.is_negative() || l.is_zero() {
                                        return Ok(llhd::void_ty());
                                    }
                                    match l.to_usize() {
                                        Some(l) => l,
                                        None => {
                                            self.emit(
                                                DiagBuilder2::error(format!(
                                                    "array index `{}` is too large; {} elements",
                                                    ty, l
                                                )), // TODO: What span should we use here?
                                            );
                                            return Err(());
                                        }
                                    }
                                }
                                Ty::Enum(ref ty) => {
                                    match self.lazy_hir(ty.decl)?.data.as_ref().unwrap().value {
                                        hir::TypeData::Enum(ref lits) => lits.len(),
                                        _ => unreachable!(),
                                    }
                                }
                                _ => {
                                    self.emit(
                                        DiagBuilder2::error(format!(
                                            "`{}` is an invalid array index type",
                                            ty
                                        )), // TODO: What span should we use here?
                                    );
                                    return Err(());
                                }
                            };
                            llty = llhd::array_ty(num, llty);
                        }
                    }
                }
                llty
            }
            Ty::File(ref _ty) => llhd::int_ty(32),
            Ty::Record(ref ty) => {
                let fields = ty
                    .fields
                    .iter()
                    .map(|&(_, ref ty)| self.map_type(ty))
                    .collect::<Result<_>>()?;
                llhd::struct_ty(fields)
            }
            Ty::Subprog(..) => unimplemented!(),
            // Unbounded integers cannot be mapped to LLHD. All cases where
            // such an int can leak through to codegen should actually be caught
            // beforehand in the type check.
            Ty::UnboundedInt | Ty::UniversalInt => unreachable!(),
        })
    }
pub fn map_type ( & self , ty : & Ty ) -> Result < llhd :: Type > { let ty = self . deref_named_type ( ty ) ? ; Ok ( match * ty { Ty :: Named ( .. ) => unreachable ! ( ) , Ty :: Null => llhd :: void_ty ( ) , Ty :: Int ( ref ty ) => { let diff = match ty . dir { hir :: Dir :: To => & ty . right_bound - & ty . left_bound , hir :: Dir :: Downto => & ty . left_bound - & ty . right_bound , } ; if diff . is_negative ( ) { llhd :: void_ty ( ) } else { llhd :: int_ty ( diff . bits ( ) as usize ) } } Ty :: Enum ( ref ty ) => { let hir = self . lazy_hir ( ty . decl ) ? ; match hir . data . as_ref ( ) . unwrap ( ) . value { hir :: TypeData :: Enum ( ref lits ) => llhd :: enum_ty ( lits . len ( ) ) , _ => unreachable ! ( ) , } } Ty :: Physical ( ref ty ) => { self . emit ( DiagBuilder2 :: error ( format ! ( " " ty ) ) ) ; return Err ( ( ) ) ; } Ty :: Access ( ref ty ) => llhd :: pointer_ty ( self . map_type ( ty ) ? ) , Ty :: Array ( ref ty ) => { let mut llty = self . map_type ( & ty . element ) ? ; for index in ty . indices . iter ( ) . rev ( ) { match * index { ArrayIndex :: Unbounded ( _ ) => { self . emit ( DiagBuilder2 :: error ( format ! ( " " ty ) ) , // TODO: What span should we use here? ) ; return Err ( ( ) ) ; } ArrayIndex :: Constrained ( ref ty ) => { let num = match * * ty { Ty :: Int ( ref ty ) => { let l = ty . len ( ) ; if l . is_negative ( ) || l . is_zero ( ) { return Ok ( llhd :: void_ty ( ) ) ; } match l . to_usize ( ) { Some ( l ) => l , None => { self . emit ( DiagBuilder2 :: error ( format ! ( " " ty l ) ) , // TODO: What span should we use here? ) ; return Err ( ( ) ) ; } } } Ty :: Enum ( ref ty ) => { match self . lazy_hir ( ty . decl ) ? . data . as_ref ( ) . unwrap ( ) . value { hir :: TypeData :: Enum ( ref lits ) => lits . len ( ) , _ => unreachable ! ( ) , } } _ => { self . emit ( DiagBuilder2 :: error ( format ! ( " " ty ) ) , // TODO: What span should we use here? ) ; return Err ( ( ) ) ; } } ; llty = llhd :: array_ty ( num , llty ) ; } } } llty } Ty :: File ( ref _ty ) => llhd :: int_ty ( 32 ) , Ty :: Record ( ref ty ) => { let fields = ty . fields . iter ( ) . map ( | & ( _ , ref ty ) | self . map_type ( ty ) ) . collect :: < Result < _ > > ( ) ? ; llhd :: struct_ty ( fields ) } Ty :: Subprog ( .. ) => unimplemented ! ( ) , // Unbounded integers cannot be mapped to LLHD. All cases where // such an int can leak through to codegen should actually be caught // beforehand in the type check. Ty :: UnboundedInt | Ty :: UniversalInt => unreachable ! ( ) , } ) }
Map a VHDL type to the corresponding LLHD type.
Map a VHDL type to the corresponding LLHD type .
&self
ty
&Ty