提交 225353d8 编写于 作者: K Keegan McAllister

Add a Rust string ostream for LLVM

上级 77b3a7ba
......@@ -21,11 +21,10 @@
use std::c_str::ToCStr;
use std::mem;
use std::string;
use std::cell::RefCell;
use std::collections::HashMap;
use libc::{c_uint, c_void, free};
use libc::c_uint;
#[deriving(Clone, PartialEq, Show)]
pub struct Type {
......@@ -339,12 +338,9 @@ pub fn find_type(&self, s: &str) -> Option<Type> {
}
pub fn type_to_string(&self, ty: Type) -> String {
unsafe {
let s = llvm::LLVMTypeToString(ty.to_ref());
let ret = string::raw::from_buf(s as *const u8);
free(s as *mut c_void);
ret
}
llvm::build_string(|s| unsafe {
llvm::LLVMWriteTypeToString(ty.to_ref(), s);
}).expect("non-UTF8 type description from LLVM")
}
pub fn types_to_str(&self, tys: &[Type]) -> String {
......@@ -353,11 +349,8 @@ pub fn types_to_str(&self, tys: &[Type]) -> String {
}
pub fn val_to_string(&self, val: ValueRef) -> String {
unsafe {
let s = llvm::LLVMValueToString(val);
let ret = string::raw::from_buf(s as *const u8);
free(s as *mut c_void);
ret
}
llvm::build_string(|s| unsafe {
llvm::LLVMWriteValueToString(val, s);
}).expect("nun-UTF8 value description from LLVM")
}
}
......@@ -28,6 +28,8 @@
extern crate libc;
use std::c_str::ToCStr;
use std::cell::RefCell;
use std::{raw, mem};
use libc::{c_uint, c_ushort, uint64_t, c_int, size_t, c_char};
use libc::{c_longlong, c_ulonglong};
use debuginfo::{DIBuilderRef, DIDescriptor,
......@@ -1839,8 +1841,8 @@ pub fn LLVMDIBuilderCreateNameSpace(Builder: DIBuilderRef,
-> ValueRef;
pub fn LLVMDICompositeTypeSetTypeArray(CompositeType: ValueRef, TypeArray: ValueRef);
pub fn LLVMTypeToString(Type: TypeRef) -> *const c_char;
pub fn LLVMValueToString(value_ref: ValueRef) -> *const c_char;
pub fn LLVMWriteTypeToString(Type: TypeRef, s: RustStringRef);
pub fn LLVMWriteValueToString(value_ref: ValueRef, s: RustStringRef);
pub fn LLVMIsAArgument(value_ref: ValueRef) -> ValueRef;
......@@ -2046,6 +2048,30 @@ pub fn get_param(llfn: ValueRef, index: c_uint) -> ValueRef {
}
}
pub enum RustString_opaque {}
pub type RustStringRef = *mut RustString_opaque;
type RustStringRepr = *mut RefCell<Vec<u8>>;
/// Appending to a Rust string -- used by raw_rust_string_ostream.
#[no_mangle]
pub unsafe extern "C" fn rust_llvm_string_write_impl(sr: RustStringRef,
ptr: *const c_char,
size: size_t) {
let slice: &[u8] = mem::transmute(raw::Slice {
data: ptr as *const u8,
len: size as uint,
});
let sr: RustStringRepr = mem::transmute(sr);
(*sr).borrow_mut().push_all(slice);
}
pub fn build_string(f: |RustStringRef|) -> Option<String> {
let mut buf = RefCell::new(Vec::new());
f(&mut buf as RustStringRepr as RustStringRef);
String::from_utf8(buf.unwrap()).ok()
}
// FIXME #15460 - create a public function that actually calls our
// static LLVM symbols. Otherwise the linker will just throw llvm
// away. We're just calling lots of stuff until we transitively get
......
......@@ -645,22 +645,18 @@ extern "C" void LLVMDICompositeTypeSetTypeArray(
#endif
}
extern "C" char *LLVMTypeToString(LLVMTypeRef Type) {
std::string s;
llvm::raw_string_ostream os(s);
extern "C" void LLVMWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
raw_rust_string_ostream os(str);
unwrap<llvm::Type>(Type)->print(os);
return strdup(os.str().data());
}
extern "C" char *LLVMValueToString(LLVMValueRef Value) {
std::string s;
llvm::raw_string_ostream os(s);
extern "C" void LLVMWriteValueToString(LLVMValueRef Value, RustStringRef str) {
raw_rust_string_ostream os(str);
os << "(";
unwrap<llvm::Value>(Value)->getType()->print(os);
os << ":";
unwrap<llvm::Value>(Value)->print(os);
os << ")";
return strdup(os.str().data());
}
#if LLVM_VERSION_MINOR >= 5
......
......@@ -69,3 +69,31 @@
#endif
void LLVMRustSetLastError(const char*);
typedef struct OpaqueRustString *RustStringRef;
extern "C" void
rust_llvm_string_write_impl(RustStringRef str, const char *ptr, size_t size);
class raw_rust_string_ostream : public llvm::raw_ostream {
RustStringRef str;
uint64_t pos;
void write_impl(const char *ptr, size_t size) override {
rust_llvm_string_write_impl(str, ptr, size);
pos += size;
}
uint64_t current_pos() const override {
return pos;
}
public:
explicit raw_rust_string_ostream(RustStringRef str)
: str(str), pos(0) { }
~raw_rust_string_ostream() {
// LLVM requires this.
flush();
}
};
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册