about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniel Micay <danielmicay@gmail.com>2013-10-11 19:56:11 -0400
committerDaniel Micay <danielmicay@gmail.com>2013-10-11 20:26:08 -0400
commit7bad4167654ef846155bae7165fd0ffcc24fcbbe (patch)
treec5acad50a7ff91138fddd98bf1d7c71a90ce63ee
parent80878ff369cabc63967a6ebfd69f3e5fa692ceff (diff)
downloadrust-7bad4167654ef846155bae7165fd0ffcc24fcbbe.tar.gz
rust-7bad4167654ef846155bae7165fd0ffcc24fcbbe.zip
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.
-rw-r--r--src/librustc/lib/llvm.rs67
-rw-r--r--src/rustllvm/RustWrapper.cpp7
-rw-r--r--src/rustllvm/rustllvm.def.in1
3 files changed, 16 insertions, 59 deletions
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs
index 04d8b3bee82..787f8e60d65 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 31a02dceb1c..f8d56f4e892 100644
--- a/src/rustllvm/RustWrapper.cpp
+++ b/src/rustllvm/RustWrapper.cpp
@@ -803,3 +803,10 @@ extern "C" void LLVMDICompositeTypeSetTypeArray(
 {
     unwrapDI<DICompositeType>(CompositeType).setTypeArray(unwrapDI<DIArray>(TypeArray));
 }
+
+extern "C" char *LLVMTypeToString(LLVMTypeRef Type) {
+    std::string s;
+    llvm::raw_string_ostream os(s);
+    unwrap<llvm::Type>(Type)->print(os);
+    return strdup(os.str().data());
+}
diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in
index 0162857e44e..c1f1444fb4f 100644
--- a/src/rustllvm/rustllvm.def.in
+++ b/src/rustllvm/rustllvm.def.in
@@ -628,3 +628,4 @@ LLVMRustSetNormalizedTarget
 LLVMRustAddAlwaysInlinePass
 LLVMAddReturnAttribute
 LLVMRemoveReturnAttribute
+LLVMTypeToString