use libc::{c_char, c_uint};
use ffi::target_machine::{self, LLVMTargetRef};
use ffi::target::{self, LLVMTargetDataRef, LLVMOpaqueTargetData};
use cbox::{CBox, DisposeRef};
use std::ffi::CString;
use std::fmt;
use ty::Type;
use util;
pub struct TargetData;
native_ref!(&TargetData = LLVMTargetDataRef);
impl TargetData {
pub fn new(rep: &str) -> CBox<TargetData> {
let c_rep = CString::new(rep).unwrap();
CBox::new(unsafe {
target::LLVMCreateTargetData(c_rep.as_ptr())
}.into())
}
pub fn is_big_endian(&self) -> bool {
let order = unsafe { target::LLVMByteOrder(self.into()) } as c_uint;
order == 0
}
pub fn get_pointer_size(&self) -> usize {
unsafe { target::LLVMPointerSize(self.into()) as usize }
}
pub fn size_of_in_bits(&self, ty: &Type) -> u64 {
unsafe { target::LLVMSizeOfTypeInBits(self.into(), ty.into()) }
}
pub fn size_of(&self, ty: &Type) -> u64 {
unsafe { target::LLVMStoreSizeOfType(self.into(), ty.into()) }
}
pub fn alignment_of(&self, ty: &Type) -> usize {
unsafe { target::LLVMABIAlignmentOfType(self.into(), ty.into()) as usize }
}
pub fn element_at(&self, struct_ty: &Type, offset: u64) -> usize {
unsafe { target::LLVMElementAtOffset(self.into(), struct_ty.into(), offset) as usize }
}
pub fn offset_of(&self, struct_ty: &Type, element: usize) -> u64 {
unsafe { target::LLVMOffsetOfElement(self.into(), struct_ty.into(), element as c_uint) }
}
pub fn as_str(&self) -> CBox<str> {
unsafe {
CBox::new(target::LLVMCopyStringRepOfTargetData(self.into()))
}
}
}
impl fmt::Display for TargetData {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str(&self.as_str())
}
}
impl DisposeRef for TargetData {
type RefTo = LLVMOpaqueTargetData;
unsafe fn dispose(ptr: LLVMTargetDataRef) {
target::LLVMDisposeTargetData(ptr)
}
}
pub struct Target;
native_ref!(&Target = LLVMTargetRef);
impl Target {
pub fn get_name(&self) -> &str {
unsafe { util::to_str(target_machine::LLVMGetTargetName(self.into()) as *mut c_char) }
}
pub fn get_description(&self) -> &str {
unsafe { util::to_str(target_machine::LLVMGetTargetDescription(self.into()) as *mut c_char) }
}
pub fn has_asm_backend(&self) -> bool {
unsafe { target_machine::LLVMTargetHasAsmBackend(self.into()) != 0 }
}
pub fn has_jit(&self) -> bool {
unsafe { target_machine::LLVMTargetHasJIT(self.into()) != 0 }
}
pub fn has_target_machine(&self) -> bool {
unsafe { target_machine::LLVMTargetHasTargetMachine(self.into()) != 0 }
}
}