pub enum Dtype {
Unit {
is_const: bool,
},
Int {
width: usize,
is_signed: bool,
is_const: bool,
},
Float {
width: usize,
is_const: bool,
},
Pointer {
inner: Box<Dtype>,
is_const: bool,
},
Array {
inner: Box<Dtype>,
size: usize,
},
Struct {
name: Option<String>,
fields: Option<Vec<Named<Dtype>>>,
is_const: bool,
size_align_offsets: Option<(usize, usize, Vec<usize>)>,
},
Function {
ret: Box<Dtype>,
params: Vec<Dtype>,
},
Typedef {
name: String,
is_const: bool,
},
}
Expand description
TODO(document)
Variants§
Unit
TODO(document)
Int
TODO(document)
Float
TODO(document)
Pointer
TODO(document)
Array
TODO(document)
Struct
TODO(document)
Fields
Function
TODO(document)
Typedef
TODO(document)
Implementations§
Source§impl Dtype
impl Dtype
Sourcepub const BITS_OF_BYTE: usize = 8usize
pub const BITS_OF_BYTE: usize = 8usize
TODO(document)
Sourcepub const SIZE_OF_BYTE: usize = 1usize
pub const SIZE_OF_BYTE: usize = 1usize
TODO(document)
Sourcepub const SIZE_OF_POINTER: usize = 8usize
pub const SIZE_OF_POINTER: usize = 8usize
TODO(document)
Sourcepub const SIZE_OF_CHAR: usize = 1usize
pub const SIZE_OF_CHAR: usize = 1usize
TODO(document)
Sourcepub const SIZE_OF_SHORT: usize = 2usize
pub const SIZE_OF_SHORT: usize = 2usize
TODO(document)
Sourcepub const SIZE_OF_INT: usize = 4usize
pub const SIZE_OF_INT: usize = 4usize
TODO(document)
Sourcepub const SIZE_OF_LONG: usize = 8usize
pub const SIZE_OF_LONG: usize = 8usize
TODO(document)
Sourcepub const SIZE_OF_LONGLONG: usize = 8usize
pub const SIZE_OF_LONGLONG: usize = 8usize
TODO(document)
Sourcepub const SIZE_OF_FLOAT: usize = 4usize
pub const SIZE_OF_FLOAT: usize = 4usize
TODO(document)
Sourcepub const SIZE_OF_DOUBLE: usize = 8usize
pub const SIZE_OF_DOUBLE: usize = 8usize
TODO(document)
Sourcepub fn array(base_dtype: Dtype, size: usize) -> Self
pub fn array(base_dtype: Dtype, size: usize) -> Self
TODO(document)
§Examples
Suppose the C declaration is int *a[2][3]
. Then a
’s ir::Dtype
should be [2 x [3 x int*]]
. But in the AST, it is parsed as Array(3, Array(2, Pointer(int)))
, reversing
the order of 2
and 3
. In the recursive translation of a declaration into Dtype, we
need to insert 3
inside [2 * int*]
.
Sourcepub fn structure(name: Option<String>, fields: Option<Vec<Named<Self>>>) -> Self
pub fn structure(name: Option<String>, fields: Option<Vec<Named<Self>>>) -> Self
TODO(document)
pub fn fill_size_align_offsets_of_struct( self, structs: &HashMap<String, Option<Dtype>>, ) -> Result<Self, DtypeError>
pub fn function(ret: Dtype, params: Vec<Dtype>) -> Self
pub fn typedef(name: String) -> Self
pub fn get_int_width(&self) -> Option<usize>
pub fn get_float_width(&self) -> Option<usize>
pub fn get_pointer_inner(&self) -> Option<&Self>
pub fn get_array_inner(&self) -> Option<&Self>
pub fn get_struct_name(&self) -> Option<&Option<String>>
pub fn get_struct_fields(&self) -> Option<&Option<Vec<Named<Self>>>>
pub fn get_struct_size_align_offsets( &self, ) -> Option<&Option<(usize, usize, Vec<usize>)>>
pub fn get_function_inner(&self) -> Option<(&Self, &Vec<Self>)>
pub fn is_scalar(&self) -> bool
pub fn is_int_signed(&self) -> bool
pub fn is_const(&self) -> bool
Sourcepub fn is_immutable(&self, structs: &HashMap<String, Option<Dtype>>) -> bool
pub fn is_immutable(&self, structs: &HashMap<String, Option<Dtype>>) -> bool
Check if Dtype
is constant. if it is constant, the variable of Dtype
is not assignable.
fn is_immutable_for_array_struct_field_inner( &self, structs: &HashMap<String, Option<Dtype>>, ) -> bool
pub fn set_const(self, is_const: bool) -> Self
pub fn size_align_of( &self, structs: &HashMap<String, Option<Dtype>>, ) -> Result<(usize, usize), DtypeError>
pub fn get_offset_struct_field( &self, field_name: &str, structs: &HashMap<String, Option<Dtype>>, ) -> Option<(usize, Self)>
pub fn set_signed(&self, is_signed: bool) -> Self
Sourcepub fn try_from_ast_declaration_specifiers(
specifiers: &[Node<DeclarationSpecifier>],
) -> Result<(Self, bool), DtypeError>
pub fn try_from_ast_declaration_specifiers( specifiers: &[Node<DeclarationSpecifier>], ) -> Result<(Self, bool), DtypeError>
Derive a data type from declaration specifiers.
Sourcepub fn try_from_ast_struct_declaration(
declaration: &StructDeclaration,
) -> Result<Vec<Named<Self>>, DtypeError>
pub fn try_from_ast_struct_declaration( declaration: &StructDeclaration, ) -> Result<Vec<Named<Self>>, DtypeError>
Derive a data type and its name from the struct declaration.
Sourcepub fn with_ast_declarator(
self,
declarator: &Declarator,
) -> Result<Named<Self>, DtypeError>
pub fn with_ast_declarator( self, declarator: &Declarator, ) -> Result<Named<Self>, DtypeError>
Generate Dtype
based on declarator and self
which has a scalar type.
Let’s say declaration is const int * const * const a;
. In general self
start with const int
which has a scalar type and declarator
represents * const * const
with
ast::Declarator
.
§Arguments
declarator
- Parts requiring conversion to ‘Dtype’ on the declaration.
Sourcepub fn with_ast_array_size(
self,
array_size: &ArraySize,
) -> Result<Self, DtypeError>
pub fn with_ast_array_size( self, array_size: &ArraySize, ) -> Result<Self, DtypeError>
Generates Dtype
based on declarator and self
which has a scalar type.
Let’s say the AST declaration is int a[2][3]
; self
represents int [2]
; and
array_size
is [3]
. Then this function should return int [2][3]
.
§Arguments
array_size
- the array size to add toself
.
pub fn resolve_typedefs( self, typedefs: &HashMap<String, Dtype>, ) -> Result<Self, DtypeError>
Sourcepub fn resolve_structs(
self,
structs: &mut HashMap<String, Option<Dtype>>,
tempid_counter: &mut usize,
) -> Result<Self, DtypeError>
pub fn resolve_structs( self, structs: &mut HashMap<String, Option<Dtype>>, tempid_counter: &mut usize, ) -> Result<Self, DtypeError>
If the struct type has a definition, it is saved to the struct table and transformed to a struct type with no definition.
Trait Implementations§
Source§impl TryFrom<&ParameterDeclaration> for Dtype
impl TryFrom<&ParameterDeclaration> for Dtype
Source§fn try_from(parameter_decl: &ParameterDeclaration) -> Result<Self, Self::Error>
fn try_from(parameter_decl: &ParameterDeclaration) -> Result<Self, Self::Error>
Generate Dtype
based on parameter declaration.
Source§type Error = DtypeError
type Error = DtypeError
Source§impl TryFrom<BaseDtype> for Dtype
impl TryFrom<BaseDtype> for Dtype
Source§fn try_from(spec: BaseDtype) -> Result<Self, DtypeError>
fn try_from(spec: BaseDtype) -> Result<Self, DtypeError>
Derive a data type containing scalar type from specifiers.
§Example
For declaration is const unsigned int * p
, specifiers
is const unsigned int
, and the
result is Dtype::Int { width: 4, is_signed: false, is_const: true }
.
Source§type Error = DtypeError
type Error = DtypeError
Source§impl TryFrom<Dtype> for Declaration
impl TryFrom<Dtype> for Declaration
Source§fn try_from(dtype: Dtype) -> Result<Self, Self::Error>
fn try_from(dtype: Dtype) -> Result<Self, Self::Error>
Create an appropriate declaration according to dtype
.
§Example
If int g = 0;
is declared, dtype
is ir::Dtype::Int{ width:32, is_signed:true, is_const:false }
.
In this case, ir::Declaration::Variable{ dtype, initializer: Some(Constant::I32(1)) }
is generated.
Conversely, if int foo();
is declared, dtype
is ir::Dtype::Function{ret: Scalar(Int), params: []}
. Thus, in this case, ir::Declaration::Function
is generated.
Source§type Error = DtypeError
type Error = DtypeError
impl Eq for Dtype
impl StructuralPartialEq for Dtype
Auto Trait Implementations§
impl Freeze for Dtype
impl RefUnwindSafe for Dtype
impl Send for Dtype
impl Sync for Dtype
impl Unpin for Dtype
impl UnwindSafe for Dtype
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more