1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // The crate store - a central repo for information collected about external
12 // crates and libraries
15 use rustc
::hir
::def_id
::{CrateNum, DefIndex}
;
16 use rustc
::hir
::map
::definitions
::DefPathTable
;
17 use rustc
::middle
::cstore
::{DepKind, ExternCrate, MetadataLoader}
;
18 use rustc
::mir
::interpret
::AllocDecodingState
;
19 use rustc_data_structures
::indexed_vec
::IndexVec
;
20 use rustc
::util
::nodemap
::{FxHashMap, NodeMap}
;
22 use rustc_data_structures
::sync
::{Lrc, RwLock, Lock}
;
24 use syntax
::ext
::base
::SyntaxExtension
;
25 use syntax
::symbol
::Symbol
;
28 pub use rustc
::middle
::cstore
::{NativeLibrary, NativeLibraryKind, LinkagePreference}
;
29 pub use rustc
::middle
::cstore
::NativeLibraryKind
::*;
30 pub use rustc
::middle
::cstore
::{CrateSource, LibSource, ForeignModule}
;
32 pub use cstore_impl
::{provide, provide_extern}
;
34 // A map from external crate numbers (as decoded from some crate file) to
35 // local crate numbers (as generated during this session). Each external
36 // crate may refer to types in other external crates, and each has their
38 pub type CrateNumMap
= IndexVec
<CrateNum
, CrateNum
>;
40 pub use rustc_data_structures
::sync
::MetadataRef
;
42 pub struct MetadataBlob(pub MetadataRef
);
44 /// Holds information about a syntax_pos::FileMap imported from another crate.
45 /// See `imported_filemaps()` for more information.
46 pub struct ImportedFileMap
{
47 /// This FileMap's byte-offset within the codemap of its original crate
48 pub original_start_pos
: syntax_pos
::BytePos
,
49 /// The end of this FileMap within the codemap of its original crate
50 pub original_end_pos
: syntax_pos
::BytePos
,
51 /// The imported FileMap's representation within the local codemap
52 pub translated_filemap
: Lrc
<syntax_pos
::FileMap
>,
55 pub struct CrateMetadata
{
58 /// Information about the extern crate that caused this crate to
59 /// be loaded. If this is `None`, then the crate was injected
60 /// (e.g., by the allocator)
61 pub extern_crate
: Lock
<Option
<ExternCrate
>>,
63 pub blob
: MetadataBlob
,
64 pub cnum_map
: CrateNumMap
,
66 pub dependencies
: Lock
<Vec
<CrateNum
>>,
67 pub codemap_import_info
: RwLock
<Vec
<ImportedFileMap
>>,
69 /// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
70 pub alloc_decoding_state
: AllocDecodingState
,
72 pub root
: schema
::CrateRoot
,
74 /// For each public item in this crate, we encode a key. When the
75 /// crate is loaded, we read all the keys and put them in this
76 /// hashmap, which gives the reverse mapping. This allows us to
77 /// quickly retrace a `DefPath`, which is needed for incremental
78 /// compilation support.
79 pub def_path_table
: Lrc
<DefPathTable
>,
81 pub trait_impls
: FxHashMap
<(u32, DefIndex
), schema
::LazySeq
<DefIndex
>>,
83 pub dep_kind
: Lock
<DepKind
>,
84 pub source
: CrateSource
,
86 pub proc_macros
: Option
<Vec
<(ast
::Name
, Lrc
<SyntaxExtension
>)>>,
90 metas
: RwLock
<IndexVec
<CrateNum
, Option
<Lrc
<CrateMetadata
>>>>,
91 /// Map from NodeId's of local extern crate statements to crate numbers
92 extern_mod_crate_map
: Lock
<NodeMap
<CrateNum
>>,
93 pub metadata_loader
: Box
<MetadataLoader
+ Sync
>,
97 pub fn new(metadata_loader
: Box
<MetadataLoader
+ Sync
>) -> CStore
{
99 // We add an empty entry for LOCAL_CRATE (which maps to zero) in
100 // order to make array indices in `metas` match with the
101 // corresponding `CrateNum`. This first entry will always remain
103 metas
: RwLock
::new(IndexVec
::from_elem_n(None
, 1)),
104 extern_mod_crate_map
: Lock
::new(FxHashMap()),
109 pub(super) fn alloc_new_crate_num(&self) -> CrateNum
{
110 let mut metas
= self.metas
.borrow_mut();
111 let cnum
= CrateNum
::new(metas
.len());
116 pub(super) fn get_crate_data(&self, cnum
: CrateNum
) -> Lrc
<CrateMetadata
> {
117 self.metas
.borrow()[cnum
].clone().unwrap()
120 pub(super) fn set_crate_data(&self, cnum
: CrateNum
, data
: Lrc
<CrateMetadata
>) {
121 let mut metas
= self.metas
.borrow_mut();
122 assert
!(metas
[cnum
].is_none(), "Overwriting crate metadata entry");
123 metas
[cnum
] = Some(data
);
126 pub(super) fn iter_crate_data
<I
>(&self, mut i
: I
)
127 where I
: FnMut(CrateNum
, &Lrc
<CrateMetadata
>)
129 for (k
, v
) in self.metas
.borrow().iter_enumerated() {
130 if let &Some(ref v
) = v
{
136 pub(super) fn crate_dependencies_in_rpo(&self, krate
: CrateNum
) -> Vec
<CrateNum
> {
137 let mut ordering
= Vec
::new();
138 self.push_dependencies_in_postorder(&mut ordering
, krate
);
143 pub(super) fn push_dependencies_in_postorder(&self,
144 ordering
: &mut Vec
<CrateNum
>,
146 if ordering
.contains(&krate
) {
150 let data
= self.get_crate_data(krate
);
151 for &dep
in data
.dependencies
.borrow().iter() {
153 self.push_dependencies_in_postorder(ordering
, dep
);
157 ordering
.push(krate
);
160 pub(super) fn do_postorder_cnums_untracked(&self) -> Vec
<CrateNum
> {
161 let mut ordering
= Vec
::new();
162 for (num
, v
) in self.metas
.borrow().iter_enumerated() {
163 if let &Some(_
) = v
{
164 self.push_dependencies_in_postorder(&mut ordering
, num
);
170 pub(super) fn add_extern_mod_stmt_cnum(&self, emod_id
: ast
::NodeId
, cnum
: CrateNum
) {
171 self.extern_mod_crate_map
.borrow_mut().insert(emod_id
, cnum
);
174 pub(super) fn do_extern_mod_stmt_cnum(&self, emod_id
: ast
::NodeId
) -> Option
<CrateNum
> {
175 self.extern_mod_crate_map
.borrow().get(&emod_id
).cloned()