pub fn index_into(
        &mut self,
        ptr: Value,
        indices: &[Value],
        location: Option<Location>,
    ) -> Value {
        let ptr_ty = ptr.get_type(self.context);

        assert!(ptr_ty.is_pointer(self.context));
        assert!(!indices.is_empty());

        let domain = ptr_ty.get_domain(self.context);
        let mut ty = ptr_ty;

        for index in indices {
            let element_ty = ty.get_element(self.context, 0);

            let new_element_ty = if element_ty.is_struct(self.context) {
                assert!(index.is_constant(self.context));

                let constant = index.get_constant(self.context);

                match constant {
                    Constant::Int(i, _) => element_ty.get_element(self.context, *i as usize),
                    Constant::UInt(u, _) => element_ty.get_element(self.context, *u as usize),
                    _ => panic!("Index into struct is not constant"),
                }
            } else if element_ty.is_array(self.context) | element_ty.is_pointer(self.context) {
                element_ty.get_element(self.context, 0)
            } else {
                element_ty
            };

            // Any other index would yield the same type as getting the index from the 0th element.
            ty = self.context.get_pointer_type(new_element_ty, domain);
        }

        self.make_value(Instruction::IndexInto(ty, ptr, indices.to_vec(), location))
    }
/// Get a pointer to an element from within another pointer.
///
/// Restrictions:
/// - `ptr` must be a pointer type.
/// - `indices` must be non-empty.
/// - Constants must be used when indexing into a struct.
///
/// # Examples
///
/// ```
/// # use yair::*;
/// # let mut context = Context::new();
/// # let module = context.create_module().build();
/// # let u32_ty = context.get_uint_type(32);
/// # let u32_ptr_ty = context.get_pointer_type(u32_ty, Domain::Cpu);
/// # let u32_array_ty = context.get_array_type(u32_ty, 42);
/// # let struct_ty = context.get_struct_type(&[ u32_ptr_ty, u32_array_ty, u32_ty ]);
/// # let ptr_ty = context.get_pointer_type(struct_ty, Domain::Cpu);
/// # let function = module.create_function(&mut context).with_name("func").with_return_type(u32_ptr_ty).with_arg("a", ptr_ty).build();
/// # let block = function.create_block(&mut context).build();
/// # let ptr = function.get_arg(&context, 0);
/// # let i0 = context.get_int_constant(8, 0);
/// # let i1 = context.get_uint_constant(32, 1);
/// # let i2 = i0;
/// # let mut instruction_builder = block.create_instructions(&mut context);
/// # let location = None;
/// let index_into = instruction_builder.index_into(ptr, &[ i0, i1, i2 ], location);
/// # assert_eq!(index_into.get_type(&context), u32_ptr_ty);
/// ```
Get a pointer to an element from within another pointer.
Restrictions:
`ptr` must be a pointer type.
`indices` must be non-empty.
Constants must be used when indexing into a struct.
Get a pointer to an element from within another pointer . Restrictions : ` ptr ` must be a pointer type . ` indices ` must be non - empty . Constants must be used when indexing into a struct .
pub fn index_into(
        &mut self,
        ptr: Value,
        indices: &[Value],
        location: Option<Location>,
    ) -> Value {
        let ptr_ty = ptr.get_type(self.context);
        assert!(ptr_ty.is_pointer(self.context));
        assert!(!indices.is_empty());
        let domain = ptr_ty.get_domain(self.context);
        let mut ty = ptr_ty;
        for index in indices {
            let element_ty = ty.get_element(self.context, 0);
            let new_element_ty = if element_ty.is_struct(self.context) {
                assert!(index.is_constant(self.context));
                let constant = index.get_constant(self.context);
                match constant {
                    Constant::Int(i, _) => element_ty.get_element(self.context, *i as usize),
                    Constant::UInt(u, _) => element_ty.get_element(self.context, *u as usize),
                    _ => panic!("Index into struct is not constant"),
                }
            } else if element_ty.is_array(self.context) | element_ty.is_pointer(self.context) {
                element_ty.get_element(self.context, 0)
            } else {
                element_ty
            };
            // Any other index would yield the same type as getting the index from the 0th element.
            ty = self.context.get_pointer_type(new_element_ty, domain);
        }
        self.make_value(Instruction::IndexInto(ty, ptr, indices.to_vec(), location))
    }
pub fn index_into ( & mut self , ptr : Value , indices : & [ Value ] , location : Option < Location > , ) -> Value { let ptr_ty = ptr . get_type ( self . context ) ; assert ! ( ptr_ty is_pointer ( self context ) ) ; assert ! ( indices is_empty ( ) ) ; let domain = ptr_ty . get_domain ( self . context ) ; let mut ty = ptr_ty ; for index in indices { let element_ty = ty . get_element ( self . context , 0 ) ; let new_element_ty = if element_ty . is_struct ( self . context ) { assert ! ( index is_constant ( self context ) ) ; let constant = index . get_constant ( self . context ) ; match constant { Constant :: Int ( i , _ ) => element_ty . get_element ( self . context , * i as usize ) , Constant :: UInt ( u , _ ) => element_ty . get_element ( self . context , * u as usize ) , _ => panic ! ( " " ) , } } else if element_ty . is_array ( self . context ) | element_ty . is_pointer ( self . context ) { element_ty . get_element ( self . context , 0 ) } else { element_ty } ; // Any other index would yield the same type as getting the index from the 0th element. ty = self . context . get_pointer_type ( new_element_ty , domain ) ; } self . make_value ( Instruction :: IndexInto ( ty , ptr , indices . to_vec ( ) , location ) ) }
Get a pointer to an element from within another pointer.
Get a pointer to an element from within another pointer .
&mut self
ptr
Value
indices
&[Value]
location
Option<Location>
&mut self
ptr
Value
indices
&[Value]
location
Option<Location>
examples
None
use yair::*;
None
let mut context = context::new();
None
let module = context.create_module().build();
None
let u32_ty = context.get_uint_type(32);
None
let u32_ptr_ty = context.get_pointer_type(u32_ty, domain::cpu);
None
let u32_array_ty = context.get_array_type(u32_ty, 42);
None
let struct_ty = context.get_struct_type(&[ u32_ptr_ty, u32_array_ty, u32_ty ]);
None
let ptr_ty = context.get_pointer_type(struct_ty, domain::cpu);
None
let function = module.create_function(&mut context).with_name("func").with_return_type(u32_ptr_ty).with_arg("a", ptr_ty).build();
None
let block = function.create_block(&mut context).build();
None
let ptr = function.get_arg(&context, 0);
None
let i0 = context.get_int_constant(8, 0);
None
let i1 = context.get_uint_constant(32, 1);
None
let i2 = i0;
None
let mut instruction_builder = block.create_instructions(&mut context);
None
let location = none;
let index_into = instruction_builder.index_into(ptr, &[ i0, i1, i2 ], location).
let index_into = instruction_builder . index_into ( ptr & [ i0 i1 i2 ] location ) .
assert_eq!(index_into.get_type(&context), u32_ptr_ty);
None