Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
6e909e38
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
6e909e38
编写于
4月 23, 2012
作者:
B
Brian Anderson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc: Use LLVM named structs for enum types
上级
929c3dd7
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
180 addition
and
95 deletion
+180
-95
src/rustc/middle/trans/base.rs
src/rustc/middle/trans/base.rs
+2
-1
src/rustc/middle/trans/type_of.rs
src/rustc/middle/trans/type_of.rs
+136
-75
src/rustc/middle/ty.rs
src/rustc/middle/ty.rs
+22
-0
src/rustc/util/ppaux.rs
src/rustc/util/ppaux.rs
+20
-19
未找到文件。
src/rustc/middle/trans/base.rs
浏览文件 @
6e909e38
...
...
@@ -2243,7 +2243,8 @@ fn trans_var(cx: block, def: ast::def, id: ast::node_id)-> lval_maybe_callee {
// Nullary variant.
let
enum_ty
=
node_id_type
(
cx
,
id
);
let
llenumblob
=
alloc_ty
(
cx
,
enum_ty
);
let
llenumty
=
type_of_enum
(
ccx
,
tid
,
enum_ty
);
// FIXME: This pointer cast probably isn't necessary
let
llenumty
=
type_of
(
ccx
,
enum_ty
);
let
llenumptr
=
PointerCast
(
cx
,
llenumblob
,
T_ptr
(
llenumty
));
let
lldiscrimptr
=
GEPi
(
cx
,
llenumptr
,
[
0
,
0
]);
let
lldiscrim_gv
=
lookup_discriminant
(
ccx
,
vid
);
...
...
src/rustc/middle/trans/type_of.rs
浏览文件 @
6e909e38
...
...
@@ -7,6 +7,11 @@
import
ty
::
*
;
export
type_of
;
export
type_of_explicit_args
;
export
type_of_fn_from_ty
;
export
type_of_fn
;
fn
type_of_explicit_args
(
cx
:
@
crate_ctxt
,
inputs
:
[
ty
::
arg
])
->
[
TypeRef
]
{
vec
::
map
(
inputs
)
{|
arg
|
let
arg_ty
=
arg
.ty
;
...
...
@@ -39,10 +44,22 @@ fn type_of_fn_from_ty(cx: @crate_ctxt, fty: ty::t) -> TypeRef {
fn
type_of
(
cx
:
@
crate_ctxt
,
t
:
ty
::
t
)
->
TypeRef
{
assert
!
ty
::
type_has_vars
(
t
);
// Check the cache.
#
debug
(
"type_of %?: %?"
,
t
,
ty
::
get
(
t
));
// Check the cache.
if
cx
.lltypes
.contains_key
(
t
)
{
ret
cx
.lltypes
.get
(
t
);
}
let
llty
=
alt
ty
::
get
(
t
)
.struct
{
// Replace any typedef'd types with their equivalent non-typedef
// type. This ensures that all LLVM nominal types that contain
// Rust types are defined as the same LLVM types. If we don't do
// this then, e.g. `option<{myfield: bool}>` would be a different
// type than `option<myrec>`.
let
t_norm
=
ty
::
normalize_ty
(
cx
.tcx
,
t
);
let
llty
=
if
t
!=
t_norm
{
type_of
(
cx
,
t_norm
)
}
else
{
alt
ty
::
get
(
t
)
.struct
{
ty
::
ty_nil
|
ty
::
ty_bot
{
T_nil
()
}
ty
::
ty_bool
{
T_bool
()
}
ty
::
ty_int
(
t
)
{
T_int_ty
(
cx
,
t
)
}
...
...
@@ -116,16 +133,60 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
ty
::
ty_self
(
_
)
{
cx
.tcx.sess
.unimpl
(
"type_of: ty_self
\
not implemented"
);
}
ty
::
ty_var
(
_
)
{
cx
.tcx.sess
.bug
(
"type_of shouldn't see a ty_var"
);
}
}
};
cx
.lltypes
.insert
(
t
,
llty
);
ret
llty
;
}
// This should only be called from type_of, above, because it
// creates new llvm named struct types lazily that are then
// cached by type_of
fn
type_of_enum
(
cx
:
@
crate_ctxt
,
did
:
ast
::
def_id
,
t
:
ty
::
t
)
->
TypeRef
{
#
debug
(
"type_of_enum %?: %?"
,
t
,
ty
::
get
(
t
));
// Every enum type has a unique name. When we find our roots
// for GC and unwinding we will use this name to rediscover
// the Rust type
let
name
=
llvm_type_name
(
cx
,
t
);
let
named_llty
=
common
::
T_named_struct
(
name
);
let
lltys
=
{
let
degen
=
(
*
ty
::
enum_variants
(
cx
.tcx
,
did
))
.len
()
==
1u
;
let
size
=
shape
::
static_size_of_enum
(
cx
,
t
);
if
!
degen
{
T_enum
(
cx
,
size
)
}
else
if
size
==
0u
{
T_struct
([
T_enum_variant
(
cx
)])
}
else
{
T_array
(
T_i8
(),
size
)
}
if
!
degen
{
[
T_enum_variant
(
cx
),
T_array
(
T_i8
(),
size
)]
}
else
if
size
==
0u
{
[
T_enum_variant
(
cx
)]
}
else
{
[
T_array
(
T_i8
(),
size
)]
}
};
common
::
set_struct_body
(
named_llty
,
lltys
);
ret
named_llty
;
}
fn
llvm_type_name
(
cx
:
@
crate_ctxt
,
t
:
ty
::
t
)
->
str
{
let
(
name
,
did
,
tps
)
=
alt
check
ty
::
get
(
t
)
.struct
{
ty
::
ty_enum
(
did
,
substs
)
{
(
"enum"
,
did
,
substs
.tps
)
}
};
ret
#
fmt
(
"%s %s[#%d]"
,
name
,
util
::
ppaux
::
parameterized
(
cx
.tcx
,
ty
::
item_path_str
(
cx
.tcx
,
did
),
none
,
tps
),
did
.crate
);
}
src/rustc/middle/ty.rs
浏览文件 @
6e909e38
...
...
@@ -149,6 +149,7 @@
export
atttce_unresolved
,
atttce_resolved
;
export
mach_sty
;
export
ty_sort_str
;
export
normalize_ty
;
// Data types
...
...
@@ -2674,6 +2675,27 @@ fn ty_params_to_tys(tcx: ty::ctxt, tps: [ast::ty_param]) -> [t] {
ty
::
mk_param
(
tcx
,
i
,
ast_util
::
local_def
(
tps
[
i
]
.id
))
})
}
#[doc
=
"
Returns an equivalent type with all the typedefs and self regions removed
"
]
fn
normalize_ty
(
cx
:
ctxt
,
t
:
t
)
->
t
{
let
t
=
alt
get
(
t
)
.struct
{
ty_enum
(
did
,
r
)
{
alt
r
.self_r
{
some
(
_
)
{
// This enum has a self region. Get rid of it
mk_enum
(
cx
,
did
,
{
self_r
:
none
,
tps
:
r
.tps
})
}
none
{
t
}
}
}
_
{
t
}
};
let
sty
=
fold_sty
(
get
(
t
)
.struct
)
{|
t
|
normalize_ty
(
cx
,
t
)
};
mk_t
(
cx
,
sty
)
}
// Local Variables:
// mode: rust
// fill-column: 78;
...
...
src/rustc/util/ppaux.rs
浏览文件 @
6e909e38
...
...
@@ -128,25 +128,6 @@ fn method_to_str(cx: ctxt, m: method) -> str {
fn
field_to_str
(
cx
:
ctxt
,
f
:
field
)
->
str
{
ret
f
.ident
+
": "
+
mt_to_str
(
cx
,
f
.mt
);
}
fn
parameterized
(
cx
:
ctxt
,
base
:
str
,
self_r
:
option
<
ty
::
region
>
,
tps
:
[
ty
::
t
])
->
str
{
let
r_str
=
alt
self_r
{
none
{
""
}
some
(
r
)
{
#
fmt
[
"/%s"
,
region_to_str
(
cx
,
r
)]
}
};
if
vec
::
len
(
tps
)
>
0u
{
let
strs
=
vec
::
map
(
tps
,
{|
t
|
ty_to_str
(
cx
,
t
)});
#
fmt
[
"%s%s<%s>"
,
base
,
r_str
,
str
::
connect
(
strs
,
","
)]
}
else
{
#
fmt
[
"%s%s"
,
base
,
r_str
]
}
}
// if there is an id, print that instead of the structural type:
alt
ty
::
type_def_id
(
typ
)
{
...
...
@@ -233,6 +214,26 @@ fn parameterized(cx: ctxt,
}
}
fn
parameterized
(
cx
:
ctxt
,
base
:
str
,
self_r
:
option
<
ty
::
region
>
,
tps
:
[
ty
::
t
])
->
str
{
let
r_str
=
alt
self_r
{
none
{
""
}
some
(
r
)
{
#
fmt
[
"/%s"
,
region_to_str
(
cx
,
r
)]
}
};
if
vec
::
len
(
tps
)
>
0u
{
let
strs
=
vec
::
map
(
tps
,
{|
t
|
ty_to_str
(
cx
,
t
)});
#
fmt
[
"%s%s<%s>"
,
base
,
r_str
,
str
::
connect
(
strs
,
","
)]
}
else
{
#
fmt
[
"%s%s"
,
base
,
r_str
]
}
}
fn
ty_to_short_str
(
cx
:
ctxt
,
typ
:
t
)
->
str
{
let
mut
s
=
encoder
::
encoded_ty
(
cx
,
typ
);
if
str
::
len
(
s
)
>=
32u
{
s
=
str
::
slice
(
s
,
0u
,
32u
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录