Skip to content

Commit 28173d3

Browse files
committed
save-analysis: index extern blocks
1 parent 62036e3 commit 28173d3

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed

Diff for: src/librustc_save_analysis/dump_visitor.rs

+35
Original file line numberDiff line numberDiff line change
@@ -1575,4 +1575,39 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll,
15751575
walk_list!(self, visit_ty, &l.ty);
15761576
walk_list!(self, visit_expr, &l.init);
15771577
}
1578+
1579+
fn visit_foreign_item(&mut self, item: &'l ast::ForeignItem) {
1580+
match item.node {
1581+
ast::ForeignItemKind::Fn(ref decl, ref generics) => {
1582+
if let Some(fn_data) = self.save_ctxt.get_extern_item_data(item) {
1583+
down_cast_data!(fn_data, FunctionData, item.span);
1584+
if !self.span.filter_generated(Some(fn_data.span), item.span) {
1585+
self.dumper.function(fn_data.clone().lower(self.tcx));
1586+
}
1587+
1588+
self.nest_tables(item.id, |v| v.process_formals(&decl.inputs,
1589+
&fn_data.qualname));
1590+
self.process_generic_params(generics, item.span, &fn_data.qualname, item.id);
1591+
}
1592+
1593+
for arg in &decl.inputs {
1594+
self.visit_ty(&arg.ty);
1595+
}
1596+
1597+
if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output {
1598+
self.visit_ty(&ret_ty);
1599+
}
1600+
}
1601+
ast::ForeignItemKind::Static(ref ty, _) => {
1602+
if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) {
1603+
down_cast_data!(var_data, VariableData, item.span);
1604+
if !self.span.filter_generated(Some(var_data.span), item.span) {
1605+
self.dumper.variable(var_data.lower(self.tcx));
1606+
}
1607+
}
1608+
1609+
self.visit_ty(ty);
1610+
}
1611+
}
1612+
}
15781613
}

Diff for: src/librustc_save_analysis/lib.rs

+55
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,46 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
119119
result
120120
}
121121

122+
pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option<Data> {
123+
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
124+
match item.node {
125+
ast::ForeignItemKind::Fn(ref decl, ref generics) => {
126+
let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Fn);
127+
Some(Data::FunctionData(FunctionData {
128+
id: item.id,
129+
name: item.ident.to_string(),
130+
qualname: qualname,
131+
declaration: None,
132+
span: sub_span.unwrap(),
133+
scope: self.enclosing_scope(item.id),
134+
value: make_signature(decl, generics),
135+
visibility: From::from(&item.vis),
136+
parent: None,
137+
docs: docs_for_attrs(&item.attrs),
138+
sig: self.sig_base_extern(item),
139+
}))
140+
}
141+
ast::ForeignItemKind::Static(ref ty, m) => {
142+
let keyword = if m { keywords::Mut } else { keywords::Static };
143+
let sub_span = self.span_utils.sub_span_after_keyword(item.span, keyword);
144+
Some(Data::VariableData(VariableData {
145+
id: item.id,
146+
kind: VariableKind::Static,
147+
name: item.ident.to_string(),
148+
qualname: qualname,
149+
span: sub_span.unwrap(),
150+
scope: self.enclosing_scope(item.id),
151+
parent: None,
152+
value: String::new(),
153+
type_value: ty_to_string(ty),
154+
visibility: From::from(&item.vis),
155+
docs: docs_for_attrs(&item.attrs),
156+
sig: Some(self.sig_base_extern(item)),
157+
}))
158+
}
159+
}
160+
}
161+
122162
pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
123163
match item.node {
124164
ast::ItemKind::Fn(ref decl, .., ref generics, _) => {
@@ -751,6 +791,21 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
751791
}
752792
}
753793

794+
fn sig_base_extern(&self, item: &ast::ForeignItem) -> Signature {
795+
let text = self.span_utils.signature_string_for_span(item.span);
796+
let name = item.ident.to_string();
797+
let ident_start = text.find(&name).expect("Name not in signature?");
798+
let ident_end = ident_start + name.len();
799+
Signature {
800+
span: mk_sp(item.span.lo, item.span.lo + BytePos(text.len() as u32)),
801+
text: text,
802+
ident_start: ident_start,
803+
ident_end: ident_end,
804+
defs: vec![],
805+
refs: vec![],
806+
}
807+
}
808+
754809
#[inline]
755810
pub fn enclosing_scope(&self, id: NodeId) -> NodeId {
756811
self.tcx.hir.get_enclosing_scope(id).unwrap_or(CRATE_NODE_ID)

Diff for: src/test/run-make/save-analysis-fail/foo.rs

+5
Original file line numberDiff line numberDiff line change
@@ -448,3 +448,8 @@ fn test_format_args() {
448448
print!("{0} + {} = {}", x, y);
449449
print!("x is {}, y is {1}, name is {n}", x, y, n = name);
450450
}
451+
452+
extern {
453+
static EXTERN_FOO: u8;
454+
fn extern_foo(a: u8, b: i32) -> String;
455+
}

0 commit comments

Comments
 (0)