Add a Rust string ostream for LLVM
This commit is contained in:
parent
77b3a7ba8b
commit
225353d8bb
src
@ -21,11 +21,10 @@ use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel};
|
||||
|
||||
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 @@ impl TypeNames {
|
||||
}
|
||||
|
||||
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 @@ impl TypeNames {
|
||||
}
|
||||
|
||||
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 @@ extern {
|
||||
-> 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();
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user