diff options
Diffstat (limited to 'src/librustc/lib/llvm.rs')
| -rw-r--r-- | src/librustc/lib/llvm.rs | 229 |
1 files changed, 87 insertions, 142 deletions
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 5d5a5e736bc..8ca8c12f412 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -8,14 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::prelude::*; -use core::hashmap::HashMap; -use core::libc::{c_uint, c_ushort}; -use core::option; -use core::ptr; -use core::str; -use core::vec; +use std::hashmap::HashMap; +use std::libc::{c_uint, c_ushort}; +use std::option; +use std::str; + +use middle::trans::type_::Type; pub type Opcode = u32; pub type Bool = c_uint; @@ -268,7 +267,7 @@ pub mod llvm { use super::{SectionIteratorRef, TargetDataRef, TypeKind, TypeRef, UseRef}; use super::{ValueRef, PassRef}; use super::debuginfo::*; - use core::libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong}; + use std::libc::{c_char, c_int, c_longlong, c_ushort, c_uint, c_ulonglong}; #[link_args = "-Lrustllvm -lrustllvm"] #[link_name = "rustllvm"] @@ -2121,155 +2120,101 @@ pub fn ConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef { /* Memory-managed object interface to type handles. */ pub struct TypeNames { - type_names: @mut HashMap<TypeRef, @str>, - named_types: @mut HashMap<@str, TypeRef> -} - -pub fn associate_type(tn: @TypeNames, s: @str, t: TypeRef) { - assert!(tn.type_names.insert(t, s)); - assert!(tn.named_types.insert(s, t)); -} - -pub fn type_has_name(tn: @TypeNames, t: TypeRef) -> Option<@str> { - return tn.type_names.find(&t).map_consume(|x| *x); -} - -pub fn name_has_type(tn: @TypeNames, s: @str) -> Option<TypeRef> { - return tn.named_types.find(&s).map_consume(|x| *x); + type_names: HashMap<TypeRef, ~str>, + named_types: HashMap<~str, TypeRef> } -pub fn mk_type_names() -> @TypeNames { - @TypeNames { - type_names: @mut HashMap::new(), - named_types: @mut HashMap::new() +impl TypeNames { + pub fn new() -> TypeNames { + TypeNames { + type_names: HashMap::new(), + named_types: HashMap::new() + } } -} -pub fn type_to_str(names: @TypeNames, ty: TypeRef) -> @str { - return type_to_str_inner(names, [], ty); -} + pub fn associate_type(&mut self, s: &str, t: &Type) { + assert!(self.type_names.insert(t.to_ref(), s.to_owned())); + assert!(self.named_types.insert(s.to_owned(), t.to_ref())); + } -pub fn type_to_str_inner(names: @TypeNames, outer0: &[TypeRef], ty: TypeRef) - -> @str { - unsafe { - match type_has_name(names, ty) { - option::Some(n) => return n, - _ => {} + pub fn find_name<'r>(&'r self, ty: &Type) -> Option<&'r str> { + match self.type_names.find(&ty.to_ref()) { + Some(a) => Some(a.slice(0, a.len())), + None => None } + } - let outer = vec::append_one(outer0.to_vec(), ty); + pub fn find_type(&self, s: &str) -> Option<Type> { + self.named_types.find_equiv(&s).map_consume(|x| Type::from_ref(*x)) + } - let kind = llvm::LLVMGetTypeKind(ty); + // We have a depth count, because we seem to make infinite types. + pub fn type_to_str_depth(&self, ty: Type, depth: int) -> ~str { + match self.find_name(&ty) { + option::Some(name) => return name.to_owned(), + None => () + } - fn tys_str(names: @TypeNames, outer: &[TypeRef], - tys: ~[TypeRef]) -> @str { - let mut s = ~""; - let mut first: bool = true; - for tys.each |t| { - if first { first = false; } else { s += ", "; } - s += type_to_str_inner(names, outer, *t); - } - // [Note at-str] FIXME #2543: Could rewrite this without the copy, - // but need better @str support. - return s.to_managed(); + if depth == 0 { + return ~"###"; } - match kind { - Void => return @"Void", - Half => return @"Half", - Float => return @"Float", - Double => return @"Double", - X86_FP80 => return @"X86_FP80", - FP128 => return @"FP128", - PPC_FP128 => return @"PPC_FP128", - Label => return @"Label", - Integer => { - // See [Note at-str] - return fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty) - as int).to_managed(); - } - Function => { - let out_ty: TypeRef = llvm::LLVMGetReturnType(ty); - let n_args = llvm::LLVMCountParamTypes(ty) as uint; - let args = vec::from_elem(n_args, 0 as TypeRef); - llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args)); - // See [Note at-str] - return fmt!("fn(%s) -> %s", - tys_str(names, outer, args), - type_to_str_inner(names, outer, out_ty)).to_managed(); - } - Struct => { - let elts = struct_tys(ty); - // See [Note at-str] - return fmt!("{%s}", tys_str(names, outer, elts)).to_managed(); - } - Array => { - let el_ty = llvm::LLVMGetElementType(ty); - // See [Note at-str] - return fmt!("[%s@ x %u", type_to_str_inner(names, outer, el_ty), - llvm::LLVMGetArrayLength(ty) as uint).to_managed(); - } - Pointer => { - let mut i = 0; - for outer0.each |tout| { - i += 1; - if *tout as int == ty as int { - let n = outer0.len() - i; - // See [Note at-str] - return fmt!("*\\%d", n as int).to_managed(); + unsafe { + let kind = ty.kind(); + + match kind { + Void => ~"Void", + Half => ~"Half", + Float => ~"Float", + Double => ~"Double", + X86_FP80 => ~"X86_FP80", + FP128 => ~"FP128", + PPC_FP128 => ~"PPC_FP128", + Label => ~"Label", + Vector => ~"Vector", + Metadata => ~"Metadata", + X86_MMX => ~"X86_MMAX", + Integer => { + fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty.to_ref()) as int) } - } - let addrstr = { - let addrspace = llvm::LLVMGetPointerAddressSpace(ty) as uint; - if addrspace == 0 { - ~"" - } else { - fmt!("addrspace(%u)", addrspace) + Function => { + let out_ty = ty.return_type(); + let args = ty.func_params(); + let args = + args.map(|&ty| self.type_to_str_depth(ty, depth-1)).connect(", "); + let out_ty = self.type_to_str_depth(out_ty, depth-1); + fmt!("fn(%s) -> %s", args, out_ty) + } + Struct => { + let tys = ty.field_types(); + let tys = tys.map(|&ty| self.type_to_str_depth(ty, depth-1)).connect(", "); + fmt!("{%s}", tys) + } + Array => { + let el_ty = ty.element_type(); + let el_ty = self.type_to_str_depth(el_ty, depth-1); + let len = ty.array_length(); + fmt!("[%s x %u]", el_ty, len) } - }; - // See [Note at-str] - return fmt!("%s*%s", addrstr, type_to_str_inner(names, - outer, - llvm::LLVMGetElementType(ty))).to_managed(); - } - Vector => return @"Vector", - Metadata => return @"Metadata", - X86_MMX => return @"X86_MMAX", - _ => fail!() + Pointer => { + let el_ty = ty.element_type(); + let el_ty = self.type_to_str_depth(el_ty, depth-1); + fmt!("*%s", el_ty) + } + _ => fail!("Unknown Type Kind (%u)", kind as uint) + } } } -} -pub fn float_width(llt: TypeRef) -> uint { - unsafe { - return match llvm::LLVMGetTypeKind(llt) as int { - 1 => 32u, - 2 => 64u, - 3 => 80u, - 4 | 5 => 128u, - _ => fail!("llvm_float_width called on a non-float type") - }; + pub fn type_to_str(&self, ty: Type) -> ~str { + self.type_to_str_depth(ty, 30) } -} -pub fn fn_ty_param_tys(fn_ty: TypeRef) -> ~[TypeRef] { - unsafe { - let args = vec::from_elem(llvm::LLVMCountParamTypes(fn_ty) as uint, - 0 as TypeRef); - llvm::LLVMGetParamTypes(fn_ty, vec::raw::to_ptr(args)); - return args; - } -} - -pub fn struct_tys(struct_ty: TypeRef) -> ~[TypeRef] { - unsafe { - let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) as uint; - if n_elts == 0 { - return ~[]; + pub fn val_to_str(&self, val: ValueRef) -> ~str { + unsafe { + let ty = Type::from_ref(llvm::LLVMTypeOf(val)); + self.type_to_str(ty) } - let mut elts = vec::from_elem(n_elts, ptr::null()); - llvm::LLVMGetStructElementTypes(struct_ty, &mut elts[0]); - return elts; } } @@ -2281,7 +2226,7 @@ pub struct target_data_res { } impl Drop for target_data_res { - fn finalize(&self) { + fn drop(&self) { unsafe { llvm::LLVMDisposeTargetData(self.TD); } @@ -2318,7 +2263,7 @@ pub struct pass_manager_res { } impl Drop for pass_manager_res { - fn finalize(&self) { + fn drop(&self) { unsafe { llvm::LLVMDisposePassManager(self.PM); } @@ -2354,7 +2299,7 @@ pub struct object_file_res { } impl Drop for object_file_res { - fn finalize(&self) { + fn drop(&self) { unsafe { llvm::LLVMDisposeObjectFile(self.ObjectFile); } @@ -2391,7 +2336,7 @@ pub struct section_iter_res { } impl Drop for section_iter_res { - fn finalize(&self) { + fn drop(&self) { unsafe { llvm::LLVMDisposeSectionIterator(self.SI); } |
