blob: 16981b3ec6de113d3b39af0f3e62c8c2c5da8741 [file] [log] [blame] [edit]
use std::marker::PhantomData;
use std::fmt;
use std::ptr;
use context::Context;
use field::Field;
use field;
use types::Type;
use types;
use location::Location;
use location;
use object::{ToObject, Object};
/// A Struct is gccjit's representation of a composite type. Despite the name,
/// Struct can represent either a struct, an union, or an opaque named type.
#[derive(Copy, Clone, Eq, Hash, PartialEq)]
pub struct Struct<'ctx> {
marker: PhantomData<&'ctx Context<'ctx>>,
ptr: *mut gccjit_sys::gcc_jit_struct
}
impl<'ctx> Struct<'ctx> {
pub fn as_type(&self) -> Type<'ctx> {
unsafe {
let ptr = gccjit_sys::gcc_jit_struct_as_type(self.ptr);
types::from_ptr(ptr)
}
}
pub fn set_fields(&self,
location: Option<Location<'ctx>>,
fields: &[Field<'ctx>]) {
let loc_ptr = match location {
Some(loc) => unsafe { location::get_ptr(&loc) },
None => ptr::null_mut()
};
let num_fields = fields.len() as i32;
let mut fields_ptrs : Vec<_> = fields.iter()
.map(|x| unsafe { field::get_ptr(x) })
.collect();
unsafe {
gccjit_sys::gcc_jit_struct_set_fields(self.ptr,
loc_ptr,
num_fields,
fields_ptrs.as_mut_ptr());
}
#[cfg(debug_assertions)]
if let Ok(Some(error)) = self.to_object().get_context().get_last_error() {
panic!("{}", error);
}
}
pub fn get_field(&self, index: i32) -> Field<'ctx> {
let field = unsafe {
let ptr = gccjit_sys::gcc_jit_struct_get_field(self.ptr, index);
#[cfg(debug_assertions)]
if ptr.is_null() {
panic!("Null ptr in get_field() from struct: {:?}", self);
}
field::from_ptr(ptr)
};
#[cfg(debug_assertions)]
if let Ok(Some(error)) = self.to_object().get_context().get_last_error() {
panic!("{}", error);
}
field
}
pub fn get_field_count(&self) -> usize {
unsafe {
let count = gccjit_sys::gcc_jit_struct_get_field_count(self.ptr) as usize;
#[cfg(debug_assertions)]
if let Ok(Some(error)) = self.to_object().get_context().get_last_error() {
panic!("{}", error);
}
count
}
}
}
impl<'ctx> ToObject<'ctx> for Struct<'ctx> {
fn to_object(&self) -> Object<'ctx> {
let ty = self.as_type();
ty.to_object()
}
}
impl<'ctx> fmt::Debug for Struct<'ctx> {
fn fmt<'a>(&self, fmt: &mut fmt::Formatter<'a>) -> Result<(), fmt::Error> {
let obj = self.as_type();
obj.fmt(fmt)
}
}
pub unsafe fn from_ptr<'ctx>(ptr: *mut gccjit_sys::gcc_jit_struct) -> Struct<'ctx> {
Struct {
marker: PhantomData,
ptr
}
}