Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
b38e0d0d
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,发现更多精彩内容 >>
提交
b38e0d0d
编写于
5月 26, 2016
作者:
M
Michael Woerister
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Build SymbolMap for symbol name conflict checking and caching.
上级
87c1c87d
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
237 addition
and
54 deletion
+237
-54
src/librustc_trans/base.rs
src/librustc_trans/base.rs
+37
-8
src/librustc_trans/callee.rs
src/librustc_trans/callee.rs
+12
-4
src/librustc_trans/consts.rs
src/librustc_trans/consts.rs
+11
-6
src/librustc_trans/context.rs
src/librustc_trans/context.rs
+13
-3
src/librustc_trans/lib.rs
src/librustc_trans/lib.rs
+1
-0
src/librustc_trans/monomorphize.rs
src/librustc_trans/monomorphize.rs
+9
-4
src/librustc_trans/symbol_map.rs
src/librustc_trans/symbol_map.rs
+115
-0
src/librustc_trans/trans_item.rs
src/librustc_trans/trans_item.rs
+39
-29
未找到文件。
src/librustc_trans/base.rs
浏览文件 @
b38e0d0d
...
...
@@ -80,6 +80,7 @@
use
mir
;
use
monomorphize
::{
self
,
Instance
};
use
partitioning
::{
self
,
PartitioningStrategy
,
CodegenUnit
};
use
symbol_map
::
SymbolMap
;
use
symbol_names_test
;
use
trans_item
::
TransItem
;
use
tvec
;
...
...
@@ -97,6 +98,7 @@
use
std
::
ffi
::{
CStr
,
CString
};
use
std
::
cell
::{
Cell
,
RefCell
};
use
std
::
collections
::{
HashMap
,
HashSet
};
use
std
::
rc
::
Rc
;
use
std
::
str
;
use
std
::{
i8
,
i16
,
i32
,
i64
};
use
syntax_pos
::{
Span
,
DUMMY_SP
};
...
...
@@ -2588,14 +2590,18 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
};
let
no_builtins
=
attr
::
contains_name
(
&
krate
.attrs
,
"no_builtins"
);
let
codegen_units
=
collect_and_partition_translation_items
(
&
shared_ccx
);
let
(
codegen_units
,
symbol_map
)
=
collect_and_partition_translation_items
(
&
shared_ccx
);
let
codegen_unit_count
=
codegen_units
.len
();
assert
!
(
tcx
.sess.opts.cg.codegen_units
==
codegen_unit_count
||
tcx
.sess.opts.debugging_opts.incremental
.is_some
());
let
crate_context_list
=
CrateContextList
::
new
(
&
shared_ccx
,
codegen_units
);
let
symbol_map
=
Rc
::
new
(
symbol_map
);
let
crate_context_list
=
CrateContextList
::
new
(
&
shared_ccx
,
codegen_units
,
symbol_map
.clone
());
let
modules
=
crate_context_list
.iter
()
.map
(|
ccx
|
ModuleTranslation
{
name
:
String
::
from
(
&
ccx
.codegen_unit
()
.name
[
..
]),
...
...
@@ -2693,8 +2699,9 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let
sess
=
shared_ccx
.sess
();
let
mut
reachable_symbols
=
shared_ccx
.reachable
()
.iter
()
.map
(|
&
id
|
{
let
def_id
=
shared_ccx
.tcx
()
.map
.local_def_id
(
id
);
Instance
::
mono
(
&
shared_ccx
,
def_id
)
.symbol_name
(
&
shared_ccx
)
symbol_for_def_id
(
def_id
,
&
shared_ccx
,
&
symbol_map
)
})
.collect
::
<
Vec
<
_
>>
();
if
sess
.entry_fn
.borrow
()
.is_some
()
{
reachable_symbols
.push
(
"main"
.to_string
());
}
...
...
@@ -2716,7 +2723,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
reachable_symbols
.extend
(
syms
.into_iter
()
.filter
(|
did
|
{
sess
.cstore
.is_extern_item
(
shared_ccx
.tcx
(),
*
did
)
})
.map
(|
did
|
{
Instance
::
mono
(
&
shared_ccx
,
did
)
.symbol_name
(
&
shared_ccx
)
symbol_for_def_id
(
did
,
&
shared_ccx
,
&
symbol_map
)
}));
}
...
...
@@ -2810,7 +2817,7 @@ fn visit_item(&mut self, i: &hir::Item) {
}
fn
collect_and_partition_translation_items
<
'a
,
'tcx
>
(
scx
:
&
SharedCrateContext
<
'a
,
'tcx
>
)
->
Vec
<
CodegenUnit
<
'tcx
>>
{
->
(
Vec
<
CodegenUnit
<
'tcx
>>
,
SymbolMap
<
'tcx
>
)
{
let
time_passes
=
scx
.sess
()
.time_passes
();
let
collection_mode
=
match
scx
.sess
()
.opts.debugging_opts.print_trans_items
{
...
...
@@ -2833,10 +2840,13 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
None
=>
TransItemCollectionMode
::
Lazy
};
let
(
items
,
inlining_map
)
=
time
(
time_passes
,
"translation item collection"
,
||
{
collector
::
collect_crate_translation_items
(
&
scx
,
collection_mode
)
let
(
items
,
inlining_map
)
=
time
(
time_passes
,
"translation item collection"
,
||
{
collector
::
collect_crate_translation_items
(
&
scx
,
collection_mode
)
});
let
symbol_map
=
SymbolMap
::
build
(
scx
,
items
.iter
()
.cloned
());
let
strategy
=
if
scx
.sess
()
.opts.debugging_opts.incremental
.is_some
()
{
PartitioningStrategy
::
PerModule
}
else
{
...
...
@@ -2910,5 +2920,24 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a
}
}
codegen_units
(
codegen_units
,
symbol_map
)
}
fn
symbol_for_def_id
<
'a
,
'tcx
>
(
def_id
:
DefId
,
scx
:
&
SharedCrateContext
<
'a
,
'tcx
>
,
symbol_map
:
&
SymbolMap
<
'tcx
>
)
->
String
{
// Just try to look things up in the symbol map. If nothing's there, we
// recompute.
if
let
Some
(
node_id
)
=
scx
.tcx
()
.map
.as_local_node_id
(
def_id
)
{
if
let
Some
(
sym
)
=
symbol_map
.get
(
TransItem
::
Static
(
node_id
))
{
return
sym
.to_owned
();
}
}
let
instance
=
Instance
::
mono
(
scx
,
def_id
);
symbol_map
.get
(
TransItem
::
Fn
(
instance
))
.map
(
str
::
to_owned
)
.unwrap_or_else
(||
instance
.symbol_name
(
scx
))
}
src/librustc_trans/callee.rs
浏览文件 @
b38e0d0d
...
...
@@ -46,6 +46,7 @@
use
machine
::
llalign_of_min
;
use
meth
;
use
monomorphize
::{
self
,
Instance
};
use
trans_item
::
TransItem
;
use
type_
::
Type
;
use
type_of
;
use
value
::
Value
;
...
...
@@ -536,11 +537,18 @@ fn is_named_tuple_constructor(tcx: TyCtxt, def_id: DefId) -> bool {
// reference. It also occurs when testing libcore and in some
// other weird situations. Annoying.
let
sym
=
instance
.symbol_name
(
ccx
.shared
());
// Let's see if we can get the symbol name from the symbol_map, so we don't
// have to recompute it.
let
mut
sym_data
=
String
::
new
();
let
sym
=
ccx
.symbol_map
()
.get
(
TransItem
::
Fn
(
instance
))
.unwrap_or_else
(||
{
sym_data
=
instance
.symbol_name
(
ccx
.shared
());
&
sym_data
[
..
]
});
let
llptrty
=
type_of
::
type_of
(
ccx
,
fn_ptr_ty
);
let
llfn
=
if
let
Some
(
llfn
)
=
declare
::
get_declared_value
(
ccx
,
&
sym
)
{
let
llfn
=
if
let
Some
(
llfn
)
=
declare
::
get_declared_value
(
ccx
,
sym
)
{
if
let
Some
(
span
)
=
local_item
{
if
declare
::
get_defined_value
(
ccx
,
&
sym
)
.is_some
()
{
if
declare
::
get_defined_value
(
ccx
,
sym
)
.is_some
()
{
ccx
.sess
()
.span_fatal
(
span
,
&
format!
(
"symbol `{}` is already defined"
,
sym
));
}
...
...
@@ -558,7 +566,7 @@ fn is_named_tuple_constructor(tcx: TyCtxt, def_id: DefId) -> bool {
llfn
}
}
else
{
let
llfn
=
declare
::
declare_fn
(
ccx
,
&
sym
,
ty
);
let
llfn
=
declare
::
declare_fn
(
ccx
,
sym
,
ty
);
assert_eq!
(
common
::
val_ty
(
llfn
),
llptrty
);
debug!
(
"get_fn: not casting pointer!"
);
...
...
src/librustc_trans/consts.rs
浏览文件 @
b38e0d0d
...
...
@@ -1013,14 +1013,16 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
return
Datum
::
new
(
g
,
ty
,
Lvalue
::
new
(
"static"
));
}
let
sym
=
instance
.symbol_name
(
ccx
.shared
());
let
g
=
if
let
Some
(
id
)
=
ccx
.tcx
()
.map
.as_local_node_id
(
def_id
)
{
let
llty
=
type_of
::
type_of
(
ccx
,
ty
);
let
(
g
,
attrs
)
=
match
ccx
.tcx
()
.map
.get
(
id
)
{
hir_map
::
NodeItem
(
&
hir
::
Item
{
ref
attrs
,
span
,
node
:
hir
::
ItemStatic
(
..
),
..
})
=>
{
let
sym
=
ccx
.symbol_map
()
.get
(
TransItem
::
Static
(
id
))
.expect
(
"Local statics should always be in the SymbolMap"
);
// Make sure that this is never executed for something inlined.
assert
!
(
!
ccx
.external_srcs
()
.borrow
()
.contains_key
(
&
id
));
...
...
@@ -1028,16 +1030,16 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
.items
.contains_key
(
&
TransItem
::
Static
(
id
));
if
defined_in_current_codegen_unit
{
if
declare
::
get_declared_value
(
ccx
,
&
sym
)
.is_none
()
{
if
declare
::
get_declared_value
(
ccx
,
sym
)
.is_none
()
{
span_bug!
(
span
,
"trans: Static not properly pre-defined?"
);
}
}
else
{
if
declare
::
get_declared_value
(
ccx
,
&
sym
)
.is_some
()
{
if
declare
::
get_declared_value
(
ccx
,
sym
)
.is_some
()
{
span_bug!
(
span
,
"trans: Conflicting symbol names for static?"
);
}
}
let
g
=
declare
::
define_global
(
ccx
,
&
sym
,
llty
)
.unwrap
();
let
g
=
declare
::
define_global
(
ccx
,
sym
,
llty
)
.unwrap
();
(
g
,
attrs
)
}
...
...
@@ -1045,6 +1047,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
hir_map
::
NodeForeignItem
(
&
hir
::
ForeignItem
{
ref
attrs
,
span
,
node
:
hir
::
ForeignItemStatic
(
..
),
..
})
=>
{
let
sym
=
instance
.symbol_name
(
ccx
.shared
());
let
g
=
if
let
Some
(
name
)
=
attr
::
first_attr_value_str_by_name
(
&
attrs
,
"linkage"
)
{
// If this is a static with a linkage specified, then we need to handle
...
...
@@ -1079,7 +1082,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
real_name
.push_str
(
&
sym
);
let
g2
=
declare
::
define_global
(
ccx
,
&
real_name
,
llty
)
.unwrap_or_else
(||{
ccx
.sess
()
.span_fatal
(
span
,
&
format!
(
"symbol `{}` is already defined"
,
sym
))
&
format!
(
"symbol `{}` is already defined"
,
&
sym
))
});
llvm
::
SetLinkage
(
g2
,
llvm
::
InternalLinkage
);
llvm
::
LLVMSetInitializer
(
g2
,
g1
);
...
...
@@ -1104,6 +1107,8 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
g
}
else
{
let
sym
=
instance
.symbol_name
(
ccx
.shared
());
// FIXME(nagisa): perhaps the map of externs could be offloaded to llvm somehow?
// FIXME(nagisa): investigate whether it can be changed into define_global
let
g
=
declare
::
declare_global
(
ccx
,
&
sym
,
type_of
::
type_of
(
ccx
,
ty
));
...
...
src/librustc_trans/context.rs
浏览文件 @
b38e0d0d
...
...
@@ -35,6 +35,7 @@
use
rustc
::
ty
::{
self
,
Ty
,
TyCtxt
};
use
session
::
config
::
NoDebugInfo
;
use
session
::
Session
;
use
symbol_map
::
SymbolMap
;
use
util
::
sha2
::
Sha256
;
use
util
::
nodemap
::{
NodeMap
,
NodeSet
,
DefIdMap
,
FnvHashMap
};
...
...
@@ -171,6 +172,8 @@ pub struct LocalCrateContext<'tcx> {
/// Depth of the current type-of computation - used to bail out
type_of_depth
:
Cell
<
usize
>
,
symbol_map
:
Rc
<
SymbolMap
<
'tcx
>>
,
}
// Implement DepTrackingMapConfig for `trait_cache`
...
...
@@ -197,12 +200,13 @@ pub struct CrateContextList<'a, 'tcx: 'a> {
impl
<
'a
,
'tcx
:
'a
>
CrateContextList
<
'a
,
'tcx
>
{
pub
fn
new
(
shared_ccx
:
&
'a
SharedCrateContext
<
'a
,
'tcx
>
,
codegen_units
:
Vec
<
CodegenUnit
<
'tcx
>>
)
codegen_units
:
Vec
<
CodegenUnit
<
'tcx
>>
,
symbol_map
:
Rc
<
SymbolMap
<
'tcx
>>
)
->
CrateContextList
<
'a
,
'tcx
>
{
CrateContextList
{
shared
:
shared_ccx
,
local_ccxs
:
codegen_units
.into_iter
()
.map
(|
codegen_unit
|
{
LocalCrateContext
::
new
(
shared_ccx
,
codegen_unit
)
LocalCrateContext
::
new
(
shared_ccx
,
codegen_unit
,
symbol_map
.clone
()
)
})
.collect
()
}
}
...
...
@@ -512,7 +516,8 @@ pub fn metadata_symbol_name(&self) -> String {
impl
<
'tcx
>
LocalCrateContext
<
'tcx
>
{
fn
new
<
'a
>
(
shared
:
&
SharedCrateContext
<
'a
,
'tcx
>
,
codegen_unit
:
CodegenUnit
<
'tcx
>
)
codegen_unit
:
CodegenUnit
<
'tcx
>
,
symbol_map
:
Rc
<
SymbolMap
<
'tcx
>>
)
->
LocalCrateContext
<
'tcx
>
{
unsafe
{
// Append ".rs" to LLVM module identifier.
...
...
@@ -571,6 +576,7 @@ fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>,
intrinsics
:
RefCell
::
new
(
FnvHashMap
()),
n_llvm_insns
:
Cell
::
new
(
0
),
type_of_depth
:
Cell
::
new
(
0
),
symbol_map
:
symbol_map
,
};
let
(
int_type
,
opaque_vec_type
,
str_slice_ty
,
mut
local_ccx
)
=
{
...
...
@@ -890,6 +896,10 @@ pub fn get_mir(&self, def_id: DefId) -> Option<CachedMir<'b, 'tcx>> {
self
.shared
.get_mir
(
def_id
)
}
pub
fn
symbol_map
(
&
self
)
->
&
SymbolMap
<
'tcx
>
{
&*
self
.local
()
.symbol_map
}
pub
fn
translation_items
(
&
self
)
->
&
RefCell
<
FnvHashMap
<
TransItem
<
'tcx
>
,
TransItemState
>>
{
&
self
.shared.translation_items
}
...
...
src/librustc_trans/lib.rs
浏览文件 @
b38e0d0d
...
...
@@ -122,6 +122,7 @@ pub mod back {
mod
mir
;
mod
monomorphize
;
mod
partitioning
;
mod
symbol_map
;
mod
symbol_names_test
;
mod
trans_item
;
mod
tvec
;
...
...
src/librustc_trans/monomorphize.rs
浏览文件 @
b38e0d0d
...
...
@@ -84,19 +84,24 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
monomorphizing
.insert
(
fn_id
,
depth
+
1
);
}
let
symbol
=
instance
.symbol_name
(
ccx
.shared
());
// Let's see if we can get the symbol name from the symbol_map, so we don't
// have to recompute it.
let
mut
sym_data
=
String
::
new
();
let
symbol
=
ccx
.symbol_map
()
.get
(
TransItem
::
Fn
(
instance
))
.unwrap_or_else
(||
{
sym_data
=
instance
.symbol_name
(
ccx
.shared
());
&
sym_data
[
..
]
});
debug!
(
"monomorphize_fn mangled to {}"
,
symbol
);
assert
!
(
declare
::
get_defined_value
(
ccx
,
&
symbol
)
.is_none
());
assert
!
(
declare
::
get_defined_value
(
ccx
,
symbol
)
.is_none
());
// FIXME(nagisa): perhaps needs a more fine grained selection?
let
lldecl
=
declare
::
define_internal_fn
(
ccx
,
&
symbol
,
mono_ty
);
let
lldecl
=
declare
::
define_internal_fn
(
ccx
,
symbol
,
mono_ty
);
// FIXME(eddyb) Doubt all extern fn should allow unwinding.
attributes
::
unwind
(
lldecl
,
true
);
ccx
.instances
()
.borrow_mut
()
.insert
(
instance
,
lldecl
);
// we can only monomorphize things in this crate (or inlined into it)
let
fn_node_id
=
ccx
.tcx
()
.map
.as_local_node_id
(
fn_id
)
.unwrap
();
let
map_node
=
errors
::
expect
(
...
...
src/librustc_trans/symbol_map.rs
0 → 100644
浏览文件 @
b38e0d0d
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use
context
::
SharedCrateContext
;
use
monomorphize
::
Instance
;
use
rustc
::
ty
::
TyCtxt
;
use
syntax
::
codemap
::
Span
;
use
trans_item
::
TransItem
;
use
util
::
nodemap
::
FnvHashMap
;
// In the SymbolMap we collect the symbol names of all translation items of
// the current crate.
pub
struct
SymbolMap
<
'tcx
>
{
index
:
FnvHashMap
<
TransItem
<
'tcx
>
,
(
usize
,
usize
)
>
,
arena
:
String
,
}
impl
<
'tcx
>
SymbolMap
<
'tcx
>
{
pub
fn
build
<
'a
,
I
>
(
scx
:
&
SharedCrateContext
<
'a
,
'tcx
>
,
trans_items
:
I
)
->
SymbolMap
<
'tcx
>
where
I
:
Iterator
<
Item
=
TransItem
<
'tcx
>>
{
// Check for duplicate symbol names
let
mut
symbols
:
Vec
<
_
>
=
trans_items
.map
(|
trans_item
|
{
(
trans_item
,
trans_item
.compute_symbol_name
(
scx
))
})
.collect
();
(
&
mut
symbols
[
..
])
.sort_by
(|
&
(
_
,
ref
sym1
),
&
(
_
,
ref
sym2
)|{
sym1
.cmp
(
sym2
)
});
for
pair
in
(
&
symbols
[
..
])
.windows
(
2
)
{
let
sym1
=
&
pair
[
0
]
.1
;
let
sym2
=
&
pair
[
1
]
.1
;
if
*
sym1
==
*
sym2
{
let
trans_item1
=
pair
[
0
]
.0
;
let
trans_item2
=
pair
[
1
]
.0
;
let
span1
=
get_span
(
scx
.tcx
(),
trans_item1
);
let
span2
=
get_span
(
scx
.tcx
(),
trans_item2
);
// Deterministically select one of the spans for error reporting
let
span
=
match
(
span1
,
span2
)
{
(
Some
(
span1
),
Some
(
span2
))
=>
{
Some
(
if
span1
.lo
.0
>
span2
.lo
.0
{
span1
}
else
{
span2
})
}
(
Some
(
span
),
None
)
|
(
None
,
Some
(
span
))
=>
Some
(
span
),
_
=>
None
};
let
error_message
=
format!
(
"symbol `{}` is already defined"
,
sym1
);
if
let
Some
(
span
)
=
span
{
scx
.sess
()
.span_fatal
(
span
,
&
error_message
)
}
else
{
scx
.sess
()
.fatal
(
&
error_message
)
}
}
}
let
mut
symbol_map
=
SymbolMap
{
index
:
FnvHashMap
(),
arena
:
String
::
with_capacity
(
1024
),
};
for
(
trans_item
,
symbol
)
in
symbols
{
let
start_index
=
symbol_map
.arena
.len
();
symbol_map
.arena
.push_str
(
&
symbol
[
..
]);
let
end_index
=
symbol_map
.arena
.len
();
let
prev_entry
=
symbol_map
.index
.insert
(
trans_item
,
(
start_index
,
end_index
));
if
prev_entry
.is_some
()
{
bug!
(
"TransItem encountered twice?"
)
}
}
fn
get_span
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
trans_item
:
TransItem
<
'tcx
>
)
->
Option
<
Span
>
{
match
trans_item
{
TransItem
::
Fn
(
Instance
{
def
,
..
})
=>
{
tcx
.map
.as_local_node_id
(
def
)
}
TransItem
::
Static
(
node_id
)
=>
Some
(
node_id
),
TransItem
::
DropGlue
(
_
)
=>
None
,
}
.map
(|
node_id
|
{
tcx
.map
.span
(
node_id
)
})
}
symbol_map
}
pub
fn
get
(
&
self
,
trans_item
:
TransItem
<
'tcx
>
)
->
Option
<&
str
>
{
self
.index
.get
(
&
trans_item
)
.map
(|
&
(
start_index
,
end_index
)|
{
&
self
.arena
[
start_index
..
end_index
]
})
}
}
src/librustc_trans/trans_item.rs
浏览文件 @
b38e0d0d
...
...
@@ -17,7 +17,7 @@
use
attributes
;
use
base
;
use
consts
;
use
context
::
CrateContext
;
use
context
::
{
CrateContext
,
SharedCrateContext
}
;
use
declare
;
use
glue
::
DropGlueKind
;
use
llvm
;
...
...
@@ -64,7 +64,6 @@ fn hash<H: Hasher>(&self, s: &mut H) {
}
}
impl
<
'a
,
'tcx
>
TransItem
<
'tcx
>
{
pub
fn
define
(
&
self
,
ccx
:
&
CrateContext
<
'a
,
'tcx
>
)
{
...
...
@@ -108,15 +107,20 @@ pub fn predefine(&self,
self
.to_raw_string
(),
ccx
.codegen_unit
()
.name
);
let
symbol_name
=
ccx
.symbol_map
()
.get
(
*
self
)
.expect
(
"Name not present in SymbolMap?"
);
debug!
(
"symbol {}"
,
symbol_name
);
match
*
self
{
TransItem
::
Static
(
node_id
)
=>
{
TransItem
::
predefine_static
(
ccx
,
node_id
,
linkage
);
TransItem
::
predefine_static
(
ccx
,
node_id
,
linkage
,
symbol_name
);
}
TransItem
::
Fn
(
instance
)
=>
{
TransItem
::
predefine_fn
(
ccx
,
instance
,
linkage
);
TransItem
::
predefine_fn
(
ccx
,
instance
,
linkage
,
symbol_name
);
}
TransItem
::
DropGlue
(
dg
)
=>
{
TransItem
::
predefine_drop_glue
(
ccx
,
dg
,
linkage
);
TransItem
::
predefine_drop_glue
(
ccx
,
dg
,
linkage
,
symbol_name
);
}
}
...
...
@@ -128,7 +132,8 @@ pub fn predefine(&self,
fn
predefine_static
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
node_id
:
ast
::
NodeId
,
linkage
:
llvm
::
Linkage
)
{
linkage
:
llvm
::
Linkage
,
symbol_name
:
&
str
)
{
let
def_id
=
ccx
.tcx
()
.map
.local_def_id
(
node_id
);
let
ty
=
ccx
.tcx
()
.lookup_item_type
(
def_id
)
.ty
;
let
llty
=
type_of
::
type_of
(
ccx
,
ty
);
...
...
@@ -137,13 +142,9 @@ fn predefine_static(ccx: &CrateContext<'a, 'tcx>,
hir
::
map
::
NodeItem
(
&
hir
::
Item
{
span
,
node
:
hir
::
ItemStatic
(
..
),
..
})
=>
{
let
instance
=
Instance
::
mono
(
ccx
.shared
(),
def_id
);
let
sym
=
instance
.symbol_name
(
ccx
.shared
());
debug!
(
"symbol {}"
,
sym
);
let
g
=
declare
::
define_global
(
ccx
,
&
sym
,
llty
)
.unwrap_or_else
(||
{
let
g
=
declare
::
define_global
(
ccx
,
symbol_name
,
llty
)
.unwrap_or_else
(||
{
ccx
.sess
()
.span_fatal
(
span
,
&
format!
(
"symbol `{}` is already defined"
,
sym
))
&
format!
(
"symbol `{}` is already defined"
,
sym
bol_name
))
});
llvm
::
SetLinkage
(
g
,
linkage
);
...
...
@@ -155,7 +156,8 @@ fn predefine_static(ccx: &CrateContext<'a, 'tcx>,
fn
predefine_fn
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
instance
:
Instance
<
'tcx
>
,
linkage
:
llvm
::
Linkage
)
{
linkage
:
llvm
::
Linkage
,
symbol_name
:
&
str
)
{
assert
!
(
!
instance
.substs.types
.needs_infer
()
&&
!
instance
.substs.types
.has_param_types
());
...
...
@@ -186,10 +188,7 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
hir_map
::
NodeImplItem
(
&
hir
::
ImplItem
{
ref
attrs
,
node
:
hir
::
ImplItemKind
::
Method
(
..
),
..
})
=>
{
let
symbol
=
instance
.symbol_name
(
ccx
.shared
());
debug!
(
"symbol {}"
,
symbol
);
let
lldecl
=
declare
::
declare_fn
(
ccx
,
&
symbol
,
mono_ty
);
let
lldecl
=
declare
::
declare_fn
(
ccx
,
symbol_name
,
mono_ty
);
llvm
::
SetLinkage
(
lldecl
,
linkage
);
attributes
::
from_fn_attrs
(
ccx
,
attrs
,
lldecl
);
base
::
set_link_section
(
ccx
,
lldecl
,
attrs
);
...
...
@@ -203,7 +202,8 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
fn
predefine_drop_glue
(
ccx
:
&
CrateContext
<
'a
,
'tcx
>
,
dg
:
glue
::
DropGlueKind
<
'tcx
>
,
linkage
:
llvm
::
Linkage
)
{
linkage
:
llvm
::
Linkage
,
symbol_name
:
&
str
)
{
let
tcx
=
ccx
.tcx
();
assert_eq!
(
dg
.ty
(),
glue
::
get_drop_glue_type
(
tcx
,
dg
.ty
()));
let
t
=
dg
.ty
();
...
...
@@ -220,21 +220,31 @@ fn predefine_drop_glue(ccx: &CrateContext<'a, 'tcx>,
fn_ty
.args
[
0
]
.original_ty
=
type_of
::
type_of
(
ccx
,
t
)
.ptr_to
();
let
llfnty
=
fn_ty
.llvm_type
(
ccx
);
let
prefix
=
match
dg
{
DropGlueKind
::
Ty
(
_
)
=>
"drop"
,
DropGlueKind
::
TyContents
(
_
)
=>
"drop_contents"
,
};
let
symbol
=
symbol_names
::
exported_name_from_type_and_prefix
(
ccx
.shared
(),
t
,
prefix
);
debug!
(
" symbol: {}"
,
symbol
);
assert
!
(
declare
::
get_defined_value
(
ccx
,
&
symbol
)
.is_none
());
let
llfn
=
declare
::
declare_cfn
(
ccx
,
&
symbol
,
llfnty
);
assert
!
(
declare
::
get_defined_value
(
ccx
,
symbol_name
)
.is_none
());
let
llfn
=
declare
::
declare_cfn
(
ccx
,
symbol_name
,
llfnty
);
llvm
::
SetLinkage
(
llfn
,
linkage
);
attributes
::
set_frame_pointer_elimination
(
ccx
,
llfn
);
llvm
::
SetLinkage
(
llfn
,
linkage
);
ccx
.drop_glues
()
.borrow_mut
()
.insert
(
dg
,
(
llfn
,
fn_ty
));
}
pub
fn
compute_symbol_name
(
&
self
,
scx
:
&
SharedCrateContext
<
'a
,
'tcx
>
)
->
String
{
match
*
self
{
TransItem
::
Fn
(
instance
)
=>
instance
.symbol_name
(
scx
),
TransItem
::
Static
(
node_id
)
=>
{
let
def_id
=
scx
.tcx
()
.map
.local_def_id
(
node_id
);
Instance
::
mono
(
scx
,
def_id
)
.symbol_name
(
scx
)
}
TransItem
::
DropGlue
(
dg
)
=>
{
let
prefix
=
match
dg
{
DropGlueKind
::
Ty
(
_
)
=>
"drop"
,
DropGlueKind
::
TyContents
(
_
)
=>
"drop_contents"
,
};
symbol_names
::
exported_name_from_type_and_prefix
(
scx
,
dg
.ty
(),
prefix
)
}
}
}
pub
fn
requests_inline
(
&
self
,
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
)
->
bool
{
match
*
self
{
TransItem
::
Fn
(
ref
instance
)
=>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录