]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/queries.rs
move `build_mir` into `build` directory
[rust.git] / src / librustc_mir / queries.rs
1 // Copyright 2015 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.
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
11 //! An experimental pass that scources for `#[rustc_mir]` attributes,
12 //! builds the resulting MIR, and dumps it out into a file for inspection.
13 //!
14 //! The attribute formats that are currently accepted are:
15 //!
16 //! - `#[rustc_mir(graphviz="file.gv")]`
17 //! - `#[rustc_mir(pretty="file.mir")]`
18
19 use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
20
21 use rustc::ty::TyCtxt;
22 use rustc::ty::maps::Providers;
23 use rustc::hir;
24 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
25 use rustc::util::nodemap::DefIdSet;
26 use syntax::ast;
27 use syntax_pos::Span;
28
29 use std::rc::Rc;
30
31 pub fn provide(providers: &mut Providers) {
32     use build::mir_build;
33     *providers = Providers {
34         mir_build,
35         mir_keys,
36         ..*providers
37     };
38 }
39
40 fn mir_keys<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, krate: CrateNum)
41                       -> Rc<DefIdSet> {
42     assert_eq!(krate, LOCAL_CRATE);
43
44     let mut set = DefIdSet();
45
46     // All body-owners have MIR associated with them.
47     set.extend(tcx.body_owners());
48
49     // Additionally, tuple struct/variant constructors have MIR, but
50     // they don't have a BodyId, so we need to build them separately.
51     struct GatherCtors<'a, 'tcx: 'a> {
52         tcx: TyCtxt<'a, 'tcx, 'tcx>,
53         set: &'a mut DefIdSet,
54     }
55     impl<'a, 'tcx> Visitor<'tcx> for GatherCtors<'a, 'tcx> {
56         fn visit_variant_data(&mut self,
57                               v: &'tcx hir::VariantData,
58                               _: ast::Name,
59                               _: &'tcx hir::Generics,
60                               _: ast::NodeId,
61                               _: Span) {
62             if let hir::VariantData::Tuple(_, node_id) = *v {
63                 self.set.insert(self.tcx.hir.local_def_id(node_id));
64             }
65             intravisit::walk_struct_def(self, v)
66         }
67         fn nested_visit_map<'b>(&'b mut self) -> NestedVisitorMap<'b, 'tcx> {
68             NestedVisitorMap::None
69         }
70     }
71     tcx.hir.krate().visit_all_item_likes(&mut GatherCtors {
72         tcx: tcx,
73         set: &mut set,
74     }.as_deep_visitor());
75
76     Rc::new(set)
77 }