From 7bad4167654ef846155bae7165fd0ffcc24fcbbe Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Fri, 11 Oct 2013 19:56:11 -0400 Subject: [PATCH] have LLVM print type strings for us Example: void ({ i64, %tydesc*, i8*, i8*, i8 }*, i64*, %"struct.std::fmt::Formatter[#1]"*)* Before, we would print 20 levels deep due to recursion in the type definition. --- src/librustc/lib/llvm.rs | 67 +++++------------------------------- src/rustllvm/RustWrapper.cpp | 7 ++++ src/rustllvm/rustllvm.def.in | 1 + 3 files changed, 16 insertions(+), 59 deletions(-) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 04d8b3bee8213..787f8e60d653f 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -15,7 +15,8 @@ use std::c_str::ToCStr; use std::hashmap::HashMap; -use std::libc::{c_uint, c_ushort}; +use std::libc::{c_uint, c_ushort, c_void, free}; +use std::str::raw::from_c_str; use std::option; use middle::trans::type_::Type; @@ -1666,6 +1667,7 @@ pub mod llvm { -> ValueRef; pub fn LLVMDICompositeTypeSetTypeArray(CompositeType: ValueRef, TypeArray: ValueRef); + pub fn LLVMTypeToString(Type: TypeRef) -> *c_char; pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef; @@ -1789,68 +1791,15 @@ impl TypeNames { self.named_types.find_equiv(&s).map(|x| Type::from_ref(*x)) } - // 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 => () - } - - if depth == 0 { - return ~"###"; - } - + pub fn type_to_str(&self, ty: Type) -> ~str { 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 => { - format!("i{}", llvm::LLVMGetIntTypeWidth(ty.to_ref()) as int) - } - 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); - format!("fn({}) -> {}", args, out_ty) - } - Struct => { - let tys = ty.field_types(); - let tys = tys.map(|&ty| self.type_to_str_depth(ty, depth-1)).connect(", "); - format!("\\{{}\\}", 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(); - format!("[{} x {}]", el_ty, len) - } - Pointer => { - let el_ty = ty.element_type(); - let el_ty = self.type_to_str_depth(el_ty, depth-1); - format!("*{}", el_ty) - } - _ => fail2!("Unknown Type Kind ({})", kind as uint) - } + let s = llvm::LLVMTypeToString(ty.to_ref()); + let ret = from_c_str(s); + free(s as *c_void); + ret } } - pub fn type_to_str(&self, ty: Type) -> ~str { - self.type_to_str_depth(ty, 30) - } - pub fn types_to_str(&self, tys: &[Type]) -> ~str { let strs = tys.map(|t| self.type_to_str(*t)); format!("[{}]", strs.connect(",")) diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 31a02dceb1c09..f8d56f4e892ac 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -803,3 +803,10 @@ extern "C" void LLVMDICompositeTypeSetTypeArray( { unwrapDI(CompositeType).setTypeArray(unwrapDI(TypeArray)); } + +extern "C" char *LLVMTypeToString(LLVMTypeRef Type) { + std::string s; + llvm::raw_string_ostream os(s); + unwrap(Type)->print(os); + return strdup(os.str().data()); +} diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index 0162857e44e37..c1f1444fb4ffc 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -628,3 +628,4 @@ LLVMRustSetNormalizedTarget LLVMRustAddAlwaysInlinePass LLVMAddReturnAttribute LLVMRemoveReturnAttribute +LLVMTypeToString