]> git.proxmox.com Git - rustc.git/blame - src/librustc_metadata/astencode.rs
New upstream version 1.13.0+dfsg1
[rustc.git] / src / librustc_metadata / astencode.rs
CommitLineData
c34b1796 1// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
223e47cc
LB
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
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.
10
54a0048b 11use rustc::hir::map as ast_map;
92a42be0 12
5bcae85e 13use rustc::hir::intravisit::{Visitor, IdRangeComputingVisitor, IdRange};
e9174d1e 14
9e0c209e
SL
15use cstore::CrateMetadata;
16use encoder::EncodeContext;
17use schema::*;
92a42be0 18
9e0c209e
SL
19use rustc::middle::cstore::{InlinedItem, InlinedItemRef};
20use rustc::middle::const_qualif::ConstQualif;
54a0048b
SL
21use rustc::hir::def::{self, Def};
22use rustc::hir::def_id::DefId;
9e0c209e 23use rustc::ty::{self, TyCtxt, Ty};
1a4d82fc 24
3157f602 25use syntax::ast;
5bcae85e 26
9e0c209e 27use rustc_serialize::Encodable;
223e47cc 28
9e0c209e
SL
29#[derive(RustcEncodable, RustcDecodable)]
30pub struct Ast<'tcx> {
31 id_range: IdRange,
32 item: Lazy<InlinedItem>,
33 side_tables: LazySeq<(ast::NodeId, TableEntry<'tcx>)>
223e47cc
LB
34}
35
9e0c209e
SL
36#[derive(RustcEncodable, RustcDecodable)]
37enum TableEntry<'tcx> {
38 Def(Def),
39 NodeType(Ty<'tcx>),
40 ItemSubsts(ty::ItemSubsts<'tcx>),
41 Adjustment(ty::adjustment::AutoAdjustment<'tcx>),
42 ConstQualif(ConstQualif)
223e47cc
LB
43}
44
9e0c209e
SL
45impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
46 pub fn encode_inlined_item(&mut self, ii: InlinedItemRef) -> Lazy<Ast<'tcx>> {
47 let mut id_visitor = IdRangeComputingVisitor::new();
48 match ii {
49 InlinedItemRef::Item(_, i) => id_visitor.visit_item(i),
50 InlinedItemRef::TraitItem(_, ti) => id_visitor.visit_trait_item(ti),
51 InlinedItemRef::ImplItem(_, ii) => id_visitor.visit_impl_item(ii)
223e47cc 52 }
223e47cc 53
9e0c209e
SL
54 let ii_pos = self.position();
55 ii.encode(self).unwrap();
56
57 let tables_pos = self.position();
58 let tables_count = {
59 let mut visitor = SideTableEncodingIdVisitor {
60 ecx: self,
61 count: 0
62 };
63 match ii {
64 InlinedItemRef::Item(_, i) => visitor.visit_item(i),
65 InlinedItemRef::TraitItem(_, ti) => visitor.visit_trait_item(ti),
66 InlinedItemRef::ImplItem(_, ii) => visitor.visit_impl_item(ii)
e9174d1e 67 }
9e0c209e
SL
68 visitor.count
69 };
1a4d82fc 70
9e0c209e
SL
71 self.lazy(&Ast {
72 id_range: id_visitor.result(),
73 item: Lazy::with_position(ii_pos),
74 side_tables: LazySeq::with_position_and_length(tables_pos, tables_count)
75 })
1a4d82fc
JJ
76 }
77}
78
9e0c209e
SL
79struct SideTableEncodingIdVisitor<'a, 'b:'a, 'tcx:'b> {
80 ecx: &'a mut EncodeContext<'b, 'tcx>,
81 count: usize
1a4d82fc
JJ
82}
83
9e0c209e 84impl<'a, 'b, 'tcx, 'v> Visitor<'v> for SideTableEncodingIdVisitor<'a, 'b, 'tcx> {
1a4d82fc 85 fn visit_id(&mut self, id: ast::NodeId) {
9e0c209e 86 debug!("Encoding side tables for id {}", id);
223e47cc 87
9e0c209e
SL
88 let tcx = self.ecx.tcx;
89 let mut encode = |entry: Option<TableEntry>| {
90 if let Some(entry) = entry {
91 (id, entry).encode(self.ecx).unwrap();
92 self.count += 1;
223e47cc 93 }
9e0c209e 94 };
1a4d82fc 95
9e0c209e
SL
96 encode(tcx.expect_def_or_none(id).map(TableEntry::Def));
97 encode(tcx.node_types().get(&id).cloned().map(TableEntry::NodeType));
98 encode(tcx.tables.borrow().item_substs.get(&id).cloned().map(TableEntry::ItemSubsts));
99 encode(tcx.tables.borrow().adjustments.get(&id).cloned().map(TableEntry::Adjustment));
100 encode(tcx.const_qualif_map.borrow().get(&id).cloned().map(TableEntry::ConstQualif));
223e47cc
LB
101 }
102}
103
9e0c209e
SL
104/// Decodes an item from its AST in the cdata's metadata and adds it to the
105/// ast-map.
106pub fn decode_inlined_item<'a, 'tcx>(cdata: &CrateMetadata,
107 tcx: TyCtxt<'a, 'tcx, 'tcx>,
108 parent_def_path: ast_map::DefPath,
109 parent_did: DefId,
110 ast: Ast<'tcx>,
111 orig_did: DefId)
112 -> &'tcx InlinedItem {
113 debug!("> Decoding inlined fn: {:?}", tcx.item_path_str(orig_did));
223e47cc 114
9e0c209e
SL
115 let cnt = ast.id_range.max.as_usize() - ast.id_range.min.as_usize();
116 let start = tcx.sess.reserve_node_ids(cnt);
117 let id_ranges = [ast.id_range, IdRange {
118 min: start,
119 max: ast::NodeId::new(start.as_usize() + cnt)
120 }];
223e47cc 121
9e0c209e
SL
122 let ii = ast.item.decode((cdata, tcx, id_ranges));
123 let ii = ast_map::map_decoded_item(&tcx.map,
124 parent_def_path,
125 parent_did,
126 ii,
127 tcx.sess.next_node_id());
b039eaaf 128
b039eaaf 129 let item_node_id = match ii {
5bcae85e 130 &InlinedItem::Item(_, ref i) => i.id,
b039eaaf 131 &InlinedItem::TraitItem(_, ref ti) => ti.id,
9e0c209e 132 &InlinedItem::ImplItem(_, ref ii) => ii.id
b039eaaf 133 };
9e0c209e
SL
134 let inlined_did = tcx.map.local_def_id(item_node_id);
135 tcx.register_item_type(inlined_did, tcx.lookup_item_type(orig_did));
b039eaaf 136
9e0c209e
SL
137 for (id, entry) in ast.side_tables.decode((cdata, tcx, id_ranges)) {
138 match entry {
139 TableEntry::Def(def) => {
140 tcx.def_map.borrow_mut().insert(id, def::PathResolution::new(def));
b039eaaf 141 }
9e0c209e
SL
142 TableEntry::NodeType(ty) => {
143 tcx.node_type_insert(id, ty);
b039eaaf 144 }
9e0c209e
SL
145 TableEntry::ItemSubsts(item_substs) => {
146 tcx.tables.borrow_mut().item_substs.insert(id, item_substs);
a7813a04 147 }
9e0c209e
SL
148 TableEntry::Adjustment(adj) => {
149 tcx.tables.borrow_mut().adjustments.insert(id, adj);
a7813a04 150 }
9e0c209e
SL
151 TableEntry::ConstQualif(qualif) => {
152 tcx.const_qualif_map.borrow_mut().insert(id, qualif);
a7813a04 153 }
223e47cc 154 }
9e0c209e
SL
155 }
156
157 ii
223e47cc 158}