Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
33d5da1e
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,发现更多精彩内容 >>
提交
33d5da1e
编写于
2月 23, 2018
作者:
M
Michael Woerister
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Clean up handling of symbol export information.
上级
e5ee0114
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
231 addition
and
209 deletion
+231
-209
src/librustc/middle/cstore.rs
src/librustc/middle/cstore.rs
+2
-5
src/librustc/ty/context.rs
src/librustc/ty/context.rs
+3
-3
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/cstore_impl.rs
+3
-4
src/librustc_metadata/encoder.rs
src/librustc_metadata/encoder.rs
+9
-10
src/librustc_trans/back/symbol_export.rs
src/librustc_trans/back/symbol_export.rs
+207
-124
src/librustc_trans/base.rs
src/librustc_trans/base.rs
+5
-7
src/librustc_trans_utils/lib.rs
src/librustc_trans_utils/lib.rs
+1
-54
src/librustc_trans_utils/trans_crate.rs
src/librustc_trans_utils/trans_crate.rs
+1
-2
未找到文件。
src/librustc/middle/cstore.rs
浏览文件 @
33d5da1e
...
...
@@ -32,7 +32,6 @@
use
ty
::{
self
,
TyCtxt
};
use
session
::{
Session
,
CrateDisambiguator
};
use
session
::
search_paths
::
PathKind
;
use
util
::
nodemap
::
NodeSet
;
use
std
::
any
::
Any
;
use
std
::
collections
::
BTreeMap
;
...
...
@@ -258,8 +257,7 @@ pub trait CrateStore {
// utility functions
fn
encode_metadata
<
'a
,
'tcx
>
(
&
self
,
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
link_meta
:
&
LinkMeta
,
reachable
:
&
NodeSet
)
link_meta
:
&
LinkMeta
)
->
EncodedMetadata
;
fn
metadata_encoding_version
(
&
self
)
->
&
[
u8
];
}
...
...
@@ -342,8 +340,7 @@ fn crates_untracked(&self) -> Vec<CrateNum> { vec![] }
fn
extern_mod_stmt_cnum_untracked
(
&
self
,
emod_id
:
ast
::
NodeId
)
->
Option
<
CrateNum
>
{
None
}
fn
encode_metadata
<
'a
,
'tcx
>
(
&
self
,
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
link_meta
:
&
LinkMeta
,
reachable
:
&
NodeSet
)
link_meta
:
&
LinkMeta
)
->
EncodedMetadata
{
bug!
(
"encode_metadata"
)
}
...
...
src/librustc/ty/context.rs
浏览文件 @
33d5da1e
...
...
@@ -46,7 +46,7 @@
use
ty
::
maps
;
use
ty
::
steal
::
Steal
;
use
ty
::
BindingMode
;
use
util
::
nodemap
::{
NodeMap
,
NodeSet
,
DefIdSet
,
ItemLocalMap
};
use
util
::
nodemap
::{
NodeMap
,
DefIdSet
,
ItemLocalMap
};
use
util
::
nodemap
::{
FxHashMap
,
FxHashSet
};
use
rustc_data_structures
::
accumulate_vec
::
AccumulateVec
;
use
rustc_data_structures
::
stable_hasher
::{
HashStable
,
hash_stable_hashmap
,
...
...
@@ -1417,10 +1417,10 @@ pub fn emit_end_regions(self) -> bool {
}
impl
<
'a
,
'tcx
>
TyCtxt
<
'a
,
'tcx
,
'tcx
>
{
pub
fn
encode_metadata
(
self
,
link_meta
:
&
LinkMeta
,
reachable
:
&
NodeSet
)
pub
fn
encode_metadata
(
self
,
link_meta
:
&
LinkMeta
)
->
EncodedMetadata
{
self
.cstore
.encode_metadata
(
self
,
link_meta
,
reachable
)
self
.cstore
.encode_metadata
(
self
,
link_meta
)
}
}
...
...
src/librustc_metadata/cstore_impl.rs
浏览文件 @
33d5da1e
...
...
@@ -27,7 +27,7 @@
use
rustc
::
hir
::
map
::{
DefKey
,
DefPath
,
DefPathHash
};
use
rustc
::
hir
::
map
::
blocks
::
FnLikeNode
;
use
rustc
::
hir
::
map
::
definitions
::
DefPathTable
;
use
rustc
::
util
::
nodemap
::
{
NodeSet
,
DefIdMap
}
;
use
rustc
::
util
::
nodemap
::
DefIdMap
;
use
std
::
any
::
Any
;
use
rustc_data_structures
::
sync
::
Lrc
;
...
...
@@ -517,11 +517,10 @@ fn postorder_cnums_untracked(&self) -> Vec<CrateNum> {
fn
encode_metadata
<
'a
,
'tcx
>
(
&
self
,
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
link_meta
:
&
LinkMeta
,
reachable
:
&
NodeSet
)
link_meta
:
&
LinkMeta
)
->
EncodedMetadata
{
encoder
::
encode_metadata
(
tcx
,
link_meta
,
reachable
)
encoder
::
encode_metadata
(
tcx
,
link_meta
)
}
fn
metadata_encoding_version
(
&
self
)
->
&
[
u8
]
...
...
src/librustc_metadata/encoder.rs
浏览文件 @
33d5da1e
...
...
@@ -27,7 +27,7 @@
use
rustc
::
ty
::
codec
::{
self
as
ty_codec
,
TyEncoder
};
use
rustc
::
session
::
config
::{
self
,
CrateTypeProcMacro
};
use
rustc
::
util
::
nodemap
::{
FxHashMap
,
Node
Set
};
use
rustc
::
util
::
nodemap
::{
FxHashMap
,
DefId
Set
};
use
rustc_data_structures
::
stable_hasher
::
StableHasher
;
use
rustc_serialize
::{
Encodable
,
Encoder
,
SpecializedEncoder
,
opaque
};
...
...
@@ -53,7 +53,6 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
opaque
:
opaque
::
Encoder
<
'a
>
,
pub
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
link_meta
:
&
'a
LinkMeta
,
reachable_non_generics
:
&
'a
NodeSet
,
lazy_state
:
LazyState
,
type_shorthands
:
FxHashMap
<
Ty
<
'tcx
>
,
usize
>
,
...
...
@@ -395,9 +394,10 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
// Encode exported symbols info.
i
=
self
.position
();
let
reachable_non_generics
=
self
.tcx
.reachable_non_generics
(
LOCAL_CRATE
);
let
reachable_non_generics
=
self
.tracked
(
IsolatedEncoder
::
encode_reachable_non_generics
,
self
.
reachable_non_generics
);
&
reachable_non_generics
);
let
reachable_non_generics_bytes
=
self
.position
()
-
i
;
// Encode and index the items.
...
...
@@ -1389,11 +1389,12 @@ fn encode_impls(&mut self, _: ()) -> LazySeq<TraitImpls> {
// symbol associated with them (they weren't translated) or if they're an FFI
// definition (as that's not defined in this crate).
fn
encode_reachable_non_generics
(
&
mut
self
,
reachable_non_generics
:
&
Node
Set
)
reachable_non_generics
:
&
DefId
Set
)
->
LazySeq
<
DefIndex
>
{
let
tcx
=
self
.tcx
;
self
.lazy_seq
(
reachable_non_generics
.iter
()
.map
(|
&
id
|
tcx
.hir
.local_def_id
(
id
)
.index
))
self
.lazy_seq
(
reachable_non_generics
.iter
()
.map
(|
def_id
|
{
debug_assert!
(
def_id
.is_local
());
def_id
.index
}))
}
fn
encode_dylib_dependency_formats
(
&
mut
self
,
_
:
())
->
LazySeq
<
Option
<
LinkagePreference
>>
{
...
...
@@ -1666,8 +1667,7 @@ fn visit_impl_item(&mut self, _impl_item: &'v hir::ImplItem) {
// generated regardless of trailing bytes that end up in it.
pub
fn
encode_metadata
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
link_meta
:
&
LinkMeta
,
reachable_non_generics
:
&
NodeSet
)
link_meta
:
&
LinkMeta
)
->
EncodedMetadata
{
let
mut
cursor
=
Cursor
::
new
(
vec!
[]);
...
...
@@ -1681,7 +1681,6 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
opaque
:
opaque
::
Encoder
::
new
(
&
mut
cursor
),
tcx
,
link_meta
,
reachable_non_generics
,
lazy_state
:
LazyState
::
NoNode
,
type_shorthands
:
Default
::
default
(),
predicate_shorthands
:
Default
::
default
(),
...
...
src/librustc_trans/back/symbol_export.rs
浏览文件 @
33d5da1e
...
...
@@ -11,15 +11,15 @@
use
rustc_data_structures
::
sync
::
Lrc
;
use
std
::
sync
::
Arc
;
use
base
;
use
monomorphize
::
Instance
;
use
rustc
::
hir
;
use
rustc
::
hir
::
def_id
::
CrateNum
;
use
rustc
::
hir
::
def_id
::{
DefId
,
LOCAL_CRATE
};
use
rustc
::
middle
::
exported_symbols
::
SymbolExportLevel
;
use
rustc
::
session
::
config
;
use
rustc
::
ty
::
TyCtxt
;
use
rustc
::
ty
::
maps
::
Providers
;
use
rustc
::
util
::
nodemap
::
FxHashMap
;
use
rustc
::
util
::
nodemap
::
{
FxHashMap
,
DefIdSet
}
;
use
rustc_allocator
::
ALLOCATOR_METHODS
;
use
syntax
::
attr
;
...
...
@@ -60,145 +60,228 @@ pub fn crates_export_threshold(crate_types: &[config::CrateType])
}
}
pub
fn
provide
(
providers
:
&
mut
Providers
)
{
providers
.reachable_non_generics
=
|
tcx
,
cnum
|
{
let
export_threshold
=
threshold
(
tcx
);
Lrc
::
new
(
tcx
.exported_symbols
(
cnum
)
.iter
()
.filter_map
(|
&
(
_
,
id
,
level
)|
{
id
.and_then
(|
id
|
{
if
level
.is_below_threshold
(
export_threshold
)
{
Some
(
id
)
fn
reachable_non_generics_provider
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
cnum
:
CrateNum
)
->
Lrc
<
DefIdSet
>
{
assert_eq!
(
cnum
,
LOCAL_CRATE
);
if
!
tcx
.sess.opts.output_types
.should_trans
()
{
return
Lrc
::
new
(
DefIdSet
())
}
let
export_threshold
=
threshold
(
tcx
);
// We already collect all potentially reachable non-generic items for
// `exported_symbols`. Now we just filter them down to what is actually
// exported for the given crate we are compiling.
let
reachable_non_generics
=
tcx
.exported_symbols
(
LOCAL_CRATE
)
.iter
()
.filter_map
(|
&
(
_
,
opt_def_id
,
level
)|
{
if
let
Some
(
def_id
)
=
opt_def_id
{
if
level
.is_below_threshold
(
export_threshold
)
{
return
Some
(
def_id
)
}
}
None
})
.collect
();
Lrc
::
new
(
reachable_non_generics
)
}
fn
is_reachable_non_generic_provider
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
def_id
:
DefId
)
->
bool
{
tcx
.reachable_non_generics
(
def_id
.krate
)
.contains
(
&
def_id
)
}
fn
exported_symbols_provider_local
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
cnum
:
CrateNum
)
->
Arc
<
Vec
<
(
String
,
Option
<
DefId
>
,
SymbolExportLevel
)
>>
{
assert_eq!
(
cnum
,
LOCAL_CRATE
);
if
!
tcx
.sess.opts.output_types
.should_trans
()
{
return
Arc
::
new
(
vec!
[])
}
let
mut
reachable_non_generics
:
DefIdSet
=
tcx
.reachable_set
(
LOCAL_CRATE
)
.0
.iter
()
.filter_map
(|
&
node_id
|
{
// We want to ignore some FFI functions that are not exposed from
// this crate. Reachable FFI functions can be lumped into two
// categories:
//
// 1. Those that are included statically via a static library
// 2. Those included otherwise (e.g. dynamically or via a framework)
//
// Although our LLVM module is not literally emitting code for the
// statically included symbols, it's an export of our library which
// needs to be passed on to the linker and encoded in the metadata.
//
// As a result, if this id is an FFI item (foreign item) then we only
// let it through if it's included statically.
match
tcx
.hir
.get
(
node_id
)
{
hir
::
map
::
NodeForeignItem
(
..
)
=>
{
let
def_id
=
tcx
.hir
.local_def_id
(
node_id
);
if
tcx
.is_statically_included_foreign_item
(
def_id
)
{
Some
(
def_id
)
}
else
{
None
}
})
})
.collect
())
};
providers
.is_reachable_non_generic
=
|
tcx
,
id
|
{
tcx
.reachable_non_generics
(
id
.krate
)
.contains
(
&
id
)
};
providers
.exported_symbols
=
|
tcx
,
cnum
|
{
assert_eq!
(
cnum
,
LOCAL_CRATE
);
let
local_exported_symbols
=
base
::
find_exported_symbols
(
tcx
);
let
mut
local_crate
:
Vec
<
_
>
=
local_exported_symbols
.iter
()
.map
(|
&
node_id
|
{
tcx
.hir
.local_def_id
(
node_id
)
})
.map
(|
def_id
|
{
let
name
=
tcx
.symbol_name
(
Instance
::
mono
(
tcx
,
def_id
));
let
export_level
=
export_level
(
tcx
,
def_id
);
debug!
(
"EXPORTED SYMBOL (local): {} ({:?})"
,
name
,
export_level
);
(
str
::
to_owned
(
&
name
),
Some
(
def_id
),
export_level
)
})
.collect
();
if
let
Some
(
_
)
=
*
tcx
.sess.entry_fn
.borrow
()
{
local_crate
.push
((
"main"
.to_string
(),
None
,
SymbolExportLevel
::
C
));
}
}
if
tcx
.sess.allocator_kind
.get
()
.is_some
()
{
for
method
in
ALLOCATOR_METHODS
{
local_crate
.push
((
format!
(
"__rust_{}"
,
method
.name
),
None
,
SymbolExportLevel
::
Rust
));
// Only consider nodes that actually have exported symbols.
hir
::
map
::
NodeItem
(
&
hir
::
Item
{
node
:
hir
::
ItemStatic
(
..
),
..
})
|
hir
::
map
::
NodeItem
(
&
hir
::
Item
{
node
:
hir
::
ItemFn
(
..
),
..
})
|
hir
::
map
::
NodeImplItem
(
&
hir
::
ImplItem
{
node
:
hir
::
ImplItemKind
::
Method
(
..
),
..
})
=>
{
let
def_id
=
tcx
.hir
.local_def_id
(
node_id
);
let
generics
=
tcx
.generics_of
(
def_id
);
if
(
generics
.parent_types
==
0
&&
generics
.types
.is_empty
())
&&
// Functions marked with #[inline] are only ever translated
// with "internal" linkage and are never exported.
!
Instance
::
mono
(
tcx
,
def_id
)
.def
.requires_local
(
tcx
)
{
Some
(
def_id
)
}
else
{
None
}
}
_
=>
None
}
}
})
.collect
();
if
let
Some
(
id
)
=
tcx
.sess.derive_registrar_fn
.get
()
{
let
def_id
=
tcx
.hir
.local_def_id
(
id
);
let
disambiguator
=
tcx
.sess
.local_crate_disambiguator
();
let
registrar
=
tcx
.sess
.generate_derive_registrar_symbol
(
disambiguator
);
local_crate
.push
((
registrar
,
Some
(
def_id
),
SymbolExportLevel
::
C
));
}
if
let
Some
(
id
)
=
tcx
.sess.derive_registrar_fn
.get
()
{
reachable_non_generics
.insert
(
tcx
.hir
.local_def_id
(
id
));
}
if
let
Some
(
id
)
=
tcx
.sess.plugin_registrar_fn
.get
()
{
reachable_non_generics
.insert
(
tcx
.hir
.local_def_id
(
id
));
}
let
mut
symbols
:
Vec
<
_
>
=
reachable_non_generics
.iter
()
.map
(|
&
def_id
|
{
let
name
=
tcx
.symbol_name
(
Instance
::
mono
(
tcx
,
def_id
));
let
export_level
=
tcx
.symbol_export_level
(
def_id
);
debug!
(
"EXPORTED SYMBOL (local): {} ({:?})"
,
name
,
export_level
);
(
str
::
to_owned
(
&
name
),
Some
(
def_id
),
export_level
)
})
.collect
();
if
let
Some
(
_
)
=
*
tcx
.sess.entry_fn
.borrow
()
{
symbols
.push
((
"main"
.to_string
(),
None
,
SymbolExportLevel
::
C
));
}
if
tcx
.sess.crate_types
.borrow
()
.contains
(
&
config
::
CrateTypeDylib
)
{
local_crate
.push
((
metadata_symbol_name
(
tcx
),
None
,
SymbolExportLevel
::
Rust
));
if
tcx
.sess.allocator_kind
.get
()
.is_some
()
{
for
method
in
ALLOCATOR_METHODS
{
symbols
.push
((
format!
(
"__rust_{}"
,
method
.name
),
None
,
SymbolExportLevel
::
Rust
));
}
}
// Sort so we get a stable incr. comp. hash.
local_crate
.sort_unstable_by
(|
&
(
ref
name1
,
..
),
&
(
ref
name2
,
..
)|
{
name1
.cmp
(
name2
)
});
if
tcx
.sess.crate_types
.borrow
()
.contains
(
&
config
::
CrateTypeDylib
)
{
symbols
.push
((
metadata_symbol_name
(
tcx
),
None
,
SymbolExportLevel
::
Rust
));
}
Arc
::
new
(
local_crate
)
};
// Sort so we get a stable incr. comp. hash.
symbols
.sort_unstable_by
(|
&
(
ref
name1
,
..
),
&
(
ref
name2
,
..
)|
{
name1
.cmp
(
name2
)
});
providers
.symbol_export_level
=
export_level
;
Arc
::
new
(
symbols
)
}
pub
fn
provide_extern
(
providers
:
&
mut
Providers
)
{
providers
.exported_symbols
=
|
tcx
,
cnum
|
{
// If this crate is a plugin and/or a custom derive crate, then
// we're not even going to link those in so we skip those crates.
if
tcx
.plugin_registrar_fn
(
cnum
)
.is_some
()
||
tcx
.derive_registrar_fn
(
cnum
)
.is_some
()
{
return
Arc
::
new
(
Vec
::
new
())
}
pub
fn
provide
(
providers
:
&
mut
Providers
)
{
providers
.reachable_non_generics
=
reachable_non_generics_provider
;
providers
.is_reachable_non_generic
=
is_reachable_non_generic_provider
;
providers
.exported_symbols
=
exported_symbols_provider_local
;
providers
.symbol_export_level
=
symbol_export_level_provider
;
}
// Check to see if this crate is a "special runtime crate". These
// crates, implementation details of the standard library, typically
// have a bunch of `pub extern` and `#[no_mangle]` functions as the
// ABI between them. We don't want their symbols to have a `C`
// export level, however, as they're just implementation details.
// Down below we'll hardwire all of the symbols to the `Rust` export
// level instead.
let
special_runtime_crate
=
tcx
.is_panic_runtime
(
cnum
)
||
tcx
.is_compiler_builtins
(
cnum
);
let
mut
crate_exports
:
Vec
<
_
>
=
tcx
.reachable_non_generics
(
cnum
)
.iter
()
.map
(|
&
def_id
|
{
let
name
=
tcx
.symbol_name
(
Instance
::
mono
(
tcx
,
def_id
));
let
export_level
=
if
special_runtime_crate
{
// We can probably do better here by just ensuring that
// it has hidden visibility rather than public
// visibility, as this is primarily here to ensure it's
// not stripped during LTO.
//
// In general though we won't link right if these
// symbols are stripped, and LTO currently strips them.
if
&*
name
==
"rust_eh_personality"
||
&*
name
==
"rust_eh_register_frames"
||
&*
name
==
"rust_eh_unregister_frames"
{
SymbolExportLevel
::
C
}
else
{
SymbolExportLevel
::
Rust
}
fn
exported_symbols_provider_extern
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
cnum
:
CrateNum
)
->
Arc
<
Vec
<
(
String
,
Option
<
DefId
>
,
SymbolExportLevel
)
>>
{
// If this crate is a plugin and/or a custom derive crate, then
// we're not even going to link those in so we skip those crates.
if
tcx
.plugin_registrar_fn
(
cnum
)
.is_some
()
||
tcx
.derive_registrar_fn
(
cnum
)
.is_some
()
{
return
Arc
::
new
(
Vec
::
new
())
}
// Check to see if this crate is a "special runtime crate". These
// crates, implementation details of the standard library, typically
// have a bunch of `pub extern` and `#[no_mangle]` functions as the
// ABI between them. We don't want their symbols to have a `C`
// export level, however, as they're just implementation details.
// Down below we'll hardwire all of the symbols to the `Rust` export
// level instead.
let
special_runtime_crate
=
tcx
.is_panic_runtime
(
cnum
)
||
tcx
.is_compiler_builtins
(
cnum
);
let
mut
crate_exports
:
Vec
<
_
>
=
tcx
.reachable_non_generics
(
cnum
)
.iter
()
.map
(|
&
def_id
|
{
let
name
=
tcx
.symbol_name
(
Instance
::
mono
(
tcx
,
def_id
));
let
export_level
=
if
special_runtime_crate
{
// We can probably do better here by just ensuring that
// it has hidden visibility rather than public
// visibility, as this is primarily here to ensure it's
// not stripped during LTO.
//
// In general though we won't link right if these
// symbols are stripped, and LTO currently strips them.
if
&*
name
==
"rust_eh_personality"
||
&*
name
==
"rust_eh_register_frames"
||
&*
name
==
"rust_eh_unregister_frames"
{
SymbolExportLevel
::
C
}
else
{
export_level
(
tcx
,
def_id
)
};
debug!
(
"EXPORTED SYMBOL (re-export): {} ({:?})"
,
name
,
export_level
);
(
str
::
to_owned
(
&
name
),
Some
(
def_id
),
export_level
)
})
.collect
();
// Sort so we get a stable incr. comp. hash.
crate_exports
.sort_unstable_by
(|
&
(
ref
name1
,
..
),
&
(
ref
name2
,
..
)|
{
name1
.cmp
(
name2
)
});
Arc
::
new
(
crate_exports
)
};
providers
.is_reachable_non_generic
=
|
tcx
,
id
|
{
tcx
.reachable_non_generics
(
id
.krate
)
.contains
(
&
id
)
};
providers
.symbol_export_level
=
export_level
;
SymbolExportLevel
::
Rust
}
}
else
{
tcx
.symbol_export_level
(
def_id
)
};
debug!
(
"EXPORTED SYMBOL (re-export): {} ({:?})"
,
name
,
export_level
);
(
str
::
to_owned
(
&
name
),
Some
(
def_id
),
export_level
)
})
.collect
();
// Sort so we get a stable incr. comp. hash.
crate_exports
.sort_unstable_by
(|
&
(
ref
name1
,
..
),
&
(
ref
name2
,
..
)|
{
name1
.cmp
(
name2
)
});
Arc
::
new
(
crate_exports
)
}
pub
fn
provide_extern
(
providers
:
&
mut
Providers
)
{
providers
.exported_symbols
=
exported_symbols_provider_extern
;
providers
.is_reachable_non_generic
=
is_reachable_non_generic_provider
;
providers
.symbol_export_level
=
symbol_export_level_provider
;
}
fn
export_level
(
tcx
:
TyCtxt
,
sym_def_id
:
DefId
)
->
SymbolExportLevel
{
fn
symbol_export_level_provider
(
tcx
:
TyCtxt
,
sym_def_id
:
DefId
)
->
SymbolExportLevel
{
// We export anything that's not mangled at the "C" layer as it probably has
// to do with ABI concerns. We do not, however, apply such treatment to
// special symbols in the standard library for various plumbing between
...
...
src/librustc_trans/base.rs
浏览文件 @
33d5da1e
...
...
@@ -70,7 +70,7 @@
use
trans_item
::{
MonoItem
,
BaseMonoItemExt
,
MonoItemExt
,
DefPathBasedNames
};
use
type_
::
Type
;
use
type_of
::
LayoutLlvmExt
;
use
rustc
::
util
::
nodemap
::{
NodeSet
,
FxHashMap
,
FxHashSet
,
DefIdSet
};
use
rustc
::
util
::
nodemap
::{
FxHashMap
,
FxHashSet
,
DefIdSet
};
use
CrateInfo
;
use
std
::
any
::
Any
;
...
...
@@ -89,7 +89,7 @@
use
mir
::
operand
::
OperandValue
;
pub
use
rustc_trans_utils
::
{
find_exported_symbols
,
check_for_rustc_errors_attr
}
;
pub
use
rustc_trans_utils
::
check_for_rustc_errors_attr
;
pub
use
rustc_mir
::
monomorphize
::
item
::
linkage_by_name
;
pub
struct
StatRecorder
<
'a
,
'tcx
:
'a
>
{
...
...
@@ -606,8 +606,7 @@ fn contains_null(s: &str) -> bool {
fn
write_metadata
<
'a
,
'gcx
>
(
tcx
:
TyCtxt
<
'a
,
'gcx
,
'gcx
>
,
llmod_id
:
&
str
,
link_meta
:
&
LinkMeta
,
exported_symbols
:
&
NodeSet
)
link_meta
:
&
LinkMeta
)
->
(
ContextRef
,
ModuleRef
,
EncodedMetadata
)
{
use
std
::
io
::
Write
;
use
flate2
::
Compression
;
...
...
@@ -643,7 +642,7 @@ enum MetadataKind {
EncodedMetadata
::
new
());
}
let
metadata
=
tcx
.encode_metadata
(
link_meta
,
exported_symbols
);
let
metadata
=
tcx
.encode_metadata
(
link_meta
);
if
kind
==
MetadataKind
::
Uncompressed
{
return
(
metadata_llcx
,
metadata_llmod
,
metadata
);
}
...
...
@@ -718,13 +717,12 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let
crate_hash
=
tcx
.crate_hash
(
LOCAL_CRATE
);
let
link_meta
=
link
::
build_link_meta
(
crate_hash
);
let
exported_symbol_node_ids
=
find_exported_symbols
(
tcx
);
// Translate the metadata.
let
llmod_id
=
"metadata"
;
let
(
metadata_llcx
,
metadata_llmod
,
metadata
)
=
time
(
tcx
.sess
.time_passes
(),
"write metadata"
,
||
{
write_metadata
(
tcx
,
llmod_id
,
&
link_meta
,
&
exported_symbol_node_ids
)
write_metadata
(
tcx
,
llmod_id
,
&
link_meta
)
});
let
metadata_module
=
ModuleTranslation
{
...
...
src/librustc_trans_utils/lib.rs
浏览文件 @
33d5da1e
...
...
@@ -44,11 +44,7 @@
pub
extern
crate
rustc
as
__
rustc
;
use
rustc
::
ty
::{
TyCtxt
,
Instance
};
use
rustc
::
hir
;
use
rustc
::
hir
::
def_id
::
LOCAL_CRATE
;
use
rustc
::
hir
::
map
as
hir_map
;
use
rustc
::
util
::
nodemap
::
NodeSet
;
use
rustc
::
ty
::
TyCtxt
;
pub
mod
diagnostics
;
pub
mod
link
;
...
...
@@ -70,53 +66,4 @@ pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
}
}
/// The context provided lists a set of reachable ids as calculated by
/// middle::reachable, but this contains far more ids and symbols than we're
/// actually exposing from the object file. This function will filter the set in
/// the context to the set of ids which correspond to symbols that are exposed
/// from the object file being generated.
///
/// This list is later used by linkers to determine the set of symbols needed to
/// be exposed from a dynamic library and it's also encoded into the metadata.
pub
fn
find_exported_symbols
<
'a
,
'tcx
>
(
tcx
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
)
->
NodeSet
{
tcx
.reachable_set
(
LOCAL_CRATE
)
.0
.iter
()
.cloned
()
.filter
(|
&
id
|
{
// Next, we want to ignore some FFI functions that are not exposed from
// this crate. Reachable FFI functions can be lumped into two
// categories:
//
// 1. Those that are included statically via a static library
// 2. Those included otherwise (e.g. dynamically or via a framework)
//
// Although our LLVM module is not literally emitting code for the
// statically included symbols, it's an export of our library which
// needs to be passed on to the linker and encoded in the metadata.
//
// As a result, if this id is an FFI item (foreign item) then we only
// let it through if it's included statically.
match
tcx
.hir
.get
(
id
)
{
hir_map
::
NodeForeignItem
(
..
)
=>
{
let
def_id
=
tcx
.hir
.local_def_id
(
id
);
tcx
.is_statically_included_foreign_item
(
def_id
)
}
// Only consider nodes that actually have exported symbols.
hir_map
::
NodeItem
(
&
hir
::
Item
{
node
:
hir
::
ItemStatic
(
..
),
..
})
|
hir_map
::
NodeItem
(
&
hir
::
Item
{
node
:
hir
::
ItemFn
(
..
),
..
})
|
hir_map
::
NodeImplItem
(
&
hir
::
ImplItem
{
node
:
hir
::
ImplItemKind
::
Method
(
..
),
..
})
=>
{
let
def_id
=
tcx
.hir
.local_def_id
(
id
);
let
generics
=
tcx
.generics_of
(
def_id
);
(
generics
.parent_types
==
0
&&
generics
.types
.is_empty
())
&&
// Functions marked with #[inline] are only ever translated
// with "internal" linkage and are never exported.
!
Instance
::
mono
(
tcx
,
def_id
)
.def
.requires_local
(
tcx
)
}
_
=>
false
}
})
.collect
()
}
__
build_diagnostic_array!
{
librustc_trans_utils
,
DIAGNOSTICS
}
src/librustc_trans_utils/trans_crate.rs
浏览文件 @
33d5da1e
...
...
@@ -247,8 +247,7 @@ fn trans_crate<'a, 'tcx>(
tcx
.sess
.abort_if_errors
();
let
link_meta
=
build_link_meta
(
tcx
.crate_hash
(
LOCAL_CRATE
));
let
exported_symbols
=
::
find_exported_symbols
(
tcx
);
let
metadata
=
tcx
.encode_metadata
(
&
link_meta
,
&
exported_symbols
);
let
metadata
=
tcx
.encode_metadata
(
&
link_meta
);
box
OngoingCrateTranslation
{
metadata
:
metadata
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录