Methodize TypeNames

This commit is contained in:
James Miller 2013-06-15 14:31:52 +12:00
parent 544f6159f7
commit 3dbdb3a364
2 changed files with 69 additions and 107 deletions

View File

@ -2121,121 +2121,81 @@ 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>
type_names: HashMap<TypeRef, @str>,
named_types: 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);
}
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: TypeRef) {
assert!(self.type_names.insert(t, s));
assert!(self.named_types.insert(s, t));
}
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(&self, ty: &TypeRef) -> Option<@str> {
self.type_names.find_copy(ty)
}
pub fn find_type(&self, s: &str) -> Option<TypeRef> {
self.named_types.find_equiv(s).map_consume(|x| *x)
}
pub fn type_to_str(&self, ty: TypeRef) -> ~str {
match self.find_name(&ty) {
option::Some(name) => return name.to_owned(),
None => ()
}
let outer = vec::append_one(outer0.to_owned(), ty);
unsafe {
let kind = llvm::LLVMGetTypeKind(ty);
let kind = llvm::LLVMGetTypeKind(ty);
match kind {
Void => ~"Void",
Half => ~"Half",
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) as int)
}
Function => {
let out_ty = 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));
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();
}
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();
let args = args.map(|&ty| self.type_to_str(ty)).connect(", ");
let out_ty = self.type_to_str(out_ty);
fmt!("fn(%s) -> %s", args, out_ty)
}
Struct => {
let tys = struct_tys(ty);
let tys = tys.map(|ty| self.type_to_str(ty)).connect(", ");
fmt!("{%s}", tys)
}
Array => {
let el_ty = llvm::LLVMGetElementType(ty);
let el_ty = self.type_to_str(el_ty);
let len = llvm::LLVMGetArrayLength(ty) as uint;
fmt!("[%s x %u]", el_ty, len)
}
Pointer => {
let el_ty = llvm::LLVMGetElementType(ty);
let el_ty = self.type_to_str(el_ty);
fmt!("*%s", el_ty)
}
}
let addrstr = {
let addrspace = llvm::LLVMGetPointerAddressSpace(ty) as uint;
if addrspace == 0 {
~""
} else {
fmt!("addrspace(%u)", addrspace)
}
};
// 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!()
}
}
}

View File

@ -46,7 +46,7 @@ pub struct CrateContext {
llmod: ModuleRef,
llcx: ContextRef,
td: TargetData,
tn: @TypeNames,
tn: TypeNames,
externs: ExternMap,
intrinsics: HashMap<&'static str, ValueRef>,
item_vals: HashMap<ast::node_id, ValueRef>,
@ -136,8 +136,10 @@ impl CrateContext {
str::as_c_str(data_layout, |buf| llvm::LLVMSetDataLayout(llmod, buf));
str::as_c_str(targ_triple, |buf| llvm::LLVMSetTarget(llmod, buf));
let targ_cfg = sess.targ_cfg;
let td = mk_target_data(sess.targ_cfg.target_strs.data_layout);
let tn = mk_type_names();
let tn = TypeNames::new();
let mut intrinsics = base::declare_intrinsics(llmod);
if sess.opts.extra_debuginfo {
base::declare_dbg_intrinsics(llmod, &mut intrinsics);
@ -145,7 +147,7 @@ impl CrateContext {
let int_type = T_int(targ_cfg);
let float_type = T_float(targ_cfg);
let tydesc_type = T_tydesc(targ_cfg);
lib::llvm::associate_type(tn, @"tydesc", tydesc_type);
tn.associate_type(@"tydesc", tydesc_type);
let crate_map = decl_crate_map(sess, link_meta, llmod);
let dbg_cx = if sess.opts.debuginfo {
Some(debuginfo::DebugContext::new(llmod, name.to_owned()))